@eslint/json 0.12.0 → 0.13.1

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/dist/esm/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
 
2
2
  /**
3
- * @import { DocumentNode, Node, Token, AnyNode, MemberNode } from "@humanwhocodes/momoa"
4
- * @import { SourceLocation, FileProblem, DirectiveType, RulesConfig, TextSourceCode, Language, OkParseResult, ParseResult, File } from "@eslint/core"
3
+ * @import { DocumentNode, AnyNode, Token, MemberNode } from "@humanwhocodes/momoa"
4
+ * @import { SourceLocation, FileProblem, DirectiveType, RulesConfig, Language, OkParseResult, ParseResult, File } from "@eslint/core"
5
5
  * @import { JSONSyntaxElement, JSONRuleDefinition } from "./types.ts"
6
6
  */
7
7
  // @ts-self-types="./index.d.ts"
@@ -37,14 +37,14 @@ const INLINE_CONFIG =
37
37
  class JSONTraversalStep extends VisitNodeStep {
38
38
  /**
39
39
  * The target of the step.
40
- * @type {Node}
40
+ * @type {AnyNode}
41
41
  */
42
42
  target = undefined;
43
43
 
44
44
  /**
45
45
  * Creates a new instance.
46
46
  * @param {Object} options The options for the step.
47
- * @param {Node} options.target The target of the step.
47
+ * @param {AnyNode} options.target The target of the step.
48
48
  * @param {1|2} options.phase The phase of the step.
49
49
  * @param {Array<any>} options.args The arguments of the step.
50
50
  */
@@ -55,13 +55,44 @@ class JSONTraversalStep extends VisitNodeStep {
55
55
  }
56
56
  }
57
57
 
58
+ /**
59
+ * Processes tokens to extract comments and their starting tokens.
60
+ * @param {Array<Token>} tokens The tokens to process.
61
+ * @returns {{ comments: Array<Token>, starts: Map<number, number>, ends: Map<number, number>}}
62
+ * An object containing an array of comments, a map of starting token range to token index, and
63
+ * a map of ending token range to token index.
64
+ */
65
+ function processTokens(tokens) {
66
+ /** @type {Array<Token>} */
67
+ const comments = [];
68
+
69
+ /** @type {Map<number, number>} */
70
+ const starts = new Map();
71
+
72
+ /** @type {Map<number, number>} */
73
+ const ends = new Map();
74
+
75
+ for (let i = 0; i < tokens.length; i++) {
76
+ const token = tokens[i];
77
+
78
+ if (token.type.endsWith("Comment")) {
79
+ comments.push(token);
80
+ }
81
+
82
+ starts.set(token.range[0], i);
83
+ ends.set(token.range[1], i);
84
+ }
85
+
86
+ return { comments, starts, ends };
87
+ }
88
+
58
89
  //-----------------------------------------------------------------------------
59
90
  // Exports
60
91
  //-----------------------------------------------------------------------------
61
92
 
62
93
  /**
63
94
  * JSON Source Code Object
64
- * @implements {TextSourceCode<{LangOptions: JSONLanguageOptions, RootNode: DocumentNode, SyntaxElementWithLoc: JSONSyntaxElement, ConfigNode: Token}>}
95
+ * @extends {TextSourceCodeBase<{LangOptions: JSONLanguageOptions, RootNode: DocumentNode, SyntaxElementWithLoc: JSONSyntaxElement, ConfigNode: Token}>}
65
96
  */
66
97
  class JSONSourceCode extends TextSourceCodeBase {
67
98
  /**
@@ -72,7 +103,7 @@ class JSONSourceCode extends TextSourceCodeBase {
72
103
 
73
104
  /**
74
105
  * Cache of parent nodes.
75
- * @type {WeakMap<Node, Node>}
106
+ * @type {WeakMap<AnyNode, AnyNode>}
76
107
  */
77
108
  #parents = new WeakMap();
78
109
 
@@ -89,11 +120,23 @@ class JSONSourceCode extends TextSourceCodeBase {
89
120
  ast = undefined;
90
121
 
91
122
  /**
92
- * The comment node in the source code.
123
+ * The comment tokens in the source code.
93
124
  * @type {Array<Token>|undefined}
94
125
  */
95
126
  comments;
96
127
 
128
+ /**
129
+ * A map of token start positions to their corresponding index.
130
+ * @type {Map<number, number>}
131
+ */
132
+ #tokenStarts;
133
+
134
+ /**
135
+ * A map of token end positions to their corresponding index.
136
+ * @type {Map<number, number>}
137
+ */
138
+ #tokenEnds;
139
+
97
140
  /**
98
141
  * Creates a new instance.
99
142
  * @param {Object} options The options for the instance.
@@ -103,9 +146,11 @@ class JSONSourceCode extends TextSourceCodeBase {
103
146
  constructor({ text, ast }) {
104
147
  super({ text, ast });
105
148
  this.ast = ast;
106
- this.comments = ast.tokens
107
- ? ast.tokens.filter(token => token.type.endsWith("Comment"))
108
- : [];
149
+
150
+ const { comments, starts, ends } = processTokens(this.ast.tokens ?? []);
151
+ this.comments = comments;
152
+ this.#tokenStarts = starts;
153
+ this.#tokenEnds = ends;
109
154
  }
110
155
 
111
156
  /**
@@ -148,7 +193,9 @@ class JSONSourceCode extends TextSourceCodeBase {
148
193
  * that ESLint needs to further process the directives.
149
194
  */
150
195
  getDisableDirectives() {
196
+ /** @type {Array<FileProblem>} */
151
197
  const problems = [];
198
+ /** @type {Array<Directive>} */
152
199
  const directives = [];
153
200
 
154
201
  this.getInlineConfigNodes().forEach(comment => {
@@ -201,7 +248,9 @@ class JSONSourceCode extends TextSourceCodeBase {
201
248
  * that ESLint needs to further process the rule configurations.
202
249
  */
203
250
  applyInlineConfig() {
251
+ /** @type {Array<FileProblem>} */
204
252
  const problems = [];
253
+ /** @type {Array<{config:{rules:RulesConfig},loc:SourceLocation}>} */
205
254
  const configs = [];
206
255
 
207
256
  this.getInlineConfigNodes().forEach(comment => {
@@ -240,8 +289,8 @@ class JSONSourceCode extends TextSourceCodeBase {
240
289
 
241
290
  /**
242
291
  * Returns the parent of the given node.
243
- * @param {Node} node The node to get the parent of.
244
- * @returns {Node|undefined} The parent of the node.
292
+ * @param {AnyNode} node The node to get the parent of.
293
+ * @returns {AnyNode|undefined} The parent of the node.
245
294
  */
246
295
  getParent(node) {
247
296
  return this.#parents.get(node);
@@ -262,12 +311,15 @@ class JSONSourceCode extends TextSourceCodeBase {
262
311
 
263
312
  for (const { node, parent, phase } of iterator(this.ast)) {
264
313
  if (parent) {
265
- this.#parents.set(node, parent);
314
+ this.#parents.set(
315
+ /** @type {AnyNode} */ (node),
316
+ /** @type {AnyNode} */ (parent),
317
+ );
266
318
  }
267
319
 
268
320
  steps.push(
269
321
  new JSONTraversalStep({
270
- target: node,
322
+ target: /** @type {AnyNode} */ (node),
271
323
  phase: phase === "enter" ? 1 : 2,
272
324
  args: [node, parent],
273
325
  }),
@@ -276,10 +328,89 @@ class JSONSourceCode extends TextSourceCodeBase {
276
328
 
277
329
  return steps;
278
330
  }
331
+
332
+ /**
333
+ * Gets the token before the given node or token, optionally including comments.
334
+ * @param {AnyNode|Token} nodeOrToken The node or token to get the previous token for.
335
+ * @param {Object} [options] Options object.
336
+ * @param {boolean} [options.includeComments] If true, return comments when they are present.
337
+ * @returns {Token|null} The previous token or comment, or null if there is none.
338
+ */
339
+ getTokenBefore(nodeOrToken, { includeComments = false } = {}) {
340
+ const index = this.#tokenStarts.get(nodeOrToken.range[0]);
341
+
342
+ if (index === undefined) {
343
+ return null;
344
+ }
345
+
346
+ let previousIndex = index - 1;
347
+ if (previousIndex < 0) {
348
+ return null;
349
+ }
350
+
351
+ const tokens = this.ast.tokens;
352
+ let tokenOrComment = tokens[previousIndex];
353
+
354
+ if (includeComments) {
355
+ return tokenOrComment;
356
+ }
357
+
358
+ // skip comments
359
+ while (tokenOrComment?.type.endsWith("Comment")) {
360
+ previousIndex--;
361
+
362
+ if (previousIndex < 0) {
363
+ return null;
364
+ }
365
+
366
+ tokenOrComment = tokens[previousIndex];
367
+ }
368
+ return tokenOrComment;
369
+ }
370
+
371
+ /**
372
+ * Gets the token after the given node or token, skipping any comments unless includeComments is true.
373
+ * @param {AnyNode|Token} nodeOrToken The node or token to get the next token for.
374
+ * @param {Object} [options] Options object.
375
+ * @param {boolean} [options.includeComments=false] If true, return comments when they are present.
376
+ * @returns {Token|null} The next token or comment, or null if there is none.
377
+ */
378
+ getTokenAfter(nodeOrToken, { includeComments = false } = {}) {
379
+ const index = this.#tokenEnds.get(nodeOrToken.range[1]);
380
+
381
+ if (index === undefined) {
382
+ return null;
383
+ }
384
+
385
+ let nextIndex = index + 1;
386
+ const tokens = this.ast.tokens;
387
+ if (nextIndex >= tokens.length) {
388
+ return null;
389
+ }
390
+
391
+ let tokenOrComment = tokens[nextIndex];
392
+
393
+ if (includeComments) {
394
+ return tokenOrComment;
395
+ }
396
+
397
+ // skip comments
398
+ while (tokenOrComment?.type.endsWith("Comment")) {
399
+ nextIndex++;
400
+
401
+ if (nextIndex >= tokens.length) {
402
+ return null;
403
+ }
404
+
405
+ tokenOrComment = tokens[nextIndex];
406
+ }
407
+
408
+ return tokenOrComment;
409
+ }
279
410
  }
280
411
 
281
412
  /**
282
- * @filedescription Functions to fix up rules to provide missing methods on the `context` object.
413
+ * @fileoverview The JSONLanguage class.
283
414
  * @author Nicholas C. Zakas
284
415
  */
285
416
 
@@ -440,6 +571,13 @@ class JSONLanguage {
440
571
  /* eslint-enable class-methods-use-this -- Required to complete interface. */
441
572
  }
442
573
 
574
+ const rules$1 = /** @type {const} */ ({
575
+ "json/no-duplicate-keys": "error",
576
+ "json/no-empty-keys": "error",
577
+ "json/no-unnormalized-keys": "error",
578
+ "json/no-unsafe-values": "error"
579
+ });
580
+
443
581
  /**
444
582
  * @fileoverview Rule to prevent duplicate keys in JSON.
445
583
  * @author Nicholas C. Zakas
@@ -465,7 +603,9 @@ const rule$5 = {
465
603
  type: "problem",
466
604
 
467
605
  docs: {
606
+ recommended: true,
468
607
  description: "Disallow duplicate keys in JSON objects",
608
+ url: "https://github.com/eslint/json/tree/main/docs/rules/no-duplicate-keys.md",
469
609
  },
470
610
 
471
611
  messages: {
@@ -536,7 +676,9 @@ const rule$4 = {
536
676
  type: "problem",
537
677
 
538
678
  docs: {
679
+ recommended: true,
539
680
  description: "Disallow empty keys in JSON objects",
681
+ url: "https://github.com/eslint/json/tree/main/docs/rules/no-empty-keys.md",
540
682
  },
541
683
 
542
684
  messages: {
@@ -563,6 +705,80 @@ const rule$4 = {
563
705
  },
564
706
  };
565
707
 
708
+ /**
709
+ * @fileoverview Rule to detect unnormalized keys in JSON.
710
+ * @author Bradley Meck Farias
711
+ */
712
+
713
+ //-----------------------------------------------------------------------------
714
+ // Type Definitions
715
+ //-----------------------------------------------------------------------------
716
+
717
+ /**
718
+ *
719
+ * @typedef {"unnormalizedKey"} NoUnnormalizedKeysMessageIds
720
+ * @typedef {{ form: string }} NoUnnormalizedKeysOptions
721
+ * @typedef {JSONRuleDefinition<{ RuleOptions: [NoUnnormalizedKeysOptions], MessageIds: NoUnnormalizedKeysMessageIds }>} NoUnnormalizedKeysRuleDefinition
722
+ */
723
+
724
+ //-----------------------------------------------------------------------------
725
+ // Rule Definition
726
+ //-----------------------------------------------------------------------------
727
+
728
+ /** @type {NoUnnormalizedKeysRuleDefinition} */
729
+ const rule$3 = {
730
+ meta: {
731
+ type: "problem",
732
+
733
+ docs: {
734
+ recommended: true,
735
+ description: "Disallow JSON keys that are not normalized",
736
+ url: "https://github.com/eslint/json/tree/main/docs/rules/no-unnormalized-keys.md",
737
+ },
738
+
739
+ messages: {
740
+ unnormalizedKey: "Unnormalized key '{{key}}' found.",
741
+ },
742
+
743
+ schema: [
744
+ {
745
+ type: "object",
746
+ properties: {
747
+ form: {
748
+ enum: ["NFC", "NFD", "NFKC", "NFKD"],
749
+ },
750
+ },
751
+ additionalProperties: false,
752
+ },
753
+ ],
754
+ },
755
+
756
+ create(context) {
757
+ const form = context.options.length
758
+ ? context.options[0].form
759
+ : undefined;
760
+
761
+ return {
762
+ Member(node) {
763
+ const key =
764
+ node.name.type === "String"
765
+ ? node.name.value
766
+ : node.name.name;
767
+
768
+ if (key.normalize(form) !== key) {
769
+ context.report({
770
+ loc: node.name.loc,
771
+ messageId: "unnormalizedKey",
772
+ data: {
773
+ key,
774
+ },
775
+ });
776
+ }
777
+ },
778
+ };
779
+ },
780
+ };
781
+
566
782
  /**
567
783
  * @fileoverview Rule to detect unsafe values in JSON.
568
784
  * @author Bradley Meck Farias
@@ -598,12 +814,14 @@ const NON_ZERO = /[1-9]/u;
598
814
  //-----------------------------------------------------------------------------
599
815
 
600
816
  /** @type {NoUnsafeValuesRuleDefinition} */
601
- const rule$3 = {
817
+ const rule$2 = {
602
818
  meta: {
603
819
  type: "problem",
604
820
 
605
821
  docs: {
822
+ recommended: true,
606
823
  description: "Disallow JSON values that are unsafe for interchange",
824
+ url: "https://github.com/eslint/json/tree/main/docs/rules/no-unsafe-values.md",
607
825
  },
608
826
 
609
827
  messages: {
@@ -714,78 +932,6 @@ const rule$3 = {
714
932
  },
715
933
  };
716
934
 
717
- /**
718
- * @fileoverview Rule to detect unnormalized keys in JSON.
719
- * @author Bradley Meck Farias
720
- */
721
-
722
- //-----------------------------------------------------------------------------
723
- // Type Definitions
724
- //-----------------------------------------------------------------------------
725
-
726
- /**
727
- *
728
- * @typedef {"unnormalizedKey"} NoUnnormalizedKeysMessageIds
729
- * @typedef {{ form: string }} NoUnnormalizedKeysOptions
730
- * @typedef {JSONRuleDefinition<{ RuleOptions: [NoUnnormalizedKeysOptions], MessageIds: NoUnnormalizedKeysMessageIds }>} NoUnnormalizedKeysRuleDefinition
731
- */
732
-
733
- //-----------------------------------------------------------------------------
734
- // Rule Definition
735
- //-----------------------------------------------------------------------------
736
-
737
- /** @type {NoUnnormalizedKeysRuleDefinition} */
738
- const rule$2 = {
739
- meta: {
740
- type: "problem",
741
-
742
- docs: {
743
- description: "Disallow JSON keys that are not normalized",
744
- },
745
-
746
- messages: {
747
- unnormalizedKey: "Unnormalized key '{{key}}' found.",
748
- },
749
-
750
- schema: [
751
- {
752
- type: "object",
753
- properties: {
754
- form: {
755
- enum: ["NFC", "NFD", "NFKC", "NFKD"],
756
- },
757
- },
758
- additionalProperties: false,
759
- },
760
- ],
761
- },
762
-
763
- create(context) {
764
- const form = context.options.length
765
- ? context.options[0].form
766
- : undefined;
767
-
768
- return {
769
- Member(node) {
770
- const key =
771
- node.name.type === "String"
772
- ? node.name.value
773
- : node.name.name;
774
-
775
- if (key.normalize(form) !== key) {
776
- context.report({
777
- loc: node.name.loc,
778
- messageId: "unnormalizedKey",
779
- data: {
780
- key,
781
- },
782
- });
783
- }
784
- },
785
- };
786
- },
787
- };
788
-
789
935
  /**
790
936
  * @fileoverview Rule to require JSON object keys to be sorted.
791
937
  * Copied largely from https://github.com/eslint/eslint/blob/main/lib/rules/sort-keys.js
@@ -888,7 +1034,9 @@ const rule$1 = {
888
1034
  ],
889
1035
 
890
1036
  docs: {
1037
+ recommended: false,
891
1038
  description: `Require JSON object keys to be sorted`,
1039
+ url: "https://github.com/eslint/json/tree/main/docs/rules/sort-keys.md",
892
1040
  },
893
1041
 
894
1042
  messages: {
@@ -1017,7 +1165,7 @@ const rule$1 = {
1017
1165
  };
1018
1166
 
1019
1167
  /**
1020
- * @fileoverview Rule to ensure top-level items are either an array or ojbect.
1168
+ * @fileoverview Rule to ensure top-level items are either an array or object.
1021
1169
  * @author Joe Hildebrand
1022
1170
  */
1023
1171
 
@@ -1041,8 +1189,10 @@ const rule = {
1041
1189
  type: "problem",
1042
1190
 
1043
1191
  docs: {
1192
+ recommended: false,
1044
1193
  description:
1045
1194
  "Require the JSON top-level value to be an array or object",
1195
+ url: "https://github.com/eslint/json/tree/main/docs/rules/top-level-interop.md",
1046
1196
  },
1047
1197
 
1048
1198
  messages: {
@@ -1067,6 +1217,15 @@ const rule = {
1067
1217
  },
1068
1218
  };
1069
1219
 
1220
+ var rules = {
1221
+ "no-duplicate-keys": rule$5,
1222
+ "no-empty-keys": rule$4,
1223
+ "no-unnormalized-keys": rule$3,
1224
+ "no-unsafe-values": rule$2,
1225
+ "sort-keys": rule$1,
1226
+ "top-level-interop": rule,
1227
+ };
1228
+
1070
1229
  /**
1071
1230
  * @fileoverview JSON plugin.
1072
1231
  * @author Nicholas C. Zakas
@@ -1080,30 +1239,18 @@ const rule = {
1080
1239
  const plugin = {
1081
1240
  meta: {
1082
1241
  name: "@eslint/json",
1083
- version: "0.12.0", // x-release-please-version
1242
+ version: "0.13.1", // x-release-please-version
1084
1243
  },
1085
1244
  languages: {
1086
1245
  json: new JSONLanguage({ mode: "json" }),
1087
1246
  jsonc: new JSONLanguage({ mode: "jsonc" }),
1088
1247
  json5: new JSONLanguage({ mode: "json5" }),
1089
1248
  },
1090
- rules: {
1091
- "no-duplicate-keys": rule$5,
1092
- "no-empty-keys": rule$4,
1093
- "no-unsafe-values": rule$3,
1094
- "no-unnormalized-keys": rule$2,
1095
- "sort-keys": rule$1,
1096
- "top-level-interop": rule,
1097
- },
1249
+ rules,
1098
1250
  configs: {
1099
1251
  recommended: {
1100
1252
  plugins: {},
1101
- rules: /** @type {const} */ ({
1102
- "json/no-duplicate-keys": "error",
1103
- "json/no-empty-keys": "error",
1104
- "json/no-unsafe-values": "error",
1105
- "json/no-unnormalized-keys": "error",
1106
- }),
1253
+ rules: rules$1,
1107
1254
  },
1108
1255
  },
1109
1256
  };
@@ -2,7 +2,7 @@
2
2
  * @fileoverview Additional types for this package.
3
3
  * @author Nicholas C. Zakas
4
4
  */
5
- import type { RuleVisitor, RuleDefinition } from "@eslint/core";
5
+ import type { CustomRuleDefinitionType, CustomRuleTypeDefinitions, RuleVisitor } from "@eslint/core";
6
6
  import type { DocumentNode, MemberNode, ElementNode, ObjectNode, ArrayNode, StringNode, NullNode, NumberNode, BooleanNode, NaNNode, InfinityNode, IdentifierNode, AnyNode, Token } from "@humanwhocodes/momoa";
7
7
  import type { JSONLanguageOptions, JSONSourceCode } from "./index.js";
8
8
  type ValueNodeParent = DocumentNode | MemberNode | ElementNode;
@@ -39,15 +39,11 @@ export interface JSONRuleVisitor extends RuleVisitor {
39
39
  "Infinity:exit"?(node: InfinityNode, parent?: ValueNodeParent): void;
40
40
  "Identifier:exit"?(node: IdentifierNode, parent?: ValueNodeParent): void;
41
41
  }
42
- export type JSONRuleDefinitionTypeOptions = {
43
- RuleOptions: unknown[];
44
- MessageIds: string;
45
- ExtRuleDocs: Record<string, unknown>;
46
- };
47
- export type JSONRuleDefinition<Options extends Partial<JSONRuleDefinitionTypeOptions> = {}> = RuleDefinition<{
42
+ export type JSONRuleDefinitionTypeOptions = CustomRuleTypeDefinitions;
43
+ export type JSONRuleDefinition<Options extends Partial<JSONRuleDefinitionTypeOptions> = {}> = CustomRuleDefinitionType<{
48
44
  LangOptions: JSONLanguageOptions;
49
45
  Code: JSONSourceCode;
50
46
  Visitor: JSONRuleVisitor;
51
47
  Node: AnyNode;
52
- } & Required<Options & Omit<JSONRuleDefinitionTypeOptions, keyof Options>>>;
48
+ }, Options>;
53
49
  export {};
package/dist/esm/types.ts CHANGED
@@ -7,7 +7,11 @@
7
7
  // Imports
8
8
  //------------------------------------------------------------------------------
9
9
 
10
- import type { RuleVisitor, RuleDefinition } from "@eslint/core";
10
+ import type {
11
+ CustomRuleDefinitionType,
12
+ CustomRuleTypeDefinitions,
13
+ RuleVisitor,
14
+ } from "@eslint/core";
11
15
  import type {
12
16
  DocumentNode,
13
17
  MemberNode,
@@ -68,25 +72,16 @@ export interface JSONRuleVisitor extends RuleVisitor {
68
72
  "Identifier:exit"?(node: IdentifierNode, parent?: ValueNodeParent): void;
69
73
  }
70
74
 
71
- export type JSONRuleDefinitionTypeOptions = {
72
- RuleOptions: unknown[];
73
- MessageIds: string;
74
- ExtRuleDocs: Record<string, unknown>;
75
- };
75
+ export type JSONRuleDefinitionTypeOptions = CustomRuleTypeDefinitions;
76
76
 
77
77
  export type JSONRuleDefinition<
78
78
  Options extends Partial<JSONRuleDefinitionTypeOptions> = {},
79
- > = RuleDefinition<
80
- // Language specific type options (non-configurable)
79
+ > = CustomRuleDefinitionType<
81
80
  {
82
81
  LangOptions: JSONLanguageOptions;
83
82
  Code: JSONSourceCode;
84
83
  Visitor: JSONRuleVisitor;
85
84
  Node: AnyNode;
86
- } & Required<
87
- // Rule specific type options (custom)
88
- Options &
89
- // Rule specific type options (defaults)
90
- Omit<JSONRuleDefinitionTypeOptions, keyof Options>
91
- >
85
+ },
86
+ Options
92
87
  >;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eslint/json",
3
- "version": "0.12.0",
3
+ "version": "0.13.1",
4
4
  "description": "JSON linting plugin for ESLint",
5
5
  "author": "Nicholas C. Zakas",
6
6
  "type": "module",
@@ -40,7 +40,14 @@
40
40
  "eslint --fix",
41
41
  "prettier --write"
42
42
  ],
43
- "!(*.js)": "prettier --write --ignore-unknown"
43
+ "!(*.js)": "prettier --write --ignore-unknown",
44
+ "README.md": [
45
+ "npm run build:update-rules-docs"
46
+ ],
47
+ "{src/rules/*.js,tools/update-rules-docs.js}": [
48
+ "npm run build:update-rules-docs",
49
+ "git add README.md"
50
+ ]
44
51
  },
45
52
  "repository": {
46
53
  "type": "git",
@@ -53,14 +60,17 @@
53
60
  "scripts": {
54
61
  "build:dedupe-types": "node tools/dedupe-types.js dist/cjs/index.cjs dist/esm/index.js",
55
62
  "build:cts": "node tools/build-cts.js",
56
- "build": "rollup -c && npm run build:dedupe-types && tsc -p tsconfig.esm.json && npm run build:cts",
63
+ "build:rules": "node tools/build-rules.js",
64
+ "build": "npm run build:rules && rollup -c && npm run build:dedupe-types && tsc -p tsconfig.esm.json && npm run build:cts",
57
65
  "build:readme": "node tools/update-readme.js",
58
- "test:jsr": "npx jsr@latest publish --dry-run",
66
+ "build:update-rules-docs": "node tools/update-rules-docs.js",
67
+ "prepare": "npm run build",
59
68
  "pretest": "npm run build",
60
69
  "lint": "eslint",
61
70
  "fmt": "prettier --write .",
62
71
  "fmt:check": "prettier --check .",
63
72
  "test": "mocha tests/**/*.js",
73
+ "test:jsr": "npx jsr@latest publish --dry-run",
64
74
  "test:coverage": "c8 npm test",
65
75
  "test:types": "tsc -p tests/types/tsconfig.json"
66
76
  },
@@ -73,25 +83,26 @@
73
83
  ],
74
84
  "license": "Apache-2.0",
75
85
  "dependencies": {
76
- "@eslint/core": "^0.12.0",
77
- "@eslint/plugin-kit": "^0.2.7",
78
- "@humanwhocodes/momoa": "^3.3.4",
86
+ "@eslint/core": "^0.15.1",
87
+ "@eslint/plugin-kit": "^0.3.4",
88
+ "@humanwhocodes/momoa": "^3.3.8",
79
89
  "natural-compare": "^1.4.0"
80
90
  },
81
91
  "devDependencies": {
82
- "c8": "^9.1.0",
92
+ "c8": "^10.1.3",
83
93
  "dedent": "^1.5.3",
84
- "eslint": "^9.23.0",
94
+ "eslint": "^9.31.0",
85
95
  "eslint-config-eslint": "^11.0.0",
86
96
  "eslint-plugin-eslint-plugin": "^6.3.2",
87
97
  "got": "^14.4.2",
88
98
  "lint-staged": "^15.2.7",
89
- "mocha": "^10.4.0",
99
+ "mdast-util-from-markdown": "^2.0.2",
100
+ "mocha": "^11.3.0",
90
101
  "prettier": "^3.4.1",
91
- "rollup": "^4.16.2",
102
+ "rollup": "^4.41.0",
92
103
  "rollup-plugin-copy": "^3.5.0",
93
104
  "rollup-plugin-delete": "^3.0.1",
94
- "typescript": "^5.4.5",
105
+ "typescript": "^5.8.3",
95
106
  "yorkie": "^2.0.0"
96
107
  },
97
108
  "engines": {