@eslint/json 0.5.0 → 0.7.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 +44 -5
- package/dist/cjs/index.cjs +90 -6
- package/dist/cjs/index.d.cts +32 -3
- package/dist/esm/index.d.ts +32 -3
- package/dist/esm/index.js +90 -6
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -154,6 +154,7 @@ export default [
|
|
|
154
154
|
|
|
155
155
|
- `no-duplicate-keys` - warns when there are two keys in an object with the same text.
|
|
156
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 as numbers outside safe range or lone surrogates.
|
|
157
158
|
|
|
158
159
|
## Configuration Comments
|
|
159
160
|
|
|
@@ -185,6 +186,35 @@ In JSONC and JSON5 files, you can also use [rule configurations comments](https:
|
|
|
185
186
|
|
|
186
187
|
Both line and block comments can be used for all kinds of configuration comments.
|
|
187
188
|
|
|
189
|
+
## Allowing trailing commas in JSONC
|
|
190
|
+
|
|
191
|
+
The Microsoft implementation of JSONC optionally allows for trailing commas in objects and arrays (files like `tsconfig.json` have this option enabled by default in Visual Studio Code). To enable trailing commas in JSONC files, use the `allowTrailingCommas` language option, as in this example:
|
|
192
|
+
|
|
193
|
+
```js
|
|
194
|
+
import json from "@eslint/json";
|
|
195
|
+
|
|
196
|
+
export default [
|
|
197
|
+
// lint JSONC files
|
|
198
|
+
{
|
|
199
|
+
files: ["**/*.jsonc"],
|
|
200
|
+
language: "json/jsonc",
|
|
201
|
+
...json.configs.recommended,
|
|
202
|
+
},
|
|
203
|
+
|
|
204
|
+
// lint JSONC files and allow trailing commas
|
|
205
|
+
{
|
|
206
|
+
files: ["**/tsconfig.json", ".vscode/*.json"],
|
|
207
|
+
language: "json/jsonc",
|
|
208
|
+
languageOptions: {
|
|
209
|
+
allowTrailingCommas: true,
|
|
210
|
+
},
|
|
211
|
+
...json.configs.recommended,
|
|
212
|
+
},
|
|
213
|
+
];
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
**Note:** The `allowTrailingCommas` option is only valid for the `json/jsonc` language.
|
|
217
|
+
|
|
188
218
|
## Frequently Asked Questions
|
|
189
219
|
|
|
190
220
|
### How does this relate to `eslint-plugin-json` and `eslint-plugin-jsonc`?
|
|
@@ -208,11 +238,20 @@ Any other rules that catch potential problems in JSON are welcome to be implemen
|
|
|
208
238
|
|
|
209
239
|
Apache 2.0
|
|
210
240
|
|
|
211
|
-
## Sponsors
|
|
212
|
-
|
|
213
241
|
<!-- NOTE: This section is autogenerated. Do not manually edit.-->
|
|
214
242
|
<!--sponsorsstart-->
|
|
215
|
-
<!--sponsorsend-->
|
|
216
243
|
|
|
217
|
-
|
|
218
|
-
|
|
244
|
+
## Sponsors
|
|
245
|
+
|
|
246
|
+
The following companies, organizations, and individuals support ESLint's ongoing maintenance and development. [Become a Sponsor](https://eslint.org/donate)
|
|
247
|
+
to get your logo on our READMEs and [website](https://eslint.org/sponsors).
|
|
248
|
+
|
|
249
|
+
<h3>Platinum Sponsors</h3>
|
|
250
|
+
<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>
|
|
251
|
+
<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>
|
|
252
|
+
<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>
|
|
253
|
+
<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>
|
|
254
|
+
<h3>Technology Sponsors</h3>
|
|
255
|
+
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.
|
|
256
|
+
<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>
|
|
257
|
+
<!--sponsorsend-->
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -296,6 +296,10 @@ class JSONSourceCode extends pluginKit.TextSourceCodeBase {
|
|
|
296
296
|
/** @typedef {import("@eslint/core").Language} Language */
|
|
297
297
|
/** @typedef {import("@eslint/core").OkParseResult<DocumentNode>} OkParseResult */
|
|
298
298
|
/** @typedef {import("@eslint/core").ParseResult<DocumentNode>} ParseResult */
|
|
299
|
+
/**
|
|
300
|
+
* @typedef {Object} JSONLanguageOptions
|
|
301
|
+
* @property {boolean} [allowTrailingCommas] Whether to allow trailing commas.
|
|
302
|
+
*/
|
|
299
303
|
|
|
300
304
|
//-----------------------------------------------------------------------------
|
|
301
305
|
// Exports
|
|
@@ -351,26 +355,42 @@ class JSONLanguage {
|
|
|
351
355
|
this.#mode = mode;
|
|
352
356
|
}
|
|
353
357
|
|
|
354
|
-
/* eslint-disable class-methods-use-this, no-unused-vars -- Required to complete interface. */
|
|
355
358
|
/**
|
|
356
359
|
* Validates the language options.
|
|
357
|
-
* @param {
|
|
360
|
+
* @param {JSONLanguageOptions} languageOptions The language options to validate.
|
|
358
361
|
* @returns {void}
|
|
359
362
|
* @throws {Error} When the language options are invalid.
|
|
360
363
|
*/
|
|
361
364
|
validateLanguageOptions(languageOptions) {
|
|
362
|
-
|
|
365
|
+
if (languageOptions.allowTrailingCommas !== undefined) {
|
|
366
|
+
if (typeof languageOptions.allowTrailingCommas !== "boolean") {
|
|
367
|
+
throw new Error(
|
|
368
|
+
"allowTrailingCommas must be a boolean if provided.",
|
|
369
|
+
);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// we know that allowTrailingCommas is a boolean here
|
|
373
|
+
|
|
374
|
+
// only allowed in JSONC mode
|
|
375
|
+
if (this.#mode !== "jsonc") {
|
|
376
|
+
throw new Error(
|
|
377
|
+
"allowTrailingCommas option is only available in JSONC.",
|
|
378
|
+
);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
363
381
|
}
|
|
364
|
-
/* eslint-enable class-methods-use-this, no-unused-vars -- Required to complete interface. */
|
|
365
382
|
|
|
366
383
|
/**
|
|
367
384
|
* Parses the given file into an AST.
|
|
368
385
|
* @param {File} file The virtual file to parse.
|
|
386
|
+
* @param {{languageOptions: JSONLanguageOptions}} context The options to use for parsing.
|
|
369
387
|
* @returns {ParseResult} The result of parsing.
|
|
370
388
|
*/
|
|
371
|
-
parse(file) {
|
|
389
|
+
parse(file, context) {
|
|
372
390
|
// Note: BOM already removed
|
|
373
391
|
const text = /** @type {string} */ (file.body);
|
|
392
|
+
const allowTrailingCommas =
|
|
393
|
+
context?.languageOptions?.allowTrailingCommas;
|
|
374
394
|
|
|
375
395
|
/*
|
|
376
396
|
* Check for parsing errors first. If there's a parsing error, nothing
|
|
@@ -383,6 +403,7 @@ class JSONLanguage {
|
|
|
383
403
|
mode: this.#mode,
|
|
384
404
|
ranges: true,
|
|
385
405
|
tokens: true,
|
|
406
|
+
allowTrailingCommas,
|
|
386
407
|
});
|
|
387
408
|
|
|
388
409
|
return {
|
|
@@ -517,6 +538,67 @@ var noEmptyKeys = {
|
|
|
517
538
|
},
|
|
518
539
|
};
|
|
519
540
|
|
|
541
|
+
/**
|
|
542
|
+
* @fileoverview Rule to detect unsafe values in JSON.
|
|
543
|
+
* @author Bradley Meck Farias
|
|
544
|
+
*/
|
|
545
|
+
|
|
546
|
+
var noUnsafeValues = {
|
|
547
|
+
meta: {
|
|
548
|
+
type: "problem",
|
|
549
|
+
|
|
550
|
+
docs: {
|
|
551
|
+
description: "Disallow JSON values that are unsafe for interchange",
|
|
552
|
+
},
|
|
553
|
+
|
|
554
|
+
messages: {
|
|
555
|
+
unsafeNumber: "Number outside safe range found.",
|
|
556
|
+
loneSurrogate: "Lone surrogate '{{ surrogate }}' found.",
|
|
557
|
+
},
|
|
558
|
+
},
|
|
559
|
+
|
|
560
|
+
create(context) {
|
|
561
|
+
return {
|
|
562
|
+
Number(node) {
|
|
563
|
+
if (Number.isFinite(node.value) !== true) {
|
|
564
|
+
context.report({
|
|
565
|
+
loc: node.loc,
|
|
566
|
+
messageId: "unsafeNumber",
|
|
567
|
+
});
|
|
568
|
+
}
|
|
569
|
+
},
|
|
570
|
+
String(node) {
|
|
571
|
+
if (node.value.isWellFormed) {
|
|
572
|
+
if (node.value.isWellFormed()) {
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
// match any high surrogate and, if it exists, a paired low surrogate
|
|
577
|
+
// match any low surrogate not already matched
|
|
578
|
+
const surrogatePattern =
|
|
579
|
+
/[\uD800-\uDBFF][\uDC00-\uDFFF]?|[\uDC00-\uDFFF]/gu;
|
|
580
|
+
let match = surrogatePattern.exec(node.value);
|
|
581
|
+
while (match) {
|
|
582
|
+
// only need to report non-paired surrogates
|
|
583
|
+
if (match[0].length < 2) {
|
|
584
|
+
context.report({
|
|
585
|
+
loc: node.loc,
|
|
586
|
+
messageId: "loneSurrogate",
|
|
587
|
+
data: {
|
|
588
|
+
surrogate: JSON.stringify(match[0]).slice(
|
|
589
|
+
1,
|
|
590
|
+
-1,
|
|
591
|
+
),
|
|
592
|
+
},
|
|
593
|
+
});
|
|
594
|
+
}
|
|
595
|
+
match = surrogatePattern.exec(node.value);
|
|
596
|
+
}
|
|
597
|
+
},
|
|
598
|
+
};
|
|
599
|
+
},
|
|
600
|
+
};
|
|
601
|
+
|
|
520
602
|
/**
|
|
521
603
|
* @fileoverview JSON plugin.
|
|
522
604
|
* @author Nicholas C. Zakas
|
|
@@ -530,7 +612,7 @@ var noEmptyKeys = {
|
|
|
530
612
|
const plugin = {
|
|
531
613
|
meta: {
|
|
532
614
|
name: "@eslint/json",
|
|
533
|
-
version: "0.
|
|
615
|
+
version: "0.7.0", // x-release-please-version
|
|
534
616
|
},
|
|
535
617
|
languages: {
|
|
536
618
|
json: new JSONLanguage({ mode: "json" }),
|
|
@@ -540,6 +622,7 @@ const plugin = {
|
|
|
540
622
|
rules: {
|
|
541
623
|
"no-duplicate-keys": noDuplicateKeys,
|
|
542
624
|
"no-empty-keys": noEmptyKeys,
|
|
625
|
+
"no-unsafe-values": noUnsafeValues,
|
|
543
626
|
},
|
|
544
627
|
configs: {},
|
|
545
628
|
};
|
|
@@ -550,6 +633,7 @@ Object.assign(plugin.configs, {
|
|
|
550
633
|
rules: {
|
|
551
634
|
"json/no-duplicate-keys": "error",
|
|
552
635
|
"json/no-empty-keys": "error",
|
|
636
|
+
"json/no-unsafe-values": "error",
|
|
553
637
|
},
|
|
554
638
|
},
|
|
555
639
|
});
|
package/dist/cjs/index.d.cts
CHANGED
|
@@ -13,6 +13,12 @@ export type RulesConfig = import("@eslint/core").RulesConfig;
|
|
|
13
13
|
export type Language = import("@eslint/core").Language;
|
|
14
14
|
export type OkParseResult = import("@eslint/core").OkParseResult<DocumentNode>;
|
|
15
15
|
export type ParseResult = import("@eslint/core").ParseResult<DocumentNode>;
|
|
16
|
+
export type JSONLanguageOptions = {
|
|
17
|
+
/**
|
|
18
|
+
* Whether to allow trailing commas.
|
|
19
|
+
*/
|
|
20
|
+
allowTrailingCommas?: boolean;
|
|
21
|
+
};
|
|
16
22
|
/**
|
|
17
23
|
* @filedescription Functions to fix up rules to provide missing methods on the `context` object.
|
|
18
24
|
* @author Nicholas C. Zakas
|
|
@@ -20,6 +26,10 @@ export type ParseResult = import("@eslint/core").ParseResult<DocumentNode>;
|
|
|
20
26
|
/** @typedef {import("@eslint/core").Language} Language */
|
|
21
27
|
/** @typedef {import("@eslint/core").OkParseResult<DocumentNode>} OkParseResult */
|
|
22
28
|
/** @typedef {import("@eslint/core").ParseResult<DocumentNode>} ParseResult */
|
|
29
|
+
/**
|
|
30
|
+
* @typedef {Object} JSONLanguageOptions
|
|
31
|
+
* @property {boolean} [allowTrailingCommas] Whether to allow trailing commas.
|
|
32
|
+
*/
|
|
23
33
|
/**
|
|
24
34
|
* JSON Language Object
|
|
25
35
|
* @implements {Language}
|
|
@@ -60,17 +70,20 @@ export class JSONLanguage implements Language {
|
|
|
60
70
|
visitorKeys: Record<string, string[]>;
|
|
61
71
|
/**
|
|
62
72
|
* Validates the language options.
|
|
63
|
-
* @param {
|
|
73
|
+
* @param {JSONLanguageOptions} languageOptions The language options to validate.
|
|
64
74
|
* @returns {void}
|
|
65
75
|
* @throws {Error} When the language options are invalid.
|
|
66
76
|
*/
|
|
67
|
-
validateLanguageOptions(languageOptions:
|
|
77
|
+
validateLanguageOptions(languageOptions: JSONLanguageOptions): void;
|
|
68
78
|
/**
|
|
69
79
|
* Parses the given file into an AST.
|
|
70
80
|
* @param {File} file The virtual file to parse.
|
|
81
|
+
* @param {{languageOptions: JSONLanguageOptions}} context The options to use for parsing.
|
|
71
82
|
* @returns {ParseResult} The result of parsing.
|
|
72
83
|
*/
|
|
73
|
-
parse(file: File
|
|
84
|
+
parse(file: File, context: {
|
|
85
|
+
languageOptions: JSONLanguageOptions;
|
|
86
|
+
}): ParseResult;
|
|
74
87
|
/**
|
|
75
88
|
* Creates a new `JSONSourceCode` object from the given information.
|
|
76
89
|
* @param {File} file The virtual file to create a `JSONSourceCode` object from.
|
|
@@ -189,6 +202,22 @@ declare namespace plugin {
|
|
|
189
202
|
Member(node: any): void;
|
|
190
203
|
};
|
|
191
204
|
};
|
|
205
|
+
"no-unsafe-values": {
|
|
206
|
+
meta: {
|
|
207
|
+
type: string;
|
|
208
|
+
docs: {
|
|
209
|
+
description: string;
|
|
210
|
+
};
|
|
211
|
+
messages: {
|
|
212
|
+
unsafeNumber: string;
|
|
213
|
+
loneSurrogate: string;
|
|
214
|
+
};
|
|
215
|
+
};
|
|
216
|
+
create(context: any): {
|
|
217
|
+
Number(node: any): void;
|
|
218
|
+
String(node: any): void;
|
|
219
|
+
};
|
|
220
|
+
};
|
|
192
221
|
};
|
|
193
222
|
let configs: {};
|
|
194
223
|
}
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -13,6 +13,12 @@ export type RulesConfig = import("@eslint/core").RulesConfig;
|
|
|
13
13
|
export type Language = import("@eslint/core").Language;
|
|
14
14
|
export type OkParseResult = import("@eslint/core").OkParseResult<DocumentNode>;
|
|
15
15
|
export type ParseResult = import("@eslint/core").ParseResult<DocumentNode>;
|
|
16
|
+
export type JSONLanguageOptions = {
|
|
17
|
+
/**
|
|
18
|
+
* Whether to allow trailing commas.
|
|
19
|
+
*/
|
|
20
|
+
allowTrailingCommas?: boolean;
|
|
21
|
+
};
|
|
16
22
|
/**
|
|
17
23
|
* @filedescription Functions to fix up rules to provide missing methods on the `context` object.
|
|
18
24
|
* @author Nicholas C. Zakas
|
|
@@ -20,6 +26,10 @@ export type ParseResult = import("@eslint/core").ParseResult<DocumentNode>;
|
|
|
20
26
|
/** @typedef {import("@eslint/core").Language} Language */
|
|
21
27
|
/** @typedef {import("@eslint/core").OkParseResult<DocumentNode>} OkParseResult */
|
|
22
28
|
/** @typedef {import("@eslint/core").ParseResult<DocumentNode>} ParseResult */
|
|
29
|
+
/**
|
|
30
|
+
* @typedef {Object} JSONLanguageOptions
|
|
31
|
+
* @property {boolean} [allowTrailingCommas] Whether to allow trailing commas.
|
|
32
|
+
*/
|
|
23
33
|
/**
|
|
24
34
|
* JSON Language Object
|
|
25
35
|
* @implements {Language}
|
|
@@ -60,17 +70,20 @@ export class JSONLanguage implements Language {
|
|
|
60
70
|
visitorKeys: Record<string, string[]>;
|
|
61
71
|
/**
|
|
62
72
|
* Validates the language options.
|
|
63
|
-
* @param {
|
|
73
|
+
* @param {JSONLanguageOptions} languageOptions The language options to validate.
|
|
64
74
|
* @returns {void}
|
|
65
75
|
* @throws {Error} When the language options are invalid.
|
|
66
76
|
*/
|
|
67
|
-
validateLanguageOptions(languageOptions:
|
|
77
|
+
validateLanguageOptions(languageOptions: JSONLanguageOptions): void;
|
|
68
78
|
/**
|
|
69
79
|
* Parses the given file into an AST.
|
|
70
80
|
* @param {File} file The virtual file to parse.
|
|
81
|
+
* @param {{languageOptions: JSONLanguageOptions}} context The options to use for parsing.
|
|
71
82
|
* @returns {ParseResult} The result of parsing.
|
|
72
83
|
*/
|
|
73
|
-
parse(file: File
|
|
84
|
+
parse(file: File, context: {
|
|
85
|
+
languageOptions: JSONLanguageOptions;
|
|
86
|
+
}): ParseResult;
|
|
74
87
|
/**
|
|
75
88
|
* Creates a new `JSONSourceCode` object from the given information.
|
|
76
89
|
* @param {File} file The virtual file to create a `JSONSourceCode` object from.
|
|
@@ -189,6 +202,22 @@ declare namespace plugin {
|
|
|
189
202
|
Member(node: any): void;
|
|
190
203
|
};
|
|
191
204
|
};
|
|
205
|
+
"no-unsafe-values": {
|
|
206
|
+
meta: {
|
|
207
|
+
type: string;
|
|
208
|
+
docs: {
|
|
209
|
+
description: string;
|
|
210
|
+
};
|
|
211
|
+
messages: {
|
|
212
|
+
unsafeNumber: string;
|
|
213
|
+
loneSurrogate: string;
|
|
214
|
+
};
|
|
215
|
+
};
|
|
216
|
+
create(context: any): {
|
|
217
|
+
Number(node: any): void;
|
|
218
|
+
String(node: any): void;
|
|
219
|
+
};
|
|
220
|
+
};
|
|
192
221
|
};
|
|
193
222
|
let configs: {};
|
|
194
223
|
}
|
package/dist/esm/index.js
CHANGED
|
@@ -293,6 +293,10 @@ class JSONSourceCode extends TextSourceCodeBase {
|
|
|
293
293
|
/** @typedef {import("@eslint/core").Language} Language */
|
|
294
294
|
/** @typedef {import("@eslint/core").OkParseResult<DocumentNode>} OkParseResult */
|
|
295
295
|
/** @typedef {import("@eslint/core").ParseResult<DocumentNode>} ParseResult */
|
|
296
|
+
/**
|
|
297
|
+
* @typedef {Object} JSONLanguageOptions
|
|
298
|
+
* @property {boolean} [allowTrailingCommas] Whether to allow trailing commas.
|
|
299
|
+
*/
|
|
296
300
|
|
|
297
301
|
//-----------------------------------------------------------------------------
|
|
298
302
|
// Exports
|
|
@@ -348,26 +352,42 @@ class JSONLanguage {
|
|
|
348
352
|
this.#mode = mode;
|
|
349
353
|
}
|
|
350
354
|
|
|
351
|
-
/* eslint-disable class-methods-use-this, no-unused-vars -- Required to complete interface. */
|
|
352
355
|
/**
|
|
353
356
|
* Validates the language options.
|
|
354
|
-
* @param {
|
|
357
|
+
* @param {JSONLanguageOptions} languageOptions The language options to validate.
|
|
355
358
|
* @returns {void}
|
|
356
359
|
* @throws {Error} When the language options are invalid.
|
|
357
360
|
*/
|
|
358
361
|
validateLanguageOptions(languageOptions) {
|
|
359
|
-
|
|
362
|
+
if (languageOptions.allowTrailingCommas !== undefined) {
|
|
363
|
+
if (typeof languageOptions.allowTrailingCommas !== "boolean") {
|
|
364
|
+
throw new Error(
|
|
365
|
+
"allowTrailingCommas must be a boolean if provided.",
|
|
366
|
+
);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
// we know that allowTrailingCommas is a boolean here
|
|
370
|
+
|
|
371
|
+
// only allowed in JSONC mode
|
|
372
|
+
if (this.#mode !== "jsonc") {
|
|
373
|
+
throw new Error(
|
|
374
|
+
"allowTrailingCommas option is only available in JSONC.",
|
|
375
|
+
);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
360
378
|
}
|
|
361
|
-
/* eslint-enable class-methods-use-this, no-unused-vars -- Required to complete interface. */
|
|
362
379
|
|
|
363
380
|
/**
|
|
364
381
|
* Parses the given file into an AST.
|
|
365
382
|
* @param {File} file The virtual file to parse.
|
|
383
|
+
* @param {{languageOptions: JSONLanguageOptions}} context The options to use for parsing.
|
|
366
384
|
* @returns {ParseResult} The result of parsing.
|
|
367
385
|
*/
|
|
368
|
-
parse(file) {
|
|
386
|
+
parse(file, context) {
|
|
369
387
|
// Note: BOM already removed
|
|
370
388
|
const text = /** @type {string} */ (file.body);
|
|
389
|
+
const allowTrailingCommas =
|
|
390
|
+
context?.languageOptions?.allowTrailingCommas;
|
|
371
391
|
|
|
372
392
|
/*
|
|
373
393
|
* Check for parsing errors first. If there's a parsing error, nothing
|
|
@@ -380,6 +400,7 @@ class JSONLanguage {
|
|
|
380
400
|
mode: this.#mode,
|
|
381
401
|
ranges: true,
|
|
382
402
|
tokens: true,
|
|
403
|
+
allowTrailingCommas,
|
|
383
404
|
});
|
|
384
405
|
|
|
385
406
|
return {
|
|
@@ -514,6 +535,67 @@ var noEmptyKeys = {
|
|
|
514
535
|
},
|
|
515
536
|
};
|
|
516
537
|
|
|
538
|
+
/**
|
|
539
|
+
* @fileoverview Rule to detect unsafe values in JSON.
|
|
540
|
+
* @author Bradley Meck Farias
|
|
541
|
+
*/
|
|
542
|
+
|
|
543
|
+
var noUnsafeValues = {
|
|
544
|
+
meta: {
|
|
545
|
+
type: "problem",
|
|
546
|
+
|
|
547
|
+
docs: {
|
|
548
|
+
description: "Disallow JSON values that are unsafe for interchange",
|
|
549
|
+
},
|
|
550
|
+
|
|
551
|
+
messages: {
|
|
552
|
+
unsafeNumber: "Number outside safe range found.",
|
|
553
|
+
loneSurrogate: "Lone surrogate '{{ surrogate }}' found.",
|
|
554
|
+
},
|
|
555
|
+
},
|
|
556
|
+
|
|
557
|
+
create(context) {
|
|
558
|
+
return {
|
|
559
|
+
Number(node) {
|
|
560
|
+
if (Number.isFinite(node.value) !== true) {
|
|
561
|
+
context.report({
|
|
562
|
+
loc: node.loc,
|
|
563
|
+
messageId: "unsafeNumber",
|
|
564
|
+
});
|
|
565
|
+
}
|
|
566
|
+
},
|
|
567
|
+
String(node) {
|
|
568
|
+
if (node.value.isWellFormed) {
|
|
569
|
+
if (node.value.isWellFormed()) {
|
|
570
|
+
return;
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
// match any high surrogate and, if it exists, a paired low surrogate
|
|
574
|
+
// match any low surrogate not already matched
|
|
575
|
+
const surrogatePattern =
|
|
576
|
+
/[\uD800-\uDBFF][\uDC00-\uDFFF]?|[\uDC00-\uDFFF]/gu;
|
|
577
|
+
let match = surrogatePattern.exec(node.value);
|
|
578
|
+
while (match) {
|
|
579
|
+
// only need to report non-paired surrogates
|
|
580
|
+
if (match[0].length < 2) {
|
|
581
|
+
context.report({
|
|
582
|
+
loc: node.loc,
|
|
583
|
+
messageId: "loneSurrogate",
|
|
584
|
+
data: {
|
|
585
|
+
surrogate: JSON.stringify(match[0]).slice(
|
|
586
|
+
1,
|
|
587
|
+
-1,
|
|
588
|
+
),
|
|
589
|
+
},
|
|
590
|
+
});
|
|
591
|
+
}
|
|
592
|
+
match = surrogatePattern.exec(node.value);
|
|
593
|
+
}
|
|
594
|
+
},
|
|
595
|
+
};
|
|
596
|
+
},
|
|
597
|
+
};
|
|
598
|
+
|
|
517
599
|
/**
|
|
518
600
|
* @fileoverview JSON plugin.
|
|
519
601
|
* @author Nicholas C. Zakas
|
|
@@ -527,7 +609,7 @@ var noEmptyKeys = {
|
|
|
527
609
|
const plugin = {
|
|
528
610
|
meta: {
|
|
529
611
|
name: "@eslint/json",
|
|
530
|
-
version: "0.
|
|
612
|
+
version: "0.7.0", // x-release-please-version
|
|
531
613
|
},
|
|
532
614
|
languages: {
|
|
533
615
|
json: new JSONLanguage({ mode: "json" }),
|
|
@@ -537,6 +619,7 @@ const plugin = {
|
|
|
537
619
|
rules: {
|
|
538
620
|
"no-duplicate-keys": noDuplicateKeys,
|
|
539
621
|
"no-empty-keys": noEmptyKeys,
|
|
622
|
+
"no-unsafe-values": noUnsafeValues,
|
|
540
623
|
},
|
|
541
624
|
configs: {},
|
|
542
625
|
};
|
|
@@ -547,6 +630,7 @@ Object.assign(plugin.configs, {
|
|
|
547
630
|
rules: {
|
|
548
631
|
"json/no-duplicate-keys": "error",
|
|
549
632
|
"json/no-empty-keys": "error",
|
|
633
|
+
"json/no-unsafe-values": "error",
|
|
550
634
|
},
|
|
551
635
|
},
|
|
552
636
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eslint/json",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "JSON linting plugin for ESLint",
|
|
5
5
|
"author": "Nicholas C. Zakas",
|
|
6
6
|
"type": "module",
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
"build:dedupe-types": "node tools/dedupe-types.js dist/cjs/index.cjs dist/esm/index.js",
|
|
45
45
|
"build:cts": "node -e \"fs.copyFileSync('dist/esm/index.d.ts', 'dist/cjs/index.d.cts')\"",
|
|
46
46
|
"build": "rollup -c && npm run build:dedupe-types && tsc -p tsconfig.esm.json && npm run build:cts",
|
|
47
|
+
"build:readme": "node tools/update-readme.js",
|
|
47
48
|
"test:jsr": "npx jsr@latest publish --dry-run",
|
|
48
49
|
"pretest": "npm run build",
|
|
49
50
|
"lint": "eslint",
|
|
@@ -61,8 +62,8 @@
|
|
|
61
62
|
],
|
|
62
63
|
"license": "Apache-2.0",
|
|
63
64
|
"dependencies": {
|
|
64
|
-
"@eslint/plugin-kit": "^0.2.
|
|
65
|
-
"@humanwhocodes/momoa": "^3.
|
|
65
|
+
"@eslint/plugin-kit": "^0.2.3",
|
|
66
|
+
"@humanwhocodes/momoa": "^3.3.3"
|
|
66
67
|
},
|
|
67
68
|
"devDependencies": {
|
|
68
69
|
"@eslint/core": "^0.6.0",
|
|
@@ -71,6 +72,7 @@
|
|
|
71
72
|
"dedent": "^1.5.3",
|
|
72
73
|
"eslint": "^9.11.1",
|
|
73
74
|
"eslint-config-eslint": "^11.0.0",
|
|
75
|
+
"got": "^14.4.2",
|
|
74
76
|
"lint-staged": "^15.2.7",
|
|
75
77
|
"mocha": "^10.4.0",
|
|
76
78
|
"prettier": "^3.3.2",
|