@depup/eslint-plugin-jsdoc 64.3.2-depup.0 → 64.3.3-depup.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.
- package/README.md +4 -3
- package/changes.json +6 -2
- package/dist/jsdocUtils.d.ts +2 -1
- package/package.json +9 -5
- package/src/jsdocUtils.js +9 -3
- package/src/rules/convertToJsdocComments.js +33 -10
- package/src/rules/noBlankBlockDescriptions.js +103 -48
package/README.md
CHANGED
|
@@ -13,16 +13,17 @@ npm install @depup/eslint-plugin-jsdoc
|
|
|
13
13
|
|
|
14
14
|
| Field | Value |
|
|
15
15
|
|-------|-------|
|
|
16
|
-
| Original | [eslint-plugin-jsdoc](https://www.npmjs.com/package/eslint-plugin-jsdoc) @ 64.3.
|
|
17
|
-
| Processed | 2026-
|
|
16
|
+
| Original | [eslint-plugin-jsdoc](https://www.npmjs.com/package/eslint-plugin-jsdoc) @ 64.3.3 |
|
|
17
|
+
| Processed | 2026-09-01 |
|
|
18
18
|
| Smoke test | passed |
|
|
19
|
-
| Deps updated |
|
|
19
|
+
| Deps updated | 2 |
|
|
20
20
|
|
|
21
21
|
## Dependency Changes
|
|
22
22
|
|
|
23
23
|
| Dependency | From | To |
|
|
24
24
|
|------------|------|-----|
|
|
25
25
|
| @es-joy/jsdoccomment | ~0.95.1 | ^0.96.0 |
|
|
26
|
+
| @typescript-eslint/utils | ^8.68.0 | ^8.69.0 |
|
|
26
27
|
|
|
27
28
|
---
|
|
28
29
|
|
package/changes.json
CHANGED
|
@@ -3,8 +3,12 @@
|
|
|
3
3
|
"@es-joy/jsdoccomment": {
|
|
4
4
|
"from": "~0.95.1",
|
|
5
5
|
"to": "^0.96.0"
|
|
6
|
+
},
|
|
7
|
+
"@typescript-eslint/utils": {
|
|
8
|
+
"from": "^8.68.0",
|
|
9
|
+
"to": "^8.69.0"
|
|
6
10
|
}
|
|
7
11
|
},
|
|
8
|
-
"timestamp": "2026-
|
|
9
|
-
"totalUpdated":
|
|
12
|
+
"timestamp": "2026-09-01T00:40:40.623Z",
|
|
13
|
+
"totalUpdated": 2
|
|
10
14
|
}
|
package/dist/jsdocUtils.d.ts
CHANGED
|
@@ -170,9 +170,10 @@ export function getAllTags(jsdoc: import("./iterateJsdoc.js").JsdocBlockWithInli
|
|
|
170
170
|
* @param {import('./iterateJsdoc.js').Context[]} contexts
|
|
171
171
|
* @param {import('./iterateJsdoc.js').CheckJsdoc} checkJsdoc
|
|
172
172
|
* @param {import('@es-joy/jsdoccomment').CommentHandler} [handler]
|
|
173
|
+
* @param {boolean} [convertAny]
|
|
173
174
|
* @returns {import('eslint').Rule.RuleListener}
|
|
174
175
|
*/
|
|
175
|
-
export function getContextObject(contexts: import("./iterateJsdoc.js").Context[], checkJsdoc: import("./iterateJsdoc.js").CheckJsdoc, handler?: import("@es-joy/jsdoccomment").CommentHandler): import("eslint").Rule.RuleListener;
|
|
176
|
+
export function getContextObject(contexts: import("./iterateJsdoc.js").Context[], checkJsdoc: import("./iterateJsdoc.js").CheckJsdoc, handler?: import("@es-joy/jsdoccomment").CommentHandler, convertAny?: boolean): import("eslint").Rule.RuleListener;
|
|
176
177
|
/**
|
|
177
178
|
* @param {import('eslint').SourceCode} sourceCode
|
|
178
179
|
* @returns {import('comment-parser').Spec[]}
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"dependencies": {
|
|
8
8
|
"@es-joy/jsdoccomment": "^0.96.0",
|
|
9
9
|
"@es-joy/resolve.exports": "1.2.0",
|
|
10
|
-
"@typescript-eslint/utils": "^8.
|
|
10
|
+
"@typescript-eslint/utils": "^8.69.0",
|
|
11
11
|
"are-docs-informative": "^0.1.1",
|
|
12
12
|
"comment-parser": "1.4.8",
|
|
13
13
|
"debug": "^4.4.3",
|
|
@@ -162,18 +162,22 @@
|
|
|
162
162
|
"test-cov": "TIMING=1 c8 --reporter text pnpm run test-no-cov",
|
|
163
163
|
"test-index": "pnpm run test-no-cov test/rules/index.js"
|
|
164
164
|
},
|
|
165
|
-
"version": "64.3.
|
|
165
|
+
"version": "64.3.3-depup.0",
|
|
166
166
|
"depup": {
|
|
167
167
|
"changes": {
|
|
168
168
|
"@es-joy/jsdoccomment": {
|
|
169
169
|
"from": "~0.95.1",
|
|
170
170
|
"to": "^0.96.0"
|
|
171
|
+
},
|
|
172
|
+
"@typescript-eslint/utils": {
|
|
173
|
+
"from": "^8.68.0",
|
|
174
|
+
"to": "^8.69.0"
|
|
171
175
|
}
|
|
172
176
|
},
|
|
173
|
-
"depsUpdated":
|
|
177
|
+
"depsUpdated": 2,
|
|
174
178
|
"originalPackage": "eslint-plugin-jsdoc",
|
|
175
|
-
"originalVersion": "64.3.
|
|
176
|
-
"processedAt": "2026-
|
|
179
|
+
"originalVersion": "64.3.3",
|
|
180
|
+
"processedAt": "2026-09-01T00:41:05.665Z",
|
|
177
181
|
"smokeTest": "passed"
|
|
178
182
|
}
|
|
179
183
|
}
|
package/src/jsdocUtils.js
CHANGED
|
@@ -1655,9 +1655,10 @@ const enforcedContexts = (context, defaultContexts, settings) => {
|
|
|
1655
1655
|
* @param {import('./iterateJsdoc.js').Context[]} contexts
|
|
1656
1656
|
* @param {import('./iterateJsdoc.js').CheckJsdoc} checkJsdoc
|
|
1657
1657
|
* @param {import('@es-joy/jsdoccomment').CommentHandler} [handler]
|
|
1658
|
+
* @param {boolean} [convertAny]
|
|
1658
1659
|
* @returns {import('eslint').Rule.RuleListener}
|
|
1659
1660
|
*/
|
|
1660
|
-
const getContextObject = (contexts, checkJsdoc, handler) => {
|
|
1661
|
+
const getContextObject = (contexts, checkJsdoc, handler, convertAny) => {
|
|
1661
1662
|
/** @type {import('eslint').Rule.RuleListener} */
|
|
1662
1663
|
const properties = {};
|
|
1663
1664
|
|
|
@@ -1696,11 +1697,16 @@ const getContextObject = (contexts, checkJsdoc, handler) => {
|
|
|
1696
1697
|
value = checkJsdoc.bind(null, selInfo, null);
|
|
1697
1698
|
}
|
|
1698
1699
|
} else {
|
|
1700
|
+
property = prop;
|
|
1701
|
+
|
|
1702
|
+
if (convertAny && property === 'any') {
|
|
1703
|
+
property = ':not(Program)';
|
|
1704
|
+
}
|
|
1705
|
+
|
|
1699
1706
|
const selInfo = {
|
|
1700
1707
|
lastIndex: idx,
|
|
1701
|
-
selector:
|
|
1708
|
+
selector: property,
|
|
1702
1709
|
};
|
|
1703
|
-
property = prop;
|
|
1704
1710
|
value = checkJsdoc.bind(null, selInfo, null);
|
|
1705
1711
|
}
|
|
1706
1712
|
|
|
@@ -185,6 +185,31 @@ export default {
|
|
|
185
185
|
}
|
|
186
186
|
};
|
|
187
187
|
|
|
188
|
+
/**
|
|
189
|
+
* Builds the opening portion of the JSDoc comment, i.e. everything before
|
|
190
|
+
* the closing delimiter.
|
|
191
|
+
* @param {string} indent
|
|
192
|
+
* @param {Token} comment
|
|
193
|
+
* @param {boolean|undefined} inlineCommentBlock
|
|
194
|
+
* @returns {string}
|
|
195
|
+
*/
|
|
196
|
+
const getCommentOpening = (indent, comment, inlineCommentBlock) => {
|
|
197
|
+
if (inlineCommentBlock || enforceJsdocLineStyle === 'single') {
|
|
198
|
+
return `/** ${comment.value.trim()} `;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const body = comment.value.trimEnd();
|
|
202
|
+
|
|
203
|
+
// When the comment's text already begins on its own line (e.g. a
|
|
204
|
+
// multi-line block comment), there is no need for the fixer to add a
|
|
205
|
+
// leading blank `*` line.
|
|
206
|
+
if ((/^[ \t]*\n/v).test(body)) {
|
|
207
|
+
return `/**${body.replace(/^[ \t]+/v, '')}\n${indent}`;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return `/**\n${indent}*${body}\n${indent}`;
|
|
211
|
+
};
|
|
212
|
+
|
|
188
213
|
/**
|
|
189
214
|
* @type {import('../iterateJsdoc.js').CheckJsdoc}
|
|
190
215
|
*/
|
|
@@ -205,11 +230,7 @@ export default {
|
|
|
205
230
|
|
|
206
231
|
/** @type {AddComment} */
|
|
207
232
|
const addComment = (inlineCommentBlock, commentToAdd, indent, lines, fixer) => {
|
|
208
|
-
const insertion = (
|
|
209
|
-
inlineCommentBlock || enforceJsdocLineStyle === 'single' ?
|
|
210
|
-
`/** ${commentToAdd.value.trim()} ` :
|
|
211
|
-
`/**\n${indent}*${commentToAdd.value.trimEnd()}\n${indent}`
|
|
212
|
-
) +
|
|
233
|
+
const insertion = getCommentOpening(indent, commentToAdd, inlineCommentBlock) +
|
|
213
234
|
`*/${'\n'.repeat((lines || 1) - 1)}`;
|
|
214
235
|
|
|
215
236
|
return fixer.replaceText(
|
|
@@ -242,11 +263,7 @@ export default {
|
|
|
242
263
|
|
|
243
264
|
/** @type {AddComment} */
|
|
244
265
|
const addComment = (inlineCommentBlock, commentToAdd, indent, lines, fixer) => {
|
|
245
|
-
const insertion = (
|
|
246
|
-
inlineCommentBlock || enforceJsdocLineStyle === 'single' ?
|
|
247
|
-
`/** ${commentToAdd.value.trim()} ` :
|
|
248
|
-
`/**\n${indent}*${commentToAdd.value.trimEnd()}\n${indent}`
|
|
249
|
-
) +
|
|
266
|
+
const insertion = getCommentOpening(indent, commentToAdd, inlineCommentBlock) +
|
|
250
267
|
`*/${'\n'.repeat((lines || 1) - 1)}${lines ? `\n${indent.slice(1)}` : ' '}`;
|
|
251
268
|
|
|
252
269
|
return [
|
|
@@ -268,12 +285,16 @@ export default {
|
|
|
268
285
|
...getContextObject(
|
|
269
286
|
enforcedContexts(context, true, settings),
|
|
270
287
|
checkNonJsdoc,
|
|
288
|
+
undefined,
|
|
289
|
+
true,
|
|
271
290
|
),
|
|
272
291
|
...getContextObject(
|
|
273
292
|
contextsAfter,
|
|
274
293
|
(_info, _handler, node) => {
|
|
275
294
|
checkNonJsdocAfter(node, contextsAfter);
|
|
276
295
|
},
|
|
296
|
+
undefined,
|
|
297
|
+
true,
|
|
277
298
|
),
|
|
278
299
|
...getContextObject(
|
|
279
300
|
contextsBeforeAndAfter,
|
|
@@ -283,6 +304,8 @@ export default {
|
|
|
283
304
|
checkNonJsdocAfter(node, contextsBeforeAndAfter);
|
|
284
305
|
}
|
|
285
306
|
},
|
|
307
|
+
undefined,
|
|
308
|
+
true,
|
|
286
309
|
),
|
|
287
310
|
};
|
|
288
311
|
},
|
|
@@ -1,60 +1,115 @@
|
|
|
1
1
|
import iterateJsdoc from '../iterateJsdoc.js';
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const atLeastTwoLinesWhitespace = /^[ \t]*\n[ \t]*\n\s*$/v;
|
|
3
|
+
const anyWhitespaceLine = /^\s*$/v;
|
|
5
4
|
|
|
6
5
|
export default iterateJsdoc(({
|
|
7
6
|
jsdoc,
|
|
8
7
|
utils,
|
|
9
8
|
}) => {
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
9
|
+
const hasTags = Boolean(jsdoc.tags.length);
|
|
10
|
+
|
|
11
|
+
// Gather the block-description lines (those before the first tag or the
|
|
12
|
+
// closing delimiter).
|
|
13
|
+
let startIdx = -1;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @type {string[]}
|
|
17
|
+
*/
|
|
18
|
+
const descLines = [];
|
|
19
|
+
jsdoc.source.some(({
|
|
20
|
+
tokens: {
|
|
21
|
+
delimiter,
|
|
22
|
+
description,
|
|
23
|
+
end,
|
|
24
|
+
tag,
|
|
25
|
+
},
|
|
26
|
+
}, idx) => {
|
|
27
|
+
if (delimiter === '/**') {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (tag || end) {
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (startIdx === -1) {
|
|
36
|
+
startIdx = idx;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
descLines.push(description);
|
|
40
|
+
|
|
41
|
+
return false;
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
if (!descLines.length) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
let leadingBlankCount = 0;
|
|
49
|
+
while (
|
|
50
|
+
leadingBlankCount < descLines.length &&
|
|
51
|
+
anyWhitespaceLine.test(descLines[leadingBlankCount])
|
|
52
|
+
) {
|
|
53
|
+
leadingBlankCount++;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const allBlank = leadingBlankCount === descLines.length;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Rebuilds the kept description lines after dropping `dropCount` leading
|
|
60
|
+
* blank lines.
|
|
61
|
+
* @param {import('../iterateJsdoc.js').Integer} dropCount
|
|
62
|
+
* @returns {() => void}
|
|
63
|
+
*/
|
|
64
|
+
const dropLeadingBlankLines = (dropCount) => {
|
|
65
|
+
return () => {
|
|
66
|
+
utils.setBlockDescription((info, seedTokens, descriptions, postDelimiters) => {
|
|
67
|
+
return descriptions.slice(dropCount).map((description, idx) => {
|
|
68
|
+
return {
|
|
69
|
+
number: 0,
|
|
70
|
+
source: '',
|
|
71
|
+
tokens: seedTokens({
|
|
72
|
+
...info,
|
|
73
|
+
description,
|
|
74
|
+
postDelimiter: description ? postDelimiters[idx + dropCount] : '',
|
|
75
|
+
}),
|
|
76
|
+
};
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
if (hasTags) {
|
|
83
|
+
if (!leadingBlankCount) {
|
|
84
|
+
return;
|
|
56
85
|
}
|
|
86
|
+
|
|
87
|
+
utils.reportJSDoc(
|
|
88
|
+
'There should be no blank lines in block descriptions followed by tags.',
|
|
89
|
+
{
|
|
90
|
+
line: startIdx + leadingBlankCount - 1,
|
|
91
|
+
},
|
|
92
|
+
dropLeadingBlankLines(leadingBlankCount),
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Without tags, only the extra (removable) leading blank lines are a problem;
|
|
99
|
+
// a single leading blank line with no following content is allowed.
|
|
100
|
+
const removeCount = allBlank ? descLines.length - 1 : leadingBlankCount;
|
|
101
|
+
|
|
102
|
+
if (removeCount < 1) {
|
|
103
|
+
return;
|
|
57
104
|
}
|
|
105
|
+
|
|
106
|
+
utils.reportJSDoc(
|
|
107
|
+
'There should be no extra blank lines in block descriptions not followed by tags.',
|
|
108
|
+
{
|
|
109
|
+
line: startIdx + removeCount,
|
|
110
|
+
},
|
|
111
|
+
dropLeadingBlankLines(removeCount),
|
|
112
|
+
);
|
|
58
113
|
}, {
|
|
59
114
|
iterateAllJsdocs: true,
|
|
60
115
|
meta: {
|