eslint-plugin-jsdoc 55.3.0 → 56.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (156) hide show
  1. package/dist/cjs/WarnSettings.d.ts +16 -0
  2. package/dist/cjs/WarnSettings.js +30 -0
  3. package/dist/cjs/alignTransform.d.ts +33 -0
  4. package/dist/cjs/alignTransform.js +285 -0
  5. package/dist/cjs/defaultTagOrder.d.ts +4 -0
  6. package/dist/cjs/defaultTagOrder.js +152 -0
  7. package/dist/cjs/exportParser.d.ts +40 -0
  8. package/dist/cjs/exportParser.js +754 -0
  9. package/dist/cjs/getDefaultTagStructureForMode.d.ts +10 -0
  10. package/dist/cjs/getDefaultTagStructureForMode.js +840 -0
  11. package/dist/cjs/getJsdocProcessorPlugin.cjs +4 -0
  12. package/dist/cjs/getJsdocProcessorPlugin.d.cts +1 -0
  13. package/dist/cjs/getJsdocProcessorPlugin.d.ts +66 -0
  14. package/dist/cjs/getJsdocProcessorPlugin.js +553 -0
  15. package/dist/cjs/index-cjs.d.ts +16 -0
  16. package/dist/cjs/index-cjs.js +492 -0
  17. package/dist/cjs/index.cjs.cjs +6 -0
  18. package/dist/cjs/index.cjs.d.cts +2 -0
  19. package/dist/cjs/iterateJsdoc.cjs +38 -0
  20. package/dist/cjs/iterateJsdoc.d.cts +2 -0
  21. package/dist/cjs/iterateJsdoc.d.ts +462 -0
  22. package/dist/cjs/iterateJsdoc.js +1981 -0
  23. package/dist/cjs/jsdocUtils.d.ts +454 -0
  24. package/dist/cjs/jsdocUtils.js +1470 -0
  25. package/dist/cjs/rules/checkAccess.d.ts +2 -0
  26. package/dist/cjs/rules/checkAccess.js +35 -0
  27. package/dist/cjs/rules/checkAlignment.d.ts +2 -0
  28. package/dist/cjs/rules/checkAlignment.js +63 -0
  29. package/dist/cjs/rules/checkExamples.d.ts +3 -0
  30. package/dist/cjs/rules/checkExamples.js +486 -0
  31. package/dist/cjs/rules/checkIndentation.d.ts +2 -0
  32. package/dist/cjs/rules/checkIndentation.js +66 -0
  33. package/dist/cjs/rules/checkLineAlignment.d.ts +9 -0
  34. package/dist/cjs/rules/checkLineAlignment.js +297 -0
  35. package/dist/cjs/rules/checkParamNames.d.ts +2 -0
  36. package/dist/cjs/rules/checkParamNames.js +320 -0
  37. package/dist/cjs/rules/checkPropertyNames.d.ts +2 -0
  38. package/dist/cjs/rules/checkPropertyNames.js +105 -0
  39. package/dist/cjs/rules/checkSyntax.d.ts +2 -0
  40. package/dist/cjs/rules/checkSyntax.js +27 -0
  41. package/dist/cjs/rules/checkTagNames.d.ts +2 -0
  42. package/dist/cjs/rules/checkTagNames.js +252 -0
  43. package/dist/cjs/rules/checkTemplateNames.d.ts +2 -0
  44. package/dist/cjs/rules/checkTemplateNames.js +189 -0
  45. package/dist/cjs/rules/checkTypes.d.ts +2 -0
  46. package/dist/cjs/rules/checkTypes.js +421 -0
  47. package/dist/cjs/rules/checkValues.d.ts +2 -0
  48. package/dist/cjs/rules/checkValues.js +163 -0
  49. package/dist/cjs/rules/convertToJsdocComments.d.ts +251 -0
  50. package/dist/cjs/rules/convertToJsdocComments.js +313 -0
  51. package/dist/cjs/rules/emptyTags.d.ts +2 -0
  52. package/dist/cjs/rules/emptyTags.js +79 -0
  53. package/dist/cjs/rules/implementsOnClasses.d.ts +2 -0
  54. package/dist/cjs/rules/implementsOnClasses.js +63 -0
  55. package/dist/cjs/rules/importsAsDependencies.d.ts +2 -0
  56. package/dist/cjs/rules/importsAsDependencies.js +105 -0
  57. package/dist/cjs/rules/informativeDocs.d.ts +2 -0
  58. package/dist/cjs/rules/informativeDocs.js +153 -0
  59. package/dist/cjs/rules/linesBeforeBlock.d.ts +2 -0
  60. package/dist/cjs/rules/linesBeforeBlock.js +106 -0
  61. package/dist/cjs/rules/matchDescription.d.ts +2 -0
  62. package/dist/cjs/rules/matchDescription.js +240 -0
  63. package/dist/cjs/rules/matchName.d.ts +2 -0
  64. package/dist/cjs/rules/matchName.js +122 -0
  65. package/dist/cjs/rules/multilineBlocks.d.ts +2 -0
  66. package/dist/cjs/rules/multilineBlocks.js +339 -0
  67. package/dist/cjs/rules/noBadBlocks.d.ts +2 -0
  68. package/dist/cjs/rules/noBadBlocks.js +88 -0
  69. package/dist/cjs/rules/noBlankBlockDescriptions.d.ts +2 -0
  70. package/dist/cjs/rules/noBlankBlockDescriptions.js +56 -0
  71. package/dist/cjs/rules/noBlankBlocks.d.ts +2 -0
  72. package/dist/cjs/rules/noBlankBlocks.js +41 -0
  73. package/dist/cjs/rules/noDefaults.d.ts +2 -0
  74. package/dist/cjs/rules/noDefaults.js +84 -0
  75. package/dist/cjs/rules/noMissingSyntax.d.ts +9 -0
  76. package/dist/cjs/rules/noMissingSyntax.js +164 -0
  77. package/dist/cjs/rules/noMultiAsterisks.d.ts +2 -0
  78. package/dist/cjs/rules/noMultiAsterisks.js +83 -0
  79. package/dist/cjs/rules/noRestrictedSyntax.d.ts +2 -0
  80. package/dist/cjs/rules/noRestrictedSyntax.js +75 -0
  81. package/dist/cjs/rules/noTypes.d.ts +2 -0
  82. package/dist/cjs/rules/noTypes.js +88 -0
  83. package/dist/cjs/rules/noUndefinedTypes.d.ts +2 -0
  84. package/dist/cjs/rules/noUndefinedTypes.js +451 -0
  85. package/dist/cjs/rules/requireAsteriskPrefix.d.ts +2 -0
  86. package/dist/cjs/rules/requireAsteriskPrefix.js +144 -0
  87. package/dist/cjs/rules/requireDescription.d.ts +2 -0
  88. package/dist/cjs/rules/requireDescription.js +136 -0
  89. package/dist/cjs/rules/requireDescriptionCompleteSentence.d.ts +2 -0
  90. package/dist/cjs/rules/requireDescriptionCompleteSentence.js +258 -0
  91. package/dist/cjs/rules/requireExample.d.ts +2 -0
  92. package/dist/cjs/rules/requireExample.js +103 -0
  93. package/dist/cjs/rules/requireFileOverview.d.ts +2 -0
  94. package/dist/cjs/rules/requireFileOverview.js +117 -0
  95. package/dist/cjs/rules/requireHyphenBeforeParamDescription.d.ts +2 -0
  96. package/dist/cjs/rules/requireHyphenBeforeParamDescription.js +144 -0
  97. package/dist/cjs/rules/requireJsdoc.d.ts +25 -0
  98. package/dist/cjs/rules/requireJsdoc.js +629 -0
  99. package/dist/cjs/rules/requireParam.d.ts +3 -0
  100. package/dist/cjs/rules/requireParam.js +480 -0
  101. package/dist/cjs/rules/requireParamDescription.d.ts +2 -0
  102. package/dist/cjs/rules/requireParamDescription.js +77 -0
  103. package/dist/cjs/rules/requireParamName.d.ts +2 -0
  104. package/dist/cjs/rules/requireParamName.js +52 -0
  105. package/dist/cjs/rules/requireParamType.d.ts +2 -0
  106. package/dist/cjs/rules/requireParamType.js +77 -0
  107. package/dist/cjs/rules/requireProperty.d.ts +2 -0
  108. package/dist/cjs/rules/requireProperty.js +44 -0
  109. package/dist/cjs/rules/requirePropertyDescription.d.ts +2 -0
  110. package/dist/cjs/rules/requirePropertyDescription.js +22 -0
  111. package/dist/cjs/rules/requirePropertyName.d.ts +2 -0
  112. package/dist/cjs/rules/requirePropertyName.js +22 -0
  113. package/dist/cjs/rules/requirePropertyType.d.ts +2 -0
  114. package/dist/cjs/rules/requirePropertyType.js +22 -0
  115. package/dist/cjs/rules/requireReturns.d.ts +2 -0
  116. package/dist/cjs/rules/requireReturns.js +197 -0
  117. package/dist/cjs/rules/requireReturnsCheck.d.ts +2 -0
  118. package/dist/cjs/rules/requireReturnsCheck.js +108 -0
  119. package/dist/cjs/rules/requireReturnsDescription.d.ts +2 -0
  120. package/dist/cjs/rules/requireReturnsDescription.js +58 -0
  121. package/dist/cjs/rules/requireReturnsType.d.ts +2 -0
  122. package/dist/cjs/rules/requireReturnsType.js +52 -0
  123. package/dist/cjs/rules/requireTemplate.d.ts +2 -0
  124. package/dist/cjs/rules/requireTemplate.js +173 -0
  125. package/dist/cjs/rules/requireThrows.d.ts +2 -0
  126. package/dist/cjs/rules/requireThrows.js +101 -0
  127. package/dist/cjs/rules/requireYields.d.ts +2 -0
  128. package/dist/cjs/rules/requireYields.js +172 -0
  129. package/dist/cjs/rules/requireYieldsCheck.d.ts +2 -0
  130. package/dist/cjs/rules/requireYieldsCheck.js +164 -0
  131. package/dist/cjs/rules/sortTags.d.ts +2 -0
  132. package/dist/cjs/rules/sortTags.js +392 -0
  133. package/dist/cjs/rules/tagLines.d.ts +2 -0
  134. package/dist/cjs/rules/tagLines.js +259 -0
  135. package/dist/cjs/rules/textEscaping.d.ts +2 -0
  136. package/dist/cjs/rules/textEscaping.js +125 -0
  137. package/dist/cjs/rules/typeFormatting.d.ts +2 -0
  138. package/dist/cjs/rules/typeFormatting.js +328 -0
  139. package/dist/cjs/rules/validTypes.d.ts +2 -0
  140. package/dist/cjs/rules/validTypes.js +333 -0
  141. package/dist/cjs/tagNames.d.ts +15 -0
  142. package/dist/cjs/tagNames.js +209 -0
  143. package/dist/cjs/utils/hasReturnValue.d.ts +19 -0
  144. package/dist/cjs/utils/hasReturnValue.js +469 -0
  145. package/dist/getJsdocProcessorPlugin.cts +3 -0
  146. package/dist/index.cjs.cts +3 -0
  147. package/dist/iterateJsdoc.cts +6 -0
  148. package/dist/rules/typeFormatting.cjs +82 -38
  149. package/dist/rules/typeFormatting.cjs.map +1 -1
  150. package/dist/rules.d.ts +4 -7
  151. package/package.json +24 -13
  152. package/src/getJsdocProcessorPlugin.cts +3 -0
  153. package/src/index.cjs.cts +3 -0
  154. package/src/iterateJsdoc.cts +6 -0
  155. package/src/rules/typeFormatting.js +104 -40
  156. package/src/rules.d.ts +4 -7
@@ -0,0 +1,136 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const iterateJsdoc_js_1 = __importDefault(require("../iterateJsdoc.js"));
7
+ /**
8
+ * @param {string} description
9
+ * @returns {import('../iterateJsdoc.js').Integer}
10
+ */
11
+ const checkDescription = (description) => {
12
+ return description
13
+ .trim()
14
+ .split('\n')
15
+ .filter(Boolean)
16
+ .length;
17
+ };
18
+ exports.default = (0, iterateJsdoc_js_1.default)(({ context, jsdoc, report, utils, }) => {
19
+ if (utils.avoidDocs()) {
20
+ return;
21
+ }
22
+ const { descriptionStyle = 'body', } = context.options[0] || {};
23
+ let targetTagName = utils.getPreferredTagName({
24
+ // We skip reporting except when `@description` is essential to the rule,
25
+ // so user can block the tag and still meaningfully use this rule
26
+ // even if the tag is present (and `check-tag-names` is the one to
27
+ // normally report the fact that it is blocked but present)
28
+ skipReportingBlockedTag: descriptionStyle !== 'tag',
29
+ tagName: 'description',
30
+ });
31
+ if (!targetTagName) {
32
+ return;
33
+ }
34
+ const isBlocked = typeof targetTagName === 'object' && 'blocked' in targetTagName && targetTagName.blocked;
35
+ if (isBlocked) {
36
+ targetTagName = /** @type {{blocked: true; tagName: string;}} */ (targetTagName).tagName;
37
+ }
38
+ if (descriptionStyle !== 'tag') {
39
+ const { description, } = utils.getDescription();
40
+ if (checkDescription(description || '')) {
41
+ return;
42
+ }
43
+ if (descriptionStyle === 'body') {
44
+ const descTags = utils.getPresentTags([
45
+ 'desc', 'description',
46
+ ]);
47
+ if (descTags.length) {
48
+ const [{ tag: tagName, },] = descTags;
49
+ report(`Remove the @${tagName} tag to leave a plain block description or add additional description text above the @${tagName} line.`);
50
+ }
51
+ else {
52
+ report('Missing JSDoc block description.');
53
+ }
54
+ return;
55
+ }
56
+ }
57
+ const functionExamples = isBlocked ?
58
+ [] :
59
+ jsdoc.tags.filter(({ tag, }) => {
60
+ return tag === targetTagName;
61
+ });
62
+ if (!functionExamples.length) {
63
+ report(descriptionStyle === 'any' ?
64
+ `Missing JSDoc block description or @${targetTagName} declaration.` :
65
+ `Missing JSDoc @${targetTagName} declaration.`);
66
+ return;
67
+ }
68
+ for (const example of functionExamples) {
69
+ if (!checkDescription(`${example.name} ${utils.getTagDescription(example)}`)) {
70
+ report(`Missing JSDoc @${targetTagName} description.`, null, example);
71
+ }
72
+ }
73
+ }, {
74
+ contextDefaults: true,
75
+ meta: {
76
+ docs: {
77
+ description: 'Requires that all functions have a description.',
78
+ url: 'https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-description.md#repos-sticky-header',
79
+ },
80
+ schema: [
81
+ {
82
+ additionalProperties: false,
83
+ properties: {
84
+ checkConstructors: {
85
+ default: true,
86
+ type: 'boolean',
87
+ },
88
+ checkGetters: {
89
+ default: true,
90
+ type: 'boolean',
91
+ },
92
+ checkSetters: {
93
+ default: true,
94
+ type: 'boolean',
95
+ },
96
+ contexts: {
97
+ items: {
98
+ anyOf: [
99
+ {
100
+ type: 'string',
101
+ },
102
+ {
103
+ additionalProperties: false,
104
+ properties: {
105
+ comment: {
106
+ type: 'string',
107
+ },
108
+ context: {
109
+ type: 'string',
110
+ },
111
+ },
112
+ type: 'object',
113
+ },
114
+ ],
115
+ },
116
+ type: 'array',
117
+ },
118
+ descriptionStyle: {
119
+ enum: [
120
+ 'body', 'tag', 'any',
121
+ ],
122
+ type: 'string',
123
+ },
124
+ exemptedBy: {
125
+ items: {
126
+ type: 'string',
127
+ },
128
+ type: 'array',
129
+ },
130
+ },
131
+ type: 'object',
132
+ },
133
+ ],
134
+ type: 'suggestion',
135
+ },
136
+ });
@@ -0,0 +1,2 @@
1
+ declare const _default: import("eslint").Rule.RuleModule;
2
+ export default _default;
@@ -0,0 +1,258 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const iterateJsdoc_js_1 = __importDefault(require("../iterateJsdoc.js"));
7
+ const escape_string_regexp_1 = __importDefault(require("escape-string-regexp"));
8
+ const otherDescriptiveTags = new Set([
9
+ 'classdesc', 'deprecated', 'exception', 'file', 'fileoverview', 'overview',
10
+ // 'copyright' and 'see' might be good addition, but as the former may be
11
+ // sensitive text, and the latter may have just a link, they are not
12
+ // included by default
13
+ 'summary', 'throws', 'todo', 'yield', 'yields',
14
+ ]);
15
+ /**
16
+ * @param {string} text
17
+ * @returns {string[]}
18
+ */
19
+ const extractParagraphs = (text) => {
20
+ return text.split(/(?<![;:])\n\n+/v);
21
+ };
22
+ /**
23
+ * @param {string} text
24
+ * @param {string|RegExp} abbreviationsRegex
25
+ * @returns {string[]}
26
+ */
27
+ const extractSentences = (text, abbreviationsRegex) => {
28
+ const txt = text
29
+ // Remove all {} tags.
30
+ .replaceAll(/(?<!^)\{[\s\S]*?\}\s*/gv, '')
31
+ // Remove custom abbreviations
32
+ .replace(abbreviationsRegex, '');
33
+ const sentenceEndGrouping = /([.?!])(?:\s+|$)/gv;
34
+ const puncts = [
35
+ ...txt.matchAll(sentenceEndGrouping),
36
+ ].map((sentEnd) => {
37
+ return sentEnd[0];
38
+ });
39
+ return txt
40
+ .split(/[.?!](?:\s+|$)/v)
41
+ // Re-add the dot.
42
+ .map((sentence, idx) => {
43
+ return !puncts[idx] && /^\s*$/v.test(sentence) ? sentence : `${sentence}${puncts[idx] || ''}`;
44
+ });
45
+ };
46
+ /**
47
+ * @param {string} text
48
+ * @returns {boolean}
49
+ */
50
+ const isNewLinePrecededByAPeriod = (text) => {
51
+ /** @type {boolean} */
52
+ let lastLineEndsSentence;
53
+ const lines = text.split('\n');
54
+ return !lines.some((line) => {
55
+ if (lastLineEndsSentence === false && /^[A-Z][a-z]/v.test(line)) {
56
+ return true;
57
+ }
58
+ lastLineEndsSentence = /[.:?!\|]$/v.test(line);
59
+ return false;
60
+ });
61
+ };
62
+ /**
63
+ * @param {string} str
64
+ * @returns {boolean}
65
+ */
66
+ const isCapitalized = (str) => {
67
+ return str[0] === str[0].toUpperCase();
68
+ };
69
+ /**
70
+ * @param {string} str
71
+ * @returns {boolean}
72
+ */
73
+ const isTable = (str) => {
74
+ return str.charAt(0) === '|';
75
+ };
76
+ /**
77
+ * @param {string} str
78
+ * @returns {string}
79
+ */
80
+ const capitalize = (str) => {
81
+ return str.charAt(0).toUpperCase() + str.slice(1);
82
+ };
83
+ /**
84
+ * @param {string} description
85
+ * @param {import('../iterateJsdoc.js').Report} reportOrig
86
+ * @param {import('eslint').Rule.Node} jsdocNode
87
+ * @param {string|RegExp} abbreviationsRegex
88
+ * @param {import('eslint').SourceCode} sourceCode
89
+ * @param {import('comment-parser').Spec|{
90
+ * line: import('../iterateJsdoc.js').Integer
91
+ * }} tag
92
+ * @param {boolean} newlineBeforeCapsAssumesBadSentenceEnd
93
+ * @returns {boolean}
94
+ */
95
+ const validateDescription = (description, reportOrig, jsdocNode, abbreviationsRegex, sourceCode, tag, newlineBeforeCapsAssumesBadSentenceEnd) => {
96
+ if (!description || (/^\n+$/v).test(description)) {
97
+ return false;
98
+ }
99
+ const descriptionNoHeadings = description.replaceAll(/^\s*#[^\n]*(\n|$)/gmv, '');
100
+ const paragraphs = extractParagraphs(descriptionNoHeadings).filter(Boolean);
101
+ return paragraphs.some((paragraph, parIdx) => {
102
+ const sentences = extractSentences(paragraph, abbreviationsRegex);
103
+ const fix = /** @type {import('eslint').Rule.ReportFixer} */ (fixer) => {
104
+ let text = sourceCode.getText(jsdocNode);
105
+ if (!/[.:?!]$/v.test(paragraph)) {
106
+ const line = paragraph.split('\n').findLast(Boolean);
107
+ text = text.replace(new RegExp(`${(0, escape_string_regexp_1.default)(
108
+ /** @type {string} */
109
+ (line))}$`, 'mv'), `${line}.`);
110
+ }
111
+ for (const sentence of sentences.filter((sentence_) => {
112
+ return !(/^\s*$/v).test(sentence_) && !isCapitalized(sentence_) &&
113
+ !isTable(sentence_);
114
+ })) {
115
+ const beginning = sentence.split('\n')[0];
116
+ if ('tag' in tag && tag.tag) {
117
+ const reg = new RegExp(`(@${(0, escape_string_regexp_1.default)(tag.tag)}.*)${(0, escape_string_regexp_1.default)(beginning)}`, 'v');
118
+ text = text.replace(reg, (_$0, $1) => {
119
+ return $1 + capitalize(beginning);
120
+ });
121
+ }
122
+ else {
123
+ text = text.replace(new RegExp('((?:[.?!]|\\*|\\})\\s*)' + (0, escape_string_regexp_1.default)(beginning), 'v'), '$1' + capitalize(beginning));
124
+ }
125
+ }
126
+ return fixer.replaceText(jsdocNode, text);
127
+ };
128
+ /**
129
+ * @param {string} msg
130
+ * @param {import('eslint').Rule.ReportFixer | null | undefined} fixer
131
+ * @param {{
132
+ * line?: number | undefined;
133
+ * column?: number | undefined;
134
+ * } | (import('comment-parser').Spec & {
135
+ * line?: number | undefined;
136
+ * column?: number | undefined;
137
+ * })} tagObj
138
+ * @returns {void}
139
+ */
140
+ const report = (msg, fixer, tagObj) => {
141
+ if ('line' in tagObj) {
142
+ /**
143
+ * @type {{
144
+ * line: number;
145
+ * }}
146
+ */ (tagObj).line += parIdx * 2;
147
+ }
148
+ else {
149
+ /** @type {import('comment-parser').Spec} */ (tagObj).source[0].number += parIdx * 2;
150
+ }
151
+ // Avoid errors if old column doesn't exist here
152
+ tagObj.column = 0;
153
+ reportOrig(msg, fixer, tagObj);
154
+ };
155
+ if (sentences.some((sentence) => {
156
+ return (/^[.?!]$/v).test(sentence);
157
+ })) {
158
+ report('Sentences must be more than punctuation.', null, tag);
159
+ }
160
+ if (sentences.some((sentence) => {
161
+ return !(/^\s*$/v).test(sentence) && !isCapitalized(sentence) && !isTable(sentence);
162
+ })) {
163
+ report('Sentences should start with an uppercase character.', fix, tag);
164
+ }
165
+ const paragraphNoAbbreviations = paragraph.replace(abbreviationsRegex, '');
166
+ if (!/(?:[.?!\|]|```)\s*$/v.test(paragraphNoAbbreviations)) {
167
+ report('Sentences must end with a period.', fix, tag);
168
+ return true;
169
+ }
170
+ if (newlineBeforeCapsAssumesBadSentenceEnd && !isNewLinePrecededByAPeriod(paragraphNoAbbreviations)) {
171
+ report('A line of text is started with an uppercase character, but the preceding line does not end the sentence.', null, tag);
172
+ return true;
173
+ }
174
+ return false;
175
+ });
176
+ };
177
+ exports.default = (0, iterateJsdoc_js_1.default)(({ context, jsdoc, jsdocNode, report, sourceCode, utils, }) => {
178
+ const /** @type {{abbreviations: string[], newlineBeforeCapsAssumesBadSentenceEnd: boolean}} */ { abbreviations = [], newlineBeforeCapsAssumesBadSentenceEnd = false, } = context.options[0] || {};
179
+ const abbreviationsRegex = abbreviations.length ?
180
+ new RegExp('\\b' + abbreviations.map((abbreviation) => {
181
+ return (0, escape_string_regexp_1.default)(abbreviation.replaceAll(/\.$/gv, '') + '.');
182
+ }).join('|') + '(?:$|\\s)', 'gv') :
183
+ '';
184
+ let { description, } = utils.getDescription();
185
+ const indices = [
186
+ ...description.matchAll(/```[\s\S]*```/gv),
187
+ ].map((match) => {
188
+ const { index, } = match;
189
+ const [{ length, },] = match;
190
+ return {
191
+ index,
192
+ length,
193
+ };
194
+ }).toReversed();
195
+ for (const { index, length, } of indices) {
196
+ description = description.slice(0, index) +
197
+ description.slice(/** @type {import('../iterateJsdoc.js').Integer} */ (index) + length);
198
+ }
199
+ if (validateDescription(description, report, jsdocNode, abbreviationsRegex, sourceCode, {
200
+ line: jsdoc.source[0].number + 1,
201
+ }, newlineBeforeCapsAssumesBadSentenceEnd)) {
202
+ return;
203
+ }
204
+ utils.forEachPreferredTag('description', (matchingJsdocTag) => {
205
+ const desc = `${matchingJsdocTag.name} ${utils.getTagDescription(matchingJsdocTag)}`.trim();
206
+ validateDescription(desc, report, jsdocNode, abbreviationsRegex, sourceCode, matchingJsdocTag, newlineBeforeCapsAssumesBadSentenceEnd);
207
+ }, true);
208
+ const { tagsWithNames, } = utils.getTagsByType(jsdoc.tags);
209
+ const tagsWithoutNames = utils.filterTags(({ tag: tagName, }) => {
210
+ return otherDescriptiveTags.has(tagName) ||
211
+ utils.hasOptionTag(tagName) && !tagsWithNames.some(({ tag, }) => {
212
+ // If user accidentally adds tags with names (or like `returns`
213
+ // get parsed as having names), do not add to this list
214
+ return tag === tagName;
215
+ });
216
+ });
217
+ tagsWithNames.some((tag) => {
218
+ const desc = /** @type {string} */ (utils.getTagDescription(tag)).replace(/^- /v, '').trimEnd();
219
+ return validateDescription(desc, report, jsdocNode, abbreviationsRegex, sourceCode, tag, newlineBeforeCapsAssumesBadSentenceEnd);
220
+ });
221
+ tagsWithoutNames.some((tag) => {
222
+ const desc = `${tag.name} ${utils.getTagDescription(tag)}`.trim();
223
+ return validateDescription(desc, report, jsdocNode, abbreviationsRegex, sourceCode, tag, newlineBeforeCapsAssumesBadSentenceEnd);
224
+ });
225
+ }, {
226
+ iterateAllJsdocs: true,
227
+ meta: {
228
+ docs: {
229
+ description: 'Requires that block description, explicit `@description`, and `@param`/`@returns` tag descriptions are written in complete sentences.',
230
+ url: 'https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-description-complete-sentence.md#repos-sticky-header',
231
+ },
232
+ fixable: 'code',
233
+ schema: [
234
+ {
235
+ additionalProperties: false,
236
+ properties: {
237
+ abbreviations: {
238
+ items: {
239
+ type: 'string',
240
+ },
241
+ type: 'array',
242
+ },
243
+ newlineBeforeCapsAssumesBadSentenceEnd: {
244
+ type: 'boolean',
245
+ },
246
+ tags: {
247
+ items: {
248
+ type: 'string',
249
+ },
250
+ type: 'array',
251
+ },
252
+ },
253
+ type: 'object',
254
+ },
255
+ ],
256
+ type: 'suggestion',
257
+ },
258
+ });
@@ -0,0 +1,2 @@
1
+ declare const _default: import("eslint").Rule.RuleModule;
2
+ export default _default;
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const iterateJsdoc_js_1 = __importDefault(require("../iterateJsdoc.js"));
7
+ exports.default = (0, iterateJsdoc_js_1.default)(({ context, jsdoc, report, utils, }) => {
8
+ if (utils.avoidDocs()) {
9
+ return;
10
+ }
11
+ const { enableFixer = true, exemptNoArguments = false, } = context.options[0] || {};
12
+ const targetTagName = 'example';
13
+ const functionExamples = jsdoc.tags.filter(({ tag, }) => {
14
+ return tag === targetTagName;
15
+ });
16
+ if (!functionExamples.length) {
17
+ if (exemptNoArguments && utils.isIteratingFunctionOrVariable() &&
18
+ !utils.hasParams()) {
19
+ return;
20
+ }
21
+ utils.reportJSDoc(`Missing JSDoc @${targetTagName} declaration.`, null, () => {
22
+ if (enableFixer) {
23
+ utils.addTag(targetTagName);
24
+ }
25
+ });
26
+ return;
27
+ }
28
+ for (const example of functionExamples) {
29
+ const exampleContent = `${example.name} ${utils.getTagDescription(example)}`
30
+ .trim()
31
+ .split('\n')
32
+ .filter(Boolean);
33
+ if (!exampleContent.length) {
34
+ report(`Missing JSDoc @${targetTagName} description.`, null, example);
35
+ }
36
+ }
37
+ }, {
38
+ contextDefaults: true,
39
+ meta: {
40
+ docs: {
41
+ description: 'Requires that all functions have examples.',
42
+ url: 'https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-example.md#repos-sticky-header',
43
+ },
44
+ fixable: 'code',
45
+ schema: [
46
+ {
47
+ additionalProperties: false,
48
+ properties: {
49
+ checkConstructors: {
50
+ default: true,
51
+ type: 'boolean',
52
+ },
53
+ checkGetters: {
54
+ default: false,
55
+ type: 'boolean',
56
+ },
57
+ checkSetters: {
58
+ default: false,
59
+ type: 'boolean',
60
+ },
61
+ contexts: {
62
+ items: {
63
+ anyOf: [
64
+ {
65
+ type: 'string',
66
+ },
67
+ {
68
+ additionalProperties: false,
69
+ properties: {
70
+ comment: {
71
+ type: 'string',
72
+ },
73
+ context: {
74
+ type: 'string',
75
+ },
76
+ },
77
+ type: 'object',
78
+ },
79
+ ],
80
+ },
81
+ type: 'array',
82
+ },
83
+ enableFixer: {
84
+ default: true,
85
+ type: 'boolean',
86
+ },
87
+ exemptedBy: {
88
+ items: {
89
+ type: 'string',
90
+ },
91
+ type: 'array',
92
+ },
93
+ exemptNoArguments: {
94
+ default: false,
95
+ type: 'boolean',
96
+ },
97
+ },
98
+ type: 'object',
99
+ },
100
+ ],
101
+ type: 'suggestion',
102
+ },
103
+ });
@@ -0,0 +1,2 @@
1
+ declare const _default: import("eslint").Rule.RuleModule;
2
+ export default _default;
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const iterateJsdoc_js_1 = __importDefault(require("../iterateJsdoc.js"));
7
+ const defaultTags = {
8
+ file: {
9
+ initialCommentsOnly: true,
10
+ mustExist: true,
11
+ preventDuplicates: true,
12
+ },
13
+ };
14
+ /**
15
+ * @param {import('../iterateJsdoc.js').StateObject} state
16
+ * @returns {void}
17
+ */
18
+ const setDefaults = (state) => {
19
+ // First iteration
20
+ if (!state.globalTags) {
21
+ state.globalTags = {};
22
+ state.hasDuplicates = {};
23
+ state.hasTag = {};
24
+ state.hasNonCommentBeforeTag = {};
25
+ }
26
+ };
27
+ exports.default = (0, iterateJsdoc_js_1.default)(({ context, jsdocNode, state, utils, }) => {
28
+ const { tags = defaultTags, } = context.options[0] || {};
29
+ setDefaults(state);
30
+ for (const tagName of Object.keys(tags)) {
31
+ const targetTagName = /** @type {string} */ (utils.getPreferredTagName({
32
+ tagName,
33
+ }));
34
+ const hasTag = Boolean(targetTagName && utils.hasTag(targetTagName));
35
+ state.hasTag[tagName] = hasTag || state.hasTag[tagName];
36
+ const hasDuplicate = state.hasDuplicates[tagName];
37
+ if (hasDuplicate === false) {
38
+ // Was marked before, so if a tag now, is a dupe
39
+ state.hasDuplicates[tagName] = hasTag;
40
+ }
41
+ else if (!hasDuplicate && hasTag) {
42
+ // No dupes set before, but has first tag, so change state
43
+ // from `undefined` to `false` so can detect next time
44
+ state.hasDuplicates[tagName] = false;
45
+ state.hasNonCommentBeforeTag[tagName] = state.hasNonComment &&
46
+ state.hasNonComment < jsdocNode.range[0];
47
+ }
48
+ }
49
+ }, {
50
+ exit({ context, state, utils, }) {
51
+ setDefaults(state);
52
+ const { tags = defaultTags, } = context.options[0] || {};
53
+ for (const [tagName, { initialCommentsOnly = false, mustExist = false, preventDuplicates = false, },] of Object.entries(tags)) {
54
+ const obj = utils.getPreferredTagNameObject({
55
+ tagName,
56
+ });
57
+ if (obj && typeof obj === 'object' && 'blocked' in obj) {
58
+ utils.reportSettings(`\`settings.jsdoc.tagNamePreference\` cannot block @${obj.tagName} ` +
59
+ 'for the `require-file-overview` rule');
60
+ }
61
+ else {
62
+ const targetTagName = (obj && typeof obj === 'object' && obj.replacement) || obj;
63
+ if (mustExist && !state.hasTag[tagName]) {
64
+ utils.reportSettings(`Missing @${targetTagName}`);
65
+ }
66
+ if (preventDuplicates && state.hasDuplicates[tagName]) {
67
+ utils.reportSettings(`Duplicate @${targetTagName}`);
68
+ }
69
+ if (initialCommentsOnly &&
70
+ state.hasNonCommentBeforeTag[tagName]) {
71
+ utils.reportSettings(`@${targetTagName} should be at the beginning of the file`);
72
+ }
73
+ }
74
+ }
75
+ },
76
+ iterateAllJsdocs: true,
77
+ meta: {
78
+ docs: {
79
+ description: 'Checks that all files have one `@file`, `@fileoverview`, or `@overview` tag at the beginning of the file.',
80
+ url: 'https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-file-overview.md#repos-sticky-header',
81
+ },
82
+ schema: [
83
+ {
84
+ additionalProperties: false,
85
+ properties: {
86
+ tags: {
87
+ patternProperties: {
88
+ '.*': {
89
+ additionalProperties: false,
90
+ properties: {
91
+ initialCommentsOnly: {
92
+ type: 'boolean',
93
+ },
94
+ mustExist: {
95
+ type: 'boolean',
96
+ },
97
+ preventDuplicates: {
98
+ type: 'boolean',
99
+ },
100
+ },
101
+ type: 'object',
102
+ },
103
+ },
104
+ type: 'object',
105
+ },
106
+ },
107
+ type: 'object',
108
+ },
109
+ ],
110
+ type: 'suggestion',
111
+ },
112
+ nonComment({ node, state, }) {
113
+ if (!state.hasNonComment) {
114
+ state.hasNonComment = node.range[0];
115
+ }
116
+ },
117
+ });
@@ -0,0 +1,2 @@
1
+ declare const _default: import("eslint").Rule.RuleModule;
2
+ export default _default;