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.
- package/dist/cjs/WarnSettings.d.ts +16 -0
- package/dist/cjs/WarnSettings.js +30 -0
- package/dist/cjs/alignTransform.d.ts +33 -0
- package/dist/cjs/alignTransform.js +285 -0
- package/dist/cjs/defaultTagOrder.d.ts +4 -0
- package/dist/cjs/defaultTagOrder.js +152 -0
- package/dist/cjs/exportParser.d.ts +40 -0
- package/dist/cjs/exportParser.js +754 -0
- package/dist/cjs/getDefaultTagStructureForMode.d.ts +10 -0
- package/dist/cjs/getDefaultTagStructureForMode.js +840 -0
- package/dist/cjs/getJsdocProcessorPlugin.cjs +4 -0
- package/dist/cjs/getJsdocProcessorPlugin.d.cts +1 -0
- package/dist/cjs/getJsdocProcessorPlugin.d.ts +66 -0
- package/dist/cjs/getJsdocProcessorPlugin.js +553 -0
- package/dist/cjs/index-cjs.d.ts +16 -0
- package/dist/cjs/index-cjs.js +492 -0
- package/dist/cjs/index.cjs.cjs +6 -0
- package/dist/cjs/index.cjs.d.cts +2 -0
- package/dist/cjs/iterateJsdoc.cjs +38 -0
- package/dist/cjs/iterateJsdoc.d.cts +2 -0
- package/dist/cjs/iterateJsdoc.d.ts +462 -0
- package/dist/cjs/iterateJsdoc.js +1981 -0
- package/dist/cjs/jsdocUtils.d.ts +454 -0
- package/dist/cjs/jsdocUtils.js +1470 -0
- package/dist/cjs/rules/checkAccess.d.ts +2 -0
- package/dist/cjs/rules/checkAccess.js +35 -0
- package/dist/cjs/rules/checkAlignment.d.ts +2 -0
- package/dist/cjs/rules/checkAlignment.js +63 -0
- package/dist/cjs/rules/checkExamples.d.ts +3 -0
- package/dist/cjs/rules/checkExamples.js +486 -0
- package/dist/cjs/rules/checkIndentation.d.ts +2 -0
- package/dist/cjs/rules/checkIndentation.js +66 -0
- package/dist/cjs/rules/checkLineAlignment.d.ts +9 -0
- package/dist/cjs/rules/checkLineAlignment.js +297 -0
- package/dist/cjs/rules/checkParamNames.d.ts +2 -0
- package/dist/cjs/rules/checkParamNames.js +320 -0
- package/dist/cjs/rules/checkPropertyNames.d.ts +2 -0
- package/dist/cjs/rules/checkPropertyNames.js +105 -0
- package/dist/cjs/rules/checkSyntax.d.ts +2 -0
- package/dist/cjs/rules/checkSyntax.js +27 -0
- package/dist/cjs/rules/checkTagNames.d.ts +2 -0
- package/dist/cjs/rules/checkTagNames.js +252 -0
- package/dist/cjs/rules/checkTemplateNames.d.ts +2 -0
- package/dist/cjs/rules/checkTemplateNames.js +189 -0
- package/dist/cjs/rules/checkTypes.d.ts +2 -0
- package/dist/cjs/rules/checkTypes.js +421 -0
- package/dist/cjs/rules/checkValues.d.ts +2 -0
- package/dist/cjs/rules/checkValues.js +163 -0
- package/dist/cjs/rules/convertToJsdocComments.d.ts +251 -0
- package/dist/cjs/rules/convertToJsdocComments.js +313 -0
- package/dist/cjs/rules/emptyTags.d.ts +2 -0
- package/dist/cjs/rules/emptyTags.js +79 -0
- package/dist/cjs/rules/implementsOnClasses.d.ts +2 -0
- package/dist/cjs/rules/implementsOnClasses.js +63 -0
- package/dist/cjs/rules/importsAsDependencies.d.ts +2 -0
- package/dist/cjs/rules/importsAsDependencies.js +105 -0
- package/dist/cjs/rules/informativeDocs.d.ts +2 -0
- package/dist/cjs/rules/informativeDocs.js +153 -0
- package/dist/cjs/rules/linesBeforeBlock.d.ts +2 -0
- package/dist/cjs/rules/linesBeforeBlock.js +106 -0
- package/dist/cjs/rules/matchDescription.d.ts +2 -0
- package/dist/cjs/rules/matchDescription.js +240 -0
- package/dist/cjs/rules/matchName.d.ts +2 -0
- package/dist/cjs/rules/matchName.js +122 -0
- package/dist/cjs/rules/multilineBlocks.d.ts +2 -0
- package/dist/cjs/rules/multilineBlocks.js +339 -0
- package/dist/cjs/rules/noBadBlocks.d.ts +2 -0
- package/dist/cjs/rules/noBadBlocks.js +88 -0
- package/dist/cjs/rules/noBlankBlockDescriptions.d.ts +2 -0
- package/dist/cjs/rules/noBlankBlockDescriptions.js +56 -0
- package/dist/cjs/rules/noBlankBlocks.d.ts +2 -0
- package/dist/cjs/rules/noBlankBlocks.js +41 -0
- package/dist/cjs/rules/noDefaults.d.ts +2 -0
- package/dist/cjs/rules/noDefaults.js +84 -0
- package/dist/cjs/rules/noMissingSyntax.d.ts +9 -0
- package/dist/cjs/rules/noMissingSyntax.js +164 -0
- package/dist/cjs/rules/noMultiAsterisks.d.ts +2 -0
- package/dist/cjs/rules/noMultiAsterisks.js +83 -0
- package/dist/cjs/rules/noRestrictedSyntax.d.ts +2 -0
- package/dist/cjs/rules/noRestrictedSyntax.js +75 -0
- package/dist/cjs/rules/noTypes.d.ts +2 -0
- package/dist/cjs/rules/noTypes.js +88 -0
- package/dist/cjs/rules/noUndefinedTypes.d.ts +2 -0
- package/dist/cjs/rules/noUndefinedTypes.js +451 -0
- package/dist/cjs/rules/requireAsteriskPrefix.d.ts +2 -0
- package/dist/cjs/rules/requireAsteriskPrefix.js +144 -0
- package/dist/cjs/rules/requireDescription.d.ts +2 -0
- package/dist/cjs/rules/requireDescription.js +136 -0
- package/dist/cjs/rules/requireDescriptionCompleteSentence.d.ts +2 -0
- package/dist/cjs/rules/requireDescriptionCompleteSentence.js +258 -0
- package/dist/cjs/rules/requireExample.d.ts +2 -0
- package/dist/cjs/rules/requireExample.js +103 -0
- package/dist/cjs/rules/requireFileOverview.d.ts +2 -0
- package/dist/cjs/rules/requireFileOverview.js +117 -0
- package/dist/cjs/rules/requireHyphenBeforeParamDescription.d.ts +2 -0
- package/dist/cjs/rules/requireHyphenBeforeParamDescription.js +144 -0
- package/dist/cjs/rules/requireJsdoc.d.ts +25 -0
- package/dist/cjs/rules/requireJsdoc.js +629 -0
- package/dist/cjs/rules/requireParam.d.ts +3 -0
- package/dist/cjs/rules/requireParam.js +480 -0
- package/dist/cjs/rules/requireParamDescription.d.ts +2 -0
- package/dist/cjs/rules/requireParamDescription.js +77 -0
- package/dist/cjs/rules/requireParamName.d.ts +2 -0
- package/dist/cjs/rules/requireParamName.js +52 -0
- package/dist/cjs/rules/requireParamType.d.ts +2 -0
- package/dist/cjs/rules/requireParamType.js +77 -0
- package/dist/cjs/rules/requireProperty.d.ts +2 -0
- package/dist/cjs/rules/requireProperty.js +44 -0
- package/dist/cjs/rules/requirePropertyDescription.d.ts +2 -0
- package/dist/cjs/rules/requirePropertyDescription.js +22 -0
- package/dist/cjs/rules/requirePropertyName.d.ts +2 -0
- package/dist/cjs/rules/requirePropertyName.js +22 -0
- package/dist/cjs/rules/requirePropertyType.d.ts +2 -0
- package/dist/cjs/rules/requirePropertyType.js +22 -0
- package/dist/cjs/rules/requireReturns.d.ts +2 -0
- package/dist/cjs/rules/requireReturns.js +197 -0
- package/dist/cjs/rules/requireReturnsCheck.d.ts +2 -0
- package/dist/cjs/rules/requireReturnsCheck.js +108 -0
- package/dist/cjs/rules/requireReturnsDescription.d.ts +2 -0
- package/dist/cjs/rules/requireReturnsDescription.js +58 -0
- package/dist/cjs/rules/requireReturnsType.d.ts +2 -0
- package/dist/cjs/rules/requireReturnsType.js +52 -0
- package/dist/cjs/rules/requireTemplate.d.ts +2 -0
- package/dist/cjs/rules/requireTemplate.js +173 -0
- package/dist/cjs/rules/requireThrows.d.ts +2 -0
- package/dist/cjs/rules/requireThrows.js +101 -0
- package/dist/cjs/rules/requireYields.d.ts +2 -0
- package/dist/cjs/rules/requireYields.js +172 -0
- package/dist/cjs/rules/requireYieldsCheck.d.ts +2 -0
- package/dist/cjs/rules/requireYieldsCheck.js +164 -0
- package/dist/cjs/rules/sortTags.d.ts +2 -0
- package/dist/cjs/rules/sortTags.js +392 -0
- package/dist/cjs/rules/tagLines.d.ts +2 -0
- package/dist/cjs/rules/tagLines.js +259 -0
- package/dist/cjs/rules/textEscaping.d.ts +2 -0
- package/dist/cjs/rules/textEscaping.js +125 -0
- package/dist/cjs/rules/typeFormatting.d.ts +2 -0
- package/dist/cjs/rules/typeFormatting.js +328 -0
- package/dist/cjs/rules/validTypes.d.ts +2 -0
- package/dist/cjs/rules/validTypes.js +333 -0
- package/dist/cjs/tagNames.d.ts +15 -0
- package/dist/cjs/tagNames.js +209 -0
- package/dist/cjs/utils/hasReturnValue.d.ts +19 -0
- package/dist/cjs/utils/hasReturnValue.js +469 -0
- package/dist/getJsdocProcessorPlugin.cts +3 -0
- package/dist/index.cjs.cts +3 -0
- package/dist/iterateJsdoc.cts +6 -0
- package/dist/rules/typeFormatting.cjs +82 -38
- package/dist/rules/typeFormatting.cjs.map +1 -1
- package/dist/rules.d.ts +4 -7
- package/package.json +24 -13
- package/src/getJsdocProcessorPlugin.cts +3 -0
- package/src/index.cjs.cts +3 -0
- package/src/iterateJsdoc.cts +6 -0
- package/src/rules/typeFormatting.js +104 -40
- package/src/rules.d.ts +4 -7
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
export function getJsdocProcessorPlugin(options?: JsdocProcessorOptions): ESLint.Plugin;
|
|
2
|
+
export type Integer = number;
|
|
3
|
+
export type JsdocProcessorOptions = {
|
|
4
|
+
/**
|
|
5
|
+
* Require captions for example tags
|
|
6
|
+
*/
|
|
7
|
+
captionRequired?: boolean | undefined;
|
|
8
|
+
/**
|
|
9
|
+
* See docs
|
|
10
|
+
*/
|
|
11
|
+
paddedIndent?: number | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* See docs
|
|
14
|
+
*/
|
|
15
|
+
checkDefaults?: boolean | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* See docs
|
|
18
|
+
*/
|
|
19
|
+
checkParams?: boolean | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* See docs
|
|
22
|
+
*/
|
|
23
|
+
checkExamples?: boolean | undefined;
|
|
24
|
+
/**
|
|
25
|
+
* See docs
|
|
26
|
+
*/
|
|
27
|
+
checkProperties?: boolean | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* See docs
|
|
30
|
+
*/
|
|
31
|
+
matchingFileName?: string | undefined;
|
|
32
|
+
/**
|
|
33
|
+
* See docs
|
|
34
|
+
*/
|
|
35
|
+
matchingFileNameDefaults?: string | undefined;
|
|
36
|
+
/**
|
|
37
|
+
* See docs
|
|
38
|
+
*/
|
|
39
|
+
matchingFileNameParams?: string | undefined;
|
|
40
|
+
/**
|
|
41
|
+
* See docs
|
|
42
|
+
*/
|
|
43
|
+
matchingFileNameProperties?: string | undefined;
|
|
44
|
+
/**
|
|
45
|
+
* See docs
|
|
46
|
+
*/
|
|
47
|
+
exampleCodeRegex?: string | RegExp | undefined;
|
|
48
|
+
/**
|
|
49
|
+
* See docs
|
|
50
|
+
*/
|
|
51
|
+
rejectExampleCodeRegex?: string | RegExp | undefined;
|
|
52
|
+
/**
|
|
53
|
+
* See docs
|
|
54
|
+
*/
|
|
55
|
+
allowedLanguagesToProcess?: string[] | undefined;
|
|
56
|
+
/**
|
|
57
|
+
* See docs
|
|
58
|
+
*/
|
|
59
|
+
sourceType?: "module" | "script" | undefined;
|
|
60
|
+
/**
|
|
61
|
+
* See docs
|
|
62
|
+
*/
|
|
63
|
+
parser?: Linter.ESTreeParser | Linter.NonESTreeParser | undefined;
|
|
64
|
+
};
|
|
65
|
+
import type { ESLint } from 'eslint';
|
|
66
|
+
import type { Linter } from 'eslint';
|
|
@@ -0,0 +1,553 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.getJsdocProcessorPlugin = void 0;
|
|
37
|
+
const jsdocUtils_js_1 = require("./jsdocUtils.js");
|
|
38
|
+
const jsdoccomment_1 = require("@es-joy/jsdoccomment");
|
|
39
|
+
const espree = __importStar(require("espree"));
|
|
40
|
+
const node_fs_1 = require("node:fs");
|
|
41
|
+
const node_path_1 = require("node:path");
|
|
42
|
+
/**
|
|
43
|
+
* @import {
|
|
44
|
+
* Integer,
|
|
45
|
+
* JsdocBlockWithInline,
|
|
46
|
+
* } from './iterateJsdoc.js';
|
|
47
|
+
* @import {
|
|
48
|
+
* ESLint,
|
|
49
|
+
* Linter,
|
|
50
|
+
* } from 'eslint';
|
|
51
|
+
*/
|
|
52
|
+
const { version, } = JSON.parse(
|
|
53
|
+
// @ts-expect-error `Buffer` is ok for `JSON.parse`
|
|
54
|
+
(0, node_fs_1.readFileSync)((0, node_path_1.join)(import.meta.dirname, '../package.json')));
|
|
55
|
+
// const zeroBasedLineIndexAdjust = -1;
|
|
56
|
+
const likelyNestedJSDocIndentSpace = 1;
|
|
57
|
+
const preTagSpaceLength = 1;
|
|
58
|
+
// If a space is present, we should ignore it
|
|
59
|
+
const firstLinePrefixLength = preTagSpaceLength;
|
|
60
|
+
const hasCaptionRegex = /^\s*<caption>([\s\S]*?)<\/caption>/v;
|
|
61
|
+
/**
|
|
62
|
+
* @param {string} str
|
|
63
|
+
* @returns {string}
|
|
64
|
+
*/
|
|
65
|
+
const escapeStringRegexp = (str) => {
|
|
66
|
+
return str.replaceAll(/[.*+?^$\{\}\(\)\|\[\]\\]/gv, '\\$&');
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* @param {string} str
|
|
70
|
+
* @param {string} ch
|
|
71
|
+
* @returns {Integer}
|
|
72
|
+
*/
|
|
73
|
+
const countChars = (str, ch) => {
|
|
74
|
+
return (str.match(new RegExp(escapeStringRegexp(ch), 'gv')) || []).length;
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* @param {string} text
|
|
78
|
+
* @returns {[
|
|
79
|
+
* Integer,
|
|
80
|
+
* Integer
|
|
81
|
+
* ]}
|
|
82
|
+
*/
|
|
83
|
+
const getLinesCols = (text) => {
|
|
84
|
+
const matchLines = countChars(text, '\n');
|
|
85
|
+
const colDelta = matchLines ?
|
|
86
|
+
text.slice(text.lastIndexOf('\n') + 1).length :
|
|
87
|
+
text.length;
|
|
88
|
+
return [
|
|
89
|
+
matchLines, colDelta,
|
|
90
|
+
];
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* @typedef {number} Integer
|
|
94
|
+
*/
|
|
95
|
+
/**
|
|
96
|
+
* @typedef {object} JsdocProcessorOptions
|
|
97
|
+
* @property {boolean} [captionRequired] Require captions for example tags
|
|
98
|
+
* @property {Integer} [paddedIndent] See docs
|
|
99
|
+
* @property {boolean} [checkDefaults] See docs
|
|
100
|
+
* @property {boolean} [checkParams] See docs
|
|
101
|
+
* @property {boolean} [checkExamples] See docs
|
|
102
|
+
* @property {boolean} [checkProperties] See docs
|
|
103
|
+
* @property {string} [matchingFileName] See docs
|
|
104
|
+
* @property {string} [matchingFileNameDefaults] See docs
|
|
105
|
+
* @property {string} [matchingFileNameParams] See docs
|
|
106
|
+
* @property {string} [matchingFileNameProperties] See docs
|
|
107
|
+
* @property {string|RegExp} [exampleCodeRegex] See docs
|
|
108
|
+
* @property {string|RegExp} [rejectExampleCodeRegex] See docs
|
|
109
|
+
* @property {string[]} [allowedLanguagesToProcess] See docs
|
|
110
|
+
* @property {"script"|"module"} [sourceType] See docs
|
|
111
|
+
* @property {import('eslint').Linter.ESTreeParser|import('eslint').Linter.NonESTreeParser} [parser] See docs
|
|
112
|
+
*/
|
|
113
|
+
/**
|
|
114
|
+
* We use a function for the ability of the user to pass in a config, but
|
|
115
|
+
* without requiring all users of the plugin to do so.
|
|
116
|
+
* @param {JsdocProcessorOptions} [options]
|
|
117
|
+
* @returns {ESLint.Plugin}
|
|
118
|
+
*/
|
|
119
|
+
const getJsdocProcessorPlugin = (options = {}) => {
|
|
120
|
+
const { allowedLanguagesToProcess = [
|
|
121
|
+
'js', 'ts', 'javascript', 'typescript',
|
|
122
|
+
], captionRequired = false, checkDefaults = false, checkExamples = true, checkParams = false, checkProperties = false, exampleCodeRegex = null, matchingFileName = null, matchingFileNameDefaults = null, matchingFileNameParams = null, matchingFileNameProperties = null, paddedIndent = 0, parser = undefined, rejectExampleCodeRegex = null, sourceType = 'module', } = options;
|
|
123
|
+
/** @type {RegExp} */
|
|
124
|
+
let exampleCodeRegExp;
|
|
125
|
+
/** @type {RegExp} */
|
|
126
|
+
let rejectExampleCodeRegExp;
|
|
127
|
+
if (exampleCodeRegex) {
|
|
128
|
+
exampleCodeRegExp = typeof exampleCodeRegex === 'string' ?
|
|
129
|
+
(0, jsdocUtils_js_1.getRegexFromString)(exampleCodeRegex) :
|
|
130
|
+
exampleCodeRegex;
|
|
131
|
+
}
|
|
132
|
+
if (rejectExampleCodeRegex) {
|
|
133
|
+
rejectExampleCodeRegExp = typeof rejectExampleCodeRegex === 'string' ?
|
|
134
|
+
(0, jsdocUtils_js_1.getRegexFromString)(rejectExampleCodeRegex) :
|
|
135
|
+
rejectExampleCodeRegex;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* @type {{
|
|
139
|
+
* targetTagName: string,
|
|
140
|
+
* ext: string,
|
|
141
|
+
* codeStartLine: number,
|
|
142
|
+
* codeStartCol: number,
|
|
143
|
+
* nonJSPrefacingCols: number,
|
|
144
|
+
* commentLineCols: [number, number]
|
|
145
|
+
* }[]}
|
|
146
|
+
*/
|
|
147
|
+
const otherInfo = [];
|
|
148
|
+
/** @type {import('eslint').Linter.LintMessage[]} */
|
|
149
|
+
let extraMessages = [];
|
|
150
|
+
/**
|
|
151
|
+
* @param {JsdocBlockWithInline} jsdoc
|
|
152
|
+
* @param {string} jsFileName
|
|
153
|
+
* @param {[number, number]} commentLineCols
|
|
154
|
+
*/
|
|
155
|
+
const getTextsAndFileNames = (jsdoc, jsFileName, commentLineCols) => {
|
|
156
|
+
/**
|
|
157
|
+
* @type {{
|
|
158
|
+
* text: string,
|
|
159
|
+
* filename: string|null|undefined
|
|
160
|
+
* }[]}
|
|
161
|
+
*/
|
|
162
|
+
const textsAndFileNames = [];
|
|
163
|
+
/**
|
|
164
|
+
* @param {{
|
|
165
|
+
* filename: string|null,
|
|
166
|
+
* defaultFileName: string|undefined,
|
|
167
|
+
* source: string,
|
|
168
|
+
* targetTagName: string,
|
|
169
|
+
* rules?: import('eslint').Linter.RulesRecord|undefined,
|
|
170
|
+
* lines?: Integer,
|
|
171
|
+
* cols?: Integer,
|
|
172
|
+
* skipInit?: boolean,
|
|
173
|
+
* ext: string,
|
|
174
|
+
* sources?: {
|
|
175
|
+
* nonJSPrefacingCols: Integer,
|
|
176
|
+
* nonJSPrefacingLines: Integer,
|
|
177
|
+
* string: string,
|
|
178
|
+
* }[],
|
|
179
|
+
* tag?: import('comment-parser').Spec & {
|
|
180
|
+
* line?: Integer,
|
|
181
|
+
* }|{
|
|
182
|
+
* line: Integer,
|
|
183
|
+
* }
|
|
184
|
+
* }} cfg
|
|
185
|
+
*/
|
|
186
|
+
const checkSource = ({ cols = 0, defaultFileName, ext, filename, lines = 0, skipInit, source, sources = [], tag = {
|
|
187
|
+
line: 0,
|
|
188
|
+
}, targetTagName, }) => {
|
|
189
|
+
if (!skipInit) {
|
|
190
|
+
sources.push({
|
|
191
|
+
nonJSPrefacingCols: cols,
|
|
192
|
+
nonJSPrefacingLines: lines,
|
|
193
|
+
string: source,
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* @param {{
|
|
198
|
+
* nonJSPrefacingCols: Integer,
|
|
199
|
+
* nonJSPrefacingLines: Integer,
|
|
200
|
+
* string: string
|
|
201
|
+
* }} cfg
|
|
202
|
+
*/
|
|
203
|
+
const addSourceInfo = function ({ nonJSPrefacingCols, nonJSPrefacingLines, string, }) {
|
|
204
|
+
const src = paddedIndent ?
|
|
205
|
+
string.replaceAll(new RegExp(`(^|\n) {${paddedIndent}}(?!$)`, 'gv'), '\n') :
|
|
206
|
+
string;
|
|
207
|
+
// Programmatic ESLint API: https://eslint.org/docs/developer-guide/nodejs-api
|
|
208
|
+
const file = filename || defaultFileName;
|
|
209
|
+
if (!('line' in tag)) {
|
|
210
|
+
tag.line = tag.source[0].number;
|
|
211
|
+
}
|
|
212
|
+
// NOTE: `tag.line` can be 0 if of form `/** @tag ... */`
|
|
213
|
+
const codeStartLine = /**
|
|
214
|
+
* @type {import('comment-parser').Spec & {
|
|
215
|
+
* line: Integer,
|
|
216
|
+
* }}
|
|
217
|
+
*/ (tag).line + nonJSPrefacingLines;
|
|
218
|
+
const codeStartCol = likelyNestedJSDocIndentSpace;
|
|
219
|
+
textsAndFileNames.push({
|
|
220
|
+
filename: file,
|
|
221
|
+
text: src,
|
|
222
|
+
});
|
|
223
|
+
otherInfo.push({
|
|
224
|
+
codeStartCol,
|
|
225
|
+
codeStartLine,
|
|
226
|
+
commentLineCols,
|
|
227
|
+
ext,
|
|
228
|
+
nonJSPrefacingCols,
|
|
229
|
+
targetTagName,
|
|
230
|
+
});
|
|
231
|
+
};
|
|
232
|
+
for (const targetSource of sources) {
|
|
233
|
+
addSourceInfo(targetSource);
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
/**
|
|
237
|
+
*
|
|
238
|
+
* @param {string|null} filename
|
|
239
|
+
* @param {string} [ext] Since `eslint-plugin-markdown` v2, and
|
|
240
|
+
* ESLint 7, this is the default which other JS-fenced rules will used.
|
|
241
|
+
* Formerly "md" was the default.
|
|
242
|
+
* @returns {{
|
|
243
|
+
* defaultFileName: string|undefined,
|
|
244
|
+
* filename: string|null,
|
|
245
|
+
* ext: string
|
|
246
|
+
* }}
|
|
247
|
+
*/
|
|
248
|
+
const getFilenameInfo = (filename, ext = 'md/*.js') => {
|
|
249
|
+
let defaultFileName;
|
|
250
|
+
if (!filename) {
|
|
251
|
+
if (typeof jsFileName === 'string' && jsFileName.includes('.')) {
|
|
252
|
+
defaultFileName = jsFileName.replace(/\.[^.]*$/v, `.${ext}`);
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
defaultFileName = `dummy.${ext}`;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return {
|
|
259
|
+
defaultFileName,
|
|
260
|
+
ext,
|
|
261
|
+
filename,
|
|
262
|
+
};
|
|
263
|
+
};
|
|
264
|
+
if (checkDefaults) {
|
|
265
|
+
const filenameInfo = getFilenameInfo(matchingFileNameDefaults, 'jsdoc-defaults');
|
|
266
|
+
(0, jsdocUtils_js_1.forEachPreferredTag)(jsdoc, 'default', (tag, targetTagName) => {
|
|
267
|
+
if (!tag.description.trim()) {
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
checkSource({
|
|
271
|
+
source: `(${(0, jsdocUtils_js_1.getTagDescription)(tag)})`,
|
|
272
|
+
targetTagName,
|
|
273
|
+
...filenameInfo,
|
|
274
|
+
});
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
if (checkParams) {
|
|
278
|
+
const filenameInfo = getFilenameInfo(matchingFileNameParams, 'jsdoc-params');
|
|
279
|
+
(0, jsdocUtils_js_1.forEachPreferredTag)(jsdoc, 'param', (tag, targetTagName) => {
|
|
280
|
+
if (!tag.default || !tag.default.trim()) {
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
checkSource({
|
|
284
|
+
source: `(${tag.default})`,
|
|
285
|
+
targetTagName,
|
|
286
|
+
...filenameInfo,
|
|
287
|
+
});
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
if (checkProperties) {
|
|
291
|
+
const filenameInfo = getFilenameInfo(matchingFileNameProperties, 'jsdoc-properties');
|
|
292
|
+
(0, jsdocUtils_js_1.forEachPreferredTag)(jsdoc, 'property', (tag, targetTagName) => {
|
|
293
|
+
if (!tag.default || !tag.default.trim()) {
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
checkSource({
|
|
297
|
+
source: `(${tag.default})`,
|
|
298
|
+
targetTagName,
|
|
299
|
+
...filenameInfo,
|
|
300
|
+
});
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
if (!checkExamples) {
|
|
304
|
+
return textsAndFileNames;
|
|
305
|
+
}
|
|
306
|
+
const tagName = /** @type {string} */ ((0, jsdocUtils_js_1.getPreferredTagName)(jsdoc, {
|
|
307
|
+
tagName: 'example',
|
|
308
|
+
}));
|
|
309
|
+
if (!(0, jsdocUtils_js_1.hasTag)(jsdoc, tagName)) {
|
|
310
|
+
return textsAndFileNames;
|
|
311
|
+
}
|
|
312
|
+
const matchingFilenameInfo = getFilenameInfo(matchingFileName);
|
|
313
|
+
(0, jsdocUtils_js_1.forEachPreferredTag)(jsdoc, 'example', (tag, targetTagName) => {
|
|
314
|
+
let source = /** @type {string} */ ((0, jsdocUtils_js_1.getTagDescription)(tag));
|
|
315
|
+
const match = source.match(hasCaptionRegex);
|
|
316
|
+
if (captionRequired && (!match || !match[1].trim())) {
|
|
317
|
+
extraMessages.push({
|
|
318
|
+
column: commentLineCols[1] + 1,
|
|
319
|
+
line: 1 + commentLineCols[0] + (tag.line ?? tag.source[0].number),
|
|
320
|
+
message: `@${targetTagName} error - Caption is expected for examples.`,
|
|
321
|
+
ruleId: 'jsdoc/example-missing-caption',
|
|
322
|
+
severity: 2,
|
|
323
|
+
});
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
source = source.replace(hasCaptionRegex, '');
|
|
327
|
+
const [lines, cols,] = match ? getLinesCols(match[0]) : [
|
|
328
|
+
0, 0,
|
|
329
|
+
];
|
|
330
|
+
if (exampleCodeRegex && !exampleCodeRegExp.test(source) ||
|
|
331
|
+
rejectExampleCodeRegex && rejectExampleCodeRegExp.test(source)) {
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
// If `allowedLanguagesToProcess` is falsy, all languages should be processed.
|
|
335
|
+
if (allowedLanguagesToProcess) {
|
|
336
|
+
const matches = (/^\s*```(?<language>\S+)([\s\S]*)```\s*$/v).exec(source);
|
|
337
|
+
if (matches?.groups && !allowedLanguagesToProcess.includes(matches.groups.language.toLowerCase())) {
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
const sources = [];
|
|
342
|
+
let skipInit = false;
|
|
343
|
+
if (exampleCodeRegex) {
|
|
344
|
+
let nonJSPrefacingCols = 0;
|
|
345
|
+
let nonJSPrefacingLines = 0;
|
|
346
|
+
let startingIndex = 0;
|
|
347
|
+
let lastStringCount = 0;
|
|
348
|
+
let exampleCode;
|
|
349
|
+
exampleCodeRegExp.lastIndex = 0;
|
|
350
|
+
while ((exampleCode = exampleCodeRegExp.exec(source)) !== null) {
|
|
351
|
+
const { '0': n0, '1': n1, index, } = exampleCode;
|
|
352
|
+
// Count anything preceding user regex match (can affect line numbering)
|
|
353
|
+
const preMatch = source.slice(startingIndex, index);
|
|
354
|
+
const [preMatchLines, colDelta,] = getLinesCols(preMatch);
|
|
355
|
+
let nonJSPreface;
|
|
356
|
+
let nonJSPrefaceLineCount;
|
|
357
|
+
if (n1) {
|
|
358
|
+
const idx = n0.indexOf(n1);
|
|
359
|
+
nonJSPreface = n0.slice(0, idx);
|
|
360
|
+
nonJSPrefaceLineCount = countChars(nonJSPreface, '\n');
|
|
361
|
+
}
|
|
362
|
+
else {
|
|
363
|
+
nonJSPreface = '';
|
|
364
|
+
nonJSPrefaceLineCount = 0;
|
|
365
|
+
}
|
|
366
|
+
nonJSPrefacingLines += lastStringCount + preMatchLines + nonJSPrefaceLineCount;
|
|
367
|
+
// Ignore `preMatch` delta if newlines here
|
|
368
|
+
if (nonJSPrefaceLineCount) {
|
|
369
|
+
const charsInLastLine = nonJSPreface.slice(nonJSPreface.lastIndexOf('\n') + 1).length;
|
|
370
|
+
nonJSPrefacingCols += charsInLastLine;
|
|
371
|
+
}
|
|
372
|
+
else {
|
|
373
|
+
nonJSPrefacingCols += colDelta + nonJSPreface.length;
|
|
374
|
+
}
|
|
375
|
+
const string = n1 || n0;
|
|
376
|
+
sources.push({
|
|
377
|
+
nonJSPrefacingCols,
|
|
378
|
+
nonJSPrefacingLines,
|
|
379
|
+
string,
|
|
380
|
+
});
|
|
381
|
+
startingIndex = exampleCodeRegExp.lastIndex;
|
|
382
|
+
lastStringCount = countChars(string, '\n');
|
|
383
|
+
if (!exampleCodeRegExp.global) {
|
|
384
|
+
break;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
skipInit = true;
|
|
388
|
+
}
|
|
389
|
+
checkSource({
|
|
390
|
+
cols,
|
|
391
|
+
lines,
|
|
392
|
+
skipInit,
|
|
393
|
+
source,
|
|
394
|
+
sources,
|
|
395
|
+
tag,
|
|
396
|
+
targetTagName,
|
|
397
|
+
...matchingFilenameInfo,
|
|
398
|
+
});
|
|
399
|
+
});
|
|
400
|
+
return textsAndFileNames;
|
|
401
|
+
};
|
|
402
|
+
// See https://eslint.org/docs/latest/extend/plugins#processors-in-plugins
|
|
403
|
+
// See https://eslint.org/docs/latest/extend/custom-processors
|
|
404
|
+
// From https://github.com/eslint/eslint/issues/14745#issuecomment-869457265
|
|
405
|
+
/*
|
|
406
|
+
{
|
|
407
|
+
"files": ["*.js", "*.ts"],
|
|
408
|
+
"processor": "jsdoc/example" // a pretended value here
|
|
409
|
+
},
|
|
410
|
+
{
|
|
411
|
+
"files": [
|
|
412
|
+
"*.js/*_jsdoc-example.js",
|
|
413
|
+
"*.ts/*_jsdoc-example.js",
|
|
414
|
+
"*.js/*_jsdoc-example.ts"
|
|
415
|
+
],
|
|
416
|
+
"rules": {
|
|
417
|
+
// specific rules for examples in jsdoc only here
|
|
418
|
+
// And other rules for `.js` and `.ts` will also be enabled for them
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
*/
|
|
422
|
+
return {
|
|
423
|
+
meta: {
|
|
424
|
+
name: 'eslint-plugin-jsdoc/processor',
|
|
425
|
+
version,
|
|
426
|
+
},
|
|
427
|
+
processors: {
|
|
428
|
+
examples: {
|
|
429
|
+
meta: {
|
|
430
|
+
name: 'eslint-plugin-jsdoc/preprocessor',
|
|
431
|
+
version,
|
|
432
|
+
},
|
|
433
|
+
/**
|
|
434
|
+
* @param {import('eslint').Linter.LintMessage[][]} messages
|
|
435
|
+
* @param {string} filename
|
|
436
|
+
*/
|
|
437
|
+
postprocess([jsMessages, ...messages
|
|
438
|
+
// eslint-disable-next-line no-unused-vars -- Placeholder
|
|
439
|
+
], filename) {
|
|
440
|
+
for (const [idx, message,] of messages.entries()) {
|
|
441
|
+
const { codeStartCol, codeStartLine, commentLineCols, nonJSPrefacingCols, targetTagName, } = otherInfo[idx];
|
|
442
|
+
for (const msg of message) {
|
|
443
|
+
const { column, endColumn, endLine, fatal, line, message: messageText, ruleId, severity,
|
|
444
|
+
// Todo: Make fixable
|
|
445
|
+
// fix
|
|
446
|
+
// fix: {range: [number, number], text: string}
|
|
447
|
+
// suggestions: {desc: , messageId:, fix: }[],
|
|
448
|
+
} = msg;
|
|
449
|
+
delete msg.fix;
|
|
450
|
+
const [codeCtxLine, codeCtxColumn,] = commentLineCols;
|
|
451
|
+
const startLine = codeCtxLine + codeStartLine + line;
|
|
452
|
+
// Seems to need one more now
|
|
453
|
+
const startCol = 1 +
|
|
454
|
+
codeCtxColumn + codeStartCol + (
|
|
455
|
+
// This might not work for line 0, but line 0 is unlikely for examples
|
|
456
|
+
line <= 1 ? nonJSPrefacingCols + firstLinePrefixLength : preTagSpaceLength) + column;
|
|
457
|
+
msg.message = '@' + targetTagName + ' ' + (severity === 2 ? 'error' : 'warning') +
|
|
458
|
+
(ruleId ? ' (' + ruleId + ')' : '') + ': ' +
|
|
459
|
+
(fatal ? 'Fatal: ' : '') +
|
|
460
|
+
messageText;
|
|
461
|
+
msg.line = startLine;
|
|
462
|
+
msg.column = startCol;
|
|
463
|
+
msg.endLine = endLine ? startLine + endLine : startLine;
|
|
464
|
+
// added `- column` to offset what `endColumn` already seemed to include
|
|
465
|
+
msg.endColumn = endColumn ? startCol - column + endColumn : startCol;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
const ret = [
|
|
469
|
+
...jsMessages,
|
|
470
|
+
].concat(...messages, ...extraMessages);
|
|
471
|
+
extraMessages = [];
|
|
472
|
+
return ret;
|
|
473
|
+
},
|
|
474
|
+
/**
|
|
475
|
+
* @param {string} text
|
|
476
|
+
* @param {string} filename
|
|
477
|
+
* @returns {(string | Linter.ProcessorFile)[]}
|
|
478
|
+
*/
|
|
479
|
+
preprocess(text, filename) {
|
|
480
|
+
try {
|
|
481
|
+
let ast;
|
|
482
|
+
// May be running a second time so catch and ignore
|
|
483
|
+
try {
|
|
484
|
+
ast = parser ?
|
|
485
|
+
// @ts-expect-error Should be present
|
|
486
|
+
parser.parseForESLint(text, {
|
|
487
|
+
comment: true,
|
|
488
|
+
ecmaVersion: 'latest',
|
|
489
|
+
sourceType,
|
|
490
|
+
}).ast :
|
|
491
|
+
espree.parse(text, {
|
|
492
|
+
comment: true,
|
|
493
|
+
ecmaVersion: 'latest',
|
|
494
|
+
sourceType,
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
catch {
|
|
498
|
+
return [
|
|
499
|
+
text,
|
|
500
|
+
];
|
|
501
|
+
}
|
|
502
|
+
/** @type {[number, number][]} */
|
|
503
|
+
const commentLineCols = [];
|
|
504
|
+
const jsdocComments = /** @type {import('estree').Comment[]} */ (
|
|
505
|
+
/**
|
|
506
|
+
* @type {import('estree').Program & {
|
|
507
|
+
* comments?: import('estree').Comment[]
|
|
508
|
+
* }}
|
|
509
|
+
*/
|
|
510
|
+
(ast).comments).filter((comment) => {
|
|
511
|
+
return (/^\*\s/v).test(comment.value);
|
|
512
|
+
}).map((comment) => {
|
|
513
|
+
const [start,
|
|
514
|
+
/* c8 ignore next -- Unsupporting processors only? */
|
|
515
|
+
] = comment.range ?? [];
|
|
516
|
+
const textToStart = text.slice(0, start);
|
|
517
|
+
const [lines, cols,] = getLinesCols(textToStart);
|
|
518
|
+
// const lines = [...textToStart.matchAll(/\n/gv)].length
|
|
519
|
+
// const lastLinePos = textToStart.lastIndexOf('\n');
|
|
520
|
+
// const cols = lastLinePos === -1
|
|
521
|
+
// ? 0
|
|
522
|
+
// : textToStart.slice(lastLinePos).length;
|
|
523
|
+
commentLineCols.push([
|
|
524
|
+
lines, cols,
|
|
525
|
+
]);
|
|
526
|
+
return (0, jsdoccomment_1.parseComment)(comment);
|
|
527
|
+
});
|
|
528
|
+
return [
|
|
529
|
+
text,
|
|
530
|
+
...jsdocComments.flatMap((jsdoc, idx) => {
|
|
531
|
+
return getTextsAndFileNames(jsdoc, filename, commentLineCols[idx]);
|
|
532
|
+
}).filter(
|
|
533
|
+
/**
|
|
534
|
+
* @returns {file is Linter.ProcessorFile}
|
|
535
|
+
*/
|
|
536
|
+
(file) => {
|
|
537
|
+
return file !== null && file !== undefined;
|
|
538
|
+
}),
|
|
539
|
+
];
|
|
540
|
+
/* c8 ignore next 6 */
|
|
541
|
+
}
|
|
542
|
+
catch (error) {
|
|
543
|
+
// eslint-disable-next-line no-console -- Debugging
|
|
544
|
+
console.log('err', filename, error);
|
|
545
|
+
}
|
|
546
|
+
return [];
|
|
547
|
+
},
|
|
548
|
+
supportsAutofix: true,
|
|
549
|
+
},
|
|
550
|
+
},
|
|
551
|
+
};
|
|
552
|
+
};
|
|
553
|
+
exports.getJsdocProcessorPlugin = getJsdocProcessorPlugin;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export default index;
|
|
2
|
+
export type ConfigGroups = "recommended" | "stylistic" | "contents" | "logical" | "requirements";
|
|
3
|
+
export type ConfigVariants = "" | "-typescript" | "-typescript-flavor";
|
|
4
|
+
export type ErrorLevelVariants = "" | "-error";
|
|
5
|
+
/**
|
|
6
|
+
* @typedef {"recommended" | "stylistic" | "contents" | "logical" | "requirements"} ConfigGroups
|
|
7
|
+
* @typedef {"" | "-typescript" | "-typescript-flavor"} ConfigVariants
|
|
8
|
+
* @typedef {"" | "-error"} ErrorLevelVariants
|
|
9
|
+
* @type {import('eslint').ESLint.Plugin & {
|
|
10
|
+
* configs: Record<`flat/${ConfigGroups}${ConfigVariants}${ErrorLevelVariants}`,
|
|
11
|
+
* import('eslint').Linter.Config>
|
|
12
|
+
* }}
|
|
13
|
+
*/
|
|
14
|
+
declare const index: import("eslint").ESLint.Plugin & {
|
|
15
|
+
configs: Record<`flat/${ConfigGroups}${ConfigVariants}${ErrorLevelVariants}`, import("eslint").Linter.Config>;
|
|
16
|
+
};
|