@eslint/json 0.7.0 → 0.8.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
@@ -155,6 +155,7 @@ export default [
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
157
  - `no-unsafe-values` - warns on values that are unsafe for interchange, such as numbers outside safe range or lone surrogates.
158
+ - `no-unnormalized-keys` - warns on keys containing [unnormalized characters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize#description). You can optionally specify the normalization form via `{ form: "form_name" }`, where `form_name` can be any of `"NFC"`, `"NFD"`, `"NFKC"`, or `"NFKD"`.
158
159
 
159
160
  ## Configuration Comments
160
161
 
@@ -455,7 +455,7 @@ class JSONLanguage {
455
455
 
456
456
  var noDuplicateKeys = {
457
457
  meta: {
458
- type: "problem",
458
+ type: /** @type {const} */ ("problem"),
459
459
 
460
460
  docs: {
461
461
  description: "Disallow duplicate keys in JSON objects",
@@ -508,7 +508,7 @@ var noDuplicateKeys = {
508
508
 
509
509
  var noEmptyKeys = {
510
510
  meta: {
511
- type: "problem",
511
+ type: /** @type {const} */ ("problem"),
512
512
 
513
513
  docs: {
514
514
  description: "Disallow empty keys in JSON objects",
@@ -545,7 +545,7 @@ var noEmptyKeys = {
545
545
 
546
546
  var noUnsafeValues = {
547
547
  meta: {
548
- type: "problem",
548
+ type: /** @type {const} */ ("problem"),
549
549
 
550
550
  docs: {
551
551
  description: "Disallow JSON values that are unsafe for interchange",
@@ -599,6 +599,61 @@ var noUnsafeValues = {
599
599
  },
600
600
  };
601
601
 
602
+ /**
603
+ * @fileoverview Rule to detect unnormalized keys in JSON.
604
+ * @author Bradley Meck Farias
605
+ */
606
+
607
+ var noUnnormalizedKeys = {
608
+ meta: {
609
+ type: /** @type {const} */ ("problem"),
610
+
611
+ docs: {
612
+ description: "Disallow JSON keys that are not normalized",
613
+ },
614
+
615
+ messages: {
616
+ unnormalizedKey: "Unnormalized key '{{key}}' found.",
617
+ },
618
+
619
+ schema: [
620
+ {
621
+ type: "object",
622
+ properties: {
623
+ form: {
624
+ enum: ["NFC", "NFD", "NFKC", "NFKD"],
625
+ },
626
+ },
627
+ additionalProperties: false,
628
+ },
629
+ ],
630
+ },
631
+
632
+ create(context) {
633
+ const normalization = context.options.length
634
+ ? text => text.normalize(context.options[0].form)
635
+ : text => text.normalize();
636
+ return {
637
+ Member(node) {
638
+ const key =
639
+ node.name.type === "String"
640
+ ? node.name.value
641
+ : node.name.name;
642
+
643
+ if (normalization(key) !== key) {
644
+ context.report({
645
+ loc: node.name.loc,
646
+ messageId: "unnormalizedKey",
647
+ data: {
648
+ key,
649
+ },
650
+ });
651
+ }
652
+ },
653
+ };
654
+ },
655
+ };
656
+
602
657
  /**
603
658
  * @fileoverview JSON plugin.
604
659
  * @author Nicholas C. Zakas
@@ -612,7 +667,7 @@ var noUnsafeValues = {
612
667
  const plugin = {
613
668
  meta: {
614
669
  name: "@eslint/json",
615
- version: "0.7.0", // x-release-please-version
670
+ version: "0.8.0", // x-release-please-version
616
671
  },
617
672
  languages: {
618
673
  json: new JSONLanguage({ mode: "json" }),
@@ -623,20 +678,25 @@ const plugin = {
623
678
  "no-duplicate-keys": noDuplicateKeys,
624
679
  "no-empty-keys": noEmptyKeys,
625
680
  "no-unsafe-values": noUnsafeValues,
681
+ "no-unnormalized-keys": noUnnormalizedKeys,
626
682
  },
627
- configs: {},
628
- };
629
-
630
- Object.assign(plugin.configs, {
631
- recommended: {
632
- plugins: { json: plugin },
633
- rules: {
634
- "json/no-duplicate-keys": "error",
635
- "json/no-empty-keys": "error",
636
- "json/no-unsafe-values": "error",
683
+ configs: {
684
+ recommended: {
685
+ plugins: {},
686
+ rules: /** @type {const} */ ({
687
+ "json/no-duplicate-keys": "error",
688
+ "json/no-empty-keys": "error",
689
+ "json/no-unsafe-values": "error",
690
+ "json/no-unnormalized-keys": "error",
691
+ }),
637
692
  },
638
693
  },
639
- });
694
+ };
695
+
696
+ // eslint-disable-next-line no-lone-blocks -- The block syntax { ... } ensures that TypeScript does not get confused about the type of `plugin`.
697
+ {
698
+ plugin.configs.recommended.plugins.json = plugin;
699
+ }
640
700
 
641
701
  exports.JSONLanguage = JSONLanguage;
642
702
  exports.JSONSourceCode = JSONSourceCode;
@@ -174,7 +174,7 @@ declare namespace plugin {
174
174
  let rules: {
175
175
  "no-duplicate-keys": {
176
176
  meta: {
177
- type: string;
177
+ type: "problem";
178
178
  docs: {
179
179
  description: string;
180
180
  };
@@ -190,7 +190,7 @@ declare namespace plugin {
190
190
  };
191
191
  "no-empty-keys": {
192
192
  meta: {
193
- type: string;
193
+ type: "problem";
194
194
  docs: {
195
195
  description: string;
196
196
  };
@@ -204,7 +204,7 @@ declare namespace plugin {
204
204
  };
205
205
  "no-unsafe-values": {
206
206
  meta: {
207
- type: string;
207
+ type: "problem";
208
208
  docs: {
209
209
  description: string;
210
210
  };
@@ -218,8 +218,42 @@ declare namespace plugin {
218
218
  String(node: any): void;
219
219
  };
220
220
  };
221
+ "no-unnormalized-keys": {
222
+ meta: {
223
+ type: "problem";
224
+ docs: {
225
+ description: string;
226
+ };
227
+ messages: {
228
+ unnormalizedKey: string;
229
+ };
230
+ schema: {
231
+ type: string;
232
+ properties: {
233
+ form: {
234
+ enum: string[];
235
+ };
236
+ };
237
+ additionalProperties: boolean;
238
+ }[];
239
+ };
240
+ create(context: any): {
241
+ Member(node: any): void;
242
+ };
243
+ };
221
244
  };
222
- let configs: {};
245
+ namespace configs {
246
+ namespace recommended {
247
+ export let plugins: {};
248
+ let rules_1: {
249
+ readonly "json/no-duplicate-keys": "error";
250
+ readonly "json/no-empty-keys": "error";
251
+ readonly "json/no-unsafe-values": "error";
252
+ readonly "json/no-unnormalized-keys": "error";
253
+ };
254
+ export { rules_1 as rules };
255
+ }
256
+ }
223
257
  }
224
258
  import { TextSourceCodeBase } from '@eslint/plugin-kit';
225
259
  import { Directive } from '@eslint/plugin-kit';
@@ -174,7 +174,7 @@ declare namespace plugin {
174
174
  let rules: {
175
175
  "no-duplicate-keys": {
176
176
  meta: {
177
- type: string;
177
+ type: "problem";
178
178
  docs: {
179
179
  description: string;
180
180
  };
@@ -190,7 +190,7 @@ declare namespace plugin {
190
190
  };
191
191
  "no-empty-keys": {
192
192
  meta: {
193
- type: string;
193
+ type: "problem";
194
194
  docs: {
195
195
  description: string;
196
196
  };
@@ -204,7 +204,7 @@ declare namespace plugin {
204
204
  };
205
205
  "no-unsafe-values": {
206
206
  meta: {
207
- type: string;
207
+ type: "problem";
208
208
  docs: {
209
209
  description: string;
210
210
  };
@@ -218,8 +218,42 @@ declare namespace plugin {
218
218
  String(node: any): void;
219
219
  };
220
220
  };
221
+ "no-unnormalized-keys": {
222
+ meta: {
223
+ type: "problem";
224
+ docs: {
225
+ description: string;
226
+ };
227
+ messages: {
228
+ unnormalizedKey: string;
229
+ };
230
+ schema: {
231
+ type: string;
232
+ properties: {
233
+ form: {
234
+ enum: string[];
235
+ };
236
+ };
237
+ additionalProperties: boolean;
238
+ }[];
239
+ };
240
+ create(context: any): {
241
+ Member(node: any): void;
242
+ };
243
+ };
221
244
  };
222
- let configs: {};
245
+ namespace configs {
246
+ namespace recommended {
247
+ export let plugins: {};
248
+ let rules_1: {
249
+ readonly "json/no-duplicate-keys": "error";
250
+ readonly "json/no-empty-keys": "error";
251
+ readonly "json/no-unsafe-values": "error";
252
+ readonly "json/no-unnormalized-keys": "error";
253
+ };
254
+ export { rules_1 as rules };
255
+ }
256
+ }
223
257
  }
224
258
  import { TextSourceCodeBase } from '@eslint/plugin-kit';
225
259
  import { Directive } from '@eslint/plugin-kit';
package/dist/esm/index.js CHANGED
@@ -452,7 +452,7 @@ class JSONLanguage {
452
452
 
453
453
  var noDuplicateKeys = {
454
454
  meta: {
455
- type: "problem",
455
+ type: /** @type {const} */ ("problem"),
456
456
 
457
457
  docs: {
458
458
  description: "Disallow duplicate keys in JSON objects",
@@ -505,7 +505,7 @@ var noDuplicateKeys = {
505
505
 
506
506
  var noEmptyKeys = {
507
507
  meta: {
508
- type: "problem",
508
+ type: /** @type {const} */ ("problem"),
509
509
 
510
510
  docs: {
511
511
  description: "Disallow empty keys in JSON objects",
@@ -542,7 +542,7 @@ var noEmptyKeys = {
542
542
 
543
543
  var noUnsafeValues = {
544
544
  meta: {
545
- type: "problem",
545
+ type: /** @type {const} */ ("problem"),
546
546
 
547
547
  docs: {
548
548
  description: "Disallow JSON values that are unsafe for interchange",
@@ -596,6 +596,61 @@ var noUnsafeValues = {
596
596
  },
597
597
  };
598
598
 
599
+ /**
600
+ * @fileoverview Rule to detect unnormalized keys in JSON.
601
+ * @author Bradley Meck Farias
602
+ */
603
+
604
+ var noUnnormalizedKeys = {
605
+ meta: {
606
+ type: /** @type {const} */ ("problem"),
607
+
608
+ docs: {
609
+ description: "Disallow JSON keys that are not normalized",
610
+ },
611
+
612
+ messages: {
613
+ unnormalizedKey: "Unnormalized key '{{key}}' found.",
614
+ },
615
+
616
+ schema: [
617
+ {
618
+ type: "object",
619
+ properties: {
620
+ form: {
621
+ enum: ["NFC", "NFD", "NFKC", "NFKD"],
622
+ },
623
+ },
624
+ additionalProperties: false,
625
+ },
626
+ ],
627
+ },
628
+
629
+ create(context) {
630
+ const normalization = context.options.length
631
+ ? text => text.normalize(context.options[0].form)
632
+ : text => text.normalize();
633
+ return {
634
+ Member(node) {
635
+ const key =
636
+ node.name.type === "String"
637
+ ? node.name.value
638
+ : node.name.name;
639
+
640
+ if (normalization(key) !== key) {
641
+ context.report({
642
+ loc: node.name.loc,
643
+ messageId: "unnormalizedKey",
644
+ data: {
645
+ key,
646
+ },
647
+ });
648
+ }
649
+ },
650
+ };
651
+ },
652
+ };
653
+
599
654
  /**
600
655
  * @fileoverview JSON plugin.
601
656
  * @author Nicholas C. Zakas
@@ -609,7 +664,7 @@ var noUnsafeValues = {
609
664
  const plugin = {
610
665
  meta: {
611
666
  name: "@eslint/json",
612
- version: "0.7.0", // x-release-please-version
667
+ version: "0.8.0", // x-release-please-version
613
668
  },
614
669
  languages: {
615
670
  json: new JSONLanguage({ mode: "json" }),
@@ -620,19 +675,24 @@ const plugin = {
620
675
  "no-duplicate-keys": noDuplicateKeys,
621
676
  "no-empty-keys": noEmptyKeys,
622
677
  "no-unsafe-values": noUnsafeValues,
678
+ "no-unnormalized-keys": noUnnormalizedKeys,
623
679
  },
624
- configs: {},
625
- };
626
-
627
- Object.assign(plugin.configs, {
628
- recommended: {
629
- plugins: { json: plugin },
630
- rules: {
631
- "json/no-duplicate-keys": "error",
632
- "json/no-empty-keys": "error",
633
- "json/no-unsafe-values": "error",
680
+ configs: {
681
+ recommended: {
682
+ plugins: {},
683
+ rules: /** @type {const} */ ({
684
+ "json/no-duplicate-keys": "error",
685
+ "json/no-empty-keys": "error",
686
+ "json/no-unsafe-values": "error",
687
+ "json/no-unnormalized-keys": "error",
688
+ }),
634
689
  },
635
690
  },
636
- });
691
+ };
692
+
693
+ // eslint-disable-next-line no-lone-blocks -- The block syntax { ... } ensures that TypeScript does not get confused about the type of `plugin`.
694
+ {
695
+ plugin.configs.recommended.plugins.json = plugin;
696
+ }
637
697
 
638
698
  export { JSONLanguage, JSONSourceCode, plugin as default };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eslint/json",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "JSON linting plugin for ESLint",
5
5
  "author": "Nicholas C. Zakas",
6
6
  "type": "module",
@@ -51,7 +51,8 @@
51
51
  "fmt": "prettier --write .",
52
52
  "fmt:check": "prettier --check .",
53
53
  "test": "mocha tests/**/*.js",
54
- "test:coverage": "c8 npm test"
54
+ "test:coverage": "c8 npm test",
55
+ "test:types": "tsc -p tests/types/tsconfig.json"
55
56
  },
56
57
  "keywords": [
57
58
  "eslint",
@@ -72,6 +73,7 @@
72
73
  "dedent": "^1.5.3",
73
74
  "eslint": "^9.11.1",
74
75
  "eslint-config-eslint": "^11.0.0",
76
+ "eslint-plugin-eslint-plugin": "^6.3.2",
75
77
  "got": "^14.4.2",
76
78
  "lint-staged": "^15.2.7",
77
79
  "mocha": "^10.4.0",