eslint-plugin-jsdoc
Version:
JSDoc linting rules for ESLint.
1 lines • 17.2 kB
Source Map (JSON)
{"version":3,"file":"matchDescription.cjs","names":["iterateJsdoc"],"sources":["../../src/rules/matchDescription.js"],"sourcesContent":["import iterateJsdoc from '../iterateJsdoc.js';\n\n// If supporting Node >= 10, we could loosen the default to this for the\n// initial letter: \\\\p{Upper}\nconst matchDescriptionDefault = '^\\n?([A-Z`\\\\d_][\\\\s\\\\S]*[.?!`\\\\p{RGI_Emoji}]\\\\s*)?$';\n\n/**\n * @param {string} value\n * @param {string} userDefault\n * @returns {string}\n */\nconst stringOrDefault = (value, userDefault) => {\n return typeof value === 'string' ?\n value :\n userDefault || matchDescriptionDefault;\n};\n\nexport default iterateJsdoc(({\n context,\n jsdoc,\n report,\n utils,\n}) => {\n const {\n mainDescription,\n matchDescription,\n message,\n nonemptyTags = true,\n tags = {},\n } = context.options[0] || {};\n\n /**\n * @param {string} desc\n * @param {import('comment-parser').Spec} [tag]\n * @returns {void}\n */\n const validateDescription = (desc, tag) => {\n let mainDescriptionMatch = mainDescription;\n let errorMessage = message;\n if (typeof mainDescription === 'object') {\n mainDescriptionMatch = mainDescription.match;\n errorMessage = mainDescription.message;\n }\n\n if (mainDescriptionMatch === false && (\n !tag || !Object.hasOwn(tags, tag.tag))\n ) {\n return;\n }\n\n let tagValue = mainDescriptionMatch;\n if (tag) {\n const tagName = tag.tag;\n if (typeof tags[tagName] === 'object') {\n tagValue = tags[tagName].match;\n errorMessage = tags[tagName].message;\n } else {\n tagValue = tags[tagName];\n }\n }\n\n const regex = utils.getRegexFromString(\n stringOrDefault(tagValue, matchDescription),\n );\n\n if (!regex.test(desc)) {\n report(\n errorMessage || 'JSDoc description does not satisfy the regex pattern.',\n null,\n tag || {\n // Add one as description would typically be into block\n line: jsdoc.source[0].number + 1,\n },\n );\n }\n };\n\n const {\n description,\n } = utils.getDescription();\n if (description) {\n validateDescription(description);\n }\n\n /**\n * @param {string} tagName\n * @returns {boolean}\n */\n const hasNoTag = (tagName) => {\n return !tags[tagName];\n };\n\n for (const tag of [\n 'description',\n 'summary',\n 'file',\n 'classdesc',\n ]) {\n utils.forEachPreferredTag(tag, (matchingJsdocTag, targetTagName) => {\n const desc = (matchingJsdocTag.name + ' ' + utils.getTagDescription(matchingJsdocTag)).trim();\n if (hasNoTag(targetTagName)) {\n validateDescription(desc, matchingJsdocTag);\n }\n }, true);\n }\n\n if (nonemptyTags) {\n for (const tag of [\n 'copyright',\n 'example',\n 'see',\n 'todo',\n ]) {\n utils.forEachPreferredTag(tag, (matchingJsdocTag, targetTagName) => {\n const desc = (matchingJsdocTag.name + ' ' + utils.getTagDescription(matchingJsdocTag)).trim();\n\n if (hasNoTag(targetTagName) && !(/.+/v).test(desc)) {\n report(\n 'JSDoc description must not be empty.',\n null,\n matchingJsdocTag,\n );\n }\n });\n }\n }\n\n if (!Object.keys(tags).length) {\n return;\n }\n\n /**\n * @param {string} tagName\n * @returns {boolean}\n */\n const hasOptionTag = (tagName) => {\n return Boolean(tags[tagName]);\n };\n\n const whitelistedTags = utils.filterTags(({\n tag: tagName,\n }) => {\n return hasOptionTag(tagName);\n });\n const {\n tagsWithNames,\n tagsWithoutNames,\n } = utils.getTagsByType(whitelistedTags);\n\n tagsWithNames.some((tag) => {\n const desc = /** @type {string} */ (\n utils.getTagDescription(tag)\n ).replace(/^[\\- ]*/v, '')\n .trim();\n\n return validateDescription(desc, tag);\n });\n\n tagsWithoutNames.some((tag) => {\n const desc = (tag.name + ' ' + utils.getTagDescription(tag)).trim();\n\n return validateDescription(desc, tag);\n });\n}, {\n contextDefaults: true,\n meta: {\n docs: {\n description: 'Enforces a regular expression pattern on descriptions.',\n url: 'https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/match-description.md#repos-sticky-header',\n },\n schema: [\n {\n additionalProperties: false,\n properties: {\n contexts: {\n description: `Set this to an array of strings representing the AST context (or an object with\noptional \\`context\\` and \\`comment\\` properties) where you wish the rule to be applied (e.g.,\n\\`ClassDeclaration\\` for ES6 classes).\n\n\\`context\\` defaults to \\`any\\` and \\`comment\\` defaults to no specific comment context.\n\nOverrides the default contexts (\\`ArrowFunctionExpression\\`, \\`FunctionDeclaration\\`,\n\\`FunctionExpression\\`). Set to \\`\"any\"\\` if you want the rule to apply to any\nJSDoc block throughout your files.\n\nSee the [\"AST and Selectors\"](../advanced.md#ast-and-selectors)\nsection of our Advanced docs for more on the expected format.`,\n items: {\n anyOf: [\n {\n type: 'string',\n },\n {\n additionalProperties: false,\n properties: {\n comment: {\n type: 'string',\n },\n context: {\n type: 'string',\n },\n },\n type: 'object',\n },\n ],\n },\n type: 'array',\n },\n mainDescription: {\n description: `If you wish to override the main block description without changing the\ndefault \\`match-description\\` (which can cascade to the \\`tags\\` with \\`true\\`),\nyou may use \\`mainDescription\\`:\n\n\\`\\`\\`js\n{\n 'jsdoc/match-description': ['error', {\n mainDescription: '[A-Z].*\\\\\\\\.',\n tags: {\n param: true,\n returns: true\n }\n }]\n}\n\\`\\`\\`\n\nThere is no need to add \\`mainDescription: true\\`, as by default, the main\nblock description (and only the main block description) is linted, though you\nmay disable checking it by setting it to \\`false\\`.\n\nYou may also provide an object with \\`message\\`:\n\n\\`\\`\\`js\n{\n 'jsdoc/match-description': ['error', {\n mainDescription: {\n message: 'Capitalize first word of JSDoc block descriptions',\n match: '[A-Z].*\\\\\\\\.'\n },\n tags: {\n param: true,\n returns: true\n }\n }]\n}\n\\`\\`\\``,\n oneOf: [\n {\n format: 'regex',\n type: 'string',\n },\n {\n type: 'boolean',\n },\n {\n additionalProperties: false,\n properties: {\n match: {\n oneOf: [\n {\n format: 'regex',\n type: 'string',\n },\n {\n type: 'boolean',\n },\n ],\n },\n message: {\n type: 'string',\n },\n },\n type: 'object',\n },\n ],\n },\n matchDescription: {\n description: `You can supply your own expression to override the default, passing a\n\\`matchDescription\\` string on the options object.\n\nDefaults to using (only) the \\`v\\` flag, so\nto add your own flags, encapsulate your expression as a string, but like a\nliteral, e.g., \\`/[A-Z].*\\\\./vi\\`.\n\n\\`\\`\\`js\n{\n 'jsdoc/match-description': ['error', {matchDescription: '[A-Z].*\\\\\\\\.'}]\n}\n\\`\\`\\``,\n format: 'regex',\n type: 'string',\n },\n message: {\n description: `You may provide a custom default message by using the following format:\n\n\\`\\`\\`js\n{\n 'jsdoc/match-description': ['error', {\n message: 'The default description should begin with a capital letter.'\n }]\n}\n\\`\\`\\`\n\nThis can be overridden per tag or for the main block description by setting\n\\`message\\` within \\`tags\\` or \\`mainDescription\\`, respectively.`,\n type: 'string',\n },\n nonemptyTags: {\n description: `If not set to \\`false\\`, will enforce that the following tags have at least\nsome content:\n\n- \\`@copyright\\`\n- \\`@example\\`\n- \\`@see\\`\n- \\`@todo\\`\n\nIf you supply your own tag description for any of the above tags in \\`tags\\`,\nyour description will take precedence.`,\n type: 'boolean',\n },\n tags: {\n description: `If you want different regular expressions to apply to tags, you may use\nthe \\`tags\\` option object:\n\n\\`\\`\\`js\n{\n 'jsdoc/match-description': ['error', {tags: {\n param: '\\\\\\\\- [A-Z].*\\\\\\\\.',\n returns: '[A-Z].*\\\\\\\\.'\n }}]\n}\n\\`\\`\\`\n\nIn place of a string, you can also add \\`true\\` to indicate that a particular\ntag should be linted with the \\`matchDescription\\` value (or the default).\n\n\\`\\`\\`js\n{\n 'jsdoc/match-description': ['error', {tags: {\n param: true,\n returns: true\n }}]\n}\n\\`\\`\\`\n\nAlternatively, you may supply an object with a \\`message\\` property to indicate\nthe error message for that tag.\n\n\\`\\`\\`js\n{\n 'jsdoc/match-description': ['error', {tags: {\n param: {message: 'Begin with a hyphen', match: '\\\\\\\\- [A-Z].*\\\\\\\\.'},\n returns: {message: 'Capitalize for returns (the default)', match: true}\n }}]\n}\n\\`\\`\\`\n\nThe tags \\`@param\\`/\\`@arg\\`/\\`@argument\\` and \\`@property\\`/\\`@prop\\` will be properly\nparsed to ensure that the matched \"description\" text includes only the text\nafter the name.\n\nAll other tags will treat the text following the tag name, a space, and\nan optional curly-bracketed type expression (and another space) as part of\nits \"description\" (e.g., for \\`@returns {someType} some description\\`, the\ndescription is \\`some description\\` while for \\`@some-tag xyz\\`, the description\nis \\`xyz\\`).`,\n patternProperties: {\n '.*': {\n oneOf: [\n {\n format: 'regex',\n type: 'string',\n },\n {\n enum: [\n true,\n ],\n type: 'boolean',\n },\n {\n additionalProperties: false,\n properties: {\n match: {\n oneOf: [\n {\n format: 'regex',\n type: 'string',\n },\n {\n enum: [\n true,\n ],\n type: 'boolean',\n },\n ],\n },\n message: {\n type: 'string',\n },\n },\n type: 'object',\n },\n ],\n },\n },\n type: 'object',\n },\n },\n type: 'object',\n },\n ],\n type: 'suggestion',\n },\n});\n"],"mappings":"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ACF,CAAC;cACD,IAAI,EAAE;YACR,CAAC;UAEL,CAAC;UACD,IAAI,EAAE;QACR,CAAC;QACD,eAAe,EAAE;UACf,WAAW,EAAE;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;UACK,KAAK,EAAE,CACL;YACE,MAAM,EAAE,OAAO;YACf,IAAI,EAAE;UACR,CAAC,EACD;YACE,IAAI,EAAE;UACR,CAAC,EACD;YACE,oBAAoB,EAAE,KAAK;YAC3B,UAAU,EAAE;cACV,KAAK,EAAE;gBACL,KAAK,EAAE,CACL;kBACE,MAAM,EAAE,OAAO;kBACf,IAAI,EAAE;gBACR,CAAC,EACD;kBACE,IAAI,EAAE;gBACR,CAAC;cAEL,CAAC;cACD,OAAO,EAAE;gBACP,IAAI,EAAE;cACR;YACF,CAAC;YACD,IAAI,EAAE;UACR,CAAC;QAEL,CAAC;QACD,gBAAgB,EAAE;UAChB,WAAW,EAAE;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;UACK,MAAM,EAAE,OAAO;UACf,IAAI,EAAE;QACR,CAAC;QACD,OAAO,EAAE;UACP,WAAW,EAAE;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kEAAkE;UACtD,IAAI,EAAE;QACR,CAAC;QACD,YAAY,EAAE;UACZ,WAAW,EAAE;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC;UAC3B,IAAI,EAAE;QACR,CAAC;QACD,IAAI,EAAE;UACJ,WAAW,EAAE;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;UACD,iBAAiB,EAAE;YACjB,IAAI,EAAE;cACJ,KAAK,EAAE,CACL;gBACE,MAAM,EAAE,OAAO;gBACf,IAAI,EAAE;cACR,CAAC,EACD;gBACE,IAAI,EAAE,CACJ,IAAI,CACL;gBACD,IAAI,EAAE;cACR,CAAC,EACD;gBACE,oBAAoB,EAAE,KAAK;gBAC3B,UAAU,EAAE;kBACV,KAAK,EAAE;oBACL,KAAK,EAAE,CACL;sBACE,MAAM,EAAE,OAAO;sBACf,IAAI,EAAE;oBACR,CAAC,EACD;sBACE,IAAI,EAAE,CACJ,IAAI,CACL;sBACD,IAAI,EAAE;oBACR,CAAC;kBAEL,CAAC;kBACD,OAAO,EAAE;oBACP,IAAI,EAAE;kBACR;gBACF,CAAC;gBACD,IAAI,EAAE;cACR,CAAC;YAEL;UACF,CAAC;UACD,IAAI,EAAE;QACR;MACF,CAAC;MACD,IAAI,EAAE;IACR,CAAC,CACF;IACD,IAAI,EAAE;EACR;AACF,CAAC,CAAC;AAAA","ignoreList":[]}