@eslint/json 0.10.0 → 0.12.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/README.md CHANGED
@@ -254,11 +254,12 @@ Apache 2.0
254
254
  The following companies, organizations, and individuals support ESLint's ongoing maintenance and development. [Become a Sponsor](https://eslint.org/donate)
255
255
  to get your logo on our READMEs and [website](https://eslint.org/sponsors).
256
256
 
257
- <h3>Platinum Sponsors</h3>
257
+ <h3>Diamond Sponsors</h3>
258
+ <p><a href="https://www.ag-grid.com/"><img src="https://images.opencollective.com/ag-grid/2c8d545/logo.png" alt="AG Grid" height="128"></a></p><h3>Platinum Sponsors</h3>
258
259
  <p><a href="https://automattic.com"><img src="https://images.opencollective.com/automattic/d0ef3e1/logo.png" alt="Automattic" height="128"></a> <a href="https://www.airbnb.com/"><img src="https://images.opencollective.com/airbnb/d327d66/logo.png" alt="Airbnb" height="128"></a></p><h3>Gold Sponsors</h3>
259
- <p><a href="https://trunk.io/"><img src="https://images.opencollective.com/trunkio/fb92d60/avatar.png" alt="trunk.io" height="96"></a></p><h3>Silver Sponsors</h3>
260
- <p><a href="https://www.serptriumph.com/"><img src="https://images.opencollective.com/serp-triumph5/fea3074/logo.png" alt="SERP Triumph" height="64"></a> <a href="https://www.jetbrains.com/"><img src="https://images.opencollective.com/jetbrains/fe76f99/logo.png" alt="JetBrains" height="64"></a> <a href="https://liftoff.io/"><img src="https://images.opencollective.com/liftoff/5c4fa84/logo.png" alt="Liftoff" height="64"></a> <a href="https://americanexpress.io"><img src="https://avatars.githubusercontent.com/u/3853301" alt="American Express" height="64"></a></p><h3>Bronze Sponsors</h3>
261
- <p><a href="https://cybozu.co.jp/"><img src="https://images.opencollective.com/cybozu/933e46d/logo.png" alt="Cybozu" height="32"></a> <a href="https://www.crosswordsolver.org/anagram-solver/"><img src="https://images.opencollective.com/anagram-solver/2666271/logo.png" alt="Anagram Solver" height="32"></a> <a href="https://icons8.com/"><img src="https://images.opencollective.com/icons8/7fa1641/logo.png" alt="Icons8" height="32"></a> <a href="https://discord.com"><img src="https://images.opencollective.com/discordapp/f9645d9/logo.png" alt="Discord" height="32"></a> <a href="https://www.gitbook.com"><img src="https://avatars.githubusercontent.com/u/7111340" alt="GitBook" height="32"></a> <a href="https://nolebase.ayaka.io"><img src="https://avatars.githubusercontent.com/u/11081491" alt="Neko" height="32"></a> <a href="https://nx.dev"><img src="https://avatars.githubusercontent.com/u/23692104" alt="Nx" height="32"></a> <a href="https://opensource.mercedes-benz.com/"><img src="https://avatars.githubusercontent.com/u/34240465" alt="Mercedes-Benz Group" height="32"></a> <a href="https://herocoders.com"><img src="https://avatars.githubusercontent.com/u/37549774" alt="HeroCoders" height="32"></a></p>
260
+ <p><a href="https://qlty.sh/"><img src="https://images.opencollective.com/qltysh/33d157d/logo.png" alt="Qlty Software" height="96"></a> <a href="https://trunk.io/"><img src="https://images.opencollective.com/trunkio/fb92d60/avatar.png" alt="trunk.io" height="96"></a> <a href="https://shopify.engineering/"><img src="https://avatars.githubusercontent.com/u/8085" alt="Shopify" height="96"></a></p><h3>Silver Sponsors</h3>
261
+ <p><a href="https://vite.dev/"><img src="https://images.opencollective.com/vite/e6d15e1/logo.png" alt="Vite" height="64"></a> <a href="https://liftoff.io/"><img src="https://images.opencollective.com/liftoff/5c4fa84/logo.png" alt="Liftoff" height="64"></a> <a href="https://americanexpress.io"><img src="https://avatars.githubusercontent.com/u/3853301" alt="American Express" height="64"></a> <a href="https://stackblitz.com"><img src="https://avatars.githubusercontent.com/u/28635252" alt="StackBlitz" height="64"></a></p><h3>Bronze Sponsors</h3>
262
+ <p><a href="https://cybozu.co.jp/"><img src="https://images.opencollective.com/cybozu/933e46d/logo.png" alt="Cybozu" height="32"></a> <a href="https://www.crosswordsolver.org/anagram-solver/"><img src="https://images.opencollective.com/anagram-solver/2666271/logo.png" alt="Anagram Solver" height="32"></a> <a href="https://icons8.com/"><img src="https://images.opencollective.com/icons8/7fa1641/logo.png" alt="Icons8" height="32"></a> <a href="https://discord.com"><img src="https://images.opencollective.com/discordapp/f9645d9/logo.png" alt="Discord" height="32"></a> <a href="https://www.gitbook.com"><img src="https://avatars.githubusercontent.com/u/7111340" alt="GitBook" height="32"></a> <a href="https://nolebase.ayaka.io"><img src="https://avatars.githubusercontent.com/u/11081491" alt="Neko" height="32"></a> <a href="https://nx.dev"><img src="https://avatars.githubusercontent.com/u/23692104" alt="Nx" height="32"></a> <a href="https://opensource.mercedes-benz.com/"><img src="https://avatars.githubusercontent.com/u/34240465" alt="Mercedes-Benz Group" height="32"></a> <a href="https://herocoders.com"><img src="https://avatars.githubusercontent.com/u/37549774" alt="HeroCoders" height="32"></a> <a href="https://www.lambdatest.com"><img src="https://avatars.githubusercontent.com/u/171592363" alt="LambdaTest" height="32"></a></p>
262
263
  <h3>Technology Sponsors</h3>
263
264
  Technology sponsors allow us to use their products and services for free as part of a contribution to the open source ecosystem and our work.
264
265
  <p><a href="https://netlify.com"><img src="https://raw.githubusercontent.com/eslint/eslint.org/main/src/assets/images/techsponsors/netlify-icon.svg" alt="Netlify" height="32"></a> <a href="https://algolia.com"><img src="https://raw.githubusercontent.com/eslint/eslint.org/main/src/assets/images/techsponsors/algolia-icon.svg" alt="Algolia" height="32"></a> <a href="https://1password.com"><img src="https://raw.githubusercontent.com/eslint/eslint.org/main/src/assets/images/techsponsors/1password-icon.svg" alt="1Password" height="32"></a></p>
@@ -1,3 +1,9 @@
1
+
2
+ /**
3
+ * @import { DocumentNode, Node, Token, AnyNode, MemberNode } from "@humanwhocodes/momoa"
4
+ * @import { SourceLocation, FileProblem, DirectiveType, RulesConfig, TextSourceCode, 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,18 +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").TextSourceCode} TextSourceCode */
27
- /** @typedef {import("@eslint/core").VisitTraversalStep} VisitTraversalStep */
28
- /** @typedef {import("@eslint/core").FileProblem} FileProblem */
29
- /** @typedef {import("@eslint/core").DirectiveType} DirectiveType */
30
- /** @typedef {import("@eslint/core").RulesConfig} RulesConfig */
25
+ /**
26
+ */
31
27
 
32
28
  //-----------------------------------------------------------------------------
33
29
  // Helpers
@@ -44,14 +40,14 @@ const INLINE_CONFIG =
44
40
  class JSONTraversalStep extends pluginKit.VisitNodeStep {
45
41
  /**
46
42
  * The target of the step.
47
- * @type {JSONNode}
43
+ * @type {Node}
48
44
  */
49
45
  target = undefined;
50
46
 
51
47
  /**
52
48
  * Creates a new instance.
53
49
  * @param {Object} options The options for the step.
54
- * @param {JSONNode} options.target The target of the step.
50
+ * @param {Node} options.target The target of the step.
55
51
  * @param {1|2} options.phase The phase of the step.
56
52
  * @param {Array<any>} options.args The arguments of the step.
57
53
  */
@@ -68,6 +64,7 @@ class JSONTraversalStep extends pluginKit.VisitNodeStep {
68
64
 
69
65
  /**
70
66
  * JSON Source Code Object
67
+ * @implements {TextSourceCode<{LangOptions: JSONLanguageOptions, RootNode: DocumentNode, SyntaxElementWithLoc: JSONSyntaxElement, ConfigNode: Token}>}
71
68
  */
72
69
  class JSONSourceCode extends pluginKit.TextSourceCodeBase {
73
70
  /**
@@ -78,13 +75,13 @@ class JSONSourceCode extends pluginKit.TextSourceCodeBase {
78
75
 
79
76
  /**
80
77
  * Cache of parent nodes.
81
- * @type {WeakMap<JSONNode, JSONNode>}
78
+ * @type {WeakMap<Node, Node>}
82
79
  */
83
80
  #parents = new WeakMap();
84
81
 
85
82
  /**
86
83
  * Collection of inline configuration comments.
87
- * @type {Array<JSONToken>}
84
+ * @type {Array<Token>}
88
85
  */
89
86
  #inlineConfigComments;
90
87
 
@@ -96,7 +93,7 @@ class JSONSourceCode extends pluginKit.TextSourceCodeBase {
96
93
 
97
94
  /**
98
95
  * The comment node in the source code.
99
- * @type {Array<JSONToken>|undefined}
96
+ * @type {Array<Token>|undefined}
100
97
  */
101
98
  comments;
102
99
 
@@ -116,7 +113,7 @@ class JSONSourceCode extends pluginKit.TextSourceCodeBase {
116
113
 
117
114
  /**
118
115
  * Returns the value of the given comment.
119
- * @param {JSONToken} comment The comment to get the value of.
116
+ * @param {Token} comment The comment to get the value of.
120
117
  * @returns {string} The value of the comment.
121
118
  * @throws {Error} When an unexpected comment type is passed.
122
119
  */
@@ -135,7 +132,7 @@ class JSONSourceCode extends pluginKit.TextSourceCodeBase {
135
132
  /**
136
133
  * Returns an array of all inline configuration nodes found in the
137
134
  * source code.
138
- * @returns {Array<JSONToken>} An array of all inline configuration nodes.
135
+ * @returns {Array<Token>} An array of all inline configuration nodes.
139
136
  */
140
137
  getInlineConfigNodes() {
141
138
  if (!this.#inlineConfigComments) {
@@ -144,7 +141,7 @@ class JSONSourceCode extends pluginKit.TextSourceCodeBase {
144
141
  );
145
142
  }
146
143
 
147
- return this.#inlineConfigComments;
144
+ return this.#inlineConfigComments ?? [];
148
145
  }
149
146
 
150
147
  /**
@@ -246,8 +243,8 @@ class JSONSourceCode extends pluginKit.TextSourceCodeBase {
246
243
 
247
244
  /**
248
245
  * Returns the parent of the given node.
249
- * @param {JSONNode} node The node to get the parent of.
250
- * @returns {JSONNode|undefined} The parent of the node.
246
+ * @param {Node} node The node to get the parent of.
247
+ * @returns {Node|undefined} The parent of the node.
251
248
  */
252
249
  getParent(node) {
253
250
  return this.#parents.get(node);
@@ -294,12 +291,13 @@ class JSONSourceCode extends pluginKit.TextSourceCodeBase {
294
291
  // Types
295
292
  //-----------------------------------------------------------------------------
296
293
 
297
- /** @typedef {import("@eslint/core").Language} Language */
298
- /** @typedef {import("@eslint/core").OkParseResult<DocumentNode>} OkParseResult */
299
- /** @typedef {import("@eslint/core").ParseResult<DocumentNode>} ParseResult */
300
294
  /**
295
+ *
296
+ * @typedef {OkParseResult<DocumentNode>} JSONOkParseResult
297
+ * @typedef {ParseResult<DocumentNode>} JSONParseResult
298
+ *
301
299
  * @typedef {Object} JSONLanguageOptions
302
- * @property {boolean} [allowTrailingCommas] Whether to allow trailing commas.
300
+ * @property {boolean} [allowTrailingCommas] Whether to allow trailing commas in JSONC mode.
303
301
  */
304
302
 
305
303
  //-----------------------------------------------------------------------------
@@ -308,7 +306,7 @@ class JSONSourceCode extends pluginKit.TextSourceCodeBase {
308
306
 
309
307
  /**
310
308
  * JSON Language Object
311
- * @implements {Language}
309
+ * @implements {Language<{ LangOptions: JSONLanguageOptions; Code: JSONSourceCode; RootNode: DocumentNode; Node: AnyNode }>}
312
310
  */
313
311
  class JSONLanguage {
314
312
  /**
@@ -385,7 +383,7 @@ class JSONLanguage {
385
383
  * Parses the given file into an AST.
386
384
  * @param {File} file The virtual file to parse.
387
385
  * @param {{languageOptions: JSONLanguageOptions}} context The options to use for parsing.
388
- * @returns {ParseResult} The result of parsing.
386
+ * @returns {JSONParseResult} The result of parsing.
389
387
  */
390
388
  parse(file, context) {
391
389
  // Note: BOM already removed
@@ -433,7 +431,7 @@ class JSONLanguage {
433
431
  /**
434
432
  * Creates a new `JSONSourceCode` object from the given information.
435
433
  * @param {File} file The virtual file to create a `JSONSourceCode` object from.
436
- * @param {OkParseResult} parseResult The result returned from `parse()`.
434
+ * @param {JSONOkParseResult} parseResult The result returned from `parse()`.
437
435
  * @returns {JSONSourceCode} The new `JSONSourceCode` object.
438
436
  */
439
437
  createSourceCode(file, parseResult) {
@@ -450,13 +448,24 @@ class JSONLanguage {
450
448
  * @author Nicholas C. Zakas
451
449
  */
452
450
 
451
+ //-----------------------------------------------------------------------------
452
+ // Type Definitions
453
+ //-----------------------------------------------------------------------------
454
+
455
+ /**
456
+ *
457
+ * @typedef {"duplicateKey"} NoDuplicateKeysMessageIds
458
+ * @typedef {JSONRuleDefinition<{ MessageIds: NoDuplicateKeysMessageIds }>} NoDuplicateKeysRuleDefinition
459
+ */
460
+
453
461
  //-----------------------------------------------------------------------------
454
462
  // Rule Definition
455
463
  //-----------------------------------------------------------------------------
456
464
 
457
- var noDuplicateKeys = {
465
+ /** @type {NoDuplicateKeysRuleDefinition} */
466
+ const rule$5 = {
458
467
  meta: {
459
- type: /** @type {const} */ ("problem"),
468
+ type: "problem",
460
469
 
461
470
  docs: {
462
471
  description: "Disallow duplicate keys in JSON objects",
@@ -468,7 +477,10 @@ var noDuplicateKeys = {
468
477
  },
469
478
 
470
479
  create(context) {
480
+ /** @type {Array<Map<string, MemberNode>|undefined>} */
471
481
  const objectKeys = [];
482
+
483
+ /** @type {Map<string, MemberNode>|undefined} */
472
484
  let keys;
473
485
 
474
486
  return {
@@ -507,9 +519,24 @@ var noDuplicateKeys = {
507
519
  * @author Nicholas C. Zakas
508
520
  */
509
521
 
510
- var noEmptyKeys = {
522
+ //-----------------------------------------------------------------------------
523
+ // Type Definitions
524
+ //-----------------------------------------------------------------------------
525
+
526
+ /**
527
+ *
528
+ * @typedef {"emptyKey"} NoEmptyKeysMessageIds
529
+ * @typedef {JSONRuleDefinition<{ MessageIds: NoEmptyKeysMessageIds }>} NoEmptyKeysRuleDefinition
530
+ */
531
+
532
+ //-----------------------------------------------------------------------------
533
+ // Rule Definition
534
+ //-----------------------------------------------------------------------------
535
+
536
+ /** @type {NoEmptyKeysRuleDefinition} */
537
+ const rule$4 = {
511
538
  meta: {
512
- type: /** @type {const} */ ("problem"),
539
+ type: "problem",
513
540
 
514
541
  docs: {
515
542
  description: "Disallow empty keys in JSON objects",
@@ -544,15 +571,39 @@ var noEmptyKeys = {
544
571
  * @author Bradley Meck Farias
545
572
  */
546
573
 
547
- // RFC 8259's `number` production, as a regex. Capture the integer part
548
- // and the fractional part.
574
+ //-----------------------------------------------------------------------------
575
+ // Type Definitions
576
+ //-----------------------------------------------------------------------------
577
+
578
+ /**
579
+ *
580
+ * @typedef {"unsafeNumber"|"unsafeInteger"|"unsafeZero"|"subnormal"|"loneSurrogate"} NoUnsafeValuesMessageIds
581
+ * @typedef {JSONRuleDefinition<{ MessageIds: NoUnsafeValuesMessageIds }>} NoUnsafeValuesRuleDefinition
582
+ */
583
+
584
+ //-----------------------------------------------------------------------------
585
+ // Helpers
586
+ //-----------------------------------------------------------------------------
587
+
588
+ /*
589
+ * This rule is based on the JSON grammar from RFC 8259, section 6.
590
+ * https://tools.ietf.org/html/rfc8259#section-6
591
+ *
592
+ * We separately capture the integer and fractional parts of a number, so that
593
+ * we can check for unsafe numbers that will evaluate to Infinity.
594
+ */
549
595
  const NUMBER =
550
596
  /^-?(?<int>0|([1-9][0-9]*))(?:\.(?<frac>[0-9]+))?(?:[eE][+-]?[0-9]+)?$/u;
551
597
  const NON_ZERO = /[1-9]/u;
552
598
 
553
- var noUnsafeValues = {
599
+ //-----------------------------------------------------------------------------
600
+ // Rule Definition
601
+ //-----------------------------------------------------------------------------
602
+
603
+ /** @type {NoUnsafeValuesRuleDefinition} */
604
+ const rule$3 = {
554
605
  meta: {
555
- type: /** @type {const} */ ("problem"),
606
+ type: "problem",
556
607
 
557
608
  docs: {
558
609
  description: "Disallow JSON values that are unsafe for interchange",
@@ -626,7 +677,9 @@ var noUnsafeValues = {
626
677
  loc: node.loc,
627
678
  messageId: "subnormal",
628
679
  // Value included so that it's seen in scientific notation
629
- data: node,
680
+ data: {
681
+ value,
682
+ },
630
683
  });
631
684
  }
632
685
  }
@@ -669,9 +722,25 @@ var noUnsafeValues = {
669
722
  * @author Bradley Meck Farias
670
723
  */
671
724
 
672
- var noUnnormalizedKeys = {
725
+ //-----------------------------------------------------------------------------
726
+ // Type Definitions
727
+ //-----------------------------------------------------------------------------
728
+
729
+ /**
730
+ *
731
+ * @typedef {"unnormalizedKey"} NoUnnormalizedKeysMessageIds
732
+ * @typedef {{ form: string }} NoUnnormalizedKeysOptions
733
+ * @typedef {JSONRuleDefinition<{ RuleOptions: [NoUnnormalizedKeysOptions], MessageIds: NoUnnormalizedKeysMessageIds }>} NoUnnormalizedKeysRuleDefinition
734
+ */
735
+
736
+ //-----------------------------------------------------------------------------
737
+ // Rule Definition
738
+ //-----------------------------------------------------------------------------
739
+
740
+ /** @type {NoUnnormalizedKeysRuleDefinition} */
741
+ const rule$2 = {
673
742
  meta: {
674
- type: /** @type {const} */ ("problem"),
743
+ type: "problem",
675
744
 
676
745
  docs: {
677
746
  description: "Disallow JSON keys that are not normalized",
@@ -695,9 +764,10 @@ var noUnnormalizedKeys = {
695
764
  },
696
765
 
697
766
  create(context) {
698
- const normalization = context.options.length
699
- ? text => text.normalize(context.options[0].form)
700
- : text => text.normalize();
767
+ const form = context.options.length
768
+ ? context.options[0].form
769
+ : undefined;
770
+
701
771
  return {
702
772
  Member(node) {
703
773
  const key =
@@ -705,7 +775,7 @@ var noUnnormalizedKeys = {
705
775
  ? node.name.value
706
776
  : node.name.name;
707
777
 
708
- if (normalization(key) !== key) {
778
+ if (key.normalize(form) !== key) {
709
779
  context.report({
710
780
  loc: node.name.loc,
711
781
  messageId: "unnormalizedKey",
@@ -720,49 +790,95 @@ var noUnnormalizedKeys = {
720
790
  };
721
791
 
722
792
  /**
723
- * @fileoverview Rule to require JSON object keys to be sorted. Copied largely from https://github.com/eslint/eslint/blob/main/lib/rules/sort-keys.js
793
+ * @fileoverview Rule to require JSON object keys to be sorted.
794
+ * Copied largely from https://github.com/eslint/eslint/blob/main/lib/rules/sort-keys.js
724
795
  * @author Robin Thomas
725
796
  */
726
797
 
727
798
 
799
+ //-----------------------------------------------------------------------------
800
+ // Type Definitions
801
+ //-----------------------------------------------------------------------------
802
+
803
+ /**
804
+ *
805
+ * @typedef {Object} SortOptions
806
+ * @property {boolean} caseSensitive
807
+ * @property {boolean} natural
808
+ * @property {number} minKeys
809
+ * @property {boolean} allowLineSeparatedGroups
810
+ *
811
+ * @typedef {"sortKeys"} SortKeysMessageIds
812
+ * @typedef {"asc"|"desc"} SortDirection
813
+ * @typedef {[SortDirection, SortOptions]} SortKeysRuleOptions
814
+ * @typedef {JSONRuleDefinition<{ RuleOptions: SortKeysRuleOptions, MessageIds: SortKeysMessageIds }>} SortKeysRuleDefinition
815
+ * @typedef {(a:string,b:string) => boolean} Comparator
816
+ */
817
+
818
+ //-----------------------------------------------------------------------------
819
+ // Helpers
820
+ //-----------------------------------------------------------------------------
821
+
728
822
  const hasNonWhitespace = /\S/u;
729
823
 
730
824
  const comparators = {
731
825
  ascending: {
732
826
  alphanumeric: {
827
+ /** @type {Comparator} */
733
828
  sensitive: (a, b) => a <= b,
829
+
830
+ /** @type {Comparator} */
734
831
  insensitive: (a, b) => a.toLowerCase() <= b.toLowerCase(),
735
832
  },
736
833
  natural: {
834
+ /** @type {Comparator} */
737
835
  sensitive: (a, b) => naturalCompare(a, b) <= 0,
836
+
837
+ /** @type {Comparator} */
738
838
  insensitive: (a, b) =>
739
839
  naturalCompare(a.toLowerCase(), b.toLowerCase()) <= 0,
740
840
  },
741
841
  },
742
842
  descending: {
743
843
  alphanumeric: {
844
+ /** @type {Comparator} */
744
845
  sensitive: (a, b) =>
745
846
  comparators.ascending.alphanumeric.sensitive(b, a),
847
+
848
+ /** @type {Comparator} */
746
849
  insensitive: (a, b) =>
747
850
  comparators.ascending.alphanumeric.insensitive(b, a),
748
851
  },
749
852
  natural: {
853
+ /** @type {Comparator} */
750
854
  sensitive: (a, b) => comparators.ascending.natural.sensitive(b, a),
855
+
856
+ /** @type {Comparator} */
751
857
  insensitive: (a, b) =>
752
858
  comparators.ascending.natural.insensitive(b, a),
753
859
  },
754
860
  },
755
861
  };
756
862
 
863
+ /**
864
+ * Gets the MemberNode's string key value.
865
+ * @param {MemberNode} member
866
+ * @return {string}
867
+ */
757
868
  function getKey(member) {
758
- return member.name.type === `Identifier`
869
+ return member.name.type === "Identifier"
759
870
  ? member.name.name
760
871
  : member.name.value;
761
872
  }
762
873
 
763
- var sortKeys = {
874
+ //-----------------------------------------------------------------------------
875
+ // Rule Definition
876
+ //-----------------------------------------------------------------------------
877
+
878
+ /** @type {SortKeysRuleDefinition} */
879
+ const rule$1 = {
764
880
  meta: {
765
- type: /** @type {const} */ ("suggestion"),
881
+ type: "suggestion",
766
882
 
767
883
  defaultOptions: [
768
884
  "asc",
@@ -832,8 +948,14 @@ var sortKeys = {
832
948
  }
833
949
  }
834
950
 
835
- // Note that there can be comments *inside* members, e.g. `{"foo: /* comment *\/ "bar"}`, but these are ignored when calculating line-separated groups
951
+ /**
952
+ * Checks if two members are line-separated.
953
+ * @param {MemberNode} prevMember The previous member.
954
+ * @param {MemberNode} member The current member.
955
+ * @return {boolean}
956
+ */
836
957
  function isLineSeparated(prevMember, member) {
958
+ // Note that there can be comments *inside* members, e.g. `{"foo: /* comment *\/ "bar"}`, but these are ignored when calculating line-separated groups
837
959
  const prevMemberEndLine = prevMember.loc.end.line;
838
960
  const thisStartLine = member.loc.start.line;
839
961
  if (thisStartLine - prevMemberEndLine < 2) {
@@ -902,9 +1024,24 @@ var sortKeys = {
902
1024
  * @author Joe Hildebrand
903
1025
  */
904
1026
 
905
- var topLevelInterop = {
1027
+ //-----------------------------------------------------------------------------
1028
+ // Type Definitions
1029
+ //-----------------------------------------------------------------------------
1030
+
1031
+ /**
1032
+ *
1033
+ * @typedef {"topLevel"} TopLevelInteropMessageIds
1034
+ * @typedef {JSONRuleDefinition<{ MessageIds: TopLevelInteropMessageIds }>} TopLevelInteropRuleDefinition
1035
+ */
1036
+
1037
+ //-----------------------------------------------------------------------------
1038
+ // Rule Definition
1039
+ //-----------------------------------------------------------------------------
1040
+
1041
+ /** @type {TopLevelInteropRuleDefinition} */
1042
+ const rule = {
906
1043
  meta: {
907
- type: /** @type {const} */ ("problem"),
1044
+ type: "problem",
908
1045
 
909
1046
  docs: {
910
1047
  description:
@@ -946,7 +1083,7 @@ var topLevelInterop = {
946
1083
  const plugin = {
947
1084
  meta: {
948
1085
  name: "@eslint/json",
949
- version: "0.10.0", // x-release-please-version
1086
+ version: "0.12.0", // x-release-please-version
950
1087
  },
951
1088
  languages: {
952
1089
  json: new JSONLanguage({ mode: "json" }),
@@ -954,12 +1091,12 @@ const plugin = {
954
1091
  json5: new JSONLanguage({ mode: "json5" }),
955
1092
  },
956
1093
  rules: {
957
- "no-duplicate-keys": noDuplicateKeys,
958
- "no-empty-keys": noEmptyKeys,
959
- "no-unsafe-values": noUnsafeValues,
960
- "no-unnormalized-keys": noUnnormalizedKeys,
961
- "sort-keys": sortKeys,
962
- "top-level-interop": topLevelInterop,
1094
+ "no-duplicate-keys": rule$5,
1095
+ "no-empty-keys": rule$4,
1096
+ "no-unsafe-values": rule$3,
1097
+ "no-unnormalized-keys": rule$2,
1098
+ "sort-keys": rule$1,
1099
+ "top-level-interop": rule,
963
1100
  },
964
1101
  configs: {
965
1102
  recommended: {