eslint-plugin-jsdoc 54.4.1 → 54.6.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 +75 -9
- package/dist/generateRule.cjs +1 -1
- package/dist/generateRule.cjs.map +1 -1
- package/dist/index.cjs +102 -63
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +12 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/rules/requireJsdoc.cjs +59 -4
- package/dist/rules/requireJsdoc.cjs.map +1 -1
- package/dist/rules/requireTemplate.cjs +3 -0
- package/dist/rules/requireTemplate.cjs.map +1 -1
- package/package.json +19 -21
- package/src/index.js +124 -64
- package/src/rules/requireJsdoc.js +67 -1
- package/src/rules/requireTemplate.js +3 -0
package/src/index.js
CHANGED
|
@@ -58,80 +58,140 @@ import sortTags from './rules/sortTags.js';
|
|
|
58
58
|
import tagLines from './rules/tagLines.js';
|
|
59
59
|
import textEscaping from './rules/textEscaping.js';
|
|
60
60
|
import validTypes from './rules/validTypes.js';
|
|
61
|
+
import {
|
|
62
|
+
merge,
|
|
63
|
+
} from 'object-deep-merge';
|
|
61
64
|
|
|
62
65
|
/* eslint-disable jsdoc/valid-types -- Bug */
|
|
63
66
|
/**
|
|
64
67
|
* @typedef {"recommended" | "stylistic" | "contents" | "logical" | "requirements"} ConfigGroups
|
|
65
68
|
* @typedef {"" | "-typescript" | "-typescript-flavor"} ConfigVariants
|
|
66
69
|
* @typedef {"" | "-error"} ErrorLevelVariants
|
|
67
|
-
* @type {
|
|
70
|
+
* @type {((
|
|
71
|
+
* cfg?: {
|
|
72
|
+
* mergeSettings?: boolean,
|
|
73
|
+
* config?: `flat/${ConfigGroups}${ConfigVariants}${ErrorLevelVariants}`,
|
|
74
|
+
* settings?: Partial<import('./iterateJsdoc.js').Settings>
|
|
75
|
+
* }
|
|
76
|
+
* ) => import('eslint').Linter.Config) & import('eslint').ESLint.Plugin & {
|
|
68
77
|
* configs: Record<`flat/${ConfigGroups}${ConfigVariants}${ErrorLevelVariants}`,
|
|
69
78
|
* import('eslint').Linter.Config>
|
|
70
79
|
* }}
|
|
71
80
|
*/
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
'
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
81
|
+
// @ts-expect-error Ok
|
|
82
|
+
const index = function (cfg) {
|
|
83
|
+
/** @type {import('eslint').Linter.Config} */
|
|
84
|
+
let outputConfig = {
|
|
85
|
+
plugins: {
|
|
86
|
+
jsdoc: index,
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
if (
|
|
90
|
+
cfg?.config
|
|
91
|
+
) {
|
|
92
|
+
// @ts-expect-error Security check
|
|
93
|
+
if (cfg.config === '__proto__') {
|
|
94
|
+
throw new TypeError('Disallowed config value');
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
outputConfig = index.configs[cfg.config];
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
outputConfig.settings = {
|
|
101
|
+
jsdoc: cfg?.mergeSettings === false ?
|
|
102
|
+
cfg.settings :
|
|
103
|
+
merge(
|
|
104
|
+
{},
|
|
105
|
+
cfg?.settings ?? {},
|
|
106
|
+
cfg?.config?.includes('recommended') ?
|
|
107
|
+
{
|
|
108
|
+
// We may need to drop these for "typescript" (non-"flavor") configs,
|
|
109
|
+
// if support is later added: https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html
|
|
110
|
+
structuredTags: {
|
|
111
|
+
next: {
|
|
112
|
+
required: [
|
|
113
|
+
'type',
|
|
114
|
+
],
|
|
115
|
+
},
|
|
116
|
+
throws: {
|
|
117
|
+
required: [
|
|
118
|
+
'type',
|
|
119
|
+
],
|
|
120
|
+
},
|
|
121
|
+
yields: {
|
|
122
|
+
required: [
|
|
123
|
+
'type',
|
|
124
|
+
],
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
} :
|
|
128
|
+
{},
|
|
129
|
+
),
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
return outputConfig;
|
|
133
|
+
};
|
|
134
|
+
/* eslint-enable jsdoc/valid-types -- Bug */
|
|
135
|
+
|
|
136
|
+
index.configs = {};
|
|
137
|
+
index.rules = {
|
|
138
|
+
'check-access': checkAccess,
|
|
139
|
+
'check-alignment': checkAlignment,
|
|
140
|
+
'check-examples': checkExamples,
|
|
141
|
+
'check-indentation': checkIndentation,
|
|
142
|
+
'check-line-alignment': checkLineAlignment,
|
|
143
|
+
'check-param-names': checkParamNames,
|
|
144
|
+
'check-property-names': checkPropertyNames,
|
|
145
|
+
'check-syntax': checkSyntax,
|
|
146
|
+
'check-tag-names': checkTagNames,
|
|
147
|
+
'check-template-names': checkTemplateNames,
|
|
148
|
+
'check-types': checkTypes,
|
|
149
|
+
'check-values': checkValues,
|
|
150
|
+
'convert-to-jsdoc-comments': convertToJsdocComments,
|
|
151
|
+
'empty-tags': emptyTags,
|
|
152
|
+
'implements-on-classes': implementsOnClasses,
|
|
153
|
+
'imports-as-dependencies': importsAsDependencies,
|
|
154
|
+
'informative-docs': informativeDocs,
|
|
155
|
+
'lines-before-block': linesBeforeBlock,
|
|
156
|
+
'match-description': matchDescription,
|
|
157
|
+
'match-name': matchName,
|
|
158
|
+
'multiline-blocks': multilineBlocks,
|
|
159
|
+
'no-bad-blocks': noBadBlocks,
|
|
160
|
+
'no-blank-block-descriptions': noBlankBlockDescriptions,
|
|
161
|
+
'no-blank-blocks': noBlankBlocks,
|
|
162
|
+
'no-defaults': noDefaults,
|
|
163
|
+
'no-missing-syntax': noMissingSyntax,
|
|
164
|
+
'no-multi-asterisks': noMultiAsterisks,
|
|
165
|
+
'no-restricted-syntax': noRestrictedSyntax,
|
|
166
|
+
'no-types': noTypes,
|
|
167
|
+
'no-undefined-types': noUndefinedTypes,
|
|
168
|
+
'require-asterisk-prefix': requireAsteriskPrefix,
|
|
169
|
+
'require-description': requireDescription,
|
|
170
|
+
'require-description-complete-sentence': requireDescriptionCompleteSentence,
|
|
171
|
+
'require-example': requireExample,
|
|
172
|
+
'require-file-overview': requireFileOverview,
|
|
173
|
+
'require-hyphen-before-param-description': requireHyphenBeforeParamDescription,
|
|
174
|
+
'require-jsdoc': requireJsdoc,
|
|
175
|
+
'require-param': requireParam,
|
|
176
|
+
'require-param-description': requireParamDescription,
|
|
177
|
+
'require-param-name': requireParamName,
|
|
178
|
+
'require-param-type': requireParamType,
|
|
179
|
+
'require-property': requireProperty,
|
|
180
|
+
'require-property-description': requirePropertyDescription,
|
|
181
|
+
'require-property-name': requirePropertyName,
|
|
182
|
+
'require-property-type': requirePropertyType,
|
|
183
|
+
'require-returns': requireReturns,
|
|
184
|
+
'require-returns-check': requireReturnsCheck,
|
|
185
|
+
'require-returns-description': requireReturnsDescription,
|
|
186
|
+
'require-returns-type': requireReturnsType,
|
|
187
|
+
'require-template': requireTemplate,
|
|
188
|
+
'require-throws': requireThrows,
|
|
189
|
+
'require-yields': requireYields,
|
|
190
|
+
'require-yields-check': requireYieldsCheck,
|
|
191
|
+
'sort-tags': sortTags,
|
|
192
|
+
'tag-lines': tagLines,
|
|
193
|
+
'text-escaping': textEscaping,
|
|
194
|
+
'valid-types': validTypes,
|
|
135
195
|
};
|
|
136
196
|
|
|
137
197
|
/**
|
|
@@ -104,6 +104,10 @@ const OPTIONS_SCHEMA = {
|
|
|
104
104
|
default: false,
|
|
105
105
|
type: 'boolean',
|
|
106
106
|
},
|
|
107
|
+
exemptOverloadedImplementations: {
|
|
108
|
+
default: false,
|
|
109
|
+
type: 'boolean',
|
|
110
|
+
},
|
|
107
111
|
fixerMessage: {
|
|
108
112
|
default: '',
|
|
109
113
|
type: 'string',
|
|
@@ -169,6 +173,10 @@ const OPTIONS_SCHEMA = {
|
|
|
169
173
|
},
|
|
170
174
|
type: 'object',
|
|
171
175
|
},
|
|
176
|
+
skipInterveningOverloadedDeclarations: {
|
|
177
|
+
default: true,
|
|
178
|
+
type: 'boolean',
|
|
179
|
+
},
|
|
172
180
|
},
|
|
173
181
|
type: 'object',
|
|
174
182
|
};
|
|
@@ -302,6 +310,8 @@ const getOption = (context, baseObject, option, key) => {
|
|
|
302
310
|
* enableFixer: boolean,
|
|
303
311
|
* exemptEmptyConstructors: boolean,
|
|
304
312
|
* exemptEmptyFunctions: boolean,
|
|
313
|
+
* skipInterveningOverloadedDeclarations: boolean,
|
|
314
|
+
* exemptOverloadedImplementations: boolean,
|
|
305
315
|
* fixerMessage: string,
|
|
306
316
|
* minLineCount: undefined|import('../iterateJsdoc.js').Integer,
|
|
307
317
|
* publicOnly: boolean|{[key: string]: boolean|undefined}
|
|
@@ -314,9 +324,11 @@ const getOptions = (context, settings) => {
|
|
|
314
324
|
enableFixer = true,
|
|
315
325
|
exemptEmptyConstructors = true,
|
|
316
326
|
exemptEmptyFunctions = false,
|
|
327
|
+
exemptOverloadedImplementations = false,
|
|
317
328
|
fixerMessage = '',
|
|
318
329
|
minLineCount = undefined,
|
|
319
330
|
publicOnly,
|
|
331
|
+
skipInterveningOverloadedDeclarations = true,
|
|
320
332
|
} = context.options[0] || {};
|
|
321
333
|
|
|
322
334
|
return {
|
|
@@ -324,6 +336,7 @@ const getOptions = (context, settings) => {
|
|
|
324
336
|
enableFixer,
|
|
325
337
|
exemptEmptyConstructors,
|
|
326
338
|
exemptEmptyFunctions,
|
|
339
|
+
exemptOverloadedImplementations,
|
|
327
340
|
fixerMessage,
|
|
328
341
|
minLineCount,
|
|
329
342
|
publicOnly: ((baseObj) => {
|
|
@@ -386,9 +399,52 @@ const getOptions = (context, settings) => {
|
|
|
386
399
|
/** @type {import('json-schema').JSONSchema4Object} */
|
|
387
400
|
(OPTIONS_SCHEMA.properties).require,
|
|
388
401
|
),
|
|
402
|
+
skipInterveningOverloadedDeclarations,
|
|
389
403
|
};
|
|
390
404
|
};
|
|
391
405
|
|
|
406
|
+
/**
|
|
407
|
+
* @param {ESLintOrTSNode} node
|
|
408
|
+
*/
|
|
409
|
+
const isFunctionWithOverload = (node) => {
|
|
410
|
+
if (node.type !== 'FunctionDeclaration') {
|
|
411
|
+
return false;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
let parent;
|
|
415
|
+
let child;
|
|
416
|
+
|
|
417
|
+
if (node.parent?.type === 'Program') {
|
|
418
|
+
parent = node.parent;
|
|
419
|
+
child = node;
|
|
420
|
+
} else if (node.parent?.type === 'ExportNamedDeclaration' &&
|
|
421
|
+
node.parent?.parent.type === 'Program') {
|
|
422
|
+
parent = node.parent?.parent;
|
|
423
|
+
child = node.parent;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
if (!child || !parent) {
|
|
427
|
+
return false;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
const functionName = node.id.name;
|
|
431
|
+
|
|
432
|
+
const idx = parent.body.indexOf(child);
|
|
433
|
+
const prevSibling = parent.body[idx - 1];
|
|
434
|
+
|
|
435
|
+
return (
|
|
436
|
+
// @ts-expect-error Should be ok
|
|
437
|
+
(prevSibling?.type === 'TSDeclareFunction' &&
|
|
438
|
+
// @ts-expect-error Should be ok
|
|
439
|
+
functionName === prevSibling.id.name) ||
|
|
440
|
+
(prevSibling?.type === 'ExportNamedDeclaration' &&
|
|
441
|
+
// @ts-expect-error Should be ok
|
|
442
|
+
prevSibling.declaration?.type === 'TSDeclareFunction' &&
|
|
443
|
+
// @ts-expect-error Should be ok
|
|
444
|
+
prevSibling.declaration?.id?.name === functionName)
|
|
445
|
+
);
|
|
446
|
+
};
|
|
447
|
+
|
|
392
448
|
/** @type {import('eslint').Rule.RuleModule} */
|
|
393
449
|
export default {
|
|
394
450
|
create (context) {
|
|
@@ -408,9 +464,11 @@ export default {
|
|
|
408
464
|
enableFixer,
|
|
409
465
|
exemptEmptyConstructors,
|
|
410
466
|
exemptEmptyFunctions,
|
|
467
|
+
exemptOverloadedImplementations,
|
|
411
468
|
fixerMessage,
|
|
412
469
|
minLineCount,
|
|
413
470
|
require: requireOption,
|
|
471
|
+
skipInterveningOverloadedDeclarations,
|
|
414
472
|
} = opts;
|
|
415
473
|
|
|
416
474
|
const publicOnly =
|
|
@@ -476,7 +534,15 @@ export default {
|
|
|
476
534
|
}
|
|
477
535
|
}
|
|
478
536
|
|
|
479
|
-
|
|
537
|
+
if (exemptOverloadedImplementations && isFunctionWithOverload(node)) {
|
|
538
|
+
return;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
const jsDocNode = getJSDocComment(
|
|
542
|
+
sourceCode, node, settings, {
|
|
543
|
+
checkOverloads: skipInterveningOverloadedDeclarations,
|
|
544
|
+
},
|
|
545
|
+
);
|
|
480
546
|
|
|
481
547
|
if (jsDocNode) {
|
|
482
548
|
return;
|
|
@@ -42,6 +42,7 @@ export default iterateJsdoc(({
|
|
|
42
42
|
/**
|
|
43
43
|
* @param {import('@typescript-eslint/types').TSESTree.FunctionDeclaration|
|
|
44
44
|
* import('@typescript-eslint/types').TSESTree.ClassDeclaration|
|
|
45
|
+
* import('@typescript-eslint/types').TSESTree.TSDeclareFunction|
|
|
45
46
|
* import('@typescript-eslint/types').TSESTree.TSInterfaceDeclaration|
|
|
46
47
|
* import('@typescript-eslint/types').TSESTree.TSTypeAliasDeclaration} aliasDeclaration
|
|
47
48
|
*/
|
|
@@ -79,6 +80,7 @@ export default iterateJsdoc(({
|
|
|
79
80
|
switch (nde.type) {
|
|
80
81
|
case 'ClassDeclaration':
|
|
81
82
|
case 'FunctionDeclaration':
|
|
83
|
+
case 'TSDeclareFunction':
|
|
82
84
|
case 'TSInterfaceDeclaration':
|
|
83
85
|
case 'TSTypeAliasDeclaration':
|
|
84
86
|
checkTypeParams(nde);
|
|
@@ -97,6 +99,7 @@ export default iterateJsdoc(({
|
|
|
97
99
|
switch (nde.declaration?.type) {
|
|
98
100
|
case 'ClassDeclaration':
|
|
99
101
|
case 'FunctionDeclaration':
|
|
102
|
+
case 'TSDeclareFunction':
|
|
100
103
|
case 'TSInterfaceDeclaration':
|
|
101
104
|
case 'TSTypeAliasDeclaration':
|
|
102
105
|
checkTypeParams(nde.declaration);
|