@eslint/json 0.12.0 → 0.13.1
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 +70 -33
- package/dist/cjs/index.cjs +251 -104
- package/dist/cjs/index.d.cts +62 -41
- package/dist/cjs/types.cts +9 -14
- package/dist/esm/index.d.ts +62 -41
- package/dist/esm/index.js +251 -104
- package/dist/esm/types.d.ts +4 -8
- package/dist/esm/types.ts +9 -14
- package/package.json +23 -12
package/dist/esm/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
|
|
2
2
|
/**
|
|
3
|
-
* @import { DocumentNode,
|
|
4
|
-
* @import { SourceLocation, FileProblem, DirectiveType, RulesConfig,
|
|
3
|
+
* @import { DocumentNode, AnyNode, Token, MemberNode } from "@humanwhocodes/momoa"
|
|
4
|
+
* @import { SourceLocation, FileProblem, DirectiveType, RulesConfig, Language, OkParseResult, ParseResult, File } from "@eslint/core"
|
|
5
5
|
* @import { JSONSyntaxElement, JSONRuleDefinition } from "./types.ts"
|
|
6
6
|
*/
|
|
7
7
|
// @ts-self-types="./index.d.ts"
|
|
@@ -37,14 +37,14 @@ const INLINE_CONFIG =
|
|
|
37
37
|
class JSONTraversalStep extends VisitNodeStep {
|
|
38
38
|
/**
|
|
39
39
|
* The target of the step.
|
|
40
|
-
* @type {
|
|
40
|
+
* @type {AnyNode}
|
|
41
41
|
*/
|
|
42
42
|
target = undefined;
|
|
43
43
|
|
|
44
44
|
/**
|
|
45
45
|
* Creates a new instance.
|
|
46
46
|
* @param {Object} options The options for the step.
|
|
47
|
-
* @param {
|
|
47
|
+
* @param {AnyNode} options.target The target of the step.
|
|
48
48
|
* @param {1|2} options.phase The phase of the step.
|
|
49
49
|
* @param {Array<any>} options.args The arguments of the step.
|
|
50
50
|
*/
|
|
@@ -55,13 +55,44 @@ class JSONTraversalStep extends VisitNodeStep {
|
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
/**
|
|
59
|
+
* Processes tokens to extract comments and their starting tokens.
|
|
60
|
+
* @param {Array<Token>} tokens The tokens to process.
|
|
61
|
+
* @returns {{ comments: Array<Token>, starts: Map<number, number>, ends: Map<number, number>}}
|
|
62
|
+
* An object containing an array of comments, a map of starting token range to token index, and
|
|
63
|
+
* a map of ending token range to token index.
|
|
64
|
+
*/
|
|
65
|
+
function processTokens(tokens) {
|
|
66
|
+
/** @type {Array<Token>} */
|
|
67
|
+
const comments = [];
|
|
68
|
+
|
|
69
|
+
/** @type {Map<number, number>} */
|
|
70
|
+
const starts = new Map();
|
|
71
|
+
|
|
72
|
+
/** @type {Map<number, number>} */
|
|
73
|
+
const ends = new Map();
|
|
74
|
+
|
|
75
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
76
|
+
const token = tokens[i];
|
|
77
|
+
|
|
78
|
+
if (token.type.endsWith("Comment")) {
|
|
79
|
+
comments.push(token);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
starts.set(token.range[0], i);
|
|
83
|
+
ends.set(token.range[1], i);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return { comments, starts, ends };
|
|
87
|
+
}
|
|
88
|
+
|
|
58
89
|
//-----------------------------------------------------------------------------
|
|
59
90
|
// Exports
|
|
60
91
|
//-----------------------------------------------------------------------------
|
|
61
92
|
|
|
62
93
|
/**
|
|
63
94
|
* JSON Source Code Object
|
|
64
|
-
* @
|
|
95
|
+
* @extends {TextSourceCodeBase<{LangOptions: JSONLanguageOptions, RootNode: DocumentNode, SyntaxElementWithLoc: JSONSyntaxElement, ConfigNode: Token}>}
|
|
65
96
|
*/
|
|
66
97
|
class JSONSourceCode extends TextSourceCodeBase {
|
|
67
98
|
/**
|
|
@@ -72,7 +103,7 @@ class JSONSourceCode extends TextSourceCodeBase {
|
|
|
72
103
|
|
|
73
104
|
/**
|
|
74
105
|
* Cache of parent nodes.
|
|
75
|
-
* @type {WeakMap<
|
|
106
|
+
* @type {WeakMap<AnyNode, AnyNode>}
|
|
76
107
|
*/
|
|
77
108
|
#parents = new WeakMap();
|
|
78
109
|
|
|
@@ -89,11 +120,23 @@ class JSONSourceCode extends TextSourceCodeBase {
|
|
|
89
120
|
ast = undefined;
|
|
90
121
|
|
|
91
122
|
/**
|
|
92
|
-
* The comment
|
|
123
|
+
* The comment tokens in the source code.
|
|
93
124
|
* @type {Array<Token>|undefined}
|
|
94
125
|
*/
|
|
95
126
|
comments;
|
|
96
127
|
|
|
128
|
+
/**
|
|
129
|
+
* A map of token start positions to their corresponding index.
|
|
130
|
+
* @type {Map<number, number>}
|
|
131
|
+
*/
|
|
132
|
+
#tokenStarts;
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* A map of token end positions to their corresponding index.
|
|
136
|
+
* @type {Map<number, number>}
|
|
137
|
+
*/
|
|
138
|
+
#tokenEnds;
|
|
139
|
+
|
|
97
140
|
/**
|
|
98
141
|
* Creates a new instance.
|
|
99
142
|
* @param {Object} options The options for the instance.
|
|
@@ -103,9 +146,11 @@ class JSONSourceCode extends TextSourceCodeBase {
|
|
|
103
146
|
constructor({ text, ast }) {
|
|
104
147
|
super({ text, ast });
|
|
105
148
|
this.ast = ast;
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
149
|
+
|
|
150
|
+
const { comments, starts, ends } = processTokens(this.ast.tokens ?? []);
|
|
151
|
+
this.comments = comments;
|
|
152
|
+
this.#tokenStarts = starts;
|
|
153
|
+
this.#tokenEnds = ends;
|
|
109
154
|
}
|
|
110
155
|
|
|
111
156
|
/**
|
|
@@ -148,7 +193,9 @@ class JSONSourceCode extends TextSourceCodeBase {
|
|
|
148
193
|
* that ESLint needs to further process the directives.
|
|
149
194
|
*/
|
|
150
195
|
getDisableDirectives() {
|
|
196
|
+
/** @type {Array<FileProblem>} */
|
|
151
197
|
const problems = [];
|
|
198
|
+
/** @type {Array<Directive>} */
|
|
152
199
|
const directives = [];
|
|
153
200
|
|
|
154
201
|
this.getInlineConfigNodes().forEach(comment => {
|
|
@@ -201,7 +248,9 @@ class JSONSourceCode extends TextSourceCodeBase {
|
|
|
201
248
|
* that ESLint needs to further process the rule configurations.
|
|
202
249
|
*/
|
|
203
250
|
applyInlineConfig() {
|
|
251
|
+
/** @type {Array<FileProblem>} */
|
|
204
252
|
const problems = [];
|
|
253
|
+
/** @type {Array<{config:{rules:RulesConfig},loc:SourceLocation}>} */
|
|
205
254
|
const configs = [];
|
|
206
255
|
|
|
207
256
|
this.getInlineConfigNodes().forEach(comment => {
|
|
@@ -240,8 +289,8 @@ class JSONSourceCode extends TextSourceCodeBase {
|
|
|
240
289
|
|
|
241
290
|
/**
|
|
242
291
|
* Returns the parent of the given node.
|
|
243
|
-
* @param {
|
|
244
|
-
* @returns {
|
|
292
|
+
* @param {AnyNode} node The node to get the parent of.
|
|
293
|
+
* @returns {AnyNode|undefined} The parent of the node.
|
|
245
294
|
*/
|
|
246
295
|
getParent(node) {
|
|
247
296
|
return this.#parents.get(node);
|
|
@@ -262,12 +311,15 @@ class JSONSourceCode extends TextSourceCodeBase {
|
|
|
262
311
|
|
|
263
312
|
for (const { node, parent, phase } of iterator(this.ast)) {
|
|
264
313
|
if (parent) {
|
|
265
|
-
this.#parents.set(
|
|
314
|
+
this.#parents.set(
|
|
315
|
+
/** @type {AnyNode} */ (node),
|
|
316
|
+
/** @type {AnyNode} */ (parent),
|
|
317
|
+
);
|
|
266
318
|
}
|
|
267
319
|
|
|
268
320
|
steps.push(
|
|
269
321
|
new JSONTraversalStep({
|
|
270
|
-
target: node,
|
|
322
|
+
target: /** @type {AnyNode} */ (node),
|
|
271
323
|
phase: phase === "enter" ? 1 : 2,
|
|
272
324
|
args: [node, parent],
|
|
273
325
|
}),
|
|
@@ -276,10 +328,89 @@ class JSONSourceCode extends TextSourceCodeBase {
|
|
|
276
328
|
|
|
277
329
|
return steps;
|
|
278
330
|
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Gets the token before the given node or token, optionally including comments.
|
|
334
|
+
* @param {AnyNode|Token} nodeOrToken The node or token to get the previous token for.
|
|
335
|
+
* @param {Object} [options] Options object.
|
|
336
|
+
* @param {boolean} [options.includeComments] If true, return comments when they are present.
|
|
337
|
+
* @returns {Token|null} The previous token or comment, or null if there is none.
|
|
338
|
+
*/
|
|
339
|
+
getTokenBefore(nodeOrToken, { includeComments = false } = {}) {
|
|
340
|
+
const index = this.#tokenStarts.get(nodeOrToken.range[0]);
|
|
341
|
+
|
|
342
|
+
if (index === undefined) {
|
|
343
|
+
return null;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
let previousIndex = index - 1;
|
|
347
|
+
if (previousIndex < 0) {
|
|
348
|
+
return null;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
const tokens = this.ast.tokens;
|
|
352
|
+
let tokenOrComment = tokens[previousIndex];
|
|
353
|
+
|
|
354
|
+
if (includeComments) {
|
|
355
|
+
return tokenOrComment;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// skip comments
|
|
359
|
+
while (tokenOrComment?.type.endsWith("Comment")) {
|
|
360
|
+
previousIndex--;
|
|
361
|
+
|
|
362
|
+
if (previousIndex < 0) {
|
|
363
|
+
return null;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
tokenOrComment = tokens[previousIndex];
|
|
367
|
+
}
|
|
368
|
+
return tokenOrComment;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* Gets the token after the given node or token, skipping any comments unless includeComments is true.
|
|
373
|
+
* @param {AnyNode|Token} nodeOrToken The node or token to get the next token for.
|
|
374
|
+
* @param {Object} [options] Options object.
|
|
375
|
+
* @param {boolean} [options.includeComments=false] If true, return comments when they are present.
|
|
376
|
+
* @returns {Token|null} The next token or comment, or null if there is none.
|
|
377
|
+
*/
|
|
378
|
+
getTokenAfter(nodeOrToken, { includeComments = false } = {}) {
|
|
379
|
+
const index = this.#tokenEnds.get(nodeOrToken.range[1]);
|
|
380
|
+
|
|
381
|
+
if (index === undefined) {
|
|
382
|
+
return null;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
let nextIndex = index + 1;
|
|
386
|
+
const tokens = this.ast.tokens;
|
|
387
|
+
if (nextIndex >= tokens.length) {
|
|
388
|
+
return null;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
let tokenOrComment = tokens[nextIndex];
|
|
392
|
+
|
|
393
|
+
if (includeComments) {
|
|
394
|
+
return tokenOrComment;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// skip comments
|
|
398
|
+
while (tokenOrComment?.type.endsWith("Comment")) {
|
|
399
|
+
nextIndex++;
|
|
400
|
+
|
|
401
|
+
if (nextIndex >= tokens.length) {
|
|
402
|
+
return null;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
tokenOrComment = tokens[nextIndex];
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
return tokenOrComment;
|
|
409
|
+
}
|
|
279
410
|
}
|
|
280
411
|
|
|
281
412
|
/**
|
|
282
|
-
* @
|
|
413
|
+
* @fileoverview The JSONLanguage class.
|
|
283
414
|
* @author Nicholas C. Zakas
|
|
284
415
|
*/
|
|
285
416
|
|
|
@@ -440,6 +571,13 @@ class JSONLanguage {
|
|
|
440
571
|
/* eslint-enable class-methods-use-this -- Required to complete interface. */
|
|
441
572
|
}
|
|
442
573
|
|
|
574
|
+
const rules$1 = /** @type {const} */ ({
|
|
575
|
+
"json/no-duplicate-keys": "error",
|
|
576
|
+
"json/no-empty-keys": "error",
|
|
577
|
+
"json/no-unnormalized-keys": "error",
|
|
578
|
+
"json/no-unsafe-values": "error"
|
|
579
|
+
});
|
|
580
|
+
|
|
443
581
|
/**
|
|
444
582
|
* @fileoverview Rule to prevent duplicate keys in JSON.
|
|
445
583
|
* @author Nicholas C. Zakas
|
|
@@ -465,7 +603,9 @@ const rule$5 = {
|
|
|
465
603
|
type: "problem",
|
|
466
604
|
|
|
467
605
|
docs: {
|
|
606
|
+
recommended: true,
|
|
468
607
|
description: "Disallow duplicate keys in JSON objects",
|
|
608
|
+
url: "https://github.com/eslint/json/tree/main/docs/rules/no-duplicate-keys.md",
|
|
469
609
|
},
|
|
470
610
|
|
|
471
611
|
messages: {
|
|
@@ -536,7 +676,9 @@ const rule$4 = {
|
|
|
536
676
|
type: "problem",
|
|
537
677
|
|
|
538
678
|
docs: {
|
|
679
|
+
recommended: true,
|
|
539
680
|
description: "Disallow empty keys in JSON objects",
|
|
681
|
+
url: "https://github.com/eslint/json/tree/main/docs/rules/no-empty-keys.md",
|
|
540
682
|
},
|
|
541
683
|
|
|
542
684
|
messages: {
|
|
@@ -563,6 +705,80 @@ const rule$4 = {
|
|
|
563
705
|
},
|
|
564
706
|
};
|
|
565
707
|
|
|
708
|
+
/**
|
|
709
|
+
* @fileoverview Rule to detect unnormalized keys in JSON.
|
|
710
|
+
* @author Bradley Meck Farias
|
|
711
|
+
*/
|
|
712
|
+
|
|
713
|
+
//-----------------------------------------------------------------------------
|
|
714
|
+
// Type Definitions
|
|
715
|
+
//-----------------------------------------------------------------------------
|
|
716
|
+
|
|
717
|
+
/**
|
|
718
|
+
*
|
|
719
|
+
* @typedef {"unnormalizedKey"} NoUnnormalizedKeysMessageIds
|
|
720
|
+
* @typedef {{ form: string }} NoUnnormalizedKeysOptions
|
|
721
|
+
* @typedef {JSONRuleDefinition<{ RuleOptions: [NoUnnormalizedKeysOptions], MessageIds: NoUnnormalizedKeysMessageIds }>} NoUnnormalizedKeysRuleDefinition
|
|
722
|
+
*/
|
|
723
|
+
|
|
724
|
+
//-----------------------------------------------------------------------------
|
|
725
|
+
// Rule Definition
|
|
726
|
+
//-----------------------------------------------------------------------------
|
|
727
|
+
|
|
728
|
+
/** @type {NoUnnormalizedKeysRuleDefinition} */
|
|
729
|
+
const rule$3 = {
|
|
730
|
+
meta: {
|
|
731
|
+
type: "problem",
|
|
732
|
+
|
|
733
|
+
docs: {
|
|
734
|
+
recommended: true,
|
|
735
|
+
description: "Disallow JSON keys that are not normalized",
|
|
736
|
+
url: "https://github.com/eslint/json/tree/main/docs/rules/no-unnormalized-keys.md",
|
|
737
|
+
},
|
|
738
|
+
|
|
739
|
+
messages: {
|
|
740
|
+
unnormalizedKey: "Unnormalized key '{{key}}' found.",
|
|
741
|
+
},
|
|
742
|
+
|
|
743
|
+
schema: [
|
|
744
|
+
{
|
|
745
|
+
type: "object",
|
|
746
|
+
properties: {
|
|
747
|
+
form: {
|
|
748
|
+
enum: ["NFC", "NFD", "NFKC", "NFKD"],
|
|
749
|
+
},
|
|
750
|
+
},
|
|
751
|
+
additionalProperties: false,
|
|
752
|
+
},
|
|
753
|
+
],
|
|
754
|
+
},
|
|
755
|
+
|
|
756
|
+
create(context) {
|
|
757
|
+
const form = context.options.length
|
|
758
|
+
? context.options[0].form
|
|
759
|
+
: undefined;
|
|
760
|
+
|
|
761
|
+
return {
|
|
762
|
+
Member(node) {
|
|
763
|
+
const key =
|
|
764
|
+
node.name.type === "String"
|
|
765
|
+
? node.name.value
|
|
766
|
+
: node.name.name;
|
|
767
|
+
|
|
768
|
+
if (key.normalize(form) !== key) {
|
|
769
|
+
context.report({
|
|
770
|
+
loc: node.name.loc,
|
|
771
|
+
messageId: "unnormalizedKey",
|
|
772
|
+
data: {
|
|
773
|
+
key,
|
|
774
|
+
},
|
|
775
|
+
});
|
|
776
|
+
}
|
|
777
|
+
},
|
|
778
|
+
};
|
|
779
|
+
},
|
|
780
|
+
};
|
|
781
|
+
|
|
566
782
|
/**
|
|
567
783
|
* @fileoverview Rule to detect unsafe values in JSON.
|
|
568
784
|
* @author Bradley Meck Farias
|
|
@@ -598,12 +814,14 @@ const NON_ZERO = /[1-9]/u;
|
|
|
598
814
|
//-----------------------------------------------------------------------------
|
|
599
815
|
|
|
600
816
|
/** @type {NoUnsafeValuesRuleDefinition} */
|
|
601
|
-
const rule$
|
|
817
|
+
const rule$2 = {
|
|
602
818
|
meta: {
|
|
603
819
|
type: "problem",
|
|
604
820
|
|
|
605
821
|
docs: {
|
|
822
|
+
recommended: true,
|
|
606
823
|
description: "Disallow JSON values that are unsafe for interchange",
|
|
824
|
+
url: "https://github.com/eslint/json/tree/main/docs/rules/no-unsafe-values.md",
|
|
607
825
|
},
|
|
608
826
|
|
|
609
827
|
messages: {
|
|
@@ -714,78 +932,6 @@ const rule$3 = {
|
|
|
714
932
|
},
|
|
715
933
|
};
|
|
716
934
|
|
|
717
|
-
/**
|
|
718
|
-
* @fileoverview Rule to detect unnormalized keys in JSON.
|
|
719
|
-
* @author Bradley Meck Farias
|
|
720
|
-
*/
|
|
721
|
-
|
|
722
|
-
//-----------------------------------------------------------------------------
|
|
723
|
-
// Type Definitions
|
|
724
|
-
//-----------------------------------------------------------------------------
|
|
725
|
-
|
|
726
|
-
/**
|
|
727
|
-
*
|
|
728
|
-
* @typedef {"unnormalizedKey"} NoUnnormalizedKeysMessageIds
|
|
729
|
-
* @typedef {{ form: string }} NoUnnormalizedKeysOptions
|
|
730
|
-
* @typedef {JSONRuleDefinition<{ RuleOptions: [NoUnnormalizedKeysOptions], MessageIds: NoUnnormalizedKeysMessageIds }>} NoUnnormalizedKeysRuleDefinition
|
|
731
|
-
*/
|
|
732
|
-
|
|
733
|
-
//-----------------------------------------------------------------------------
|
|
734
|
-
// Rule Definition
|
|
735
|
-
//-----------------------------------------------------------------------------
|
|
736
|
-
|
|
737
|
-
/** @type {NoUnnormalizedKeysRuleDefinition} */
|
|
738
|
-
const rule$2 = {
|
|
739
|
-
meta: {
|
|
740
|
-
type: "problem",
|
|
741
|
-
|
|
742
|
-
docs: {
|
|
743
|
-
description: "Disallow JSON keys that are not normalized",
|
|
744
|
-
},
|
|
745
|
-
|
|
746
|
-
messages: {
|
|
747
|
-
unnormalizedKey: "Unnormalized key '{{key}}' found.",
|
|
748
|
-
},
|
|
749
|
-
|
|
750
|
-
schema: [
|
|
751
|
-
{
|
|
752
|
-
type: "object",
|
|
753
|
-
properties: {
|
|
754
|
-
form: {
|
|
755
|
-
enum: ["NFC", "NFD", "NFKC", "NFKD"],
|
|
756
|
-
},
|
|
757
|
-
},
|
|
758
|
-
additionalProperties: false,
|
|
759
|
-
},
|
|
760
|
-
],
|
|
761
|
-
},
|
|
762
|
-
|
|
763
|
-
create(context) {
|
|
764
|
-
const form = context.options.length
|
|
765
|
-
? context.options[0].form
|
|
766
|
-
: undefined;
|
|
767
|
-
|
|
768
|
-
return {
|
|
769
|
-
Member(node) {
|
|
770
|
-
const key =
|
|
771
|
-
node.name.type === "String"
|
|
772
|
-
? node.name.value
|
|
773
|
-
: node.name.name;
|
|
774
|
-
|
|
775
|
-
if (key.normalize(form) !== key) {
|
|
776
|
-
context.report({
|
|
777
|
-
loc: node.name.loc,
|
|
778
|
-
messageId: "unnormalizedKey",
|
|
779
|
-
data: {
|
|
780
|
-
key,
|
|
781
|
-
},
|
|
782
|
-
});
|
|
783
|
-
}
|
|
784
|
-
},
|
|
785
|
-
};
|
|
786
|
-
},
|
|
787
|
-
};
|
|
788
|
-
|
|
789
935
|
/**
|
|
790
936
|
* @fileoverview Rule to require JSON object keys to be sorted.
|
|
791
937
|
* Copied largely from https://github.com/eslint/eslint/blob/main/lib/rules/sort-keys.js
|
|
@@ -888,7 +1034,9 @@ const rule$1 = {
|
|
|
888
1034
|
],
|
|
889
1035
|
|
|
890
1036
|
docs: {
|
|
1037
|
+
recommended: false,
|
|
891
1038
|
description: `Require JSON object keys to be sorted`,
|
|
1039
|
+
url: "https://github.com/eslint/json/tree/main/docs/rules/sort-keys.md",
|
|
892
1040
|
},
|
|
893
1041
|
|
|
894
1042
|
messages: {
|
|
@@ -1017,7 +1165,7 @@ const rule$1 = {
|
|
|
1017
1165
|
};
|
|
1018
1166
|
|
|
1019
1167
|
/**
|
|
1020
|
-
* @fileoverview Rule to ensure top-level items are either an array or
|
|
1168
|
+
* @fileoverview Rule to ensure top-level items are either an array or object.
|
|
1021
1169
|
* @author Joe Hildebrand
|
|
1022
1170
|
*/
|
|
1023
1171
|
|
|
@@ -1041,8 +1189,10 @@ const rule = {
|
|
|
1041
1189
|
type: "problem",
|
|
1042
1190
|
|
|
1043
1191
|
docs: {
|
|
1192
|
+
recommended: false,
|
|
1044
1193
|
description:
|
|
1045
1194
|
"Require the JSON top-level value to be an array or object",
|
|
1195
|
+
url: "https://github.com/eslint/json/tree/main/docs/rules/top-level-interop.md",
|
|
1046
1196
|
},
|
|
1047
1197
|
|
|
1048
1198
|
messages: {
|
|
@@ -1067,6 +1217,15 @@ const rule = {
|
|
|
1067
1217
|
},
|
|
1068
1218
|
};
|
|
1069
1219
|
|
|
1220
|
+
var rules = {
|
|
1221
|
+
"no-duplicate-keys": rule$5,
|
|
1222
|
+
"no-empty-keys": rule$4,
|
|
1223
|
+
"no-unnormalized-keys": rule$3,
|
|
1224
|
+
"no-unsafe-values": rule$2,
|
|
1225
|
+
"sort-keys": rule$1,
|
|
1226
|
+
"top-level-interop": rule,
|
|
1227
|
+
};
|
|
1228
|
+
|
|
1070
1229
|
/**
|
|
1071
1230
|
* @fileoverview JSON plugin.
|
|
1072
1231
|
* @author Nicholas C. Zakas
|
|
@@ -1080,30 +1239,18 @@ const rule = {
|
|
|
1080
1239
|
const plugin = {
|
|
1081
1240
|
meta: {
|
|
1082
1241
|
name: "@eslint/json",
|
|
1083
|
-
version: "0.
|
|
1242
|
+
version: "0.13.1", // x-release-please-version
|
|
1084
1243
|
},
|
|
1085
1244
|
languages: {
|
|
1086
1245
|
json: new JSONLanguage({ mode: "json" }),
|
|
1087
1246
|
jsonc: new JSONLanguage({ mode: "jsonc" }),
|
|
1088
1247
|
json5: new JSONLanguage({ mode: "json5" }),
|
|
1089
1248
|
},
|
|
1090
|
-
rules
|
|
1091
|
-
"no-duplicate-keys": rule$5,
|
|
1092
|
-
"no-empty-keys": rule$4,
|
|
1093
|
-
"no-unsafe-values": rule$3,
|
|
1094
|
-
"no-unnormalized-keys": rule$2,
|
|
1095
|
-
"sort-keys": rule$1,
|
|
1096
|
-
"top-level-interop": rule,
|
|
1097
|
-
},
|
|
1249
|
+
rules,
|
|
1098
1250
|
configs: {
|
|
1099
1251
|
recommended: {
|
|
1100
1252
|
plugins: {},
|
|
1101
|
-
rules:
|
|
1102
|
-
"json/no-duplicate-keys": "error",
|
|
1103
|
-
"json/no-empty-keys": "error",
|
|
1104
|
-
"json/no-unsafe-values": "error",
|
|
1105
|
-
"json/no-unnormalized-keys": "error",
|
|
1106
|
-
}),
|
|
1253
|
+
rules: rules$1,
|
|
1107
1254
|
},
|
|
1108
1255
|
},
|
|
1109
1256
|
};
|
package/dist/esm/types.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @fileoverview Additional types for this package.
|
|
3
3
|
* @author Nicholas C. Zakas
|
|
4
4
|
*/
|
|
5
|
-
import type {
|
|
5
|
+
import type { CustomRuleDefinitionType, CustomRuleTypeDefinitions, RuleVisitor } from "@eslint/core";
|
|
6
6
|
import type { DocumentNode, MemberNode, ElementNode, ObjectNode, ArrayNode, StringNode, NullNode, NumberNode, BooleanNode, NaNNode, InfinityNode, IdentifierNode, AnyNode, Token } from "@humanwhocodes/momoa";
|
|
7
7
|
import type { JSONLanguageOptions, JSONSourceCode } from "./index.js";
|
|
8
8
|
type ValueNodeParent = DocumentNode | MemberNode | ElementNode;
|
|
@@ -39,15 +39,11 @@ export interface JSONRuleVisitor extends RuleVisitor {
|
|
|
39
39
|
"Infinity:exit"?(node: InfinityNode, parent?: ValueNodeParent): void;
|
|
40
40
|
"Identifier:exit"?(node: IdentifierNode, parent?: ValueNodeParent): void;
|
|
41
41
|
}
|
|
42
|
-
export type JSONRuleDefinitionTypeOptions =
|
|
43
|
-
|
|
44
|
-
MessageIds: string;
|
|
45
|
-
ExtRuleDocs: Record<string, unknown>;
|
|
46
|
-
};
|
|
47
|
-
export type JSONRuleDefinition<Options extends Partial<JSONRuleDefinitionTypeOptions> = {}> = RuleDefinition<{
|
|
42
|
+
export type JSONRuleDefinitionTypeOptions = CustomRuleTypeDefinitions;
|
|
43
|
+
export type JSONRuleDefinition<Options extends Partial<JSONRuleDefinitionTypeOptions> = {}> = CustomRuleDefinitionType<{
|
|
48
44
|
LangOptions: JSONLanguageOptions;
|
|
49
45
|
Code: JSONSourceCode;
|
|
50
46
|
Visitor: JSONRuleVisitor;
|
|
51
47
|
Node: AnyNode;
|
|
52
|
-
}
|
|
48
|
+
}, Options>;
|
|
53
49
|
export {};
|
package/dist/esm/types.ts
CHANGED
|
@@ -7,7 +7,11 @@
|
|
|
7
7
|
// Imports
|
|
8
8
|
//------------------------------------------------------------------------------
|
|
9
9
|
|
|
10
|
-
import type {
|
|
10
|
+
import type {
|
|
11
|
+
CustomRuleDefinitionType,
|
|
12
|
+
CustomRuleTypeDefinitions,
|
|
13
|
+
RuleVisitor,
|
|
14
|
+
} from "@eslint/core";
|
|
11
15
|
import type {
|
|
12
16
|
DocumentNode,
|
|
13
17
|
MemberNode,
|
|
@@ -68,25 +72,16 @@ export interface JSONRuleVisitor extends RuleVisitor {
|
|
|
68
72
|
"Identifier:exit"?(node: IdentifierNode, parent?: ValueNodeParent): void;
|
|
69
73
|
}
|
|
70
74
|
|
|
71
|
-
export type JSONRuleDefinitionTypeOptions =
|
|
72
|
-
RuleOptions: unknown[];
|
|
73
|
-
MessageIds: string;
|
|
74
|
-
ExtRuleDocs: Record<string, unknown>;
|
|
75
|
-
};
|
|
75
|
+
export type JSONRuleDefinitionTypeOptions = CustomRuleTypeDefinitions;
|
|
76
76
|
|
|
77
77
|
export type JSONRuleDefinition<
|
|
78
78
|
Options extends Partial<JSONRuleDefinitionTypeOptions> = {},
|
|
79
|
-
> =
|
|
80
|
-
// Language specific type options (non-configurable)
|
|
79
|
+
> = CustomRuleDefinitionType<
|
|
81
80
|
{
|
|
82
81
|
LangOptions: JSONLanguageOptions;
|
|
83
82
|
Code: JSONSourceCode;
|
|
84
83
|
Visitor: JSONRuleVisitor;
|
|
85
84
|
Node: AnyNode;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
Options &
|
|
89
|
-
// Rule specific type options (defaults)
|
|
90
|
-
Omit<JSONRuleDefinitionTypeOptions, keyof Options>
|
|
91
|
-
>
|
|
85
|
+
},
|
|
86
|
+
Options
|
|
92
87
|
>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eslint/json",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.1",
|
|
4
4
|
"description": "JSON linting plugin for ESLint",
|
|
5
5
|
"author": "Nicholas C. Zakas",
|
|
6
6
|
"type": "module",
|
|
@@ -40,7 +40,14 @@
|
|
|
40
40
|
"eslint --fix",
|
|
41
41
|
"prettier --write"
|
|
42
42
|
],
|
|
43
|
-
"!(*.js)": "prettier --write --ignore-unknown"
|
|
43
|
+
"!(*.js)": "prettier --write --ignore-unknown",
|
|
44
|
+
"README.md": [
|
|
45
|
+
"npm run build:update-rules-docs"
|
|
46
|
+
],
|
|
47
|
+
"{src/rules/*.js,tools/update-rules-docs.js}": [
|
|
48
|
+
"npm run build:update-rules-docs",
|
|
49
|
+
"git add README.md"
|
|
50
|
+
]
|
|
44
51
|
},
|
|
45
52
|
"repository": {
|
|
46
53
|
"type": "git",
|
|
@@ -53,14 +60,17 @@
|
|
|
53
60
|
"scripts": {
|
|
54
61
|
"build:dedupe-types": "node tools/dedupe-types.js dist/cjs/index.cjs dist/esm/index.js",
|
|
55
62
|
"build:cts": "node tools/build-cts.js",
|
|
56
|
-
"build": "
|
|
63
|
+
"build:rules": "node tools/build-rules.js",
|
|
64
|
+
"build": "npm run build:rules && rollup -c && npm run build:dedupe-types && tsc -p tsconfig.esm.json && npm run build:cts",
|
|
57
65
|
"build:readme": "node tools/update-readme.js",
|
|
58
|
-
"
|
|
66
|
+
"build:update-rules-docs": "node tools/update-rules-docs.js",
|
|
67
|
+
"prepare": "npm run build",
|
|
59
68
|
"pretest": "npm run build",
|
|
60
69
|
"lint": "eslint",
|
|
61
70
|
"fmt": "prettier --write .",
|
|
62
71
|
"fmt:check": "prettier --check .",
|
|
63
72
|
"test": "mocha tests/**/*.js",
|
|
73
|
+
"test:jsr": "npx jsr@latest publish --dry-run",
|
|
64
74
|
"test:coverage": "c8 npm test",
|
|
65
75
|
"test:types": "tsc -p tests/types/tsconfig.json"
|
|
66
76
|
},
|
|
@@ -73,25 +83,26 @@
|
|
|
73
83
|
],
|
|
74
84
|
"license": "Apache-2.0",
|
|
75
85
|
"dependencies": {
|
|
76
|
-
"@eslint/core": "^0.
|
|
77
|
-
"@eslint/plugin-kit": "^0.
|
|
78
|
-
"@humanwhocodes/momoa": "^3.3.
|
|
86
|
+
"@eslint/core": "^0.15.1",
|
|
87
|
+
"@eslint/plugin-kit": "^0.3.4",
|
|
88
|
+
"@humanwhocodes/momoa": "^3.3.8",
|
|
79
89
|
"natural-compare": "^1.4.0"
|
|
80
90
|
},
|
|
81
91
|
"devDependencies": {
|
|
82
|
-
"c8": "^
|
|
92
|
+
"c8": "^10.1.3",
|
|
83
93
|
"dedent": "^1.5.3",
|
|
84
|
-
"eslint": "^9.
|
|
94
|
+
"eslint": "^9.31.0",
|
|
85
95
|
"eslint-config-eslint": "^11.0.0",
|
|
86
96
|
"eslint-plugin-eslint-plugin": "^6.3.2",
|
|
87
97
|
"got": "^14.4.2",
|
|
88
98
|
"lint-staged": "^15.2.7",
|
|
89
|
-
"
|
|
99
|
+
"mdast-util-from-markdown": "^2.0.2",
|
|
100
|
+
"mocha": "^11.3.0",
|
|
90
101
|
"prettier": "^3.4.1",
|
|
91
|
-
"rollup": "^4.
|
|
102
|
+
"rollup": "^4.41.0",
|
|
92
103
|
"rollup-plugin-copy": "^3.5.0",
|
|
93
104
|
"rollup-plugin-delete": "^3.0.1",
|
|
94
|
-
"typescript": "^5.
|
|
105
|
+
"typescript": "^5.8.3",
|
|
95
106
|
"yorkie": "^2.0.0"
|
|
96
107
|
},
|
|
97
108
|
"engines": {
|