@eslint/json 1.1.0 → 2.0.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 +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -5
- package/dist/rules/no-duplicate-keys.js +2 -0
- package/dist/rules/no-empty-keys.js +2 -0
- package/dist/rules/no-unnormalized-keys.js +2 -0
- package/dist/rules/no-unsafe-values.js +2 -0
- package/dist/rules/sort-keys.js +36 -0
- package/dist/rules/top-level-interop.js +2 -0
- package/package.json +20 -7
package/README.md
CHANGED
|
@@ -296,7 +296,7 @@ to get your logo on our READMEs and [website](https://eslint.org/sponsors).
|
|
|
296
296
|
<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
297
|
<p><a href="https://qlty.sh/"><img src="https://images.opencollective.com/qltysh/33d157d/logo.png" alt="Qlty Software" height="96"></a></p><h3>Silver Sponsors</h3>
|
|
298
298
|
<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://www.crawljobs.com/"><img src="https://images.opencollective.com/crawljobs-poland/fa43a17/logo.png" alt="CrawlJobs" height="32"></a> <a href="https://
|
|
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://www.crawljobs.com/"><img src="https://images.opencollective.com/crawljobs-poland/fa43a17/logo.png" alt="CrawlJobs" height="32"></a> <a href="https://syntax.fm"><img src="https://github.com/syntaxfm.png" alt="Syntax" height="32"></a> <a href="https://depot.dev"><img src="https://images.opencollective.com/depot/39125a1/logo.png" alt="Depot" 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://herocoders.com"><img src="https://avatars.githubusercontent.com/u/37549774" alt="HeroCoders" height="32"></a> <a href="https://citadel.co.jp"><img src="https://avatars.githubusercontent.com/u/75781367" alt="Citadel AI" height="32"></a></p>
|
|
300
300
|
<h3>Technology Sponsors</h3>
|
|
301
301
|
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
302
|
<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/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -15,7 +15,8 @@ import rules from "./build/rules.js";
|
|
|
15
15
|
const plugin = {
|
|
16
16
|
meta: {
|
|
17
17
|
name: "@eslint/json",
|
|
18
|
-
|
|
18
|
+
namespace: "json",
|
|
19
|
+
version: "2.0.0", // x-release-please-version
|
|
19
20
|
},
|
|
20
21
|
languages: {
|
|
21
22
|
json: new JSONLanguage({ mode: "json" }),
|
|
@@ -31,10 +32,7 @@ const plugin = {
|
|
|
31
32
|
},
|
|
32
33
|
},
|
|
33
34
|
};
|
|
34
|
-
|
|
35
|
-
{
|
|
36
|
-
plugin.configs.recommended.plugins.json = plugin;
|
|
37
|
-
}
|
|
35
|
+
Object.assign(plugin.configs.recommended.plugins, { json: plugin });
|
|
38
36
|
export default plugin;
|
|
39
37
|
export { JSONSourceCode };
|
|
40
38
|
export * from "./languages/json-language.js";
|
|
@@ -22,9 +22,11 @@ import { getKey, getRawKey } from "../util.js";
|
|
|
22
22
|
const rule = {
|
|
23
23
|
meta: {
|
|
24
24
|
type: "problem",
|
|
25
|
+
languages: ["json/json", "json/jsonc", "json/json5"],
|
|
25
26
|
docs: {
|
|
26
27
|
recommended: true,
|
|
27
28
|
description: "Disallow duplicate keys in JSON objects",
|
|
29
|
+
dialects: ["JSON", "JSONC", "JSON5"],
|
|
28
30
|
url: "https://github.com/eslint/json/tree/main/docs/rules/no-duplicate-keys.md",
|
|
29
31
|
},
|
|
30
32
|
messages: {
|
|
@@ -21,9 +21,11 @@ import { getKey } from "../util.js";
|
|
|
21
21
|
const rule = {
|
|
22
22
|
meta: {
|
|
23
23
|
type: "problem",
|
|
24
|
+
languages: ["json/json", "json/jsonc", "json/json5"],
|
|
24
25
|
docs: {
|
|
25
26
|
recommended: true,
|
|
26
27
|
description: "Disallow empty keys in JSON objects",
|
|
28
|
+
dialects: ["JSON", "JSONC", "JSON5"],
|
|
27
29
|
url: "https://github.com/eslint/json/tree/main/docs/rules/no-empty-keys.md",
|
|
28
30
|
},
|
|
29
31
|
messages: {
|
|
@@ -22,10 +22,12 @@ import { getKey, getRawKey } from "../util.js";
|
|
|
22
22
|
const rule = {
|
|
23
23
|
meta: {
|
|
24
24
|
type: "problem",
|
|
25
|
+
languages: ["json/json", "json/jsonc", "json/json5"],
|
|
25
26
|
fixable: "code",
|
|
26
27
|
docs: {
|
|
27
28
|
recommended: true,
|
|
28
29
|
description: "Disallow JSON keys that are not normalized",
|
|
30
|
+
dialects: ["JSON", "JSONC", "JSON5"],
|
|
29
31
|
url: "https://github.com/eslint/json/tree/main/docs/rules/no-unnormalized-keys.md",
|
|
30
32
|
},
|
|
31
33
|
messages: {
|
|
@@ -32,9 +32,11 @@ const NON_ZERO = /[1-9]/u;
|
|
|
32
32
|
const rule = {
|
|
33
33
|
meta: {
|
|
34
34
|
type: "problem",
|
|
35
|
+
languages: ["json/json", "json/jsonc", "json/json5"],
|
|
35
36
|
docs: {
|
|
36
37
|
recommended: true,
|
|
37
38
|
description: "Disallow JSON values that are unsafe for interchange",
|
|
39
|
+
dialects: ["JSON", "JSONC", "JSON5"],
|
|
38
40
|
url: "https://github.com/eslint/json/tree/main/docs/rules/no-unsafe-values.md",
|
|
39
41
|
},
|
|
40
42
|
messages: {
|
package/dist/rules/sort-keys.js
CHANGED
|
@@ -33,6 +33,7 @@ import { getKey, getRawKey } from "../util.js";
|
|
|
33
33
|
// Helpers
|
|
34
34
|
//-----------------------------------------------------------------------------
|
|
35
35
|
const hasNonWhitespace = /\S/u;
|
|
36
|
+
const commentTypes = new Set(["LineComment", "BlockComment"]);
|
|
36
37
|
/** @type {ComparatorMap} */
|
|
37
38
|
const comparators = {
|
|
38
39
|
ascending: {
|
|
@@ -63,6 +64,8 @@ const comparators = {
|
|
|
63
64
|
const rule = {
|
|
64
65
|
meta: {
|
|
65
66
|
type: "suggestion",
|
|
67
|
+
languages: ["json/json", "json/jsonc", "json/json5"],
|
|
68
|
+
fixable: "code",
|
|
66
69
|
defaultOptions: [
|
|
67
70
|
"asc",
|
|
68
71
|
{
|
|
@@ -75,6 +78,7 @@ const rule = {
|
|
|
75
78
|
docs: {
|
|
76
79
|
recommended: false,
|
|
77
80
|
description: `Require JSON object keys to be sorted`,
|
|
81
|
+
dialects: ["JSON", "JSONC", "JSON5"],
|
|
78
82
|
url: "https://github.com/eslint/json/tree/main/docs/rules/sort-keys.md",
|
|
79
83
|
},
|
|
80
84
|
messages: {
|
|
@@ -144,6 +148,25 @@ const rule = {
|
|
|
144
148
|
}
|
|
145
149
|
return false;
|
|
146
150
|
}
|
|
151
|
+
/**
|
|
152
|
+
* Checks if a member has a comment before or after it.
|
|
153
|
+
* @param {MemberNode} member The member to check.
|
|
154
|
+
* @returns {boolean} True if a comment is adjacent to the member.
|
|
155
|
+
*/
|
|
156
|
+
function hasAdjacentComment(member) {
|
|
157
|
+
const before = sourceCode.getTokenBefore(member, {
|
|
158
|
+
includeComments: true,
|
|
159
|
+
});
|
|
160
|
+
let after = sourceCode.getTokenAfter(member, {
|
|
161
|
+
includeComments: true,
|
|
162
|
+
});
|
|
163
|
+
if (after.type === "Comma") {
|
|
164
|
+
after = sourceCode.getTokenAfter(after, {
|
|
165
|
+
includeComments: true,
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
return (commentTypes.has(before.type) || commentTypes.has(after.type));
|
|
169
|
+
}
|
|
147
170
|
return {
|
|
148
171
|
Object(node) {
|
|
149
172
|
/** @type {MemberNode} */
|
|
@@ -158,6 +181,9 @@ const rule = {
|
|
|
158
181
|
for (const member of node.members) {
|
|
159
182
|
const thisName = getKey(member);
|
|
160
183
|
const thisRawName = getRawKey(member, sourceCode);
|
|
184
|
+
// Capture `prevMember` for this iteration so the fixer closure uses the
|
|
185
|
+
// intended node even though `prevMember` is reassigned in the loop.
|
|
186
|
+
const prevMemberNode = prevMember;
|
|
161
187
|
if (prevMember &&
|
|
162
188
|
!isValidOrder(prevName, thisName) &&
|
|
163
189
|
(!allowLineSeparatedGroups ||
|
|
@@ -172,6 +198,16 @@ const rule = {
|
|
|
172
198
|
sensitivity,
|
|
173
199
|
sortName,
|
|
174
200
|
},
|
|
201
|
+
fix(fixer) {
|
|
202
|
+
if (hasAdjacentComment(member) ||
|
|
203
|
+
hasAdjacentComment(prevMemberNode)) {
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
206
|
+
return [
|
|
207
|
+
fixer.replaceText(member, sourceCode.getText(prevMemberNode)),
|
|
208
|
+
fixer.replaceText(prevMemberNode, sourceCode.getText(member)),
|
|
209
|
+
];
|
|
210
|
+
},
|
|
175
211
|
});
|
|
176
212
|
}
|
|
177
213
|
prevMember = member;
|
|
@@ -17,9 +17,11 @@
|
|
|
17
17
|
const rule = {
|
|
18
18
|
meta: {
|
|
19
19
|
type: "problem",
|
|
20
|
+
languages: ["json/json", "json/jsonc", "json/json5"],
|
|
20
21
|
docs: {
|
|
21
22
|
recommended: false,
|
|
22
23
|
description: "Require the JSON top-level value to be an array or object",
|
|
24
|
+
dialects: ["JSON", "JSONC", "JSON5"],
|
|
23
25
|
url: "https://github.com/eslint/json/tree/main/docs/rules/top-level-interop.md",
|
|
24
26
|
},
|
|
25
27
|
messages: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eslint/json",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "JSON linting plugin for ESLint",
|
|
5
5
|
"author": "Nicholas C. Zakas",
|
|
6
6
|
"type": "module",
|
|
@@ -50,12 +50,17 @@
|
|
|
50
50
|
"lint": "eslint",
|
|
51
51
|
"lint:fix": "eslint --fix",
|
|
52
52
|
"lint:types": "attw --pack --profile esm-only",
|
|
53
|
+
"lint:unused": "knip",
|
|
53
54
|
"fmt": "prettier --write .",
|
|
54
55
|
"fmt:check": "prettier --check .",
|
|
55
56
|
"test": "mocha \"tests/**/*.test.js\"",
|
|
56
57
|
"test:coverage": "c8 npm test",
|
|
57
58
|
"test:jsr": "npx -y jsr@latest publish --dry-run",
|
|
58
|
-
"test:types": "tsc -p tests/types/tsconfig.json"
|
|
59
|
+
"test:types": "tsc -p tests/types/tsconfig.json",
|
|
60
|
+
"test:types:5.3": "npx -p typescript@5.3 -y -- tsc -p tests/types/tsconfig.legacy.json",
|
|
61
|
+
"test:types:5.x": "npx -p typescript@5.x -y -- tsc -p tests/types/tsconfig.json",
|
|
62
|
+
"test:types:7.x": "npx -p @typescript/native-preview@latest -y -- tsgo -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:7.x"
|
|
59
64
|
},
|
|
60
65
|
"keywords": [
|
|
61
66
|
"eslint",
|
|
@@ -66,26 +71,34 @@
|
|
|
66
71
|
],
|
|
67
72
|
"license": "Apache-2.0",
|
|
68
73
|
"dependencies": {
|
|
69
|
-
"@eslint/core": "^1.
|
|
70
|
-
"@eslint/plugin-kit": "^0.
|
|
74
|
+
"@eslint/core": "^1.2.1",
|
|
75
|
+
"@eslint/plugin-kit": "^0.7.1",
|
|
71
76
|
"@humanwhocodes/momoa": "^3.3.10",
|
|
72
77
|
"natural-compare": "^1.4.0"
|
|
73
78
|
},
|
|
74
79
|
"devDependencies": {
|
|
75
80
|
"@arethetypeswrong/cli": "^0.18.2",
|
|
81
|
+
"@types/natural-compare": "^1.4.3",
|
|
82
|
+
"@types/node": "^20.19.0",
|
|
76
83
|
"c8": "^11.0.0",
|
|
77
84
|
"dedent": "^1.5.3",
|
|
78
|
-
"eslint": "^10.
|
|
85
|
+
"eslint": "^10.4.0",
|
|
79
86
|
"eslint-config-eslint": "^14.0.0",
|
|
80
87
|
"eslint-plugin-eslint-plugin": "^7.3.2",
|
|
81
88
|
"globals": "^17.0.0",
|
|
89
|
+
"knip": "^6.0.0",
|
|
82
90
|
"lint-staged": "^16.0.0",
|
|
83
91
|
"mdast-util-from-markdown": "^2.0.2",
|
|
84
92
|
"mocha": "^11.3.0",
|
|
85
|
-
"prettier": "3.8.
|
|
86
|
-
"typescript": "^
|
|
93
|
+
"prettier": "3.8.3",
|
|
94
|
+
"typescript": "^6.0.2",
|
|
87
95
|
"yorkie": "^2.0.0"
|
|
88
96
|
},
|
|
97
|
+
"overrides": {
|
|
98
|
+
"@arethetypeswrong/core": {
|
|
99
|
+
"fflate": "0.8.2"
|
|
100
|
+
}
|
|
101
|
+
},
|
|
89
102
|
"engines": {
|
|
90
103
|
"node": "^20.19.0 || ^22.13.0 || >=24"
|
|
91
104
|
}
|