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