@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/dist/esm/index.js CHANGED
@@ -20,11 +20,12 @@ import naturalCompare from 'natural-compare';
20
20
  /** @typedef {import("@eslint/core").SourceLocation} SourceLocation */
21
21
  /** @typedef {import("@eslint/core").File} File */
22
22
  /** @typedef {import("@eslint/core").TraversalStep} TraversalStep */
23
- /** @typedef {import("@eslint/core").TextSourceCode} TextSourceCode */
24
23
  /** @typedef {import("@eslint/core").VisitTraversalStep} VisitTraversalStep */
25
24
  /** @typedef {import("@eslint/core").FileProblem} FileProblem */
26
25
  /** @typedef {import("@eslint/core").DirectiveType} DirectiveType */
27
26
  /** @typedef {import("@eslint/core").RulesConfig} RulesConfig */
27
+ /** @typedef {import("./types.ts").IJSONSourceCode} IJSONSourceCode */
28
+ /** @typedef {import("./types.ts").JSONSyntaxElement} JSONSyntaxElement */
28
29
 
29
30
  //-----------------------------------------------------------------------------
30
31
  // Helpers
@@ -65,6 +66,7 @@ class JSONTraversalStep extends VisitNodeStep {
65
66
 
66
67
  /**
67
68
  * JSON Source Code Object
69
+ * @implements {IJSONSourceCode}
68
70
  */
69
71
  class JSONSourceCode extends TextSourceCodeBase {
70
72
  /**
@@ -141,7 +143,7 @@ class JSONSourceCode extends TextSourceCodeBase {
141
143
  );
142
144
  }
143
145
 
144
- return this.#inlineConfigComments;
146
+ return this.#inlineConfigComments ?? [];
145
147
  }
146
148
 
147
149
  /**
@@ -294,10 +296,8 @@ class JSONSourceCode extends TextSourceCodeBase {
294
296
  /** @typedef {import("@eslint/core").Language} Language */
295
297
  /** @typedef {import("@eslint/core").OkParseResult<DocumentNode>} OkParseResult */
296
298
  /** @typedef {import("@eslint/core").ParseResult<DocumentNode>} ParseResult */
297
- /**
298
- * @typedef {Object} JSONLanguageOptions
299
- * @property {boolean} [allowTrailingCommas] Whether to allow trailing commas.
300
- */
299
+ /** @typedef {import("./types.ts").IJSONLanguage} IJSONLanguage */
300
+ /** @typedef {import("./types.ts").JSONLanguageOptions} JSONLanguageOptions */
301
301
 
302
302
  //-----------------------------------------------------------------------------
303
303
  // Exports
@@ -305,7 +305,7 @@ class JSONSourceCode extends TextSourceCodeBase {
305
305
 
306
306
  /**
307
307
  * JSON Language Object
308
- * @implements {Language}
308
+ * @implements {IJSONLanguage}
309
309
  */
310
310
  class JSONLanguage {
311
311
  /**
@@ -447,13 +447,22 @@ class JSONLanguage {
447
447
  * @author Nicholas C. Zakas
448
448
  */
449
449
 
450
+ //-----------------------------------------------------------------------------
451
+ // Type Definitions
452
+ //-----------------------------------------------------------------------------
453
+
454
+ /** @typedef {"duplicateKey"} NoDuplicateKeysMessageIds */
455
+ /** @typedef {import("./types.ts").JSONRuleDefinition<[], NoDuplicateKeysMessageIds>} NoDuplicateKeysRuleDefinition */
456
+ /** @typedef {import("@humanwhocodes/momoa").MemberNode} MemberNode */
457
+
450
458
  //-----------------------------------------------------------------------------
451
459
  // Rule Definition
452
460
  //-----------------------------------------------------------------------------
453
461
 
454
- var noDuplicateKeys = {
462
+ /** @type {NoDuplicateKeysRuleDefinition} */
463
+ const rule$5 = {
455
464
  meta: {
456
- type: /** @type {const} */ ("problem"),
465
+ type: "problem",
457
466
 
458
467
  docs: {
459
468
  description: "Disallow duplicate keys in JSON objects",
@@ -465,7 +474,10 @@ var noDuplicateKeys = {
465
474
  },
466
475
 
467
476
  create(context) {
477
+ /** @type {Array<Map<string, MemberNode>|undefined>} */
468
478
  const objectKeys = [];
479
+
480
+ /** @type {Map<string, MemberNode>|undefined} */
469
481
  let keys;
470
482
 
471
483
  return {
@@ -504,9 +516,21 @@ var noDuplicateKeys = {
504
516
  * @author Nicholas C. Zakas
505
517
  */
506
518
 
507
- var noEmptyKeys = {
519
+ //-----------------------------------------------------------------------------
520
+ // Type Definitions
521
+ //-----------------------------------------------------------------------------
522
+
523
+ /** @typedef {"emptyKey"} NoEmptyKeysMessageIds */
524
+ /** @typedef {import("./types.ts").JSONRuleDefinition<[], NoEmptyKeysMessageIds>} NoEmptyKeysRuleDefinition */
525
+
526
+ //-----------------------------------------------------------------------------
527
+ // Rule Definition
528
+ //-----------------------------------------------------------------------------
529
+
530
+ /** @type {NoEmptyKeysRuleDefinition} */
531
+ const rule$4 = {
508
532
  meta: {
509
- type: /** @type {const} */ ("problem"),
533
+ type: "problem",
510
534
 
511
535
  docs: {
512
536
  description: "Disallow empty keys in JSON objects",
@@ -541,15 +565,36 @@ var noEmptyKeys = {
541
565
  * @author Bradley Meck Farias
542
566
  */
543
567
 
544
- // RFC 8259's `number` production, as a regex. Capture the integer part
545
- // and the fractional part.
568
+ //-----------------------------------------------------------------------------
569
+ // Type Definitions
570
+ //-----------------------------------------------------------------------------
571
+
572
+ /** @typedef {"unsafeNumber"|"unsafeInteger"|"unsafeZero"|"subnormal"|"loneSurrogate"} NoUnsafeValuesMessageIds */
573
+ /** @typedef {import("./types.ts").JSONRuleDefinition<[], NoUnsafeValuesMessageIds>} NoUnsafeValuesRuleDefinition */
574
+
575
+ //-----------------------------------------------------------------------------
576
+ // Helpers
577
+ //-----------------------------------------------------------------------------
578
+
579
+ /*
580
+ * This rule is based on the JSON grammar from RFC 8259, section 6.
581
+ * https://tools.ietf.org/html/rfc8259#section-6
582
+ *
583
+ * We separately capture the integer and fractional parts of a number, so that
584
+ * we can check for unsafe numbers that will evaluate to Infinity.
585
+ */
546
586
  const NUMBER =
547
587
  /^-?(?<int>0|([1-9][0-9]*))(?:\.(?<frac>[0-9]+))?(?:[eE][+-]?[0-9]+)?$/u;
548
588
  const NON_ZERO = /[1-9]/u;
549
589
 
550
- var noUnsafeValues = {
590
+ //-----------------------------------------------------------------------------
591
+ // Rule Definition
592
+ //-----------------------------------------------------------------------------
593
+
594
+ /** @type {NoUnsafeValuesRuleDefinition} */
595
+ const rule$3 = {
551
596
  meta: {
552
- type: /** @type {const} */ ("problem"),
597
+ type: "problem",
553
598
 
554
599
  docs: {
555
600
  description: "Disallow JSON values that are unsafe for interchange",
@@ -623,7 +668,9 @@ var noUnsafeValues = {
623
668
  loc: node.loc,
624
669
  messageId: "subnormal",
625
670
  // Value included so that it's seen in scientific notation
626
- data: node,
671
+ data: {
672
+ value,
673
+ },
627
674
  });
628
675
  }
629
676
  }
@@ -666,9 +713,21 @@ var noUnsafeValues = {
666
713
  * @author Bradley Meck Farias
667
714
  */
668
715
 
669
- var noUnnormalizedKeys = {
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 = {
670
729
  meta: {
671
- type: /** @type {const} */ ("problem"),
730
+ type: "problem",
672
731
 
673
732
  docs: {
674
733
  description: "Disallow JSON keys that are not normalized",
@@ -692,9 +751,10 @@ var noUnnormalizedKeys = {
692
751
  },
693
752
 
694
753
  create(context) {
695
- const normalization = context.options.length
696
- ? text => text.normalize(context.options[0].form)
697
- : text => text.normalize();
754
+ const form = context.options.length
755
+ ? context.options[0].form
756
+ : undefined;
757
+
698
758
  return {
699
759
  Member(node) {
700
760
  const key =
@@ -702,7 +762,7 @@ var noUnnormalizedKeys = {
702
762
  ? node.name.value
703
763
  : node.name.name;
704
764
 
705
- if (normalization(key) !== key) {
765
+ if (key.normalize(form) !== key) {
706
766
  context.report({
707
767
  loc: node.name.loc,
708
768
  messageId: "unnormalizedKey",
@@ -717,49 +777,95 @@ var noUnnormalizedKeys = {
717
777
  };
718
778
 
719
779
  /**
720
- * @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
780
+ * @fileoverview Rule to require JSON object keys to be sorted.
781
+ * Copied largely from https://github.com/eslint/eslint/blob/main/lib/rules/sort-keys.js
721
782
  * @author Robin Thomas
722
783
  */
723
784
 
724
785
 
786
+ //-----------------------------------------------------------------------------
787
+ // Type Definitions
788
+ //-----------------------------------------------------------------------------
789
+
790
+ /** @typedef {"sortKeys"} SortKeysMessageIds */
791
+
792
+ /**
793
+ * @typedef {Object} SortOptions
794
+ * @property {boolean} caseSensitive
795
+ * @property {boolean} natural
796
+ * @property {number} minKeys
797
+ * @property {boolean} allowLineSeparatedGroups
798
+ */
799
+
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
+ //-----------------------------------------------------------------------------
806
+ // Helpers
807
+ //-----------------------------------------------------------------------------
808
+
725
809
  const hasNonWhitespace = /\S/u;
726
810
 
727
811
  const comparators = {
728
812
  ascending: {
729
813
  alphanumeric: {
814
+ /** @type {Comparator} */
730
815
  sensitive: (a, b) => a <= b,
816
+
817
+ /** @type {Comparator} */
731
818
  insensitive: (a, b) => a.toLowerCase() <= b.toLowerCase(),
732
819
  },
733
820
  natural: {
821
+ /** @type {Comparator} */
734
822
  sensitive: (a, b) => naturalCompare(a, b) <= 0,
823
+
824
+ /** @type {Comparator} */
735
825
  insensitive: (a, b) =>
736
826
  naturalCompare(a.toLowerCase(), b.toLowerCase()) <= 0,
737
827
  },
738
828
  },
739
829
  descending: {
740
830
  alphanumeric: {
831
+ /** @type {Comparator} */
741
832
  sensitive: (a, b) =>
742
833
  comparators.ascending.alphanumeric.sensitive(b, a),
834
+
835
+ /** @type {Comparator} */
743
836
  insensitive: (a, b) =>
744
837
  comparators.ascending.alphanumeric.insensitive(b, a),
745
838
  },
746
839
  natural: {
840
+ /** @type {Comparator} */
747
841
  sensitive: (a, b) => comparators.ascending.natural.sensitive(b, a),
842
+
843
+ /** @type {Comparator} */
748
844
  insensitive: (a, b) =>
749
845
  comparators.ascending.natural.insensitive(b, a),
750
846
  },
751
847
  },
752
848
  };
753
849
 
850
+ /**
851
+ * Gets the MemberNode's string key value.
852
+ * @param {MemberNode} member
853
+ * @return {string}
854
+ */
754
855
  function getKey(member) {
755
- return member.name.type === `Identifier`
856
+ return member.name.type === "Identifier"
756
857
  ? member.name.name
757
858
  : member.name.value;
758
859
  }
759
860
 
760
- var sortKeys = {
861
+ //-----------------------------------------------------------------------------
862
+ // Rule Definition
863
+ //-----------------------------------------------------------------------------
864
+
865
+ /** @type {SortKeysRuleDefinition} */
866
+ const rule$1 = {
761
867
  meta: {
762
- type: /** @type {const} */ ("suggestion"),
868
+ type: "suggestion",
763
869
 
764
870
  defaultOptions: [
765
871
  "asc",
@@ -829,8 +935,14 @@ var sortKeys = {
829
935
  }
830
936
  }
831
937
 
832
- // Note that there can be comments *inside* members, e.g. `{"foo: /* comment *\/ "bar"}`, but these are ignored when calculating line-separated groups
938
+ /**
939
+ * Checks if two members are line-separated.
940
+ * @param {MemberNode} prevMember The previous member.
941
+ * @param {MemberNode} member The current member.
942
+ * @return {boolean}
943
+ */
833
944
  function isLineSeparated(prevMember, member) {
945
+ // Note that there can be comments *inside* members, e.g. `{"foo: /* comment *\/ "bar"}`, but these are ignored when calculating line-separated groups
834
946
  const prevMemberEndLine = prevMember.loc.end.line;
835
947
  const thisStartLine = member.loc.start.line;
836
948
  if (thisStartLine - prevMemberEndLine < 2) {
@@ -899,9 +1011,21 @@ var sortKeys = {
899
1011
  * @author Joe Hildebrand
900
1012
  */
901
1013
 
902
- var topLevelInterop = {
1014
+ //-----------------------------------------------------------------------------
1015
+ // Type Definitions
1016
+ //-----------------------------------------------------------------------------
1017
+
1018
+ /** @typedef {"topLevel"} TopLevelInteropMessageIds */
1019
+ /** @typedef {import("./types.ts").JSONRuleDefinition<[], TopLevelInteropMessageIds>} TopLevelInteropRuleDefinition */
1020
+
1021
+ //-----------------------------------------------------------------------------
1022
+ // Rule Definition
1023
+ //-----------------------------------------------------------------------------
1024
+
1025
+ /** @type {TopLevelInteropRuleDefinition} */
1026
+ const rule = {
903
1027
  meta: {
904
- type: /** @type {const} */ ("problem"),
1028
+ type: "problem",
905
1029
 
906
1030
  docs: {
907
1031
  description:
@@ -943,7 +1067,7 @@ var topLevelInterop = {
943
1067
  const plugin = {
944
1068
  meta: {
945
1069
  name: "@eslint/json",
946
- version: "0.10.0", // x-release-please-version
1070
+ version: "0.11.0", // x-release-please-version
947
1071
  },
948
1072
  languages: {
949
1073
  json: new JSONLanguage({ mode: "json" }),
@@ -951,12 +1075,12 @@ const plugin = {
951
1075
  json5: new JSONLanguage({ mode: "json5" }),
952
1076
  },
953
1077
  rules: {
954
- "no-duplicate-keys": noDuplicateKeys,
955
- "no-empty-keys": noEmptyKeys,
956
- "no-unsafe-values": noUnsafeValues,
957
- "no-unnormalized-keys": noUnnormalizedKeys,
958
- "sort-keys": sortKeys,
959
- "top-level-interop": topLevelInterop,
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,
960
1084
  },
961
1085
  configs: {
962
1086
  recommended: {
@@ -0,0 +1,91 @@
1
+ /**
2
+ * @fileoverview Additional types for this package.
3
+ * @author Nicholas C. Zakas
4
+ */
5
+ import type { RuleVisitor, TextSourceCode, Language, LanguageOptions, RuleDefinition } from "@eslint/core";
6
+ import { DocumentNode, MemberNode, ElementNode, ObjectNode, ArrayNode, StringNode, NullNode, NumberNode, BooleanNode, NaNNode, InfinityNode, IdentifierNode, AnyNode, Token } from "@humanwhocodes/momoa";
7
+ type ValueNodeParent = DocumentNode | MemberNode | ElementNode;
8
+ /**
9
+ * A JSON syntax element, including nodes and tokens.
10
+ */
11
+ export type JSONSyntaxElement = Token | AnyNode;
12
+ /**
13
+ * Language options provided for JSON files.
14
+ */
15
+ export interface JSONLanguageOptions extends LanguageOptions {
16
+ /**
17
+ * Whether to allow trailing commas. Only valid in JSONC.
18
+ */
19
+ allowTrailingCommas?: boolean;
20
+ }
21
+ /**
22
+ * The visitor format returned from rules in this package.
23
+ */
24
+ export interface JSONRuleVisitor extends RuleVisitor {
25
+ Document?(node: DocumentNode): void;
26
+ Member?(node: MemberNode, parent?: ObjectNode): void;
27
+ Element?(node: ElementNode, parent?: ArrayNode): void;
28
+ Object?(node: ObjectNode, parent?: ValueNodeParent): void;
29
+ Array?(node: ArrayNode, parent?: ValueNodeParent): void;
30
+ String?(node: StringNode, parent?: ValueNodeParent): void;
31
+ Null?(node: NullNode, parent?: ValueNodeParent): void;
32
+ Number?(node: NumberNode, parent?: ValueNodeParent): void;
33
+ Boolean?(node: BooleanNode, parent?: ValueNodeParent): void;
34
+ NaN?(node: NaNNode, parent?: ValueNodeParent): void;
35
+ Infinity?(node: InfinityNode, parent?: ValueNodeParent): void;
36
+ Identifier?(node: IdentifierNode, parent?: ValueNodeParent): void;
37
+ "Document:exit"?(node: DocumentNode): void;
38
+ "Member:exit"?(node: MemberNode, parent?: ObjectNode): void;
39
+ "Element:exit"?(node: ElementNode, parent?: ArrayNode): void;
40
+ "Object:exit"?(node: ObjectNode, parent?: ValueNodeParent): void;
41
+ "Array:exit"?(node: ArrayNode, parent?: ValueNodeParent): void;
42
+ "String:exit"?(node: StringNode, parent?: ValueNodeParent): void;
43
+ "Null:exit"?(node: NullNode, parent?: ValueNodeParent): void;
44
+ "Number:exit"?(node: NumberNode, parent?: ValueNodeParent): void;
45
+ "Boolean:exit"?(node: BooleanNode, parent?: ValueNodeParent): void;
46
+ "NaN:exit"?(node: NaNNode, parent?: ValueNodeParent): void;
47
+ "Infinity:exit"?(node: InfinityNode, parent?: ValueNodeParent): void;
48
+ "Identifier:exit"?(node: IdentifierNode, parent?: ValueNodeParent): void;
49
+ }
50
+ /**
51
+ * The `SourceCode` implementation for JSON files.
52
+ */
53
+ export interface IJSONSourceCode extends TextSourceCode<{
54
+ LangOptions: JSONLanguageOptions;
55
+ RootNode: DocumentNode;
56
+ SyntaxElementWithLoc: JSONSyntaxElement;
57
+ ConfigNode: Token;
58
+ }> {
59
+ /**
60
+ * Get the text of a syntax element.
61
+ * @param syntaxElement The syntax element to get the text of.
62
+ * @param beforeCount The number of characters to include before the syntax element.
63
+ * @param afterCount The number of characters to include after the syntax element.
64
+ * @returns The text of the syntax element.
65
+ */
66
+ getText(syntaxElement: JSONSyntaxElement, beforeCount?: number, afterCount?: number): string;
67
+ /**
68
+ * Any comments found in a JSONC or JSON5 file.
69
+ */
70
+ comments: Array<Token> | undefined;
71
+ /**
72
+ * The lines of text found in the file.
73
+ */
74
+ lines: Array<string>;
75
+ }
76
+ export type IJSONLanguage = Language<{
77
+ LangOptions: JSONLanguageOptions;
78
+ Code: IJSONSourceCode;
79
+ RootNode: DocumentNode;
80
+ Node: AnyNode;
81
+ }>;
82
+ export type JSONRuleDefinition<JSONRuleOptions extends unknown[], JSONRuleMessageIds extends string = ""> = RuleDefinition<{
83
+ LangOptions: JSONLanguageOptions;
84
+ Code: IJSONSourceCode;
85
+ RuleOptions: JSONRuleOptions;
86
+ Visitor: JSONRuleVisitor;
87
+ Node: AnyNode;
88
+ MessageIds: JSONRuleMessageIds;
89
+ ExtRuleDocs: {};
90
+ }>;
91
+ export {};
@@ -0,0 +1,138 @@
1
+ /**
2
+ * @fileoverview Additional types for this package.
3
+ * @author Nicholas C. Zakas
4
+ */
5
+
6
+ //------------------------------------------------------------------------------
7
+ // Imports
8
+ //------------------------------------------------------------------------------
9
+
10
+ import type {
11
+ RuleVisitor,
12
+ TextSourceCode,
13
+ Language,
14
+ LanguageOptions,
15
+ RuleDefinition,
16
+ } from "@eslint/core";
17
+ import {
18
+ DocumentNode,
19
+ MemberNode,
20
+ ElementNode,
21
+ ObjectNode,
22
+ ArrayNode,
23
+ StringNode,
24
+ NullNode,
25
+ NumberNode,
26
+ BooleanNode,
27
+ NaNNode,
28
+ InfinityNode,
29
+ IdentifierNode,
30
+ AnyNode,
31
+ Token,
32
+ } from "@humanwhocodes/momoa";
33
+
34
+ //------------------------------------------------------------------------------
35
+ // Types
36
+ //------------------------------------------------------------------------------
37
+
38
+ type ValueNodeParent = DocumentNode | MemberNode | ElementNode;
39
+
40
+ /**
41
+ * A JSON syntax element, including nodes and tokens.
42
+ */
43
+ export type JSONSyntaxElement = Token | AnyNode;
44
+
45
+ /**
46
+ * Language options provided for JSON files.
47
+ */
48
+ export interface JSONLanguageOptions extends LanguageOptions {
49
+ /**
50
+ * Whether to allow trailing commas. Only valid in JSONC.
51
+ */
52
+ allowTrailingCommas?: boolean;
53
+ }
54
+
55
+ /**
56
+ * The visitor format returned from rules in this package.
57
+ */
58
+ export interface JSONRuleVisitor extends RuleVisitor {
59
+ Document?(node: DocumentNode): void;
60
+ Member?(node: MemberNode, parent?: ObjectNode): void;
61
+ Element?(node: ElementNode, parent?: ArrayNode): void;
62
+ Object?(node: ObjectNode, parent?: ValueNodeParent): void;
63
+ Array?(node: ArrayNode, parent?: ValueNodeParent): void;
64
+ String?(node: StringNode, parent?: ValueNodeParent): void;
65
+ Null?(node: NullNode, parent?: ValueNodeParent): void;
66
+ Number?(node: NumberNode, parent?: ValueNodeParent): void;
67
+ Boolean?(node: BooleanNode, parent?: ValueNodeParent): void;
68
+ NaN?(node: NaNNode, parent?: ValueNodeParent): void;
69
+ Infinity?(node: InfinityNode, parent?: ValueNodeParent): void;
70
+ Identifier?(node: IdentifierNode, parent?: ValueNodeParent): void;
71
+
72
+ "Document:exit"?(node: DocumentNode): void;
73
+ "Member:exit"?(node: MemberNode, parent?: ObjectNode): void;
74
+ "Element:exit"?(node: ElementNode, parent?: ArrayNode): void;
75
+ "Object:exit"?(node: ObjectNode, parent?: ValueNodeParent): void;
76
+ "Array:exit"?(node: ArrayNode, parent?: ValueNodeParent): void;
77
+ "String:exit"?(node: StringNode, parent?: ValueNodeParent): void;
78
+ "Null:exit"?(node: NullNode, parent?: ValueNodeParent): void;
79
+ "Number:exit"?(node: NumberNode, parent?: ValueNodeParent): void;
80
+ "Boolean:exit"?(node: BooleanNode, parent?: ValueNodeParent): void;
81
+ "NaN:exit"?(node: NaNNode, parent?: ValueNodeParent): void;
82
+ "Infinity:exit"?(node: InfinityNode, parent?: ValueNodeParent): void;
83
+ "Identifier:exit"?(node: IdentifierNode, parent?: ValueNodeParent): void;
84
+ }
85
+
86
+ /**
87
+ * The `SourceCode` implementation for JSON files.
88
+ */
89
+ export interface IJSONSourceCode
90
+ extends TextSourceCode<{
91
+ LangOptions: JSONLanguageOptions;
92
+ RootNode: DocumentNode;
93
+ SyntaxElementWithLoc: JSONSyntaxElement;
94
+ ConfigNode: Token;
95
+ }> {
96
+ /**
97
+ * Get the text of a syntax element.
98
+ * @param syntaxElement The syntax element to get the text of.
99
+ * @param beforeCount The number of characters to include before the syntax element.
100
+ * @param afterCount The number of characters to include after the syntax element.
101
+ * @returns The text of the syntax element.
102
+ */
103
+ getText(
104
+ syntaxElement: JSONSyntaxElement,
105
+ beforeCount?: number,
106
+ afterCount?: number,
107
+ ): string;
108
+
109
+ /**
110
+ * Any comments found in a JSONC or JSON5 file.
111
+ */
112
+ comments: Array<Token> | undefined;
113
+
114
+ /**
115
+ * The lines of text found in the file.
116
+ */
117
+ lines: Array<string>;
118
+ }
119
+
120
+ export type IJSONLanguage = Language<{
121
+ LangOptions: JSONLanguageOptions;
122
+ Code: IJSONSourceCode;
123
+ RootNode: DocumentNode;
124
+ Node: AnyNode;
125
+ }>;
126
+
127
+ export type JSONRuleDefinition<
128
+ JSONRuleOptions extends unknown[],
129
+ JSONRuleMessageIds extends string = "",
130
+ > = RuleDefinition<{
131
+ LangOptions: JSONLanguageOptions;
132
+ Code: IJSONSourceCode;
133
+ RuleOptions: JSONRuleOptions;
134
+ Visitor: JSONRuleVisitor;
135
+ Node: AnyNode;
136
+ MessageIds: JSONRuleMessageIds;
137
+ ExtRuleDocs: {};
138
+ }>;
package/package.json CHANGED
@@ -1,19 +1,29 @@
1
1
  {
2
2
  "name": "@eslint/json",
3
- "version": "0.10.0",
3
+ "version": "0.11.0",
4
4
  "description": "JSON linting plugin for ESLint",
5
5
  "author": "Nicholas C. Zakas",
6
6
  "type": "module",
7
7
  "main": "dist/esm/index.js",
8
8
  "types": "dist/esm/index.d.ts",
9
9
  "exports": {
10
- "require": {
11
- "types": "./dist/cjs/index.d.cts",
12
- "default": "./dist/cjs/index.cjs"
10
+ ".": {
11
+ "require": {
12
+ "types": "./dist/cjs/index.d.cts",
13
+ "default": "./dist/cjs/index.cjs"
14
+ },
15
+ "import": {
16
+ "types": "./dist/esm/index.d.ts",
17
+ "default": "./dist/esm/index.js"
18
+ }
13
19
  },
14
- "import": {
15
- "types": "./dist/esm/index.d.ts",
16
- "default": "./dist/esm/index.js"
20
+ "./types": {
21
+ "require": {
22
+ "types": "./dist/cjs/types.cts"
23
+ },
24
+ "import": {
25
+ "types": "./dist/esm/types.d.ts"
26
+ }
17
27
  }
18
28
  },
19
29
  "files": [
@@ -42,7 +52,7 @@
42
52
  "homepage": "https://github.com/eslint/json#readme",
43
53
  "scripts": {
44
54
  "build:dedupe-types": "node tools/dedupe-types.js dist/cjs/index.cjs dist/esm/index.js",
45
- "build:cts": "node -e \"fs.copyFileSync('dist/esm/index.d.ts', 'dist/cjs/index.d.cts')\"",
55
+ "build:cts": "node tools/build-cts.js",
46
56
  "build": "rollup -c && npm run build:dedupe-types && tsc -p tsconfig.esm.json && npm run build:cts",
47
57
  "build:readme": "node tools/update-readme.js",
48
58
  "test:jsr": "npx jsr@latest publish --dry-run",
@@ -63,13 +73,12 @@
63
73
  ],
64
74
  "license": "Apache-2.0",
65
75
  "dependencies": {
66
- "@eslint/core": "^0.10.0",
67
- "@eslint/plugin-kit": "^0.2.5",
76
+ "@eslint/core": "^0.12.0",
77
+ "@eslint/plugin-kit": "^0.2.7",
68
78
  "@humanwhocodes/momoa": "^3.3.4",
69
79
  "natural-compare": "^1.4.0"
70
80
  },
71
81
  "devDependencies": {
72
- "@types/eslint": "^8.56.10",
73
82
  "c8": "^9.1.0",
74
83
  "dedent": "^1.5.3",
75
84
  "eslint": "^9.11.1",