diff --git a/.README/README.md b/.README/README.md index 9a26bce2..b3119911 100644 --- a/.README/README.md +++ b/.README/README.md @@ -50,6 +50,75 @@ const config = [ 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 + +#### 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 + - `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'], +]; +``` + +##### 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 + ### `eslintrc` Add `plugins` section to [.eslintrc.*](https://eslint.org/docs/user-guide/configuring#configuration-file-formats) diff --git a/README.md b/README.md index 4d1c7200..6835f072 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,79 @@ const config = [ 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 + + + +#### 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 + - `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'], +]; +``` + + + +##### 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 + ### eslintrc diff --git a/src/index.js b/src/index.js index d0a8ed4b..b9e9f135 100644 --- a/src/index.js +++ b/src/index.js @@ -260,6 +260,106 @@ const createRecommendedTypeScriptFlavorRuleset = (warnOrError, flatName) => { }; }; +/** + * @param {(string | unknown[])[]} ruleNames + */ +const createStandaloneRulesetFactory = (ruleNames) => { + /** + * @param {"warn"|"error"} warnOrError + * @param {string} [flatName] + * @returns {import('eslint').Linter.FlatConfig} + */ + return (warnOrError, flatName) => { + return { + name: 'jsdoc/' + flatName, + plugins: { jsdoc: index }, + rules: Object.fromEntries( + ruleNames.map( + ruleName => + typeof ruleName === "string" + ? [ruleName, warnOrError] + : [ruleName[0], warnOrError, ...ruleName.slice(1)] + ) + ), + }; + }; +} + +const contentsRules = [ + 'jsdoc/informative-docs', + 'jsdoc/match-description', + 'jsdoc/no-blank-block-descriptions', + 'jsdoc/no-blank-blocks', + ['jsdoc/text-escaping', { escapeHTML: true }] +] + +const createContentsTypescriptRuleset = createStandaloneRulesetFactory(contentsRules); + +const createContentsTypescriptFlavorRuleset = createStandaloneRulesetFactory(contentsRules); + +const logicalRules = [ + 'jsdoc/check-access', + 'jsdoc/check-param-names', + 'jsdoc/check-property-names', + 'jsdoc/check-syntax', + 'jsdoc/check-tag-names', + 'jsdoc/check-template-names', + 'jsdoc/check-types', + 'jsdoc/check-values', + 'jsdoc/empty-tags', + 'jsdoc/implements-on-classes', + 'jsdoc/require-returns-check', + 'jsdoc/require-yields-check', + 'jsdoc/no-bad-blocks', + 'jsdoc/no-defaults', + 'jsdoc/no-types', + 'jsdoc/no-undefined-types', + 'jsdoc/valid-types', +]; + +const createLogicalTypescriptRuleset = createStandaloneRulesetFactory(logicalRules); + +const createLogicalTypescriptFlavorRuleset = createStandaloneRulesetFactory(logicalRules); + +const requirementsRules = [ + 'jsdoc/require-example', + 'jsdoc/require-jsdoc', + 'jsdoc/require-param', + 'jsdoc/require-param-description', + 'jsdoc/require-param-name', + 'jsdoc/require-property', + 'jsdoc/require-property-description', + 'jsdoc/require-property-name', + 'jsdoc/require-returns', + 'jsdoc/require-returns-description', + 'jsdoc/require-yields', +]; + +const createRequirementsTypeScriptRuleset = createStandaloneRulesetFactory(requirementsRules); + +const createRequirementsTypeScriptFlavorRuleset = createStandaloneRulesetFactory([ + ...requirementsRules, + 'jsdoc/require-param-type', + 'jsdoc/require-property-type', + 'jsdoc/require-returns-type', + 'jsdoc/require-template', +]); + +const stylisticRules = [ + 'jsdoc/check-alignment', + 'jsdoc/check-line-alignment', + 'jsdoc/lines-before-block', + 'jsdoc/multiline-blocks', + 'jsdoc/no-multi-asterisks', + 'jsdoc/require-asterisk-prefix', + ['jsdoc/require-hyphen-before-param-description', 'never'], + 'jsdoc/tag-lines', +]; + +const createStylisticTypeScriptRuleset = createStandaloneRulesetFactory(stylisticRules); + +const createStylisticTypeScriptFlavorRuleset = createStandaloneRulesetFactory(stylisticRules); + /* c8 ignore next 3 -- TS */ if (!index.configs) { throw new Error('TypeScript guard'); @@ -279,6 +379,23 @@ index.configs['flat/recommended-typescript-error'] = createRecommendedTypeScript index.configs['flat/recommended-typescript-flavor'] = createRecommendedTypeScriptFlavorRuleset('warn', 'flat/recommended-typescript-flavor'); index.configs['flat/recommended-typescript-flavor-error'] = createRecommendedTypeScriptFlavorRuleset('error', 'flat/recommended-typescript-flavor-error'); +index.configs['flat/contents-typescript'] = createContentsTypescriptRuleset('warn', 'flat/contents-typescript'); +index.configs['flat/contents-typescript-error'] = createContentsTypescriptRuleset('error', 'flat/contents-typescript-error'); +index.configs['flat/contents-typescript-flavor'] = createContentsTypescriptFlavorRuleset('warn', 'flat/contents-typescript-flavor'); +index.configs['flat/contents-typescript-flavor-error'] = createContentsTypescriptFlavorRuleset('error', 'flat/contents-typescript-error-flavor'); +index.configs['flat/logical-typescript'] = createLogicalTypescriptRuleset('warn', 'flat/logical-typescript'); +index.configs['flat/logical-typescript-error'] = createLogicalTypescriptRuleset('error', 'flat/logical-typescript-error'); +index.configs['flat/logical-typescript-flavor'] = createLogicalTypescriptFlavorRuleset('warn', 'flat/logical-typescript-flavor'); +index.configs['flat/logical-typescript-flavor-error'] = createLogicalTypescriptFlavorRuleset('error', 'flat/logical-typescript-error-flavor'); +index.configs['flat/requirements-typescript'] = createRequirementsTypeScriptRuleset('warn', 'flat/requirements-typescript'); +index.configs['flat/requirements-typescript-error'] = createRequirementsTypeScriptRuleset('error', 'flat/requirements-typescript-error'); +index.configs['flat/requirements-typescript-flavor'] = createRequirementsTypeScriptFlavorRuleset('warn', 'flat/requirements-typescript-flavor'); +index.configs['flat/requirements-typescript-flavor-error'] = createRequirementsTypeScriptFlavorRuleset('error', 'flat/requirements-typescript-error-flavor'); +index.configs['flat/stylistic-typescript'] = createStylisticTypeScriptRuleset('warn', 'flat/stylistic-typescript'); +index.configs['flat/stylistic-typescript-error'] = createStylisticTypeScriptRuleset('error', 'flat/stylistic-typescript-error'); +index.configs['flat/stylistic-typescript-flavor'] = createStylisticTypeScriptFlavorRuleset('warn', 'flat/stylistic-typescript-flavor'); +index.configs['flat/stylistic-typescript-flavor-error'] = createStylisticTypeScriptFlavorRuleset('error', 'flat/stylistic-typescript-error-flavor'); + index.configs.examples = /** @type {import('eslint').Linter.FlatConfig[]} */ ([ { name: 'jsdoc/examples/processor',