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