@eslint/json 0.10.0 → 0.11.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
@@ -256,9 +256,9 @@ to get your logo on our READMEs and [website](https://eslint.org/sponsors).
256
256
 
257
257
  <h3>Platinum Sponsors</h3>
258
258
  <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>
259
+ <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>
260
+ <p><a href="https://vite.dev/"><img src="https://images.opencollective.com/vite/e6d15e1/logo.png" alt="Vite" 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://stackblitz.com"><img src="https://avatars.githubusercontent.com/u/28635252" alt="StackBlitz" 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> <a href="https://www.lambdatest.com"><img src="https://avatars.githubusercontent.com/u/171592363" alt="LambdaTest" height="32"></a></p>
262
262
  <h3>Technology Sponsors</h3>
263
263
  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
264
  <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>
@@ -23,11 +23,12 @@ var naturalCompare = require('natural-compare');
23
23
  /** @typedef {import("@eslint/core").SourceLocation} SourceLocation */
24
24
  /** @typedef {import("@eslint/core").File} File */
25
25
  /** @typedef {import("@eslint/core").TraversalStep} TraversalStep */
26
- /** @typedef {import("@eslint/core").TextSourceCode} TextSourceCode */
27
26
  /** @typedef {import("@eslint/core").VisitTraversalStep} VisitTraversalStep */
28
27
  /** @typedef {import("@eslint/core").FileProblem} FileProblem */
29
28
  /** @typedef {import("@eslint/core").DirectiveType} DirectiveType */
30
29
  /** @typedef {import("@eslint/core").RulesConfig} RulesConfig */
30
+ /** @typedef {import("./types.ts").IJSONSourceCode} IJSONSourceCode */
31
+ /** @typedef {import("./types.ts").JSONSyntaxElement} JSONSyntaxElement */
31
32
 
32
33
  //-----------------------------------------------------------------------------
33
34
  // Helpers
@@ -68,6 +69,7 @@ class JSONTraversalStep extends pluginKit.VisitNodeStep {
68
69
 
69
70
  /**
70
71
  * JSON Source Code Object
72
+ * @implements {IJSONSourceCode}
71
73
  */
72
74
  class JSONSourceCode extends pluginKit.TextSourceCodeBase {
73
75
  /**
@@ -144,7 +146,7 @@ class JSONSourceCode extends pluginKit.TextSourceCodeBase {
144
146
  );
145
147
  }
146
148
 
147
- return this.#inlineConfigComments;
149
+ return this.#inlineConfigComments ?? [];
148
150
  }
149
151
 
150
152
  /**
@@ -297,10 +299,8 @@ class JSONSourceCode extends pluginKit.TextSourceCodeBase {
297
299
  /** @typedef {import("@eslint/core").Language} Language */
298
300
  /** @typedef {import("@eslint/core").OkParseResult<DocumentNode>} OkParseResult */
299
301
  /** @typedef {import("@eslint/core").ParseResult<DocumentNode>} ParseResult */
300
- /**
301
- * @typedef {Object} JSONLanguageOptions
302
- * @property {boolean} [allowTrailingCommas] Whether to allow trailing commas.
303
- */
302
+ /** @typedef {import("./types.ts").IJSONLanguage} IJSONLanguage */
303
+ /** @typedef {import("./types.ts").JSONLanguageOptions} JSONLanguageOptions */
304
304
 
305
305
  //-----------------------------------------------------------------------------
306
306
  // Exports
@@ -308,7 +308,7 @@ class JSONSourceCode extends pluginKit.TextSourceCodeBase {
308
308
 
309
309
  /**
310
310
  * JSON Language Object
311
- * @implements {Language}
311
+ * @implements {IJSONLanguage}
312
312
  */
313
313
  class JSONLanguage {
314
314
  /**
@@ -450,13 +450,22 @@ class JSONLanguage {
450
450
  * @author Nicholas C. Zakas
451
451
  */
452
452
 
453
+ //-----------------------------------------------------------------------------
454
+ // Type Definitions
455
+ //-----------------------------------------------------------------------------
456
+
457
+ /** @typedef {"duplicateKey"} NoDuplicateKeysMessageIds */
458
+ /** @typedef {import("./types.ts").JSONRuleDefinition<[], NoDuplicateKeysMessageIds>} NoDuplicateKeysRuleDefinition */
459
+ /** @typedef {import("@humanwhocodes/momoa").MemberNode} MemberNode */
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,21 @@ var noDuplicateKeys = {
507
519
  * @author Nicholas C. Zakas
508
520
  */
509
521
 
510
- var noEmptyKeys = {
522
+ //-----------------------------------------------------------------------------
523
+ // Type Definitions
524
+ //-----------------------------------------------------------------------------
525
+
526
+ /** @typedef {"emptyKey"} NoEmptyKeysMessageIds */
527
+ /** @typedef {import("./types.ts").JSONRuleDefinition<[], NoEmptyKeysMessageIds>} NoEmptyKeysRuleDefinition */
528
+
529
+ //-----------------------------------------------------------------------------
530
+ // Rule Definition
531
+ //-----------------------------------------------------------------------------
532
+
533
+ /** @type {NoEmptyKeysRuleDefinition} */
534
+ const rule$4 = {
511
535
  meta: {
512
- type: /** @type {const} */ ("problem"),
536
+ type: "problem",
513
537
 
514
538
  docs: {
515
539
  description: "Disallow empty keys in JSON objects",
@@ -544,15 +568,36 @@ var noEmptyKeys = {
544
568
  * @author Bradley Meck Farias
545
569
  */
546
570
 
547
- // RFC 8259's `number` production, as a regex. Capture the integer part
548
- // and the fractional part.
571
+ //-----------------------------------------------------------------------------
572
+ // Type Definitions
573
+ //-----------------------------------------------------------------------------
574
+
575
+ /** @typedef {"unsafeNumber"|"unsafeInteger"|"unsafeZero"|"subnormal"|"loneSurrogate"} NoUnsafeValuesMessageIds */
576
+ /** @typedef {import("./types.ts").JSONRuleDefinition<[], NoUnsafeValuesMessageIds>} NoUnsafeValuesRuleDefinition */
577
+
578
+ //-----------------------------------------------------------------------------
579
+ // Helpers
580
+ //-----------------------------------------------------------------------------
581
+
582
+ /*
583
+ * This rule is based on the JSON grammar from RFC 8259, section 6.
584
+ * https://tools.ietf.org/html/rfc8259#section-6
585
+ *
586
+ * We separately capture the integer and fractional parts of a number, so that
587
+ * we can check for unsafe numbers that will evaluate to Infinity.
588
+ */
549
589
  const NUMBER =
550
590
  /^-?(?<int>0|([1-9][0-9]*))(?:\.(?<frac>[0-9]+))?(?:[eE][+-]?[0-9]+)?$/u;
551
591
  const NON_ZERO = /[1-9]/u;
552
592
 
553
- var noUnsafeValues = {
593
+ //-----------------------------------------------------------------------------
594
+ // Rule Definition
595
+ //-----------------------------------------------------------------------------
596
+
597
+ /** @type {NoUnsafeValuesRuleDefinition} */
598
+ const rule$3 = {
554
599
  meta: {
555
- type: /** @type {const} */ ("problem"),
600
+ type: "problem",
556
601
 
557
602
  docs: {
558
603
  description: "Disallow JSON values that are unsafe for interchange",
@@ -626,7 +671,9 @@ var noUnsafeValues = {
626
671
  loc: node.loc,
627
672
  messageId: "subnormal",
628
673
  // Value included so that it's seen in scientific notation
629
- data: node,
674
+ data: {
675
+ value,
676
+ },
630
677
  });
631
678
  }
632
679
  }
@@ -669,9 +716,21 @@ var noUnsafeValues = {
669
716
  * @author Bradley Meck Farias
670
717
  */
671
718
 
672
- var noUnnormalizedKeys = {
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 = {
673
732
  meta: {
674
- type: /** @type {const} */ ("problem"),
733
+ type: "problem",
675
734
 
676
735
  docs: {
677
736
  description: "Disallow JSON keys that are not normalized",
@@ -695,9 +754,10 @@ var noUnnormalizedKeys = {
695
754
  },
696
755
 
697
756
  create(context) {
698
- const normalization = context.options.length
699
- ? text => text.normalize(context.options[0].form)
700
- : text => text.normalize();
757
+ const form = context.options.length
758
+ ? context.options[0].form
759
+ : undefined;
760
+
701
761
  return {
702
762
  Member(node) {
703
763
  const key =
@@ -705,7 +765,7 @@ var noUnnormalizedKeys = {
705
765
  ? node.name.value
706
766
  : node.name.name;
707
767
 
708
- if (normalization(key) !== key) {
768
+ if (key.normalize(form) !== key) {
709
769
  context.report({
710
770
  loc: node.name.loc,
711
771
  messageId: "unnormalizedKey",
@@ -720,49 +780,95 @@ var noUnnormalizedKeys = {
720
780
  };
721
781
 
722
782
  /**
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
783
+ * @fileoverview Rule to require JSON object keys to be sorted.
784
+ * Copied largely from https://github.com/eslint/eslint/blob/main/lib/rules/sort-keys.js
724
785
  * @author Robin Thomas
725
786
  */
726
787
 
727
788
 
789
+ //-----------------------------------------------------------------------------
790
+ // Type Definitions
791
+ //-----------------------------------------------------------------------------
792
+
793
+ /** @typedef {"sortKeys"} SortKeysMessageIds */
794
+
795
+ /**
796
+ * @typedef {Object} SortOptions
797
+ * @property {boolean} caseSensitive
798
+ * @property {boolean} natural
799
+ * @property {number} minKeys
800
+ * @property {boolean} allowLineSeparatedGroups
801
+ */
802
+
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
+ //-----------------------------------------------------------------------------
809
+ // Helpers
810
+ //-----------------------------------------------------------------------------
811
+
728
812
  const hasNonWhitespace = /\S/u;
729
813
 
730
814
  const comparators = {
731
815
  ascending: {
732
816
  alphanumeric: {
817
+ /** @type {Comparator} */
733
818
  sensitive: (a, b) => a <= b,
819
+
820
+ /** @type {Comparator} */
734
821
  insensitive: (a, b) => a.toLowerCase() <= b.toLowerCase(),
735
822
  },
736
823
  natural: {
824
+ /** @type {Comparator} */
737
825
  sensitive: (a, b) => naturalCompare(a, b) <= 0,
826
+
827
+ /** @type {Comparator} */
738
828
  insensitive: (a, b) =>
739
829
  naturalCompare(a.toLowerCase(), b.toLowerCase()) <= 0,
740
830
  },
741
831
  },
742
832
  descending: {
743
833
  alphanumeric: {
834
+ /** @type {Comparator} */
744
835
  sensitive: (a, b) =>
745
836
  comparators.ascending.alphanumeric.sensitive(b, a),
837
+
838
+ /** @type {Comparator} */
746
839
  insensitive: (a, b) =>
747
840
  comparators.ascending.alphanumeric.insensitive(b, a),
748
841
  },
749
842
  natural: {
843
+ /** @type {Comparator} */
750
844
  sensitive: (a, b) => comparators.ascending.natural.sensitive(b, a),
845
+
846
+ /** @type {Comparator} */
751
847
  insensitive: (a, b) =>
752
848
  comparators.ascending.natural.insensitive(b, a),
753
849
  },
754
850
  },
755
851
  };
756
852
 
853
+ /**
854
+ * Gets the MemberNode's string key value.
855
+ * @param {MemberNode} member
856
+ * @return {string}
857
+ */
757
858
  function getKey(member) {
758
- return member.name.type === `Identifier`
859
+ return member.name.type === "Identifier"
759
860
  ? member.name.name
760
861
  : member.name.value;
761
862
  }
762
863
 
763
- var sortKeys = {
864
+ //-----------------------------------------------------------------------------
865
+ // Rule Definition
866
+ //-----------------------------------------------------------------------------
867
+
868
+ /** @type {SortKeysRuleDefinition} */
869
+ const rule$1 = {
764
870
  meta: {
765
- type: /** @type {const} */ ("suggestion"),
871
+ type: "suggestion",
766
872
 
767
873
  defaultOptions: [
768
874
  "asc",
@@ -832,8 +938,14 @@ var sortKeys = {
832
938
  }
833
939
  }
834
940
 
835
- // Note that there can be comments *inside* members, e.g. `{"foo: /* comment *\/ "bar"}`, but these are ignored when calculating line-separated groups
941
+ /**
942
+ * Checks if two members are line-separated.
943
+ * @param {MemberNode} prevMember The previous member.
944
+ * @param {MemberNode} member The current member.
945
+ * @return {boolean}
946
+ */
836
947
  function isLineSeparated(prevMember, member) {
948
+ // Note that there can be comments *inside* members, e.g. `{"foo: /* comment *\/ "bar"}`, but these are ignored when calculating line-separated groups
837
949
  const prevMemberEndLine = prevMember.loc.end.line;
838
950
  const thisStartLine = member.loc.start.line;
839
951
  if (thisStartLine - prevMemberEndLine < 2) {
@@ -902,9 +1014,21 @@ var sortKeys = {
902
1014
  * @author Joe Hildebrand
903
1015
  */
904
1016
 
905
- var topLevelInterop = {
1017
+ //-----------------------------------------------------------------------------
1018
+ // Type Definitions
1019
+ //-----------------------------------------------------------------------------
1020
+
1021
+ /** @typedef {"topLevel"} TopLevelInteropMessageIds */
1022
+ /** @typedef {import("./types.ts").JSONRuleDefinition<[], TopLevelInteropMessageIds>} TopLevelInteropRuleDefinition */
1023
+
1024
+ //-----------------------------------------------------------------------------
1025
+ // Rule Definition
1026
+ //-----------------------------------------------------------------------------
1027
+
1028
+ /** @type {TopLevelInteropRuleDefinition} */
1029
+ const rule = {
906
1030
  meta: {
907
- type: /** @type {const} */ ("problem"),
1031
+ type: "problem",
908
1032
 
909
1033
  docs: {
910
1034
  description:
@@ -946,7 +1070,7 @@ var topLevelInterop = {
946
1070
  const plugin = {
947
1071
  meta: {
948
1072
  name: "@eslint/json",
949
- version: "0.10.0", // x-release-please-version
1073
+ version: "0.11.0", // x-release-please-version
950
1074
  },
951
1075
  languages: {
952
1076
  json: new JSONLanguage({ mode: "json" }),
@@ -954,12 +1078,12 @@ const plugin = {
954
1078
  json5: new JSONLanguage({ mode: "json5" }),
955
1079
  },
956
1080
  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,
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,
963
1087
  },
964
1088
  configs: {
965
1089
  recommended: {
@@ -5,20 +5,41 @@ export type SourceRange = import("@eslint/core").SourceRange;
5
5
  export type SourceLocation = import("@eslint/core").SourceLocation;
6
6
  export type File = import("@eslint/core").File;
7
7
  export type TraversalStep = import("@eslint/core").TraversalStep;
8
- export type TextSourceCode = import("@eslint/core").TextSourceCode;
9
8
  export type VisitTraversalStep = import("@eslint/core").VisitTraversalStep;
10
9
  export type FileProblem = import("@eslint/core").FileProblem;
11
10
  export type DirectiveType = import("@eslint/core").DirectiveType;
12
11
  export type RulesConfig = import("@eslint/core").RulesConfig;
12
+ export type IJSONSourceCode = import("./types.cts").IJSONSourceCode;
13
+ export type JSONSyntaxElement = import("./types.cts").JSONSyntaxElement;
13
14
  export type Language = import("@eslint/core").Language;
14
15
  export type OkParseResult = import("@eslint/core").OkParseResult<DocumentNode>;
15
16
  export type ParseResult = import("@eslint/core").ParseResult<DocumentNode>;
16
- export type JSONLanguageOptions = {
17
- /**
18
- * Whether to allow trailing commas.
19
- */
20
- allowTrailingCommas?: boolean;
17
+ export type IJSONLanguage = import("./types.cts").IJSONLanguage;
18
+ export type JSONLanguageOptions = import("./types.cts").JSONLanguageOptions;
19
+ export type NoDuplicateKeysMessageIds = "duplicateKey";
20
+ export type NoDuplicateKeysRuleDefinition = import("./types.cts").JSONRuleDefinition<[], NoDuplicateKeysMessageIds>;
21
+ export type MemberNode = import("@humanwhocodes/momoa").MemberNode;
22
+ export type NoEmptyKeysMessageIds = "emptyKey";
23
+ export type NoEmptyKeysRuleDefinition = import("./types.cts").JSONRuleDefinition<[], NoEmptyKeysMessageIds>;
24
+ export type NoUnsafeValuesMessageIds = "unsafeNumber" | "unsafeInteger" | "unsafeZero" | "subnormal" | "loneSurrogate";
25
+ export type NoUnsafeValuesRuleDefinition = import("./types.cts").JSONRuleDefinition<[], NoUnsafeValuesMessageIds>;
26
+ export type NoUnnormalizedKeysMessageIds = "unnormalizedKey";
27
+ export type NoUnnormalizedKeysRuleDefinition = import("./types.cts").JSONRuleDefinition<[{
28
+ form: string;
29
+ }], NoUnnormalizedKeysMessageIds>;
30
+ export type SortKeysMessageIds = "sortKeys";
31
+ export type SortOptions = {
32
+ caseSensitive: boolean;
33
+ natural: boolean;
34
+ minKeys: number;
35
+ allowLineSeparatedGroups: boolean;
21
36
  };
37
+ export type SortDirection = "asc" | "desc";
38
+ export type SortKeysRuleOptions = [SortDirection, SortOptions];
39
+ export type SortKeysRuleDefinition = import("./types.cts").JSONRuleDefinition<SortKeysRuleOptions, SortKeysMessageIds>;
40
+ export type Comparator = (a: string, b: string) => boolean;
41
+ export type TopLevelInteropMessageIds = "topLevel";
42
+ export type TopLevelInteropRuleDefinition = import("./types.cts").JSONRuleDefinition<[], TopLevelInteropMessageIds>;
22
43
  /**
23
44
  * @filedescription Functions to fix up rules to provide missing methods on the `context` object.
24
45
  * @author Nicholas C. Zakas
@@ -26,15 +47,13 @@ export type JSONLanguageOptions = {
26
47
  /** @typedef {import("@eslint/core").Language} Language */
27
48
  /** @typedef {import("@eslint/core").OkParseResult<DocumentNode>} OkParseResult */
28
49
  /** @typedef {import("@eslint/core").ParseResult<DocumentNode>} ParseResult */
29
- /**
30
- * @typedef {Object} JSONLanguageOptions
31
- * @property {boolean} [allowTrailingCommas] Whether to allow trailing commas.
32
- */
50
+ /** @typedef {import("./types.cts").IJSONLanguage} IJSONLanguage */
51
+ /** @typedef {import("./types.cts").JSONLanguageOptions} JSONLanguageOptions */
33
52
  /**
34
53
  * JSON Language Object
35
- * @implements {Language}
54
+ * @implements {IJSONLanguage}
36
55
  */
37
- export class JSONLanguage implements Language {
56
+ export class JSONLanguage implements IJSONLanguage {
38
57
  /**
39
58
  * Creates a new instance.
40
59
  * @param {Object} options The options to use for this instance.
@@ -95,8 +114,9 @@ export class JSONLanguage implements Language {
95
114
  }
96
115
  /**
97
116
  * JSON Source Code Object
117
+ * @implements {IJSONSourceCode}
98
118
  */
99
- export class JSONSourceCode extends TextSourceCodeBase {
119
+ export class JSONSourceCode extends TextSourceCodeBase implements IJSONSourceCode {
100
120
  /**
101
121
  * Creates a new instance.
102
122
  * @param {Object} options The options for the instance.
@@ -172,137 +192,12 @@ declare namespace plugin {
172
192
  let json5: JSONLanguage;
173
193
  }
174
194
  let rules: {
175
- "no-duplicate-keys": {
176
- meta: {
177
- type: "problem";
178
- docs: {
179
- description: string;
180
- };
181
- messages: {
182
- duplicateKey: string;
183
- };
184
- };
185
- create(context: any): {
186
- Object(): void;
187
- Member(node: any): void;
188
- "Object:exit"(): void;
189
- };
190
- };
191
- "no-empty-keys": {
192
- meta: {
193
- type: "problem";
194
- docs: {
195
- description: string;
196
- };
197
- messages: {
198
- emptyKey: string;
199
- };
200
- };
201
- create(context: any): {
202
- Member(node: any): void;
203
- };
204
- };
205
- "no-unsafe-values": {
206
- meta: {
207
- type: "problem";
208
- docs: {
209
- description: string;
210
- };
211
- messages: {
212
- unsafeNumber: string;
213
- unsafeInteger: string;
214
- unsafeZero: string;
215
- subnormal: string;
216
- loneSurrogate: string;
217
- };
218
- };
219
- create(context: any): {
220
- Number(node: any): void;
221
- String(node: any): void;
222
- };
223
- };
224
- "no-unnormalized-keys": {
225
- meta: {
226
- type: "problem";
227
- docs: {
228
- description: string;
229
- };
230
- messages: {
231
- unnormalizedKey: string;
232
- };
233
- schema: {
234
- type: string;
235
- properties: {
236
- form: {
237
- enum: string[];
238
- };
239
- };
240
- additionalProperties: boolean;
241
- }[];
242
- };
243
- create(context: any): {
244
- Member(node: any): void;
245
- };
246
- };
247
- "sort-keys": {
248
- meta: {
249
- type: "suggestion";
250
- defaultOptions: (string | {
251
- allowLineSeparatedGroups: boolean;
252
- caseSensitive: boolean;
253
- minKeys: number;
254
- natural: boolean;
255
- })[];
256
- docs: {
257
- description: string;
258
- };
259
- messages: {
260
- sortKeys: string;
261
- };
262
- schema: ({
263
- enum: string[];
264
- type?: undefined;
265
- properties?: undefined;
266
- additionalProperties?: undefined;
267
- } | {
268
- type: string;
269
- properties: {
270
- caseSensitive: {
271
- type: string;
272
- };
273
- natural: {
274
- type: string;
275
- };
276
- minKeys: {
277
- type: string;
278
- minimum: number;
279
- };
280
- allowLineSeparatedGroups: {
281
- type: string;
282
- };
283
- };
284
- additionalProperties: boolean;
285
- enum?: undefined;
286
- })[];
287
- };
288
- create(context: any): {
289
- Object(node: any): void;
290
- };
291
- };
292
- "top-level-interop": {
293
- meta: {
294
- type: "problem";
295
- docs: {
296
- description: string;
297
- };
298
- messages: {
299
- topLevel: string;
300
- };
301
- };
302
- create(context: any): {
303
- Document(node: any): void;
304
- };
305
- };
195
+ "no-duplicate-keys": NoDuplicateKeysRuleDefinition;
196
+ "no-empty-keys": NoEmptyKeysRuleDefinition;
197
+ "no-unsafe-values": NoUnsafeValuesRuleDefinition;
198
+ "no-unnormalized-keys": NoUnnormalizedKeysRuleDefinition;
199
+ "sort-keys": SortKeysRuleDefinition;
200
+ "top-level-interop": TopLevelInteropRuleDefinition;
306
201
  };
307
202
  namespace configs {
308
203
  namespace recommended {