eslint-plugin-conventions 4.0.4 → 4.0.7
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 +1 -1
- package/package.json +1 -1
- package/src/index.d.ts +7 -79
- package/src/index.js +6 -14
- package/src/index.js.map +1 -1
- package/src/rules/conventions/no-json-schema-tags.d.ts +29 -0
- package/src/rules/conventions/no-json-schema-tags.js +185 -0
- package/src/rules/conventions/no-json-schema-tags.js.map +1 -0
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
<a href="https://www.npmjs.com/package/eslint-plugin-conventions" target="_blank"><img src="https://img.shields.io/npm/v/eslint-plugin-conventions.svg" alt="NPM Version" /></a>
|
|
11
11
|
<a href="https://www.npmjs.com/package/eslint-plugin-conventions" target="_blank"><img src="https://img.shields.io/npm/dm/eslint-plugin-conventions.svg" alt="NPM Downloads" /></a>
|
|
12
12
|
<a href="https://opensource.org/licenses/MIT" target="_blank"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="Package License" /></a>
|
|
13
|
-
<a href="https://app.codecov.io/gh/ofri-peretz/eslint/components?components%5B0%5D=conventions" target="_blank"><img src="https://codecov.io/gh/ofri-peretz/eslint/graph/badge.svg?component=eslint-plugin-conventions" alt="Codecov" /></a>
|
|
13
|
+
<a href="https://app.codecov.io/gh/ofri-peretz/eslint/components?components%5B0%5D=eslint-plugin-conventions" target="_blank"><img src="https://codecov.io/gh/ofri-peretz/eslint/graph/badge.svg?component=eslint-plugin-conventions" alt="Codecov" /></a>
|
|
14
14
|
<a href="https://github.com/ofri-peretz/eslint" target="_blank"><img src="https://img.shields.io/badge/Since-Dec_2025-blue?logo=rocket&logoColor=white" alt="Since Dec 2025" /></a>
|
|
15
15
|
</p>
|
|
16
16
|
|
package/package.json
CHANGED
package/src/index.d.ts
CHANGED
|
@@ -32,31 +32,7 @@ export declare const rules: {
|
|
|
32
32
|
'consistent-existence-index-check': TSESLint.RuleModule<"consistentExistenceCheck", [(import("./rules/conventions/consistent-existence-index-check").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
33
33
|
name: string;
|
|
34
34
|
};
|
|
35
|
-
'
|
|
36
|
-
name: string;
|
|
37
|
-
};
|
|
38
|
-
'conventions/expiring-todo-comments': TSESLint.RuleModule<"expiringTodoComment" | "invalidTodoCondition" | "multipleTodoConditions", [(import("./rules/conventions/expiring-todo-comments").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
39
|
-
name: string;
|
|
40
|
-
};
|
|
41
|
-
'conventions/prefer-code-point': TSESLint.RuleModule<"preferCodePoint", [], unknown, TSESLint.RuleListener> & {
|
|
42
|
-
name: string;
|
|
43
|
-
};
|
|
44
|
-
'conventions/prefer-dom-node-text-content': TSESLint.RuleModule<"preferDomNodeTextContent", [], unknown, TSESLint.RuleListener> & {
|
|
45
|
-
name: string;
|
|
46
|
-
};
|
|
47
|
-
'conventions/no-console-spaces': TSESLint.RuleModule<"noConsoleSpaces", [], unknown, TSESLint.RuleListener> & {
|
|
48
|
-
name: string;
|
|
49
|
-
};
|
|
50
|
-
'deprecation/no-deprecated-api': TSESLint.RuleModule<"deprecatedAPI" | "useReplacement", [(import("./rules/deprecation/no-deprecated-api").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
51
|
-
name: string;
|
|
52
|
-
};
|
|
53
|
-
'conventions/prefer-dependency-version-strategy': TSESLint.RuleModule<"preferStrategy" | "invalidStrategy", [(import("./rules/conventions/prefer-dependency-version-strategy").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
54
|
-
name: string;
|
|
55
|
-
};
|
|
56
|
-
'conventions/filename-case': TSESLint.RuleModule<"filenameCase", [(import("./rules/conventions/filename-case").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
57
|
-
name: string;
|
|
58
|
-
};
|
|
59
|
-
'conventions/consistent-existence-index-check': TSESLint.RuleModule<"consistentExistenceCheck", [(import("./rules/conventions/consistent-existence-index-check").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
35
|
+
'no-json-schema-tags': TSESLint.RuleModule<"jsonSchemaTag" | "moveToDescription", [(import("./rules/conventions/no-json-schema-tags").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
60
36
|
name: string;
|
|
61
37
|
};
|
|
62
38
|
};
|
|
@@ -93,31 +69,7 @@ export declare const plugin: {
|
|
|
93
69
|
'consistent-existence-index-check': TSESLint.RuleModule<"consistentExistenceCheck", [(import("./rules/conventions/consistent-existence-index-check").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
94
70
|
name: string;
|
|
95
71
|
};
|
|
96
|
-
'
|
|
97
|
-
name: string;
|
|
98
|
-
};
|
|
99
|
-
'conventions/expiring-todo-comments': TSESLint.RuleModule<"expiringTodoComment" | "invalidTodoCondition" | "multipleTodoConditions", [(import("./rules/conventions/expiring-todo-comments").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
100
|
-
name: string;
|
|
101
|
-
};
|
|
102
|
-
'conventions/prefer-code-point': TSESLint.RuleModule<"preferCodePoint", [], unknown, TSESLint.RuleListener> & {
|
|
103
|
-
name: string;
|
|
104
|
-
};
|
|
105
|
-
'conventions/prefer-dom-node-text-content': TSESLint.RuleModule<"preferDomNodeTextContent", [], unknown, TSESLint.RuleListener> & {
|
|
106
|
-
name: string;
|
|
107
|
-
};
|
|
108
|
-
'conventions/no-console-spaces': TSESLint.RuleModule<"noConsoleSpaces", [], unknown, TSESLint.RuleListener> & {
|
|
109
|
-
name: string;
|
|
110
|
-
};
|
|
111
|
-
'deprecation/no-deprecated-api': TSESLint.RuleModule<"deprecatedAPI" | "useReplacement", [(import("./rules/deprecation/no-deprecated-api").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
112
|
-
name: string;
|
|
113
|
-
};
|
|
114
|
-
'conventions/prefer-dependency-version-strategy': TSESLint.RuleModule<"preferStrategy" | "invalidStrategy", [(import("./rules/conventions/prefer-dependency-version-strategy").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
115
|
-
name: string;
|
|
116
|
-
};
|
|
117
|
-
'conventions/filename-case': TSESLint.RuleModule<"filenameCase", [(import("./rules/conventions/filename-case").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
118
|
-
name: string;
|
|
119
|
-
};
|
|
120
|
-
'conventions/consistent-existence-index-check': TSESLint.RuleModule<"consistentExistenceCheck", [(import("./rules/conventions/consistent-existence-index-check").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
72
|
+
'no-json-schema-tags': TSESLint.RuleModule<"jsonSchemaTag" | "moveToDescription", [(import("./rules/conventions/no-json-schema-tags").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
121
73
|
name: string;
|
|
122
74
|
};
|
|
123
75
|
};
|
|
@@ -125,7 +77,7 @@ export declare const plugin: {
|
|
|
125
77
|
export declare const configs: {
|
|
126
78
|
recommended: {
|
|
127
79
|
plugins: {
|
|
128
|
-
|
|
80
|
+
conventions: {
|
|
129
81
|
meta: {
|
|
130
82
|
name: string;
|
|
131
83
|
version: string;
|
|
@@ -158,40 +110,16 @@ export declare const configs: {
|
|
|
158
110
|
'consistent-existence-index-check': TSESLint.RuleModule<"consistentExistenceCheck", [(import("./rules/conventions/consistent-existence-index-check").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
159
111
|
name: string;
|
|
160
112
|
};
|
|
161
|
-
'
|
|
162
|
-
name: string;
|
|
163
|
-
};
|
|
164
|
-
'conventions/expiring-todo-comments': TSESLint.RuleModule<"expiringTodoComment" | "invalidTodoCondition" | "multipleTodoConditions", [(import("./rules/conventions/expiring-todo-comments").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
165
|
-
name: string;
|
|
166
|
-
};
|
|
167
|
-
'conventions/prefer-code-point': TSESLint.RuleModule<"preferCodePoint", [], unknown, TSESLint.RuleListener> & {
|
|
168
|
-
name: string;
|
|
169
|
-
};
|
|
170
|
-
'conventions/prefer-dom-node-text-content': TSESLint.RuleModule<"preferDomNodeTextContent", [], unknown, TSESLint.RuleListener> & {
|
|
171
|
-
name: string;
|
|
172
|
-
};
|
|
173
|
-
'conventions/no-console-spaces': TSESLint.RuleModule<"noConsoleSpaces", [], unknown, TSESLint.RuleListener> & {
|
|
174
|
-
name: string;
|
|
175
|
-
};
|
|
176
|
-
'deprecation/no-deprecated-api': TSESLint.RuleModule<"deprecatedAPI" | "useReplacement", [(import("./rules/deprecation/no-deprecated-api").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
177
|
-
name: string;
|
|
178
|
-
};
|
|
179
|
-
'conventions/prefer-dependency-version-strategy': TSESLint.RuleModule<"preferStrategy" | "invalidStrategy", [(import("./rules/conventions/prefer-dependency-version-strategy").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
180
|
-
name: string;
|
|
181
|
-
};
|
|
182
|
-
'conventions/filename-case': TSESLint.RuleModule<"filenameCase", [(import("./rules/conventions/filename-case").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
183
|
-
name: string;
|
|
184
|
-
};
|
|
185
|
-
'conventions/consistent-existence-index-check': TSESLint.RuleModule<"consistentExistenceCheck", [(import("./rules/conventions/consistent-existence-index-check").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
113
|
+
'no-json-schema-tags': TSESLint.RuleModule<"jsonSchemaTag" | "moveToDescription", [(import("./rules/conventions/no-json-schema-tags").Options | undefined)?], unknown, TSESLint.RuleListener> & {
|
|
186
114
|
name: string;
|
|
187
115
|
};
|
|
188
116
|
};
|
|
189
117
|
};
|
|
190
118
|
};
|
|
191
119
|
rules: {
|
|
192
|
-
'
|
|
193
|
-
'
|
|
194
|
-
'
|
|
120
|
+
'conventions/no-commented-code': "warn";
|
|
121
|
+
'conventions/expiring-todo-comments': "warn";
|
|
122
|
+
'conventions/no-deprecated-api': "warn";
|
|
195
123
|
};
|
|
196
124
|
};
|
|
197
125
|
};
|
package/src/index.js
CHANGED
|
@@ -16,6 +16,7 @@ const no_deprecated_api_1 = require("./rules/deprecation/no-deprecated-api");
|
|
|
16
16
|
const prefer_dependency_version_strategy_1 = require("./rules/conventions/prefer-dependency-version-strategy");
|
|
17
17
|
const filename_case_1 = require("./rules/conventions/filename-case");
|
|
18
18
|
const consistent_existence_index_check_1 = require("./rules/conventions/consistent-existence-index-check");
|
|
19
|
+
const no_json_schema_tags_1 = require("./rules/conventions/no-json-schema-tags");
|
|
19
20
|
exports.rules = {
|
|
20
21
|
'no-commented-code': no_commented_code_1.noCommentedCode,
|
|
21
22
|
'expiring-todo-comments': expiring_todo_comments_1.expiringTodoComments,
|
|
@@ -26,16 +27,7 @@ exports.rules = {
|
|
|
26
27
|
'prefer-dependency-version-strategy': prefer_dependency_version_strategy_1.preferDependencyVersionStrategy,
|
|
27
28
|
'filename-case': filename_case_1.filenameCase,
|
|
28
29
|
'consistent-existence-index-check': consistent_existence_index_check_1.consistentExistenceIndexCheck,
|
|
29
|
-
|
|
30
|
-
'conventions/no-commented-code': no_commented_code_1.noCommentedCode,
|
|
31
|
-
'conventions/expiring-todo-comments': expiring_todo_comments_1.expiringTodoComments,
|
|
32
|
-
'conventions/prefer-code-point': prefer_code_point_1.preferCodePoint,
|
|
33
|
-
'conventions/prefer-dom-node-text-content': prefer_dom_node_text_content_1.preferDomNodeTextContent,
|
|
34
|
-
'conventions/no-console-spaces': no_console_spaces_1.noConsoleSpaces,
|
|
35
|
-
'deprecation/no-deprecated-api': no_deprecated_api_1.noDeprecatedApi,
|
|
36
|
-
'conventions/prefer-dependency-version-strategy': prefer_dependency_version_strategy_1.preferDependencyVersionStrategy,
|
|
37
|
-
'conventions/filename-case': filename_case_1.filenameCase,
|
|
38
|
-
'conventions/consistent-existence-index-check': consistent_existence_index_check_1.consistentExistenceIndexCheck,
|
|
30
|
+
'no-json-schema-tags': no_json_schema_tags_1.noJsonSchemaTags,
|
|
39
31
|
};
|
|
40
32
|
exports.plugin = {
|
|
41
33
|
meta: {
|
|
@@ -47,12 +39,12 @@ exports.plugin = {
|
|
|
47
39
|
exports.configs = {
|
|
48
40
|
recommended: {
|
|
49
41
|
plugins: {
|
|
50
|
-
|
|
42
|
+
conventions: exports.plugin,
|
|
51
43
|
},
|
|
52
44
|
rules: {
|
|
53
|
-
'
|
|
54
|
-
'
|
|
55
|
-
'
|
|
45
|
+
'conventions/no-commented-code': 'warn',
|
|
46
|
+
'conventions/expiring-todo-comments': 'warn',
|
|
47
|
+
'conventions/no-deprecated-api': 'warn',
|
|
56
48
|
},
|
|
57
49
|
},
|
|
58
50
|
};
|
package/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/eslint-plugin-conventions/src/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAIH,oBAAoB;AACpB,6EAAwE;AACxE,uFAAkF;AAClF,6EAAwE;AACxE,mGAA4F;AAC5F,6EAAwE;AACxE,6EAAwE;AACxE,+GAAyG;AACzG,qEAAiE;AACjE,2GAAqG;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/eslint-plugin-conventions/src/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAIH,oBAAoB;AACpB,6EAAwE;AACxE,uFAAkF;AAClF,6EAAwE;AACxE,mGAA4F;AAC5F,6EAAwE;AACxE,6EAAwE;AACxE,+GAAyG;AACzG,qEAAiE;AACjE,2GAAqG;AACrG,iFAA2E;AAE9D,QAAA,KAAK,GAAG;IACnB,mBAAmB,EAAE,mCAAe;IACpC,wBAAwB,EAAE,6CAAoB;IAC9C,mBAAmB,EAAE,mCAAe;IACpC,8BAA8B,EAAE,uDAAwB;IACxD,mBAAmB,EAAE,mCAAe;IACpC,mBAAmB,EAAE,mCAAe;IACpC,oCAAoC,EAAE,oEAA+B;IACrE,eAAe,EAAE,4BAAY;IAC7B,kCAAkC,EAAE,gEAA6B;IACjE,qBAAqB,EAAE,sCAAgB;CACkC,CAAC;AAE/D,QAAA,MAAM,GAAG;IACpB,IAAI,EAAE;QACJ,IAAI,EAAE,2BAA2B;QACjC,OAAO,EAAE,OAAO;KACjB;IACD,KAAK,EAAL,aAAK;CAC+B,CAAC;AAE1B,QAAA,OAAO,GAAG;IACrB,WAAW,EAAE;QACX,OAAO,EAAE;YACP,WAAW,EAAE,cAAM;SACpB;QACD,KAAK,EAAE;YACL,+BAA+B,EAAE,MAAM;YACvC,oCAAoC,EAAE,MAAM;YAC5C,+BAA+B,EAAE,MAAM;SACxC;KACmC;CACc,CAAC;AAEvD,kBAAe,cAAM,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Ofri Peretz
|
|
3
|
+
* Licensed under the MIT License. Use of this source code is governed by the
|
|
4
|
+
* MIT license that can be found in the LICENSE file.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* ESLint Rule: no-json-schema-tags
|
|
8
|
+
* Detects JSON Schema keywords mistakenly used as JSDoc tags.
|
|
9
|
+
*
|
|
10
|
+
* Tags like @minimum, @maximum, @minLength, @maxLength are valid in
|
|
11
|
+
* JSON Schema but have no meaning in JSDoc. When used in JSDoc, they
|
|
12
|
+
* cause CI failures (e.g. DefinitelyTyped dtslint `check-tag-names`).
|
|
13
|
+
*
|
|
14
|
+
* Suggests moving constraint information into description text instead.
|
|
15
|
+
*
|
|
16
|
+
* @see https://json-schema.org/understanding-json-schema/reference
|
|
17
|
+
* @see https://jsdoc.app/about-block-inline-tags
|
|
18
|
+
*/
|
|
19
|
+
import type { TSESLint } from '@interlace/eslint-devkit';
|
|
20
|
+
type MessageIds = 'jsonSchemaTag' | 'moveToDescription';
|
|
21
|
+
export interface Options {
|
|
22
|
+
/** Additional custom tags to forbid. Default: [] */
|
|
23
|
+
additionalForbiddenTags?: string[];
|
|
24
|
+
}
|
|
25
|
+
type RuleOptions = [Options?];
|
|
26
|
+
export declare const noJsonSchemaTags: TSESLint.RuleModule<MessageIds, RuleOptions, unknown, TSESLint.RuleListener> & {
|
|
27
|
+
name: string;
|
|
28
|
+
};
|
|
29
|
+
export {};
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) 2025 Ofri Peretz
|
|
4
|
+
* Licensed under the MIT License. Use of this source code is governed by the
|
|
5
|
+
* MIT license that can be found in the LICENSE file.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.noJsonSchemaTags = void 0;
|
|
9
|
+
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
10
|
+
/**
|
|
11
|
+
* JSON Schema keywords that are commonly misused as JSDoc tags.
|
|
12
|
+
* These have precise semantics in JSON Schema but are invalid
|
|
13
|
+
* (or meaningless) in a JSDoc context.
|
|
14
|
+
*/
|
|
15
|
+
const DEFAULT_FORBIDDEN_TAGS = new Set([
|
|
16
|
+
'minimum',
|
|
17
|
+
'maximum',
|
|
18
|
+
'exclusiveMinimum',
|
|
19
|
+
'exclusiveMaximum',
|
|
20
|
+
'minLength',
|
|
21
|
+
'maxLength',
|
|
22
|
+
'minItems',
|
|
23
|
+
'maxItems',
|
|
24
|
+
'minProperties',
|
|
25
|
+
'maxProperties',
|
|
26
|
+
'multipleOf',
|
|
27
|
+
'pattern',
|
|
28
|
+
'uniqueItems',
|
|
29
|
+
'const',
|
|
30
|
+
'enum',
|
|
31
|
+
'format',
|
|
32
|
+
'contentMediaType',
|
|
33
|
+
'contentEncoding',
|
|
34
|
+
]);
|
|
35
|
+
/**
|
|
36
|
+
* Parse a block comment to find `@tagName` occurrences and their positions.
|
|
37
|
+
*/
|
|
38
|
+
function findForbiddenTags(commentText, forbiddenSet) {
|
|
39
|
+
const results = [];
|
|
40
|
+
// Match @tagName patterns. We don't anchor at line start because block
|
|
41
|
+
// comments can have `* @tag …` or simply `@tag …` on any line.
|
|
42
|
+
const tagRegex = /@([a-zA-Z][a-zA-Z0-9]*)\b/g;
|
|
43
|
+
let match;
|
|
44
|
+
while ((match = tagRegex.exec(commentText)) !== null) {
|
|
45
|
+
const tagName = match[1];
|
|
46
|
+
if (forbiddenSet.has(tagName)) {
|
|
47
|
+
results.push({ tag: tagName, offset: match.index });
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return results;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Build a human-readable suggestion for how to express the constraint
|
|
54
|
+
* in description text instead of a JSON Schema tag.
|
|
55
|
+
*/
|
|
56
|
+
function getSuggestionText(tag) {
|
|
57
|
+
const suggestions = {
|
|
58
|
+
minimum: 'Include range in description, e.g. "(min: 1)" or "Range: 1-100"',
|
|
59
|
+
maximum: 'Include range in description, e.g. "(max: 100)" or "Range: 1-100"',
|
|
60
|
+
exclusiveMinimum: 'Include constraint in description, e.g. "(> 0)"',
|
|
61
|
+
exclusiveMaximum: 'Include constraint in description, e.g. "(< 100)"',
|
|
62
|
+
minLength: 'Include length constraint in description, e.g. "(min length: 1)"',
|
|
63
|
+
maxLength: 'Include length constraint in description, e.g. "(max length: 255)"',
|
|
64
|
+
minItems: 'Include item count in description, e.g. "(at least 1 item)"',
|
|
65
|
+
maxItems: 'Include item count in description, e.g. "(at most 10 items)"',
|
|
66
|
+
pattern: 'Include the expected format in description text',
|
|
67
|
+
enum: 'Use @typedef or list allowed values in description',
|
|
68
|
+
const: 'Use @default instead, or document the fixed value in description',
|
|
69
|
+
format: 'Describe the expected format in description, e.g. "(ISO 8601 date)"',
|
|
70
|
+
};
|
|
71
|
+
return (suggestions[tag] ||
|
|
72
|
+
'Move this constraint information into the description text');
|
|
73
|
+
}
|
|
74
|
+
exports.noJsonSchemaTags = (0, eslint_devkit_1.createRule)({
|
|
75
|
+
name: 'no-json-schema-tags',
|
|
76
|
+
meta: {
|
|
77
|
+
type: 'suggestion',
|
|
78
|
+
docs: {
|
|
79
|
+
description: 'Disallow JSON Schema keywords used as JSDoc tags (e.g. @minimum, @maximum)',
|
|
80
|
+
},
|
|
81
|
+
hasSuggestions: true,
|
|
82
|
+
messages: {
|
|
83
|
+
jsonSchemaTag: (0, eslint_devkit_1.formatLLMMessage)({
|
|
84
|
+
icon: eslint_devkit_1.MessageIcons.WARNING,
|
|
85
|
+
issueName: 'JSON Schema Tag in JSDoc',
|
|
86
|
+
description: '`@{{tag}}` is a JSON Schema keyword, not a valid JSDoc tag. It will cause CI failures in projects with strict tag validation (e.g. DefinitelyTyped). {{suggestion}}',
|
|
87
|
+
severity: 'MEDIUM',
|
|
88
|
+
fix: 'Remove the @{{tag}} tag and express the constraint in the description text instead',
|
|
89
|
+
documentationLink: 'https://jsdoc.app/about-block-inline-tags',
|
|
90
|
+
}),
|
|
91
|
+
moveToDescription: (0, eslint_devkit_1.formatLLMMessage)({
|
|
92
|
+
icon: eslint_devkit_1.MessageIcons.INFO,
|
|
93
|
+
issueName: 'Move to Description Text',
|
|
94
|
+
description: 'Remove the `@{{tag}}` tag and add the constraint directly to the description',
|
|
95
|
+
severity: 'LOW',
|
|
96
|
+
fix: 'Delete the @{{tag}} line and include the information in the type description',
|
|
97
|
+
documentationLink: 'https://jsdoc.app/about-block-inline-tags',
|
|
98
|
+
}),
|
|
99
|
+
},
|
|
100
|
+
schema: [
|
|
101
|
+
{
|
|
102
|
+
type: 'object',
|
|
103
|
+
properties: {
|
|
104
|
+
additionalForbiddenTags: {
|
|
105
|
+
type: 'array',
|
|
106
|
+
items: { type: 'string' },
|
|
107
|
+
default: [],
|
|
108
|
+
description: 'Additional tag names to forbid',
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
additionalProperties: false,
|
|
112
|
+
},
|
|
113
|
+
],
|
|
114
|
+
},
|
|
115
|
+
defaultOptions: [{ additionalForbiddenTags: [] }],
|
|
116
|
+
create(context, [options = {}]) {
|
|
117
|
+
const { additionalForbiddenTags = [] } = options;
|
|
118
|
+
// Build the full set of forbidden tags
|
|
119
|
+
const forbiddenTags = new Set(DEFAULT_FORBIDDEN_TAGS);
|
|
120
|
+
for (const tag of additionalForbiddenTags) {
|
|
121
|
+
forbiddenTags.add(tag);
|
|
122
|
+
}
|
|
123
|
+
const sourceCode = context.sourceCode || context.sourceCode;
|
|
124
|
+
return {
|
|
125
|
+
Program() {
|
|
126
|
+
const comments = sourceCode.getAllComments();
|
|
127
|
+
for (const comment of comments) {
|
|
128
|
+
// Only inspect block comments (JSDoc is always /* … */)
|
|
129
|
+
if (comment.type !== 'Block') {
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
const commentText = comment.value;
|
|
133
|
+
const hits = findForbiddenTags(commentText, forbiddenTags);
|
|
134
|
+
for (const { tag, offset } of hits) {
|
|
135
|
+
// Compute absolute source position.
|
|
136
|
+
// comment.range[0] → opening `/*`, content starts at +2.
|
|
137
|
+
const absoluteStart = comment
|
|
138
|
+
.range[0] +
|
|
139
|
+
2 +
|
|
140
|
+
offset;
|
|
141
|
+
const absoluteEnd = absoluteStart + 1 + tag.length; // `@` + tagName
|
|
142
|
+
const suggestion = getSuggestionText(tag);
|
|
143
|
+
context.report({
|
|
144
|
+
loc: {
|
|
145
|
+
start: sourceCode.getLocFromIndex(absoluteStart),
|
|
146
|
+
end: sourceCode.getLocFromIndex(absoluteEnd),
|
|
147
|
+
},
|
|
148
|
+
messageId: 'jsonSchemaTag',
|
|
149
|
+
data: {
|
|
150
|
+
tag,
|
|
151
|
+
suggestion,
|
|
152
|
+
},
|
|
153
|
+
suggest: [
|
|
154
|
+
{
|
|
155
|
+
messageId: 'moveToDescription',
|
|
156
|
+
data: { tag },
|
|
157
|
+
fix: (fixer) => {
|
|
158
|
+
// Remove the entire @tag and its value (to end of line)
|
|
159
|
+
// Find the line boundaries
|
|
160
|
+
const fullSource = sourceCode.getText();
|
|
161
|
+
let lineStart = absoluteStart;
|
|
162
|
+
while (lineStart > 0 && fullSource[lineStart - 1] !== '\n') {
|
|
163
|
+
lineStart--;
|
|
164
|
+
}
|
|
165
|
+
let lineEnd = absoluteEnd;
|
|
166
|
+
while (lineEnd < fullSource.length &&
|
|
167
|
+
fullSource[lineEnd] !== '\n') {
|
|
168
|
+
lineEnd++;
|
|
169
|
+
}
|
|
170
|
+
// Include the trailing newline if present
|
|
171
|
+
if (lineEnd < fullSource.length && fullSource[lineEnd] === '\n') {
|
|
172
|
+
lineEnd++;
|
|
173
|
+
}
|
|
174
|
+
return fixer.removeRange([lineStart, lineEnd]);
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
],
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
};
|
|
183
|
+
},
|
|
184
|
+
});
|
|
185
|
+
//# sourceMappingURL=no-json-schema-tags.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-json-schema-tags.js","sourceRoot":"","sources":["../../../../../../packages/eslint-plugin-conventions/src/rules/conventions/no-json-schema-tags.ts"],"names":[],"mappings":"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"}
|