UNPKG

eslint-plugin-jsdoc

Version:
1 lines 10.6 kB
{"version":3,"file":"checkIndentation.cjs","names":["_iterateJsdoc","_interopRequireDefault","require","e","__esModule","default","maskExcludedContent","str","excludeTags","regContent","RegExp","join","replace","_match","margin","code","repeat","match","length","maskCodeBlocks","replaceAll","getLineNumber","lines","lineIndex","precedingText","slice","lineBreaks","_default","exports","iterateJsdoc","context","jsdocNode","report","sourceCode","options","allowIndentedSections","textWithoutCodeBlocks","getText","text","split","hasSeenContent","currentSectionIndent","line","entries","indentMatch","afterIndent","indentAmount","test","trim","reg","lastIndex","iterateAllJsdocs","meta","docs","description","url","schema","additionalProperties","properties","type","items","pattern","module"],"sources":["../../src/rules/checkIndentation.js"],"sourcesContent":["import iterateJsdoc from '../iterateJsdoc.js';\n\n/**\n * @param {string} str\n * @param {string[]} excludeTags\n * @returns {string}\n */\nconst maskExcludedContent = (str, excludeTags) => {\n const regContent = new RegExp(`([ \\\\t]+\\\\*)[ \\\\t]@(?:${excludeTags.join('|')})(?=[ \\\\n])([\\\\w\\\\|\\\\W]*?\\\\n)(?=[ \\\\t]*\\\\*(?:[ \\\\t]*@\\\\w+\\\\s|\\\\/))`, 'gv');\n\n return str.replace(regContent, (_match, margin, code) => {\n return (margin + '\\n').repeat(code.match(/\\n/gv).length);\n });\n};\n\n/**\n * @param {string} str\n * @returns {string}\n */\nconst maskCodeBlocks = (str) => {\n const regContent = /([ \\t]+\\*)[ \\t]```[^\\n]*?([\\w\\|\\W]*?\\n)(?=[ \\t]*\\*(?:[ \\t]*(?:```|@\\w+\\s)|\\/))/gv;\n\n return str.replaceAll(regContent, (_match, margin, code) => {\n return (margin + '\\n').repeat(code.match(/\\n/gv).length);\n });\n};\n\n/**\n * @param {string[]} lines\n * @param {number} lineIndex\n * @returns {number}\n */\nconst getLineNumber = (lines, lineIndex) => {\n const precedingText = lines.slice(0, lineIndex).join('\\n');\n const lineBreaks = precedingText.match(/\\n/gv) || [];\n return lineBreaks.length + 1;\n};\n\nexport default iterateJsdoc(({\n context,\n jsdocNode,\n report,\n sourceCode,\n}) => {\n const options = context.options[0] || {};\n const /** @type {{excludeTags: string[], allowIndentedSections: boolean}} */ {\n allowIndentedSections = false,\n excludeTags = [\n 'example',\n ],\n } = options;\n\n const textWithoutCodeBlocks = maskCodeBlocks(sourceCode.getText(jsdocNode));\n const text = excludeTags.length ? maskExcludedContent(textWithoutCodeBlocks, excludeTags) : textWithoutCodeBlocks;\n\n if (allowIndentedSections) {\n // When allowIndentedSections is enabled, only check for indentation on tag lines\n // and the very first line of the main description\n const lines = text.split('\\n');\n let hasSeenContent = false;\n let currentSectionIndent = null;\n\n for (const [\n lineIndex,\n line,\n ] of lines.entries()) {\n // Check for indentation (two or more spaces after *)\n const indentMatch = line.match(/^(?:\\/?\\**|[\\t ]*)\\*([\\t ]{2,})/v);\n\n if (indentMatch) {\n // Check what comes after the indentation\n const afterIndent = line.slice(indentMatch[0].length);\n const indentAmount = indentMatch[1].length;\n\n // If this is a tag line with indentation, always report\n if (/^@\\w+/v.test(afterIndent)) {\n report('There must be no indentation.', null, {\n line: getLineNumber(lines, lineIndex),\n });\n return;\n }\n\n // If we haven't seen any content yet (main description first line) and there's content, report\n if (!hasSeenContent && afterIndent.trim().length > 0) {\n report('There must be no indentation.', null, {\n line: getLineNumber(lines, lineIndex),\n });\n return;\n }\n\n // For continuation lines, check consistency\n if (hasSeenContent && afterIndent.trim().length > 0) {\n if (currentSectionIndent === null) {\n // First indented line in this section, set the indent level\n currentSectionIndent = indentAmount;\n } else if (indentAmount < currentSectionIndent) {\n // Indentation is less than the established level (inconsistent)\n report('There must be no indentation.', null, {\n line: getLineNumber(lines, lineIndex),\n });\n return;\n }\n }\n } else if (/^\\s*\\*\\s+\\S/v.test(line)) {\n // No indentation on this line, reset section indent tracking\n // (unless it's just whitespace or a closing comment)\n currentSectionIndent = null;\n }\n\n // Track if we've seen any content (non-whitespace after the *)\n if (/^\\s*\\*\\s+\\S/v.test(line)) {\n hasSeenContent = true;\n }\n\n // Reset section indent when we encounter a tag\n if (/@\\w+/v.test(line)) {\n currentSectionIndent = null;\n }\n }\n } else {\n const reg = /^(?:\\/?\\**|[ \\t]*)\\*[ \\t]{2}/gmv;\n if (reg.test(text)) {\n const lineBreaks = text.slice(0, reg.lastIndex).match(/\\n/gv) || [];\n report('There must be no indentation.', null, {\n line: lineBreaks.length,\n });\n }\n }\n}, {\n iterateAllJsdocs: true,\n meta: {\n docs: {\n description: 'Reports invalid padding inside JSDoc blocks.',\n url: 'https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/check-indentation.md#repos-sticky-header',\n },\n schema: [\n {\n additionalProperties: false,\n properties: {\n allowIndentedSections: {\n description: 'Allows indentation of nested sections on subsequent lines (like bullet lists)',\n type: 'boolean',\n },\n excludeTags: {\n description: `Array of tags (e.g., \\`['example', 'description']\\`) whose content will be\n\"hidden\" from the \\`check-indentation\\` rule. Defaults to \\`['example']\\`.\n\nBy default, the whole JSDoc block will be checked for invalid padding.\nThat would include \\`@example\\` blocks too, which can get in the way\nof adding full, readable examples of code without ending up with multiple\nlinting issues.\n\nWhen disabled (by passing \\`excludeTags: []\\` option), the following code *will*\nreport a padding issue:\n\n\\`\\`\\`js\n/**\n * @example\n * anArray.filter((a) => {\n * return a.b;\n * });\n */\n\\`\\`\\``,\n items: {\n pattern: '^\\\\S+$',\n type: 'string',\n },\n type: 'array',\n },\n },\n type: 'object',\n },\n ],\n type: 'layout',\n },\n});\n"],"mappings":"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","ignoreList":[]}