@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 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://depot.dev"><img src="https://images.opencollective.com/depot/39125a1/logo.png" alt="Depot" height="32"></a> <a href="https://www.n-ix.com/"><img src="https://images.opencollective.com/n-ix-ltd/575a7a5/logo.png" alt="N-iX Ltd" 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://www.lambdatest.com"><img src="https://avatars.githubusercontent.com/u/171592363" alt="TestMu AI Open Source Office (Formerly LambdaTest)" height="32"></a></p>
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
@@ -5,6 +5,7 @@ export * from "./types.js";
5
5
  declare namespace plugin {
6
6
  export namespace meta {
7
7
  let name: string;
8
+ let namespace: string;
8
9
  let version: string;
9
10
  }
10
11
  export namespace languages {
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
- version: "1.1.0", // x-release-please-version
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
- // eslint-disable-next-line no-lone-blocks -- The block syntax { ... } ensures that TypeScript does not get confused about the type of `plugin`.
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: {
@@ -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": "1.1.0",
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.1.1",
70
- "@eslint/plugin-kit": "^0.6.1",
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.0.0",
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.1",
86
- "typescript": "^5.9.2",
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
  }