eslint-plugin-crisp 1.4.7 → 1.4.9
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 +11 -3
- package/index.js +4 -0
- package/package.json +1 -1
- package/recommended-ts.js +10 -0
- package/recommended-vue.js +1 -0
- package/recommended.js +2 -1
- package/rules/jsdoc-description-length.js +113 -0
- package/rules/jsdoc-no-param-return.js +63 -0
package/README.md
CHANGED
|
@@ -146,12 +146,18 @@ Each item has emojis denoting:
|
|
|
146
146
|
| Name | Description | 🟠 | 🟢 | 🟣 |
|
|
147
147
|
| :- | :- | :- | :- | :- |
|
|
148
148
|
| [jsdoc/no-undefined-types](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/no-undefined-types.md) | Rule is **disabled** to allow some undefined types | 🟠 |
|
|
149
|
+
| [jsdoc/no-types](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/no-types.md) | Disallows types in JSDoc tags, relying on the TypeScript signature instead | | | 🟣 |
|
|
149
150
|
| [jsdoc/require-description](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-description.md) | Requires all functions to have a description in their JSDoc | | 🟢 | 🟣 |
|
|
150
151
|
| [jsdoc/require-param](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-param.md) | Rule is **disabled** as TS functions are self documented | | | 🟣 |
|
|
152
|
+
| [jsdoc/require-param-type](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-param-type.md) | Rule is **disabled** as types come from the TypeScript signature | | | 🟣 |
|
|
151
153
|
| [jsdoc/require-param-description](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-param-description.md) | Rule is **disabled** as we don't write any description for `@param` tags | 🟠 | 🟢 | 🟣 |
|
|
152
|
-
| [jsdoc/
|
|
153
|
-
| [jsdoc/require-
|
|
154
|
-
| [jsdoc/require-
|
|
154
|
+
| [jsdoc/check-param-names](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/check-param-names.md) | Rule is **disabled** as TS functions are self documented | | | 🟣 |
|
|
155
|
+
| [jsdoc/require-property-description](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-property-description.md) | Rule is **disabled** as we don't write any description for `@property` tags | 🟠 | 🟢 | 🟣 |
|
|
156
|
+
| [jsdoc/require-returns](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-returns.md) | Rule is **disabled** as TS functions are self documented | | | 🟣 |
|
|
157
|
+
| [jsdoc/require-returns-type](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-returns-type.md) | Rule is **disabled** as types come from the TypeScript signature | | | 🟣 |
|
|
158
|
+
| [jsdoc/require-returns-check](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-returns-check.md) | Rule is **disabled** as we don't write `@returns` tags | | | 🟣 |
|
|
159
|
+
| [jsdoc/require-yields](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-yields.md) | Rule is **disabled** as TS functions are self documented | | | 🟣 |
|
|
160
|
+
| [jsdoc/require-yields-check](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-yields-check.md) | Rule is **disabled** as we don't write `@yields` tags | | | 🟣 |
|
|
155
161
|
| [jsdoc/require-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-jsdoc.md) | Enforces JSDoc comments on functions and classes | 🟠 | 🟢 | 🟣 |
|
|
156
162
|
| [jsdoc/sort-tags](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/sort-tags.md) | Enforces specific order for tags | 🟠 | 🟢 | 🟣 |
|
|
157
163
|
|
|
@@ -165,6 +171,8 @@ Each item has emojis denoting:
|
|
|
165
171
|
| [crisp/jsdoc-enforce-access](https://github.com/crisp-oss/eslint-plugin-crisp/blob/master/rules/jsdoc-enforce-access.js) | Requires one of `@public`, `@private`, or `@protected` for functions | | 🟢 |
|
|
166
172
|
| [crisp/jsdoc-enforce-classdesc](https://github.com/crisp-oss/eslint-plugin-crisp/blob/master/rules/jsdoc-enforce-classdesc.js) | Ensures JSDoc for class headers to include a non-empty `@classdesc` | 🟠 | 🟢 |
|
|
167
173
|
| [crisp/jsdoc-require-description-uppercase](https://github.com/crisp-oss/eslint-plugin-crisp/blob/master/rules/jsdoc-require-description-uppercase.js) | Requires descriptions to start with an uppercase character | 🟠 | 🟢 |
|
|
174
|
+
| [crisp/jsdoc-description-length](https://github.com/crisp-oss/eslint-plugin-crisp/blob/master/rules/jsdoc-description-length.js) | Enforces a maximum length for JSDoc descriptions | 🟠 | 🟢 | 🟣 |
|
|
175
|
+
| [crisp/jsdoc-no-param-return](https://github.com/crisp-oss/eslint-plugin-crisp/blob/master/rules/jsdoc-no-param-return.js) | Forbids `@param` and `@return` tags in JSDoc, relying on the TypeScript signature instead | | | 🟣 |
|
|
168
176
|
|
|
169
177
|
#### General Vue rules
|
|
170
178
|
|
package/index.js
CHANGED
|
@@ -18,7 +18,9 @@ import ruleJsdocCheckIndentation from "./rules/jsdoc-check-indentation.js";
|
|
|
18
18
|
import ruleJsdocCheckOptionalParams from "./rules/jsdoc-check-optional-params.js";
|
|
19
19
|
import ruleJsdocEnforceAccess from "./rules/jsdoc-enforce-access.js";
|
|
20
20
|
import ruleJsdocEnforceClassdesc from "./rules/jsdoc-enforce-classdesc.js";
|
|
21
|
+
import ruleJsdocNoParamReturn from "./rules/jsdoc-no-param-return.js";
|
|
21
22
|
import ruleJsdocRequireDescriptionUppercase from "./rules/jsdoc-require-description-uppercase.js";
|
|
23
|
+
import ruleJsdocDescriptionLength from "./rules/jsdoc-description-length.js";
|
|
22
24
|
import ruleMethodsNaming from "./rules/methods-naming.js";
|
|
23
25
|
import ruleMethodsOrdering from "./rules/methods-ordering.js";
|
|
24
26
|
import ruleMultilineCommentEndBackslash from "./rules/multiline-comment-end-backslash.js";
|
|
@@ -80,7 +82,9 @@ const plugin = {
|
|
|
80
82
|
"jsdoc-check-optional-params": ruleJsdocCheckOptionalParams,
|
|
81
83
|
"jsdoc-enforce-access": ruleJsdocEnforceAccess,
|
|
82
84
|
"jsdoc-enforce-classdesc": ruleJsdocEnforceClassdesc,
|
|
85
|
+
"jsdoc-no-param-return": ruleJsdocNoParamReturn,
|
|
83
86
|
"jsdoc-require-description-uppercase": ruleJsdocRequireDescriptionUppercase,
|
|
87
|
+
"jsdoc-description-length": ruleJsdocDescriptionLength,
|
|
84
88
|
"methods-naming": ruleMethodsNaming,
|
|
85
89
|
"methods-ordering": ruleMethodsOrdering,
|
|
86
90
|
"multiline-comment-end-backslash": ruleMultilineCommentEndBackslash,
|
package/package.json
CHANGED
package/recommended-ts.js
CHANGED
|
@@ -181,13 +181,23 @@ export default function configRecommendedTS(pluginCrisp) {
|
|
|
181
181
|
"crisp/regex-in-constructor": "error",
|
|
182
182
|
"crisp/ternary-parenthesis": "error",
|
|
183
183
|
|
|
184
|
+
// Crisp JSDoc rules
|
|
185
|
+
"crisp/jsdoc-description-length": "error",
|
|
186
|
+
"crisp/jsdoc-no-param-return": "error",
|
|
187
|
+
|
|
184
188
|
// General JSDoc rules
|
|
189
|
+
"jsdoc/no-types": "error",
|
|
185
190
|
"jsdoc/require-description": "error",
|
|
186
191
|
"jsdoc/require-param": "off",
|
|
192
|
+
"jsdoc/require-param-type": "off",
|
|
187
193
|
"jsdoc/require-param-description": "off",
|
|
194
|
+
"jsdoc/check-param-names": "off",
|
|
188
195
|
"jsdoc/require-property-description": "off",
|
|
189
196
|
"jsdoc/require-returns": "off",
|
|
197
|
+
"jsdoc/require-returns-type": "off",
|
|
198
|
+
"jsdoc/require-returns-check": "off",
|
|
190
199
|
"jsdoc/require-yields": "off",
|
|
200
|
+
"jsdoc/require-yields-check": "off",
|
|
191
201
|
"jsdoc/require-jsdoc": [
|
|
192
202
|
"error",
|
|
193
203
|
|
package/recommended-vue.js
CHANGED
|
@@ -247,6 +247,7 @@ export default function configRecommendedVue(pluginCrisp) {
|
|
|
247
247
|
"crisp/jsdoc-enforce-access": "error",
|
|
248
248
|
"crisp/jsdoc-enforce-classdesc": "error",
|
|
249
249
|
"crisp/jsdoc-require-description-uppercase": "error",
|
|
250
|
+
"crisp/jsdoc-description-length": "error",
|
|
250
251
|
|
|
251
252
|
// General Vue rules
|
|
252
253
|
"vue/attributes-order": [
|
package/recommended.js
CHANGED
|
@@ -232,7 +232,8 @@ export default function configRecommended(pluginCrisp) {
|
|
|
232
232
|
"crisp/jsdoc-align-params": "error",
|
|
233
233
|
"crisp/jsdoc-check-indentation": "error",
|
|
234
234
|
"crisp/jsdoc-enforce-classdesc": "error",
|
|
235
|
-
"crisp/jsdoc-require-description-uppercase": "error"
|
|
235
|
+
"crisp/jsdoc-require-description-uppercase": "error",
|
|
236
|
+
"crisp/jsdoc-description-length": "error"
|
|
236
237
|
}
|
|
237
238
|
}
|
|
238
239
|
];
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
meta: {
|
|
3
|
+
type: "suggestion",
|
|
4
|
+
docs: {
|
|
5
|
+
description:
|
|
6
|
+
"Enforce JSDoc description line limits and continuation format.",
|
|
7
|
+
},
|
|
8
|
+
schema: [
|
|
9
|
+
{
|
|
10
|
+
type: "object",
|
|
11
|
+
properties: {
|
|
12
|
+
maxLines: {
|
|
13
|
+
type: "integer",
|
|
14
|
+
minimum: 1,
|
|
15
|
+
default: 2,
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
additionalProperties: false,
|
|
19
|
+
},
|
|
20
|
+
],
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
create(context) {
|
|
24
|
+
const options = context.options[0] || {};
|
|
25
|
+
const maxLines = options.maxLines || 2;
|
|
26
|
+
const sourceCode = context.sourceCode || context.getSourceCode();
|
|
27
|
+
|
|
28
|
+
function checkComment(comment) {
|
|
29
|
+
if (comment.type !== "Block" || !comment.value.startsWith("*")) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Skip section headers (lines full of asterisks)
|
|
34
|
+
if (/\*{10,}/.test(comment.value)) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const rawLines = comment.value.split("\n").slice(1);
|
|
39
|
+
|
|
40
|
+
// Extract description lines (before any @tag)
|
|
41
|
+
const descLines = [];
|
|
42
|
+
|
|
43
|
+
for (const line of rawLines) {
|
|
44
|
+
const content = line.replace(/^\s*\*\s?/, "");
|
|
45
|
+
|
|
46
|
+
if (content.trimStart().startsWith("@")) {
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (content.trim().length > 0) {
|
|
51
|
+
descLines.push({ raw: line, content: content });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (descLines.length <= 1) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (descLines.length > maxLines) {
|
|
60
|
+
context.report({
|
|
61
|
+
loc: comment.loc,
|
|
62
|
+
message:
|
|
63
|
+
"JSDoc description must not exceed {{ maxLines }} line(s).",
|
|
64
|
+
data: { maxLines: String(maxLines) },
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Multi-line is allowed, check continuation format
|
|
71
|
+
for (let i = 0; i < descLines.length - 1; i++) {
|
|
72
|
+
const trimmed = descLines[i].content.trimEnd();
|
|
73
|
+
|
|
74
|
+
if (!trimmed.endsWith("\\")) {
|
|
75
|
+
context.report({
|
|
76
|
+
loc: comment.loc,
|
|
77
|
+
message:
|
|
78
|
+
"Multi-line JSDoc description must end with '\\' before " +
|
|
79
|
+
"each continuation.",
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Check indentation on continuation lines (3 spaces after *)
|
|
87
|
+
for (let i = 1; i < descLines.length; i++) {
|
|
88
|
+
const match = descLines[i].raw.match(/^\s*\*( *)/);
|
|
89
|
+
|
|
90
|
+
if (!match || match[1].length !== 3) {
|
|
91
|
+
context.report({
|
|
92
|
+
loc: comment.loc,
|
|
93
|
+
message:
|
|
94
|
+
"Continuation lines in JSDoc description must be indented " +
|
|
95
|
+
"with 3 spaces after '*'.",
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return {
|
|
104
|
+
"Program:exit"() {
|
|
105
|
+
const comments = sourceCode.getAllComments();
|
|
106
|
+
|
|
107
|
+
for (const comment of comments) {
|
|
108
|
+
checkComment(comment);
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
},
|
|
113
|
+
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
const FORBIDDEN_TAG_REGEX = /^\s*\*\s*@(param|arg|argument|returns?|yields?)\b/;
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
meta: {
|
|
5
|
+
type: "suggestion",
|
|
6
|
+
docs: {
|
|
7
|
+
description:
|
|
8
|
+
"Forbid @param and @return tags (and their descriptions) in JSDoc, " +
|
|
9
|
+
"rely on the TypeScript signature instead.",
|
|
10
|
+
},
|
|
11
|
+
fixable: "code",
|
|
12
|
+
schema: [],
|
|
13
|
+
messages: {
|
|
14
|
+
noParamReturn:
|
|
15
|
+
"@param and @return tags are not permitted in JSDoc, rely on the " +
|
|
16
|
+
"TypeScript signature instead.",
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
create(context) {
|
|
21
|
+
const sourceCode = context.sourceCode || context.getSourceCode();
|
|
22
|
+
|
|
23
|
+
function checkComment(comment) {
|
|
24
|
+
if (comment.type !== "Block" || !comment.value.startsWith("*")) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const lines = comment.value.split("\n");
|
|
29
|
+
|
|
30
|
+
// Detect whether at least one forbidden tag line is present
|
|
31
|
+
const hasForbidden = lines.some((line) => {
|
|
32
|
+
return FORBIDDEN_TAG_REGEX.test(line);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
if (!hasForbidden) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
context.report({
|
|
40
|
+
node: comment,
|
|
41
|
+
messageId: "noParamReturn",
|
|
42
|
+
|
|
43
|
+
fix(fixer) {
|
|
44
|
+
const kept = lines.filter((line) => {
|
|
45
|
+
return !FORBIDDEN_TAG_REGEX.test(line);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
return fixer.replaceText(comment, `/*${kept.join("\n")}*/`);
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return {
|
|
54
|
+
"Program:exit"() {
|
|
55
|
+
const comments = sourceCode.getAllComments();
|
|
56
|
+
|
|
57
|
+
for (const comment of comments) {
|
|
58
|
+
checkComment(comment);
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
},
|
|
63
|
+
};
|