@sushichan044/eslint-todo 0.1.1 → 0.1.3

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
@@ -1,5 +1,8 @@
1
1
  # @sushichan044/eslint-todo
2
2
 
3
+ > [!CAUTION]
4
+ > This library will soon be subject to destructive changes based on [ESLint bulk suppressions](https://eslint.org/blog/2025/04/introducing-bulk-suppressions/#getting-started).
5
+
3
6
  Simple tool to temporarily disable existing ESLint violations like `.rubocop_todo.yml` in RuboCop.
4
7
 
5
8
  It also has a utility that helps reducing ignored violations at your pace.
@@ -2,13 +2,11 @@ import { defineCommand, runMain } from 'citty';
2
2
  import { createConsola } from 'consola';
3
3
  import { colorize } from 'consola/utils';
4
4
  import { relative } from 'pathe';
5
- import { r as resolveConfig } from '../shared/eslint-todo.BAvNAJxm.mjs';
6
- import { L as LATEST_TODO_MODULE_HANDLER, i as isNonEmptyString, T as TodoModuleV1Handler, E as ESLintTodoCore } from '../shared/eslint-todo.CgzyQ8Wn.mjs';
5
+ import { t as toRuleBasedSuppression, S as SuppressionsJsonGenerator, T as TodoModuleV1Handler, r as resolveConfig } from '../shared/eslint-todo.Cf8KdZHE.mjs';
6
+ import { T as TodoModuleV2Handler, i as isRuleFixable, a as isNonEmptyString, r as readESLintConfig, c as createESLintConfigSubset, E as ESLintTodoCore } from '../shared/eslint-todo.BOQSBLS6.mjs';
7
7
  import { createHooks } from 'hookable';
8
8
  import { launchRemoteESLintTodoCore } from '../remote/client.mjs';
9
9
  import { klona } from 'klona/json';
10
- import 'typia/lib/internal/_accessExpressionAsString.js';
11
- import 'typia/lib/internal/_validateReport.js';
12
10
  import '../config/index.mjs';
13
11
  import 'defu';
14
12
  import 'eslint';
@@ -17,7 +15,9 @@ import 'node:fs/promises';
17
15
  import 'magicast';
18
16
  import 'klona';
19
17
  import 'node:process';
20
- import 'valibot';
18
+ import 'bundle-require';
19
+ import 'find-up';
20
+ import 'mlly';
21
21
  import 'cross-spawn';
22
22
  import 'jiti';
23
23
  import 'comlink';
@@ -25,7 +25,7 @@ import 'comlink/dist/esm/node-adapter.mjs';
25
25
  import 'node:url';
26
26
  import 'node:worker_threads';
27
27
 
28
- const version = "0.1.0";
28
+ const version = "0.1.2";
29
29
 
30
30
  const defineAction = (action) => {
31
31
  return action;
@@ -43,6 +43,7 @@ function prepareAction(action, options) {
43
43
  const actionApi = {
44
44
  config: options.config,
45
45
  core: remoteCore,
46
+ eslintConfig: options.eslintConfig,
46
47
  hooks,
47
48
  logger: options.consola
48
49
  };
@@ -90,7 +91,7 @@ const deleteRule = (currentModule, ruleSelection) => {
90
91
  const deleteRuleAction = defineAction(
91
92
  async ({ core, hooks }, input) => {
92
93
  const currentModule = await core.readTodoModule();
93
- if (!LATEST_TODO_MODULE_HANDLER.isVersion(currentModule)) {
94
+ if (!TodoModuleV2Handler.isVersion(currentModule)) {
94
95
  throw new Error(
95
96
  "This action requires the latest version of the todo file."
96
97
  );
@@ -127,13 +128,21 @@ const genAction = defineAction(
127
128
  }
128
129
  );
129
130
 
130
- const selectRuleBasedOnLimit = (todoModule, correctConfig) => {
131
+ const selectRuleBasedOnLimit = (suppressions, eslintConfig, correctConfig) => {
131
132
  switch (correctConfig.limit.type) {
132
133
  case "file": {
133
- return selectRuleBasedOnFilesLimit(todoModule, correctConfig);
134
+ return selectRuleBasedOnFilesLimit(
135
+ suppressions,
136
+ eslintConfig,
137
+ correctConfig
138
+ );
134
139
  }
135
140
  case "violation": {
136
- return selectRuleBasedOnViolationsLimit(todoModule, correctConfig);
141
+ return selectRuleBasedOnViolationsLimit(
142
+ suppressions,
143
+ eslintConfig,
144
+ correctConfig
145
+ );
137
146
  }
138
147
  default: {
139
148
  const l = correctConfig.limit.type;
@@ -141,7 +150,7 @@ const selectRuleBasedOnLimit = (todoModule, correctConfig) => {
141
150
  }
142
151
  }
143
152
  };
144
- const selectRuleBasedOnFilesLimit = (todoModule, config) => {
153
+ const selectRuleBasedOnFilesLimit = (suppressions, eslintConfig, config) => {
145
154
  const {
146
155
  autoFixableOnly,
147
156
  exclude: { rules: excludedRules },
@@ -154,14 +163,15 @@ const selectRuleBasedOnFilesLimit = (todoModule, config) => {
154
163
  let fullSelectableRule = null;
155
164
  let selectedTargetCount = 0;
156
165
  let partialSelectableRule = null;
157
- for (const [ruleId, entry] of Object.entries(todoModule.todo)) {
158
- if (autoFixableOnly && !entry.autoFix) {
166
+ const ruleBasedSuppressions = toRuleBasedSuppression(suppressions);
167
+ for (const [ruleId, entry] of Object.entries(ruleBasedSuppressions)) {
168
+ if (autoFixableOnly && !isRuleFixable(eslintConfig, ruleId)) {
159
169
  continue;
160
170
  }
161
171
  if (excludedRules.includes(ruleId)) {
162
172
  continue;
163
173
  }
164
- const violatedFiles = Object.keys(entry.violations).length;
174
+ const violatedFiles = Object.keys(entry).length;
165
175
  if (violatedFiles > limitCount) {
166
176
  if (allowPartialSelection && partialSelectableRule == null) {
167
177
  partialSelectableRule = ruleId;
@@ -182,12 +192,11 @@ const selectRuleBasedOnFilesLimit = (todoModule, config) => {
182
192
  success: true
183
193
  };
184
194
  }
185
- if (allowPartialSelection && isKeyOfTodoModuleV2(todoModule, partialSelectableRule)) {
186
- const rule = todoModule.todo[partialSelectableRule];
187
- const selectedPaths = Object.keys(rule.violations).slice(0, limitCount);
195
+ if (allowPartialSelection && partialSelectableRule != null && Object.hasOwn(ruleBasedSuppressions, partialSelectableRule)) {
196
+ const rule = ruleBasedSuppressions[partialSelectableRule];
188
197
  const selectedViolations = {};
189
- for (const file of selectedPaths) {
190
- selectedViolations[file] = rule.violations[file];
198
+ for (const file of Object.keys(rule).slice(0, limitCount)) {
199
+ selectedViolations[file] = rule[file].count;
191
200
  }
192
201
  return {
193
202
  selection: {
@@ -200,7 +209,7 @@ const selectRuleBasedOnFilesLimit = (todoModule, config) => {
200
209
  }
201
210
  return { success: false };
202
211
  };
203
- const selectRuleBasedOnViolationsLimit = (todoModule, config) => {
212
+ const selectRuleBasedOnViolationsLimit = (suppressions, eslintConfig, config) => {
204
213
  const {
205
214
  autoFixableOnly,
206
215
  exclude: { rules: excludedRules },
@@ -213,15 +222,16 @@ const selectRuleBasedOnViolationsLimit = (todoModule, config) => {
213
222
  let fullSelectableRule = null;
214
223
  let selectedTargetCount = 0;
215
224
  let partialSelectableRule = null;
216
- for (const [ruleId, entry] of Object.entries(todoModule.todo)) {
217
- if (autoFixableOnly && !entry.autoFix) {
225
+ const ruleBasedSuppressions = toRuleBasedSuppression(suppressions);
226
+ for (const [ruleId, entry] of Object.entries(ruleBasedSuppressions)) {
227
+ if (autoFixableOnly && !isRuleFixable(eslintConfig, ruleId)) {
218
228
  continue;
219
229
  }
220
230
  if (excludedRules.includes(ruleId)) {
221
231
  continue;
222
232
  }
223
- const totalViolationCount = Object.values(entry.violations).reduce(
224
- (sum, count) => sum + count,
233
+ const totalViolationCount = Object.values(entry).reduce(
234
+ (sum, count) => sum + count.count,
225
235
  0
226
236
  );
227
237
  if (totalViolationCount > limitCount) {
@@ -244,11 +254,11 @@ const selectRuleBasedOnViolationsLimit = (todoModule, config) => {
244
254
  success: true
245
255
  };
246
256
  }
247
- if (allowPartialSelection && isKeyOfTodoModuleV2(todoModule, partialSelectableRule)) {
248
- const rule = todoModule.todo[partialSelectableRule];
257
+ if (allowPartialSelection && partialSelectableRule != null && Object.hasOwn(ruleBasedSuppressions, partialSelectableRule)) {
258
+ const rule = ruleBasedSuppressions[partialSelectableRule];
249
259
  let selectedCount = 0;
250
260
  const selectedViolations = {};
251
- for (const [file, count] of Object.entries(rule.violations)) {
261
+ for (const [file, { count }] of Object.entries(rule)) {
252
262
  if (selectedCount + count > limitCount) {
253
263
  break;
254
264
  }
@@ -269,19 +279,21 @@ const selectRuleBasedOnViolationsLimit = (todoModule, config) => {
269
279
  }
270
280
  return { success: false };
271
281
  };
272
- const isKeyOfTodoModuleV2 = (todoModule, ruleId) => {
273
- return isNonEmptyString(ruleId) && Object.hasOwn(todoModule.todo, ruleId);
274
- };
275
282
 
276
- const selectRulesToFixAction = defineAction(async ({ config, core, hooks }) => {
283
+ const selectRulesToFixAction = defineAction(async ({ config, core, eslintConfig, hooks }) => {
277
284
  const currentModule = await core.readTodoModule();
278
- if (!LATEST_TODO_MODULE_HANDLER.isVersion(currentModule)) {
285
+ if (!TodoModuleV2Handler.isVersion(currentModule)) {
279
286
  throw new Error(
280
287
  "This action requires the latest version of the todo file."
281
288
  );
282
289
  }
290
+ const suppressions = SuppressionsJsonGenerator.fromV2(currentModule);
283
291
  await hooks.callHook("before:select-rule");
284
- const result = selectRuleBasedOnLimit(currentModule, config.correct);
292
+ const result = selectRuleBasedOnLimit(
293
+ suppressions,
294
+ eslintConfig,
295
+ config.correct
296
+ );
285
297
  await hooks.callHook("after:select-rule", result);
286
298
  return result;
287
299
  });
@@ -450,6 +462,8 @@ const cli = defineCommand({
450
462
  todoFile: args.todoFile
451
463
  });
452
464
  const config = await resolveConfig(cliCwd, userConfig);
465
+ const eslintConfig = await readESLintConfig(config.root);
466
+ const eslintConfigSubset = createESLintConfigSubset(eslintConfig);
453
467
  const eslintTodoCore = new ESLintTodoCore(config);
454
468
  const todoFilePathFromCLI = relative(
455
469
  cliCwd,
@@ -457,13 +471,15 @@ const cli = defineCommand({
457
471
  );
458
472
  const updateActionExecutor = prepareAction(updateAction, {
459
473
  config,
460
- consola
474
+ consola,
475
+ eslintConfig: eslintConfigSubset
461
476
  });
462
477
  await updateActionExecutor();
463
478
  if (context.mode === "generate") {
464
479
  const genActionExecutor = prepareAction(genAction, {
465
480
  config,
466
481
  consola,
482
+ eslintConfig: eslintConfigSubset,
467
483
  hooks: {
468
484
  "after:lint": () => {
469
485
  consola.success("ESLint finished!");
@@ -500,6 +516,7 @@ If you want to fix ESLint errors, please use \`eslint --fix\` instead.`
500
516
  const selectRulesToFixExecutor = prepareAction(selectRulesToFixAction, {
501
517
  config,
502
518
  consola,
519
+ eslintConfig: eslintConfigSubset,
503
520
  hooks: {
504
521
  "before:select-rule": () => {
505
522
  consola.start("Selecting rules to fix ...");
@@ -522,6 +539,7 @@ If you want to fix ESLint errors, please use \`eslint --fix\` instead.`
522
539
  const deleteRuleExecutor = prepareAction(deleteRuleAction, {
523
540
  config,
524
541
  consola,
542
+ eslintConfig: eslintConfigSubset,
525
543
  hooks: {
526
544
  "after:delete-and-write": () => {
527
545
  if (result.selection.type === "full") {
@@ -1,9 +1,7 @@
1
1
  import { cwd } from 'node:process';
2
- import { r as resolveConfig } from '../shared/eslint-todo.BAvNAJxm.mjs';
3
- import { E as ESLintTodoCore, T as TodoModuleV1Handler, a as TodoModuleV2Handler } from '../shared/eslint-todo.CgzyQ8Wn.mjs';
2
+ import { r as resolveConfig, T as TodoModuleV1Handler, b as buildESLintConfigWithSuppressionsJson, S as SuppressionsJsonGenerator } from '../shared/eslint-todo.Cf8KdZHE.mjs';
3
+ import { E as ESLintTodoCore, T as TodoModuleV2Handler } from '../shared/eslint-todo.BOQSBLS6.mjs';
4
4
  import 'pathe';
5
- import 'typia/lib/internal/_accessExpressionAsString.js';
6
- import 'typia/lib/internal/_validateReport.js';
7
5
  import '../config/index.mjs';
8
6
  import 'defu';
9
7
  import 'eslint';
@@ -11,7 +9,9 @@ import 'node:fs';
11
9
  import 'node:fs/promises';
12
10
  import 'magicast';
13
11
  import 'klona';
14
- import 'valibot';
12
+ import 'bundle-require';
13
+ import 'find-up';
14
+ import 'mlly';
15
15
  import 'cross-spawn';
16
16
  import 'jiti';
17
17
 
@@ -41,14 +41,40 @@ const eslintConfigTodo = async (config) => {
41
41
  name: "@sushichan044/eslint-todo/ignore"
42
42
  }
43
43
  ];
44
- if (module == null || !TodoModuleV1Handler.isVersion(module) && !TodoModuleV2Handler.isVersion(module)) {
45
- configs.push({
44
+ if (module == null) {
45
+ return [
46
+ ...configs,
47
+ {
48
+ files: [todoModulePath.relative],
49
+ name: "@sushichan044/eslint-todo/warning/FILE_NOT_FOUND_OR_INVALID_TODO_FILE"
50
+ }
51
+ ];
52
+ }
53
+ if (TodoModuleV1Handler.isVersion(module)) {
54
+ return [
55
+ ...configs,
56
+ ...buildESLintConfigWithSuppressionsJson(
57
+ SuppressionsJsonGenerator.fromV1(module),
58
+ "off"
59
+ )
60
+ ];
61
+ }
62
+ if (TodoModuleV2Handler.isVersion(module)) {
63
+ return [
64
+ ...configs,
65
+ ...buildESLintConfigWithSuppressionsJson(
66
+ SuppressionsJsonGenerator.fromV2(module),
67
+ "off"
68
+ )
69
+ ];
70
+ }
71
+ return [
72
+ ...configs,
73
+ {
46
74
  files: [todoModulePath.relative],
47
75
  name: "@sushichan044/eslint-todo/warning/FILE_NOT_FOUND_OR_INVALID_TODO_FILE"
48
- });
49
- return configs;
50
- }
51
- return [...configs, ...core.buildESLintConfig(module, "off")];
76
+ }
77
+ ];
52
78
  };
53
79
 
54
80
  export { eslintConfigTodo as default };
package/dist/index.d.mts CHANGED
@@ -1,3 +1,4 @@
1
1
  import 'eslint';
2
2
  import './shared/eslint-todo.BiAsjzmN.mjs';
3
- export { E as ESLintTodoCore } from './shared/eslint-todo.DNIHS8ep.mjs';
3
+ export { E as ESLintTodoCore } from './shared/eslint-todo.BCcby3-6.mjs';
4
+ import '@typescript-eslint/utils/ts-eslint';
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  import 'eslint';
2
2
  import './shared/eslint-todo.BiAsjzmN.js';
3
- export { E as ESLintTodoCore } from './shared/eslint-todo.5g6Wlxnm.js';
3
+ export { E as ESLintTodoCore } from './shared/eslint-todo.BfLjFpqs.js';
4
+ import '@typescript-eslint/utils/ts-eslint';
package/dist/index.mjs CHANGED
@@ -2,11 +2,13 @@ import 'eslint';
2
2
  import 'node:fs';
3
3
  import 'node:fs/promises';
4
4
  import 'pathe';
5
- export { E as ESLintTodoCore } from './shared/eslint-todo.CgzyQ8Wn.mjs';
5
+ export { E as ESLintTodoCore } from './shared/eslint-todo.BOQSBLS6.mjs';
6
6
  import 'magicast';
7
7
  import 'defu';
8
8
  import 'klona';
9
9
  import 'node:process';
10
- import 'valibot';
10
+ import 'bundle-require';
11
+ import 'find-up';
12
+ import 'mlly';
11
13
  import 'cross-spawn';
12
14
  import 'jiti';
@@ -1,8 +1,9 @@
1
1
  import * as Comlink from 'comlink';
2
2
  import { RemoteESLintTodoCore } from './core.mjs';
3
3
  import '../shared/eslint-todo.BiAsjzmN.mjs';
4
- import '../shared/eslint-todo.DNIHS8ep.mjs';
4
+ import '../shared/eslint-todo.BCcby3-6.mjs';
5
5
  import 'eslint';
6
+ import '@typescript-eslint/utils/ts-eslint';
6
7
 
7
8
  type RemoteCore = {
8
9
  RemoteESLintTodoCore: Comlink.Remote<typeof RemoteESLintTodoCore>;
@@ -1,8 +1,9 @@
1
1
  import * as Comlink from 'comlink';
2
2
  import { RemoteESLintTodoCore } from './core.js';
3
3
  import '../shared/eslint-todo.BiAsjzmN.js';
4
- import '../shared/eslint-todo.5g6Wlxnm.js';
4
+ import '../shared/eslint-todo.BfLjFpqs.js';
5
5
  import 'eslint';
6
+ import '@typescript-eslint/utils/ts-eslint';
6
7
 
7
8
  type RemoteCore = {
8
9
  RemoteESLintTodoCore: Comlink.Remote<typeof RemoteESLintTodoCore>;
@@ -1,15 +1,16 @@
1
1
  import { U as UserConfig } from '../shared/eslint-todo.BiAsjzmN.mjs';
2
- import { I as IESLintTodoCoreLike, S as SupportedTodoModules, R as RuleSeverity, E as ESLintTodoCore } from '../shared/eslint-todo.DNIHS8ep.mjs';
2
+ import { I as IESLintTodoCoreLike, E as ESLintTodoCore } from '../shared/eslint-todo.BCcby3-6.mjs';
3
3
  import 'eslint';
4
+ import '@typescript-eslint/utils/ts-eslint';
4
5
 
5
6
  declare class RemoteESLintTodoCore implements IESLintTodoCoreLike {
6
7
  #private;
7
8
  constructor(userConfig?: UserConfig);
8
- buildESLintConfig(todoModule: SupportedTodoModules, severity: RuleSeverity): ReturnType<ESLintTodoCore["buildESLintConfig"]>;
9
9
  buildTodoFromLintResults(...parameters: Parameters<ESLintTodoCore["buildTodoFromLintResults"]>): ReturnType<ESLintTodoCore["buildTodoFromLintResults"]>;
10
10
  getTodoModulePath(...parameters: Parameters<ESLintTodoCore["getTodoModulePath"]>): ReturnType<ESLintTodoCore["getTodoModulePath"]>;
11
11
  initializeESLint(...parameters: Parameters<ESLintTodoCore["initializeESLint"]>): ReturnType<ESLintTodoCore["initializeESLint"]>;
12
12
  lint(...parameters: Parameters<ESLintTodoCore["lint"]>): ReturnType<ESLintTodoCore["lint"]>;
13
+ readESLintConfig(...parameters: Parameters<ESLintTodoCore["readESLintConfig"]>): ReturnType<ESLintTodoCore["readESLintConfig"]>;
13
14
  readTodoModule(...parameters: Parameters<ESLintTodoCore["_DO_NOT_USE_DIRECTLY_unsafeReadTodoModule"]>): ReturnType<ESLintTodoCore["_DO_NOT_USE_DIRECTLY_unsafeReadTodoModule"]>;
14
15
  resetTodoModule(...parameters: Parameters<ESLintTodoCore["resetTodoModule"]>): ReturnType<ESLintTodoCore["resetTodoModule"]>;
15
16
  todoModuleHasUncommittedChanges(...parameters: Parameters<ESLintTodoCore["todoModuleHasUncommittedChanges"]>): ReturnType<ESLintTodoCore["todoModuleHasUncommittedChanges"]>;
@@ -1,15 +1,16 @@
1
1
  import { U as UserConfig } from '../shared/eslint-todo.BiAsjzmN.js';
2
- import { I as IESLintTodoCoreLike, S as SupportedTodoModules, R as RuleSeverity, E as ESLintTodoCore } from '../shared/eslint-todo.5g6Wlxnm.js';
2
+ import { I as IESLintTodoCoreLike, E as ESLintTodoCore } from '../shared/eslint-todo.BfLjFpqs.js';
3
3
  import 'eslint';
4
+ import '@typescript-eslint/utils/ts-eslint';
4
5
 
5
6
  declare class RemoteESLintTodoCore implements IESLintTodoCoreLike {
6
7
  #private;
7
8
  constructor(userConfig?: UserConfig);
8
- buildESLintConfig(todoModule: SupportedTodoModules, severity: RuleSeverity): ReturnType<ESLintTodoCore["buildESLintConfig"]>;
9
9
  buildTodoFromLintResults(...parameters: Parameters<ESLintTodoCore["buildTodoFromLintResults"]>): ReturnType<ESLintTodoCore["buildTodoFromLintResults"]>;
10
10
  getTodoModulePath(...parameters: Parameters<ESLintTodoCore["getTodoModulePath"]>): ReturnType<ESLintTodoCore["getTodoModulePath"]>;
11
11
  initializeESLint(...parameters: Parameters<ESLintTodoCore["initializeESLint"]>): ReturnType<ESLintTodoCore["initializeESLint"]>;
12
12
  lint(...parameters: Parameters<ESLintTodoCore["lint"]>): ReturnType<ESLintTodoCore["lint"]>;
13
+ readESLintConfig(...parameters: Parameters<ESLintTodoCore["readESLintConfig"]>): ReturnType<ESLintTodoCore["readESLintConfig"]>;
13
14
  readTodoModule(...parameters: Parameters<ESLintTodoCore["_DO_NOT_USE_DIRECTLY_unsafeReadTodoModule"]>): ReturnType<ESLintTodoCore["_DO_NOT_USE_DIRECTLY_unsafeReadTodoModule"]>;
14
15
  resetTodoModule(...parameters: Parameters<ESLintTodoCore["resetTodoModule"]>): ReturnType<ESLintTodoCore["resetTodoModule"]>;
15
16
  todoModuleHasUncommittedChanges(...parameters: Parameters<ESLintTodoCore["todoModuleHasUncommittedChanges"]>): ReturnType<ESLintTodoCore["todoModuleHasUncommittedChanges"]>;
@@ -1,7 +1,7 @@
1
1
  import * as Comlink from 'comlink';
2
2
  import nodeEndPoint from 'comlink/dist/esm/node-adapter.mjs';
3
3
  import { parentPort } from 'node:worker_threads';
4
- import { E as ESLintTodoCore } from '../shared/eslint-todo.CgzyQ8Wn.mjs';
4
+ import { E as ESLintTodoCore } from '../shared/eslint-todo.BOQSBLS6.mjs';
5
5
  import 'eslint';
6
6
  import 'node:fs';
7
7
  import 'node:fs/promises';
@@ -10,7 +10,9 @@ import 'magicast';
10
10
  import 'defu';
11
11
  import 'klona';
12
12
  import 'node:process';
13
- import 'valibot';
13
+ import 'bundle-require';
14
+ import 'find-up';
15
+ import 'mlly';
14
16
  import 'cross-spawn';
15
17
  import 'jiti';
16
18
 
@@ -21,9 +23,6 @@ class RemoteESLintTodoCore {
21
23
  constructor(userConfig) {
22
24
  this.#todoCore = new ESLintTodoCore(userConfig);
23
25
  }
24
- buildESLintConfig(todoModule, severity) {
25
- return this.#todoCore.buildESLintConfig(todoModule, severity);
26
- }
27
26
  buildTodoFromLintResults(...parameters) {
28
27
  return this.#todoCore.buildTodoFromLintResults(...parameters);
29
28
  }
@@ -36,6 +35,9 @@ class RemoteESLintTodoCore {
36
35
  async lint(...parameters) {
37
36
  return this.#todoCore.lint(...parameters);
38
37
  }
38
+ async readESLintConfig(...parameters) {
39
+ return this.#todoCore.readESLintConfig(...parameters);
40
+ }
39
41
  async readTodoModule(...parameters) {
40
42
  return this.#todoCore._DO_NOT_USE_DIRECTLY_unsafeReadTodoModule(
41
43
  ...parameters
@@ -1,5 +1,60 @@
1
1
  import { Linter, ESLint } from 'eslint';
2
2
  import { M as MaybePromisifyAllMethods, U as UserConfig } from './eslint-todo.BiAsjzmN.mjs';
3
+ import { RuleMetaData } from '@typescript-eslint/utils/ts-eslint';
4
+
5
+ /**
6
+ * @module eslint-flat-config-resolver
7
+ *
8
+ * This module is for resolving the ESLint config with rule metadata.
9
+ *
10
+ * This file includes code modified from the ESLint Config Inspector project
11
+ * (https://github.com/eslint/config-inspector/blob/8a65a0b00a5f32b4e28699d66b1c125fbeb7fa24/src/configs.ts)
12
+ * Original code copyright: Copyright (c) ESLint contributors
13
+ * Licensed under the Apache License, Version 2.0
14
+ *
15
+ * Changes from source code:
16
+ * - Drop legacy ESLint support
17
+ * - handle ESLint violations
18
+ * - only accepts root: string as parameter
19
+ *
20
+ * For full license and copyright information, see the LICENSE and NOTICE files.
21
+ */
22
+
23
+ /**
24
+ * @package
25
+ */
26
+ interface FlatConfigItem extends Linter.Config {
27
+ index: number;
28
+ }
29
+ /**
30
+ * @package
31
+ */
32
+ interface Payload {
33
+ configs: FlatConfigItem[];
34
+ files: null;
35
+ meta: PayloadMeta;
36
+ rules: Record<string, RuleInfo>;
37
+ }
38
+ interface PayloadMeta {
39
+ basePath: string;
40
+ configPath: string;
41
+ lastUpdate: number;
42
+ wsPort?: number;
43
+ }
44
+ interface RuleInfo extends RuleMetaData<any, any> {
45
+ /**
46
+ * The rule may be removed
47
+ */
48
+ invalid?: boolean;
49
+ name: string;
50
+ plugin: string;
51
+ }
52
+
53
+ interface ESLintConfig {
54
+ configs: FlatConfigItem[];
55
+ dependencies: string[];
56
+ payload: Payload;
57
+ }
3
58
 
4
59
  type TodoFilePath = {
5
60
  /**
@@ -13,7 +68,6 @@ type TodoFilePath = {
13
68
  };
14
69
 
15
70
  type TodoModuleLike = Record<string, unknown>;
16
- type RuleSeverity = Extract<Linter.RuleSeverity, "error" | "off">;
17
71
 
18
72
  type ESLintTodoEntryV2 = {
19
73
  /**
@@ -53,57 +107,14 @@ type TodoModuleV2 = {
53
107
  todo: Record<string, ESLintTodoEntryV2>;
54
108
  };
55
109
 
56
- type ESLintTodoEntryV1 = {
57
- /**
58
- * Whether rule can be auto fixed.
59
- */
60
- autoFix: boolean;
61
- /**
62
- * Files violating the rule.
63
- */
64
- files: string[];
65
- };
66
- /**
67
- * ESLint todo object. key is ESLint rule id.
68
- *
69
- * @example
70
- * ```js
71
- * {
72
- * "no-console": {
73
- * autoFix: false,
74
- * files: ["src/index.js"]
75
- * }
76
- * }
77
- * ```
78
- */
79
- type TodoModuleV1 = Record<string, ESLintTodoEntryV1>;
80
-
81
- type SupportedTodoModulesArray = [
82
- TodoModuleV2,
83
- TodoModuleV1
84
- ];
85
- type SupportedTodoModules = SupportedTodoModulesArray[number];
86
- type LatestTodoModule = SupportedTodoModulesArray[0];
87
-
88
110
  type ESLintInitializeOptions = Pick<ESLint.Options, "overrideConfig">;
89
111
  type IESLintTodoCoreLike = MaybePromisifyAllMethods<ESLintTodoCoreLike>;
90
112
  interface ESLintTodoCoreLike {
91
- /**
92
- * Build ESLint configs for the todo file.
93
- * @param todoModule
94
- * Todo module object with supported version.
95
- * @param severity
96
- * Severity of the rule.
97
- * @returns
98
- * - ESLint configs to disable todo rules.
99
- * - `null` if unsupported todo module passed.
100
- */
101
- buildESLintConfig(todoModule: SupportedTodoModules, severity: RuleSeverity): Linter.Config[];
102
113
  /**
103
114
  * Build a todo object from the lint results.
104
115
  * @param lintResults LintResults from ESLint
105
116
  */
106
- buildTodoFromLintResults(lintResults: ESLint.LintResult[]): LatestTodoModule;
117
+ buildTodoFromLintResults(lintResults: ESLint.LintResult[]): TodoModuleV2;
107
118
  /**
108
119
  * Get the path of current todo module.
109
120
  */
@@ -117,6 +128,10 @@ interface ESLintTodoCoreLike {
117
128
  * @returns LintResults from ESLint
118
129
  */
119
130
  lint(): Promise<ESLint.LintResult[]>;
131
+ /**
132
+ * Read the ESLint config with resolved rule metadata.
133
+ */
134
+ readESLintConfig(): Promise<ESLintConfig>;
120
135
  /**
121
136
  * Empty the todo module and reset to the default.
122
137
  */
@@ -140,14 +155,15 @@ declare class ESLintTodoCore implements IESLintTodoCoreLike {
140
155
  * You should use `launchRemoteCore()` to create a remote worker and use `RemoteESLintTodoCore.readTodoModule()` instead.
141
156
  */
142
157
  _DO_NOT_USE_DIRECTLY_unsafeReadTodoModule(): Promise<TodoModuleLike>;
143
- buildESLintConfig(todoModule: SupportedTodoModules, severity: RuleSeverity): Linter.Config[];
144
- buildTodoFromLintResults(lintResults: ESLint.LintResult[]): LatestTodoModule;
158
+ buildTodoFromLintResults(lintResults: ESLint.LintResult[]): TodoModuleV2;
145
159
  getTodoModulePath(): TodoFilePath;
146
160
  initializeESLint(options?: ESLintInitializeOptions): void;
147
161
  lint(): Promise<ESLint.LintResult[]>;
162
+ readESLintConfig(): Promise<ESLintConfig>;
148
163
  resetTodoModule(): Promise<void>;
149
164
  todoModuleHasUncommittedChanges(): Promise<boolean>;
150
165
  writeTodoModule(todo: TodoModuleLike): Promise<void>;
151
166
  }
152
167
 
153
- export { ESLintTodoCore as E, type IESLintTodoCoreLike as I, type RuleSeverity as R, type SupportedTodoModules as S };
168
+ export { ESLintTodoCore as E };
169
+ export type { IESLintTodoCoreLike as I };