@eslint/json 0.11.0 → 0.13.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/esm/index.js CHANGED
@@ -1,3 +1,9 @@
1
+
2
+ /**
3
+ * @import { DocumentNode, AnyNode, Token, MemberNode } from "@humanwhocodes/momoa"
4
+ * @import { SourceLocation, FileProblem, DirectiveType, RulesConfig, Language, OkParseResult, ParseResult, File } from "@eslint/core"
5
+ * @import { JSONSyntaxElement, JSONRuleDefinition } from "./types.ts"
6
+ */
1
7
  // @ts-self-types="./index.d.ts"
2
8
  import { iterator, visitorKeys, parse } from '@humanwhocodes/momoa';
3
9
  import { ConfigCommentParser, TextSourceCodeBase, Directive, VisitNodeStep } from '@eslint/plugin-kit';
@@ -13,19 +19,8 @@ import naturalCompare from 'natural-compare';
13
19
  // Types
14
20
  //-----------------------------------------------------------------------------
15
21
 
16
- /** @typedef {import("@humanwhocodes/momoa").DocumentNode} DocumentNode */
17
- /** @typedef {import("@humanwhocodes/momoa").Node} JSONNode */
18
- /** @typedef {import("@humanwhocodes/momoa").Token} JSONToken */
19
- /** @typedef {import("@eslint/core").SourceRange} SourceRange */
20
- /** @typedef {import("@eslint/core").SourceLocation} SourceLocation */
21
- /** @typedef {import("@eslint/core").File} File */
22
- /** @typedef {import("@eslint/core").TraversalStep} TraversalStep */
23
- /** @typedef {import("@eslint/core").VisitTraversalStep} VisitTraversalStep */
24
- /** @typedef {import("@eslint/core").FileProblem} FileProblem */
25
- /** @typedef {import("@eslint/core").DirectiveType} DirectiveType */
26
- /** @typedef {import("@eslint/core").RulesConfig} RulesConfig */
27
- /** @typedef {import("./types.ts").IJSONSourceCode} IJSONSourceCode */
28
- /** @typedef {import("./types.ts").JSONSyntaxElement} JSONSyntaxElement */
22
+ /**
23
+ */
29
24
 
30
25
  //-----------------------------------------------------------------------------
31
26
  // Helpers
@@ -42,14 +37,14 @@ const INLINE_CONFIG =
42
37
  class JSONTraversalStep extends VisitNodeStep {
43
38
  /**
44
39
  * The target of the step.
45
- * @type {JSONNode}
40
+ * @type {AnyNode}
46
41
  */
47
42
  target = undefined;
48
43
 
49
44
  /**
50
45
  * Creates a new instance.
51
46
  * @param {Object} options The options for the step.
52
- * @param {JSONNode} options.target The target of the step.
47
+ * @param {AnyNode} options.target The target of the step.
53
48
  * @param {1|2} options.phase The phase of the step.
54
49
  * @param {Array<any>} options.args The arguments of the step.
55
50
  */
@@ -60,13 +55,44 @@ class JSONTraversalStep extends VisitNodeStep {
60
55
  }
61
56
  }
62
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
+
63
89
  //-----------------------------------------------------------------------------
64
90
  // Exports
65
91
  //-----------------------------------------------------------------------------
66
92
 
67
93
  /**
68
94
  * JSON Source Code Object
69
- * @implements {IJSONSourceCode}
95
+ * @extends {TextSourceCodeBase<{LangOptions: JSONLanguageOptions, RootNode: DocumentNode, SyntaxElementWithLoc: JSONSyntaxElement, ConfigNode: Token}>}
70
96
  */
71
97
  class JSONSourceCode extends TextSourceCodeBase {
72
98
  /**
@@ -77,13 +103,13 @@ class JSONSourceCode extends TextSourceCodeBase {
77
103
 
78
104
  /**
79
105
  * Cache of parent nodes.
80
- * @type {WeakMap<JSONNode, JSONNode>}
106
+ * @type {WeakMap<AnyNode, AnyNode>}
81
107
  */
82
108
  #parents = new WeakMap();
83
109
 
84
110
  /**
85
111
  * Collection of inline configuration comments.
86
- * @type {Array<JSONToken>}
112
+ * @type {Array<Token>}
87
113
  */
88
114
  #inlineConfigComments;
89
115
 
@@ -94,11 +120,23 @@ class JSONSourceCode extends TextSourceCodeBase {
94
120
  ast = undefined;
95
121
 
96
122
  /**
97
- * The comment node in the source code.
98
- * @type {Array<JSONToken>|undefined}
123
+ * The comment tokens in the source code.
124
+ * @type {Array<Token>|undefined}
99
125
  */
100
126
  comments;
101
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
+
102
140
  /**
103
141
  * Creates a new instance.
104
142
  * @param {Object} options The options for the instance.
@@ -108,14 +146,16 @@ class JSONSourceCode extends TextSourceCodeBase {
108
146
  constructor({ text, ast }) {
109
147
  super({ text, ast });
110
148
  this.ast = ast;
111
- this.comments = ast.tokens
112
- ? ast.tokens.filter(token => token.type.endsWith("Comment"))
113
- : [];
149
+
150
+ const { comments, starts, ends } = processTokens(this.ast.tokens ?? []);
151
+ this.comments = comments;
152
+ this.#tokenStarts = starts;
153
+ this.#tokenEnds = ends;
114
154
  }
115
155
 
116
156
  /**
117
157
  * Returns the value of the given comment.
118
- * @param {JSONToken} comment The comment to get the value of.
158
+ * @param {Token} comment The comment to get the value of.
119
159
  * @returns {string} The value of the comment.
120
160
  * @throws {Error} When an unexpected comment type is passed.
121
161
  */
@@ -134,7 +174,7 @@ class JSONSourceCode extends TextSourceCodeBase {
134
174
  /**
135
175
  * Returns an array of all inline configuration nodes found in the
136
176
  * source code.
137
- * @returns {Array<JSONToken>} An array of all inline configuration nodes.
177
+ * @returns {Array<Token>} An array of all inline configuration nodes.
138
178
  */
139
179
  getInlineConfigNodes() {
140
180
  if (!this.#inlineConfigComments) {
@@ -245,8 +285,8 @@ class JSONSourceCode extends TextSourceCodeBase {
245
285
 
246
286
  /**
247
287
  * Returns the parent of the given node.
248
- * @param {JSONNode} node The node to get the parent of.
249
- * @returns {JSONNode|undefined} The parent of the node.
288
+ * @param {AnyNode} node The node to get the parent of.
289
+ * @returns {AnyNode|undefined} The parent of the node.
250
290
  */
251
291
  getParent(node) {
252
292
  return this.#parents.get(node);
@@ -267,12 +307,15 @@ class JSONSourceCode extends TextSourceCodeBase {
267
307
 
268
308
  for (const { node, parent, phase } of iterator(this.ast)) {
269
309
  if (parent) {
270
- this.#parents.set(node, parent);
310
+ this.#parents.set(
311
+ /** @type {AnyNode} */ (node),
312
+ /** @type {AnyNode} */ (parent),
313
+ );
271
314
  }
272
315
 
273
316
  steps.push(
274
317
  new JSONTraversalStep({
275
- target: node,
318
+ target: /** @type {AnyNode} */ (node),
276
319
  phase: phase === "enter" ? 1 : 2,
277
320
  args: [node, parent],
278
321
  }),
@@ -281,10 +324,89 @@ class JSONSourceCode extends TextSourceCodeBase {
281
324
 
282
325
  return steps;
283
326
  }
327
+
328
+ /**
329
+ * Gets the token before the given node or token, optionally including comments.
330
+ * @param {AnyNode|Token} nodeOrToken The node or token to get the previous token for.
331
+ * @param {Object} [options] Options object.
332
+ * @param {boolean} [options.includeComments] If true, return comments when they are present.
333
+ * @returns {Token|null} The previous token or comment, or null if there is none.
334
+ */
335
+ getTokenBefore(nodeOrToken, { includeComments = false } = {}) {
336
+ const index = this.#tokenStarts.get(nodeOrToken.range[0]);
337
+
338
+ if (index === undefined) {
339
+ return null;
340
+ }
341
+
342
+ let previousIndex = index - 1;
343
+ if (previousIndex < 0) {
344
+ return null;
345
+ }
346
+
347
+ const tokens = this.ast.tokens;
348
+ let tokenOrComment = tokens[previousIndex];
349
+
350
+ if (includeComments) {
351
+ return tokenOrComment;
352
+ }
353
+
354
+ // skip comments
355
+ while (tokenOrComment?.type.endsWith("Comment")) {
356
+ previousIndex--;
357
+
358
+ if (previousIndex < 0) {
359
+ return null;
360
+ }
361
+
362
+ tokenOrComment = tokens[previousIndex];
363
+ }
364
+ return tokenOrComment;
365
+ }
366
+
367
+ /**
368
+ * Gets the token after the given node or token, skipping any comments unless includeComments is true.
369
+ * @param {AnyNode|Token} nodeOrToken The node or token to get the next token for.
370
+ * @param {Object} [options] Options object.
371
+ * @param {boolean} [options.includeComments=false] If true, return comments when they are present.
372
+ * @returns {Token|null} The next token or comment, or null if there is none.
373
+ */
374
+ getTokenAfter(nodeOrToken, { includeComments = false } = {}) {
375
+ const index = this.#tokenEnds.get(nodeOrToken.range[1]);
376
+
377
+ if (index === undefined) {
378
+ return null;
379
+ }
380
+
381
+ let nextIndex = index + 1;
382
+ const tokens = this.ast.tokens;
383
+ if (nextIndex >= tokens.length) {
384
+ return null;
385
+ }
386
+
387
+ let tokenOrComment = tokens[nextIndex];
388
+
389
+ if (includeComments) {
390
+ return tokenOrComment;
391
+ }
392
+
393
+ // skip comments
394
+ while (tokenOrComment?.type.endsWith("Comment")) {
395
+ nextIndex++;
396
+
397
+ if (nextIndex >= tokens.length) {
398
+ return null;
399
+ }
400
+
401
+ tokenOrComment = tokens[nextIndex];
402
+ }
403
+
404
+ return tokenOrComment;
405
+ }
284
406
  }
285
407
 
286
408
  /**
287
- * @filedescription Functions to fix up rules to provide missing methods on the `context` object.
409
+ * @fileoverview The JSONLanguage class.
288
410
  * @author Nicholas C. Zakas
289
411
  */
290
412
 
@@ -293,11 +415,14 @@ class JSONSourceCode extends TextSourceCodeBase {
293
415
  // Types
294
416
  //-----------------------------------------------------------------------------
295
417
 
296
- /** @typedef {import("@eslint/core").Language} Language */
297
- /** @typedef {import("@eslint/core").OkParseResult<DocumentNode>} OkParseResult */
298
- /** @typedef {import("@eslint/core").ParseResult<DocumentNode>} ParseResult */
299
- /** @typedef {import("./types.ts").IJSONLanguage} IJSONLanguage */
300
- /** @typedef {import("./types.ts").JSONLanguageOptions} JSONLanguageOptions */
418
+ /**
419
+ *
420
+ * @typedef {OkParseResult<DocumentNode>} JSONOkParseResult
421
+ * @typedef {ParseResult<DocumentNode>} JSONParseResult
422
+ *
423
+ * @typedef {Object} JSONLanguageOptions
424
+ * @property {boolean} [allowTrailingCommas] Whether to allow trailing commas in JSONC mode.
425
+ */
301
426
 
302
427
  //-----------------------------------------------------------------------------
303
428
  // Exports
@@ -305,7 +430,7 @@ class JSONSourceCode extends TextSourceCodeBase {
305
430
 
306
431
  /**
307
432
  * JSON Language Object
308
- * @implements {IJSONLanguage}
433
+ * @implements {Language<{ LangOptions: JSONLanguageOptions; Code: JSONSourceCode; RootNode: DocumentNode; Node: AnyNode }>}
309
434
  */
310
435
  class JSONLanguage {
311
436
  /**
@@ -382,7 +507,7 @@ class JSONLanguage {
382
507
  * Parses the given file into an AST.
383
508
  * @param {File} file The virtual file to parse.
384
509
  * @param {{languageOptions: JSONLanguageOptions}} context The options to use for parsing.
385
- * @returns {ParseResult} The result of parsing.
510
+ * @returns {JSONParseResult} The result of parsing.
386
511
  */
387
512
  parse(file, context) {
388
513
  // Note: BOM already removed
@@ -430,7 +555,7 @@ class JSONLanguage {
430
555
  /**
431
556
  * Creates a new `JSONSourceCode` object from the given information.
432
557
  * @param {File} file The virtual file to create a `JSONSourceCode` object from.
433
- * @param {OkParseResult} parseResult The result returned from `parse()`.
558
+ * @param {JSONOkParseResult} parseResult The result returned from `parse()`.
434
559
  * @returns {JSONSourceCode} The new `JSONSourceCode` object.
435
560
  */
436
561
  createSourceCode(file, parseResult) {
@@ -442,6 +567,13 @@ class JSONLanguage {
442
567
  /* eslint-enable class-methods-use-this -- Required to complete interface. */
443
568
  }
444
569
 
570
+ const rules$1 = /** @type {const} */ ({
571
+ "json/no-duplicate-keys": "error",
572
+ "json/no-empty-keys": "error",
573
+ "json/no-unnormalized-keys": "error",
574
+ "json/no-unsafe-values": "error"
575
+ });
576
+
445
577
  /**
446
578
  * @fileoverview Rule to prevent duplicate keys in JSON.
447
579
  * @author Nicholas C. Zakas
@@ -451,9 +583,11 @@ class JSONLanguage {
451
583
  // Type Definitions
452
584
  //-----------------------------------------------------------------------------
453
585
 
454
- /** @typedef {"duplicateKey"} NoDuplicateKeysMessageIds */
455
- /** @typedef {import("./types.ts").JSONRuleDefinition<[], NoDuplicateKeysMessageIds>} NoDuplicateKeysRuleDefinition */
456
- /** @typedef {import("@humanwhocodes/momoa").MemberNode} MemberNode */
586
+ /**
587
+ *
588
+ * @typedef {"duplicateKey"} NoDuplicateKeysMessageIds
589
+ * @typedef {JSONRuleDefinition<{ MessageIds: NoDuplicateKeysMessageIds }>} NoDuplicateKeysRuleDefinition
590
+ */
457
591
 
458
592
  //-----------------------------------------------------------------------------
459
593
  // Rule Definition
@@ -465,7 +599,9 @@ const rule$5 = {
465
599
  type: "problem",
466
600
 
467
601
  docs: {
602
+ recommended: true,
468
603
  description: "Disallow duplicate keys in JSON objects",
604
+ url: "https://github.com/eslint/json/tree/main/docs/rules/no-duplicate-keys.md",
469
605
  },
470
606
 
471
607
  messages: {
@@ -520,8 +656,11 @@ const rule$5 = {
520
656
  // Type Definitions
521
657
  //-----------------------------------------------------------------------------
522
658
 
523
- /** @typedef {"emptyKey"} NoEmptyKeysMessageIds */
524
- /** @typedef {import("./types.ts").JSONRuleDefinition<[], NoEmptyKeysMessageIds>} NoEmptyKeysRuleDefinition */
659
+ /**
660
+ *
661
+ * @typedef {"emptyKey"} NoEmptyKeysMessageIds
662
+ * @typedef {JSONRuleDefinition<{ MessageIds: NoEmptyKeysMessageIds }>} NoEmptyKeysRuleDefinition
663
+ */
525
664
 
526
665
  //-----------------------------------------------------------------------------
527
666
  // Rule Definition
@@ -533,7 +672,9 @@ const rule$4 = {
533
672
  type: "problem",
534
673
 
535
674
  docs: {
675
+ recommended: true,
536
676
  description: "Disallow empty keys in JSON objects",
677
+ url: "https://github.com/eslint/json/tree/main/docs/rules/no-empty-keys.md",
537
678
  },
538
679
 
539
680
  messages: {
@@ -560,6 +701,80 @@ const rule$4 = {
560
701
  },
561
702
  };
562
703
 
704
+ /**
705
+ * @fileoverview Rule to detect unnormalized keys in JSON.
706
+ * @author Bradley Meck Farias
707
+ */
708
+
709
+ //-----------------------------------------------------------------------------
710
+ // Type Definitions
711
+ //-----------------------------------------------------------------------------
712
+
713
+ /**
714
+ *
715
+ * @typedef {"unnormalizedKey"} NoUnnormalizedKeysMessageIds
716
+ * @typedef {{ form: string }} NoUnnormalizedKeysOptions
717
+ * @typedef {JSONRuleDefinition<{ RuleOptions: [NoUnnormalizedKeysOptions], MessageIds: NoUnnormalizedKeysMessageIds }>} NoUnnormalizedKeysRuleDefinition
718
+ */
719
+
720
+ //-----------------------------------------------------------------------------
721
+ // Rule Definition
722
+ //-----------------------------------------------------------------------------
723
+
724
+ /** @type {NoUnnormalizedKeysRuleDefinition} */
725
+ const rule$3 = {
726
+ meta: {
727
+ type: "problem",
728
+
729
+ docs: {
730
+ recommended: true,
731
+ description: "Disallow JSON keys that are not normalized",
732
+ url: "https://github.com/eslint/json/tree/main/docs/rules/no-unnormalized-keys.md",
733
+ },
734
+
735
+ messages: {
736
+ unnormalizedKey: "Unnormalized key '{{key}}' found.",
737
+ },
738
+
739
+ schema: [
740
+ {
741
+ type: "object",
742
+ properties: {
743
+ form: {
744
+ enum: ["NFC", "NFD", "NFKC", "NFKD"],
745
+ },
746
+ },
747
+ additionalProperties: false,
748
+ },
749
+ ],
750
+ },
751
+
752
+ create(context) {
753
+ const form = context.options.length
754
+ ? context.options[0].form
755
+ : undefined;
756
+
757
+ return {
758
+ Member(node) {
759
+ const key =
760
+ node.name.type === "String"
761
+ ? node.name.value
762
+ : node.name.name;
763
+
764
+ if (key.normalize(form) !== key) {
765
+ context.report({
766
+ loc: node.name.loc,
767
+ messageId: "unnormalizedKey",
768
+ data: {
769
+ key,
770
+ },
771
+ });
772
+ }
773
+ },
774
+ };
775
+ },
776
+ };
777
+
563
778
  /**
564
779
  * @fileoverview Rule to detect unsafe values in JSON.
565
780
  * @author Bradley Meck Farias
@@ -569,8 +784,11 @@ const rule$4 = {
569
784
  // Type Definitions
570
785
  //-----------------------------------------------------------------------------
571
786
 
572
- /** @typedef {"unsafeNumber"|"unsafeInteger"|"unsafeZero"|"subnormal"|"loneSurrogate"} NoUnsafeValuesMessageIds */
573
- /** @typedef {import("./types.ts").JSONRuleDefinition<[], NoUnsafeValuesMessageIds>} NoUnsafeValuesRuleDefinition */
787
+ /**
788
+ *
789
+ * @typedef {"unsafeNumber"|"unsafeInteger"|"unsafeZero"|"subnormal"|"loneSurrogate"} NoUnsafeValuesMessageIds
790
+ * @typedef {JSONRuleDefinition<{ MessageIds: NoUnsafeValuesMessageIds }>} NoUnsafeValuesRuleDefinition
791
+ */
574
792
 
575
793
  //-----------------------------------------------------------------------------
576
794
  // Helpers
@@ -592,12 +810,14 @@ const NON_ZERO = /[1-9]/u;
592
810
  //-----------------------------------------------------------------------------
593
811
 
594
812
  /** @type {NoUnsafeValuesRuleDefinition} */
595
- const rule$3 = {
813
+ const rule$2 = {
596
814
  meta: {
597
815
  type: "problem",
598
816
 
599
817
  docs: {
818
+ recommended: true,
600
819
  description: "Disallow JSON values that are unsafe for interchange",
820
+ url: "https://github.com/eslint/json/tree/main/docs/rules/no-unsafe-values.md",
601
821
  },
602
822
 
603
823
  messages: {
@@ -708,74 +928,6 @@ const rule$3 = {
708
928
  },
709
929
  };
710
930
 
711
- /**
712
- * @fileoverview Rule to detect unnormalized keys in JSON.
713
- * @author Bradley Meck Farias
714
- */
715
-
716
- //-----------------------------------------------------------------------------
717
- // Type Definitions
718
- //-----------------------------------------------------------------------------
719
-
720
- /** @typedef {"unnormalizedKey"} NoUnnormalizedKeysMessageIds */
721
- /** @typedef {import("./types.ts").JSONRuleDefinition<[{form:string}], NoUnnormalizedKeysMessageIds>} NoUnnormalizedKeysRuleDefinition */
722
-
723
- //-----------------------------------------------------------------------------
724
- // Rule Definition
725
- //-----------------------------------------------------------------------------
726
-
727
- /** @type {NoUnnormalizedKeysRuleDefinition} */
728
- const rule$2 = {
729
- meta: {
730
- type: "problem",
731
-
732
- docs: {
733
- description: "Disallow JSON keys that are not normalized",
734
- },
735
-
736
- messages: {
737
- unnormalizedKey: "Unnormalized key '{{key}}' found.",
738
- },
739
-
740
- schema: [
741
- {
742
- type: "object",
743
- properties: {
744
- form: {
745
- enum: ["NFC", "NFD", "NFKC", "NFKD"],
746
- },
747
- },
748
- additionalProperties: false,
749
- },
750
- ],
751
- },
752
-
753
- create(context) {
754
- const form = context.options.length
755
- ? context.options[0].form
756
- : undefined;
757
-
758
- return {
759
- Member(node) {
760
- const key =
761
- node.name.type === "String"
762
- ? node.name.value
763
- : node.name.name;
764
-
765
- if (key.normalize(form) !== key) {
766
- context.report({
767
- loc: node.name.loc,
768
- messageId: "unnormalizedKey",
769
- data: {
770
- key,
771
- },
772
- });
773
- }
774
- },
775
- };
776
- },
777
- };
778
-
779
931
  /**
780
932
  * @fileoverview Rule to require JSON object keys to be sorted.
781
933
  * Copied largely from https://github.com/eslint/eslint/blob/main/lib/rules/sort-keys.js
@@ -787,21 +939,21 @@ const rule$2 = {
787
939
  // Type Definitions
788
940
  //-----------------------------------------------------------------------------
789
941
 
790
- /** @typedef {"sortKeys"} SortKeysMessageIds */
791
-
792
942
  /**
943
+ *
793
944
  * @typedef {Object} SortOptions
794
945
  * @property {boolean} caseSensitive
795
946
  * @property {boolean} natural
796
947
  * @property {number} minKeys
797
948
  * @property {boolean} allowLineSeparatedGroups
949
+ *
950
+ * @typedef {"sortKeys"} SortKeysMessageIds
951
+ * @typedef {"asc"|"desc"} SortDirection
952
+ * @typedef {[SortDirection, SortOptions]} SortKeysRuleOptions
953
+ * @typedef {JSONRuleDefinition<{ RuleOptions: SortKeysRuleOptions, MessageIds: SortKeysMessageIds }>} SortKeysRuleDefinition
954
+ * @typedef {(a:string,b:string) => boolean} Comparator
798
955
  */
799
956
 
800
- /** @typedef {"asc"|"desc"} SortDirection */
801
- /** @typedef {[SortDirection, SortOptions]} SortKeysRuleOptions */
802
- /** @typedef {import("./types.ts").JSONRuleDefinition<SortKeysRuleOptions, SortKeysMessageIds>} SortKeysRuleDefinition */
803
- /** @typedef {(a:string,b:string) => boolean} Comparator */
804
-
805
957
  //-----------------------------------------------------------------------------
806
958
  // Helpers
807
959
  //-----------------------------------------------------------------------------
@@ -878,7 +1030,9 @@ const rule$1 = {
878
1030
  ],
879
1031
 
880
1032
  docs: {
1033
+ recommended: false,
881
1034
  description: `Require JSON object keys to be sorted`,
1035
+ url: "https://github.com/eslint/json/tree/main/docs/rules/sort-keys.md",
882
1036
  },
883
1037
 
884
1038
  messages: {
@@ -1007,7 +1161,7 @@ const rule$1 = {
1007
1161
  };
1008
1162
 
1009
1163
  /**
1010
- * @fileoverview Rule to ensure top-level items are either an array or ojbect.
1164
+ * @fileoverview Rule to ensure top-level items are either an array or object.
1011
1165
  * @author Joe Hildebrand
1012
1166
  */
1013
1167
 
@@ -1015,8 +1169,11 @@ const rule$1 = {
1015
1169
  // Type Definitions
1016
1170
  //-----------------------------------------------------------------------------
1017
1171
 
1018
- /** @typedef {"topLevel"} TopLevelInteropMessageIds */
1019
- /** @typedef {import("./types.ts").JSONRuleDefinition<[], TopLevelInteropMessageIds>} TopLevelInteropRuleDefinition */
1172
+ /**
1173
+ *
1174
+ * @typedef {"topLevel"} TopLevelInteropMessageIds
1175
+ * @typedef {JSONRuleDefinition<{ MessageIds: TopLevelInteropMessageIds }>} TopLevelInteropRuleDefinition
1176
+ */
1020
1177
 
1021
1178
  //-----------------------------------------------------------------------------
1022
1179
  // Rule Definition
@@ -1028,8 +1185,10 @@ const rule = {
1028
1185
  type: "problem",
1029
1186
 
1030
1187
  docs: {
1188
+ recommended: false,
1031
1189
  description:
1032
1190
  "Require the JSON top-level value to be an array or object",
1191
+ url: "https://github.com/eslint/json/tree/main/docs/rules/top-level-interop.md",
1033
1192
  },
1034
1193
 
1035
1194
  messages: {
@@ -1054,6 +1213,15 @@ const rule = {
1054
1213
  },
1055
1214
  };
1056
1215
 
1216
+ var rules = {
1217
+ "no-duplicate-keys": rule$5,
1218
+ "no-empty-keys": rule$4,
1219
+ "no-unnormalized-keys": rule$3,
1220
+ "no-unsafe-values": rule$2,
1221
+ "sort-keys": rule$1,
1222
+ "top-level-interop": rule,
1223
+ };
1224
+
1057
1225
  /**
1058
1226
  * @fileoverview JSON plugin.
1059
1227
  * @author Nicholas C. Zakas
@@ -1067,30 +1235,18 @@ const rule = {
1067
1235
  const plugin = {
1068
1236
  meta: {
1069
1237
  name: "@eslint/json",
1070
- version: "0.11.0", // x-release-please-version
1238
+ version: "0.13.0", // x-release-please-version
1071
1239
  },
1072
1240
  languages: {
1073
1241
  json: new JSONLanguage({ mode: "json" }),
1074
1242
  jsonc: new JSONLanguage({ mode: "jsonc" }),
1075
1243
  json5: new JSONLanguage({ mode: "json5" }),
1076
1244
  },
1077
- rules: {
1078
- "no-duplicate-keys": rule$5,
1079
- "no-empty-keys": rule$4,
1080
- "no-unsafe-values": rule$3,
1081
- "no-unnormalized-keys": rule$2,
1082
- "sort-keys": rule$1,
1083
- "top-level-interop": rule,
1084
- },
1245
+ rules,
1085
1246
  configs: {
1086
1247
  recommended: {
1087
1248
  plugins: {},
1088
- rules: /** @type {const} */ ({
1089
- "json/no-duplicate-keys": "error",
1090
- "json/no-empty-keys": "error",
1091
- "json/no-unsafe-values": "error",
1092
- "json/no-unnormalized-keys": "error",
1093
- }),
1249
+ rules: rules$1,
1094
1250
  },
1095
1251
  },
1096
1252
  };