| import iterateJsdoc from '../iterateJsdoc.js'; |
| |
| export default iterateJsdoc(({ |
| context, |
| indent, |
| jsdoc, |
| utils, |
| }) => { |
| const [ |
| defaultRequireValue = 'always', |
| { |
| tags: tagMap = {}, |
| } = {}, |
| ] = context.options; |
| |
| const { |
| source, |
| } = jsdoc; |
| |
| const always = defaultRequireValue === 'always'; |
| const never = defaultRequireValue === 'never'; |
| |
| /** @type {string} */ |
| let currentTag; |
| source.some(({ |
| number, |
| tokens, |
| }) => { |
| const { |
| delimiter, |
| description, |
| end, |
| tag, |
| } = tokens; |
| |
| /** |
| * @returns {void} |
| */ |
| const neverFix = () => { |
| tokens.delimiter = ''; |
| tokens.postDelimiter = ''; |
| }; |
| |
| /** |
| * @param {string} checkValue |
| * @returns {boolean} |
| */ |
| const checkNever = (checkValue) => { |
| if (delimiter && delimiter !== '/**' && ( |
| never && !tagMap.always?.includes(checkValue) || |
| tagMap.never?.includes(checkValue) |
| )) { |
| utils.reportJSDoc('Expected JSDoc line to have no prefix.', { |
| column: 0, |
| line: number, |
| }, neverFix); |
| |
| return true; |
| } |
| |
| return false; |
| }; |
| |
| /** |
| * @returns {void} |
| */ |
| const alwaysFix = () => { |
| if (!tokens.start) { |
| tokens.start = indent + ' '; |
| } |
| |
| tokens.delimiter = '*'; |
| tokens.postDelimiter = tag || description ? ' ' : ''; |
| }; |
| |
| /** |
| * @param {string} checkValue |
| * @returns {boolean} |
| */ |
| const checkAlways = (checkValue) => { |
| if ( |
| !delimiter && ( |
| always && !tagMap.never?.includes(checkValue) || |
| tagMap.always?.includes(checkValue) |
| ) |
| ) { |
| utils.reportJSDoc('Expected JSDoc line to have the prefix.', { |
| column: 0, |
| line: number, |
| }, alwaysFix); |
| |
| return true; |
| } |
| |
| return false; |
| }; |
| |
| if (tag) { |
| // Remove at sign |
| currentTag = tag.slice(1); |
| } |
| |
| if ( |
| // If this is the end but has a tag, the delimiter will also be |
| // populated and will be safely ignored later |
| end && !tag |
| ) { |
| return false; |
| } |
| |
| if (!currentTag) { |
| if (tagMap.any?.includes('*description')) { |
| return false; |
| } |
| |
| if (checkNever('*description')) { |
| return true; |
| } |
| |
| if (checkAlways('*description')) { |
| return true; |
| } |
| |
| return false; |
| } |
| |
| if (tagMap.any?.includes(currentTag)) { |
| return false; |
| } |
| |
| if (checkNever(currentTag)) { |
| return true; |
| } |
| |
| if (checkAlways(currentTag)) { |
| return true; |
| } |
| |
| return false; |
| }); |
| }, { |
| iterateAllJsdocs: true, |
| meta: { |
| docs: { |
| description: |
| 'Requires that each JSDoc line starts with an `*`.', |
| url: 'https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-asterisk-prefix.md#repos-sticky-header', |
| }, |
| fixable: 'code', |
| schema: [ |
| { |
| description: `If it is \`"always"\` then a problem is raised when there is no asterisk |
| prefix on a given JSDoc line. If it is \`"never"\` then a problem is raised |
| when there is an asterisk present. |
| |
| The default value is \`"always"\`. You may also set the default to \`"any"\` |
| and use the \`tags\` option to apply to specific tags only.`, |
| enum: [ |
| 'always', 'never', 'any', |
| ], |
| type: 'string', |
| }, |
| { |
| additionalProperties: false, |
| properties: { |
| tags: { |
| additionalProperties: false, |
| description: `If you want different values to apply to specific tags, you may use |
| the \`tags\` option object. The keys are \`always\`, \`never\`, or \`any\` and |
| the values are arrays of tag names or the special value \`*description\` |
| which applies to the main JSDoc block description. |
| |
| \`\`\`js |
| { |
| 'jsdoc/require-asterisk-prefix': ['error', 'always', { |
| tags: { |
| always: ['*description'], |
| any: ['example', 'license'], |
| never: ['copyright'] |
| } |
| }] |
| } |
| \`\`\``, |
| properties: { |
| always: { |
| description: `If it is \`"always"\` then a problem is raised when there is no asterisk |
| prefix on a given JSDoc line.`, |
| items: { |
| type: 'string', |
| }, |
| type: 'array', |
| }, |
| any: { |
| description: 'No problem is raised regardless of asterisk presence or non-presence.', |
| items: { |
| type: 'string', |
| }, |
| type: 'array', |
| }, |
| never: { |
| description: `If it is \`"never"\` then a problem is raised |
| when there is an asterisk present.`, |
| items: { |
| type: 'string', |
| }, |
| type: 'array', |
| }, |
| }, |
| type: 'object', |
| }, |
| }, |
| type: 'object', |
| }, |
| ], |
| type: 'layout', |
| }, |
| }); |