@sushichan044/eslint-todo 0.0.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/bin/eslint-todo.mjs +8 -0
- package/dist/cli.d.mts +3 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.mjs +45 -0
- package/dist/eslint.d.mts +6 -0
- package/dist/eslint.d.ts +6 -0
- package/dist/eslint.mjs +44 -0
- package/dist/index.d.mts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.mjs +68 -0
- package/dist/shared/eslint-todo.BijUMnSZ.d.mts +16 -0
- package/dist/shared/eslint-todo.BijUMnSZ.d.ts +16 -0
- package/dist/shared/eslint-todo.DYn5wjQX.mjs +24 -0
- package/package.json +59 -0
package/dist/cli.d.mts
ADDED
package/dist/cli.d.ts
ADDED
package/dist/cli.mjs
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { defineCommand, runMain } from 'citty';
|
|
2
|
+
import { generateESLintTodo } from './index.mjs';
|
|
3
|
+
import 'eslint';
|
|
4
|
+
import 'node:fs';
|
|
5
|
+
import 'node:fs/promises';
|
|
6
|
+
import 'node:path';
|
|
7
|
+
import 'magicast';
|
|
8
|
+
import './shared/eslint-todo.DYn5wjQX.mjs';
|
|
9
|
+
import 'defu';
|
|
10
|
+
import 'node:process';
|
|
11
|
+
import 'jiti';
|
|
12
|
+
|
|
13
|
+
const cli = defineCommand({
|
|
14
|
+
args: {
|
|
15
|
+
cwd: {
|
|
16
|
+
description: "Current working directory",
|
|
17
|
+
required: false,
|
|
18
|
+
type: "string",
|
|
19
|
+
valueHint: "path"
|
|
20
|
+
},
|
|
21
|
+
"todo-file": {
|
|
22
|
+
description: "ESLint todo file name",
|
|
23
|
+
required: false,
|
|
24
|
+
type: "string",
|
|
25
|
+
valueHint: "filename"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
meta: {
|
|
29
|
+
description: "Generate ESLint todo file and temporally suppress ESLint errors!",
|
|
30
|
+
name: "@sushichan044/eslint-todo/cli",
|
|
31
|
+
version: "0.0.1"
|
|
32
|
+
},
|
|
33
|
+
async run({ args }) {
|
|
34
|
+
const options = {
|
|
35
|
+
cwd: args.cwd,
|
|
36
|
+
todoFile: args["todo-file"]
|
|
37
|
+
};
|
|
38
|
+
await generateESLintTodo(options);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
const run = async (argv) => {
|
|
42
|
+
await runMain(cli, { rawArgs: argv });
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export { run };
|
package/dist/eslint.d.ts
ADDED
package/dist/eslint.mjs
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { o as optionsWithDefault, a as importDefault, e as escapeGlobCharacters } from './shared/eslint-todo.DYn5wjQX.mjs';
|
|
4
|
+
import 'defu';
|
|
5
|
+
import 'node:process';
|
|
6
|
+
import 'jiti';
|
|
7
|
+
|
|
8
|
+
const eslintConfigTodo = async (userOptions = {}) => {
|
|
9
|
+
const resolvedOptions = optionsWithDefault(userOptions);
|
|
10
|
+
const todoPath = path.resolve(resolvedOptions.cwd, resolvedOptions.todoFile);
|
|
11
|
+
if (!existsSync(todoPath)) {
|
|
12
|
+
return [];
|
|
13
|
+
}
|
|
14
|
+
const todoModule = await importDefault(todoPath);
|
|
15
|
+
const config = buildESLintFlatConfig({
|
|
16
|
+
todo: todoModule,
|
|
17
|
+
...resolvedOptions
|
|
18
|
+
});
|
|
19
|
+
return config;
|
|
20
|
+
};
|
|
21
|
+
const buildESLintFlatConfig = (options) => {
|
|
22
|
+
const { cwd, todo, todoFile } = options;
|
|
23
|
+
const configs = [];
|
|
24
|
+
const relativeTodoFilePath = path.relative(cwd, path.resolve(cwd, todoFile));
|
|
25
|
+
configs.push({
|
|
26
|
+
files: [relativeTodoFilePath],
|
|
27
|
+
linterOptions: {
|
|
28
|
+
reportUnusedDisableDirectives: false
|
|
29
|
+
},
|
|
30
|
+
name: "@sushichan044/eslint-todo/setup"
|
|
31
|
+
});
|
|
32
|
+
Object.entries(todo).forEach(([ruleId, entry]) => {
|
|
33
|
+
configs.push({
|
|
34
|
+
files: entry.files.map((f) => escapeGlobCharacters(f)),
|
|
35
|
+
name: `@sushichan044/eslint-todo/todo/${ruleId}`,
|
|
36
|
+
rules: {
|
|
37
|
+
[ruleId]: "off"
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
return configs;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export { eslintConfigTodo };
|
package/dist/index.d.mts
ADDED
package/dist/index.d.ts
ADDED
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { ESLint } from 'eslint';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { writeFile } from 'node:fs/promises';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { parseModule, generateCode } from 'magicast';
|
|
6
|
+
import { o as optionsWithDefault, i as isNonEmptyString } from './shared/eslint-todo.DYn5wjQX.mjs';
|
|
7
|
+
import 'defu';
|
|
8
|
+
import 'node:process';
|
|
9
|
+
import 'jiti';
|
|
10
|
+
|
|
11
|
+
const generateESLintTodoModule = (eslintTodo) => {
|
|
12
|
+
const js = `/* eslint-disable */
|
|
13
|
+
/**
|
|
14
|
+
* Auto generated file by eslint-todo. DO NOT EDIT MANUALLY.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
export default {};
|
|
18
|
+
`;
|
|
19
|
+
const mod = parseModule(js);
|
|
20
|
+
mod.exports["default"] = eslintTodo;
|
|
21
|
+
const { code: jsCode } = generateCode(mod, {
|
|
22
|
+
format: { objectCurlySpacing: true, tabWidth: 2 }
|
|
23
|
+
});
|
|
24
|
+
return `${jsCode}
|
|
25
|
+
`;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const resetTodoFile = async (todoFilePath) => {
|
|
29
|
+
if (!existsSync(todoFilePath)) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
await writeFile(todoFilePath, generateESLintTodoModule({}));
|
|
33
|
+
};
|
|
34
|
+
const runESLintLinting = async (eslint, options) => eslint.lintFiles(path.resolve(options.cwd, "**/*"));
|
|
35
|
+
const aggregateESLintTodoByRuleId = (results, options) => {
|
|
36
|
+
return results.reduce((acc, lintResult) => {
|
|
37
|
+
for (const message of lintResult.messages) {
|
|
38
|
+
if (!isNonEmptyString(message.ruleId)) {
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
acc[message.ruleId] ??= {
|
|
42
|
+
autoFix: false,
|
|
43
|
+
files: []
|
|
44
|
+
};
|
|
45
|
+
if (Object.prototype.hasOwnProperty.call(acc, message.ruleId)) {
|
|
46
|
+
acc[message.ruleId].files.push(
|
|
47
|
+
path.relative(options.cwd, lintResult.filePath)
|
|
48
|
+
);
|
|
49
|
+
acc[message.ruleId].autoFix = message.fix != null;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return acc;
|
|
53
|
+
}, {});
|
|
54
|
+
};
|
|
55
|
+
const generateESLintTodo = async (userOptions) => {
|
|
56
|
+
const resolvedOptions = optionsWithDefault(userOptions);
|
|
57
|
+
const resolvedTodoPath = path.resolve(
|
|
58
|
+
resolvedOptions.cwd,
|
|
59
|
+
resolvedOptions.todoFile
|
|
60
|
+
);
|
|
61
|
+
await resetTodoFile(resolvedTodoPath);
|
|
62
|
+
const eslint = new ESLint();
|
|
63
|
+
const results = await runESLintLinting(eslint, resolvedOptions);
|
|
64
|
+
const todoByRuleId = aggregateESLintTodoByRuleId(results, resolvedOptions);
|
|
65
|
+
await writeFile(resolvedTodoPath, generateESLintTodoModule(todoByRuleId));
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export { generateESLintTodo };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
type Options = {
|
|
2
|
+
/**
|
|
3
|
+
* The file path to read and write the ESLint todo list.
|
|
4
|
+
* @default ".eslint-todo.js"
|
|
5
|
+
*/
|
|
6
|
+
todoFile: string;
|
|
7
|
+
/**
|
|
8
|
+
* The current working directory.
|
|
9
|
+
*
|
|
10
|
+
* @default process.cwd()
|
|
11
|
+
*/
|
|
12
|
+
cwd: string;
|
|
13
|
+
};
|
|
14
|
+
type UserOptions = Partial<Options>;
|
|
15
|
+
|
|
16
|
+
export type { UserOptions as U };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
type Options = {
|
|
2
|
+
/**
|
|
3
|
+
* The file path to read and write the ESLint todo list.
|
|
4
|
+
* @default ".eslint-todo.js"
|
|
5
|
+
*/
|
|
6
|
+
todoFile: string;
|
|
7
|
+
/**
|
|
8
|
+
* The current working directory.
|
|
9
|
+
*
|
|
10
|
+
* @default process.cwd()
|
|
11
|
+
*/
|
|
12
|
+
cwd: string;
|
|
13
|
+
};
|
|
14
|
+
type UserOptions = Partial<Options>;
|
|
15
|
+
|
|
16
|
+
export type { UserOptions as U };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { defu } from 'defu';
|
|
2
|
+
import { cwd } from 'node:process';
|
|
3
|
+
import { createJiti } from 'jiti';
|
|
4
|
+
|
|
5
|
+
const optionsWithDefault = (options = {}) => {
|
|
6
|
+
return defu(options, defaultOptions);
|
|
7
|
+
};
|
|
8
|
+
const defaultOptions = {
|
|
9
|
+
cwd: cwd(),
|
|
10
|
+
todoFile: ".eslint-todo.js"
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const jiti = createJiti(import.meta.url);
|
|
14
|
+
const importDefault = async (url) => {
|
|
15
|
+
return await jiti.import(url, { default: true });
|
|
16
|
+
};
|
|
17
|
+
const escapeGlobCharacters = (glob) => {
|
|
18
|
+
return glob.replace(/\\/g, "\\\\").replace(/\*/g, "\\*").replace(/\?/g, "\\?").replace(/\[/g, "\\[").replace(/\]/g, "\\]").replace(/\{/g, "\\{").replace(/\}/g, "\\}").replace(/\)/g, "\\)").replace(/\(/g, "\\(").replace(/\!/g, "\\!");
|
|
19
|
+
};
|
|
20
|
+
const isNonEmptyString = (maybeString) => {
|
|
21
|
+
return maybeString != null && maybeString !== "";
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export { importDefault as a, escapeGlobCharacters as e, isNonEmptyString as i, optionsWithDefault as o };
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sushichan044/eslint-todo",
|
|
3
|
+
"repository": {
|
|
4
|
+
"type": "git",
|
|
5
|
+
"url": "https://github.com/sushichan044/eslint-todo.git"
|
|
6
|
+
},
|
|
7
|
+
"version": "0.0.1",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"bin": {
|
|
10
|
+
"eslint-todo": "bin/eslint-todo.mjs"
|
|
11
|
+
},
|
|
12
|
+
"module": "./dist/index.mjs",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"import": "./dist/index.mjs",
|
|
16
|
+
"types": "./dist/index.d.ts"
|
|
17
|
+
},
|
|
18
|
+
"./cli": {
|
|
19
|
+
"import": "./dist/cli.mjs",
|
|
20
|
+
"types": "./dist/cli.d.ts"
|
|
21
|
+
},
|
|
22
|
+
"./eslint": {
|
|
23
|
+
"import": "./dist/eslint.mjs",
|
|
24
|
+
"types": "./dist/eslint.d.ts"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"dist"
|
|
29
|
+
],
|
|
30
|
+
"peerDependencies": {
|
|
31
|
+
"eslint": "^8.57.0 || ^9.0.0"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"citty": "0.1.6",
|
|
35
|
+
"defu": "6.1.4",
|
|
36
|
+
"jiti": "2.4.2",
|
|
37
|
+
"magicast": "0.3.5"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/node": "22.13.0",
|
|
41
|
+
"@virtual-live-lab/eslint-config": "2.2.16",
|
|
42
|
+
"@virtual-live-lab/prettier-config": "2.0.15",
|
|
43
|
+
"@virtual-live-lab/tsconfig": "2.1.16",
|
|
44
|
+
"eslint": "9.19.0",
|
|
45
|
+
"prettier": "3.4.2",
|
|
46
|
+
"typescript": "5.7.3",
|
|
47
|
+
"typescript-eslint": "8.23.0",
|
|
48
|
+
"unbuild": "3.3.1",
|
|
49
|
+
"vitest": "3.0.4"
|
|
50
|
+
},
|
|
51
|
+
"engines": {
|
|
52
|
+
"node": "^20.0.0 || ^22.0.0 || ^23.0.0"
|
|
53
|
+
},
|
|
54
|
+
"scripts": {
|
|
55
|
+
"build": "unbuild",
|
|
56
|
+
"test": "vitest",
|
|
57
|
+
"eslint:inspect": "eslint --inspect-config"
|
|
58
|
+
}
|
|
59
|
+
}
|