@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/dist/esm/index.js CHANGED
@@ -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
  // @ts-self-types="./index.d.ts"
2
8
  import { iterator, visitorKeys, parse } from '@humanwhocodes/momoa';
3
9
  import { ConfigCommentParser, TextSourceCodeBase, Directive, VisitNodeStep } from '@eslint/plugin-kit';
@@ -13,18 +19,8 @@ import naturalCompare from 'natural-compare';
13
19
  // Types
14
20
  //-----------------------------------------------------------------------------
15
21
 
16
- /** @typedef {import("@humanwhocodes/momoa").DocumentNode} DocumentNode */
17
- /** @typedef {import("@humanwhocodes/momoa").Node} JSONNode */
18
- /** @typedef {import("@humanwhocodes/momoa").Token} JSONToken */
19
- /** @typedef {import("@eslint/core").SourceRange} SourceRange */
20
- /** @typedef {import("@eslint/core").SourceLocation} SourceLocation */
21
- /** @typedef {import("@eslint/core").File} File */
22
- /** @typedef {import("@eslint/core").TraversalStep} TraversalStep */
23
- /** @typedef {import("@eslint/core").TextSourceCode} TextSourceCode */
24
- /** @typedef {import("@eslint/core").VisitTraversalStep} VisitTraversalStep */
25
- /** @typedef {import("@eslint/core").FileProblem} FileProblem */
26
- /** @typedef {import("@eslint/core").DirectiveType} DirectiveType */
27
- /** @typedef {import("@eslint/core").RulesConfig} RulesConfig */
22
+ /**
23
+ */
28
24
 
29
25
  //-----------------------------------------------------------------------------
30
26
  // Helpers
@@ -41,14 +37,14 @@ const INLINE_CONFIG =
41
37
  class JSONTraversalStep extends VisitNodeStep {
42
38
  /**
43
39
  * The target of the step.
44
- * @type {JSONNode}
40
+ * @type {Node}
45
41
  */
46
42
  target = undefined;
47
43
 
48
44
  /**
49
45
  * Creates a new instance.
50
46
  * @param {Object} options The options for the step.
51
- * @param {JSONNode} options.target The target of the step.
47
+ * @param {Node} options.target The target of the step.
52
48
  * @param {1|2} options.phase The phase of the step.
53
49
  * @param {Array<any>} options.args The arguments of the step.
54
50
  */
@@ -65,6 +61,7 @@ class JSONTraversalStep extends VisitNodeStep {
65
61
 
66
62
  /**
67
63
  * JSON Source Code Object
64
+ * @implements {TextSourceCode<{LangOptions: JSONLanguageOptions, RootNode: DocumentNode, SyntaxElementWithLoc: JSONSyntaxElement, ConfigNode: Token}>}
68
65
  */
69
66
  class JSONSourceCode extends TextSourceCodeBase {
70
67
  /**
@@ -75,13 +72,13 @@ class JSONSourceCode extends TextSourceCodeBase {
75
72
 
76
73
  /**
77
74
  * Cache of parent nodes.
78
- * @type {WeakMap<JSONNode, JSONNode>}
75
+ * @type {WeakMap<Node, Node>}
79
76
  */
80
77
  #parents = new WeakMap();
81
78
 
82
79
  /**
83
80
  * Collection of inline configuration comments.
84
- * @type {Array<JSONToken>}
81
+ * @type {Array<Token>}
85
82
  */
86
83
  #inlineConfigComments;
87
84
 
@@ -93,7 +90,7 @@ class JSONSourceCode extends TextSourceCodeBase {
93
90
 
94
91
  /**
95
92
  * The comment node in the source code.
96
- * @type {Array<JSONToken>|undefined}
93
+ * @type {Array<Token>|undefined}
97
94
  */
98
95
  comments;
99
96
 
@@ -113,7 +110,7 @@ class JSONSourceCode extends TextSourceCodeBase {
113
110
 
114
111
  /**
115
112
  * Returns the value of the given comment.
116
- * @param {JSONToken} comment The comment to get the value of.
113
+ * @param {Token} comment The comment to get the value of.
117
114
  * @returns {string} The value of the comment.
118
115
  * @throws {Error} When an unexpected comment type is passed.
119
116
  */
@@ -132,7 +129,7 @@ class JSONSourceCode extends TextSourceCodeBase {
132
129
  /**
133
130
  * Returns an array of all inline configuration nodes found in the
134
131
  * source code.
135
- * @returns {Array<JSONToken>} An array of all inline configuration nodes.
132
+ * @returns {Array<Token>} An array of all inline configuration nodes.
136
133
  */
137
134
  getInlineConfigNodes() {
138
135
  if (!this.#inlineConfigComments) {
@@ -141,7 +138,7 @@ class JSONSourceCode extends TextSourceCodeBase {
141
138
  );
142
139
  }
143
140
 
144
- return this.#inlineConfigComments;
141
+ return this.#inlineConfigComments ?? [];
145
142
  }
146
143
 
147
144
  /**
@@ -243,8 +240,8 @@ class JSONSourceCode extends TextSourceCodeBase {
243
240
 
244
241
  /**
245
242
  * Returns the parent of the given node.
246
- * @param {JSONNode} node The node to get the parent of.
247
- * @returns {JSONNode|undefined} The parent of the node.
243
+ * @param {Node} node The node to get the parent of.
244
+ * @returns {Node|undefined} The parent of the node.
248
245
  */
249
246
  getParent(node) {
250
247
  return this.#parents.get(node);
@@ -291,12 +288,13 @@ class JSONSourceCode extends TextSourceCodeBase {
291
288
  // Types
292
289
  //-----------------------------------------------------------------------------
293
290
 
294
- /** @typedef {import("@eslint/core").Language} Language */
295
- /** @typedef {import("@eslint/core").OkParseResult<DocumentNode>} OkParseResult */
296
- /** @typedef {import("@eslint/core").ParseResult<DocumentNode>} ParseResult */
297
291
  /**
292
+ *
293
+ * @typedef {OkParseResult<DocumentNode>} JSONOkParseResult
294
+ * @typedef {ParseResult<DocumentNode>} JSONParseResult
295
+ *
298
296
  * @typedef {Object} JSONLanguageOptions
299
- * @property {boolean} [allowTrailingCommas] Whether to allow trailing commas.
297
+ * @property {boolean} [allowTrailingCommas] Whether to allow trailing commas in JSONC mode.
300
298
  */
301
299
 
302
300
  //-----------------------------------------------------------------------------
@@ -305,7 +303,7 @@ class JSONSourceCode extends TextSourceCodeBase {
305
303
 
306
304
  /**
307
305
  * JSON Language Object
308
- * @implements {Language}
306
+ * @implements {Language<{ LangOptions: JSONLanguageOptions; Code: JSONSourceCode; RootNode: DocumentNode; Node: AnyNode }>}
309
307
  */
310
308
  class JSONLanguage {
311
309
  /**
@@ -382,7 +380,7 @@ class JSONLanguage {
382
380
  * Parses the given file into an AST.
383
381
  * @param {File} file The virtual file to parse.
384
382
  * @param {{languageOptions: JSONLanguageOptions}} context The options to use for parsing.
385
- * @returns {ParseResult} The result of parsing.
383
+ * @returns {JSONParseResult} The result of parsing.
386
384
  */
387
385
  parse(file, context) {
388
386
  // Note: BOM already removed
@@ -430,7 +428,7 @@ class JSONLanguage {
430
428
  /**
431
429
  * Creates a new `JSONSourceCode` object from the given information.
432
430
  * @param {File} file The virtual file to create a `JSONSourceCode` object from.
433
- * @param {OkParseResult} parseResult The result returned from `parse()`.
431
+ * @param {JSONOkParseResult} parseResult The result returned from `parse()`.
434
432
  * @returns {JSONSourceCode} The new `JSONSourceCode` object.
435
433
  */
436
434
  createSourceCode(file, parseResult) {
@@ -447,13 +445,24 @@ class JSONLanguage {
447
445
  * @author Nicholas C. Zakas
448
446
  */
449
447
 
448
+ //-----------------------------------------------------------------------------
449
+ // Type Definitions
450
+ //-----------------------------------------------------------------------------
451
+
452
+ /**
453
+ *
454
+ * @typedef {"duplicateKey"} NoDuplicateKeysMessageIds
455
+ * @typedef {JSONRuleDefinition<{ MessageIds: NoDuplicateKeysMessageIds }>} NoDuplicateKeysRuleDefinition
456
+ */
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,24 @@ var noDuplicateKeys = {
504
516
  * @author Nicholas C. Zakas
505
517
  */
506
518
 
507
- var noEmptyKeys = {
519
+ //-----------------------------------------------------------------------------
520
+ // Type Definitions
521
+ //-----------------------------------------------------------------------------
522
+
523
+ /**
524
+ *
525
+ * @typedef {"emptyKey"} NoEmptyKeysMessageIds
526
+ * @typedef {JSONRuleDefinition<{ MessageIds: NoEmptyKeysMessageIds }>} NoEmptyKeysRuleDefinition
527
+ */
528
+
529
+ //-----------------------------------------------------------------------------
530
+ // Rule Definition
531
+ //-----------------------------------------------------------------------------
532
+
533
+ /** @type {NoEmptyKeysRuleDefinition} */
534
+ const rule$4 = {
508
535
  meta: {
509
- type: /** @type {const} */ ("problem"),
536
+ type: "problem",
510
537
 
511
538
  docs: {
512
539
  description: "Disallow empty keys in JSON objects",
@@ -541,15 +568,39 @@ var noEmptyKeys = {
541
568
  * @author Bradley Meck Farias
542
569
  */
543
570
 
544
- // RFC 8259's `number` production, as a regex. Capture the integer part
545
- // and the fractional part.
571
+ //-----------------------------------------------------------------------------
572
+ // Type Definitions
573
+ //-----------------------------------------------------------------------------
574
+
575
+ /**
576
+ *
577
+ * @typedef {"unsafeNumber"|"unsafeInteger"|"unsafeZero"|"subnormal"|"loneSurrogate"} NoUnsafeValuesMessageIds
578
+ * @typedef {JSONRuleDefinition<{ MessageIds: NoUnsafeValuesMessageIds }>} NoUnsafeValuesRuleDefinition
579
+ */
580
+
581
+ //-----------------------------------------------------------------------------
582
+ // Helpers
583
+ //-----------------------------------------------------------------------------
584
+
585
+ /*
586
+ * This rule is based on the JSON grammar from RFC 8259, section 6.
587
+ * https://tools.ietf.org/html/rfc8259#section-6
588
+ *
589
+ * We separately capture the integer and fractional parts of a number, so that
590
+ * we can check for unsafe numbers that will evaluate to Infinity.
591
+ */
546
592
  const NUMBER =
547
593
  /^-?(?<int>0|([1-9][0-9]*))(?:\.(?<frac>[0-9]+))?(?:[eE][+-]?[0-9]+)?$/u;
548
594
  const NON_ZERO = /[1-9]/u;
549
595
 
550
- var noUnsafeValues = {
596
+ //-----------------------------------------------------------------------------
597
+ // Rule Definition
598
+ //-----------------------------------------------------------------------------
599
+
600
+ /** @type {NoUnsafeValuesRuleDefinition} */
601
+ const rule$3 = {
551
602
  meta: {
552
- type: /** @type {const} */ ("problem"),
603
+ type: "problem",
553
604
 
554
605
  docs: {
555
606
  description: "Disallow JSON values that are unsafe for interchange",
@@ -623,7 +674,9 @@ var noUnsafeValues = {
623
674
  loc: node.loc,
624
675
  messageId: "subnormal",
625
676
  // Value included so that it's seen in scientific notation
626
- data: node,
677
+ data: {
678
+ value,
679
+ },
627
680
  });
628
681
  }
629
682
  }
@@ -666,9 +719,25 @@ var noUnsafeValues = {
666
719
  * @author Bradley Meck Farias
667
720
  */
668
721
 
669
- var noUnnormalizedKeys = {
722
+ //-----------------------------------------------------------------------------
723
+ // Type Definitions
724
+ //-----------------------------------------------------------------------------
725
+
726
+ /**
727
+ *
728
+ * @typedef {"unnormalizedKey"} NoUnnormalizedKeysMessageIds
729
+ * @typedef {{ form: string }} NoUnnormalizedKeysOptions
730
+ * @typedef {JSONRuleDefinition<{ RuleOptions: [NoUnnormalizedKeysOptions], MessageIds: NoUnnormalizedKeysMessageIds }>} NoUnnormalizedKeysRuleDefinition
731
+ */
732
+
733
+ //-----------------------------------------------------------------------------
734
+ // Rule Definition
735
+ //-----------------------------------------------------------------------------
736
+
737
+ /** @type {NoUnnormalizedKeysRuleDefinition} */
738
+ const rule$2 = {
670
739
  meta: {
671
- type: /** @type {const} */ ("problem"),
740
+ type: "problem",
672
741
 
673
742
  docs: {
674
743
  description: "Disallow JSON keys that are not normalized",
@@ -692,9 +761,10 @@ var noUnnormalizedKeys = {
692
761
  },
693
762
 
694
763
  create(context) {
695
- const normalization = context.options.length
696
- ? text => text.normalize(context.options[0].form)
697
- : text => text.normalize();
764
+ const form = context.options.length
765
+ ? context.options[0].form
766
+ : undefined;
767
+
698
768
  return {
699
769
  Member(node) {
700
770
  const key =
@@ -702,7 +772,7 @@ var noUnnormalizedKeys = {
702
772
  ? node.name.value
703
773
  : node.name.name;
704
774
 
705
- if (normalization(key) !== key) {
775
+ if (key.normalize(form) !== key) {
706
776
  context.report({
707
777
  loc: node.name.loc,
708
778
  messageId: "unnormalizedKey",
@@ -717,49 +787,95 @@ var noUnnormalizedKeys = {
717
787
  };
718
788
 
719
789
  /**
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
790
+ * @fileoverview Rule to require JSON object keys to be sorted.
791
+ * Copied largely from https://github.com/eslint/eslint/blob/main/lib/rules/sort-keys.js
721
792
  * @author Robin Thomas
722
793
  */
723
794
 
724
795
 
796
+ //-----------------------------------------------------------------------------
797
+ // Type Definitions
798
+ //-----------------------------------------------------------------------------
799
+
800
+ /**
801
+ *
802
+ * @typedef {Object} SortOptions
803
+ * @property {boolean} caseSensitive
804
+ * @property {boolean} natural
805
+ * @property {number} minKeys
806
+ * @property {boolean} allowLineSeparatedGroups
807
+ *
808
+ * @typedef {"sortKeys"} SortKeysMessageIds
809
+ * @typedef {"asc"|"desc"} SortDirection
810
+ * @typedef {[SortDirection, SortOptions]} SortKeysRuleOptions
811
+ * @typedef {JSONRuleDefinition<{ RuleOptions: SortKeysRuleOptions, MessageIds: SortKeysMessageIds }>} SortKeysRuleDefinition
812
+ * @typedef {(a:string,b:string) => boolean} Comparator
813
+ */
814
+
815
+ //-----------------------------------------------------------------------------
816
+ // Helpers
817
+ //-----------------------------------------------------------------------------
818
+
725
819
  const hasNonWhitespace = /\S/u;
726
820
 
727
821
  const comparators = {
728
822
  ascending: {
729
823
  alphanumeric: {
824
+ /** @type {Comparator} */
730
825
  sensitive: (a, b) => a <= b,
826
+
827
+ /** @type {Comparator} */
731
828
  insensitive: (a, b) => a.toLowerCase() <= b.toLowerCase(),
732
829
  },
733
830
  natural: {
831
+ /** @type {Comparator} */
734
832
  sensitive: (a, b) => naturalCompare(a, b) <= 0,
833
+
834
+ /** @type {Comparator} */
735
835
  insensitive: (a, b) =>
736
836
  naturalCompare(a.toLowerCase(), b.toLowerCase()) <= 0,
737
837
  },
738
838
  },
739
839
  descending: {
740
840
  alphanumeric: {
841
+ /** @type {Comparator} */
741
842
  sensitive: (a, b) =>
742
843
  comparators.ascending.alphanumeric.sensitive(b, a),
844
+
845
+ /** @type {Comparator} */
743
846
  insensitive: (a, b) =>
744
847
  comparators.ascending.alphanumeric.insensitive(b, a),
745
848
  },
746
849
  natural: {
850
+ /** @type {Comparator} */
747
851
  sensitive: (a, b) => comparators.ascending.natural.sensitive(b, a),
852
+
853
+ /** @type {Comparator} */
748
854
  insensitive: (a, b) =>
749
855
  comparators.ascending.natural.insensitive(b, a),
750
856
  },
751
857
  },
752
858
  };
753
859
 
860
+ /**
861
+ * Gets the MemberNode's string key value.
862
+ * @param {MemberNode} member
863
+ * @return {string}
864
+ */
754
865
  function getKey(member) {
755
- return member.name.type === `Identifier`
866
+ return member.name.type === "Identifier"
756
867
  ? member.name.name
757
868
  : member.name.value;
758
869
  }
759
870
 
760
- var sortKeys = {
871
+ //-----------------------------------------------------------------------------
872
+ // Rule Definition
873
+ //-----------------------------------------------------------------------------
874
+
875
+ /** @type {SortKeysRuleDefinition} */
876
+ const rule$1 = {
761
877
  meta: {
762
- type: /** @type {const} */ ("suggestion"),
878
+ type: "suggestion",
763
879
 
764
880
  defaultOptions: [
765
881
  "asc",
@@ -829,8 +945,14 @@ var sortKeys = {
829
945
  }
830
946
  }
831
947
 
832
- // Note that there can be comments *inside* members, e.g. `{"foo: /* comment *\/ "bar"}`, but these are ignored when calculating line-separated groups
948
+ /**
949
+ * Checks if two members are line-separated.
950
+ * @param {MemberNode} prevMember The previous member.
951
+ * @param {MemberNode} member The current member.
952
+ * @return {boolean}
953
+ */
833
954
  function isLineSeparated(prevMember, member) {
955
+ // Note that there can be comments *inside* members, e.g. `{"foo: /* comment *\/ "bar"}`, but these are ignored when calculating line-separated groups
834
956
  const prevMemberEndLine = prevMember.loc.end.line;
835
957
  const thisStartLine = member.loc.start.line;
836
958
  if (thisStartLine - prevMemberEndLine < 2) {
@@ -899,9 +1021,24 @@ var sortKeys = {
899
1021
  * @author Joe Hildebrand
900
1022
  */
901
1023
 
902
- var topLevelInterop = {
1024
+ //-----------------------------------------------------------------------------
1025
+ // Type Definitions
1026
+ //-----------------------------------------------------------------------------
1027
+
1028
+ /**
1029
+ *
1030
+ * @typedef {"topLevel"} TopLevelInteropMessageIds
1031
+ * @typedef {JSONRuleDefinition<{ MessageIds: TopLevelInteropMessageIds }>} TopLevelInteropRuleDefinition
1032
+ */
1033
+
1034
+ //-----------------------------------------------------------------------------
1035
+ // Rule Definition
1036
+ //-----------------------------------------------------------------------------
1037
+
1038
+ /** @type {TopLevelInteropRuleDefinition} */
1039
+ const rule = {
903
1040
  meta: {
904
- type: /** @type {const} */ ("problem"),
1041
+ type: "problem",
905
1042
 
906
1043
  docs: {
907
1044
  description:
@@ -943,7 +1080,7 @@ var topLevelInterop = {
943
1080
  const plugin = {
944
1081
  meta: {
945
1082
  name: "@eslint/json",
946
- version: "0.10.0", // x-release-please-version
1083
+ version: "0.12.0", // x-release-please-version
947
1084
  },
948
1085
  languages: {
949
1086
  json: new JSONLanguage({ mode: "json" }),
@@ -951,12 +1088,12 @@ const plugin = {
951
1088
  json5: new JSONLanguage({ mode: "json5" }),
952
1089
  },
953
1090
  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,
1091
+ "no-duplicate-keys": rule$5,
1092
+ "no-empty-keys": rule$4,
1093
+ "no-unsafe-values": rule$3,
1094
+ "no-unnormalized-keys": rule$2,
1095
+ "sort-keys": rule$1,
1096
+ "top-level-interop": rule,
960
1097
  },
961
1098
  configs: {
962
1099
  recommended: {
@@ -0,0 +1,53 @@
1
+ /**
2
+ * @fileoverview Additional types for this package.
3
+ * @author Nicholas C. Zakas
4
+ */
5
+ import type { RuleVisitor, RuleDefinition } from "@eslint/core";
6
+ import type { DocumentNode, MemberNode, ElementNode, ObjectNode, ArrayNode, StringNode, NullNode, NumberNode, BooleanNode, NaNNode, InfinityNode, IdentifierNode, AnyNode, Token } from "@humanwhocodes/momoa";
7
+ import type { JSONLanguageOptions, JSONSourceCode } from "./index.js";
8
+ type ValueNodeParent = DocumentNode | MemberNode | ElementNode;
9
+ /**
10
+ * A JSON syntax element, including nodes and tokens.
11
+ */
12
+ export type JSONSyntaxElement = Token | AnyNode;
13
+ /**
14
+ * The visitor format returned from rules in this package.
15
+ */
16
+ export interface JSONRuleVisitor extends RuleVisitor {
17
+ Document?(node: DocumentNode): void;
18
+ Member?(node: MemberNode, parent?: ObjectNode): void;
19
+ Element?(node: ElementNode, parent?: ArrayNode): void;
20
+ Object?(node: ObjectNode, parent?: ValueNodeParent): void;
21
+ Array?(node: ArrayNode, parent?: ValueNodeParent): void;
22
+ String?(node: StringNode, parent?: ValueNodeParent): void;
23
+ Null?(node: NullNode, parent?: ValueNodeParent): void;
24
+ Number?(node: NumberNode, parent?: ValueNodeParent): void;
25
+ Boolean?(node: BooleanNode, parent?: ValueNodeParent): void;
26
+ NaN?(node: NaNNode, parent?: ValueNodeParent): void;
27
+ Infinity?(node: InfinityNode, parent?: ValueNodeParent): void;
28
+ Identifier?(node: IdentifierNode, parent?: ValueNodeParent): void;
29
+ "Document:exit"?(node: DocumentNode): void;
30
+ "Member:exit"?(node: MemberNode, parent?: ObjectNode): void;
31
+ "Element:exit"?(node: ElementNode, parent?: ArrayNode): void;
32
+ "Object:exit"?(node: ObjectNode, parent?: ValueNodeParent): void;
33
+ "Array:exit"?(node: ArrayNode, parent?: ValueNodeParent): void;
34
+ "String:exit"?(node: StringNode, parent?: ValueNodeParent): void;
35
+ "Null:exit"?(node: NullNode, parent?: ValueNodeParent): void;
36
+ "Number:exit"?(node: NumberNode, parent?: ValueNodeParent): void;
37
+ "Boolean:exit"?(node: BooleanNode, parent?: ValueNodeParent): void;
38
+ "NaN:exit"?(node: NaNNode, parent?: ValueNodeParent): void;
39
+ "Infinity:exit"?(node: InfinityNode, parent?: ValueNodeParent): void;
40
+ "Identifier:exit"?(node: IdentifierNode, parent?: ValueNodeParent): void;
41
+ }
42
+ export type JSONRuleDefinitionTypeOptions = {
43
+ RuleOptions: unknown[];
44
+ MessageIds: string;
45
+ ExtRuleDocs: Record<string, unknown>;
46
+ };
47
+ export type JSONRuleDefinition<Options extends Partial<JSONRuleDefinitionTypeOptions> = {}> = RuleDefinition<{
48
+ LangOptions: JSONLanguageOptions;
49
+ Code: JSONSourceCode;
50
+ Visitor: JSONRuleVisitor;
51
+ Node: AnyNode;
52
+ } & Required<Options & Omit<JSONRuleDefinitionTypeOptions, keyof Options>>>;
53
+ export {};
@@ -0,0 +1,92 @@
1
+ /**
2
+ * @fileoverview Additional types for this package.
3
+ * @author Nicholas C. Zakas
4
+ */
5
+
6
+ //------------------------------------------------------------------------------
7
+ // Imports
8
+ //------------------------------------------------------------------------------
9
+
10
+ import type { RuleVisitor, RuleDefinition } from "@eslint/core";
11
+ import type {
12
+ DocumentNode,
13
+ MemberNode,
14
+ ElementNode,
15
+ ObjectNode,
16
+ ArrayNode,
17
+ StringNode,
18
+ NullNode,
19
+ NumberNode,
20
+ BooleanNode,
21
+ NaNNode,
22
+ InfinityNode,
23
+ IdentifierNode,
24
+ AnyNode,
25
+ Token,
26
+ } from "@humanwhocodes/momoa";
27
+ import type { JSONLanguageOptions, JSONSourceCode } from "./index.js";
28
+
29
+ //------------------------------------------------------------------------------
30
+ // Types
31
+ //------------------------------------------------------------------------------
32
+
33
+ type ValueNodeParent = DocumentNode | MemberNode | ElementNode;
34
+
35
+ /**
36
+ * A JSON syntax element, including nodes and tokens.
37
+ */
38
+ export type JSONSyntaxElement = Token | AnyNode;
39
+
40
+ /**
41
+ * The visitor format returned from rules in this package.
42
+ */
43
+ export interface JSONRuleVisitor extends RuleVisitor {
44
+ Document?(node: DocumentNode): void;
45
+ Member?(node: MemberNode, parent?: ObjectNode): void;
46
+ Element?(node: ElementNode, parent?: ArrayNode): void;
47
+ Object?(node: ObjectNode, parent?: ValueNodeParent): void;
48
+ Array?(node: ArrayNode, parent?: ValueNodeParent): void;
49
+ String?(node: StringNode, parent?: ValueNodeParent): void;
50
+ Null?(node: NullNode, parent?: ValueNodeParent): void;
51
+ Number?(node: NumberNode, parent?: ValueNodeParent): void;
52
+ Boolean?(node: BooleanNode, parent?: ValueNodeParent): void;
53
+ NaN?(node: NaNNode, parent?: ValueNodeParent): void;
54
+ Infinity?(node: InfinityNode, parent?: ValueNodeParent): void;
55
+ Identifier?(node: IdentifierNode, parent?: ValueNodeParent): void;
56
+
57
+ "Document:exit"?(node: DocumentNode): void;
58
+ "Member:exit"?(node: MemberNode, parent?: ObjectNode): void;
59
+ "Element:exit"?(node: ElementNode, parent?: ArrayNode): void;
60
+ "Object:exit"?(node: ObjectNode, parent?: ValueNodeParent): void;
61
+ "Array:exit"?(node: ArrayNode, parent?: ValueNodeParent): void;
62
+ "String:exit"?(node: StringNode, parent?: ValueNodeParent): void;
63
+ "Null:exit"?(node: NullNode, parent?: ValueNodeParent): void;
64
+ "Number:exit"?(node: NumberNode, parent?: ValueNodeParent): void;
65
+ "Boolean:exit"?(node: BooleanNode, parent?: ValueNodeParent): void;
66
+ "NaN:exit"?(node: NaNNode, parent?: ValueNodeParent): void;
67
+ "Infinity:exit"?(node: InfinityNode, parent?: ValueNodeParent): void;
68
+ "Identifier:exit"?(node: IdentifierNode, parent?: ValueNodeParent): void;
69
+ }
70
+
71
+ export type JSONRuleDefinitionTypeOptions = {
72
+ RuleOptions: unknown[];
73
+ MessageIds: string;
74
+ ExtRuleDocs: Record<string, unknown>;
75
+ };
76
+
77
+ export type JSONRuleDefinition<
78
+ Options extends Partial<JSONRuleDefinitionTypeOptions> = {},
79
+ > = RuleDefinition<
80
+ // Language specific type options (non-configurable)
81
+ {
82
+ LangOptions: JSONLanguageOptions;
83
+ Code: JSONSourceCode;
84
+ Visitor: JSONRuleVisitor;
85
+ Node: AnyNode;
86
+ } & Required<
87
+ // Rule specific type options (custom)
88
+ Options &
89
+ // Rule specific type options (defaults)
90
+ Omit<JSONRuleDefinitionTypeOptions, keyof Options>
91
+ >
92
+ >;