@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 +5 -4
- package/dist/cjs/index.cjs +195 -58
- package/dist/cjs/index.d.cts +82 -168
- package/dist/cjs/types.cts +92 -0
- package/dist/esm/index.d.ts +82 -168
- package/dist/esm/index.js +195 -58
- package/dist/esm/types.d.ts +53 -0
- package/dist/esm/types.ts +92 -0
- package/package.json +22 -12
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
|
-
/**
|
|
17
|
-
|
|
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 {
|
|
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 {
|
|
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<
|
|
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<
|
|
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<
|
|
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 {
|
|
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<
|
|
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 {
|
|
247
|
-
* @returns {
|
|
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 {
|
|
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 {
|
|
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
|
-
|
|
462
|
+
/** @type {NoDuplicateKeysRuleDefinition} */
|
|
463
|
+
const rule$5 = {
|
|
455
464
|
meta: {
|
|
456
|
-
type:
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
545
|
-
//
|
|
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
|
-
|
|
596
|
+
//-----------------------------------------------------------------------------
|
|
597
|
+
// Rule Definition
|
|
598
|
+
//-----------------------------------------------------------------------------
|
|
599
|
+
|
|
600
|
+
/** @type {NoUnsafeValuesRuleDefinition} */
|
|
601
|
+
const rule$3 = {
|
|
551
602
|
meta: {
|
|
552
|
-
type:
|
|
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:
|
|
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
|
-
|
|
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:
|
|
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
|
|
696
|
-
?
|
|
697
|
-
:
|
|
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 (
|
|
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.
|
|
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 ===
|
|
866
|
+
return member.name.type === "Identifier"
|
|
756
867
|
? member.name.name
|
|
757
868
|
: member.name.value;
|
|
758
869
|
}
|
|
759
870
|
|
|
760
|
-
|
|
871
|
+
//-----------------------------------------------------------------------------
|
|
872
|
+
// Rule Definition
|
|
873
|
+
//-----------------------------------------------------------------------------
|
|
874
|
+
|
|
875
|
+
/** @type {SortKeysRuleDefinition} */
|
|
876
|
+
const rule$1 = {
|
|
761
877
|
meta: {
|
|
762
|
-
type:
|
|
878
|
+
type: "suggestion",
|
|
763
879
|
|
|
764
880
|
defaultOptions: [
|
|
765
881
|
"asc",
|
|
@@ -829,8 +945,14 @@ var sortKeys = {
|
|
|
829
945
|
}
|
|
830
946
|
}
|
|
831
947
|
|
|
832
|
-
|
|
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
|
-
|
|
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:
|
|
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.
|
|
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":
|
|
955
|
-
"no-empty-keys":
|
|
956
|
-
"no-unsafe-values":
|
|
957
|
-
"no-unnormalized-keys":
|
|
958
|
-
"sort-keys":
|
|
959
|
-
"top-level-interop":
|
|
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
|
+
>;
|