Website Structure

This commit is contained in:
supalerk-ar66 2026-01-13 10:46:40 +07:00
parent 62812f2090
commit 71f0676a62
22365 changed files with 4265753 additions and 791 deletions

View file

@ -0,0 +1,24 @@
Copyright (c) 2018, Gajus Kuizinas (http://gajus.com/)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Gajus Kuizinas (http://gajus.com/) nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL ANUARY BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -0,0 +1,515 @@
<a name="user-content-eslint-plugin-jsdoc"></a>
<a name="eslint-plugin-jsdoc"></a>
# eslint-plugin-jsdoc
[![NPM version](https://img.shields.io/npm/v/eslint-plugin-jsdoc.svg?style=flat-square)](https://www.npmjs.org/package/eslint-plugin-jsdoc)
[![Travis build status](https://img.shields.io/travis/gajus/eslint-plugin-jsdoc/master.svg?style=flat-square)](https://travis-ci.org/gajus/eslint-plugin-jsdoc)
[![js-canonical-style](https://img.shields.io/badge/code%20style-canonical-blue.svg?style=flat-square)](https://github.com/gajus/canonical)
[![Discord Chat](https://img.shields.io/badge/chat-on%20disord-green.svg?logo=discord)](https://discord.gg/kFFy3nc)
JSDoc linting rules for ESLint.
* [eslint-plugin-jsdoc](#user-content-eslint-plugin-jsdoc)
* [Installation](#user-content-eslint-plugin-jsdoc-installation)
* [Configuration](#user-content-eslint-plugin-jsdoc-configuration)
* [Flat config (procedural)](#user-content-eslint-plugin-jsdoc-configuration-flat-config-procedural)
* [Flat config (declarative)](#user-content-eslint-plugin-jsdoc-configuration-flat-config-declarative)
* [`eslintrc`](#user-content-eslint-plugin-jsdoc-configuration-eslintrc)
* [Options](#user-content-eslint-plugin-jsdoc-options)
* [Settings](#user-content-eslint-plugin-jsdoc-settings)
* [Advanced](#user-content-eslint-plugin-jsdoc-advanced)
* [Processors](#user-content-eslint-plugin-jsdoc-processors)
* [Rules](#user-content-eslint-plugin-jsdoc-rules)
<a name="user-content-eslint-plugin-jsdoc-installation"></a>
<a name="eslint-plugin-jsdoc-installation"></a>
## Installation
Install [ESLint](https://www.github.com/eslint/eslint) either locally or
globally.
```sh
npm install --save-dev eslint
```
If you have installed `ESLint` globally, you have to install JSDoc plugin
globally too. Otherwise, install it locally.
```sh
npm install --save-dev eslint-plugin-jsdoc
```
<a name="user-content-eslint-plugin-jsdoc-configuration"></a>
<a name="eslint-plugin-jsdoc-configuration"></a>
## Configuration
<a name="user-content-eslint-plugin-jsdoc-configuration-flat-config-procedural"></a>
<a name="eslint-plugin-jsdoc-configuration-flat-config-procedural"></a>
### Flat config (procedural)
This is the currently recommended approach for all flat configs (besides the
array-based `examples`, `default-expressions`, and
`examples-and-default-expressions` configs).
```js
import {jsdoc} from 'eslint-plugin-jsdoc';
export default [
jsdoc({
config: 'flat/recommended',
})
];
```
Or with TypeScript-aware extra rules and/or settings supplied:
```js
import {jsdoc} from 'eslint-plugin-jsdoc';
export default [
jsdoc({
config: 'flat/recommended',
rules: {
'jsdoc/check-values': [
'error',
{
allowedLicenses: [
'MIT', 'ISC',
],
},
],
},
// Uncomment this if you wish your `settings` to overwrite the config's own settings;
// otherwise, the default behavior is to merge recursively
// mergeSettings: false,
settings: {
// Do not add a `jsdoc` child object here as you would for regular ESLint `settings`
structuredTags: {
see: {
name: 'namepath-referencing',
required: [
'name',
],
},
},
/*
// Since the recommended config has been chosen, the above settings will
// be merged by default with the following (which are tags that are
// being allowed and requiring a type):
structuredTags: {
next: {
required: [
'type',
],
},
rejects: {
required: [
'type',
],
},
},
*/
}
})
];
```
A `plugins` property can also be supplied to merge with the resulting `jsdoc` plugin.
Other config properties such as `files`, `ignores`, etc. are also copied over,
though noting that if the specified config produces an array, they will not
currently function.
There is also a `extraRuleDefinitions.forbid` option, the details of which are
explained in the [Advanced](./docs/advanced.md#forbidding-structures) docs
(under creating your own rules and forbidding structures).
<a name="user-content-eslint-plugin-jsdoc-configuration-flat-config-declarative"></a>
<a name="eslint-plugin-jsdoc-configuration-flat-config-declarative"></a>
### Flat config (declarative)
```js
import jsdoc from 'eslint-plugin-jsdoc';
const config = [
// configuration included in plugin
jsdoc.configs['flat/recommended'],
// other configuration objects...
{
files: ['**/*.js'],
// `plugins` here is not necessary if including the above config
plugins: {
jsdoc,
},
rules: {
'jsdoc/require-description': 'warn'
}
}
];
export default config;
```
The general starting rulesets you can extend from in flat config are:
- `jsdoc.configs['flat/recommended']`: Recommended starting rules for enforcing proper tag values, that common tags exist, and that tags are formatted and styled consistently
- `jsdoc.configs['flat/recommended-error']`: The same, reporting with failing errors instead of mere warnings
- `jsdoc.configs['flat/recommended-typescript']`: A similar recommended starting list, adjusted for projects using TypeScript syntax (and not just the "typescript" `mode` setting)
- `jsdoc.configs['flat/recommended-typescript-error']`: The same, reporting with failing errors instead of mere warnings
- `jsdoc.configs['flat/recommended-typescript-flavor']`: A similar recommended starting list, adjusted for projects using JavaScript syntax (source files that are still `.js`) but using TypeScript flavor within JSDoc (i.e., the default "typescript" `mode` in `eslint-plugin-jsdoc`)
- `jsdoc.configs['flat/recommended-typescript-flavor-error']`: The same, reporting with failing errors instead of mere warnings
- `jsdoc.configs['flat/recommended-mixed']`: A combination of `flat/recommended-typescript-flavor` and `flat/recommended-typescript` with automatic assignment of subconfig based on file extension (`**/*.{js,jsx,cjs,mjs}` and `**/*.{ts,tsx,cts,mts}`, respectively)
<a name="user-content-eslint-plugin-jsdoc-configuration-flat-config-declarative-granular-flat-configs"></a>
<a name="eslint-plugin-jsdoc-configuration-flat-config-declarative-granular-flat-configs"></a>
#### Granular Flat Configs
There also exist several more granular, standalone TypeScript rulesets you can extend from.
These each only enable mostly or only rules from the recommended starting rules:
- **Contents**: rules that check names and descriptions
- `jsdoc.configs['flat/contents-typescript']`: for TypeScript files, with reports set to warn
- `jsdoc.configs['flat/contents-typescript-error']`: for TypeScript files, with reports set to error
- `jsdoc.configs['flat/contents-typescript-flavor']`: for files using JavaScript syntax and JSDoc types, with reports set to warn
- `jsdoc.configs['flat/contents-typescript-flavor-error']`: for files using JavaScript syntax and JSDoc types, with reports set to error
- **Logical**: rules that enforce proper tag values
- `jsdoc.configs['flat/logical-typescript']`: for TypeScript files, with reports set to warn
- `jsdoc.configs['flat/logical-typescript-error']`: for TypeScript files, with reports set to error
- `jsdoc.configs['flat/logical-typescript-flavor']`: for files using JavaScript syntax and JSDoc types, with reports set to warn
- `jsdoc.configs['flat/logical-typescript-flavor-error']`: for files using JavaScript syntax and JSDoc types, with reports set to error
- **Requirements**: rules that enforce tags exist or have or don't have types
- `jsdoc.configs['flat/requirements-typescript']`: for TypeScript files, with reports set to warn
- `jsdoc.configs['flat/requirements-typescript-error']`: for TypeScript files, with reports set to error
- `jsdoc.configs['flat/requirements-typescript-flavor']`: for files using JavaScript syntax and JSDoc types, with reports set to warn
- `jsdoc.configs['flat/requirements-typescript-flavor-error']`: for files using JavaScript syntax and JSDoc types, with reports set to error
- **Stylistic**: rules that enforce clear, consistent tag formatting and styles
- `jsdoc.configs['flat/stylistic-typescript']`: for TypeScript files, with reports set to warn
- `jsdoc.configs['flat/stylistic-typescript-error']`: for TypeScript files, with reports set to error
- `jsdoc.configs['flat/stylistic-typescript-flavor']`: for files using JavaScript syntax and JSDoc types, with reports set to warn
- `jsdoc.configs['flat/stylistic-typescript-flavor-error']`: for files using JavaScript syntax and JSDoc types, with reports set to error
For example, to enforce only that any JSDoc tags and their contents are valid and styled consistently in TypeScript files, without enforcing that tags must always exist:
```js
import jsdoc from 'eslint-plugin-jsdoc';
export default [
jsdoc.configs['flat/contents-typescript-error'],
jsdoc.configs['flat/logical-typescript-error'],
jsdoc.configs['flat/stylistic-typescript-error'],
];
```
<a name="user-content-eslint-plugin-jsdoc-configuration-flat-config-declarative-granular-flat-configs-why-certain-rules-were-excluded-from-the-granular-configs"></a>
<a name="eslint-plugin-jsdoc-configuration-flat-config-declarative-granular-flat-configs-why-certain-rules-were-excluded-from-the-granular-configs"></a>
##### Why certain rules were excluded from the granular configs
A few rules were left out of the granular configs. Here is why:
Rules which might have been added to `required`:
- [`require-throws`](./docs/rules/require-throws.md#readme) - Since this can't enforce all cases, some may not wish this rule enforced.
- [`require-file-overview`](./docs/rules/require-file-overview.md#readme) - Too demanding for all projects
- [`convert-to-jsdoc-comments`](./docs/rules/convert-to-jsdoc-comments.md#readme) - Overly aggressive for some projects
Rules which might have been added to `logical`:
- [`no-missing-syntax`](./docs/rules/no-missing-syntax.md#readme) - Has no default options.
- [`no-restricted-syntax`](./docs/rules/no-restricted-syntax.md#readme) - Has no default options.
Rules which might have been added to `contents`:
- [`match-name`](./docs/rules/match-name.md#readme) - Has no default options.
- [`require-description`](./docs/rules/require-description.md#readme) - Too demanding for all projects
- [`require-description-complete-sentence`](./docs/rules/require-description-complete-sentence.md#readme) - Too demanding for all projects
Rules which might have been added to `stylistic`:
- [`check-indentation`](./docs/rules/check-indentation.md#readme) - May not be desired by all projects
- [`sort-tags`](./docs/rules/sort-tags.md#readme) - Too project-specific
<a name="user-content-eslint-plugin-jsdoc-configuration-eslintrc"></a>
<a name="eslint-plugin-jsdoc-configuration-eslintrc"></a>
### <code>eslintrc</code>
Add `plugins` section to [.eslintrc.*](https://eslint.org/docs/user-guide/configuring#configuration-file-formats)
and specify `eslint-plugin-jsdoc` as a plugin.
```json
{
"plugins": [
"jsdoc"
]
}
```
Finally, enable all of the rules that you would like to use.
```javascript
{
"rules": {
"jsdoc/check-access": 1, // Recommended
"jsdoc/check-alignment": 1, // Recommended
// "jsdoc/check-examples": 1, // Deprecated and not for ESLint >= 8
"jsdoc/check-indentation": 1,
"jsdoc/check-line-alignment": 1,
"jsdoc/check-param-names": 1, // Recommended
"jsdoc/check-property-names": 1, // Recommended
"jsdoc/check-syntax": 1,
"jsdoc/check-tag-names": 1, // Recommended
"jsdoc/check-template-names": 1,
"jsdoc/check-types": 1, // Recommended
"jsdoc/check-values": 1, // Recommended
"jsdoc/convert-to-jsdoc-comments": 1,
"jsdoc/empty-tags": 1, // Recommended
"jsdoc/escape-inline-tags": 1, // Recommended for TS configs
"jsdoc/implements-on-classes": 1, // Recommended
"jsdoc/imports-as-dependencies": 1,
"jsdoc/informative-docs": 1,
"jsdoc/lines-before-block": 1,
"jsdoc/match-description": 1,
"jsdoc/match-name": 1,
"jsdoc/multiline-blocks": 1, // Recommended
"jsdoc/no-bad-blocks": 1,
"jsdoc/no-blank-block-descriptions": 1,
"jsdoc/no-defaults": 1, // Recommended
"jsdoc/no-missing-syntax": 1,
"jsdoc/no-multi-asterisks": 1, // Recommended
"jsdoc/no-restricted-syntax": 1,
"jsdoc/no-types": 1, // Recommended for TS configs
"jsdoc/no-undefined-types": 1, // Recommended for non-TS configs
"jsdoc/reject-any-type": 1, // Recommended
"jsdoc/reject-function-type": 1, // Recommended
"jsdoc/require-asterisk-prefix": 1,
"jsdoc/require-description": 1,
"jsdoc/require-description-complete-sentence": 1,
"jsdoc/require-example": 1,
"jsdoc/require-file-overview": 1,
"jsdoc/require-hyphen-before-param-description": 1,
"jsdoc/require-jsdoc": 1, // Recommended
"jsdoc/require-next-description": 1,
"jsdoc/require-next-type": 1, // Recommended
"jsdoc/require-param-description": 1, // Recommended
"jsdoc/require-param-name": 1, // Recommended
"jsdoc/require-param-type": 1, // Recommended in non-TS configs
"jsdoc/require-param": 1, // Recommended
"jsdoc/require-property-description": 1, // Recommended
"jsdoc/require-property-name": 1, // Recommended
"jsdoc/require-property-type": 1, // Recommended in non-TS configs
"jsdoc/require-property": 1, // Recommended
"jsdoc/require-rejects": 1, // Recommended
"jsdoc/require-returns-check": 1, // Recommended
"jsdoc/require-returns-description": 1, // Recommended
"jsdoc/require-returns-type": 1, // Recommended in non-TS configs
"jsdoc/require-returns": 1, // Recommended
"jsdoc/require-template": 1,
"jsdoc/require-template-description": 1,
"jsdoc/require-throws": 1,
"jsdoc/require-throws-description": 1,
"jsdoc/require-throws-type": 1, // Recommended
"jsdoc/require-yields-check": 1, // Recommended
"jsdoc/require-yields-description": 1,
"jsdoc/require-yields-type": 1, // Recommended
"jsdoc/require-yields": 1, // Recommended
"jsdoc/sort-tags": 1,
"jsdoc/tag-lines": 1, // Recommended
"jsdoc/text-escaping": 1,
"jsdoc/ts-method-signature-style": 1,
"jsdoc/ts-prefer-function-type": 1,
"jsdoc/ts-no-unnecessary-template-expression": 1,
"jsdoc/type-formatting": 1,
"jsdoc/valid-types": 1 // Recommended
}
}
```
Or you can simply add the following to [.eslintrc.*](https://eslint.org/docs/user-guide/configuring#configuration-file-formats),
which enables the rules commented above as "recommended":
```json
{
"extends": ["plugin:jsdoc/recommended"]
}
```
You can then selectively add to or override the recommended rules.
Alternatively, if you wish to have all linting issues reported
as failing errors, you may use the "recommended-error" config:
```json
{
"extends": ["plugin:jsdoc/recommended-error"]
}
```
If you plan to use TypeScript syntax (and not just "typescript"
`mode` to indicate the JSDoc flavor is TypeScript), you can use:
```json
{
"extends": ["plugin:jsdoc/recommended-typescript"]
}
```
...or to report with failing errors instead of mere warnings:
```json
{
"extends": ["plugin:jsdoc/recommended-typescript-error"]
}
```
If you are not using TypeScript syntax (your source files are still `.js` files)
but you are using the TypeScript flavor within JSDoc (i.e., the default
"typescript" `mode` in `eslint-plugin-jsdoc`) and you are perhaps using
`allowJs` and `checkJs` options of TypeScript's `tsconfig.json`), you may
use:
```json
{
"extends": ["plugin:jsdoc/recommended-typescript-flavor"]
}
```
...or to report with failing errors instead of mere warnings:
```json
{
"extends": ["plugin:jsdoc/recommended-typescript-flavor-error"]
}
```
<a name="user-content-eslint-plugin-jsdoc-options"></a>
<a name="eslint-plugin-jsdoc-options"></a>
## Options
Rules may, as per the [ESLint user guide](https://eslint.org/docs/user-guide/configuring), have their own individual options. In `eslint-plugin-jsdoc`, a few options,
such as, `exemptedBy` and `contexts`, may be used across different rules.
`eslint-plugin-jsdoc` options, if present, are generally in the form of an
object supplied as the second argument in an array after the error level
(any exceptions to this format are explained within that rule's docs).
```js
// `.eslintrc.js`
{
rules: {
'jsdoc/require-example': [
// The Error level should be `error`, `warn`, or `off` (or 2, 1, or 0)
'error',
// The options vary by rule, but are generally added to an options
// object as follows:
{
checkConstructors: true,
exemptedBy: ['type']
}
]
}
}
```
<a name="user-content-eslint-plugin-jsdoc-settings"></a>
<a name="eslint-plugin-jsdoc-settings"></a>
## Settings
See [Settings](./docs/settings.md#readme).
<a name="user-content-eslint-plugin-jsdoc-advanced"></a>
<a name="eslint-plugin-jsdoc-advanced"></a>
## Advanced
See [Advanced](./docs/advanced.md#readme).
<a name="user-content-eslint-plugin-jsdoc-processors"></a>
<a name="eslint-plugin-jsdoc-processors"></a>
## Processors
See our `@example` and other item [processors](./docs/processors.md#readme).
<a name="user-content-eslint-plugin-jsdoc-rules"></a>
<a name="eslint-plugin-jsdoc-rules"></a>
## Rules
Problems reported by rules which have a wrench :wrench: below can be fixed automatically by running ESLint on the command line with `--fix` option.
Note that a number of fixable rules have an `enableFixer` option which can
be set to `false` to disable the fixer (or in the case of `check-param-names`,
`check-property-names`, and `no-blank-blocks`, set to `true` to enable a
non-default-recommended fixer).
|recommended|fixable|rule|description|
|-|-|-|-|
|:heavy_check_mark:|| [check-access](./docs/rules/check-access.md#readme) | Checks that `@access` tags have a valid value. |
|:heavy_check_mark:|:wrench:| [check-alignment](./docs/rules/check-alignment.md#readme) | Reports invalid alignment of JSDoc block asterisks. |
||| [check-examples](./docs/rules/check-examples.md#readme) | @deprecated - Use `getJsdocProcessorPlugin` processor; ensures that (JavaScript) samples within `@example` tags adhere to ESLint rules. |
||| [check-indentation](./docs/rules/check-indentation.md#readme) | Reports invalid padding inside JSDoc blocks. |
||:wrench:| [check-line-alignment](./docs/rules/check-line-alignment.md#readme) | Reports invalid alignment of JSDoc block lines. |
|:heavy_check_mark:|:wrench:| [check-param-names](./docs/rules/check-param-names.md#readme) | Checks for dupe `@param` names, that nested param names have roots, and that parameter names in function declarations match JSDoc param names. |
|:heavy_check_mark:|:wrench:| [check-property-names](./docs/rules/check-property-names.md#readme) | Ensures that property names in JSDoc are not duplicated on the same block and that nested properties have defined roots. |
||| [check-syntax](./docs/rules/check-syntax.md#readme) | Reports against syntax not valid for the mode (e.g., Google Closure Compiler in non-Closure mode). |
|:heavy_check_mark:|:wrench:| [check-tag-names](./docs/rules/check-tag-names.md#readme) | Reports invalid block tag names. |
||| [check-template-names](./docs/rules/check-template-names.md#readme) | Checks that any `@template` names are actually used in the connected `@typedef` or type alias. |
|:heavy_check_mark:|:wrench:| [check-types](./docs/rules/check-types.md#readme) | Reports types deemed invalid (customizable and with defaults, for preventing and/or recommending replacements). |
|:heavy_check_mark:|| [check-values](./docs/rules/check-values.md#readme) | This rule checks the values for a handful of tags: `@version`, `@since`, `@license` and `@author`. |
||:wrench:| [convert-to-jsdoc-comments](./docs/rules/convert-to-jsdoc-comments.md#readme) | Converts non-JSDoc comments preceding or following nodes into JSDoc ones |
|:heavy_check_mark:|:wrench:| [empty-tags](./docs/rules/empty-tags.md#readme) | Checks tags that are expected to be empty (e.g., `@abstract` or `@async`), reporting if they have content |
|:heavy_check_mark:|:wrench:| [escape-inline-tags](./docs/rules/escape-inline-tags.md#readme) | Reports use of JSDoc tags in non-tag positions (in the default "typescript" mode). |
|:heavy_check_mark:|| [implements-on-classes](./docs/rules/implements-on-classes.md#readme) | Prohibits use of `@implements` on non-constructor functions (to enforce the tag only being used on classes/constructors). |
||| [imports-as-dependencies](./docs/rules/imports-as-dependencies.md#readme) | Reports if JSDoc `import()` statements point to a package which is not listed in `dependencies` or `devDependencies` |
||| [informative-docs](./docs/rules/informative-docs.md#readme) | This rule reports doc comments that only restate their attached name. |
||:wrench:| [lines-before-block](./docs/rules/lines-before-block.md#readme) | Enforces minimum number of newlines before JSDoc comment blocks |
||| [match-description](./docs/rules/match-description.md#readme) | Enforces a regular expression pattern on descriptions. |
||:wrench:| [match-name](./docs/rules/match-name.md#readme) | Reports the name portion of a JSDoc tag if matching or not matching a given regular expression. |
|:heavy_check_mark:|:wrench:| [multiline-blocks](./docs/rules/multiline-blocks.md#readme) | Controls how and whether JSDoc blocks can be expressed as single or multiple line blocks. |
||:wrench:| [no-bad-blocks](./docs/rules/no-bad-blocks.md#readme) | This rule checks for multi-line-style comments which fail to meet the criteria of a JSDoc block. |
||:wrench:| [no-blank-block-descriptions](./docs/rules/no-blank-block-descriptions.md#readme) | If tags are present, this rule will prevent empty lines in the block description. If no tags are present, this rule will prevent extra empty lines in the block description. |
||:wrench:| [no-blank-blocks](./docs/rules/no-blank-blocks.md#readme) | Removes empty blocks with nothing but possibly line breaks |
|:heavy_check_mark:|:wrench:| [no-defaults](./docs/rules/no-defaults.md#readme) | This rule reports defaults being used on the relevant portion of `@param` or `@default`. |
||| [no-missing-syntax](./docs/rules/no-missing-syntax.md#readme) | Reports when certain comment structures are always expected. |
|:heavy_check_mark:|:wrench:| [no-multi-asterisks](./docs/rules/no-multi-asterisks.md#readme) | Prevents use of multiple asterisks at the beginning of lines. |
||| [no-restricted-syntax](./docs/rules/no-restricted-syntax.md#readme) | Reports when certain comment structures are present. |
|On in TS; Off in TS flavor|:wrench:| [no-types](./docs/rules/no-types.md#readme) | This rule reports types being used on `@param` or `@returns` (redundant with TypeScript). |
|:heavy_check_mark: (Off in TS; Off in TS flavor)|| [no-undefined-types](./docs/rules/no-undefined-types.md#readme) | Besides some expected built-in types, prohibits any types not specified as globals or within `@typedef`. |
||:wrench:| [prefer-import-tag](./docs/rules/prefer-import-tag.md#readme) | Prefer `@import` tags to inline `import()` statements. |
|:heavy_check_mark:|| [reject-any-type](./docs/rules/reject-any-type.md#readme) | Reports use of `any` or `*` type |
|:heavy_check_mark:|| [reject-function-type](./docs/rules/reject-function-type.md#readme) | Reports use of `Function` type |
||:wrench:| [require-asterisk-prefix](./docs/rules/require-asterisk-prefix.md#readme) | Requires that each JSDoc line starts with an `*`. |
||| [require-description](./docs/rules/require-description.md#readme) | Requires that all functions (and potentially other contexts) have a description. |
||:wrench:| [require-description-complete-sentence](./docs/rules/require-description-complete-sentence.md#readme) | Requires that block description, explicit `@description`, and `@param`/`@returns` tag descriptions are written in complete sentences. |
||:wrench:| [require-example](./docs/rules/require-example.md#readme) | Requires that all functions (and potentially other contexts) have examples. |
||| [require-file-overview](./docs/rules/require-file-overview.md#readme) | Checks that all files have one `@file`, `@fileoverview`, or `@overview` tag at the beginning of the file. |
||:wrench:| [require-hyphen-before-param-description](./docs/rules/require-hyphen-before-param-description.md#readme) | Requires a hyphen before the `@param` description (and optionally before `@property` descriptions). |
|:heavy_check_mark:|:wrench:| [require-jsdoc](./docs/rules/require-jsdoc.md#readme) | Checks for presence of JSDoc comments, on functions and potentially other contexts (optionally limited to exports). |
||| [require-next-description](./docs/rules/require-next-description.md#readme) | Requires a description for `@next` tags |
|:heavy_check_mark:|| [require-next-type](./docs/rules/require-next-type.md#readme) | Requires a type for `@next` tags |
|:heavy_check_mark:|:wrench:| [require-param](./docs/rules/require-param.md#readme) | Requires that all function parameters are documented with a `@param` tag. |
|:heavy_check_mark:|:wrench:| [require-param-description](./docs/rules/require-param-description.md#readme) | Requires that each `@param` tag has a `description` value. |
|:heavy_check_mark:|| [require-param-name](./docs/rules/require-param-name.md#readme) | Requires that all `@param` tags have names. |
|:heavy_check_mark: (Off in TS; On in TS flavor)|:wrench:| [require-param-type](./docs/rules/require-param-type.md#readme) | Requires that each `@param` tag has a type value (in curly brackets). |
|:heavy_check_mark:|:wrench:| [require-property](./docs/rules/require-property.md#readme) | Requires that all `@typedef` and `@namespace` tags have `@property` when their type is a plain `object`, `Object`, or `PlainObject`. |
|:heavy_check_mark:|| [require-property-description](./docs/rules/require-property-description.md#readme) | Requires that each `@property` tag has a `description` value. |
|:heavy_check_mark:|| [require-property-name](./docs/rules/require-property-name.md#readme) | Requires that all `@property` tags have names. |
|:heavy_check_mark: (Off in TS; On in TS flavor)|| [require-property-type](./docs/rules/require-property-type.md#readme) | Requires that each `@property` tag has a type value (in curly brackets). |
||| [require-rejects](./docs/rules/require-rejects.md#readme) | Requires that Promise rejections are documented with `@rejects` tags. |
|:heavy_check_mark:|:wrench:| [require-returns](./docs/rules/require-returns.md#readme) | Requires that returns are documented with `@returns`. |
|:heavy_check_mark:|| [require-returns-check](./docs/rules/require-returns-check.md#readme) | Requires a return statement in function body if a `@returns` tag is specified in JSDoc comment(and reports if multiple `@returns` tags are present). |
|:heavy_check_mark:|| [require-returns-description](./docs/rules/require-returns-description.md#readme) | Requires that the `@returns` tag has a `description` value (not including `void`/`undefined` type returns). |
|:heavy_check_mark: (Off in TS; On in TS flavor)|| [require-returns-type](./docs/rules/require-returns-type.md#readme) | Requires that `@returns` tag has type value (in curly brackets). |
||| [require-tags](./docs/rules/require-tags.md#readme) | Requires tags be present, optionally for specific contexts |
||| [require-template](./docs/rules/require-template.md#readme) | Requires `@template` tags be present when type parameters are used. |
||| [require-template-description](./docs/rules/require-template-description.md#readme) | Requires a description for `@template` tags |
||| [require-throws](./docs/rules/require-throws.md#readme) | Requires that throw statements are documented with `@throws` tags. |
||| [require-throws-description](./docs/rules/require-throws-description.md#readme) | Requires a description for `@throws` tags |
|:heavy_check_mark:|| [require-throws-type](./docs/rules/require-throws-type.md#readme) | Requires a type for `@throws` tags |
|:heavy_check_mark:|| [require-yields](./docs/rules/require-yields.md#readme) | Requires yields are documented with `@yields` tags. |
|:heavy_check_mark:|| [require-yields-check](./docs/rules/require-yields-check.md#readme) | Ensures that if a `@yields` is present that a `yield` (or `yield` with a value) is present in the function body (or that if a `@next` is present that there is a yield with a return value present). |
||| [require-yields-description](./docs/rules/require-yields-description.md#readme) | Requires a description for `@yields` tags |
|:heavy_check_mark:|| [require-yields-type](./docs/rules/require-yields-type.md#readme) | Requires a type for `@yields` tags |
||:wrench:| [sort-tags](./docs/rules/sort-tags.md#readme) | Sorts tags by a specified sequence according to tag name, optionally adding line breaks between tag groups. |
|:heavy_check_mark:|:wrench:| [tag-lines](./docs/rules/tag-lines.md#readme) | Enforces lines (or no lines) before, after, or between tags. |
||:wrench:| [text-escaping](./docs/rules/text-escaping.md#readme) | Auto-escape certain characters that are input within block and tag descriptions. |
||:wrench:| [ts-method-signature-style](./docs/rules/ts-method-signature-style.md#readme) | Prefers either function properties or method signatures |
|:heavy_check_mark:|| [ts-no-empty-object-type](./docs/rules/ts-no-empty-object-type.md#readme) | Warns against use of the empty object type |
||:wrench:| [ts-no-unnecessary-template-expression](./docs/rules/ts-no-unnecessary-template-expression.md#readme) | Catches unnecessary template expressions such as string expressions within a template literal. |
||:wrench:| [ts-prefer-function-type](./docs/rules/ts-prefer-function-type.md#readme) | Prefers function types over call signatures when there are no other properties. |
||:wrench:| [type-formatting](./docs/rules/type-formatting.md#readme) | Formats JSDoc type values. |
|:heavy_check_mark:|| [valid-types](./docs/rules/valid-types.md#readme) | Requires all types/namepaths to be valid JSDoc, Closure compiler, or TypeScript types (configurable in settings). |

View file

@ -0,0 +1,38 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
const WarnSettings = function () {
/** @type {WeakMap<object, Set<string>>} */
const warnedSettings = new WeakMap();
return {
/**
* Warn only once for each context and setting
* @param {import('eslint').Rule.RuleContext} context
* @param {string} setting
* @returns {boolean}
*/
hasBeenWarned(context, setting) {
return warnedSettings.has(context) && /** @type {Set<string>} */warnedSettings.get(context).has(setting);
},
/**
* @param {import('eslint').Rule.RuleContext} context
* @param {string} setting
* @returns {void}
*/
markSettingAsWarned(context, setting) {
// c8 ignore else
if (!warnedSettings.has(context)) {
warnedSettings.set(context, new Set());
}
/** @type {Set<string>} */
warnedSettings.get(context).add(setting);
}
};
};
var _default = exports.default = WarnSettings;
module.exports = exports.default;
//# sourceMappingURL=WarnSettings.cjs.map

View file

@ -0,0 +1 @@
{"version":3,"file":"WarnSettings.cjs","names":["WarnSettings","warnedSettings","WeakMap","hasBeenWarned","context","setting","has","get","markSettingAsWarned","set","Set","add","_default","exports","default","module"],"sources":["../src/WarnSettings.js"],"sourcesContent":["const WarnSettings = function () {\n /** @type {WeakMap<object, Set<string>>} */\n const warnedSettings = new WeakMap();\n\n return {\n /**\n * Warn only once for each context and setting\n * @param {import('eslint').Rule.RuleContext} context\n * @param {string} setting\n * @returns {boolean}\n */\n hasBeenWarned (context, setting) {\n return warnedSettings.has(context) && /** @type {Set<string>} */ (\n warnedSettings.get(context)\n ).has(setting);\n },\n\n /**\n * @param {import('eslint').Rule.RuleContext} context\n * @param {string} setting\n * @returns {void}\n */\n markSettingAsWarned (context, setting) {\n // c8 ignore else\n if (!warnedSettings.has(context)) {\n warnedSettings.set(context, new Set());\n }\n\n /** @type {Set<string>} */ (warnedSettings.get(context)).add(setting);\n },\n };\n};\n\nexport default WarnSettings;\n"],"mappings":";;;;;;AAAA,MAAMA,YAAY,GAAG,SAAAA,CAAA,EAAY;EAC/B;EACA,MAAMC,cAAc,GAAG,IAAIC,OAAO,CAAC,CAAC;EAEpC,OAAO;IACL;AACJ;AACA;AACA;AACA;AACA;IACIC,aAAaA,CAAEC,OAAO,EAAEC,OAAO,EAAE;MAC/B,OAAOJ,cAAc,CAACK,GAAG,CAACF,OAAO,CAAC,IAAI,0BACpCH,cAAc,CAACM,GAAG,CAACH,OAAO,CAAC,CAC3BE,GAAG,CAACD,OAAO,CAAC;IAChB,CAAC;IAED;AACJ;AACA;AACA;AACA;IACIG,mBAAmBA,CAAEJ,OAAO,EAAEC,OAAO,EAAE;MACrC;MACA,IAAI,CAACJ,cAAc,CAACK,GAAG,CAACF,OAAO,CAAC,EAAE;QAChCH,cAAc,CAACQ,GAAG,CAACL,OAAO,EAAE,IAAIM,GAAG,CAAC,CAAC,CAAC;MACxC;;MAEA;MAA4BT,cAAc,CAACM,GAAG,CAACH,OAAO,CAAC,CAAEO,GAAG,CAACN,OAAO,CAAC;IACvE;EACF,CAAC;AACH,CAAC;AAAC,IAAAO,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAEad,YAAY;AAAAe,MAAA,CAAAF,OAAA,GAAAA,OAAA,CAAAC,OAAA","ignoreList":[]}

View file

@ -0,0 +1,17 @@
export default WarnSettings;
declare function WarnSettings(): {
/**
* Warn only once for each context and setting
* @param {import('eslint').Rule.RuleContext} context
* @param {string} setting
* @returns {boolean}
*/
hasBeenWarned(context: import("eslint").Rule.RuleContext, setting: string): boolean;
/**
* @param {import('eslint').Rule.RuleContext} context
* @param {string} setting
* @returns {void}
*/
markSettingAsWarned(context: import("eslint").Rule.RuleContext, setting: string): void;
};
//# sourceMappingURL=WarnSettings.d.ts.map

View file

@ -0,0 +1,402 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _commentParser = require("comment-parser");
/**
* Transform based on https://github.com/syavorsky/comment-parser/blob/master/src/transforms/align.ts
*
* It contains some customizations to align based on the tags, and some custom options.
*/
/**
* Detects if a line starts with a markdown list marker
* Supports: -, *, numbered lists (1., 2., etc.)
* This explicitly excludes hyphens that are part of JSDoc tag syntax
* @param {string} text - The text to check
* @param {boolean} isFirstLineOfTag - True if this is the first line (tag line)
* @returns {boolean} - True if the text starts with a list marker
*/
const startsWithListMarker = (text, isFirstLineOfTag = false) => {
// On the first line of a tag, the hyphen is typically the JSDoc separator,
// not a list marker
if (isFirstLineOfTag) {
return false;
}
// Match lines that start with optional whitespace, then a list marker
// - or * followed by a space
// or a number followed by . or ) and a space
return /^\s*(?:[\-*]|\d+(?:\.|\)))\s+/v.test(text);
};
/**
* @typedef {{
* hasNoTypes: boolean,
* maxNamedTagLength: import('./iterateJsdoc.js').Integer,
* maxUnnamedTagLength: import('./iterateJsdoc.js').Integer
* }} TypelessInfo
*/
const {
rewireSource
} = _commentParser.util;
/**
* @typedef {{
* name: import('./iterateJsdoc.js').Integer,
* start: import('./iterateJsdoc.js').Integer,
* tag: import('./iterateJsdoc.js').Integer,
* type: import('./iterateJsdoc.js').Integer
* }} Width
*/
/** @type {Width} */
const zeroWidth = {
name: 0,
start: 0,
tag: 0,
type: 0
};
/**
* @param {string[]} tags
* @param {import('./iterateJsdoc.js').Integer} index
* @param {import('comment-parser').Line[]} source
* @returns {boolean}
*/
const shouldAlign = (tags, index, source) => {
const tag = source[index].tokens.tag.replace('@', '');
const includesTag = tags.includes(tag);
if (includesTag) {
return true;
}
if (tag !== '') {
return false;
}
for (let iterator = index; iterator >= 0; iterator--) {
const previousTag = source[iterator].tokens.tag.replace('@', '');
if (previousTag !== '') {
if (tags.includes(previousTag)) {
return true;
}
return false;
}
}
return true;
};
/**
* @param {string[]} tags
* @returns {(
* width: Width,
* line: {
* tokens: import('comment-parser').Tokens
* },
* index: import('./iterateJsdoc.js').Integer,
* source: import('comment-parser').Line[]
* ) => Width}
*/
const getWidth = tags => {
return (width, {
tokens
}, index, source) => {
if (!shouldAlign(tags, index, source)) {
return width;
}
return {
name: Math.max(width.name, tokens.name.length),
start: tokens.delimiter === '/**' ? tokens.start.length : width.start,
tag: Math.max(width.tag, tokens.tag.length),
type: Math.max(width.type, tokens.type.length)
};
};
};
/**
* @param {{
* description: string;
* tags: import('comment-parser').Spec[];
* problems: import('comment-parser').Problem[];
* }} fields
* @returns {TypelessInfo}
*/
const getTypelessInfo = fields => {
const hasNoTypes = fields.tags.every(({
type
}) => {
return !type;
});
const maxNamedTagLength = Math.max(...fields.tags.map(({
name,
tag
}) => {
return name.length === 0 ? -1 : tag.length;
}).filter(length => {
return length !== -1;
})) + 1;
const maxUnnamedTagLength = Math.max(...fields.tags.map(({
name,
tag
}) => {
return name.length === 0 ? tag.length : -1;
}).filter(length => {
return length !== -1;
})) + 1;
return {
hasNoTypes,
maxNamedTagLength,
maxUnnamedTagLength
};
};
/**
* @param {import('./iterateJsdoc.js').Integer} len
* @returns {string}
*/
const space = len => {
return ''.padStart(len, ' ');
};
/**
* Check if a tag or any of its lines contain list markers
* @param {import('./iterateJsdoc.js').Integer} index - Current line index
* @param {import('comment-parser').Line[]} source - All source lines
* @returns {{hasListMarker: boolean, tagStartIndex: import('./iterateJsdoc.js').Integer}}
*/
const checkForListMarkers = (index, source) => {
let hasListMarker = false;
let tagStartIndex = index;
while (tagStartIndex > 0 && source[tagStartIndex].tokens.tag === '') {
tagStartIndex--;
}
for (let idx = tagStartIndex; idx <= index; idx++) {
const isFirstLine = idx === tagStartIndex;
if (source[idx]?.tokens?.description && startsWithListMarker(source[idx].tokens.description, isFirstLine)) {
hasListMarker = true;
break;
}
}
return {
hasListMarker,
tagStartIndex
};
};
/**
* Calculate extra indentation for list items relative to the first continuation line
* @param {import('./iterateJsdoc.js').Integer} index - Current line index
* @param {import('./iterateJsdoc.js').Integer} tagStartIndex - Index of the tag line
* @param {import('comment-parser').Line[]} source - All source lines
* @returns {string} - Extra indentation spaces
*/
const calculateListExtraIndent = (index, tagStartIndex, source) => {
// Find the first continuation line to use as baseline
let firstContinuationIndent = null;
for (let idx = tagStartIndex + 1; idx < source.length; idx++) {
if (source[idx].tokens.description && !source[idx].tokens.tag) {
firstContinuationIndent = source[idx].tokens.postDelimiter.length;
break;
}
}
// Calculate the extra indentation of current line relative to the first continuation line
const currentOriginalIndent = source[index].tokens.postDelimiter.length;
const extraIndent = firstContinuationIndent !== null && currentOriginalIndent > firstContinuationIndent ? ' '.repeat(currentOriginalIndent - firstContinuationIndent) : '';
return extraIndent;
};
/**
* @param {{
* customSpacings: import('../src/rules/checkLineAlignment.js').CustomSpacings,
* tags: string[],
* indent: string,
* preserveMainDescriptionPostDelimiter: boolean,
* wrapIndent: string,
* disableWrapIndent: boolean,
* }} cfg
* @returns {(
* block: import('comment-parser').Block
* ) => import('comment-parser').Block}
*/
const alignTransform = ({
customSpacings,
disableWrapIndent,
indent,
preserveMainDescriptionPostDelimiter,
tags,
wrapIndent
}) => {
let intoTags = false;
/** @type {Width} */
let width;
/**
* @param {import('comment-parser').Tokens} tokens
* @param {TypelessInfo} typelessInfo
* @returns {import('comment-parser').Tokens}
*/
const alignTokens = (tokens, typelessInfo) => {
const nothingAfter = {
delim: false,
name: false,
tag: false,
type: false
};
if (tokens.description === '') {
nothingAfter.name = true;
tokens.postName = '';
if (tokens.name === '') {
nothingAfter.type = true;
tokens.postType = '';
if (tokens.type === '') {
nothingAfter.tag = true;
tokens.postTag = '';
/* c8 ignore next: Never happens because the !intoTags return. But it's here for consistency with the original align transform */
if (tokens.tag === '') {
nothingAfter.delim = true;
}
}
}
}
let untypedNameAdjustment = 0;
let untypedTypeAdjustment = 0;
if (typelessInfo.hasNoTypes) {
nothingAfter.tag = true;
tokens.postTag = '';
if (tokens.name === '') {
untypedNameAdjustment = typelessInfo.maxNamedTagLength - tokens.tag.length;
} else {
untypedNameAdjustment = typelessInfo.maxNamedTagLength > typelessInfo.maxUnnamedTagLength ? 0 : Math.max(0, typelessInfo.maxUnnamedTagLength - (tokens.tag.length + tokens.name.length + 1));
untypedTypeAdjustment = typelessInfo.maxNamedTagLength - tokens.tag.length;
}
}
// Todo: Avoid fixing alignment of blocks with multiline wrapping of type
if (tokens.tag === '' && tokens.type) {
return tokens;
}
const spacings = {
postDelimiter: customSpacings?.postDelimiter || 1,
postName: customSpacings?.postName || 1,
postTag: customSpacings?.postTag || 1,
postType: customSpacings?.postType || 1
};
tokens.postDelimiter = nothingAfter.delim ? '' : space(spacings.postDelimiter);
if (!nothingAfter.tag) {
tokens.postTag = space(width.tag - tokens.tag.length + spacings.postTag);
}
if (!nothingAfter.type) {
tokens.postType = space(width.type - tokens.type.length + spacings.postType + untypedTypeAdjustment);
}
if (!nothingAfter.name) {
// If post name is empty for all lines (name width 0), don't add post name spacing.
tokens.postName = width.name === 0 ? '' : space(width.name - tokens.name.length + spacings.postName + untypedNameAdjustment);
}
return tokens;
};
/**
* @param {import('comment-parser').Line} line
* @param {import('./iterateJsdoc.js').Integer} index
* @param {import('comment-parser').Line[]} source
* @param {TypelessInfo} typelessInfo
* @param {string|false} indentTag
* @returns {import('comment-parser').Line}
*/
const update = (line, index, source, typelessInfo, indentTag) => {
/** @type {import('comment-parser').Tokens} */
const tokens = {
...line.tokens
};
if (tokens.tag !== '') {
intoTags = true;
}
const isEmpty = tokens.tag === '' && tokens.name === '' && tokens.type === '' && tokens.description === '';
// dangling '*/'
if (tokens.end === '*/' && isEmpty) {
tokens.start = indent + ' ';
return {
...line,
tokens
};
}
switch (tokens.delimiter) {
case '*':
tokens.start = indent + ' ';
break;
case '/**':
tokens.start = indent;
break;
default:
tokens.delimiter = '';
// compensate delimiter
tokens.start = indent + ' ';
}
if (!intoTags) {
if (tokens.description === '') {
tokens.postDelimiter = '';
} else if (!preserveMainDescriptionPostDelimiter) {
tokens.postDelimiter = ' ';
}
return {
...line,
tokens
};
}
const postHyphenSpacing = customSpacings?.postHyphen ?? 1;
const hyphenSpacing = /^\s*-\s+/v;
tokens.description = tokens.description.replace(hyphenSpacing, '-' + ''.padStart(postHyphenSpacing, ' '));
// Not align.
if (shouldAlign(tags, index, source)) {
alignTokens(tokens, typelessInfo);
if (!disableWrapIndent && indentTag) {
const {
hasListMarker,
tagStartIndex
} = checkForListMarkers(index, source);
if (hasListMarker && index > tagStartIndex) {
const extraIndent = calculateListExtraIndent(index, tagStartIndex, source);
tokens.postDelimiter += wrapIndent + extraIndent;
} else {
// Normal case: add wrapIndent after the aligned delimiter
tokens.postDelimiter += wrapIndent;
}
}
}
return {
...line,
tokens
};
};
return ({
source,
...fields
}) => {
width = source.reduce(getWidth(tags), {
...zeroWidth
});
const typelessInfo = getTypelessInfo(fields);
let tagIndentMode = false;
return rewireSource({
...fields,
source: source.map((line, index) => {
const indentTag = !disableWrapIndent && tagIndentMode && !line.tokens.tag && line.tokens.description;
const ret = update(line, index, source, typelessInfo, indentTag);
if (!disableWrapIndent && line.tokens.tag) {
tagIndentMode = true;
}
return ret;
})
});
};
};
var _default = exports.default = alignTransform;
module.exports = exports.default;
//# sourceMappingURL=alignTransform.cjs.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,34 @@
export default alignTransform;
export type TypelessInfo = {
hasNoTypes: boolean;
maxNamedTagLength: import("./iterateJsdoc.js").Integer;
maxUnnamedTagLength: import("./iterateJsdoc.js").Integer;
};
export type Width = {
name: import("./iterateJsdoc.js").Integer;
start: import("./iterateJsdoc.js").Integer;
tag: import("./iterateJsdoc.js").Integer;
type: import("./iterateJsdoc.js").Integer;
};
/**
* @param {{
* customSpacings: import('../src/rules/checkLineAlignment.js').CustomSpacings,
* tags: string[],
* indent: string,
* preserveMainDescriptionPostDelimiter: boolean,
* wrapIndent: string,
* disableWrapIndent: boolean,
* }} cfg
* @returns {(
* block: import('comment-parser').Block
* ) => import('comment-parser').Block}
*/
declare function alignTransform({ customSpacings, disableWrapIndent, indent, preserveMainDescriptionPostDelimiter, tags, wrapIndent, }: {
customSpacings: import("../src/rules/checkLineAlignment.js").CustomSpacings;
tags: string[];
indent: string;
preserveMainDescriptionPostDelimiter: boolean;
wrapIndent: string;
disableWrapIndent: boolean;
}): (block: import("comment-parser").Block) => import("comment-parser").Block;
//# sourceMappingURL=alignTransform.d.ts.map

View file

@ -0,0 +1,101 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.buildForbidRuleDefinition = void 0;
var _iterateJsdoc = _interopRequireDefault(require("./iterateJsdoc.cjs"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/**
* @typedef {(string|{
* comment: string,
* context: string,
* message?: string
* })[]} Contexts
*/
/**
* @param {{
* contexts?: Contexts,
* description?: string,
* getContexts?: (
* ctxt: import('eslint').Rule.RuleContext,
* report: import('./iterateJsdoc.js').Report
* ) => Contexts|false,
* contextName?: string,
* modifyContext?: (context: import('eslint').Rule.RuleContext) => import('eslint').Rule.RuleContext,
* schema?: import('eslint').Rule.RuleMetaData['schema']
* url?: string,
* }} cfg
* @returns {import('eslint').Rule.RuleModule}
*/
const buildForbidRuleDefinition = ({
contextName,
contexts: cntxts,
description,
getContexts,
modifyContext,
schema,
url
}) => {
return (0, _iterateJsdoc.default)(({
context,
info: {
comment
},
report,
utils
}) => {
/** @type {Contexts|boolean|undefined} */
let contexts = cntxts;
if (getContexts) {
contexts = getContexts(context, report);
if (!contexts) {
return;
}
}
const {
contextStr,
foundContext
} = utils.findContext(/** @type {Contexts} */contexts, comment);
// We are not on the *particular* matching context/comment, so don't assume
// we need reporting
if (!foundContext) {
return;
}
const message = /** @type {import('./iterateJsdoc.js').ContextObject} */foundContext?.message ?? 'Syntax is restricted: {{context}}' + (comment ? ' with {{comment}}' : '');
report(message, null, null, comment ? {
comment,
context: contextStr
} : {
context: contextStr
});
}, {
contextSelected: true,
meta: {
docs: {
description: description ?? contextName ?? 'Reports when certain comment structures are present.',
url: url ?? 'https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/advanced.md#user-content-advanced-creating-your-own-rules'
},
schema: schema ?? [],
type: 'suggestion'
},
modifyContext: modifyContext ?? (getContexts ? undefined : context => {
// Reproduce context object with our own `contexts`
const propertyDescriptors = Object.getOwnPropertyDescriptors(context);
return Object.create(Object.getPrototypeOf(context), {
...propertyDescriptors,
options: {
...propertyDescriptors.options,
value: [{
contexts: cntxts
}]
}
});
}),
nonGlobalSettings: true
});
};
exports.buildForbidRuleDefinition = buildForbidRuleDefinition;
//# sourceMappingURL=buildForbidRuleDefinition.cjs.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,15 @@
export function buildForbidRuleDefinition({ contextName, contexts: cntxts, description, getContexts, modifyContext, schema, url, }: {
contexts?: Contexts;
description?: string;
getContexts?: (ctxt: import("eslint").Rule.RuleContext, report: import("./iterateJsdoc.js").Report) => Contexts | false;
contextName?: string;
modifyContext?: (context: import("eslint").Rule.RuleContext) => import("eslint").Rule.RuleContext;
schema?: import("eslint").Rule.RuleMetaData["schema"];
url?: string;
}): import("eslint").Rule.RuleModule;
export type Contexts = (string | {
comment: string;
context: string;
message?: string;
})[];
//# sourceMappingURL=buildForbidRuleDefinition.d.ts.map

View file

@ -0,0 +1,352 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.buildRejectOrPreferRuleDefinition = void 0;
var _iterateJsdoc = _interopRequireDefault(require("./iterateJsdoc.cjs"));
var _jsdoccomment = require("@es-joy/jsdoccomment");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/**
* Adjusts the parent type node `meta` for generic matches (or type node
* `type` for `JsdocTypeAny`) and sets the type node `value`.
* @param {string} type The actual type
* @param {string} preferred The preferred type
* @param {boolean} isGenericMatch
* @param {string} typeNodeName
* @param {import('jsdoc-type-pratt-parser').NonRootResult} node
* @param {import('jsdoc-type-pratt-parser').NonRootResult|undefined} parentNode
* @returns {void}
*/
const adjustNames = (type, preferred, isGenericMatch, typeNodeName, node, parentNode) => {
let ret = preferred;
if (isGenericMatch) {
const parentMeta = /** @type {import('jsdoc-type-pratt-parser').GenericResult} */parentNode.meta;
if (preferred === '[]') {
parentMeta.brackets = 'square';
parentMeta.dot = false;
ret = 'Array';
} else {
const dotBracketEnd = preferred.match(/\.(?:<>)?$/v);
if (dotBracketEnd) {
parentMeta.brackets = 'angle';
parentMeta.dot = true;
ret = preferred.slice(0, -dotBracketEnd[0].length);
} else {
const bracketEnd = preferred.endsWith('<>');
if (bracketEnd) {
parentMeta.brackets = 'angle';
parentMeta.dot = false;
ret = preferred.slice(0, -2);
} else if (parentMeta?.brackets === 'square' && (typeNodeName === '[]' || typeNodeName === 'Array')) {
parentMeta.brackets = 'angle';
parentMeta.dot = false;
}
}
}
} else if (type === 'JsdocTypeAny') {
node.type = 'JsdocTypeName';
}
/** @type {import('jsdoc-type-pratt-parser').NameResult} */
node.value = ret.replace(/(?:\.|<>|\.<>|\[\])$/v, '');
// For bare pseudo-types like `<>`
if (!ret) {
/** @type {import('jsdoc-type-pratt-parser').NameResult} */node.value = typeNodeName;
}
};
/**
* @param {boolean} [upperCase]
* @returns {string}
*/
const getMessage = upperCase => {
return 'Use object shorthand or index signatures instead of ' + '`' + (upperCase ? 'O' : 'o') + 'bject`, e.g., `{[key: string]: string}`';
};
/**
* @type {{
* message: string,
* replacement: false
* }}
*/
const info = {
message: getMessage(),
replacement: false
};
/**
* @type {{
* message: string,
* replacement: false
* }}
*/
const infoUC = {
message: getMessage(true),
replacement: false
};
/**
* @param {{
* checkNativeTypes?: import('./rules/checkTypes.js').CheckNativeTypes|null
* overrideSettings?: import('./iterateJsdoc.js').Settings['preferredTypes']|null,
* description?: string,
* schema?: import('eslint').Rule.RuleMetaData['schema'],
* typeName?: string,
* url?: string,
* }} cfg
* @returns {import('eslint').Rule.RuleModule}
*/
const buildRejectOrPreferRuleDefinition = ({
checkNativeTypes = null,
typeName,
description = typeName ?? 'Reports types deemed invalid (customizable and with defaults, for preventing and/or recommending replacements).',
overrideSettings = null,
schema = [],
url = 'https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/check-types.md#repos-sticky-header'
}) => {
return (0, _iterateJsdoc.default)(({
context,
jsdocNode,
report,
settings,
sourceCode,
utils
}) => {
const jsdocTagsWithPossibleType = utils.filterTags(tag => {
return Boolean(utils.tagMightHaveTypePosition(tag.tag));
});
const
/**
* @type {{
* preferredTypes: import('./iterateJsdoc.js').PreferredTypes,
* structuredTags: import('./iterateJsdoc.js').StructuredTags,
* mode: import('./jsdocUtils.js').ParserMode
* }}
*/
{
mode,
preferredTypes: preferredTypesOriginal,
structuredTags
} = overrideSettings ? {
mode: settings.mode,
preferredTypes: overrideSettings,
structuredTags: {}
} : settings;
const injectObjectPreferredTypes = !overrideSettings && !('Object' in preferredTypesOriginal || 'object' in preferredTypesOriginal || 'object.<>' in preferredTypesOriginal || 'Object.<>' in preferredTypesOriginal || 'object<>' in preferredTypesOriginal);
/** @type {import('./iterateJsdoc.js').PreferredTypes} */
const typeToInject = mode === 'typescript' ? {
Object: 'object',
'object.<>': info,
'Object.<>': infoUC,
'object<>': info,
'Object<>': infoUC
} : {
Object: 'object',
'object.<>': 'Object<>',
'Object.<>': 'Object<>',
'object<>': 'Object<>'
};
/** @type {import('./iterateJsdoc.js').PreferredTypes} */
const preferredTypes = {
...(injectObjectPreferredTypes ? typeToInject : {}),
...preferredTypesOriginal
};
const
/**
* @type {{
* noDefaults: boolean,
* unifyParentAndChildTypeChecks: boolean,
* exemptTagContexts: ({
* tag: string,
* types: true|string[]
* })[]
* }}
*/
{
exemptTagContexts = [],
noDefaults,
unifyParentAndChildTypeChecks
} = context.options[0] || {};
/**
* Gets information about the preferred type: whether there is a matching
* preferred type, what the type is, and whether it is a match to a generic.
* @param {string} _type Not currently in use
* @param {string} typeNodeName
* @param {import('jsdoc-type-pratt-parser').NonRootResult|undefined} parentNode
* @param {string|undefined} property
* @returns {[hasMatchingPreferredType: boolean, typeName: string, isGenericMatch: boolean]}
*/
const getPreferredTypeInfo = (_type, typeNodeName, parentNode, property) => {
let hasMatchingPreferredType = false;
let isGenericMatch = false;
let typName = typeNodeName;
const isNameOfGeneric = parentNode !== undefined && parentNode.type === 'JsdocTypeGeneric' && property === 'left';
const brackets = /** @type {import('jsdoc-type-pratt-parser').GenericResult} */parentNode?.meta?.brackets;
const dot = /** @type {import('jsdoc-type-pratt-parser').GenericResult} */parentNode?.meta?.dot;
if (brackets === 'angle') {
const checkPostFixes = dot ? ['.', '.<>'] : ['<>'];
isGenericMatch = checkPostFixes.some(checkPostFix => {
const preferredType = preferredTypes?.[typeNodeName + checkPostFix];
// Does `unifyParentAndChildTypeChecks` need to be checked here?
if ((unifyParentAndChildTypeChecks || isNameOfGeneric || (/* c8 ignore next 2 -- If checking `unifyParentAndChildTypeChecks` */
typeof preferredType === 'object' && preferredType?.unifyParentAndChildTypeChecks)) && preferredType !== undefined) {
typName += checkPostFix;
return true;
}
return false;
});
}
if (!isGenericMatch && property && /** @type {import('jsdoc-type-pratt-parser').NonRootResult} */parentNode.type === 'JsdocTypeGeneric') {
const checkPostFixes = dot ? ['.', '.<>'] : [brackets === 'angle' ? '<>' : '[]'];
isGenericMatch = checkPostFixes.some(checkPostFix => {
const preferredType = preferredTypes?.[checkPostFix];
if (
// Does `unifyParentAndChildTypeChecks` need to be checked here?
(unifyParentAndChildTypeChecks || isNameOfGeneric || (/* c8 ignore next 2 -- If checking `unifyParentAndChildTypeChecks` */
typeof preferredType === 'object' && preferredType?.unifyParentAndChildTypeChecks)) && preferredType !== undefined) {
typName = checkPostFix;
return true;
}
return false;
});
}
const prefType = preferredTypes?.[typeNodeName];
const directNameMatch = prefType !== undefined && !Object.values(preferredTypes).includes(typeNodeName);
const specificUnify = typeof prefType === 'object' && prefType?.unifyParentAndChildTypeChecks;
const unifiedSyntaxParentMatch = property && directNameMatch && (unifyParentAndChildTypeChecks || specificUnify);
isGenericMatch = isGenericMatch || Boolean(unifiedSyntaxParentMatch);
hasMatchingPreferredType = isGenericMatch || directNameMatch && !property;
return [hasMatchingPreferredType, typName, isGenericMatch];
};
/**
* Collect invalid type info.
* @param {string} type
* @param {string} value
* @param {string} tagName
* @param {string} nameInTag
* @param {number} idx
* @param {string|undefined} property
* @param {import('jsdoc-type-pratt-parser').NonRootResult} node
* @param {import('jsdoc-type-pratt-parser').NonRootResult|undefined} parentNode
* @param {(string|false|undefined)[][]} invalidTypes
* @returns {void}
*/
const getInvalidTypes = (type, value, tagName, nameInTag, idx, property, node, parentNode, invalidTypes) => {
let typeNodeName = type === 'JsdocTypeAny' ? '*' : value;
const [hasMatchingPreferredType, typName, isGenericMatch] = getPreferredTypeInfo(type, typeNodeName, parentNode, property);
let preferred;
let types;
if (hasMatchingPreferredType) {
const preferredSetting = preferredTypes[typName];
typeNodeName = typName === '[]' ? typName : typeNodeName;
if (!preferredSetting) {
invalidTypes.push([typeNodeName]);
} else if (typeof preferredSetting === 'string') {
preferred = preferredSetting;
invalidTypes.push([typeNodeName, preferred]);
} else if (preferredSetting && typeof preferredSetting === 'object') {
const nextItem = preferredSetting.skipRootChecking && jsdocTagsWithPossibleType[idx + 1];
if (!nextItem || !nextItem.name.startsWith(`${nameInTag}.`)) {
preferred = preferredSetting.replacement;
invalidTypes.push([typeNodeName, preferred, preferredSetting.message]);
}
} else {
utils.reportSettings('Invalid `settings.jsdoc.preferredTypes`. Values must be falsy, a string, or an object.');
return;
}
} else if (Object.entries(structuredTags).some(([tag, {
type: typs
}]) => {
types = typs;
return tag === tagName && Array.isArray(types) && !types.includes(typeNodeName);
})) {
invalidTypes.push([typeNodeName, types]);
} else if (checkNativeTypes && !noDefaults && type === 'JsdocTypeName') {
preferred = checkNativeTypes(preferredTypes, typeNodeName, preferred, parentNode, invalidTypes);
}
// For fixer
if (preferred) {
adjustNames(type, preferred, isGenericMatch, typeNodeName, node, parentNode);
}
};
for (const [idx, jsdocTag] of jsdocTagsWithPossibleType.entries()) {
/** @type {(string|false|undefined)[][]} */
const invalidTypes = [];
let typeAst;
try {
typeAst = mode === 'permissive' ? (0, _jsdoccomment.tryParse)(jsdocTag.type) : (0, _jsdoccomment.parse)(jsdocTag.type, mode);
} catch {
continue;
}
const {
name: nameInTag,
tag: tagName
} = jsdocTag;
(0, _jsdoccomment.traverse)(typeAst, (node, parentNode, property) => {
const {
type,
value
} =
/**
* @type {import('jsdoc-type-pratt-parser').NameResult}
*/
node;
if (!['JsdocTypeAny', 'JsdocTypeName'].includes(type)) {
return;
}
getInvalidTypes(type, value, tagName, nameInTag, idx, property, node, parentNode, invalidTypes);
});
if (invalidTypes.length) {
const fixedType = (0, _jsdoccomment.stringify)(typeAst);
/**
* @type {import('eslint').Rule.ReportFixer}
*/
const fix = fixer => {
return fixer.replaceText(jsdocNode, sourceCode.getText(jsdocNode).replace(`{${jsdocTag.type}}`, `{${fixedType}}`));
};
for (const [badType, preferredType = '', msg] of invalidTypes) {
const tagValue = jsdocTag.name ? ` "${jsdocTag.name}"` : '';
if (exemptTagContexts.some(({
tag,
types
}) => {
return tag === tagName && (types === true || types.includes(jsdocTag.type));
})) {
continue;
}
report(msg || `Invalid JSDoc @${tagName}${tagValue} type "${badType}"` + (preferredType ? '; ' : '.') + (preferredType ? `prefer: ${JSON.stringify(preferredType)}.` : ''), preferredType ? fix : null, jsdocTag, msg ? {
tagName,
tagValue
} : undefined);
}
}
}
}, {
iterateAllJsdocs: true,
meta: {
docs: {
description,
url
},
...(!overrideSettings || Object.values(overrideSettings).some(os => {
return os && typeof os === 'object' ? /* c8 ignore next -- Ok */
os.replacement : typeof os === 'string';
}) ? {
fixable: 'code'
} : {}),
schema,
type: 'suggestion'
}
});
};
exports.buildRejectOrPreferRuleDefinition = buildRejectOrPreferRuleDefinition;
//# sourceMappingURL=buildRejectOrPreferRuleDefinition.cjs.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,9 @@
export function buildRejectOrPreferRuleDefinition({ checkNativeTypes, typeName, description, overrideSettings, schema, url, }: {
checkNativeTypes?: import("./rules/checkTypes.js").CheckNativeTypes | null;
overrideSettings?: import("./iterateJsdoc.js").Settings["preferredTypes"] | null;
description?: string;
schema?: import("eslint").Rule.RuleMetaData["schema"];
typeName?: string;
url?: string;
}): import("eslint").Rule.RuleModule;
//# sourceMappingURL=buildRejectOrPreferRuleDefinition.d.ts.map

View file

@ -0,0 +1,16 @@
export default WarnSettings;
declare function WarnSettings(): {
/**
* Warn only once for each context and setting
* @param {import('eslint').Rule.RuleContext} context
* @param {string} setting
* @returns {boolean}
*/
hasBeenWarned(context: import("eslint").Rule.RuleContext, setting: string): boolean;
/**
* @param {import('eslint').Rule.RuleContext} context
* @param {string} setting
* @returns {void}
*/
markSettingAsWarned(context: import("eslint").Rule.RuleContext, setting: string): void;
};

View file

@ -0,0 +1,33 @@
export default alignTransform;
export type TypelessInfo = {
hasNoTypes: boolean;
maxNamedTagLength: import("./iterateJsdoc.js").Integer;
maxUnnamedTagLength: import("./iterateJsdoc.js").Integer;
};
export type Width = {
name: import("./iterateJsdoc.js").Integer;
start: import("./iterateJsdoc.js").Integer;
tag: import("./iterateJsdoc.js").Integer;
type: import("./iterateJsdoc.js").Integer;
};
/**
* @param {{
* customSpacings: import('../src/rules/checkLineAlignment.js').CustomSpacings,
* tags: string[],
* indent: string,
* preserveMainDescriptionPostDelimiter: boolean,
* wrapIndent: string,
* disableWrapIndent: boolean,
* }} cfg
* @returns {(
* block: import('comment-parser').Block
* ) => import('comment-parser').Block}
*/
declare function alignTransform({ customSpacings, disableWrapIndent, indent, preserveMainDescriptionPostDelimiter, tags, wrapIndent, }: {
customSpacings: import("../src/rules/checkLineAlignment.js").CustomSpacings;
tags: string[];
indent: string;
preserveMainDescriptionPostDelimiter: boolean;
wrapIndent: string;
disableWrapIndent: boolean;
}): (block: import("comment-parser").Block) => import("comment-parser").Block;

View file

@ -0,0 +1,14 @@
export function buildForbidRuleDefinition({ contextName, contexts: cntxts, description, getContexts, modifyContext, schema, url, }: {
contexts?: Contexts;
description?: string;
getContexts?: (ctxt: import("eslint").Rule.RuleContext, report: import("./iterateJsdoc.js").Report) => Contexts | false;
contextName?: string;
modifyContext?: (context: import("eslint").Rule.RuleContext) => import("eslint").Rule.RuleContext;
schema?: import("eslint").Rule.RuleMetaData["schema"];
url?: string;
}): import("eslint").Rule.RuleModule;
export type Contexts = (string | {
comment: string;
context: string;
message?: string;
})[];

View file

@ -0,0 +1,8 @@
export function buildRejectOrPreferRuleDefinition({ checkNativeTypes, typeName, description, overrideSettings, schema, url, }: {
checkNativeTypes?: import("./rules/checkTypes.js").CheckNativeTypes | null;
overrideSettings?: import("./iterateJsdoc.js").Settings["preferredTypes"] | null;
description?: string;
schema?: import("eslint").Rule.RuleMetaData["schema"];
typeName?: string;
url?: string;
}): import("eslint").Rule.RuleModule;

View file

@ -0,0 +1,4 @@
export default defaultTagOrder;
declare const defaultTagOrder: {
tags: string[];
}[];

View file

@ -0,0 +1,40 @@
declare namespace _default {
export { isUncommentedExport };
export { parse };
}
export default _default;
export type ValueObject = {
value: string;
};
export type CreatedNode = {
type?: string;
value?: ValueObject | import("eslint").Rule.Node | import("@typescript-eslint/types").TSESTree.Node;
props: {
[key: string]: CreatedNode | null;
};
special?: true;
globalVars?: CreatedNode;
exported?: boolean;
ANONYMOUS_DEFAULT?: import("eslint").Rule.Node;
};
export type CreateSymbol = (node: import("eslint").Rule.Node | null, globals: CreatedNode, value: import("eslint").Rule.Node | import("@typescript-eslint/types").TSESTree.Node | null, scope?: CreatedNode | undefined, isGlobal?: boolean | SymbolOptions | undefined) => CreatedNode | null;
export type SymbolOptions = {
simpleIdentifier?: boolean;
};
/**
*
* @param {import('eslint').Rule.Node} node
* @param {import('eslint').SourceCode} sourceCode
* @param {import('./rules/requireJsdoc.js').RequireJsdocOpts} opt
* @param {import('./iterateJsdoc.js').Settings} settings
* @returns {boolean}
*/
declare function isUncommentedExport(node: import("eslint").Rule.Node, sourceCode: import("eslint").SourceCode, opt: import("./rules/requireJsdoc.js").RequireJsdocOpts, settings: import("./iterateJsdoc.js").Settings): boolean;
/**
*
* @param {import('eslint').Rule.Node} ast
* @param {import('eslint').Rule.Node} node
* @param {import('./rules/requireJsdoc.js').RequireJsdocOpts} opt
* @returns {CreatedNode}
*/
declare function parse(ast: import("eslint").Rule.Node, node: import("eslint").Rule.Node, opt: import("./rules/requireJsdoc.js").RequireJsdocOpts): CreatedNode;

View file

@ -0,0 +1,10 @@
export default getDefaultTagStructureForMode;
export type TagStructure = Map<string, Map<string, (string | boolean)>>;
/**
* @typedef {Map<string, Map<string, (string|boolean)>>} TagStructure
*/
/**
* @param {import('./jsdocUtils.js').ParserMode} mode
* @returns {TagStructure}
*/
declare function getDefaultTagStructureForMode(mode: import("./jsdocUtils.js").ParserMode): TagStructure;

View file

@ -0,0 +1,5 @@
import { getJsdocProcessorPlugin } from './getJsdocProcessorPlugin.js';
declare const _default: {
getJsdocProcessorPlugin: typeof getJsdocProcessorPlugin;
};
export = _default;

View file

@ -0,0 +1,66 @@
export function getJsdocProcessorPlugin(options?: JsdocProcessorOptions): ESLint.Plugin;
export type Integer = number;
export type JsdocProcessorOptions = {
/**
* Require captions for example tags
*/
captionRequired?: boolean | undefined;
/**
* See docs
*/
paddedIndent?: number | undefined;
/**
* See docs
*/
checkDefaults?: boolean | undefined;
/**
* See docs
*/
checkParams?: boolean | undefined;
/**
* See docs
*/
checkExamples?: boolean | undefined;
/**
* See docs
*/
checkProperties?: boolean | undefined;
/**
* See docs
*/
matchingFileName?: string | undefined;
/**
* See docs
*/
matchingFileNameDefaults?: string | undefined;
/**
* See docs
*/
matchingFileNameParams?: string | undefined;
/**
* See docs
*/
matchingFileNameProperties?: string | undefined;
/**
* See docs
*/
exampleCodeRegex?: string | RegExp | undefined;
/**
* See docs
*/
rejectExampleCodeRegex?: string | RegExp | undefined;
/**
* See docs
*/
allowedLanguagesToProcess?: string[] | undefined;
/**
* See docs
*/
sourceType?: "module" | "script" | undefined;
/**
* See docs
*/
parser?: Linter.ESTreeParser | Linter.NonESTreeParser | undefined;
};
import type { ESLint } from 'eslint';
import type { Linter } from 'eslint';

View file

@ -0,0 +1,23 @@
export default index;
export type ConfigGroups = "recommended" | "stylistic" | "contents" | "logical" | "requirements";
export type ConfigVariants = "" | "-typescript" | "-typescript-flavor";
export type ErrorLevelVariants = "" | "-error";
/**
* @typedef {"recommended" | "stylistic" | "contents" | "logical" | "requirements"} ConfigGroups
* @typedef {"" | "-typescript" | "-typescript-flavor"} ConfigVariants
* @typedef {"" | "-error"} ErrorLevelVariants
* @type {import('eslint').ESLint.Plugin & {
* configs: Record<
* `flat/${ConfigGroups}${ConfigVariants}${ErrorLevelVariants}`,
* import('eslint').Linter.Config
* > &
* Record<
* "examples"|"default-expressions"|"examples-and-default-expressions",
* import('eslint').Linter.Config[]
* > &
* Record<"flat/recommended-mixed", import('eslint').Linter.Config[]>
* }}
*/
declare const index: import("eslint").ESLint.Plugin & {
configs: Record<`flat/${ConfigGroups}${ConfigVariants}${ErrorLevelVariants}`, import("eslint").Linter.Config> & Record<"examples" | "default-expressions" | "examples-and-default-expressions", import("eslint").Linter.Config[]> & Record<"flat/recommended-mixed", import("eslint").Linter.Config[]>;
};

View file

@ -0,0 +1,2 @@
import items from './index-cjs.js';
export = items;

View file

@ -0,0 +1,7 @@
import iterateJsdoc, { getSettings, parseComment } from './iterateJsdoc.js';
declare const _default: {
default: typeof iterateJsdoc;
getSettings: typeof getSettings;
parseComment: typeof parseComment;
};
export = _default;

View file

@ -0,0 +1,491 @@
/**
* @param {JsdocVisitor} iterator
* @param {RuleConfig} ruleConfig
* @returns {import('eslint').Rule.RuleModule}
*/
export default function iterateJsdoc(iterator: JsdocVisitor, ruleConfig: RuleConfig): import("eslint").Rule.RuleModule;
export { parseComment } from "@es-joy/jsdoccomment";
export type Integer = number;
export type JsdocBlockWithInline = import("@es-joy/jsdoccomment").JsdocBlockWithInline;
export type ContextObject = {
disallowName?: string;
allowName?: string;
context?: string;
comment?: string;
tags?: string[];
replacement?: string;
minimum?: Integer;
message?: string;
forceRequireReturn?: boolean;
};
export type Context = string | ContextObject;
export type CheckJsdoc = (info: {
lastIndex?: Integer;
isFunctionContext?: boolean;
selector?: string;
comment?: string;
}, handler: null | ((jsdoc: import("@es-joy/jsdoccomment").JsdocBlockWithInline) => boolean | undefined), node: import("eslint").Rule.Node) => void;
export type ForEachPreferredTag = (tagName: string, arrayHandler: (matchingJsdocTag: import("@es-joy/jsdoccomment").JsdocTagWithInline, targetTagName: string) => void, skipReportingBlockedTag?: boolean | undefined) => void;
export type ReportSettings = (message: string) => void;
export type ParseClosureTemplateTag = (tag: import("comment-parser").Spec) => string[];
export type GetPreferredTagNameObject = (cfg: {
tagName: string;
}) => string | false | {
message: string;
replacement?: string | undefined;
} | {
blocked: true;
tagName: string;
};
export type BasicUtils = {
forEachPreferredTag: ForEachPreferredTag;
reportSettings: ReportSettings;
parseClosureTemplateTag: ParseClosureTemplateTag;
getPreferredTagNameObject: GetPreferredTagNameObject;
pathDoesNotBeginWith: import("./jsdocUtils.js").PathDoesNotBeginWith;
isNameOrNamepathDefiningTag: IsNamepathX;
isNamepathReferencingTag: IsNamepathX;
isNamepathOrUrlReferencingTag: IsNamepathX;
tagMightHaveNameOrNamepath: IsNamepathX;
tagMightHaveName: IsNamepathX;
};
export type IsIteratingFunction = () => boolean;
export type IsVirtualFunction = () => boolean;
export type Stringify = (tagBlock: import("comment-parser").Block, specRewire?: boolean | undefined) => string;
export type ReportJSDoc = (msg: string, tag?: import("comment-parser").Spec | {
line: Integer;
column?: Integer;
} | null | undefined, handler?: ((fixer: import("eslint").Rule.RuleFixer) => import("eslint").Rule.Fix | void) | null | undefined, specRewire?: boolean | undefined, data?: undefined | {
[key: string]: string;
}) => any;
export type GetRegexFromString = (str: string, requiredFlags?: string | undefined) => RegExp;
export type GetTagDescription = (tg: import("comment-parser").Spec, returnArray?: boolean | undefined) => string[] | string;
export type SetTagDescription = (tg: import("comment-parser").Spec, matcher: RegExp, setter: (description: string) => string) => Integer;
export type GetDescription = () => {
description: string;
descriptions: string[];
lastDescriptionLine: Integer;
};
export type SetBlockDescription = (setter: (info: {
delimiter: string;
postDelimiter: string;
start: string;
}, seedTokens: (tokens?: Partial<import("comment-parser").Tokens>) => import("comment-parser").Tokens, descLines: string[], postDelims: string[]) => import("comment-parser").Line[]) => void;
export type SetDescriptionLines = (matcher: RegExp, setter: (description: string) => string) => Integer;
export type ChangeTag = (tag: import("comment-parser").Spec, ...tokens: Partial<import("comment-parser").Tokens>[]) => void;
export type SetTag = (tag: import("comment-parser").Spec & {
line: Integer;
}, tokens?: Partial<import("comment-parser").Tokens> | undefined) => void;
export type RemoveTag = (tagIndex: Integer, cfg?: {
removeEmptyBlock?: boolean;
tagSourceOffset?: Integer;
} | undefined) => void;
export type AddTag = (targetTagName: string, number?: number | undefined, tokens?: Partial<import("comment-parser").Tokens> | undefined) => void;
export type GetFirstLine = () => Integer | undefined;
export type SeedTokens = (tokens?: Partial<import("comment-parser").Tokens> | undefined) => import("comment-parser").Tokens;
/**
* Sets tokens to empty string.
*/
export type EmptyTokens = (tokens: import("comment-parser").Tokens) => void;
export type AddLine = (sourceIndex: Integer, tokens: Partial<import("comment-parser").Tokens>) => void;
export type AddLines = (tagIndex: Integer, tagSourceOffset: Integer, numLines: Integer) => void;
export type MakeMultiline = () => void;
export type GetFunctionParameterNames = (useDefaultObjectProperties?: boolean | undefined, ignoreInterfacedParameters?: boolean | undefined) => import("./jsdocUtils.js").ParamNameInfo[];
export type HasParams = () => Integer;
export type IsGenerator = () => boolean;
export type IsConstructor = () => boolean;
export type GetJsdocTagsDeep = (tagName: string) => false | {
idx: Integer;
name: string;
type: string;
}[];
export type GetPreferredTagName = (cfg: {
tagName: string;
skipReportingBlockedTag?: boolean;
allowObjectReturn?: boolean;
defaultMessage?: string;
}) => string | undefined | false | {
message: string;
replacement?: string | undefined;
} | {
blocked: true;
tagName: string;
};
export type IsValidTag = (name: string, definedTags: string[]) => boolean;
export type HasATag = (names: string[]) => boolean;
export type HasTag = (name: string) => boolean;
export type ComparePaths = (name: string) => (otherPathName: string) => boolean;
export type DropPathSegmentQuotes = (name: string) => string;
export type AvoidDocs = () => boolean;
export type TagMightHaveNamePositionTypePosition = (tagName: string, otherModeMaps?: import("./getDefaultTagStructureForMode.js").TagStructure[] | undefined) => boolean | {
otherMode: true;
};
export type TagMustHave = (tagName: string, otherModeMaps: import("./getDefaultTagStructureForMode.js").TagStructure[]) => boolean | {
otherMode: false;
};
export type TagMissingRequiredTypeOrNamepath = (tag: import("comment-parser").Spec, otherModeMaps: import("./getDefaultTagStructureForMode.js").TagStructure[]) => boolean | {
otherMode: false;
};
export type IsNamepathX = (tagName: string) => boolean;
export type GetTagStructureForMode = (mde: import("./jsdocUtils.js").ParserMode) => import("./getDefaultTagStructureForMode.js").TagStructure;
export type MayBeUndefinedTypeTag = (tag: import("comment-parser").Spec) => boolean;
export type HasValueOrExecutorHasNonEmptyResolveValue = (anyPromiseAsReturn: boolean, allBranches?: boolean | undefined) => boolean;
export type HasYieldValue = () => boolean;
export type HasYieldReturnValue = () => boolean;
export type HasThrowValue = () => boolean;
export type IsAsync = () => boolean | undefined;
export type GetTags = (tagName: string) => import("comment-parser").Spec[];
export type GetPresentTags = (tagList: string[]) => import("@es-joy/jsdoccomment").JsdocTagWithInline[];
export type FilterTags = (filter: (tag: import("@es-joy/jsdoccomment").JsdocTagWithInline) => boolean) => import("@es-joy/jsdoccomment").JsdocTagWithInline[];
export type FilterAllTags = (filter: (tag: (import("comment-parser").Spec | import("@es-joy/jsdoccomment").JsdocInlineTagNoType)) => boolean) => (import("comment-parser").Spec | import("@es-joy/jsdoccomment").JsdocInlineTagNoType)[];
export type getInlineTags = () => (import("comment-parser").Spec | (import("@es-joy/jsdoccomment").JsdocInlineTagNoType & {
line?: number | undefined;
column?: number | undefined;
}))[];
export type GetTagsByType = (tags: import("comment-parser").Spec[]) => {
tagsWithNames: import("comment-parser").Spec[];
tagsWithoutNames: import("comment-parser").Spec[];
};
export type HasOptionTag = (tagName: string) => boolean;
export type GetClassNode = () => Node | null;
export type GetClassJsdoc = () => null | JsdocBlockWithInline;
export type ClassHasTag = (tagName: string) => boolean;
export type FindContext = (contexts: Context[], comment: string | undefined) => {
foundContext: Context | undefined;
contextStr: string;
};
export type Utils = BasicUtils & {
isIteratingFunction: IsIteratingFunction;
isIteratingFunctionOrVariable: IsIteratingFunction;
isVirtualFunction: IsVirtualFunction;
stringify: Stringify;
reportJSDoc: ReportJSDoc;
getRegexFromString: GetRegexFromString;
getTagDescription: GetTagDescription;
setTagDescription: SetTagDescription;
getDescription: GetDescription;
setBlockDescription: SetBlockDescription;
setDescriptionLines: SetDescriptionLines;
changeTag: ChangeTag;
setTag: SetTag;
removeTag: RemoveTag;
addTag: AddTag;
getFirstLine: GetFirstLine;
seedTokens: SeedTokens;
emptyTokens: EmptyTokens;
addLine: AddLine;
addLines: AddLines;
makeMultiline: MakeMultiline;
flattenRoots: import("./jsdocUtils.js").FlattenRoots;
getFunctionParameterNames: GetFunctionParameterNames;
hasParams: HasParams;
isGenerator: IsGenerator;
isConstructor: IsConstructor;
getJsdocTagsDeep: GetJsdocTagsDeep;
getPreferredTagName: GetPreferredTagName;
isValidTag: IsValidTag;
hasATag: HasATag;
hasTag: HasTag;
comparePaths: ComparePaths;
dropPathSegmentQuotes: DropPathSegmentQuotes;
avoidDocs: AvoidDocs;
tagMightHaveNamePosition: TagMightHaveNamePositionTypePosition;
tagMightHaveTypePosition: TagMightHaveNamePositionTypePosition;
tagMustHaveNamePosition: TagMustHave;
tagMustHaveTypePosition: TagMustHave;
tagMissingRequiredTypeOrNamepath: TagMissingRequiredTypeOrNamepath;
isNameOrNamepathDefiningTag: IsNamepathX;
isNamepathReferencingTag: IsNamepathX;
isNamepathOrUrlReferencingTag: IsNamepathX;
tagMightHaveNameOrNamepath: IsNamepathX;
tagMightHaveName: IsNamepathX;
tagMightHaveNamepath: IsNamepathX;
getTagStructureForMode: GetTagStructureForMode;
mayBeUndefinedTypeTag: MayBeUndefinedTypeTag;
hasValueOrExecutorHasNonEmptyResolveValue: HasValueOrExecutorHasNonEmptyResolveValue;
hasYieldValue: HasYieldValue;
hasYieldReturnValue: HasYieldReturnValue;
hasThrowValue: HasThrowValue;
isAsync: IsAsync;
getTags: GetTags;
getPresentTags: GetPresentTags;
filterTags: FilterTags;
filterAllTags: FilterAllTags;
getInlineTags: getInlineTags;
getTagsByType: GetTagsByType;
hasOptionTag: HasOptionTag;
getClassNode: GetClassNode;
getClassJsdoc: GetClassJsdoc;
classHasTag: ClassHasTag;
findContext: FindContext;
};
/**
* Should use ESLint rule's typing.
*/
export type EslintRuleMeta = import("eslint").Rule.RuleMetaData;
/**
* A plain object for tracking state as needed by rules across iterations.
*/
export type StateObject = {
globalTags: boolean;
hasDuplicates: {
[key: string]: boolean;
};
selectorMap: {
[selector: string]: {
[comment: string]: Integer;
};
};
hasTag: {
[key: string]: boolean;
};
hasNonComment: number;
hasNonCommentBeforeTag: {
[key: string]: boolean | number;
};
foundTypedefValues: string[];
};
/**
* The Node AST as supplied by the parser.
*/
export type Node = import("eslint").Rule.Node;
export type Report = (message: string, fix?: import("@eslint/core").RuleFixer | null | undefined, jsdocLoc?: {
line?: Integer;
column?: Integer;
} | (import("comment-parser").Spec & {
line?: Integer;
}) | null | undefined, data?: undefined | {
[key: string]: string;
}) => void;
export type PreferredTypes = {
[key: string]: false | string | {
message: string;
replacement?: false | string;
skipRootChecking?: boolean;
unifyParentAndChildTypeChecks?: boolean;
};
};
export type StructuredTags = {
[key: string]: {
name?: "text" | "name-defining" | "namepath-defining" | "namepath-referencing" | false;
type?: boolean | string[];
required?: ("name" | "type" | "typeOrNameRequired")[];
};
};
/**
* Settings from ESLint types.
*/
export type Settings = {
maxLines: Integer;
minLines: Integer;
tagNamePreference: import("./jsdocUtils.js").TagNamePreference;
mode: import("./jsdocUtils.js").ParserMode;
preferredTypes: PreferredTypes;
structuredTags: StructuredTags;
contexts?: Context[];
augmentsExtendsReplacesDocs?: boolean;
ignoreReplacesDocs?: boolean;
implementsReplacesDocs?: boolean;
overrideReplacesDocs?: boolean;
ignoreInternal?: boolean;
ignorePrivate?: boolean;
exemptDestructuredRootsFromChecks?: boolean;
};
export type JSDocSettings = {
settings?: {
jsdoc?: {
ignorePrivate: boolean;
ignoreInternal: boolean;
maxLines: Integer;
minLines: Integer;
tagNamePreference: import("./jsdocUtils.js").TagNamePreference;
preferredTypes: PreferredTypes;
structuredTags: StructuredTags;
overrideReplacesDocs: boolean;
ignoreReplacesDocs: boolean;
implementsReplacesDocs: boolean;
augmentsExtendsReplacesDocs: boolean;
exemptDestructuredRootsFromChecks: boolean;
mode: import("./jsdocUtils.js").ParserMode;
contexts: Context[];
};
};
};
/**
* Create the report function
*/
export type MakeReport = (context: import("eslint").Rule.RuleContext, commentNode: import("estree").Node) => Report;
export type JsdocVisitorBasic = (arg: {
context: import("eslint").Rule.RuleContext;
sourceCode: import("eslint").SourceCode;
indent?: string;
info?: {
comment?: string | undefined;
lastIndex?: Integer | undefined;
};
state?: StateObject;
globalState?: Map<string, Map<string, string>>;
jsdoc?: JsdocBlockWithInline;
jsdocNode?: import("eslint").Rule.Node & {
range: [number, number];
};
node?: Node;
allComments?: import("estree").Node[];
report?: Report;
makeReport?: MakeReport;
settings: Settings;
utils: BasicUtils;
}) => void;
export type JsdocVisitor = (arg: {
context: import("eslint").Rule.RuleContext;
sourceCode: import("eslint").SourceCode;
indent: string;
info: {
comment?: string | undefined;
lastIndex?: Integer | undefined;
};
state: StateObject;
globalState: Map<string, Map<string, string>>;
jsdoc: JsdocBlockWithInline;
jsdocNode: import("eslint").Rule.Node & {
range: [number, number];
};
node: Node | null;
allComments?: import("estree").Node[];
report: Report;
makeReport?: MakeReport;
settings: Settings;
utils: Utils;
}) => void;
export type NonCommentArgs = {
node: Node;
state: StateObject;
};
export type RuleConfig = {
/**
* ESLint rule meta
*/
meta: EslintRuleMeta;
/**
* Any default contexts
*/
contextDefaults?: jsdocUtils.DefaultContexts | undefined;
/**
* Whether to force a `contexts` check
*/
contextSelected?: true | undefined;
/**
* Modify the rule's context object
*/
modifyContext?: ((context: import("eslint").Rule.RuleContext) => import("eslint").Rule.RuleContext) | undefined;
/**
* Whether to iterate all JSDoc blocks by default
* regardless of context
*/
iterateAllJsdocs?: true | undefined;
/**
* Whether to check `@private` blocks (normally exempted)
*/
checkPrivate?: true | undefined;
/**
* Whether to check `@internal` blocks (normally exempted)
*/
checkInternal?: true | undefined;
/**
* Whether to iterates over all JSDoc blocks regardless of attachment
*/
checkFile?: true | undefined;
/**
* Whether to avoid relying on settings for global contexts
*/
nonGlobalSettings?: true | undefined;
/**
* Whether to disable the tracking of visited comment nodes (as
* non-tracked may conduct further actions)
*/
noTracking?: true | undefined;
/**
* Whether the rule expects contexts to be based on a match option
*/
matchContext?: true | undefined;
/**
* Handler to be executed upon exiting iteration of program AST
*/
exit?: ((args: {
context: import("eslint").Rule.RuleContext;
state: StateObject;
settings: Settings;
utils: BasicUtils;
}) => void) | undefined;
/**
* Handler to be executed if rule wishes
* to be supplied nodes without comments
*/
nonComment?: ((nca: NonCommentArgs) => void) | undefined;
};
/**
* @typedef {{
* [key: string]: false|string|{
* message: string,
* replacement?: false|string
* skipRootChecking?: boolean
* unifyParentAndChildTypeChecks?: boolean
* }
* }} PreferredTypes
*/
/**
* @typedef {{
* [key: string]: {
* name?: "text"|"name-defining"|"namepath-defining"|"namepath-referencing"|false,
* type?: boolean|string[],
* required?: ("name"|"type"|"typeOrNameRequired")[]
* }
* }} StructuredTags
*/
/**
* Settings from ESLint types.
* @typedef {{
* maxLines: Integer,
* minLines: Integer,
* tagNamePreference: import('./jsdocUtils.js').TagNamePreference,
* mode: import('./jsdocUtils.js').ParserMode,
* preferredTypes: PreferredTypes,
* structuredTags: StructuredTags,
* contexts?: Context[],
* augmentsExtendsReplacesDocs?: boolean,
* ignoreReplacesDocs?: boolean,
* implementsReplacesDocs?: boolean,
* overrideReplacesDocs?: boolean,
* ignoreInternal?: boolean,
* ignorePrivate?: boolean,
* exemptDestructuredRootsFromChecks?: boolean,
* }} Settings
*/
/**
* @typedef {{
* settings?: {
* jsdoc?: {
* ignorePrivate: boolean,
* ignoreInternal: boolean,
* maxLines: Integer,
* minLines: Integer,
* tagNamePreference: import('./jsdocUtils.js').TagNamePreference,
* preferredTypes: PreferredTypes,
* structuredTags: StructuredTags,
* overrideReplacesDocs: boolean,
* ignoreReplacesDocs: boolean,
* implementsReplacesDocs: boolean,
* augmentsExtendsReplacesDocs: boolean,
* exemptDestructuredRootsFromChecks: boolean,
* mode: import('./jsdocUtils.js').ParserMode,
* contexts: Context[],
* }
* }
* }} JSDocSettings
*/
/**
* @param {import('eslint').Rule.RuleContext & JSDocSettings} context
* @returns {Settings|false}
*/
export function getSettings(context: import("eslint").Rule.RuleContext & JSDocSettings): Settings | false;
import * as jsdocUtils from './jsdocUtils.js';

View file

@ -0,0 +1,493 @@
export type Integer = number;
export type ESTreeOrTypeScriptNode = import("./utils/hasReturnValue.js").ESTreeOrTypeScriptNode;
export type ParserMode = "jsdoc" | "typescript" | "closure" | "permissive";
export type ParamCommon = undefined | string | {
name: Integer;
restElement: boolean;
} | {
isRestProperty: boolean | undefined;
name: string;
restElement: boolean;
} | {
name: string;
restElement: boolean;
};
export type ParamNameInfo = ParamCommon | [string | undefined, (FlattendRootInfo & {
annotationParamName?: string;
})] | NestedParamInfo;
export type FlattendRootInfo = {
hasPropertyRest: boolean;
hasRestElement: boolean;
names: string[];
rests: boolean[];
};
export type NestedParamInfo = [string, (string[] | ParamInfo[])];
export type ParamInfo = ParamCommon | [string | undefined, (FlattendRootInfo & {
annotationParamName?: string;
})] | NestedParamInfo;
/**
* Given a nested array of property names, reduce them to a single array,
* appending the name of the root element along the way if present.
*/
export type FlattenRoots = (params: ParamInfo[], root?: string | undefined) => FlattendRootInfo;
export type Reporter = {
report: (descriptor: import("eslint").Rule.ReportDescriptor) => void;
};
export type DefaultContexts = true | string[];
export type TagNamePreference = {
[key: string]: false | string | {
message: string;
replacement?: string;
};
};
export type PathDoesNotBeginWith = (name: string, otherPathName: string) => boolean;
/**
* @param {string} name
* @returns {(otherPathName: string) => boolean}
*/
export function comparePaths(name: string): (otherPathName: string) => boolean;
/**
* Since path segments may be unquoted (if matching a reserved word,
* identifier or numeric literal) or single or double quoted, in either
* the `@param` or in source, we need to strip the quotes to give a fair
* comparison.
* @param {string} str
* @returns {string}
*/
export function dropPathSegmentQuotes(str: string): string;
/**
* @typedef {true|string[]} DefaultContexts
*/
/**
* Checks user option for `contexts` array, defaulting to
* contexts designated by the rule. Returns an array of
* ESTree AST types, indicating allowable contexts.
* @param {import('eslint').Rule.RuleContext} context
* @param {DefaultContexts|undefined} defaultContexts
* @param {{
* contexts?: import('./iterateJsdoc.js').Context[]
* }} settings
* @returns {(string|import('./iterateJsdoc.js').ContextObject)[]}
*/
export function enforcedContexts(context: import("eslint").Rule.RuleContext, defaultContexts: DefaultContexts | undefined, settings: {
contexts?: import("./iterateJsdoc.js").Context[];
}): (string | import("./iterateJsdoc.js").ContextObject)[];
/**
* @param {import('./iterateJsdoc.js').JsdocBlockWithInline} jsdoc
* @param {import('eslint').Rule.Node|null} node
* @param {import('eslint').Rule.RuleContext} context
* @param {import('json-schema').JSONSchema4} schema
* @returns {boolean}
*/
export function exemptSpeciaMethods(jsdoc: import("./iterateJsdoc.js").JsdocBlockWithInline, node: import("eslint").Rule.Node | null, context: import("eslint").Rule.RuleContext, schema: import("json-schema").JSONSchema4): boolean;
/**
* @param {import('./iterateJsdoc.js').JsdocBlockWithInline} jsdoc
* @param {(tag: import('@es-joy/jsdoccomment').JsdocTagWithInline) => boolean} filter
* @returns {import('@es-joy/jsdoccomment').JsdocTagWithInline[]}
*/
export function filterTags(jsdoc: import("./iterateJsdoc.js").JsdocBlockWithInline, filter: (tag: import("@es-joy/jsdoccomment").JsdocTagWithInline) => boolean): import("@es-joy/jsdoccomment").JsdocTagWithInline[];
/**
* @typedef {undefined|string|{
* name: Integer,
* restElement: boolean
* }|{
* isRestProperty: boolean|undefined,
* name: string,
* restElement: boolean
* }|{
* name: string,
* restElement: boolean
* }} ParamCommon
*/
/**
* @typedef {ParamCommon|[string|undefined, (FlattendRootInfo & {
* annotationParamName?: string,
* })]|NestedParamInfo} ParamNameInfo
*/
/**
* @typedef {{
* hasPropertyRest: boolean,
* hasRestElement: boolean,
* names: string[],
* rests: boolean[],
* }} FlattendRootInfo
*/
/**
* @typedef {[string, (string[]|ParamInfo[])]} NestedParamInfo
*/
/**
* @typedef {ParamCommon|
* [string|undefined, (FlattendRootInfo & {
* annotationParamName?: string
* })]|
* NestedParamInfo} ParamInfo
*/
/**
* Given a nested array of property names, reduce them to a single array,
* appending the name of the root element along the way if present.
* @callback FlattenRoots
* @param {ParamInfo[]} params
* @param {string} [root]
* @returns {FlattendRootInfo}
*/
/** @type {FlattenRoots} */
export const flattenRoots: FlattenRoots;
/**
* @param {import('./iterateJsdoc.js').JsdocBlockWithInline} jsdoc
* @param {string} tagName
* @param {(
* matchingJsdocTag: import('@es-joy/jsdoccomment').JsdocTagWithInline,
* targetTagName: string
* ) => void} arrayHandler
* @param {object} cfg
* @param {import('eslint').Rule.RuleContext} [cfg.context]
* @param {ParserMode} [cfg.mode]
* @param {import('./iterateJsdoc.js').Report} [cfg.report]
* @param {TagNamePreference} [cfg.tagNamePreference]
* @param {boolean} [cfg.skipReportingBlockedTag]
* @returns {void}
*/
export function forEachPreferredTag(jsdoc: import("./iterateJsdoc.js").JsdocBlockWithInline, tagName: string, arrayHandler: (matchingJsdocTag: import("@es-joy/jsdoccomment").JsdocTagWithInline, targetTagName: string) => void, { context, mode, report, skipReportingBlockedTag, tagNamePreference, }?: {
context?: import("eslint").Rule.RuleContext | undefined;
mode?: ParserMode | undefined;
report?: import("./iterateJsdoc.js").Report | undefined;
tagNamePreference?: TagNamePreference | undefined;
skipReportingBlockedTag?: boolean | undefined;
}): void;
/**
* Get all tags, inline tags and inline tags in tags
* @param {import('./iterateJsdoc.js').JsdocBlockWithInline} jsdoc
* @returns {(import('comment-parser').Spec|
* import('@es-joy/jsdoccomment').JsdocInlineTagNoType & {
* line?: number | undefined; column?: number | undefined;
* })[]}
*/
export function getAllTags(jsdoc: import("./iterateJsdoc.js").JsdocBlockWithInline): (import("comment-parser").Spec | (import("@es-joy/jsdoccomment").JsdocInlineTagNoType & {
line?: number | undefined;
column?: number | undefined;
}))[];
/**
* @param {import('./iterateJsdoc.js').Context[]} contexts
* @param {import('./iterateJsdoc.js').CheckJsdoc} checkJsdoc
* @param {import('@es-joy/jsdoccomment').CommentHandler} [handler]
* @returns {import('eslint').Rule.RuleListener}
*/
export function getContextObject(contexts: import("./iterateJsdoc.js").Context[], checkJsdoc: import("./iterateJsdoc.js").CheckJsdoc, handler?: import("@es-joy/jsdoccomment").CommentHandler): import("eslint").Rule.RuleListener;
/**
* @param {ESTreeOrTypeScriptNode|null} functionNode
* @param {boolean} [checkDefaultObjects]
* @param {boolean} [ignoreInterfacedParameters]
* @throws {Error}
* @returns {ParamNameInfo[]}
*/
export function getFunctionParameterNames(functionNode: ESTreeOrTypeScriptNode | null, checkDefaultObjects?: boolean, ignoreInterfacedParameters?: boolean): ParamNameInfo[];
/**
* @param {import('eslint').SourceCode|{
* text: string
* }} sourceCode
* @returns {string}
*/
export function getIndent(sourceCode: import("eslint").SourceCode | {
text: string;
}): string;
/**
* Get all inline tags and inline tags in tags
* @param {import('./iterateJsdoc.js').JsdocBlockWithInline} jsdoc
* @returns {(import('comment-parser').Spec|
* import('@es-joy/jsdoccomment').JsdocInlineTagNoType & {
* line?: number | undefined; column?: number | undefined;
* })[]}
*/
export function getInlineTags(jsdoc: import("./iterateJsdoc.js").JsdocBlockWithInline): (import("comment-parser").Spec | (import("@es-joy/jsdoccomment").JsdocInlineTagNoType & {
line?: number | undefined;
column?: number | undefined;
}))[];
/**
* Gets all names of the target type, including those that refer to a path, e.g.
* `foo` or `foo.bar`.
* @param {import('comment-parser').Block} jsdoc
* @param {string} targetTagName
* @returns {{
* idx: Integer,
* name: string,
* type: string
* }[]}
*/
export function getJsdocTagsDeep(jsdoc: import("comment-parser").Block, targetTagName: string): {
idx: Integer;
name: string;
type: string;
}[];
/**
* @param {import('./iterateJsdoc.js').JsdocBlockWithInline} jsdoc
* @param {{
* tagName: string,
* context?: import('eslint').Rule.RuleContext,
* mode?: ParserMode,
* report?: import('./iterateJsdoc.js').Report
* tagNamePreference?: TagNamePreference
* skipReportingBlockedTag?: boolean,
* allowObjectReturn?: boolean,
* defaultMessage?: string,
* }} cfg
* @returns {string|undefined|false|{
* message: string;
* replacement?: string|undefined;
* }|{
* blocked: true,
* tagName: string
* }}
*/
export function getPreferredTagName(jsdoc: import("./iterateJsdoc.js").JsdocBlockWithInline, { allowObjectReturn, context, tagName, defaultMessage, mode, report, skipReportingBlockedTag, tagNamePreference, }: {
tagName: string;
context?: import("eslint").Rule.RuleContext;
mode?: ParserMode;
report?: import("./iterateJsdoc.js").Report;
tagNamePreference?: TagNamePreference;
skipReportingBlockedTag?: boolean;
allowObjectReturn?: boolean;
defaultMessage?: string;
}): string | undefined | false | {
message: string;
replacement?: string | undefined;
} | {
blocked: true;
tagName: string;
};
/**
* @typedef {{
* report: (descriptor: import('eslint').Rule.ReportDescriptor) => void
* }} Reporter
*/
/**
* @param {string} name
* @param {ParserMode|undefined} mode
* @param {TagNamePreference} tagPreference
* @param {import('eslint').Rule.RuleContext} context
* @returns {string|false|{
* message: string;
* replacement?: string|undefined;
* }}
*/
export function getPreferredTagNameSimple(name: string, mode: ParserMode | undefined, tagPreference?: TagNamePreference, context?: import("eslint").Rule.RuleContext): string | false | {
message: string;
replacement?: string | undefined;
};
/**
* @param {string} regexString
* @param {string} [requiredFlags]
* @returns {RegExp}
*/
export function getRegexFromString(regexString: string, requiredFlags?: string): RegExp;
/**
* @param {import('comment-parser').Spec} tg
* @param {boolean} [returnArray]
* @returns {string[]|string}
*/
export function getTagDescription(tg: import("comment-parser").Spec, returnArray?: boolean): string[] | string;
/**
* @param {import('./iterateJsdoc.js').JsdocBlockWithInline} jsdoc
* @param {string} tagName
* @returns {import('comment-parser').Spec[]}
*/
export function getTags(jsdoc: import("./iterateJsdoc.js").JsdocBlockWithInline, tagName: string): import("comment-parser").Spec[];
/**
* @typedef {{
* [key: string]: false|string|
* {message: string, replacement?: string}
* }} TagNamePreference
*/
/**
* @param {import('eslint').Rule.RuleContext} context
* @param {ParserMode|undefined} mode
* @param {import('comment-parser').Spec[]} tags
* @returns {{
* tagsWithNames: import('comment-parser').Spec[],
* tagsWithoutNames: import('comment-parser').Spec[]
* }}
*/
export function getTagsByType(context: import("eslint").Rule.RuleContext, mode: ParserMode | undefined, tags: import("comment-parser").Spec[]): {
tagsWithNames: import("comment-parser").Spec[];
tagsWithoutNames: import("comment-parser").Spec[];
};
/**
* @param {ParserMode} mode
* @param {import('./iterateJsdoc.js').StructuredTags} structuredTags
* @returns {import('./getDefaultTagStructureForMode.js').TagStructure}
*/
export function getTagStructureForMode(mode: ParserMode, structuredTags: import("./iterateJsdoc.js").StructuredTags): import("./getDefaultTagStructureForMode.js").TagStructure;
/**
* @param {import('./iterateJsdoc.js').JsdocBlockWithInline} jsdoc
* @param {string[]} targetTagNames
* @returns {boolean}
*/
export function hasATag(jsdoc: import("./iterateJsdoc.js").JsdocBlockWithInline, targetTagNames: string[]): boolean;
/**
* @param {ESTreeOrTypeScriptNode} functionNode
* @returns {Integer}
*/
export function hasParams(functionNode: ESTreeOrTypeScriptNode): Integer;
/**
* @param {import('./iterateJsdoc.js').JsdocBlockWithInline} jsdoc
* @param {string} targetTagName
* @returns {boolean}
*/
export function hasTag(jsdoc: import("./iterateJsdoc.js").JsdocBlockWithInline, targetTagName: string): boolean;
/**
* Checks if a node has a throws statement.
* @param {ESTreeOrTypeScriptNode|null|undefined} node
* @param {boolean} [innerFunction]
* @returns {boolean}
*/
export function hasThrowValue(node: ESTreeOrTypeScriptNode | null | undefined, innerFunction?: boolean): boolean;
/**
* Checks if a node has a return statement. Void return does not count.
* @param {ESTreeOrTypeScriptNode} node
* @param {boolean} [checkYieldReturnValue]
* @returns {boolean}
*/
export function hasYieldValue(node: ESTreeOrTypeScriptNode, checkYieldReturnValue?: boolean): boolean;
/**
* @param {import('eslint').Rule.Node|null} node
* @returns {boolean}
*/
export function isConstructor(node: import("eslint").Rule.Node | null): boolean;
/**
* @param {import('eslint').Rule.Node|null} node
* @returns {boolean}
*/
export function isGetter(node: import("eslint").Rule.Node | null): boolean;
/**
* @param {string} tag
* @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
* @returns {boolean}
*/
export function isNameOrNamepathDefiningTag(tag: string, tagMap?: import("./getDefaultTagStructureForMode.js").TagStructure): boolean;
/**
* @param {string} tag
* @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
* @returns {boolean}
*/
export function isNamepathOrUrlReferencingTag(tag: string, tagMap?: import("./getDefaultTagStructureForMode.js").TagStructure): boolean;
/**
* @param {string} tag
* @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
* @returns {boolean}
*/
export function isNamepathReferencingTag(tag: string, tagMap?: import("./getDefaultTagStructureForMode.js").TagStructure): boolean;
/**
* @param {import('eslint').Rule.Node|null} node
* @returns {boolean}
*/
export function isSetter(node: import("eslint").Rule.Node | null): boolean;
/**
* @param {import('eslint').Rule.RuleContext} context
* @param {ParserMode|undefined} mode
* @param {string} name
* @param {string[]} definedTags
* @returns {boolean}
*/
export function isValidTag(context: import("eslint").Rule.RuleContext, mode: ParserMode | undefined, name: string, definedTags: string[]): boolean;
/**
* Checks if the JSDoc comment has an undefined type.
* @param {import('comment-parser').Spec|null|undefined} tag
* the tag which should be checked.
* @param {ParserMode} mode
* @returns {boolean}
* true in case a defined type is undeclared; otherwise false.
*/
export function mayBeUndefinedTypeTag(tag: import("comment-parser").Spec | null | undefined, mode: ParserMode): boolean;
/**
* @param {import('./iterateJsdoc.js').StructuredTags} structuredTags
* @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
* @returns {void}
*/
export function overrideTagStructure(structuredTags: import("./iterateJsdoc.js").StructuredTags, tagMap?: import("./getDefaultTagStructureForMode.js").TagStructure): void;
/**
* @param {string} tag
*/
/**
* Parses GCC Generic/Template types
* @see {@link https://github.com/google/closure-compiler/wiki/Generic-Types}
* @see {@link https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html#template}
* @param {import('comment-parser').Spec} tag
* @returns {string[]}
*/
export function parseClosureTemplateTag(tag: import("comment-parser").Spec): string[];
/**
* @callback PathDoesNotBeginWith
* @param {string} name
* @param {string} otherPathName
* @returns {boolean}
*/
/** @type {PathDoesNotBeginWith} */
export const pathDoesNotBeginWith: PathDoesNotBeginWith;
/**
* @param {import('@es-joy/jsdoccomment').JsdocBlockWithInline} jsdoc
* @param {import('@es-joy/jsdoccomment').JsdocTagWithInline} tag
* @param {import('jsdoc-type-pratt-parser').RootResult} parsedType
* @param {string} indent
* @param {string} typeBracketSpacing
*/
export function rewireByParsedType(jsdoc: import("@es-joy/jsdoccomment").JsdocBlockWithInline, tag: import("@es-joy/jsdoccomment").JsdocTagWithInline, parsedType: import("jsdoc-type-pratt-parser").RootResult, indent: string, typeBracketSpacing?: string): void;
/**
* @param {ParserMode} mode
* @returns {void}
*/
export function setTagStructure(mode: ParserMode): void;
export const strictNativeTypes: string[];
/**
* @param {string} tag
* @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
* @returns {boolean}
*/
export function tagMightHaveEitherTypeOrNamePosition(tag: string, tagMap: import("./getDefaultTagStructureForMode.js").TagStructure): boolean;
/**
* @param {string} tag
* @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
* @returns {boolean}
*/
export function tagMightHaveName(tag: string, tagMap?: import("./getDefaultTagStructureForMode.js").TagStructure): boolean;
/**
* @param {string} tag
* @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
* @returns {boolean}
*/
export function tagMightHaveNameOrNamepath(tag: string, tagMap?: import("./getDefaultTagStructureForMode.js").TagStructure): boolean;
/**
* @param {string} tag
* @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
* @returns {boolean}
*/
export function tagMightHaveNamepath(tag: string, tagMap?: import("./getDefaultTagStructureForMode.js").TagStructure): boolean;
/**
* @param {string} tag
* @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
* @returns {boolean}
*/
export function tagMightHaveNamePosition(tag: string, tagMap?: import("./getDefaultTagStructureForMode.js").TagStructure): boolean;
/**
* @param {string} tag
* @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
* @returns {boolean|string}
*/
export function tagMightHaveTypePosition(tag: string, tagMap?: import("./getDefaultTagStructureForMode.js").TagStructure): boolean | string;
/**
* @param {import('comment-parser').Spec} tag
* @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
* @returns {boolean|undefined}
*/
export function tagMissingRequiredTypeOrNamepath(tag: import("comment-parser").Spec, tagMap?: import("./getDefaultTagStructureForMode.js").TagStructure): boolean | undefined;
/**
* @param {string} tag
* @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
* @returns {boolean|undefined}
*/
export function tagMustHaveNamePosition(tag: string, tagMap?: import("./getDefaultTagStructureForMode.js").TagStructure): boolean | undefined;
/**
* @param {string} tag
* @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
* @returns {boolean|undefined}
*/
export function tagMustHaveTypePosition(tag: string, tagMap?: import("./getDefaultTagStructureForMode.js").TagStructure): boolean | undefined;
export { hasReturnValue, hasValueOrExecutorHasNonEmptyResolveValue } from "./utils/hasReturnValue.js";

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,3 @@
declare const _default: eslint.Rule.RuleModule;
export default _default;
import eslint from 'eslint';

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,9 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;
export type CustomSpacings = {
postDelimiter: import("../iterateJsdoc.js").Integer;
postHyphen: import("../iterateJsdoc.js").Integer;
postName: import("../iterateJsdoc.js").Integer;
postTag: import("../iterateJsdoc.js").Integer;
postType: import("../iterateJsdoc.js").Integer;
};

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,7 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;
/**
* Iterates strict types to see if any should be added to `invalidTypes` (and
* the the relevant strict type returned as the new preferred type).
*/
export type CheckNativeTypes = (preferredTypes: import("../iterateJsdoc.js").PreferredTypes, typeNodeName: string, preferred: string | undefined, parentNode: import("jsdoc-type-pratt-parser").NonRootResult | undefined, invalidTypes: (string | false | undefined)[][]) => string | undefined;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,9 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;
export type ContextObject = {
comment: string;
context: string;
message: string;
minimum: import("../iterateJsdoc.js").Integer;
};
export type Context = string | ContextObject;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,25 @@
declare const _default: {
create(context: import("eslint").Rule.RuleContext): {};
meta: {
docs: {
category: string;
description: string;
recommended: boolean;
url: string;
};
fixable: "code";
messages: {
missingJsDoc: string;
};
schema: import("json-schema").JSONSchema4[];
type: "suggestion";
};
};
export default _default;
export type RequireJsdocOpts = {
ancestorsOnly: boolean;
esm: boolean;
initModuleExports: boolean;
initWindow: boolean;
};
export type ESLintOrTSNode = import("eslint").Rule.Node | import("@typescript-eslint/types").TSESTree.Node;

View file

@ -0,0 +1,3 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;
export type RootNamerReturn = [string, boolean, () => RootNamerReturn];

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,2 @@
declare const _default: import("eslint").Rule.RuleModule;
export default _default;

View file

@ -0,0 +1,15 @@
export type AliasedTags = {
[key: string]: string[];
};
/**
* @type {AliasedTags}
*/
export const closureTags: AliasedTags;
/**
* @type {AliasedTags}
*/
export const jsdocTags: AliasedTags;
/**
* @type {AliasedTags}
*/
export const typeScriptTags: AliasedTags;

View file

@ -0,0 +1,19 @@
export type ESTreeOrTypeScriptNode = import("estree").Node | import("@typescript-eslint/types").TSESTree.Node;
export type PromiseFilter = (node: ESTreeOrTypeScriptNode | undefined) => boolean;
/**
* Checks if a node has a return statement. Void return does not count.
* @param {ESTreeOrTypeScriptNode|undefined|null} node
* @param {boolean} [throwOnNullReturn]
* @param {PromiseFilter} [promFilter]
* @returns {boolean|undefined}
*/
export function hasReturnValue(node: ESTreeOrTypeScriptNode | undefined | null, throwOnNullReturn?: boolean, promFilter?: PromiseFilter): boolean | undefined;
/**
* Checks if a Promise executor has no resolve value or an empty value.
* An `undefined` resolve does not count.
* @param {ESTreeOrTypeScriptNode} node
* @param {boolean} anyPromiseAsReturn
* @param {boolean} [allBranches]
* @returns {boolean}
*/
export function hasValueOrExecutorHasNonEmptyResolveValue(node: ESTreeOrTypeScriptNode, anyPromiseAsReturn: boolean, allBranches?: boolean): boolean;

View file

@ -0,0 +1,46 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
const defaultTagOrder = [{
tags: [
// Brief descriptions
'summary', 'typeSummary',
// Module/file-level
'module', 'exports', 'file', 'fileoverview', 'overview', 'import',
// Identifying (name, type)
'template', 'typedef', 'interface', 'record', 'name', 'kind', 'type', 'alias', 'external', 'host', 'callback', 'func', 'function', 'method', 'class', 'constructor',
// Relationships
'modifies', 'mixes', 'mixin', 'mixinClass', 'mixinFunction', 'namespace', 'borrows', 'constructs', 'lends', 'implements', 'requires',
// Long descriptions
'desc', 'description', 'classdesc', 'tutorial', 'copyright', 'license',
// Simple annotations
// TypeScript
'internal', 'overload', 'const', 'constant', 'final', 'global', 'readonly', 'abstract', 'virtual', 'var', 'member', 'memberof', 'memberof!', 'inner', 'instance', 'inheritdoc', 'inheritDoc', 'override', 'hideconstructor',
// Core function/object info
'param', 'arg', 'argument', 'prop', 'property', 'return', 'returns',
// Important behavior details
'async', 'generator', 'default', 'defaultvalue', 'enum', 'augments', 'extends', 'throws', 'exception', 'yield', 'yields', 'event', 'fires', 'emits', 'listens', 'this',
// TypeScript
'satisfies',
// Access
'static', 'private', 'protected', 'public', 'access', 'package', '-other',
// Supplementary descriptions
'see', 'example',
// METADATA
// Other Closure (undocumented) metadata
'closurePrimitive', 'customElement', 'expose', 'hidden', 'idGenerator', 'meaning', 'ngInject', 'owner', 'wizaction',
// Other Closure (documented) metadata
'define', 'dict', 'export', 'externs', 'implicitCast', 'noalias', 'nocollapse', 'nocompile', 'noinline', 'nosideeffects', 'polymer', 'polymerBehavior', 'preserve', 'struct', 'suppress', 'unrestricted',
// @homer0/prettier-plugin-jsdoc metadata
'category',
// Non-Closure metadata
'ignore', 'author', 'version', 'variation', 'since', 'deprecated', 'todo']
}];
var _default = exports.default = defaultTagOrder;
module.exports = exports.default;
//# sourceMappingURL=defaultTagOrder.cjs.map

View file

@ -0,0 +1 @@
{"version":3,"file":"defaultTagOrder.cjs","names":["defaultTagOrder","tags","_default","exports","default","module"],"sources":["../src/defaultTagOrder.js"],"sourcesContent":["const defaultTagOrder = [\n {\n tags: [\n // Brief descriptions\n 'summary',\n 'typeSummary',\n\n // Module/file-level\n 'module',\n 'exports',\n 'file',\n 'fileoverview',\n 'overview',\n 'import',\n\n // Identifying (name, type)\n 'template',\n 'typedef',\n 'interface',\n 'record',\n 'name',\n 'kind',\n 'type',\n 'alias',\n 'external',\n 'host',\n 'callback',\n 'func',\n 'function',\n 'method',\n 'class',\n 'constructor',\n\n // Relationships\n 'modifies',\n 'mixes',\n 'mixin',\n 'mixinClass',\n 'mixinFunction',\n 'namespace',\n 'borrows',\n 'constructs',\n 'lends',\n 'implements',\n 'requires',\n\n // Long descriptions\n 'desc',\n 'description',\n 'classdesc',\n 'tutorial',\n 'copyright',\n 'license',\n\n // Simple annotations\n\n // TypeScript\n 'internal',\n 'overload',\n\n 'const',\n 'constant',\n 'final',\n 'global',\n 'readonly',\n 'abstract',\n 'virtual',\n 'var',\n 'member',\n 'memberof',\n 'memberof!',\n 'inner',\n 'instance',\n 'inheritdoc',\n 'inheritDoc',\n 'override',\n 'hideconstructor',\n\n // Core function/object info\n 'param',\n 'arg',\n 'argument',\n 'prop',\n 'property',\n 'return',\n 'returns',\n\n // Important behavior details\n 'async',\n 'generator',\n 'default',\n 'defaultvalue',\n 'enum',\n 'augments',\n 'extends',\n 'throws',\n 'exception',\n 'yield',\n 'yields',\n 'event',\n 'fires',\n 'emits',\n 'listens',\n 'this',\n\n // TypeScript\n 'satisfies',\n\n // Access\n 'static',\n 'private',\n 'protected',\n 'public',\n 'access',\n 'package',\n\n '-other',\n\n // Supplementary descriptions\n 'see',\n 'example',\n\n // METADATA\n\n // Other Closure (undocumented) metadata\n 'closurePrimitive',\n 'customElement',\n 'expose',\n 'hidden',\n 'idGenerator',\n 'meaning',\n 'ngInject',\n 'owner',\n 'wizaction',\n\n // Other Closure (documented) metadata\n 'define',\n 'dict',\n 'export',\n 'externs',\n 'implicitCast',\n 'noalias',\n 'nocollapse',\n 'nocompile',\n 'noinline',\n 'nosideeffects',\n 'polymer',\n 'polymerBehavior',\n 'preserve',\n 'struct',\n 'suppress',\n 'unrestricted',\n\n // @homer0/prettier-plugin-jsdoc metadata\n 'category',\n\n // Non-Closure metadata\n 'ignore',\n 'author',\n 'version',\n 'variation',\n 'since',\n 'deprecated',\n 'todo',\n ],\n },\n];\n\nexport default defaultTagOrder;\n"],"mappings":";;;;;;AAAA,MAAMA,eAAe,GAAG,CACtB;EACEC,IAAI,EAAE;EACJ;EACA,SAAS,EACT,aAAa;EAEb;EACA,QAAQ,EACR,SAAS,EACT,MAAM,EACN,cAAc,EACd,UAAU,EACV,QAAQ;EAER;EACA,UAAU,EACV,SAAS,EACT,WAAW,EACX,QAAQ,EACR,MAAM,EACN,MAAM,EACN,MAAM,EACN,OAAO,EACP,UAAU,EACV,MAAM,EACN,UAAU,EACV,MAAM,EACN,UAAU,EACV,QAAQ,EACR,OAAO,EACP,aAAa;EAEb;EACA,UAAU,EACV,OAAO,EACP,OAAO,EACP,YAAY,EACZ,eAAe,EACf,WAAW,EACX,SAAS,EACT,YAAY,EACZ,OAAO,EACP,YAAY,EACZ,UAAU;EAEV;EACA,MAAM,EACN,aAAa,EACb,WAAW,EACX,UAAU,EACV,WAAW,EACX,SAAS;EAET;;EAEA;EACA,UAAU,EACV,UAAU,EAEV,OAAO,EACP,UAAU,EACV,OAAO,EACP,QAAQ,EACR,UAAU,EACV,UAAU,EACV,SAAS,EACT,KAAK,EACL,QAAQ,EACR,UAAU,EACV,WAAW,EACX,OAAO,EACP,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,iBAAiB;EAEjB;EACA,OAAO,EACP,KAAK,EACL,UAAU,EACV,MAAM,EACN,UAAU,EACV,QAAQ,EACR,SAAS;EAET;EACA,OAAO,EACP,WAAW,EACX,SAAS,EACT,cAAc,EACd,MAAM,EACN,UAAU,EACV,SAAS,EACT,QAAQ,EACR,WAAW,EACX,OAAO,EACP,QAAQ,EACR,OAAO,EACP,OAAO,EACP,OAAO,EACP,SAAS,EACT,MAAM;EAEN;EACA,WAAW;EAEX;EACA,QAAQ,EACR,SAAS,EACT,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,SAAS,EAET,QAAQ;EAER;EACA,KAAK,EACL,SAAS;EAET;;EAEA;EACA,kBAAkB,EAClB,eAAe,EACf,QAAQ,EACR,QAAQ,EACR,aAAa,EACb,SAAS,EACT,UAAU,EACV,OAAO,EACP,WAAW;EAEX;EACA,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,SAAS,EACT,cAAc,EACd,SAAS,EACT,YAAY,EACZ,WAAW,EACX,UAAU,EACV,eAAe,EACf,SAAS,EACT,iBAAiB,EACjB,UAAU,EACV,QAAQ,EACR,UAAU,EACV,cAAc;EAEd;EACA,UAAU;EAEV;EACA,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,WAAW,EACX,OAAO,EACP,YAAY,EACZ,MAAM;AAEV,CAAC,CACF;AAAC,IAAAC,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAEaJ,eAAe;AAAAK,MAAA,CAAAF,OAAA,GAAAA,OAAA,CAAAC,OAAA","ignoreList":[]}

View file

@ -0,0 +1,5 @@
export default defaultTagOrder;
declare const defaultTagOrder: {
tags: string[];
}[];
//# sourceMappingURL=defaultTagOrder.d.ts.map

View file

@ -0,0 +1,732 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _jsdoccomment = require("@es-joy/jsdoccomment");
var _debug = _interopRequireDefault(require("debug"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const debug = (0, _debug.default)('requireExportJsdoc');
/**
* @typedef {{
* value: string
* }} ValueObject
*/
/**
* @typedef {{
* type?: string,
* value?: ValueObject|import('eslint').Rule.Node|import('@typescript-eslint/types').TSESTree.Node,
* props: {
* [key: string]: CreatedNode|null,
* },
* special?: true,
* globalVars?: CreatedNode,
* exported?: boolean,
* ANONYMOUS_DEFAULT?: import('eslint').Rule.Node
* }} CreatedNode
*/
/**
* @returns {CreatedNode}
*/
const createNode = function () {
return {
props: {}
};
};
/**
* @param {CreatedNode|null} symbol
* @returns {string|null}
*/
const getSymbolValue = function (symbol) {
/* c8 ignore next 3 */
if (!symbol) {
return null;
}
/* c8 ignore else */
if (symbol.type === 'literal') {
return /** @type {ValueObject} */symbol.value.value;
}
/* c8 ignore next 2 */
// eslint-disable-next-line @stylistic/padding-line-between-statements -- c8
return null;
};
/**
*
* @param {import('estree').Identifier} node
* @param {CreatedNode} globals
* @param {CreatedNode} scope
* @param {SymbolOptions} opts
* @returns {CreatedNode|null}
*/
const getIdentifier = function (node, globals, scope, opts) {
if (opts.simpleIdentifier) {
// Type is Identier for noncomputed properties
const identifierLiteral = createNode();
identifierLiteral.type = 'literal';
identifierLiteral.value = {
value: node.name
};
return identifierLiteral;
}
/* c8 ignore next */
const block = scope || globals;
// As scopes are not currently supported, they are not traversed upwards recursively
if (block.props[node.name]) {
return block.props[node.name];
}
// Seems this will only be entered once scopes added and entered
/* c8 ignore next 3 */
if (globals.props[node.name]) {
return globals.props[node.name];
}
return null;
};
/**
* @callback CreateSymbol
* @param {import('eslint').Rule.Node|null} node
* @param {CreatedNode} globals
* @param {import('eslint').Rule.Node|import('@typescript-eslint/types').TSESTree.Node|null} value
* @param {CreatedNode} [scope]
* @param {boolean|SymbolOptions} [isGlobal]
* @returns {CreatedNode|null}
*/
/** @type {CreateSymbol} */
let createSymbol; // eslint-disable-line prefer-const
/**
* @typedef {{
* simpleIdentifier?: boolean
* }} SymbolOptions
*/
/**
*
* @param {import('eslint').Rule.Node|import('@typescript-eslint/types').TSESTree.Node} node
* @param {CreatedNode} globals
* @param {CreatedNode} scope
* @param {SymbolOptions} [opt]
* @returns {CreatedNode|null}
*/
const getSymbol = function (node, globals, scope, opt) {
const opts = opt || {};
/* c8 ignore next */
switch (node.type) {
/* c8 ignore next 4 -- No longer needed? */
case 'ArrowFunctionExpression':
// Fallthrough
case 'ClassDeclaration':
case 'FunctionDeclaration':
case 'FunctionExpression':
case 'TSEnumDeclaration':
case 'TSInterfaceDeclaration':
case 'TSTypeAliasDeclaration':
{
const val = createNode();
val.props.prototype = createNode();
val.props.prototype.type = 'object';
val.type = 'object';
val.value = node;
return val;
}
case 'AssignmentExpression':
{
return createSymbol(/** @type {import('eslint').Rule.Node} */
node.left, globals, /** @type {import('eslint').Rule.Node} */
node.right, scope, opts);
}
case 'ClassBody':
{
const val = createNode();
for (const method of node.body) {
// StaticBlock
if (!('key' in method)) {
continue;
}
val.props[/** @type {import('estree').Identifier} */(/** @type {import('estree').MethodDefinition} */method.key).name] = createNode();
/** @type {{[key: string]: CreatedNode}} */
val.props[/** @type {import('estree').Identifier} */(/** @type {import('estree').MethodDefinition} */method.key).name].type = 'object';
/** @type {{[key: string]: CreatedNode}} */
val.props[/** @type {import('estree').Identifier} */(/** @type {import('estree').MethodDefinition} */method.key).name].value = /** @type {import('eslint').Rule.Node} */
/** @type {import('estree').MethodDefinition} */method.value;
}
val.type = 'object';
val.value = node.parent;
return val;
}
case 'ClassExpression':
{
return getSymbol(/** @type {import('eslint').Rule.Node} */
node.body, globals, scope, opts);
}
case 'Identifier':
{
return getIdentifier(node, globals, scope, opts);
}
case 'Literal':
{
const val = createNode();
val.type = 'literal';
val.value = node;
return val;
}
case 'MemberExpression':
{
const obj = getSymbol(/** @type {import('eslint').Rule.Node} */
node.object, globals, scope, opts);
const propertySymbol = getSymbol(/** @type {import('eslint').Rule.Node} */
node.property, globals, scope, {
simpleIdentifier: !node.computed
});
const propertyValue = getSymbolValue(propertySymbol);
/* c8 ignore else */
if (obj && propertyValue && obj.props[propertyValue]) {
const block = obj.props[propertyValue];
return block;
}
/* c8 ignore next 11 */
/*
if (opts.createMissingProps && propertyValue) {
obj.props[propertyValue] = createNode();
return obj.props[propertyValue];
}
*/
// eslint-disable-next-line @stylistic/padding-line-between-statements -- c8
debug(`MemberExpression: Missing property ${/** @type {import('estree').PrivateIdentifier} */node.property.name}`);
/* c8 ignore next 2 */
return null;
}
case 'ObjectExpression':
{
const val = createNode();
val.type = 'object';
for (const prop of node.properties) {
if ([
// @babel/eslint-parser
'ExperimentalSpreadProperty',
// typescript-eslint, espree, acorn, etc.
'SpreadElement'].includes(prop.type)) {
continue;
}
const propVal = getSymbol(/** @type {import('eslint').Rule.Node} */
/** @type {import('estree').Property} */
prop.value, globals, scope, opts);
/* c8 ignore next 8 */
if (propVal) {
val.props[/** @type {import('estree').PrivateIdentifier} */
(/** @type {import('estree').Property} */prop.key).name] = propVal;
}
}
return val;
}
}
/* c8 ignore next 2 */
// eslint-disable-next-line @stylistic/padding-line-between-statements -- c8
return null;
};
/**
*
* @param {CreatedNode} block
* @param {string} name
* @param {CreatedNode|null} value
* @param {CreatedNode} globals
* @param {boolean|SymbolOptions|undefined} isGlobal
* @returns {void}
*/
const createBlockSymbol = function (block, name, value, globals, isGlobal) {
block.props[name] = value;
if (isGlobal && globals.props.window && globals.props.window.special) {
globals.props.window.props[name] = value;
}
};
createSymbol = function (node, globals, value, scope, isGlobal) {
const block = scope || globals;
/* c8 ignore next 3 */
if (!node) {
return null;
}
let symbol;
switch (node.type) {
case 'ClassDeclaration':
/* c8 ignore next */
// @ts-expect-error TS OK
// Fall through
case 'FunctionDeclaration':
case 'TSEnumDeclaration':
/* c8 ignore next */
// @ts-expect-error TS OK
// Fall through
case 'TSInterfaceDeclaration':
case 'TSTypeAliasDeclaration':
{
const nde = /** @type {import('estree').ClassDeclaration} */node;
/* c8 ignore else */
if (nde.id && nde.id.type === 'Identifier') {
return createSymbol(/** @type {import('eslint').Rule.Node} */nde.id, globals, node, globals);
}
/* c8 ignore next 3 */
// eslint-disable-next-line @stylistic/padding-line-between-statements -- c8
break;
}
case 'Identifier':
{
const nde = /** @type {import('estree').Identifier} */node;
if (value) {
const valueSymbol = getSymbol(value, globals, block);
/* c8 ignore else */
if (valueSymbol) {
createBlockSymbol(block, nde.name, valueSymbol, globals, isGlobal);
return block.props[nde.name];
}
/* c8 ignore next 2 */
// eslint-disable-next-line @stylistic/padding-line-between-statements -- c8
debug('Identifier: Missing value symbol for %s', nde.name);
} else {
createBlockSymbol(block, nde.name, createNode(), globals, isGlobal);
return block.props[nde.name];
}
/* c8 ignore next 3 */
// eslint-disable-next-line @stylistic/padding-line-between-statements -- c8
break;
}
case 'MemberExpression':
{
const nde = /** @type {import('estree').MemberExpression} */node;
symbol = getSymbol(/** @type {import('eslint').Rule.Node} */nde.object, globals, block);
const propertySymbol = getSymbol(/** @type {import('eslint').Rule.Node} */nde.property, globals, block, {
simpleIdentifier: !nde.computed
});
const propertyValue = getSymbolValue(propertySymbol);
if (symbol && propertyValue) {
createBlockSymbol(symbol, propertyValue, getSymbol(/** @type {import('eslint').Rule.Node} */
value, globals, block), globals, isGlobal);
return symbol.props[propertyValue];
}
debug('MemberExpression: Missing symbol: %s', /** @type {import('estree').Identifier} */nde.property.name);
break;
}
}
return null;
};
/**
* Creates variables from variable definitions
* @param {import('eslint').Rule.Node} node
* @param {CreatedNode} globals
* @param {import('./rules/requireJsdoc.js').RequireJsdocOpts} opts
* @returns {void}
*/
const initVariables = function (node, globals, opts) {
switch (node.type) {
case 'ExportNamedDeclaration':
{
if (node.declaration) {
initVariables(/** @type {import('eslint').Rule.Node} */
node.declaration, globals, opts);
}
break;
}
case 'ExpressionStatement':
{
initVariables(/** @type {import('eslint').Rule.Node} */
node.expression, globals, opts);
break;
}
case 'Program':
{
for (const childNode of node.body) {
initVariables(/** @type {import('eslint').Rule.Node} */
childNode, globals, opts);
}
break;
}
case 'VariableDeclaration':
{
for (const declaration of node.declarations) {
// let and const
const symbol = createSymbol(/** @type {import('eslint').Rule.Node} */
declaration.id, globals, null, globals);
if (opts.initWindow && node.kind === 'var' && globals.props.window) {
// If var, also add to window
globals.props.window.props[/** @type {import('estree').Identifier} */
declaration.id.name] = symbol;
}
}
break;
}
}
};
/**
* Populates variable maps using AST
* @param {import('eslint').Rule.Node|import('@typescript-eslint/types').TSESTree.Node} node
* @param {CreatedNode} globals
* @param {import('./rules/requireJsdoc.js').RequireJsdocOpts} opt
* @param {true} [isExport]
* @returns {boolean}
*/
const mapVariables = function (node, globals, opt, isExport) {
/* c8 ignore next */
const opts = opt || {};
/* c8 ignore next */
switch (node.type) {
case 'AssignmentExpression':
{
createSymbol(/** @type {import('eslint').Rule.Node} */
node.left, globals, /** @type {import('eslint').Rule.Node} */
node.right);
break;
}
case 'ClassDeclaration':
{
createSymbol(/** @type {import('eslint').Rule.Node|null} */node.id, globals, /** @type {import('eslint').Rule.Node} */node.body, globals);
break;
}
case 'ExportDefaultDeclaration':
{
const symbol = createSymbol(/** @type {import('eslint').Rule.Node} */
node.declaration, globals, /** @type {import('eslint').Rule.Node} */
node.declaration);
if (symbol) {
symbol.exported = true;
/* c8 ignore next 6 */
} else {
// if (!node.id) {
globals.ANONYMOUS_DEFAULT = /** @type {import('eslint').Rule.Node} */
node.declaration;
}
break;
}
case 'ExportNamedDeclaration':
{
if (node.declaration) {
if (node.declaration.type === 'VariableDeclaration') {
mapVariables(/** @type {import('eslint').Rule.Node} */
node.declaration, globals, opts, true);
} else {
const symbol = createSymbol(/** @type {import('eslint').Rule.Node} */
node.declaration, globals, /** @type {import('eslint').Rule.Node} */
node.declaration);
/* c8 ignore next 3 */
if (symbol) {
symbol.exported = true;
}
}
}
for (const specifier of node.specifiers) {
mapVariables(/** @type {import('eslint').Rule.Node} */
specifier, globals, opts);
}
break;
}
case 'ExportSpecifier':
{
const symbol = getSymbol(/** @type {import('eslint').Rule.Node} */
node.local, globals, globals);
/* c8 ignore next 3 */
if (symbol) {
symbol.exported = true;
}
break;
}
case 'ExpressionStatement':
{
mapVariables(/** @type {import('eslint').Rule.Node} */
node.expression, globals, opts);
break;
}
case 'FunctionDeclaration':
case 'TSTypeAliasDeclaration':
{
/* c8 ignore next 10 */
if (/** @type {import('estree').Identifier} */node.id.type === 'Identifier') {
createSymbol(/** @type {import('eslint').Rule.Node} */
node.id, globals, node, globals, true);
}
break;
}
case 'Program':
{
if (opts.ancestorsOnly) {
return false;
}
for (const childNode of node.body) {
mapVariables(/** @type {import('eslint').Rule.Node} */
childNode, globals, opts);
}
break;
}
case 'VariableDeclaration':
{
for (const declaration of node.declarations) {
const isGlobal = Boolean(opts.initWindow && node.kind === 'var' && globals.props.window);
const symbol = createSymbol(/** @type {import('eslint').Rule.Node} */
declaration.id, globals, /** @type {import('eslint').Rule.Node} */
declaration.init, globals, isGlobal);
if (symbol && isExport) {
symbol.exported = true;
}
}
break;
}
default:
{
/* c8 ignore next */
return false;
}
}
return true;
};
/**
*
* @param {import('eslint').Rule.Node} node
* @param {CreatedNode|ValueObject|string|undefined|
* import('eslint').Rule.Node|import('@typescript-eslint/types').TSESTree.Node} block
* @param {(CreatedNode|ValueObject|string|
* import('eslint').Rule.Node|import('@typescript-eslint/types').TSESTree.Node)[]} [cache]
* @returns {boolean}
*/
const findNode = function (node, block, cache) {
let blockCache = cache || [];
if (!block || blockCache.includes(block)) {
return false;
}
blockCache = blockCache.slice();
blockCache.push(block);
if (typeof block === 'object' && 'type' in block && (block.type === 'object' || block.type === 'MethodDefinition') && block.value === node) {
return true;
}
if (typeof block !== 'object') {
return false;
}
const props = 'props' in block && block.props || 'body' in block && block.body;
for (const propval of Object.values(props || {})) {
if (Array.isArray(propval)) {
/* c8 ignore next 5 */
if (propval.some(val => {
return findNode(node, val, blockCache);
})) {
return true;
}
} else if (findNode(node, propval, blockCache)) {
return true;
}
}
return false;
};
const exportTypes = new Set(['ExportDefaultDeclaration', 'ExportNamedDeclaration']);
const ignorableNestedTypes = new Set(['ArrowFunctionExpression', 'FunctionDeclaration', 'FunctionExpression']);
/**
* @param {import('eslint').Rule.Node} nde
* @returns {import('eslint').Rule.Node|false}
*/
const getExportAncestor = function (nde) {
/** @type {import('eslint').Rule.Node|null} */
let node = nde;
let idx = 0;
const ignorableIfDeep = ignorableNestedTypes.has(nde?.type);
while (node) {
// Ignore functions nested more deeply than say `export default function () {}`
if (idx >= 2 && ignorableIfDeep) {
break;
}
if (exportTypes.has(node.type)) {
return node;
}
node = node.parent;
idx++;
}
return false;
};
const canBeExportedByAncestorType = new Set(['ClassProperty', 'Method', 'PropertyDefinition', 'TSMethodSignature', 'TSPropertySignature']);
const canExportChildrenType = new Set(['ClassBody', 'ClassDeclaration', 'ClassDefinition', 'ClassExpression', 'Program', 'TSInterfaceBody', 'TSInterfaceDeclaration', 'TSTypeAliasDeclaration', 'TSTypeLiteral', 'TSTypeParameterInstantiation', 'TSTypeReference']);
/**
* @param {import('eslint').Rule.Node} nde
* @returns {false|import('eslint').Rule.Node}
*/
const isExportByAncestor = function (nde) {
if (!canBeExportedByAncestorType.has(nde.type)) {
return false;
}
let node = nde.parent;
while (node) {
if (exportTypes.has(node.type)) {
return node;
}
if (!canExportChildrenType.has(node.type)) {
return false;
}
node = node.parent;
}
return false;
};
/**
*
* @param {CreatedNode} block
* @param {import('eslint').Rule.Node} node
* @param {CreatedNode[]} [cache] Currently unused
* @returns {boolean}
*/
const findExportedNode = function (block, node, cache) {
/* c8 ignore next 3 */
if (block === null) {
return false;
}
const blockCache = cache || [];
const {
props
} = block;
for (const propval of Object.values(props)) {
const pval = /** @type {CreatedNode} */propval;
blockCache.push(pval);
if (pval.exported && (node === pval.value || findNode(node, pval.value))) {
return true;
}
// No need to check `propval` for exported nodes as ESM
// exports are only global
}
return false;
};
/**
*
* @param {import('eslint').Rule.Node} node
* @param {CreatedNode} globals
* @param {import('./rules/requireJsdoc.js').RequireJsdocOpts} opt
* @returns {boolean}
*/
const isNodeExported = function (node, globals, opt) {
const moduleExports = globals.props.module?.props?.exports;
if (opt.initModuleExports && moduleExports && findNode(node, moduleExports)) {
return true;
}
if (opt.initWindow && globals.props.window && findNode(node, globals.props.window)) {
return true;
}
if (opt.esm && findExportedNode(globals, node)) {
return true;
}
return false;
};
/**
*
* @param {import('eslint').Rule.Node} node
* @param {CreatedNode} globalVars
* @param {import('./rules/requireJsdoc.js').RequireJsdocOpts} opts
* @returns {boolean}
*/
const parseRecursive = function (node, globalVars, opts) {
// Iterate from top using recursion - stop at first processed node from top
if (node.parent && parseRecursive(node.parent, globalVars, opts)) {
return true;
}
return mapVariables(node, globalVars, opts);
};
/**
*
* @param {import('eslint').Rule.Node} ast
* @param {import('eslint').Rule.Node} node
* @param {import('./rules/requireJsdoc.js').RequireJsdocOpts} opt
* @returns {CreatedNode}
*/
const parse = function (ast, node, opt) {
/* c8 ignore next 6 */
const opts = opt || {
ancestorsOnly: false,
esm: true,
initModuleExports: true,
initWindow: true
};
const globalVars = createNode();
if (opts.initModuleExports) {
globalVars.props.module = createNode();
globalVars.props.module.props.exports = createNode();
globalVars.props.exports = globalVars.props.module.props.exports;
}
if (opts.initWindow) {
globalVars.props.window = createNode();
globalVars.props.window.special = true;
}
if (opts.ancestorsOnly) {
parseRecursive(node, globalVars, opts);
} else {
initVariables(ast, globalVars, opts);
mapVariables(ast, globalVars, opts);
}
return {
globalVars,
props: {}
};
};
const accessibilityNodes = new Set(['MethodDefinition', 'PropertyDefinition']);
/**
*
* @param {import('eslint').Rule.Node} node
* @returns {boolean}
*/
const isPrivate = node => {
return accessibilityNodes.has(node.type) && 'accessibility' in node && node.accessibility !== 'public' && node.accessibility !== undefined || 'key' in node && node.key.type === 'PrivateIdentifier';
};
/**
*
* @param {import('eslint').Rule.Node} node
* @param {import('eslint').SourceCode} sourceCode
* @param {import('./rules/requireJsdoc.js').RequireJsdocOpts} opt
* @param {import('./iterateJsdoc.js').Settings} settings
* @returns {boolean}
*/
const isUncommentedExport = function (node, sourceCode, opt, settings) {
// console.log({node});
// Optimize with ancestor check for esm
if (opt.esm) {
if (isPrivate(node) || node.parent && isPrivate(node.parent)) {
return false;
}
const exportNode = getExportAncestor(node);
// Is export node comment
if (exportNode && !(0, _jsdoccomment.findJSDocComment)(exportNode, sourceCode, settings)) {
return true;
}
/**
* Some typescript types are not in variable map, but inherit exported (interface property and method)
*/
if (isExportByAncestor(node) && !(0, _jsdoccomment.findJSDocComment)(node, sourceCode, settings)) {
return true;
}
}
const ast = /** @type {unknown} */sourceCode.ast;
const parseResult = parse(/** @type {import('eslint').Rule.Node} */
ast, node, opt);
return isNodeExported(node, /** @type {CreatedNode} */parseResult.globalVars, opt);
};
var _default = exports.default = {
isUncommentedExport,
parse
};
module.exports = exports.default;
//# sourceMappingURL=exportParser.cjs.map

Some files were not shown because too many files have changed in this diff Show more