@eslint/json 2.0.1 → 2.1.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 +14 -2
- package/dist/build/recommended-config.d.ts +1 -1
- package/dist/build/rules.d.ts +30 -6
- package/dist/build/rules.js +6 -6
- package/dist/index.d.ts +177 -25
- package/dist/index.js +1 -1
- package/dist/languages/json-language.d.ts +26 -26
- package/dist/languages/json-language.js +1 -2
- package/dist/languages/json-source-code.d.ts +42 -40
- package/dist/languages/json-source-code.js +1 -2
- package/dist/rules/no-duplicate-keys.d.ts +29 -5
- package/dist/rules/no-duplicate-keys.js +5 -7
- package/dist/rules/no-empty-keys.d.ts +29 -5
- package/dist/rules/no-empty-keys.js +5 -7
- package/dist/rules/no-unnormalized-keys.d.ts +42 -5
- package/dist/rules/no-unnormalized-keys.js +5 -7
- package/dist/rules/no-unsafe-values.d.ts +32 -4
- package/dist/rules/no-unsafe-values.js +8 -9
- package/dist/rules/sort-keys.d.ts +61 -4
- package/dist/rules/sort-keys.js +5 -7
- package/dist/rules/top-level-interop.d.ts +29 -9
- package/dist/rules/top-level-interop.js +5 -7
- package/dist/types.d.ts +12 -2
- package/dist/util.d.ts +4 -4
- package/package.json +9 -6
package/README.md
CHANGED
|
@@ -8,7 +8,19 @@ This package contains a plugin that allows you to natively lint JSON, JSONC, and
|
|
|
8
8
|
|
|
9
9
|
## Installation
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
You can install ESLint using npm or other package managers:
|
|
12
|
+
|
|
13
|
+
```shell
|
|
14
|
+
npm install eslint -D
|
|
15
|
+
# or
|
|
16
|
+
yarn add eslint -D
|
|
17
|
+
# or
|
|
18
|
+
pnpm install eslint -D
|
|
19
|
+
# or
|
|
20
|
+
bun add eslint -D
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Then, for Node.js and compatible runtimes:
|
|
12
24
|
|
|
13
25
|
```shell
|
|
14
26
|
npm install @eslint/json -D
|
|
@@ -296,7 +308,7 @@ to get your logo on our READMEs and [website](https://eslint.org/sponsors).
|
|
|
296
308
|
<p><a href="https://automattic.com"><img src="https://images.opencollective.com/automattic/d0ef3e1/logo.png" alt="Automattic" height="128"></a></p><h3>Gold Sponsors</h3>
|
|
297
309
|
<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://shopify.engineering/"><img src="https://avatars.githubusercontent.com/u/8085" alt="Shopify" height="96"></a> <a href="https://www.coderabbit.ai/?utm_source=cr_org&utm_medium=github"><img src="https://avatars.githubusercontent.com/u/132028505" alt="CodeRabbit" height="96"></a></p><h3>Silver Sponsors</h3>
|
|
298
310
|
<p><a href="https://vite.dev/"><img src="https://images.opencollective.com/vite/d472863/logo.png" alt="Vite" height="64"></a> <a href="https://liftoff.io/"><img src="https://images.opencollective.com/liftoff/2d6c3b6/logo.png" alt="Liftoff" 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>
|
|
299
|
-
<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://opensource.sap.com"><img src="https://avatars.githubusercontent.com/u/2531208" alt="SAP" height="32"></a> <a href="https://
|
|
311
|
+
<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://opensource.sap.com"><img src="https://avatars.githubusercontent.com/u/2531208" alt="SAP" 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://citadel-ai.com"><img src="https://avatars.githubusercontent.com/u/75781367" alt="Citadel AI" height="32"></a> <a href="https://www.testmuai.com"><img src="https://avatars.githubusercontent.com/u/171592363" alt="TestMu AI Open Source Office (Formerly LambdaTest)" height="32"></a></p>
|
|
300
312
|
<h3>Technology Sponsors</h3>
|
|
301
313
|
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.
|
|
302
314
|
<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/build/rules.d.ts
CHANGED
|
@@ -1,9 +1,33 @@
|
|
|
1
|
+
import rule0 from "../rules/no-duplicate-keys.js";
|
|
2
|
+
import rule1 from "../rules/no-empty-keys.js";
|
|
3
|
+
import rule2 from "../rules/no-unnormalized-keys.js";
|
|
4
|
+
import rule3 from "../rules/no-unsafe-values.js";
|
|
5
|
+
import rule4 from "../rules/sort-keys.js";
|
|
6
|
+
import rule5 from "../rules/top-level-interop.js";
|
|
1
7
|
declare const _default: {
|
|
2
|
-
"no-duplicate-keys":
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
"
|
|
7
|
-
|
|
8
|
+
"no-duplicate-keys": {
|
|
9
|
+
meta: typeof rule0.meta;
|
|
10
|
+
create: (context: unknown) => any;
|
|
11
|
+
};
|
|
12
|
+
"no-empty-keys": {
|
|
13
|
+
meta: typeof rule1.meta;
|
|
14
|
+
create: (context: unknown) => any;
|
|
15
|
+
};
|
|
16
|
+
"no-unnormalized-keys": {
|
|
17
|
+
meta: typeof rule2.meta;
|
|
18
|
+
create: (context: unknown) => any;
|
|
19
|
+
};
|
|
20
|
+
"no-unsafe-values": {
|
|
21
|
+
meta: typeof rule3.meta;
|
|
22
|
+
create: (context: unknown) => any;
|
|
23
|
+
};
|
|
24
|
+
"sort-keys": {
|
|
25
|
+
meta: typeof rule4.meta;
|
|
26
|
+
create: (context: unknown) => any;
|
|
27
|
+
};
|
|
28
|
+
"top-level-interop": {
|
|
29
|
+
meta: typeof rule5.meta;
|
|
30
|
+
create: (context: unknown) => any;
|
|
31
|
+
};
|
|
8
32
|
};
|
|
9
33
|
export default _default;
|
package/dist/build/rules.js
CHANGED
|
@@ -5,10 +5,10 @@ import rule3 from "../rules/no-unsafe-values.js";
|
|
|
5
5
|
import rule4 from "../rules/sort-keys.js";
|
|
6
6
|
import rule5 from "../rules/top-level-interop.js";
|
|
7
7
|
export default {
|
|
8
|
-
"no-duplicate-keys": rule0,
|
|
9
|
-
"no-empty-keys": rule1,
|
|
10
|
-
"no-unnormalized-keys": rule2,
|
|
11
|
-
"no-unsafe-values": rule3,
|
|
12
|
-
"sort-keys": rule4,
|
|
13
|
-
"top-level-interop": rule5,
|
|
8
|
+
"no-duplicate-keys": /** @type {{meta: typeof rule0.meta; create: (context: unknown) => any}} */ (rule0),
|
|
9
|
+
"no-empty-keys": /** @type {{meta: typeof rule1.meta; create: (context: unknown) => any}} */ (rule1),
|
|
10
|
+
"no-unnormalized-keys": /** @type {{meta: typeof rule2.meta; create: (context: unknown) => any}} */ (rule2),
|
|
11
|
+
"no-unsafe-values": /** @type {{meta: typeof rule3.meta; create: (context: unknown) => any}} */ (rule3),
|
|
12
|
+
"sort-keys": /** @type {{meta: typeof rule4.meta; create: (context: unknown) => any}} */ (rule4),
|
|
13
|
+
"top-level-interop": /** @type {{meta: typeof rule5.meta; create: (context: unknown) => any}} */ (rule5),
|
|
14
14
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,29 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview JSON plugin.
|
|
3
|
+
* @author Nicholas C. Zakas
|
|
4
|
+
*/
|
|
5
|
+
import { JSONLanguage } from "./languages/json-language.js";
|
|
6
|
+
import { JSONSourceCode } from "./languages/json-source-code.js";
|
|
7
|
+
declare const plugin: {
|
|
8
|
+
meta: {
|
|
9
|
+
name: string;
|
|
10
|
+
namespace: string;
|
|
11
|
+
version: string;
|
|
12
|
+
};
|
|
13
|
+
languages: {
|
|
14
|
+
json: JSONLanguage;
|
|
15
|
+
jsonc: JSONLanguage;
|
|
16
|
+
json5: JSONLanguage;
|
|
17
|
+
};
|
|
18
|
+
rules: {
|
|
19
|
+
"no-duplicate-keys": {
|
|
20
|
+
meta: {
|
|
21
|
+
type: "problem";
|
|
22
|
+
languages: string[];
|
|
23
|
+
docs: {
|
|
24
|
+
recommended: boolean;
|
|
25
|
+
description: string;
|
|
26
|
+
dialects: string[];
|
|
27
|
+
url: string;
|
|
28
|
+
};
|
|
29
|
+
messages: {
|
|
30
|
+
duplicateKey: string;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
create: (context: unknown) => any;
|
|
34
|
+
};
|
|
35
|
+
"no-empty-keys": {
|
|
36
|
+
meta: {
|
|
37
|
+
type: "problem";
|
|
38
|
+
languages: string[];
|
|
39
|
+
docs: {
|
|
40
|
+
recommended: boolean;
|
|
41
|
+
description: string;
|
|
42
|
+
dialects: string[];
|
|
43
|
+
url: string;
|
|
44
|
+
};
|
|
45
|
+
messages: {
|
|
46
|
+
emptyKey: string;
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
create: (context: unknown) => any;
|
|
50
|
+
};
|
|
51
|
+
"no-unnormalized-keys": {
|
|
52
|
+
meta: {
|
|
53
|
+
type: "problem";
|
|
54
|
+
languages: string[];
|
|
55
|
+
fixable: "code";
|
|
56
|
+
docs: {
|
|
57
|
+
recommended: boolean;
|
|
58
|
+
description: string;
|
|
59
|
+
dialects: string[];
|
|
60
|
+
url: string;
|
|
61
|
+
};
|
|
62
|
+
messages: {
|
|
63
|
+
unnormalizedKey: string;
|
|
64
|
+
};
|
|
65
|
+
schema: {
|
|
66
|
+
type: "object";
|
|
67
|
+
properties: {
|
|
68
|
+
form: {
|
|
69
|
+
enum: string[];
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
additionalProperties: false;
|
|
73
|
+
}[];
|
|
74
|
+
defaultOptions: [{
|
|
75
|
+
form: string;
|
|
76
|
+
}];
|
|
77
|
+
};
|
|
78
|
+
create: (context: unknown) => any;
|
|
79
|
+
};
|
|
80
|
+
"no-unsafe-values": {
|
|
81
|
+
meta: {
|
|
82
|
+
type: "problem";
|
|
83
|
+
languages: string[];
|
|
84
|
+
docs: {
|
|
85
|
+
recommended: boolean;
|
|
86
|
+
description: string;
|
|
87
|
+
dialects: string[];
|
|
88
|
+
url: string;
|
|
89
|
+
};
|
|
90
|
+
messages: {
|
|
91
|
+
unsafeNumber: string;
|
|
92
|
+
unsafeInteger: string;
|
|
93
|
+
unsafeZero: string;
|
|
94
|
+
subnormal: string;
|
|
95
|
+
loneSurrogate: string;
|
|
96
|
+
};
|
|
97
|
+
};
|
|
98
|
+
create: (context: unknown) => any;
|
|
99
|
+
};
|
|
100
|
+
"sort-keys": {
|
|
101
|
+
meta: {
|
|
102
|
+
type: "suggestion";
|
|
103
|
+
languages: string[];
|
|
104
|
+
fixable: "code";
|
|
105
|
+
defaultOptions: ["asc", {
|
|
106
|
+
allowLineSeparatedGroups: false;
|
|
107
|
+
caseSensitive: true;
|
|
108
|
+
minKeys: number;
|
|
109
|
+
natural: false;
|
|
110
|
+
}];
|
|
111
|
+
docs: {
|
|
112
|
+
recommended: boolean;
|
|
113
|
+
description: string;
|
|
114
|
+
dialects: string[];
|
|
115
|
+
url: string;
|
|
116
|
+
};
|
|
117
|
+
messages: {
|
|
118
|
+
sortKeys: string;
|
|
119
|
+
};
|
|
120
|
+
schema: ({
|
|
121
|
+
enum: string[];
|
|
122
|
+
type?: undefined;
|
|
123
|
+
properties?: undefined;
|
|
124
|
+
additionalProperties?: undefined;
|
|
125
|
+
} | {
|
|
126
|
+
enum?: undefined;
|
|
127
|
+
type: "object";
|
|
128
|
+
properties: {
|
|
129
|
+
caseSensitive: {
|
|
130
|
+
type: "boolean";
|
|
131
|
+
};
|
|
132
|
+
natural: {
|
|
133
|
+
type: "boolean";
|
|
134
|
+
};
|
|
135
|
+
minKeys: {
|
|
136
|
+
type: "integer";
|
|
137
|
+
minimum: number;
|
|
138
|
+
};
|
|
139
|
+
allowLineSeparatedGroups: {
|
|
140
|
+
type: "boolean";
|
|
141
|
+
};
|
|
142
|
+
};
|
|
143
|
+
additionalProperties: false;
|
|
144
|
+
})[];
|
|
145
|
+
};
|
|
146
|
+
create: (context: unknown) => any;
|
|
147
|
+
};
|
|
148
|
+
"top-level-interop": {
|
|
149
|
+
meta: {
|
|
150
|
+
type: "problem";
|
|
151
|
+
languages: string[];
|
|
152
|
+
docs: {
|
|
153
|
+
recommended: boolean;
|
|
154
|
+
description: string;
|
|
155
|
+
dialects: string[];
|
|
156
|
+
url: string;
|
|
157
|
+
};
|
|
158
|
+
messages: {
|
|
159
|
+
topLevel: string;
|
|
160
|
+
};
|
|
161
|
+
};
|
|
162
|
+
create: (context: unknown) => any;
|
|
163
|
+
};
|
|
164
|
+
};
|
|
165
|
+
configs: {
|
|
166
|
+
recommended: {
|
|
167
|
+
name: string;
|
|
168
|
+
plugins: {};
|
|
169
|
+
rules: {
|
|
170
|
+
readonly "json/no-duplicate-keys": "error";
|
|
171
|
+
readonly "json/no-empty-keys": "error";
|
|
172
|
+
readonly "json/no-unnormalized-keys": "error";
|
|
173
|
+
readonly "json/no-unsafe-values": "error";
|
|
174
|
+
};
|
|
175
|
+
};
|
|
176
|
+
};
|
|
177
|
+
};
|
|
1
178
|
export default plugin;
|
|
2
179
|
export { JSONSourceCode };
|
|
3
180
|
export * from "./languages/json-language.js";
|
|
4
181
|
export * from "./types.js";
|
|
5
|
-
declare namespace plugin {
|
|
6
|
-
export namespace meta {
|
|
7
|
-
let name: string;
|
|
8
|
-
let namespace: string;
|
|
9
|
-
let version: string;
|
|
10
|
-
}
|
|
11
|
-
export namespace languages {
|
|
12
|
-
let json: JSONLanguage;
|
|
13
|
-
let jsonc: JSONLanguage;
|
|
14
|
-
let json5: JSONLanguage;
|
|
15
|
-
}
|
|
16
|
-
export { rules };
|
|
17
|
-
export namespace configs {
|
|
18
|
-
namespace recommended {
|
|
19
|
-
let name_1: string;
|
|
20
|
-
export { name_1 as name };
|
|
21
|
-
export let plugins: {};
|
|
22
|
-
export { recommendedRules as rules };
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
import { JSONSourceCode } from "./languages/json-source-code.js";
|
|
27
|
-
import { JSONLanguage } from "./languages/json-language.js";
|
|
28
|
-
import rules from "./build/rules.js";
|
|
29
|
-
import recommendedRules from "./build/recommended-config.js";
|
package/dist/index.js
CHANGED
|
@@ -1,24 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview The JSONLanguage class.
|
|
3
|
+
* @author Nicholas C. Zakas
|
|
4
|
+
*/
|
|
5
|
+
import { JSONSourceCode } from "./json-source-code.js";
|
|
6
|
+
import type { DocumentNode, AnyNode } from "@humanwhocodes/momoa";
|
|
7
|
+
import type { Language, OkParseResult, ParseResult, File } from "@eslint/core";
|
|
8
|
+
import type { JSONLanguageOptions } from "../types.js";
|
|
9
|
+
export type JSONOkParseResult = OkParseResult<DocumentNode>;
|
|
10
|
+
export type JSONParseResult = ParseResult<DocumentNode>;
|
|
1
11
|
/**
|
|
2
12
|
* @import { DocumentNode, AnyNode } from "@humanwhocodes/momoa";
|
|
3
13
|
* @import { Language, OkParseResult, ParseResult, File } from "@eslint/core";
|
|
14
|
+
* @import { JSONLanguageOptions } from "../types.js";
|
|
4
15
|
* @typedef {OkParseResult<DocumentNode>} JSONOkParseResult
|
|
5
16
|
* @typedef {ParseResult<DocumentNode>} JSONParseResult
|
|
6
|
-
* @typedef {Object} JSONLanguageOptions
|
|
7
|
-
* @property {boolean} [allowTrailingCommas] Whether to allow trailing commas in JSONC mode.
|
|
8
17
|
*/
|
|
9
18
|
/**
|
|
10
19
|
* JSON Language Object
|
|
11
20
|
* @implements {Language<{ LangOptions: JSONLanguageOptions; Code: JSONSourceCode; RootNode: DocumentNode; Node: AnyNode }>}
|
|
12
21
|
*/
|
|
13
|
-
export class JSONLanguage implements Language
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
mode: "json" | "jsonc" | "json5";
|
|
21
|
-
});
|
|
22
|
+
export declare class JSONLanguage implements Language<{
|
|
23
|
+
LangOptions: JSONLanguageOptions;
|
|
24
|
+
Code: JSONSourceCode;
|
|
25
|
+
RootNode: DocumentNode;
|
|
26
|
+
Node: AnyNode;
|
|
27
|
+
}> {
|
|
28
|
+
#private;
|
|
22
29
|
/**
|
|
23
30
|
* The type of file to read.
|
|
24
31
|
* @type {"text"}
|
|
@@ -44,6 +51,14 @@ export class JSONLanguage implements Language {
|
|
|
44
51
|
* @type {Record<string, string[]>}
|
|
45
52
|
*/
|
|
46
53
|
visitorKeys: Record<string, string[]>;
|
|
54
|
+
/**
|
|
55
|
+
* Creates a new instance.
|
|
56
|
+
* @param {Object} options The options to use for this instance.
|
|
57
|
+
* @param {"json"|"jsonc"|"json5"} options.mode The parser mode to use.
|
|
58
|
+
*/
|
|
59
|
+
constructor({ mode }: {
|
|
60
|
+
mode: "json" | "jsonc" | "json5";
|
|
61
|
+
});
|
|
47
62
|
/**
|
|
48
63
|
* Validates the language options.
|
|
49
64
|
* @param {JSONLanguageOptions} languageOptions The language options to validate.
|
|
@@ -67,19 +82,4 @@ export class JSONLanguage implements Language {
|
|
|
67
82
|
* @returns {JSONSourceCode} The new `JSONSourceCode` object.
|
|
68
83
|
*/
|
|
69
84
|
createSourceCode(file: File, parseResult: JSONOkParseResult): JSONSourceCode;
|
|
70
|
-
#private;
|
|
71
85
|
}
|
|
72
|
-
export type JSONOkParseResult = OkParseResult<DocumentNode>;
|
|
73
|
-
export type JSONParseResult = ParseResult<DocumentNode>;
|
|
74
|
-
export type JSONLanguageOptions = {
|
|
75
|
-
/**
|
|
76
|
-
* Whether to allow trailing commas in JSONC mode.
|
|
77
|
-
*/
|
|
78
|
-
allowTrailingCommas?: boolean;
|
|
79
|
-
};
|
|
80
|
-
import type { Language } from "@eslint/core";
|
|
81
|
-
import type { File } from "@eslint/core";
|
|
82
|
-
import { JSONSourceCode } from "./json-source-code.js";
|
|
83
|
-
import type { DocumentNode } from "@humanwhocodes/momoa";
|
|
84
|
-
import type { OkParseResult } from "@eslint/core";
|
|
85
|
-
import type { ParseResult } from "@eslint/core";
|
|
@@ -14,10 +14,9 @@ import { visitorKeys } from "@humanwhocodes/momoa";
|
|
|
14
14
|
/**
|
|
15
15
|
* @import { DocumentNode, AnyNode } from "@humanwhocodes/momoa";
|
|
16
16
|
* @import { Language, OkParseResult, ParseResult, File } from "@eslint/core";
|
|
17
|
+
* @import { JSONLanguageOptions } from "../types.js";
|
|
17
18
|
* @typedef {OkParseResult<DocumentNode>} JSONOkParseResult
|
|
18
19
|
* @typedef {ParseResult<DocumentNode>} JSONParseResult
|
|
19
|
-
* @typedef {Object} JSONLanguageOptions
|
|
20
|
-
* @property {boolean} [allowTrailingCommas] Whether to allow trailing commas in JSONC mode.
|
|
21
20
|
*/
|
|
22
21
|
//-----------------------------------------------------------------------------
|
|
23
22
|
// Exports
|
|
@@ -1,13 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview The JSONSourceCode class.
|
|
3
|
+
* @author Nicholas C. Zakas
|
|
4
|
+
*/
|
|
5
|
+
import { VisitNodeStep, TextSourceCodeBase, Directive } from "@eslint/plugin-kit";
|
|
6
|
+
import type { DocumentNode, AnyNode, Token, LocationRange } from "@humanwhocodes/momoa";
|
|
7
|
+
import type { FileProblem, RulesConfig } from "@eslint/core";
|
|
8
|
+
import type { JSONLanguageOptions, JSONSyntaxElement } from "../types.js";
|
|
9
|
+
/**
|
|
10
|
+
* A class to represent a step in the traversal process.
|
|
11
|
+
*/
|
|
12
|
+
declare class JSONTraversalStep extends VisitNodeStep {
|
|
13
|
+
/**
|
|
14
|
+
* The target of the step.
|
|
15
|
+
* @type {AnyNode}
|
|
16
|
+
*/
|
|
17
|
+
target: AnyNode;
|
|
18
|
+
/**
|
|
19
|
+
* Creates a new instance.
|
|
20
|
+
* @param {Object} options The options for the step.
|
|
21
|
+
* @param {AnyNode} options.target The target of the step.
|
|
22
|
+
* @param {1|2} options.phase The phase of the step.
|
|
23
|
+
* @param {Array<any>} options.args The arguments of the step.
|
|
24
|
+
*/
|
|
25
|
+
constructor({ target, phase, args }: {
|
|
26
|
+
target: AnyNode;
|
|
27
|
+
phase: 1 | 2;
|
|
28
|
+
args: Array<any>;
|
|
29
|
+
});
|
|
30
|
+
}
|
|
1
31
|
/**
|
|
2
32
|
* JSON Source Code Object
|
|
3
33
|
* @extends {TextSourceCodeBase<{LangOptions: JSONLanguageOptions, RootNode: DocumentNode, SyntaxElementWithLoc: JSONSyntaxElement, ConfigNode: Token}>}
|
|
4
34
|
*/
|
|
5
|
-
export class JSONSourceCode extends TextSourceCodeBase<{
|
|
35
|
+
export declare class JSONSourceCode extends TextSourceCodeBase<{
|
|
6
36
|
LangOptions: JSONLanguageOptions;
|
|
7
37
|
RootNode: DocumentNode;
|
|
8
38
|
SyntaxElementWithLoc: JSONSyntaxElement;
|
|
9
39
|
ConfigNode: Token;
|
|
10
40
|
}> {
|
|
41
|
+
#private;
|
|
42
|
+
/**
|
|
43
|
+
* The AST of the source code.
|
|
44
|
+
* @type {DocumentNode}
|
|
45
|
+
*/
|
|
46
|
+
ast: DocumentNode;
|
|
47
|
+
/**
|
|
48
|
+
* The comment tokens in the source code.
|
|
49
|
+
* @type {Array<Token>|undefined}
|
|
50
|
+
*/
|
|
51
|
+
comments: Array<Token> | undefined;
|
|
11
52
|
/**
|
|
12
53
|
* Creates a new instance.
|
|
13
54
|
* @param {Object} options The options for the instance.
|
|
@@ -18,11 +59,6 @@ export class JSONSourceCode extends TextSourceCodeBase<{
|
|
|
18
59
|
text: string;
|
|
19
60
|
ast: DocumentNode;
|
|
20
61
|
});
|
|
21
|
-
/**
|
|
22
|
-
* The comment tokens in the source code.
|
|
23
|
-
* @type {Array<Token>|undefined}
|
|
24
|
-
*/
|
|
25
|
-
comments: Array<Token> | undefined;
|
|
26
62
|
/**
|
|
27
63
|
* Returns an array of all inline configuration nodes found in the
|
|
28
64
|
* source code.
|
|
@@ -85,39 +121,5 @@ export class JSONSourceCode extends TextSourceCodeBase<{
|
|
|
85
121
|
getTokenAfter(nodeOrToken: AnyNode | Token, { includeComments }?: {
|
|
86
122
|
includeComments?: boolean;
|
|
87
123
|
}): Token | null;
|
|
88
|
-
#private;
|
|
89
|
-
}
|
|
90
|
-
import type { JSONLanguageOptions } from "./json-language.js";
|
|
91
|
-
import type { DocumentNode } from "@humanwhocodes/momoa";
|
|
92
|
-
import type { JSONSyntaxElement } from "../types.js";
|
|
93
|
-
import type { Token } from "@humanwhocodes/momoa";
|
|
94
|
-
import { TextSourceCodeBase } from "@eslint/plugin-kit";
|
|
95
|
-
import type { FileProblem } from "@eslint/core";
|
|
96
|
-
import { Directive } from "@eslint/plugin-kit";
|
|
97
|
-
import type { RulesConfig } from "@eslint/core";
|
|
98
|
-
import type { LocationRange } from "@humanwhocodes/momoa";
|
|
99
|
-
import type { AnyNode } from "@humanwhocodes/momoa";
|
|
100
|
-
/**
|
|
101
|
-
* A class to represent a step in the traversal process.
|
|
102
|
-
*/
|
|
103
|
-
declare class JSONTraversalStep extends VisitNodeStep {
|
|
104
|
-
/**
|
|
105
|
-
* Creates a new instance.
|
|
106
|
-
* @param {Object} options The options for the step.
|
|
107
|
-
* @param {AnyNode} options.target The target of the step.
|
|
108
|
-
* @param {1|2} options.phase The phase of the step.
|
|
109
|
-
* @param {Array<any>} options.args The arguments of the step.
|
|
110
|
-
*/
|
|
111
|
-
constructor({ target, phase, args }: {
|
|
112
|
-
target: AnyNode;
|
|
113
|
-
phase: 1 | 2;
|
|
114
|
-
args: Array<any>;
|
|
115
|
-
});
|
|
116
|
-
/**
|
|
117
|
-
* The target of the step.
|
|
118
|
-
* @type {AnyNode}
|
|
119
|
-
*/
|
|
120
|
-
target: AnyNode;
|
|
121
124
|
}
|
|
122
|
-
import { VisitNodeStep } from "@eslint/plugin-kit";
|
|
123
125
|
export {};
|
|
@@ -13,8 +13,7 @@ import { VisitNodeStep, TextSourceCodeBase, ConfigCommentParser, Directive, } fr
|
|
|
13
13
|
/**
|
|
14
14
|
* @import { DocumentNode, AnyNode, Token, LocationRange } from "@humanwhocodes/momoa";
|
|
15
15
|
* @import { FileProblem, DirectiveType, RulesConfig } from "@eslint/core";
|
|
16
|
-
* @import { JSONSyntaxElement } from "../types.js";
|
|
17
|
-
* @import { JSONLanguageOptions } from "./json-language.js";
|
|
16
|
+
* @import { JSONLanguageOptions, JSONSyntaxElement } from "../types.js";
|
|
18
17
|
*/
|
|
19
18
|
//-----------------------------------------------------------------------------
|
|
20
19
|
// Helpers
|
|
@@ -1,14 +1,38 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Rule to prevent duplicate keys in JSON.
|
|
3
|
+
* @author Nicholas C. Zakas
|
|
4
|
+
*/
|
|
5
|
+
import type { JSONRuleVisitor, JSONRuleDefinition } from "../types.js";
|
|
2
6
|
export type NoDuplicateKeysMessageIds = "duplicateKey";
|
|
3
7
|
export type NoDuplicateKeysRuleDefinition = JSONRuleDefinition<{
|
|
4
8
|
MessageIds: NoDuplicateKeysMessageIds;
|
|
5
9
|
}>;
|
|
6
10
|
/**
|
|
7
11
|
* @import { MemberNode } from "@humanwhocodes/momoa";
|
|
8
|
-
* @import { JSONRuleDefinition } from "../types.js";
|
|
12
|
+
* @import { JSONRuleVisitor, JSONRuleDefinition } from "../types.js";
|
|
9
13
|
* @typedef {"duplicateKey"} NoDuplicateKeysMessageIds
|
|
10
14
|
* @typedef {JSONRuleDefinition<{ MessageIds: NoDuplicateKeysMessageIds }>} NoDuplicateKeysRuleDefinition
|
|
11
15
|
*/
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
16
|
+
declare const _default: {
|
|
17
|
+
meta: {
|
|
18
|
+
type: "problem";
|
|
19
|
+
languages: string[];
|
|
20
|
+
docs: {
|
|
21
|
+
recommended: boolean;
|
|
22
|
+
description: string;
|
|
23
|
+
dialects: string[];
|
|
24
|
+
url: string;
|
|
25
|
+
};
|
|
26
|
+
messages: {
|
|
27
|
+
duplicateKey: string;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
create(context: import("@eslint/core").RuleContext<{
|
|
31
|
+
LangOptions: import("../types.js").JSONLanguageOptions;
|
|
32
|
+
Code: import("../index.js").JSONSourceCode;
|
|
33
|
+
RuleOptions: unknown[];
|
|
34
|
+
Node: import("../types.js").JSONSyntaxElement;
|
|
35
|
+
MessageIds: "duplicateKey";
|
|
36
|
+
}>): JSONRuleVisitor;
|
|
37
|
+
};
|
|
38
|
+
export default _default;
|
|
@@ -11,15 +11,14 @@ import { getKey, getRawKey } from "../util.js";
|
|
|
11
11
|
//-----------------------------------------------------------------------------
|
|
12
12
|
/**
|
|
13
13
|
* @import { MemberNode } from "@humanwhocodes/momoa";
|
|
14
|
-
* @import { JSONRuleDefinition } from "../types.js";
|
|
14
|
+
* @import { JSONRuleVisitor, JSONRuleDefinition } from "../types.js";
|
|
15
15
|
* @typedef {"duplicateKey"} NoDuplicateKeysMessageIds
|
|
16
16
|
* @typedef {JSONRuleDefinition<{ MessageIds: NoDuplicateKeysMessageIds }>} NoDuplicateKeysRuleDefinition
|
|
17
17
|
*/
|
|
18
18
|
//-----------------------------------------------------------------------------
|
|
19
19
|
// Rule Definition
|
|
20
20
|
//-----------------------------------------------------------------------------
|
|
21
|
-
/** @
|
|
22
|
-
const rule = {
|
|
21
|
+
export default /** @satisfies {NoDuplicateKeysRuleDefinition} */ {
|
|
23
22
|
meta: {
|
|
24
23
|
type: "problem",
|
|
25
24
|
languages: ["json/json", "json/jsonc", "json/json5"],
|
|
@@ -27,7 +26,7 @@ const rule = {
|
|
|
27
26
|
recommended: true,
|
|
28
27
|
description: "Disallow duplicate keys in JSON objects",
|
|
29
28
|
dialects: ["JSON", "JSONC", "JSON5"],
|
|
30
|
-
url: "https://github.com/eslint/json/
|
|
29
|
+
url: "https://github.com/eslint/json/blob/main/docs/rules/no-duplicate-keys.md",
|
|
31
30
|
},
|
|
32
31
|
messages: {
|
|
33
32
|
duplicateKey: 'Duplicate key "{{key}}" found.',
|
|
@@ -38,7 +37,7 @@ const rule = {
|
|
|
38
37
|
const objectKeys = [];
|
|
39
38
|
/** @type {Map<string, MemberNode>|undefined} */
|
|
40
39
|
let keys;
|
|
41
|
-
return {
|
|
40
|
+
return /** @type {JSONRuleVisitor} */ ({
|
|
42
41
|
Object() {
|
|
43
42
|
objectKeys.push(keys);
|
|
44
43
|
keys = new Map();
|
|
@@ -62,7 +61,6 @@ const rule = {
|
|
|
62
61
|
"Object:exit"() {
|
|
63
62
|
keys = objectKeys.pop();
|
|
64
63
|
},
|
|
65
|
-
};
|
|
64
|
+
});
|
|
66
65
|
},
|
|
67
66
|
};
|
|
68
|
-
export default rule;
|
|
@@ -1,13 +1,37 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Rule to prevent empty keys in JSON.
|
|
3
|
+
* @author Nicholas C. Zakas
|
|
4
|
+
*/
|
|
5
|
+
import type { JSONRuleVisitor, JSONRuleDefinition } from "../types.js";
|
|
2
6
|
export type NoEmptyKeysMessageIds = "emptyKey";
|
|
3
7
|
export type NoEmptyKeysRuleDefinition = JSONRuleDefinition<{
|
|
4
8
|
MessageIds: NoEmptyKeysMessageIds;
|
|
5
9
|
}>;
|
|
6
10
|
/**
|
|
7
|
-
* @import { JSONRuleDefinition } from "../types.js";
|
|
11
|
+
* @import { JSONRuleVisitor, JSONRuleDefinition } from "../types.js";
|
|
8
12
|
* @typedef {"emptyKey"} NoEmptyKeysMessageIds
|
|
9
13
|
* @typedef {JSONRuleDefinition<{ MessageIds: NoEmptyKeysMessageIds }>} NoEmptyKeysRuleDefinition
|
|
10
14
|
*/
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
15
|
+
declare const _default: {
|
|
16
|
+
meta: {
|
|
17
|
+
type: "problem";
|
|
18
|
+
languages: string[];
|
|
19
|
+
docs: {
|
|
20
|
+
recommended: boolean;
|
|
21
|
+
description: string;
|
|
22
|
+
dialects: string[];
|
|
23
|
+
url: string;
|
|
24
|
+
};
|
|
25
|
+
messages: {
|
|
26
|
+
emptyKey: string;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
create(context: import("@eslint/core").RuleContext<{
|
|
30
|
+
LangOptions: import("../types.js").JSONLanguageOptions;
|
|
31
|
+
Code: import("../index.js").JSONSourceCode;
|
|
32
|
+
RuleOptions: unknown[];
|
|
33
|
+
Node: import("../types.js").JSONSyntaxElement;
|
|
34
|
+
MessageIds: "emptyKey";
|
|
35
|
+
}>): JSONRuleVisitor;
|
|
36
|
+
};
|
|
37
|
+
export default _default;
|
|
@@ -10,15 +10,14 @@ import { getKey } from "../util.js";
|
|
|
10
10
|
// Type Definitions
|
|
11
11
|
//-----------------------------------------------------------------------------
|
|
12
12
|
/**
|
|
13
|
-
* @import { JSONRuleDefinition } from "../types.js";
|
|
13
|
+
* @import { JSONRuleVisitor, JSONRuleDefinition } from "../types.js";
|
|
14
14
|
* @typedef {"emptyKey"} NoEmptyKeysMessageIds
|
|
15
15
|
* @typedef {JSONRuleDefinition<{ MessageIds: NoEmptyKeysMessageIds }>} NoEmptyKeysRuleDefinition
|
|
16
16
|
*/
|
|
17
17
|
//-----------------------------------------------------------------------------
|
|
18
18
|
// Rule Definition
|
|
19
19
|
//-----------------------------------------------------------------------------
|
|
20
|
-
/** @
|
|
21
|
-
const rule = {
|
|
20
|
+
export default /** @satisfies {NoEmptyKeysRuleDefinition} */ {
|
|
22
21
|
meta: {
|
|
23
22
|
type: "problem",
|
|
24
23
|
languages: ["json/json", "json/jsonc", "json/json5"],
|
|
@@ -26,14 +25,14 @@ const rule = {
|
|
|
26
25
|
recommended: true,
|
|
27
26
|
description: "Disallow empty keys in JSON objects",
|
|
28
27
|
dialects: ["JSON", "JSONC", "JSON5"],
|
|
29
|
-
url: "https://github.com/eslint/json/
|
|
28
|
+
url: "https://github.com/eslint/json/blob/main/docs/rules/no-empty-keys.md",
|
|
30
29
|
},
|
|
31
30
|
messages: {
|
|
32
31
|
emptyKey: "Empty key found.",
|
|
33
32
|
},
|
|
34
33
|
},
|
|
35
34
|
create(context) {
|
|
36
|
-
return {
|
|
35
|
+
return /** @type {JSONRuleVisitor} */ ({
|
|
37
36
|
Member(node) {
|
|
38
37
|
const key = getKey(node);
|
|
39
38
|
if (key.trim() === "") {
|
|
@@ -43,7 +42,6 @@ const rule = {
|
|
|
43
42
|
});
|
|
44
43
|
}
|
|
45
44
|
},
|
|
46
|
-
};
|
|
45
|
+
});
|
|
47
46
|
},
|
|
48
47
|
};
|
|
49
|
-
export default rule;
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Rule to detect unnormalized keys in JSON.
|
|
3
|
+
* @author Bradley Meck Farias
|
|
4
|
+
*/
|
|
5
|
+
import type { JSONRuleVisitor, JSONRuleDefinition } from "../types.js";
|
|
2
6
|
export type NoUnnormalizedKeysMessageIds = "unnormalizedKey";
|
|
3
7
|
export type NoUnnormalizedKeysOptions = {
|
|
4
8
|
form: string;
|
|
@@ -8,11 +12,44 @@ export type NoUnnormalizedKeysRuleDefinition = JSONRuleDefinition<{
|
|
|
8
12
|
MessageIds: NoUnnormalizedKeysMessageIds;
|
|
9
13
|
}>;
|
|
10
14
|
/**
|
|
11
|
-
* @import { JSONRuleDefinition } from "../types.js";
|
|
15
|
+
* @import { JSONRuleVisitor, JSONRuleDefinition } from "../types.js";
|
|
12
16
|
* @typedef {"unnormalizedKey"} NoUnnormalizedKeysMessageIds
|
|
13
17
|
* @typedef {{ form: string }} NoUnnormalizedKeysOptions
|
|
14
18
|
* @typedef {JSONRuleDefinition<{ RuleOptions: [NoUnnormalizedKeysOptions], MessageIds: NoUnnormalizedKeysMessageIds }>} NoUnnormalizedKeysRuleDefinition
|
|
15
19
|
*/
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
20
|
+
declare const _default: {
|
|
21
|
+
meta: {
|
|
22
|
+
type: "problem";
|
|
23
|
+
languages: string[];
|
|
24
|
+
fixable: "code";
|
|
25
|
+
docs: {
|
|
26
|
+
recommended: boolean;
|
|
27
|
+
description: string;
|
|
28
|
+
dialects: string[];
|
|
29
|
+
url: string;
|
|
30
|
+
};
|
|
31
|
+
messages: {
|
|
32
|
+
unnormalizedKey: string;
|
|
33
|
+
};
|
|
34
|
+
schema: {
|
|
35
|
+
type: "object";
|
|
36
|
+
properties: {
|
|
37
|
+
form: {
|
|
38
|
+
enum: string[];
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
additionalProperties: false;
|
|
42
|
+
}[];
|
|
43
|
+
defaultOptions: [{
|
|
44
|
+
form: string;
|
|
45
|
+
}];
|
|
46
|
+
};
|
|
47
|
+
create(context: import("@eslint/core").RuleContext<{
|
|
48
|
+
LangOptions: import("../types.js").JSONLanguageOptions;
|
|
49
|
+
Code: import("../index.js").JSONSourceCode;
|
|
50
|
+
RuleOptions: [NoUnnormalizedKeysOptions];
|
|
51
|
+
Node: import("../types.js").JSONSyntaxElement;
|
|
52
|
+
MessageIds: "unnormalizedKey";
|
|
53
|
+
}>): JSONRuleVisitor;
|
|
54
|
+
};
|
|
55
|
+
export default _default;
|
|
@@ -10,7 +10,7 @@ import { getKey, getRawKey } from "../util.js";
|
|
|
10
10
|
// Type Definitions
|
|
11
11
|
//-----------------------------------------------------------------------------
|
|
12
12
|
/**
|
|
13
|
-
* @import { JSONRuleDefinition } from "../types.js";
|
|
13
|
+
* @import { JSONRuleVisitor, JSONRuleDefinition } from "../types.js";
|
|
14
14
|
* @typedef {"unnormalizedKey"} NoUnnormalizedKeysMessageIds
|
|
15
15
|
* @typedef {{ form: string }} NoUnnormalizedKeysOptions
|
|
16
16
|
* @typedef {JSONRuleDefinition<{ RuleOptions: [NoUnnormalizedKeysOptions], MessageIds: NoUnnormalizedKeysMessageIds }>} NoUnnormalizedKeysRuleDefinition
|
|
@@ -18,8 +18,7 @@ import { getKey, getRawKey } from "../util.js";
|
|
|
18
18
|
//-----------------------------------------------------------------------------
|
|
19
19
|
// Rule Definition
|
|
20
20
|
//-----------------------------------------------------------------------------
|
|
21
|
-
/** @
|
|
22
|
-
const rule = {
|
|
21
|
+
export default /** @satisfies {NoUnnormalizedKeysRuleDefinition} */ {
|
|
23
22
|
meta: {
|
|
24
23
|
type: "problem",
|
|
25
24
|
languages: ["json/json", "json/jsonc", "json/json5"],
|
|
@@ -28,7 +27,7 @@ const rule = {
|
|
|
28
27
|
recommended: true,
|
|
29
28
|
description: "Disallow JSON keys that are not normalized",
|
|
30
29
|
dialects: ["JSON", "JSONC", "JSON5"],
|
|
31
|
-
url: "https://github.com/eslint/json/
|
|
30
|
+
url: "https://github.com/eslint/json/blob/main/docs/rules/no-unnormalized-keys.md",
|
|
32
31
|
},
|
|
33
32
|
messages: {
|
|
34
33
|
unnormalizedKey: "Unnormalized key '{{key}}' found.",
|
|
@@ -52,7 +51,7 @@ const rule = {
|
|
|
52
51
|
},
|
|
53
52
|
create(context) {
|
|
54
53
|
const [{ form }] = context.options;
|
|
55
|
-
return {
|
|
54
|
+
return /** @type {JSONRuleVisitor} */ ({
|
|
56
55
|
Member(node) {
|
|
57
56
|
const key = getKey(node);
|
|
58
57
|
const rawKey = getRawKey(node, context.sourceCode);
|
|
@@ -77,7 +76,6 @@ const rule = {
|
|
|
77
76
|
});
|
|
78
77
|
}
|
|
79
78
|
},
|
|
80
|
-
};
|
|
79
|
+
});
|
|
81
80
|
},
|
|
82
81
|
};
|
|
83
|
-
export default rule;
|
|
@@ -1,8 +1,36 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Rule to detect unsafe values in JSON.
|
|
3
|
+
* @author Bradley Meck Farias
|
|
4
|
+
*/
|
|
5
|
+
import type { JSONRuleVisitor, JSONRuleDefinition } from "../types.js";
|
|
2
6
|
export type NoUnsafeValuesMessageIds = "unsafeNumber" | "unsafeInteger" | "unsafeZero" | "subnormal" | "loneSurrogate";
|
|
3
7
|
export type NoUnsafeValuesRuleDefinition = JSONRuleDefinition<{
|
|
4
8
|
MessageIds: NoUnsafeValuesMessageIds;
|
|
5
9
|
}>;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
10
|
+
declare const _default: {
|
|
11
|
+
meta: {
|
|
12
|
+
type: "problem";
|
|
13
|
+
languages: string[];
|
|
14
|
+
docs: {
|
|
15
|
+
recommended: boolean;
|
|
16
|
+
description: string;
|
|
17
|
+
dialects: string[];
|
|
18
|
+
url: string;
|
|
19
|
+
};
|
|
20
|
+
messages: {
|
|
21
|
+
unsafeNumber: string;
|
|
22
|
+
unsafeInteger: string;
|
|
23
|
+
unsafeZero: string;
|
|
24
|
+
subnormal: string;
|
|
25
|
+
loneSurrogate: string;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
create(context: import("@eslint/core").RuleContext<{
|
|
29
|
+
LangOptions: import("../types.js").JSONLanguageOptions;
|
|
30
|
+
Code: import("../index.js").JSONSourceCode;
|
|
31
|
+
RuleOptions: unknown[];
|
|
32
|
+
Node: import("../types.js").JSONSyntaxElement;
|
|
33
|
+
MessageIds: NoUnsafeValuesMessageIds;
|
|
34
|
+
}>): JSONRuleVisitor;
|
|
35
|
+
};
|
|
36
|
+
export default _default;
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
// Type Definitions
|
|
7
7
|
//-----------------------------------------------------------------------------
|
|
8
8
|
/**
|
|
9
|
-
* @import { JSONRuleDefinition } from "../types.js";
|
|
9
|
+
* @import { JSONRuleVisitor, JSONRuleDefinition } from "../types.js";
|
|
10
10
|
* @typedef {"unsafeNumber"|"unsafeInteger"|"unsafeZero"|"subnormal"|"loneSurrogate"} NoUnsafeValuesMessageIds
|
|
11
11
|
* @typedef {JSONRuleDefinition<{ MessageIds: NoUnsafeValuesMessageIds }>} NoUnsafeValuesRuleDefinition
|
|
12
12
|
*/
|
|
@@ -25,11 +25,11 @@
|
|
|
25
25
|
*/
|
|
26
26
|
const NUMBER = /^[+-]?(?<int>0|([1-9]\d*))?(?:\.(?<frac>\d*))?(?:e[+-]?\d+)?$/iu;
|
|
27
27
|
const NON_ZERO = /[1-9]/u;
|
|
28
|
+
const HEX = /^[+-]?0x/iu;
|
|
28
29
|
//-----------------------------------------------------------------------------
|
|
29
30
|
// Rule Definition
|
|
30
31
|
//-----------------------------------------------------------------------------
|
|
31
|
-
/** @
|
|
32
|
-
const rule = {
|
|
32
|
+
export default /** @satisfies {NoUnsafeValuesRuleDefinition} */ {
|
|
33
33
|
meta: {
|
|
34
34
|
type: "problem",
|
|
35
35
|
languages: ["json/json", "json/jsonc", "json/json5"],
|
|
@@ -37,7 +37,7 @@ const rule = {
|
|
|
37
37
|
recommended: true,
|
|
38
38
|
description: "Disallow JSON values that are unsafe for interchange",
|
|
39
39
|
dialects: ["JSON", "JSONC", "JSON5"],
|
|
40
|
-
url: "https://github.com/eslint/json/
|
|
40
|
+
url: "https://github.com/eslint/json/blob/main/docs/rules/no-unsafe-values.md",
|
|
41
41
|
},
|
|
42
42
|
messages: {
|
|
43
43
|
unsafeNumber: "The number '{{ value }}' will evaluate to Infinity.",
|
|
@@ -48,7 +48,7 @@ const rule = {
|
|
|
48
48
|
},
|
|
49
49
|
},
|
|
50
50
|
create(context) {
|
|
51
|
-
return {
|
|
51
|
+
return /** @type {JSONRuleVisitor} */ ({
|
|
52
52
|
Number(node) {
|
|
53
53
|
const value = context.sourceCode.getText(node);
|
|
54
54
|
if (Number.isFinite(node.value) !== true) {
|
|
@@ -80,8 +80,8 @@ const rule = {
|
|
|
80
80
|
});
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
|
-
else if (!/[.e]/iu.test(value)) {
|
|
84
|
-
// Intended to be an integer
|
|
83
|
+
else if (HEX.test(value) || !/[.e]/iu.test(value)) {
|
|
84
|
+
// Intended to be an integer; in hex, `e` is a digit, not an exponent
|
|
85
85
|
if (node.value > Number.MAX_SAFE_INTEGER ||
|
|
86
86
|
node.value < Number.MIN_SAFE_INTEGER) {
|
|
87
87
|
context.report({
|
|
@@ -135,7 +135,6 @@ const rule = {
|
|
|
135
135
|
}
|
|
136
136
|
}
|
|
137
137
|
},
|
|
138
|
-
};
|
|
138
|
+
});
|
|
139
139
|
},
|
|
140
140
|
};
|
|
141
|
-
export default rule;
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Rule to require JSON object keys to be sorted.
|
|
3
|
+
* Copied largely from https://github.com/eslint/eslint/blob/main/lib/rules/sort-keys.js
|
|
4
|
+
* @author Robin Thomas
|
|
5
|
+
*/
|
|
6
|
+
import type { JSONRuleVisitor, JSONRuleDefinition } from "../types.js";
|
|
2
7
|
export type SortOptions = {
|
|
3
8
|
/**
|
|
4
9
|
* Whether key comparisons are case-sensitive.
|
|
@@ -29,6 +34,58 @@ export type DirectionName = "ascending" | "descending";
|
|
|
29
34
|
export type SortName = "alphanumeric" | "natural";
|
|
30
35
|
export type Sensitivity = "sensitive" | "insensitive";
|
|
31
36
|
export type ComparatorMap = Record<DirectionName, Record<SortName, Record<Sensitivity, Comparator>>>;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
37
|
+
declare const _default: {
|
|
38
|
+
meta: {
|
|
39
|
+
type: "suggestion";
|
|
40
|
+
languages: string[];
|
|
41
|
+
fixable: "code";
|
|
42
|
+
defaultOptions: ["asc", {
|
|
43
|
+
allowLineSeparatedGroups: false;
|
|
44
|
+
caseSensitive: true;
|
|
45
|
+
minKeys: number;
|
|
46
|
+
natural: false;
|
|
47
|
+
}];
|
|
48
|
+
docs: {
|
|
49
|
+
recommended: boolean;
|
|
50
|
+
description: string;
|
|
51
|
+
dialects: string[];
|
|
52
|
+
url: string;
|
|
53
|
+
};
|
|
54
|
+
messages: {
|
|
55
|
+
sortKeys: string;
|
|
56
|
+
};
|
|
57
|
+
schema: ({
|
|
58
|
+
enum: string[];
|
|
59
|
+
type?: undefined;
|
|
60
|
+
properties?: undefined;
|
|
61
|
+
additionalProperties?: undefined;
|
|
62
|
+
} | {
|
|
63
|
+
enum?: undefined;
|
|
64
|
+
type: "object";
|
|
65
|
+
properties: {
|
|
66
|
+
caseSensitive: {
|
|
67
|
+
type: "boolean";
|
|
68
|
+
};
|
|
69
|
+
natural: {
|
|
70
|
+
type: "boolean";
|
|
71
|
+
};
|
|
72
|
+
minKeys: {
|
|
73
|
+
type: "integer";
|
|
74
|
+
minimum: number;
|
|
75
|
+
};
|
|
76
|
+
allowLineSeparatedGroups: {
|
|
77
|
+
type: "boolean";
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
additionalProperties: false;
|
|
81
|
+
})[];
|
|
82
|
+
};
|
|
83
|
+
create(context: import("@eslint/core").RuleContext<{
|
|
84
|
+
LangOptions: import("../types.js").JSONLanguageOptions;
|
|
85
|
+
Code: import("../index.js").JSONSourceCode;
|
|
86
|
+
RuleOptions: SortKeysRuleOptions;
|
|
87
|
+
Node: import("../types.js").JSONSyntaxElement;
|
|
88
|
+
MessageIds: "sortKeys";
|
|
89
|
+
}>): JSONRuleVisitor;
|
|
90
|
+
};
|
|
91
|
+
export default _default;
|
package/dist/rules/sort-keys.js
CHANGED
|
@@ -12,7 +12,7 @@ import { getKey, getRawKey } from "../util.js";
|
|
|
12
12
|
// Type Definitions
|
|
13
13
|
//-----------------------------------------------------------------------------
|
|
14
14
|
/**
|
|
15
|
-
* @import { JSONRuleDefinition } from "../types.js";
|
|
15
|
+
* @import { JSONRuleVisitor, JSONRuleDefinition } from "../types.js";
|
|
16
16
|
* @import { MemberNode } from "@humanwhocodes/momoa";
|
|
17
17
|
* @typedef {Object} SortOptions
|
|
18
18
|
* @property {boolean} caseSensitive Whether key comparisons are case-sensitive.
|
|
@@ -60,8 +60,7 @@ const comparators = {
|
|
|
60
60
|
//-----------------------------------------------------------------------------
|
|
61
61
|
// Rule Definition
|
|
62
62
|
//-----------------------------------------------------------------------------
|
|
63
|
-
/** @
|
|
64
|
-
const rule = {
|
|
63
|
+
export default /** @satisfies {SortKeysRuleDefinition} */ {
|
|
65
64
|
meta: {
|
|
66
65
|
type: "suggestion",
|
|
67
66
|
languages: ["json/json", "json/jsonc", "json/json5"],
|
|
@@ -79,7 +78,7 @@ const rule = {
|
|
|
79
78
|
recommended: false,
|
|
80
79
|
description: `Require JSON object keys to be sorted`,
|
|
81
80
|
dialects: ["JSON", "JSONC", "JSON5"],
|
|
82
|
-
url: "https://github.com/eslint/json/
|
|
81
|
+
url: "https://github.com/eslint/json/blob/main/docs/rules/sort-keys.md",
|
|
83
82
|
},
|
|
84
83
|
messages: {
|
|
85
84
|
sortKeys: "Expected object keys to be in {{sortName}} case-{{sensitivity}} {{direction}} order. '{{thisName}}' should be before '{{prevName}}'.",
|
|
@@ -167,7 +166,7 @@ const rule = {
|
|
|
167
166
|
}
|
|
168
167
|
return (commentTypes.has(before.type) || commentTypes.has(after.type));
|
|
169
168
|
}
|
|
170
|
-
return {
|
|
169
|
+
return /** @type {JSONRuleVisitor} */ ({
|
|
171
170
|
Object(node) {
|
|
172
171
|
/** @type {MemberNode} */
|
|
173
172
|
let prevMember;
|
|
@@ -215,7 +214,6 @@ const rule = {
|
|
|
215
214
|
prevRawName = thisRawName;
|
|
216
215
|
}
|
|
217
216
|
},
|
|
218
|
-
};
|
|
217
|
+
});
|
|
219
218
|
},
|
|
220
219
|
};
|
|
221
|
-
export default rule;
|
|
@@ -1,17 +1,37 @@
|
|
|
1
|
-
export default rule;
|
|
2
|
-
export type TopLevelInteropMessageIds = "topLevel";
|
|
3
|
-
export type TopLevelInteropRuleDefinition = JSONRuleDefinition<{
|
|
4
|
-
MessageIds: TopLevelInteropMessageIds;
|
|
5
|
-
}>;
|
|
6
1
|
/**
|
|
7
2
|
* @fileoverview Rule to ensure top-level items are either an array or object.
|
|
8
3
|
* @author Joe Hildebrand
|
|
9
4
|
*/
|
|
5
|
+
import type { JSONRuleVisitor, JSONRuleDefinition } from "../types.js";
|
|
6
|
+
export type TopLevelInteropMessageIds = "topLevel";
|
|
7
|
+
export type TopLevelInteropRuleDefinition = JSONRuleDefinition<{
|
|
8
|
+
MessageIds: TopLevelInteropMessageIds;
|
|
9
|
+
}>;
|
|
10
10
|
/**
|
|
11
|
-
* @import { JSONRuleDefinition } from "../types.js";
|
|
11
|
+
* @import { JSONRuleVisitor, JSONRuleDefinition } from "../types.js";
|
|
12
12
|
* @typedef {"topLevel"} TopLevelInteropMessageIds
|
|
13
13
|
* @typedef {JSONRuleDefinition<{ MessageIds: TopLevelInteropMessageIds }>} TopLevelInteropRuleDefinition
|
|
14
14
|
*/
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
declare const _default: {
|
|
16
|
+
meta: {
|
|
17
|
+
type: "problem";
|
|
18
|
+
languages: string[];
|
|
19
|
+
docs: {
|
|
20
|
+
recommended: boolean;
|
|
21
|
+
description: string;
|
|
22
|
+
dialects: string[];
|
|
23
|
+
url: string;
|
|
24
|
+
};
|
|
25
|
+
messages: {
|
|
26
|
+
topLevel: string;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
create(context: import("@eslint/core").RuleContext<{
|
|
30
|
+
LangOptions: import("../types.js").JSONLanguageOptions;
|
|
31
|
+
Code: import("../index.js").JSONSourceCode;
|
|
32
|
+
RuleOptions: unknown[];
|
|
33
|
+
Node: import("../types.js").JSONSyntaxElement;
|
|
34
|
+
MessageIds: "topLevel";
|
|
35
|
+
}>): JSONRuleVisitor;
|
|
36
|
+
};
|
|
37
|
+
export default _default;
|
|
@@ -6,15 +6,14 @@
|
|
|
6
6
|
// Type Definitions
|
|
7
7
|
//-----------------------------------------------------------------------------
|
|
8
8
|
/**
|
|
9
|
-
* @import { JSONRuleDefinition } from "../types.js";
|
|
9
|
+
* @import { JSONRuleVisitor, JSONRuleDefinition } from "../types.js";
|
|
10
10
|
* @typedef {"topLevel"} TopLevelInteropMessageIds
|
|
11
11
|
* @typedef {JSONRuleDefinition<{ MessageIds: TopLevelInteropMessageIds }>} TopLevelInteropRuleDefinition
|
|
12
12
|
*/
|
|
13
13
|
//-----------------------------------------------------------------------------
|
|
14
14
|
// Rule Definition
|
|
15
15
|
//-----------------------------------------------------------------------------
|
|
16
|
-
/** @
|
|
17
|
-
const rule = {
|
|
16
|
+
export default /** @satisfies {TopLevelInteropRuleDefinition} */ {
|
|
18
17
|
meta: {
|
|
19
18
|
type: "problem",
|
|
20
19
|
languages: ["json/json", "json/jsonc", "json/json5"],
|
|
@@ -22,14 +21,14 @@ const rule = {
|
|
|
22
21
|
recommended: false,
|
|
23
22
|
description: "Require the JSON top-level value to be an array or object",
|
|
24
23
|
dialects: ["JSON", "JSONC", "JSON5"],
|
|
25
|
-
url: "https://github.com/eslint/json/
|
|
24
|
+
url: "https://github.com/eslint/json/blob/main/docs/rules/top-level-interop.md",
|
|
26
25
|
},
|
|
27
26
|
messages: {
|
|
28
27
|
topLevel: "Top level item should be array or object, got '{{type}}'.",
|
|
29
28
|
},
|
|
30
29
|
},
|
|
31
30
|
create(context) {
|
|
32
|
-
return {
|
|
31
|
+
return /** @type {JSONRuleVisitor} */ ({
|
|
33
32
|
Document(node) {
|
|
34
33
|
const { type } = node.body;
|
|
35
34
|
if (type !== "Object" && type !== "Array") {
|
|
@@ -40,7 +39,6 @@ const rule = {
|
|
|
40
39
|
});
|
|
41
40
|
}
|
|
42
41
|
},
|
|
43
|
-
};
|
|
42
|
+
});
|
|
44
43
|
},
|
|
45
44
|
};
|
|
46
|
-
export default rule;
|
package/dist/types.d.ts
CHANGED
|
@@ -2,11 +2,21 @@
|
|
|
2
2
|
* @fileoverview Additional types for this package.
|
|
3
3
|
* @author Nicholas C. Zakas
|
|
4
4
|
*/
|
|
5
|
-
import type { RuleVisitor } from "@eslint/core";
|
|
5
|
+
import type { LanguageOptions, RuleVisitor } from "@eslint/core";
|
|
6
6
|
import type { CustomRuleDefinitionType, CustomRuleTypeDefinitions, CustomRuleVisitorWithExit } from "@eslint/plugin-kit";
|
|
7
7
|
import type { DocumentNode, MemberNode, ElementNode, ObjectNode, ArrayNode, StringNode, NullNode, NumberNode, BooleanNode, NaNNode, InfinityNode, IdentifierNode, AnyNode, Token } from "@humanwhocodes/momoa";
|
|
8
|
-
import type {
|
|
8
|
+
import type { JSONSourceCode } from "./index.js";
|
|
9
9
|
type ValueNodeParent = DocumentNode | MemberNode | ElementNode;
|
|
10
|
+
/**
|
|
11
|
+
* Language options provided for JSON files.
|
|
12
|
+
*/
|
|
13
|
+
export interface JSONLanguageOptions extends LanguageOptions {
|
|
14
|
+
/**
|
|
15
|
+
* Whether to allow trailing commas in JSONC mode.
|
|
16
|
+
* @default false
|
|
17
|
+
*/
|
|
18
|
+
allowTrailingCommas?: boolean;
|
|
19
|
+
}
|
|
10
20
|
/**
|
|
11
21
|
* A JSON syntax element, including nodes and tokens.
|
|
12
22
|
*/
|
package/dist/util.d.ts
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
* @fileoverview Utility Library
|
|
3
3
|
* @author 루밀LuMir(lumirlumir)
|
|
4
4
|
*/
|
|
5
|
+
import type { MemberNode } from "@humanwhocodes/momoa";
|
|
6
|
+
import type { JSONSourceCode } from "./languages/json-source-code.js";
|
|
5
7
|
/**
|
|
6
8
|
* @import { MemberNode } from "@humanwhocodes/momoa";
|
|
7
9
|
* @import { JSONSourceCode } from "./languages/json-source-code.js";
|
|
@@ -11,13 +13,11 @@
|
|
|
11
13
|
* @param {MemberNode} node The node to get the key from.
|
|
12
14
|
* @returns {string} The key value.
|
|
13
15
|
*/
|
|
14
|
-
export function getKey(node: MemberNode): string;
|
|
16
|
+
export declare function getKey(node: MemberNode): string;
|
|
15
17
|
/**
|
|
16
18
|
* Gets the `MemberNode`'s raw key value.
|
|
17
19
|
* @param {MemberNode} node The node to get the raw key from.
|
|
18
20
|
* @param {JSONSourceCode} sourceCode The JSON source code object.
|
|
19
21
|
* @returns {string} The raw key value.
|
|
20
22
|
*/
|
|
21
|
-
export function getRawKey(node: MemberNode, sourceCode: JSONSourceCode): string;
|
|
22
|
-
import type { MemberNode } from "@humanwhocodes/momoa";
|
|
23
|
-
import type { JSONSourceCode } from "./languages/json-source-code.js";
|
|
23
|
+
export declare function getRawKey(node: MemberNode, sourceCode: JSONSourceCode): string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eslint/json",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "JSON linting plugin for ESLint",
|
|
5
5
|
"author": "Nicholas C. Zakas",
|
|
6
6
|
"type": "module",
|
|
@@ -59,8 +59,8 @@
|
|
|
59
59
|
"test:types": "tsc -p tests/types/tsconfig.json",
|
|
60
60
|
"test:types:5.3": "npx -p typescript@5.3 -y -- tsc -p tests/types/tsconfig.legacy.json",
|
|
61
61
|
"test:types:5.x": "npx -p typescript@5.x -y -- tsc -p tests/types/tsconfig.json",
|
|
62
|
-
"test:types:
|
|
63
|
-
"test:types:all": "npm run test:types && npm run test:types:5.3 && npm run test:types:5.x && npm run test:types:
|
|
62
|
+
"test:types:6.x": "npx -p typescript@6.x -y -- tsc -p tests/types/tsconfig.json",
|
|
63
|
+
"test:types:all": "npm run test:types && npm run test:types:5.3 && npm run test:types:5.x && npm run test:types:6.x"
|
|
64
64
|
},
|
|
65
65
|
"keywords": [
|
|
66
66
|
"eslint",
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
"@arethetypeswrong/cli": "^0.18.3",
|
|
81
81
|
"@types/natural-compare": "^1.4.3",
|
|
82
82
|
"@types/node": "^20.19.0",
|
|
83
|
-
"c8": "^
|
|
83
|
+
"c8": "^12.0.0",
|
|
84
84
|
"dedent": "^1.5.3",
|
|
85
85
|
"eslint": "^10.4.0",
|
|
86
86
|
"eslint-config-eslint": "^14.0.0",
|
|
@@ -90,11 +90,14 @@
|
|
|
90
90
|
"lint-staged": "^16.0.0",
|
|
91
91
|
"mdast-util-from-markdown": "^2.0.2",
|
|
92
92
|
"mocha": "^11.3.0",
|
|
93
|
-
"prettier": "3.
|
|
94
|
-
"typescript": "^
|
|
93
|
+
"prettier": "3.9.6",
|
|
94
|
+
"typescript": "^7.0.2",
|
|
95
95
|
"yorkie": "^2.0.0"
|
|
96
96
|
},
|
|
97
97
|
"engines": {
|
|
98
98
|
"node": "^20.19.0 || ^22.13.0 || >=24"
|
|
99
|
+
},
|
|
100
|
+
"allowScripts": {
|
|
101
|
+
"yorkie": true
|
|
99
102
|
}
|
|
100
103
|
}
|