@sushichan044/eslint-todo 0.0.2 → 0.0.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 +23 -24
- package/bin/eslint-todo.mjs +1 -4
- package/dist/cli/index.mjs +222 -76
- package/dist/eslint/index.mjs +6 -6
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +1 -1
- package/dist/remote/client.d.mts +1 -1
- package/dist/remote/client.d.ts +1 -1
- package/dist/remote/core.d.mts +8 -8
- package/dist/remote/core.d.ts +8 -8
- package/dist/remote/core.mjs +17 -15
- package/dist/shared/{eslint-todo.B_vRyhWL.d.mts → eslint-todo.BR1uwV1v.d.mts} +1 -1
- package/dist/shared/{eslint-todo.BwJWAS7j.mjs → eslint-todo.BShlgWEx.mjs} +20 -20
- package/dist/shared/{eslint-todo.BD1wUnwb.d.ts → eslint-todo.DyfNwDMO.d.ts} +1 -1
- package/package.json +16 -12
package/README.md
CHANGED
|
@@ -1,33 +1,35 @@
|
|
|
1
1
|
# @sushichan044/eslint-todo
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Simple tool to temporarily disable existing ESLint violations like `.rubocop_todo.yml` in RuboCop.
|
|
4
|
+
|
|
5
|
+
It also has a utility that helps reducing ignored violations at your pace.
|
|
6
|
+
|
|
7
|
+
> [!NOTE]
|
|
4
8
|
> This tool only supports ESLint Flat Config with ES Module.
|
|
5
9
|
>
|
|
6
10
|
> If you want to use this tool to supress ESLint errors when migrating to ESLint Flat Config,
|
|
7
11
|
> you first need to create Flat Config and then use this tool. Maybe utilities like [@eslint/compat](https://github.com/eslint/rewrite/tree/main/packages/compat) can help you.
|
|
8
12
|
|
|
9
|
-
Simple tool to temporarily disable existing ESLint violations like `.rubocop_todo.yml` in RuboCop.
|
|
10
|
-
|
|
11
|
-
This allows existing offending files to be excluded from scanning on a rule-by-rule basis, which is useful when making destructive changes to ESLint settings.
|
|
12
|
-
|
|
13
|
-
It also has a utility that reduces the number of ignored rules at a pace that works for your team.
|
|
14
|
-
|
|
15
|
-
## Features
|
|
16
|
-
|
|
17
|
-
- Temporarily disable ESLint rules for specific files having existing violations with one command.
|
|
18
|
-
- Assistive feature to gradually eliminate ignored errors.
|
|
19
|
-
|
|
20
13
|
## Installation
|
|
21
14
|
|
|
22
15
|
```bash
|
|
23
|
-
|
|
16
|
+
npm install --save-dev eslint @sushichan044/eslint-todo
|
|
24
17
|
```
|
|
25
18
|
|
|
19
|
+
Requires:
|
|
20
|
+
|
|
21
|
+
- **ES Module**
|
|
22
|
+
- ESLint: `^8.57.0 || ^9.0.0`
|
|
23
|
+
- **Flat Config**
|
|
24
|
+
- Node.js: `>= 20.0.0`
|
|
25
|
+
- May work in Deno, but not tested.
|
|
26
|
+
|
|
26
27
|
## Getting Started
|
|
27
28
|
|
|
28
|
-
1. Add `eslint-todo` config
|
|
29
|
+
1. Add `eslint-todo` config **at the bottom of your configs**. Do not forget `await`.
|
|
29
30
|
|
|
30
31
|
``` diff
|
|
32
|
+
// example: eslint.config.js
|
|
31
33
|
+ import { eslintConfigTodo } from '@sushichan044/eslint-todo/eslint';
|
|
32
34
|
|
|
33
35
|
export default [
|
|
@@ -36,16 +38,13 @@ pnpm install -D @sushichan044/eslint-todo
|
|
|
36
38
|
]
|
|
37
39
|
```
|
|
38
40
|
|
|
39
|
-
2. Run `eslint-todo` to generate ESLint Todo file
|
|
40
|
-
|
|
41
|
-
> [!NOTE]
|
|
42
|
-
> Run this command at the directory where your `eslint.config.js` is located.
|
|
41
|
+
2. Run `eslint-todo` to generate ESLint Todo file at the directory where `eslint.config.js` is placed.
|
|
43
42
|
|
|
44
43
|
```bash
|
|
45
|
-
|
|
44
|
+
npx eslint-todo
|
|
46
45
|
```
|
|
47
46
|
|
|
48
|
-
3. Ignore `.eslint-todo.js`
|
|
47
|
+
3. Ignore generated `.eslint-todo.js` in some tools if you needed.
|
|
49
48
|
|
|
50
49
|
```diff
|
|
51
50
|
// example: .prettierignore
|
|
@@ -67,10 +66,10 @@ Add `--correct` flag to launch eslint-todo with error reduction mode.
|
|
|
67
66
|
In this mode, eslint-todo searches the todo file with the limit from CLI and removes one matching rule from the todo file.
|
|
68
67
|
This allows ESLint to detect that rule as a violation again. For safety, only auto-fixable rules are searched by default.
|
|
69
68
|
|
|
70
|
-
You can use `--limit`, `--limit-type`, `--
|
|
69
|
+
You can use `--limit`, `--limit-type`, `--auto-fixable-only` options to control the behavior.
|
|
71
70
|
|
|
72
71
|
Default options are: <br>
|
|
73
|
-
Select one rule that has a total of 100 or fewer violations from auto-fixable rules.
|
|
72
|
+
Select one rule that has a total of 100 or fewer violations from **auto-fixable** rules.
|
|
74
73
|
|
|
75
74
|
```bash
|
|
76
75
|
eslint-todo --correct --limit 100 --limit-type violation
|
|
@@ -82,10 +81,10 @@ Select one rule that has a total of 10 or fewer files with violations from auto-
|
|
|
82
81
|
eslint-todo --correct --limit 10 --limit-type file
|
|
83
82
|
```
|
|
84
83
|
|
|
85
|
-
Select one rule that has a total of 100 or fewer violations from all rules including non-auto-fixable rules:
|
|
84
|
+
Select one rule that has a total of 100 or fewer violations from **all rules including non-auto-fixable** rules:
|
|
86
85
|
|
|
87
86
|
```bash
|
|
88
|
-
eslint-todo --correct --limit 100 --limit-type violation --
|
|
87
|
+
eslint-todo --correct --limit 100 --limit-type violation --auto-fixable-only false
|
|
89
88
|
```
|
|
90
89
|
|
|
91
90
|
## Configuration (CLI)
|
package/bin/eslint-todo.mjs
CHANGED
package/dist/cli/index.mjs
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { defineCommand, runMain } from 'citty';
|
|
2
2
|
import { createConsola } from 'consola';
|
|
3
3
|
import { colorize } from 'consola/utils';
|
|
4
|
-
import { L as LATEST_MODULE_HANDLER, T as TodoModuleV1Handler, E as ESLintTodoCore } from '../shared/eslint-todo.
|
|
4
|
+
import { L as LATEST_MODULE_HANDLER, i as isNonEmptyString, T as TodoModuleV1Handler, E as ESLintTodoCore } from '../shared/eslint-todo.BShlgWEx.mjs';
|
|
5
5
|
import { launchRemoteESLintTodoCore } from '../remote/client.mjs';
|
|
6
6
|
import { klona } from 'klona/json';
|
|
7
|
+
import defu from 'defu';
|
|
7
8
|
import { relative } from 'pathe';
|
|
8
9
|
import * as v from 'valibot';
|
|
9
10
|
import 'eslint';
|
|
@@ -11,7 +12,6 @@ import 'node:fs';
|
|
|
11
12
|
import 'node:fs/promises';
|
|
12
13
|
import 'magicast';
|
|
13
14
|
import 'es-toolkit/compat';
|
|
14
|
-
import 'defu';
|
|
15
15
|
import 'node:process';
|
|
16
16
|
import 'jiti';
|
|
17
17
|
import 'comlink';
|
|
@@ -19,7 +19,7 @@ import 'comlink/dist/esm/node-adapter.mjs';
|
|
|
19
19
|
import 'node:url';
|
|
20
20
|
import 'node:worker_threads';
|
|
21
21
|
|
|
22
|
-
const version = "0.0.
|
|
22
|
+
const version = "0.0.3";
|
|
23
23
|
|
|
24
24
|
const defineAction = (action) => action;
|
|
25
25
|
const NO_INPUT = Symbol("NO_INPUT");
|
|
@@ -36,36 +36,53 @@ async function runAction(action, options, input = NO_INPUT) {
|
|
|
36
36
|
return await action(actionApi);
|
|
37
37
|
}
|
|
38
38
|
return await action(actionApi, input);
|
|
39
|
-
} catch (
|
|
40
|
-
consola.error(
|
|
41
|
-
throw
|
|
39
|
+
} catch (error) {
|
|
40
|
+
consola.error(error);
|
|
41
|
+
throw error;
|
|
42
42
|
} finally {
|
|
43
43
|
await remoteService.terminate();
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
const deleteRule = (currentModule,
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
delete newModule.todo[ruleId];
|
|
47
|
+
const deleteRule = (currentModule, ruleSelection) => {
|
|
48
|
+
if (!Object.hasOwn(currentModule.todo, ruleSelection.ruleId)) {
|
|
49
|
+
return currentModule;
|
|
51
50
|
}
|
|
52
|
-
|
|
51
|
+
if (ruleSelection.type === "full") {
|
|
52
|
+
const newModule = klona(currentModule);
|
|
53
|
+
delete newModule.todo[ruleSelection.ruleId];
|
|
54
|
+
return newModule;
|
|
55
|
+
}
|
|
56
|
+
if (ruleSelection.type === "partial") {
|
|
57
|
+
const newModule = klona(currentModule);
|
|
58
|
+
const entry = newModule.todo[ruleSelection.ruleId];
|
|
59
|
+
for (const [file, count] of Object.entries(ruleSelection.violations)) {
|
|
60
|
+
if (!Object.hasOwn(entry.violations, file)) {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (entry.violations[file] == null || entry.violations[file] !== count) {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
delete entry.violations[file];
|
|
67
|
+
}
|
|
68
|
+
return newModule;
|
|
69
|
+
}
|
|
70
|
+
const _exhaustiveCheck = ruleSelection;
|
|
71
|
+
throw new Error(
|
|
72
|
+
`Unknown rule selection type ${JSON.stringify(_exhaustiveCheck)}`
|
|
73
|
+
);
|
|
53
74
|
};
|
|
54
75
|
|
|
55
|
-
const deleteRuleAction = defineAction(
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
"This action requires the latest version of the todo file."
|
|
62
|
-
);
|
|
63
|
-
}
|
|
64
|
-
logger.info(`Deleting rule ${ruleId} from the todo file ...`);
|
|
65
|
-
const newModule = deleteRule(currentModule, ruleId);
|
|
66
|
-
await core.writeTodoModule(newModule);
|
|
76
|
+
const deleteRuleAction = defineAction(async ({ core }, input) => {
|
|
77
|
+
const currentModule = await core.readTodoModule();
|
|
78
|
+
if (!LATEST_MODULE_HANDLER.isVersion(currentModule)) {
|
|
79
|
+
throw new Error(
|
|
80
|
+
"This action requires the latest version of the todo file."
|
|
81
|
+
);
|
|
67
82
|
}
|
|
68
|
-
);
|
|
83
|
+
const newModule = deleteRule(currentModule, input);
|
|
84
|
+
await core.writeTodoModule(newModule);
|
|
85
|
+
});
|
|
69
86
|
|
|
70
87
|
const genAction = defineAction(async ({ core, logger }) => {
|
|
71
88
|
await core.resetTodoModule();
|
|
@@ -77,63 +94,154 @@ const genAction = defineAction(async ({ core, logger }) => {
|
|
|
77
94
|
await core.writeTodoModule(todo);
|
|
78
95
|
});
|
|
79
96
|
|
|
97
|
+
const operationOptionsWithDefault = (options = {}) => {
|
|
98
|
+
return defu(options, getDefaultOperationOptions());
|
|
99
|
+
};
|
|
100
|
+
const getDefaultOperationOptions = () => ({
|
|
101
|
+
allowPartialSelection: false,
|
|
102
|
+
autoFixableOnly: true
|
|
103
|
+
});
|
|
104
|
+
|
|
80
105
|
const selectRuleBasedOnLimit = (todoModule, limit, options = {}) => {
|
|
106
|
+
const resolvedOptions = operationOptionsWithDefault(options);
|
|
81
107
|
switch (limit.type) {
|
|
82
|
-
case "file":
|
|
83
|
-
return selectRuleBasedOnFilesLimit(todoModule, limit,
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
108
|
+
case "file": {
|
|
109
|
+
return selectRuleBasedOnFilesLimit(todoModule, limit, resolvedOptions);
|
|
110
|
+
}
|
|
111
|
+
case "violation": {
|
|
112
|
+
return selectRuleBasedOnViolationsLimit(
|
|
113
|
+
todoModule,
|
|
114
|
+
limit,
|
|
115
|
+
resolvedOptions
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
default: {
|
|
87
119
|
const l = limit;
|
|
88
120
|
throw new Error(`Got unknown limit: ${JSON.stringify(l)}`);
|
|
121
|
+
}
|
|
89
122
|
}
|
|
90
123
|
};
|
|
91
|
-
const selectRuleBasedOnFilesLimit = (todoModule, limit, options
|
|
124
|
+
const selectRuleBasedOnFilesLimit = (todoModule, limit, options) => {
|
|
92
125
|
const { count: limitCount } = limit;
|
|
93
|
-
const { autoFixableOnly
|
|
94
|
-
|
|
95
|
-
|
|
126
|
+
const { allowPartialSelection, autoFixableOnly } = options;
|
|
127
|
+
if (limitCount <= 0) {
|
|
128
|
+
throw new Error("The file limit must be greater than 0.");
|
|
129
|
+
}
|
|
130
|
+
let fullSelectableRule = null;
|
|
131
|
+
let selectedTargetCount = 0;
|
|
132
|
+
let partialSelectableRule = null;
|
|
96
133
|
for (const [ruleId, entry] of Object.entries(todoModule.todo)) {
|
|
97
134
|
if (autoFixableOnly && !entry.autoFix) {
|
|
98
135
|
continue;
|
|
99
136
|
}
|
|
100
|
-
const
|
|
101
|
-
if (
|
|
102
|
-
|
|
103
|
-
|
|
137
|
+
const violatedFiles = Object.keys(entry.violations).length;
|
|
138
|
+
if (violatedFiles > limitCount) {
|
|
139
|
+
if (allowPartialSelection && partialSelectableRule == null) {
|
|
140
|
+
partialSelectableRule = ruleId;
|
|
141
|
+
}
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
if (violatedFiles > selectedTargetCount) {
|
|
145
|
+
fullSelectableRule = ruleId;
|
|
146
|
+
selectedTargetCount = violatedFiles;
|
|
104
147
|
}
|
|
105
148
|
}
|
|
106
|
-
|
|
149
|
+
if (fullSelectableRule != null) {
|
|
150
|
+
return {
|
|
151
|
+
selection: {
|
|
152
|
+
ruleId: fullSelectableRule,
|
|
153
|
+
type: "full"
|
|
154
|
+
},
|
|
155
|
+
success: true
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
if (allowPartialSelection && isKeyOfTodo(todoModule.todo, partialSelectableRule)) {
|
|
159
|
+
const rule = todoModule.todo[partialSelectableRule];
|
|
160
|
+
const selectedPaths = Object.keys(rule.violations).slice(0, limitCount);
|
|
161
|
+
const selectedViolations = {};
|
|
162
|
+
for (const file of selectedPaths) {
|
|
163
|
+
selectedViolations[file] = rule.violations[file];
|
|
164
|
+
}
|
|
165
|
+
return {
|
|
166
|
+
selection: {
|
|
167
|
+
ruleId: partialSelectableRule,
|
|
168
|
+
type: "partial",
|
|
169
|
+
violations: selectedViolations
|
|
170
|
+
},
|
|
171
|
+
success: true
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
return { success: false };
|
|
107
175
|
};
|
|
108
|
-
const selectRuleBasedOnViolationsLimit = (todoModule, limit, options
|
|
176
|
+
const selectRuleBasedOnViolationsLimit = (todoModule, limit, options) => {
|
|
109
177
|
const { count: limitCount } = limit;
|
|
110
|
-
const { autoFixableOnly
|
|
111
|
-
|
|
112
|
-
|
|
178
|
+
const { allowPartialSelection, autoFixableOnly } = options;
|
|
179
|
+
if (limitCount <= 0) {
|
|
180
|
+
throw new Error("The violation limit must be greater than 0.");
|
|
181
|
+
}
|
|
182
|
+
let fullSelectableRule = null;
|
|
183
|
+
let selectedTargetCount = 0;
|
|
184
|
+
let partialSelectableRule = null;
|
|
113
185
|
for (const [ruleId, entry] of Object.entries(todoModule.todo)) {
|
|
114
186
|
if (autoFixableOnly && !entry.autoFix) {
|
|
115
187
|
continue;
|
|
116
188
|
}
|
|
117
|
-
const
|
|
189
|
+
const totalViolationCount = Object.values(entry.violations).reduce(
|
|
118
190
|
(sum, count) => sum + count,
|
|
119
191
|
0
|
|
120
192
|
);
|
|
121
|
-
if (
|
|
122
|
-
|
|
123
|
-
|
|
193
|
+
if (totalViolationCount > limitCount) {
|
|
194
|
+
if (allowPartialSelection && partialSelectableRule == null) {
|
|
195
|
+
partialSelectableRule = ruleId;
|
|
196
|
+
}
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
if (totalViolationCount > selectedTargetCount) {
|
|
200
|
+
fullSelectableRule = ruleId;
|
|
201
|
+
selectedTargetCount = totalViolationCount;
|
|
124
202
|
}
|
|
125
203
|
}
|
|
126
|
-
|
|
204
|
+
if (fullSelectableRule != null) {
|
|
205
|
+
return {
|
|
206
|
+
selection: {
|
|
207
|
+
ruleId: fullSelectableRule,
|
|
208
|
+
type: "full"
|
|
209
|
+
},
|
|
210
|
+
success: true
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
if (allowPartialSelection && isKeyOfTodo(todoModule.todo, partialSelectableRule)) {
|
|
214
|
+
const rule = todoModule.todo[partialSelectableRule];
|
|
215
|
+
let selectedCount = 0;
|
|
216
|
+
const selectedViolations = {};
|
|
217
|
+
for (const [file, count] of Object.entries(rule.violations)) {
|
|
218
|
+
if (selectedCount + count > limitCount) {
|
|
219
|
+
break;
|
|
220
|
+
}
|
|
221
|
+
selectedCount += count;
|
|
222
|
+
selectedViolations[file] = count;
|
|
223
|
+
}
|
|
224
|
+
if (Object.keys(selectedViolations).length === 0) {
|
|
225
|
+
return { success: false };
|
|
226
|
+
}
|
|
227
|
+
return {
|
|
228
|
+
selection: {
|
|
229
|
+
ruleId: partialSelectableRule,
|
|
230
|
+
type: "partial",
|
|
231
|
+
violations: selectedViolations
|
|
232
|
+
},
|
|
233
|
+
success: true
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
return { success: false };
|
|
237
|
+
};
|
|
238
|
+
const isKeyOfTodo = (todoModule, ruleId) => {
|
|
239
|
+
return isNonEmptyString(ruleId) && Object.hasOwn(todoModule, ruleId);
|
|
127
240
|
};
|
|
128
241
|
|
|
129
242
|
const selectRulesToFixAction = defineAction(
|
|
130
243
|
async ({ core, logger }, input) => {
|
|
131
|
-
const {
|
|
132
|
-
limit,
|
|
133
|
-
options = {
|
|
134
|
-
autoFixableOnly: true
|
|
135
|
-
}
|
|
136
|
-
} = input;
|
|
244
|
+
const { limit, options } = input;
|
|
137
245
|
const currentModule = await core.readTodoModule();
|
|
138
246
|
if (!LATEST_MODULE_HANDLER.isVersion(currentModule)) {
|
|
139
247
|
throw new Error(
|
|
@@ -192,6 +300,7 @@ const resolveCLIOperation = (input) => {
|
|
|
192
300
|
return {
|
|
193
301
|
limit,
|
|
194
302
|
options: {
|
|
303
|
+
allowPartialSelection: input.allowPartialSelection,
|
|
195
304
|
autoFixableOnly: input.autoFixableOnly
|
|
196
305
|
}
|
|
197
306
|
};
|
|
@@ -200,6 +309,13 @@ const resolveCLIOperation = (input) => {
|
|
|
200
309
|
const consola = createConsola({ formatOptions: { date: false } });
|
|
201
310
|
const cli = defineCommand({
|
|
202
311
|
args: {
|
|
312
|
+
// IMPORTANT:
|
|
313
|
+
// do not set default values for boolean options!
|
|
314
|
+
// CLI flag name is unexpected behavior when default value is set.
|
|
315
|
+
//
|
|
316
|
+
// example: `auto-fixable-only` with `default: true` results in
|
|
317
|
+
// $ eslint-todo --no-auto-fixable-only
|
|
318
|
+
// because the default value is true, the flag is negated.
|
|
203
319
|
// general options
|
|
204
320
|
"cwd": {
|
|
205
321
|
description: "Current working directory (default: .)",
|
|
@@ -222,8 +338,13 @@ const cli = defineCommand({
|
|
|
222
338
|
type: "boolean"
|
|
223
339
|
},
|
|
224
340
|
// operation options
|
|
341
|
+
"allow-partial-selection": {
|
|
342
|
+
description: "Allow partial selection of violations. Only works with --correct. (default: false)",
|
|
343
|
+
required: false,
|
|
344
|
+
type: "boolean",
|
|
345
|
+
valueHint: "boolean"
|
|
346
|
+
},
|
|
225
347
|
"auto-fixable-only": {
|
|
226
|
-
default: true,
|
|
227
348
|
description: "Only handle auto-fixable violations. (default: true)",
|
|
228
349
|
required: false,
|
|
229
350
|
type: "boolean",
|
|
@@ -272,12 +393,13 @@ const cli = defineCommand({
|
|
|
272
393
|
todoFile: args["todo-file"]
|
|
273
394
|
};
|
|
274
395
|
const eslintTodoCore = new ESLintTodoCore(options);
|
|
275
|
-
const
|
|
396
|
+
const context = resolveCLIContext({
|
|
276
397
|
cwd: cliCwd,
|
|
277
398
|
mode: {
|
|
278
399
|
correct: args.correct
|
|
279
400
|
},
|
|
280
401
|
operation: {
|
|
402
|
+
allowPartialSelection: args["allow-partial-selection"],
|
|
281
403
|
autoFixableOnly: args["auto-fixable-only"],
|
|
282
404
|
limit: args.limit,
|
|
283
405
|
limitType: args["limit-type"]
|
|
@@ -285,43 +407,67 @@ const cli = defineCommand({
|
|
|
285
407
|
todoFileAbsolutePath: eslintTodoCore.getTodoModulePath().absolute
|
|
286
408
|
});
|
|
287
409
|
await runAction(updateAction, { consola, options });
|
|
288
|
-
if (
|
|
410
|
+
if (context.mode === "generate") {
|
|
289
411
|
await runAction(genAction, { consola, options });
|
|
290
|
-
consola.success(`ESLint todo file generated at ${
|
|
412
|
+
consola.success(`ESLint todo file generated at ${context.todoFilePath}!`);
|
|
291
413
|
return;
|
|
292
414
|
}
|
|
293
|
-
if (
|
|
294
|
-
const
|
|
415
|
+
if (context.mode === "correct") {
|
|
416
|
+
const result = await runAction(
|
|
295
417
|
selectRulesToFixAction,
|
|
296
418
|
{ consola, options },
|
|
297
|
-
|
|
419
|
+
context.operation
|
|
298
420
|
);
|
|
299
|
-
if (!
|
|
421
|
+
if (!result.success) {
|
|
300
422
|
consola.warn(
|
|
301
423
|
"Couldn't find any rule to fix. Increase the limit and retry."
|
|
302
424
|
);
|
|
303
425
|
return;
|
|
304
426
|
}
|
|
305
|
-
await runAction(
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
427
|
+
await runAction(deleteRuleAction, { consola, options }, result.selection);
|
|
428
|
+
if (result.selection.type === "full") {
|
|
429
|
+
consola.success(
|
|
430
|
+
`All violations of rule ${colorize(
|
|
431
|
+
"magenta",
|
|
432
|
+
result.selection.ruleId
|
|
433
|
+
)} are deleted from the todo file and now ESLint will detect the violations.`
|
|
434
|
+
);
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
if (result.selection.type === "partial") {
|
|
438
|
+
const violationCount = Object.entries(
|
|
439
|
+
result.selection.violations
|
|
440
|
+
).reduce((sum, [, count]) => sum + count, 0);
|
|
441
|
+
consola.success(
|
|
442
|
+
`${violationCount} violations of rule ${colorize(
|
|
443
|
+
"magenta",
|
|
444
|
+
result.selection.ruleId
|
|
445
|
+
)} are deleted from the todo file and now ESLint will detect the violations.`
|
|
446
|
+
);
|
|
447
|
+
return;
|
|
448
|
+
}
|
|
449
|
+
const _exhaustiveCheck = result.selection;
|
|
450
|
+
throw new Error(
|
|
451
|
+
`Unknown selection type: ${JSON.stringify(_exhaustiveCheck)}`
|
|
312
452
|
);
|
|
313
|
-
return;
|
|
314
453
|
}
|
|
315
|
-
throw new Error(`Unknown mode: ${JSON.stringify(
|
|
454
|
+
throw new Error(`Unknown mode: ${JSON.stringify(context.mode)}`);
|
|
316
455
|
},
|
|
317
456
|
setup({ args }) {
|
|
318
457
|
consola.info(`eslint-todo CLI ${version}`);
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
458
|
+
switch (true) {
|
|
459
|
+
case args.debug: {
|
|
460
|
+
consola.level = 4;
|
|
461
|
+
break;
|
|
462
|
+
}
|
|
463
|
+
case args.trace: {
|
|
464
|
+
consola.level = 5;
|
|
465
|
+
break;
|
|
466
|
+
}
|
|
467
|
+
case args.verbose: {
|
|
468
|
+
consola.level = 999;
|
|
469
|
+
break;
|
|
470
|
+
}
|
|
325
471
|
}
|
|
326
472
|
}
|
|
327
473
|
});
|
package/dist/eslint/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { E as ESLintTodoCore, T as TodoModuleV1Handler, a as TodoModuleV2Handler, b as buildESLintConfigForModule } from '../shared/eslint-todo.
|
|
1
|
+
import { E as ESLintTodoCore, T as TodoModuleV1Handler, a as TodoModuleV2Handler, b as buildESLintConfigForModule } from '../shared/eslint-todo.BShlgWEx.mjs';
|
|
2
2
|
import 'eslint';
|
|
3
3
|
import 'node:fs';
|
|
4
4
|
import 'node:fs/promises';
|
|
@@ -22,17 +22,17 @@ const eslintConfigTodo = async (userOptions = {}) => {
|
|
|
22
22
|
})();
|
|
23
23
|
const configs = [
|
|
24
24
|
{
|
|
25
|
-
files: [todoModulePath.relative],
|
|
26
|
-
linterOptions: {
|
|
27
|
-
reportUnusedDisableDirectives: false
|
|
28
|
-
},
|
|
29
25
|
name: "@sushichan044/eslint-todo/setup"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
ignores: [todoModulePath.relative],
|
|
29
|
+
name: "@sushichan044/eslint-todo/ignore"
|
|
30
30
|
}
|
|
31
31
|
];
|
|
32
32
|
if (module == null || !TodoModuleV1Handler.isVersion(module) && !TodoModuleV2Handler.isVersion(module)) {
|
|
33
33
|
configs.push({
|
|
34
34
|
files: [todoModulePath.relative],
|
|
35
|
-
name: "@sushichan044/eslint-todo/warning/
|
|
35
|
+
name: "@sushichan044/eslint-todo/warning/FILE_NOT_FOUND_OR_INVALID_TODO_FILE"
|
|
36
36
|
});
|
|
37
37
|
return configs;
|
|
38
38
|
}
|
package/dist/index.d.mts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -2,7 +2,7 @@ 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.
|
|
5
|
+
export { E as ESLintTodoCore } from './shared/eslint-todo.BShlgWEx.mjs';
|
|
6
6
|
import 'magicast';
|
|
7
7
|
import 'es-toolkit/compat';
|
|
8
8
|
import 'valibot';
|
package/dist/remote/client.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as Comlink from 'comlink';
|
|
2
2
|
import { RemoteESLintTodoCore } from './core.mjs';
|
|
3
3
|
import '../shared/eslint-todo.BijUMnSZ.mjs';
|
|
4
|
-
import '../shared/eslint-todo.
|
|
4
|
+
import '../shared/eslint-todo.BR1uwV1v.mjs';
|
|
5
5
|
import 'eslint';
|
|
6
6
|
|
|
7
7
|
type RemoteCore = {
|
package/dist/remote/client.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as Comlink from 'comlink';
|
|
2
2
|
import { RemoteESLintTodoCore } from './core.js';
|
|
3
3
|
import '../shared/eslint-todo.BijUMnSZ.js';
|
|
4
|
-
import '../shared/eslint-todo.
|
|
4
|
+
import '../shared/eslint-todo.DyfNwDMO.js';
|
|
5
5
|
import 'eslint';
|
|
6
6
|
|
|
7
7
|
type RemoteCore = {
|
package/dist/remote/core.d.mts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { U as UserOptions } from '../shared/eslint-todo.BijUMnSZ.mjs';
|
|
2
|
-
import { I as IESLintTodoCoreLike, S as SupportedModules, R as RuleSeverity, E as ESLintTodoCore } from '../shared/eslint-todo.
|
|
2
|
+
import { I as IESLintTodoCoreLike, S as SupportedModules, R as RuleSeverity, E as ESLintTodoCore } from '../shared/eslint-todo.BR1uwV1v.mjs';
|
|
3
3
|
import 'eslint';
|
|
4
4
|
|
|
5
5
|
declare class RemoteESLintTodoCore implements IESLintTodoCoreLike {
|
|
6
6
|
#private;
|
|
7
7
|
constructor(userOptions: UserOptions);
|
|
8
8
|
buildESLintConfig(todoModule: SupportedModules, severity: RuleSeverity): ReturnType<ESLintTodoCore["buildESLintConfig"]>;
|
|
9
|
-
buildTodoFromLintResults(...
|
|
10
|
-
getTodoModulePath(...
|
|
11
|
-
initializeESLint(...
|
|
12
|
-
lint(...
|
|
13
|
-
readTodoModule(...
|
|
14
|
-
resetTodoModule(...
|
|
15
|
-
writeTodoModule(...
|
|
9
|
+
buildTodoFromLintResults(...parameters: Parameters<ESLintTodoCore["buildTodoFromLintResults"]>): ReturnType<ESLintTodoCore["buildTodoFromLintResults"]>;
|
|
10
|
+
getTodoModulePath(...parameters: Parameters<ESLintTodoCore["getTodoModulePath"]>): ReturnType<ESLintTodoCore["getTodoModulePath"]>;
|
|
11
|
+
initializeESLint(...parameters: Parameters<ESLintTodoCore["initializeESLint"]>): ReturnType<ESLintTodoCore["initializeESLint"]>;
|
|
12
|
+
lint(...parameters: Parameters<ESLintTodoCore["lint"]>): ReturnType<ESLintTodoCore["lint"]>;
|
|
13
|
+
readTodoModule(...parameters: Parameters<ESLintTodoCore["_DO_NOT_USE_DIRECTLY_unsafeReadTodoModule"]>): ReturnType<ESLintTodoCore["_DO_NOT_USE_DIRECTLY_unsafeReadTodoModule"]>;
|
|
14
|
+
resetTodoModule(...parameters: Parameters<ESLintTodoCore["resetTodoModule"]>): ReturnType<ESLintTodoCore["resetTodoModule"]>;
|
|
15
|
+
writeTodoModule(...parameters: Parameters<ESLintTodoCore["writeTodoModule"]>): ReturnType<ESLintTodoCore["writeTodoModule"]>;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
export { RemoteESLintTodoCore };
|
package/dist/remote/core.d.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { U as UserOptions } from '../shared/eslint-todo.BijUMnSZ.js';
|
|
2
|
-
import { I as IESLintTodoCoreLike, S as SupportedModules, R as RuleSeverity, E as ESLintTodoCore } from '../shared/eslint-todo.
|
|
2
|
+
import { I as IESLintTodoCoreLike, S as SupportedModules, R as RuleSeverity, E as ESLintTodoCore } from '../shared/eslint-todo.DyfNwDMO.js';
|
|
3
3
|
import 'eslint';
|
|
4
4
|
|
|
5
5
|
declare class RemoteESLintTodoCore implements IESLintTodoCoreLike {
|
|
6
6
|
#private;
|
|
7
7
|
constructor(userOptions: UserOptions);
|
|
8
8
|
buildESLintConfig(todoModule: SupportedModules, severity: RuleSeverity): ReturnType<ESLintTodoCore["buildESLintConfig"]>;
|
|
9
|
-
buildTodoFromLintResults(...
|
|
10
|
-
getTodoModulePath(...
|
|
11
|
-
initializeESLint(...
|
|
12
|
-
lint(...
|
|
13
|
-
readTodoModule(...
|
|
14
|
-
resetTodoModule(...
|
|
15
|
-
writeTodoModule(...
|
|
9
|
+
buildTodoFromLintResults(...parameters: Parameters<ESLintTodoCore["buildTodoFromLintResults"]>): ReturnType<ESLintTodoCore["buildTodoFromLintResults"]>;
|
|
10
|
+
getTodoModulePath(...parameters: Parameters<ESLintTodoCore["getTodoModulePath"]>): ReturnType<ESLintTodoCore["getTodoModulePath"]>;
|
|
11
|
+
initializeESLint(...parameters: Parameters<ESLintTodoCore["initializeESLint"]>): ReturnType<ESLintTodoCore["initializeESLint"]>;
|
|
12
|
+
lint(...parameters: Parameters<ESLintTodoCore["lint"]>): ReturnType<ESLintTodoCore["lint"]>;
|
|
13
|
+
readTodoModule(...parameters: Parameters<ESLintTodoCore["_DO_NOT_USE_DIRECTLY_unsafeReadTodoModule"]>): ReturnType<ESLintTodoCore["_DO_NOT_USE_DIRECTLY_unsafeReadTodoModule"]>;
|
|
14
|
+
resetTodoModule(...parameters: Parameters<ESLintTodoCore["resetTodoModule"]>): ReturnType<ESLintTodoCore["resetTodoModule"]>;
|
|
15
|
+
writeTodoModule(...parameters: Parameters<ESLintTodoCore["writeTodoModule"]>): ReturnType<ESLintTodoCore["writeTodoModule"]>;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
export { RemoteESLintTodoCore };
|
package/dist/remote/core.mjs
CHANGED
|
@@ -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.
|
|
4
|
+
import { E as ESLintTodoCore } from '../shared/eslint-todo.BShlgWEx.mjs';
|
|
5
5
|
import 'eslint';
|
|
6
6
|
import 'node:fs';
|
|
7
7
|
import 'node:fs/promises';
|
|
@@ -23,26 +23,28 @@ class RemoteESLintTodoCore {
|
|
|
23
23
|
buildESLintConfig(todoModule, severity) {
|
|
24
24
|
return this.#todoCore.buildESLintConfig(todoModule, severity);
|
|
25
25
|
}
|
|
26
|
-
buildTodoFromLintResults(...
|
|
27
|
-
return this.#todoCore.buildTodoFromLintResults(...
|
|
26
|
+
buildTodoFromLintResults(...parameters) {
|
|
27
|
+
return this.#todoCore.buildTodoFromLintResults(...parameters);
|
|
28
28
|
}
|
|
29
|
-
getTodoModulePath(...
|
|
30
|
-
return this.#todoCore.getTodoModulePath(...
|
|
29
|
+
getTodoModulePath(...parameters) {
|
|
30
|
+
return this.#todoCore.getTodoModulePath(...parameters);
|
|
31
31
|
}
|
|
32
|
-
initializeESLint(...
|
|
33
|
-
return this.#todoCore.initializeESLint(...
|
|
32
|
+
initializeESLint(...parameters) {
|
|
33
|
+
return this.#todoCore.initializeESLint(...parameters);
|
|
34
34
|
}
|
|
35
|
-
async lint(...
|
|
36
|
-
return this.#todoCore.lint(...
|
|
35
|
+
async lint(...parameters) {
|
|
36
|
+
return this.#todoCore.lint(...parameters);
|
|
37
37
|
}
|
|
38
|
-
async readTodoModule(...
|
|
39
|
-
return this.#todoCore._DO_NOT_USE_DIRECTLY_unsafeReadTodoModule(
|
|
38
|
+
async readTodoModule(...parameters) {
|
|
39
|
+
return this.#todoCore._DO_NOT_USE_DIRECTLY_unsafeReadTodoModule(
|
|
40
|
+
...parameters
|
|
41
|
+
);
|
|
40
42
|
}
|
|
41
|
-
async resetTodoModule(...
|
|
42
|
-
return this.#todoCore.resetTodoModule(...
|
|
43
|
+
async resetTodoModule(...parameters) {
|
|
44
|
+
return this.#todoCore.resetTodoModule(...parameters);
|
|
43
45
|
}
|
|
44
|
-
async writeTodoModule(...
|
|
45
|
-
return this.#todoCore.writeTodoModule(...
|
|
46
|
+
async writeTodoModule(...parameters) {
|
|
47
|
+
return this.#todoCore.writeTodoModule(...parameters);
|
|
46
48
|
}
|
|
47
49
|
}
|
|
48
50
|
Comlink.expose(
|
|
@@ -82,7 +82,7 @@ type TodoFilePath = {
|
|
|
82
82
|
|
|
83
83
|
type MaybePromise<T> = Promise<T> | T;
|
|
84
84
|
type MaybePromisifyAllMethods<T> = {
|
|
85
|
-
[K in keyof T]: T[K] extends (...
|
|
85
|
+
[K in keyof T]: T[K] extends (...arguments_: infer A) => infer R ? R extends PromiseLike<unknown> ? (...arguments_: A) => R : (...arguments_: A) => MaybePromise<R> : T[K];
|
|
86
86
|
};
|
|
87
87
|
|
|
88
88
|
type ESLintInitializeOptions = Pick<ESLint.Options, "overrideConfig">;
|
|
@@ -18,9 +18,9 @@ const generateTodoModuleCode = (eslintTodo) => {
|
|
|
18
18
|
"",
|
|
19
19
|
"export default {};"
|
|
20
20
|
].join("\n");
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
const { code: jsCode } = generateCode(
|
|
21
|
+
const module_ = parseModule(js);
|
|
22
|
+
module_.exports.default = eslintTodo;
|
|
23
|
+
const { code: jsCode } = generateCode(module_, {
|
|
24
24
|
format: { objectCurlySpacing: true, tabWidth: 2 }
|
|
25
25
|
});
|
|
26
26
|
return `${jsCode}
|
|
@@ -28,7 +28,7 @@ const generateTodoModuleCode = (eslintTodo) => {
|
|
|
28
28
|
};
|
|
29
29
|
|
|
30
30
|
const escapeGlobCharacters = (glob) => {
|
|
31
|
-
return glob.
|
|
31
|
+
return glob.replaceAll("\\", "\\\\").replaceAll("*", String.raw`\*`).replaceAll("?", String.raw`\?`).replaceAll("[", String.raw`\[`).replaceAll("]", String.raw`\]`).replaceAll("{", String.raw`\{`).replaceAll("}", String.raw`\}`).replaceAll(")", String.raw`\)`).replaceAll("(", String.raw`\(`).replaceAll("!", String.raw`\!`);
|
|
32
32
|
};
|
|
33
33
|
const isNonEmptyString = (maybeString) => {
|
|
34
34
|
return typeof maybeString === "string" && maybeString !== "";
|
|
@@ -41,7 +41,7 @@ const TodoModuleV2Handler = {
|
|
|
41
41
|
version: 2,
|
|
42
42
|
buildConfigsForESLint: ({ todo }, severity) => {
|
|
43
43
|
return Object.entries(todo).map(([ruleId, entry]) => ({
|
|
44
|
-
files: Object.keys(entry.violations).map(escapeGlobCharacters),
|
|
44
|
+
files: Object.keys(entry.violations).map((f) => escapeGlobCharacters(f)),
|
|
45
45
|
name: `@sushichan044/eslint-todo/${severity}/${ruleId}`,
|
|
46
46
|
rules: {
|
|
47
47
|
[ruleId]: severity
|
|
@@ -49,23 +49,23 @@ const TodoModuleV2Handler = {
|
|
|
49
49
|
}));
|
|
50
50
|
},
|
|
51
51
|
buildTodoFromLintResults(lintResult, options) {
|
|
52
|
-
return lintResult.reduce((
|
|
52
|
+
return lintResult.reduce((todoModule, result) => {
|
|
53
53
|
const relativeFilePath = relative(options.cwd, result.filePath);
|
|
54
54
|
for (const message of result.messages) {
|
|
55
55
|
if (!isNonEmptyString(message.ruleId)) {
|
|
56
56
|
continue;
|
|
57
57
|
}
|
|
58
|
-
|
|
58
|
+
todoModule.todo[message.ruleId] ??= {
|
|
59
59
|
autoFix: false,
|
|
60
60
|
violations: {}
|
|
61
61
|
};
|
|
62
|
-
|
|
63
|
-
if (Object.hasOwn(
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
todoModule.todo[message.ruleId].violations[relativeFilePath] ??= 0;
|
|
63
|
+
if (Object.hasOwn(todoModule.todo, message.ruleId)) {
|
|
64
|
+
todoModule.todo[message.ruleId].violations[relativeFilePath]++;
|
|
65
|
+
todoModule.todo[message.ruleId].autoFix = message.fix != null;
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
|
-
return
|
|
68
|
+
return todoModule;
|
|
69
69
|
}, TodoModuleV2Handler.getDefaultTodo());
|
|
70
70
|
},
|
|
71
71
|
getDefaultTodo() {
|
|
@@ -89,7 +89,7 @@ const TodoModuleV1Handler = {
|
|
|
89
89
|
version: 1,
|
|
90
90
|
buildConfigsForESLint: (todo, severity) => {
|
|
91
91
|
return Object.entries(todo).map(([ruleId, entry]) => ({
|
|
92
|
-
files: entry.files.map(escapeGlobCharacters),
|
|
92
|
+
files: entry.files.map((f) => escapeGlobCharacters(f)),
|
|
93
93
|
name: `@sushichan044/eslint-todo/${severity}/${ruleId}`,
|
|
94
94
|
rules: {
|
|
95
95
|
[ruleId]: severity
|
|
@@ -97,22 +97,22 @@ const TodoModuleV1Handler = {
|
|
|
97
97
|
}));
|
|
98
98
|
},
|
|
99
99
|
buildTodoFromLintResults(lintResult, options) {
|
|
100
|
-
return lintResult.reduce((
|
|
100
|
+
return lintResult.reduce((todoModule, result) => {
|
|
101
101
|
const relativeFilePath = relative(options.cwd, result.filePath);
|
|
102
102
|
for (const message of result.messages) {
|
|
103
103
|
if (!isNonEmptyString(message.ruleId)) {
|
|
104
104
|
continue;
|
|
105
105
|
}
|
|
106
|
-
|
|
106
|
+
todoModule[message.ruleId] ??= {
|
|
107
107
|
autoFix: false,
|
|
108
108
|
files: []
|
|
109
109
|
};
|
|
110
|
-
if (Object.hasOwn(
|
|
111
|
-
|
|
112
|
-
|
|
110
|
+
if (Object.hasOwn(todoModule, message.ruleId)) {
|
|
111
|
+
todoModule[message.ruleId].files.push(relativeFilePath);
|
|
112
|
+
todoModule[message.ruleId].autoFix = message.fix != null;
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
|
-
return
|
|
115
|
+
return todoModule;
|
|
116
116
|
}, TodoModuleV1Handler.getDefaultTodo());
|
|
117
117
|
},
|
|
118
118
|
getDefaultTodo() {
|
|
@@ -243,4 +243,4 @@ class ESLintTodoCore {
|
|
|
243
243
|
}
|
|
244
244
|
}
|
|
245
245
|
|
|
246
|
-
export { ESLintTodoCore as E, LATEST_MODULE_HANDLER as L, TodoModuleV1Handler as T, TodoModuleV2Handler as a, buildESLintConfigForModule as b };
|
|
246
|
+
export { ESLintTodoCore as E, LATEST_MODULE_HANDLER as L, TodoModuleV1Handler as T, TodoModuleV2Handler as a, buildESLintConfigForModule as b, isNonEmptyString as i };
|
|
@@ -82,7 +82,7 @@ type TodoFilePath = {
|
|
|
82
82
|
|
|
83
83
|
type MaybePromise<T> = Promise<T> | T;
|
|
84
84
|
type MaybePromisifyAllMethods<T> = {
|
|
85
|
-
[K in keyof T]: T[K] extends (...
|
|
85
|
+
[K in keyof T]: T[K] extends (...arguments_: infer A) => infer R ? R extends PromiseLike<unknown> ? (...arguments_: A) => R : (...arguments_: A) => MaybePromise<R> : T[K];
|
|
86
86
|
};
|
|
87
87
|
|
|
88
88
|
type ESLintInitializeOptions = Pick<ESLint.Options, "overrideConfig">;
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"type": "git",
|
|
5
5
|
"url": "https://github.com/sushichan044/eslint-todo.git"
|
|
6
6
|
},
|
|
7
|
-
"version": "0.0.
|
|
7
|
+
"version": "0.0.3",
|
|
8
8
|
"type": "module",
|
|
9
9
|
"bin": {
|
|
10
10
|
"eslint-todo": "bin/eslint-todo.mjs"
|
|
@@ -36,25 +36,29 @@
|
|
|
36
36
|
"klona": "2.0.6",
|
|
37
37
|
"magicast": "0.3.5",
|
|
38
38
|
"pathe": "2.0.3",
|
|
39
|
-
"valibot": "1.0.0-rc.
|
|
39
|
+
"valibot": "1.0.0-rc.3"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@eslint/config-inspector": "1.0.
|
|
43
|
-
"@types/node": "22.13.
|
|
42
|
+
"@eslint/config-inspector": "1.0.1",
|
|
43
|
+
"@types/node": "22.13.8",
|
|
44
44
|
"@virtual-live-lab/eslint-config": "2.2.17",
|
|
45
45
|
"@virtual-live-lab/prettier-config": "2.0.16",
|
|
46
46
|
"@virtual-live-lab/tsconfig": "2.1.17",
|
|
47
|
-
"@vitest/coverage-v8": "3.0.
|
|
48
|
-
"@vitest/eslint-plugin": "1.1.
|
|
49
|
-
"eslint": "9.
|
|
47
|
+
"@vitest/coverage-v8": "3.0.7",
|
|
48
|
+
"@vitest/eslint-plugin": "1.1.36",
|
|
49
|
+
"eslint": "9.21.0",
|
|
50
50
|
"eslint-flat-config-utils": "2.0.1",
|
|
51
|
+
"eslint-plugin-import-access": "2.2.2",
|
|
52
|
+
"eslint-plugin-unicorn": "57.0.0",
|
|
51
53
|
"eslint-typegen": "2.0.0",
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
+
"globals": "16.0.0",
|
|
55
|
+
"pkg-pr-new": "0.0.40",
|
|
56
|
+
"pnpm": "10.5.2",
|
|
57
|
+
"prettier": "3.5.3",
|
|
54
58
|
"typescript": "5.7.3",
|
|
55
|
-
"typescript-eslint": "8.
|
|
56
|
-
"unbuild": "3.
|
|
57
|
-
"vitest": "3.0.
|
|
59
|
+
"typescript-eslint": "8.25.0",
|
|
60
|
+
"unbuild": "3.5.0",
|
|
61
|
+
"vitest": "3.0.7"
|
|
58
62
|
},
|
|
59
63
|
"engines": {
|
|
60
64
|
"node": "^20.0.0 || ^22.0.0 || ^23.0.0"
|