@eslint/json 0.8.0 → 0.9.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 +16 -10
- package/dist/cjs/index.cjs +103 -2
- package/dist/cjs/index.d.cts +17 -0
- package/dist/esm/index.d.ts +17 -0
- package/dist/esm/index.js +103 -2
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -30,9 +30,9 @@ deno add @eslint/json
|
|
|
30
30
|
|
|
31
31
|
This package exports these languages:
|
|
32
32
|
|
|
33
|
-
-
|
|
34
|
-
-
|
|
35
|
-
-
|
|
33
|
+
- `"json/json"` is for regular JSON files
|
|
34
|
+
- `"json/jsonc"` is for JSON files that support comments ([JSONC](https://github.com/microsoft/node-jsonc-parser)) such as those used for Visual Studio Code configuration files
|
|
35
|
+
- `"json/json5"` is for [JSON5](https://json5.org) files
|
|
36
36
|
|
|
37
37
|
Depending on which types of JSON files you'd like to lint, you can set up your `eslint.config.js` file to include just the files you'd like. Here's an example that lints JSON, JSONC, and JSON5 files:
|
|
38
38
|
|
|
@@ -152,10 +152,16 @@ export default [
|
|
|
152
152
|
|
|
153
153
|
## Rules
|
|
154
154
|
|
|
155
|
-
-
|
|
156
|
-
-
|
|
157
|
-
-
|
|
158
|
-
|
|
155
|
+
- `no-duplicate-keys` - warns when there are two keys in an object with the same text.
|
|
156
|
+
- `no-empty-keys` - warns when there is a key in an object that is an empty string or contains only whitespace (note: `package-lock.json` uses empty keys intentionally)
|
|
157
|
+
- `no-unsafe-values` - warns on values that are unsafe for interchange, such
|
|
158
|
+
as strings with unmatched
|
|
159
|
+
[surrogates](https://en.wikipedia.org/wiki/UTF-16), numbers that evaluate to
|
|
160
|
+
Infinity, numbers that evaluate to zero unintentionally, numbers that look
|
|
161
|
+
like integers but are too large, and
|
|
162
|
+
[subnormal numbers](https://en.wikipedia.org/wiki/Subnormal_number).
|
|
163
|
+
- `no-unnormalized-keys` - warns on keys containing [unnormalized characters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize#description). You can optionally specify the normalization form via `{ form: "form_name" }`, where `form_name` can be any of `"NFC"`, `"NFD"`, `"NFKC"`, or `"NFKD"`.
|
|
164
|
+
- `top-level-interop` - warns when the top-level item in the document is neither an array nor an object. This can be enabled to ensure maximal interoperability with the oldest JSON parsers.
|
|
159
165
|
|
|
160
166
|
## Configuration Comments
|
|
161
167
|
|
|
@@ -222,8 +228,8 @@ export default [
|
|
|
222
228
|
|
|
223
229
|
This plugin implements JSON parsing for ESLint using the language plugins API, which is the official way of supporting non-JavaScript languages in ESLint. This differs from the other plugins:
|
|
224
230
|
|
|
225
|
-
-
|
|
226
|
-
-
|
|
231
|
+
- `eslint-plugin-json` uses a processor to parse the JSON, meaning it doesn't create an AST and you can't write custom rules for it.
|
|
232
|
+
- `eslint-plugin-jsonc` uses a parser that still goes through the JavaScript linting functionality and requires several rules to disallow valid JavaScript syntax that is invalid in JSON.
|
|
227
233
|
|
|
228
234
|
As such, this plugin is more robust and faster than the others. You can write your own custom rules when using the languages in this plugin, too.
|
|
229
235
|
|
|
@@ -251,7 +257,7 @@ to get your logo on our READMEs and [website](https://eslint.org/sponsors).
|
|
|
251
257
|
<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>
|
|
252
258
|
<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>
|
|
253
259
|
<p><a href="https://www.serptriumph.com/"><img src="https://images.opencollective.com/serp-triumph5/fea3074/logo.png" alt="SERP Triumph" height="64"></a> <a href="https://www.jetbrains.com/"><img src="https://images.opencollective.com/jetbrains/fe76f99/logo.png" alt="JetBrains" height="64"></a> <a href="https://liftoff.io/"><img src="https://images.opencollective.com/liftoff/5c4fa84/logo.png" alt="Liftoff" height="64"></a> <a href="https://americanexpress.io"><img src="https://avatars.githubusercontent.com/u/3853301?v=4" alt="American Express" height="64"></a> <a href="https://www.workleap.com"><img src="https://avatars.githubusercontent.com/u/53535748?u=d1e55d7661d724bf2281c1bfd33cb8f99fe2465f&v=4" alt="Workleap" height="64"></a></p><h3>Bronze Sponsors</h3>
|
|
254
|
-
<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://syntax.fm"><img src="https://github.com/syntaxfm.png" alt="Syntax" height="32"></a> <a href="https://www.wordhint.net/"><img src="https://images.opencollective.com/wordhint/be86813/avatar.png" alt="WordHint" 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?v=4" alt="GitBook" height="32"></a> <a href="https://nx.dev"><img src="https://avatars.githubusercontent.com/u/23692104?v=4" alt="Nx" height="32"></a> <a href="https://herocoders.com"><img src="https://avatars.githubusercontent.com/u/37549774?v=4" alt="HeroCoders" height="32"></a></p>
|
|
260
|
+
<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://syntax.fm"><img src="https://github.com/syntaxfm.png" alt="Syntax" height="32"></a> <a href="https://www.wordhint.net/"><img src="https://images.opencollective.com/wordhint/be86813/avatar.png" alt="WordHint" 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?v=4" alt="GitBook" height="32"></a> <a href="https://nx.dev"><img src="https://avatars.githubusercontent.com/u/23692104?v=4" alt="Nx" height="32"></a> <a href="https://opensource.mercedes-benz.com/"><img src="https://avatars.githubusercontent.com/u/34240465?v=4" alt="Mercedes-Benz Group" height="32"></a> <a href="https://herocoders.com"><img src="https://avatars.githubusercontent.com/u/37549774?v=4" alt="HeroCoders" height="32"></a></p>
|
|
255
261
|
<h3>Technology Sponsors</h3>
|
|
256
262
|
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.
|
|
257
263
|
<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
|
@@ -543,6 +543,12 @@ var noEmptyKeys = {
|
|
|
543
543
|
* @author Bradley Meck Farias
|
|
544
544
|
*/
|
|
545
545
|
|
|
546
|
+
// RFC 8259's `number` production, as a regex. Capture the integer part
|
|
547
|
+
// and the fractional part.
|
|
548
|
+
const NUMBER =
|
|
549
|
+
/^-?(?<int>0|([1-9][0-9]*))(?:\.(?<frac>[0-9]+))?(?:[eE][+-]?[0-9]+)?$/u;
|
|
550
|
+
const NON_ZERO = /[1-9]/u;
|
|
551
|
+
|
|
546
552
|
var noUnsafeValues = {
|
|
547
553
|
meta: {
|
|
548
554
|
type: /** @type {const} */ ("problem"),
|
|
@@ -552,7 +558,12 @@ var noUnsafeValues = {
|
|
|
552
558
|
},
|
|
553
559
|
|
|
554
560
|
messages: {
|
|
555
|
-
unsafeNumber: "
|
|
561
|
+
unsafeNumber: "The number '{{ value }}' will evaluate to Infinity.",
|
|
562
|
+
unsafeInteger:
|
|
563
|
+
"The integer '{{ value }}' is outside the safe integer range.",
|
|
564
|
+
unsafeZero: "The number '{{ value }}' will evaluate to zero.",
|
|
565
|
+
subnormal:
|
|
566
|
+
"Unexpected subnormal number '{{ value }}' found, which may cause interoperability issues.",
|
|
556
567
|
loneSurrogate: "Lone surrogate '{{ surrogate }}' found.",
|
|
557
568
|
},
|
|
558
569
|
},
|
|
@@ -560,11 +571,64 @@ var noUnsafeValues = {
|
|
|
560
571
|
create(context) {
|
|
561
572
|
return {
|
|
562
573
|
Number(node) {
|
|
574
|
+
const value = context.sourceCode.getText(node);
|
|
575
|
+
|
|
563
576
|
if (Number.isFinite(node.value) !== true) {
|
|
564
577
|
context.report({
|
|
565
578
|
loc: node.loc,
|
|
566
579
|
messageId: "unsafeNumber",
|
|
580
|
+
data: { value },
|
|
567
581
|
});
|
|
582
|
+
} else {
|
|
583
|
+
// Also matches -0, intentionally
|
|
584
|
+
if (node.value === 0) {
|
|
585
|
+
// If the value has been rounded down to 0, but there was some
|
|
586
|
+
// fraction or non-zero part before the e-, this is a very small
|
|
587
|
+
// number that doesn't fit inside an f64.
|
|
588
|
+
const match = value.match(NUMBER);
|
|
589
|
+
// assert(match, "If the regex is right, match is always truthy")
|
|
590
|
+
|
|
591
|
+
// If any part of the number other than the exponent has a
|
|
592
|
+
// non-zero digit in it, this number was not intended to be
|
|
593
|
+
// evaluated down to a zero.
|
|
594
|
+
if (
|
|
595
|
+
NON_ZERO.test(match.groups.int) ||
|
|
596
|
+
NON_ZERO.test(match.groups.frac)
|
|
597
|
+
) {
|
|
598
|
+
context.report({
|
|
599
|
+
loc: node.loc,
|
|
600
|
+
messageId: "unsafeZero",
|
|
601
|
+
data: { value },
|
|
602
|
+
});
|
|
603
|
+
}
|
|
604
|
+
} else if (!/[.e]/iu.test(value)) {
|
|
605
|
+
// Intended to be an integer
|
|
606
|
+
if (
|
|
607
|
+
node.value > Number.MAX_SAFE_INTEGER ||
|
|
608
|
+
node.value < Number.MIN_SAFE_INTEGER
|
|
609
|
+
) {
|
|
610
|
+
context.report({
|
|
611
|
+
loc: node.loc,
|
|
612
|
+
messageId: "unsafeInteger",
|
|
613
|
+
data: { value },
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
} else {
|
|
617
|
+
// Floating point. Check for subnormal.
|
|
618
|
+
const buffer = new ArrayBuffer(8);
|
|
619
|
+
const view = new DataView(buffer);
|
|
620
|
+
view.setFloat64(0, node.value, false);
|
|
621
|
+
const asBigInt = view.getBigUint64(0, false);
|
|
622
|
+
// Subnormals have an 11-bit exponent of 0 and a non-zero mantissa.
|
|
623
|
+
if ((asBigInt & 0x7ff0000000000000n) === 0n) {
|
|
624
|
+
context.report({
|
|
625
|
+
loc: node.loc,
|
|
626
|
+
messageId: "subnormal",
|
|
627
|
+
// Value included so that it's seen in scientific notation
|
|
628
|
+
data: node,
|
|
629
|
+
});
|
|
630
|
+
}
|
|
631
|
+
}
|
|
568
632
|
}
|
|
569
633
|
},
|
|
570
634
|
String(node) {
|
|
@@ -654,6 +718,42 @@ var noUnnormalizedKeys = {
|
|
|
654
718
|
},
|
|
655
719
|
};
|
|
656
720
|
|
|
721
|
+
/**
|
|
722
|
+
* @fileoverview Rule to ensure top-level items are either an array or ojbect.
|
|
723
|
+
* @author Joe Hildebrand
|
|
724
|
+
*/
|
|
725
|
+
|
|
726
|
+
var topLevelInterop = {
|
|
727
|
+
meta: {
|
|
728
|
+
type: /** @type {const} */ ("problem"),
|
|
729
|
+
|
|
730
|
+
docs: {
|
|
731
|
+
description:
|
|
732
|
+
"Require the JSON top-level value to be an array or object",
|
|
733
|
+
},
|
|
734
|
+
|
|
735
|
+
messages: {
|
|
736
|
+
topLevel:
|
|
737
|
+
"Top level item should be array or object, got '{{type}}'.",
|
|
738
|
+
},
|
|
739
|
+
},
|
|
740
|
+
|
|
741
|
+
create(context) {
|
|
742
|
+
return {
|
|
743
|
+
Document(node) {
|
|
744
|
+
const { type } = node.body;
|
|
745
|
+
if (type !== "Object" && type !== "Array") {
|
|
746
|
+
context.report({
|
|
747
|
+
loc: node.loc,
|
|
748
|
+
messageId: "topLevel",
|
|
749
|
+
data: { type },
|
|
750
|
+
});
|
|
751
|
+
}
|
|
752
|
+
},
|
|
753
|
+
};
|
|
754
|
+
},
|
|
755
|
+
};
|
|
756
|
+
|
|
657
757
|
/**
|
|
658
758
|
* @fileoverview JSON plugin.
|
|
659
759
|
* @author Nicholas C. Zakas
|
|
@@ -667,7 +767,7 @@ var noUnnormalizedKeys = {
|
|
|
667
767
|
const plugin = {
|
|
668
768
|
meta: {
|
|
669
769
|
name: "@eslint/json",
|
|
670
|
-
version: "0.
|
|
770
|
+
version: "0.9.0", // x-release-please-version
|
|
671
771
|
},
|
|
672
772
|
languages: {
|
|
673
773
|
json: new JSONLanguage({ mode: "json" }),
|
|
@@ -679,6 +779,7 @@ const plugin = {
|
|
|
679
779
|
"no-empty-keys": noEmptyKeys,
|
|
680
780
|
"no-unsafe-values": noUnsafeValues,
|
|
681
781
|
"no-unnormalized-keys": noUnnormalizedKeys,
|
|
782
|
+
"top-level-interop": topLevelInterop,
|
|
682
783
|
},
|
|
683
784
|
configs: {
|
|
684
785
|
recommended: {
|
package/dist/cjs/index.d.cts
CHANGED
|
@@ -210,6 +210,9 @@ declare namespace plugin {
|
|
|
210
210
|
};
|
|
211
211
|
messages: {
|
|
212
212
|
unsafeNumber: string;
|
|
213
|
+
unsafeInteger: string;
|
|
214
|
+
unsafeZero: string;
|
|
215
|
+
subnormal: string;
|
|
213
216
|
loneSurrogate: string;
|
|
214
217
|
};
|
|
215
218
|
};
|
|
@@ -241,6 +244,20 @@ declare namespace plugin {
|
|
|
241
244
|
Member(node: any): void;
|
|
242
245
|
};
|
|
243
246
|
};
|
|
247
|
+
"top-level-interop": {
|
|
248
|
+
meta: {
|
|
249
|
+
type: "problem";
|
|
250
|
+
docs: {
|
|
251
|
+
description: string;
|
|
252
|
+
};
|
|
253
|
+
messages: {
|
|
254
|
+
topLevel: string;
|
|
255
|
+
};
|
|
256
|
+
};
|
|
257
|
+
create(context: any): {
|
|
258
|
+
Document(node: any): void;
|
|
259
|
+
};
|
|
260
|
+
};
|
|
244
261
|
};
|
|
245
262
|
namespace configs {
|
|
246
263
|
namespace recommended {
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -210,6 +210,9 @@ declare namespace plugin {
|
|
|
210
210
|
};
|
|
211
211
|
messages: {
|
|
212
212
|
unsafeNumber: string;
|
|
213
|
+
unsafeInteger: string;
|
|
214
|
+
unsafeZero: string;
|
|
215
|
+
subnormal: string;
|
|
213
216
|
loneSurrogate: string;
|
|
214
217
|
};
|
|
215
218
|
};
|
|
@@ -241,6 +244,20 @@ declare namespace plugin {
|
|
|
241
244
|
Member(node: any): void;
|
|
242
245
|
};
|
|
243
246
|
};
|
|
247
|
+
"top-level-interop": {
|
|
248
|
+
meta: {
|
|
249
|
+
type: "problem";
|
|
250
|
+
docs: {
|
|
251
|
+
description: string;
|
|
252
|
+
};
|
|
253
|
+
messages: {
|
|
254
|
+
topLevel: string;
|
|
255
|
+
};
|
|
256
|
+
};
|
|
257
|
+
create(context: any): {
|
|
258
|
+
Document(node: any): void;
|
|
259
|
+
};
|
|
260
|
+
};
|
|
244
261
|
};
|
|
245
262
|
namespace configs {
|
|
246
263
|
namespace recommended {
|
package/dist/esm/index.js
CHANGED
|
@@ -540,6 +540,12 @@ var noEmptyKeys = {
|
|
|
540
540
|
* @author Bradley Meck Farias
|
|
541
541
|
*/
|
|
542
542
|
|
|
543
|
+
// RFC 8259's `number` production, as a regex. Capture the integer part
|
|
544
|
+
// and the fractional part.
|
|
545
|
+
const NUMBER =
|
|
546
|
+
/^-?(?<int>0|([1-9][0-9]*))(?:\.(?<frac>[0-9]+))?(?:[eE][+-]?[0-9]+)?$/u;
|
|
547
|
+
const NON_ZERO = /[1-9]/u;
|
|
548
|
+
|
|
543
549
|
var noUnsafeValues = {
|
|
544
550
|
meta: {
|
|
545
551
|
type: /** @type {const} */ ("problem"),
|
|
@@ -549,7 +555,12 @@ var noUnsafeValues = {
|
|
|
549
555
|
},
|
|
550
556
|
|
|
551
557
|
messages: {
|
|
552
|
-
unsafeNumber: "
|
|
558
|
+
unsafeNumber: "The number '{{ value }}' will evaluate to Infinity.",
|
|
559
|
+
unsafeInteger:
|
|
560
|
+
"The integer '{{ value }}' is outside the safe integer range.",
|
|
561
|
+
unsafeZero: "The number '{{ value }}' will evaluate to zero.",
|
|
562
|
+
subnormal:
|
|
563
|
+
"Unexpected subnormal number '{{ value }}' found, which may cause interoperability issues.",
|
|
553
564
|
loneSurrogate: "Lone surrogate '{{ surrogate }}' found.",
|
|
554
565
|
},
|
|
555
566
|
},
|
|
@@ -557,11 +568,64 @@ var noUnsafeValues = {
|
|
|
557
568
|
create(context) {
|
|
558
569
|
return {
|
|
559
570
|
Number(node) {
|
|
571
|
+
const value = context.sourceCode.getText(node);
|
|
572
|
+
|
|
560
573
|
if (Number.isFinite(node.value) !== true) {
|
|
561
574
|
context.report({
|
|
562
575
|
loc: node.loc,
|
|
563
576
|
messageId: "unsafeNumber",
|
|
577
|
+
data: { value },
|
|
564
578
|
});
|
|
579
|
+
} else {
|
|
580
|
+
// Also matches -0, intentionally
|
|
581
|
+
if (node.value === 0) {
|
|
582
|
+
// If the value has been rounded down to 0, but there was some
|
|
583
|
+
// fraction or non-zero part before the e-, this is a very small
|
|
584
|
+
// number that doesn't fit inside an f64.
|
|
585
|
+
const match = value.match(NUMBER);
|
|
586
|
+
// assert(match, "If the regex is right, match is always truthy")
|
|
587
|
+
|
|
588
|
+
// If any part of the number other than the exponent has a
|
|
589
|
+
// non-zero digit in it, this number was not intended to be
|
|
590
|
+
// evaluated down to a zero.
|
|
591
|
+
if (
|
|
592
|
+
NON_ZERO.test(match.groups.int) ||
|
|
593
|
+
NON_ZERO.test(match.groups.frac)
|
|
594
|
+
) {
|
|
595
|
+
context.report({
|
|
596
|
+
loc: node.loc,
|
|
597
|
+
messageId: "unsafeZero",
|
|
598
|
+
data: { value },
|
|
599
|
+
});
|
|
600
|
+
}
|
|
601
|
+
} else if (!/[.e]/iu.test(value)) {
|
|
602
|
+
// Intended to be an integer
|
|
603
|
+
if (
|
|
604
|
+
node.value > Number.MAX_SAFE_INTEGER ||
|
|
605
|
+
node.value < Number.MIN_SAFE_INTEGER
|
|
606
|
+
) {
|
|
607
|
+
context.report({
|
|
608
|
+
loc: node.loc,
|
|
609
|
+
messageId: "unsafeInteger",
|
|
610
|
+
data: { value },
|
|
611
|
+
});
|
|
612
|
+
}
|
|
613
|
+
} else {
|
|
614
|
+
// Floating point. Check for subnormal.
|
|
615
|
+
const buffer = new ArrayBuffer(8);
|
|
616
|
+
const view = new DataView(buffer);
|
|
617
|
+
view.setFloat64(0, node.value, false);
|
|
618
|
+
const asBigInt = view.getBigUint64(0, false);
|
|
619
|
+
// Subnormals have an 11-bit exponent of 0 and a non-zero mantissa.
|
|
620
|
+
if ((asBigInt & 0x7ff0000000000000n) === 0n) {
|
|
621
|
+
context.report({
|
|
622
|
+
loc: node.loc,
|
|
623
|
+
messageId: "subnormal",
|
|
624
|
+
// Value included so that it's seen in scientific notation
|
|
625
|
+
data: node,
|
|
626
|
+
});
|
|
627
|
+
}
|
|
628
|
+
}
|
|
565
629
|
}
|
|
566
630
|
},
|
|
567
631
|
String(node) {
|
|
@@ -651,6 +715,42 @@ var noUnnormalizedKeys = {
|
|
|
651
715
|
},
|
|
652
716
|
};
|
|
653
717
|
|
|
718
|
+
/**
|
|
719
|
+
* @fileoverview Rule to ensure top-level items are either an array or ojbect.
|
|
720
|
+
* @author Joe Hildebrand
|
|
721
|
+
*/
|
|
722
|
+
|
|
723
|
+
var topLevelInterop = {
|
|
724
|
+
meta: {
|
|
725
|
+
type: /** @type {const} */ ("problem"),
|
|
726
|
+
|
|
727
|
+
docs: {
|
|
728
|
+
description:
|
|
729
|
+
"Require the JSON top-level value to be an array or object",
|
|
730
|
+
},
|
|
731
|
+
|
|
732
|
+
messages: {
|
|
733
|
+
topLevel:
|
|
734
|
+
"Top level item should be array or object, got '{{type}}'.",
|
|
735
|
+
},
|
|
736
|
+
},
|
|
737
|
+
|
|
738
|
+
create(context) {
|
|
739
|
+
return {
|
|
740
|
+
Document(node) {
|
|
741
|
+
const { type } = node.body;
|
|
742
|
+
if (type !== "Object" && type !== "Array") {
|
|
743
|
+
context.report({
|
|
744
|
+
loc: node.loc,
|
|
745
|
+
messageId: "topLevel",
|
|
746
|
+
data: { type },
|
|
747
|
+
});
|
|
748
|
+
}
|
|
749
|
+
},
|
|
750
|
+
};
|
|
751
|
+
},
|
|
752
|
+
};
|
|
753
|
+
|
|
654
754
|
/**
|
|
655
755
|
* @fileoverview JSON plugin.
|
|
656
756
|
* @author Nicholas C. Zakas
|
|
@@ -664,7 +764,7 @@ var noUnnormalizedKeys = {
|
|
|
664
764
|
const plugin = {
|
|
665
765
|
meta: {
|
|
666
766
|
name: "@eslint/json",
|
|
667
|
-
version: "0.
|
|
767
|
+
version: "0.9.0", // x-release-please-version
|
|
668
768
|
},
|
|
669
769
|
languages: {
|
|
670
770
|
json: new JSONLanguage({ mode: "json" }),
|
|
@@ -676,6 +776,7 @@ const plugin = {
|
|
|
676
776
|
"no-empty-keys": noEmptyKeys,
|
|
677
777
|
"no-unsafe-values": noUnsafeValues,
|
|
678
778
|
"no-unnormalized-keys": noUnnormalizedKeys,
|
|
779
|
+
"top-level-interop": topLevelInterop,
|
|
679
780
|
},
|
|
680
781
|
configs: {
|
|
681
782
|
recommended: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eslint/json",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "JSON linting plugin for ESLint",
|
|
5
5
|
"author": "Nicholas C. Zakas",
|
|
6
6
|
"type": "module",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"license": "Apache-2.0",
|
|
65
65
|
"dependencies": {
|
|
66
66
|
"@eslint/plugin-kit": "^0.2.3",
|
|
67
|
-
"@humanwhocodes/momoa": "^3.3.
|
|
67
|
+
"@humanwhocodes/momoa": "^3.3.4"
|
|
68
68
|
},
|
|
69
69
|
"devDependencies": {
|
|
70
70
|
"@eslint/core": "^0.6.0",
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
"got": "^14.4.2",
|
|
78
78
|
"lint-staged": "^15.2.7",
|
|
79
79
|
"mocha": "^10.4.0",
|
|
80
|
-
"prettier": "^3.
|
|
80
|
+
"prettier": "^3.4.1",
|
|
81
81
|
"rollup": "^4.16.2",
|
|
82
82
|
"rollup-plugin-copy": "^3.5.0",
|
|
83
83
|
"typescript": "^5.4.5",
|