@santi020k/eslint-config-basic 3.3.0 → 3.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +49 -0
- package/dist/cli-preset.d.ts +13 -2
- package/dist/cli-preset.js +58 -9
- package/dist/cli-preset.js.map +1 -1
- package/dist/cli-workflows.d.ts +23 -3
- package/dist/cli-workflows.js +173 -11
- package/dist/cli-workflows.js.map +1 -1
- package/dist/cli.d.ts +2 -1
- package/dist/cli.js +44 -4
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +12 -2
- package/dist/index.js.map +1 -1
- package/dist/recommended.d.ts +6 -3
- package/dist/recommended.js +2 -1
- package/dist/recommended.js.map +1 -1
- package/dist/tailwind.d.ts +2 -1
- package/dist/tailwind.js +87 -11
- package/dist/tailwind.js.map +1 -1
- package/package.json +9 -9
package/dist/cli-workflows.js
CHANGED
|
@@ -3,6 +3,18 @@ import { existsSync, readdirSync, readFileSync, statSync, writeFileSync } from "
|
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import { basename, dirname, extname, join, relative, resolve } from "node:path";
|
|
5
5
|
const SNAPSHOT_FILENAME = ".eslint-config-snapshot.json";
|
|
6
|
+
const ESLINT_CONFIG_FILENAMES = [
|
|
7
|
+
"eslint.config.js",
|
|
8
|
+
"eslint.config.mjs",
|
|
9
|
+
"eslint.config.cjs",
|
|
10
|
+
"eslint.config.ts",
|
|
11
|
+
"eslint.config.mts",
|
|
12
|
+
"eslint.config.cts"
|
|
13
|
+
];
|
|
14
|
+
const NON_PORTABLE_DECLARATION_PATTERNS = [
|
|
15
|
+
{ label: "a pnpm-internal installation path", pattern: /(?:^|[\\/])\.pnpm(?:[\\/]|$)/m },
|
|
16
|
+
{ label: "the transitive typescript-eslint package", pattern: /["']typescript-eslint["']/m }
|
|
17
|
+
];
|
|
6
18
|
const SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
7
19
|
".astro",
|
|
8
20
|
".cjs",
|
|
@@ -52,6 +64,149 @@ const defaultCommandRunner = (executable, args, cwd) => {
|
|
|
52
64
|
stdout: result.stdout
|
|
53
65
|
};
|
|
54
66
|
};
|
|
67
|
+
const resolveProjectRequire = (cwd) => createRequire(join(cwd, "package.json"));
|
|
68
|
+
const formatTypeScriptDiagnostic = (typescript, diagnostic, cwd) => {
|
|
69
|
+
const message = typescript.flattenDiagnosticMessageText(diagnostic.messageText, "\n");
|
|
70
|
+
if (!diagnostic.file || diagnostic.start === void 0) return `TS${diagnostic.code}: ${message}`;
|
|
71
|
+
const position = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
|
|
72
|
+
return `${relative(cwd, diagnostic.file.fileName)}:${position.line + 1}:${position.character + 1} TS${diagnostic.code}: ${message}`;
|
|
73
|
+
};
|
|
74
|
+
const getConfigAmbientOptions = (configPath) => {
|
|
75
|
+
const content = readFileSync(configPath, "utf8");
|
|
76
|
+
const usesNodeGlobals = /\b(?:Buffer|NodeJS|process|require|module|__dirname|__filename)\b/.test(content) || /\bimport\.meta\.(?:dirname|filename)\b/.test(content);
|
|
77
|
+
if (!usesNodeGlobals) return { types: [] };
|
|
78
|
+
try {
|
|
79
|
+
const nodeManifest = createRequire(configPath).resolve("@types/node/package.json");
|
|
80
|
+
return {
|
|
81
|
+
typeRoots: [dirname(dirname(nodeManifest))],
|
|
82
|
+
types: ["node"]
|
|
83
|
+
};
|
|
84
|
+
} catch {
|
|
85
|
+
return { types: [] };
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
const getConfigCompilerOptions = (typescript, configPath) => {
|
|
89
|
+
const tsconfig = typescript.findConfigFile(
|
|
90
|
+
dirname(configPath),
|
|
91
|
+
(fileName) => typescript.sys.fileExists(fileName)
|
|
92
|
+
);
|
|
93
|
+
const diagnostics = [];
|
|
94
|
+
let options = {};
|
|
95
|
+
if (tsconfig) {
|
|
96
|
+
const readResult = typescript.readConfigFile(
|
|
97
|
+
tsconfig,
|
|
98
|
+
(fileName) => typescript.sys.readFile(fileName)
|
|
99
|
+
);
|
|
100
|
+
if (readResult.error) {
|
|
101
|
+
diagnostics.push(readResult.error);
|
|
102
|
+
} else {
|
|
103
|
+
const parsed = typescript.parseJsonConfigFileContent(
|
|
104
|
+
readResult.config,
|
|
105
|
+
typescript.sys,
|
|
106
|
+
dirname(tsconfig)
|
|
107
|
+
);
|
|
108
|
+
diagnostics.push(...parsed.errors.filter((diagnostic) => ![18002, 18003].includes(diagnostic.code)));
|
|
109
|
+
options = parsed.options;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
diagnostics,
|
|
114
|
+
options: {
|
|
115
|
+
...options,
|
|
116
|
+
...getConfigAmbientOptions(configPath),
|
|
117
|
+
allowJs: true,
|
|
118
|
+
checkJs: false,
|
|
119
|
+
composite: false,
|
|
120
|
+
declaration: true,
|
|
121
|
+
declarationDir: void 0,
|
|
122
|
+
emitDeclarationOnly: true,
|
|
123
|
+
incremental: false,
|
|
124
|
+
...Number(typescript.versionMajorMinor.split(".")[0]) >= 6 ? { ignoreDeprecations: "6.0" } : {},
|
|
125
|
+
module: options.module ?? typescript.ModuleKind.NodeNext,
|
|
126
|
+
moduleResolution: options.moduleResolution ?? typescript.ModuleResolutionKind.NodeNext,
|
|
127
|
+
noEmit: false,
|
|
128
|
+
noEmitOnError: false,
|
|
129
|
+
outDir: void 0,
|
|
130
|
+
rootDir: void 0,
|
|
131
|
+
skipLibCheck: true,
|
|
132
|
+
target: options.target ?? typescript.ScriptTarget.ES2022,
|
|
133
|
+
tsBuildInfoFile: void 0
|
|
134
|
+
},
|
|
135
|
+
tsconfig: tsconfig ?? null
|
|
136
|
+
};
|
|
137
|
+
};
|
|
138
|
+
const emitConfigDeclarations = (typescript, cwd, configPath) => {
|
|
139
|
+
const setup = getConfigCompilerOptions(typescript, configPath);
|
|
140
|
+
const program = typescript.createProgram([configPath], setup.options);
|
|
141
|
+
const outputs = /* @__PURE__ */ new Map();
|
|
142
|
+
const emitResult = program.emit(
|
|
143
|
+
void 0,
|
|
144
|
+
(fileName, content) => outputs.set(fileName, content),
|
|
145
|
+
void 0,
|
|
146
|
+
true
|
|
147
|
+
);
|
|
148
|
+
const diagnostics = [
|
|
149
|
+
...setup.diagnostics,
|
|
150
|
+
...typescript.getPreEmitDiagnostics(program),
|
|
151
|
+
...emitResult.diagnostics
|
|
152
|
+
].filter((diagnostic) => diagnostic.category === typescript.DiagnosticCategory.Error);
|
|
153
|
+
const declarationStem = `${basename(configPath, extname(configPath))}.d.`;
|
|
154
|
+
const declarations = [...outputs.entries()].filter(([fileName]) => basename(fileName).startsWith(declarationStem) && /\.d\.(?:cts|mts|ts)$/.test(fileName));
|
|
155
|
+
const issues = [...new Set(
|
|
156
|
+
diagnostics.map((diagnostic) => formatTypeScriptDiagnostic(typescript, diagnostic, cwd))
|
|
157
|
+
)];
|
|
158
|
+
if (declarations.length === 0) issues.push("TypeScript did not emit a declaration for this config.");
|
|
159
|
+
for (const [fileName, content] of declarations) {
|
|
160
|
+
for (const { label, pattern } of NON_PORTABLE_DECLARATION_PATTERNS) {
|
|
161
|
+
if (pattern.test(content)) issues.push(`${relative(cwd, fileName)} references ${label}.`);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return {
|
|
165
|
+
declarations: declarations.map(([fileName]) => relative(cwd, fileName)).sort(),
|
|
166
|
+
file: relative(cwd, configPath),
|
|
167
|
+
issues,
|
|
168
|
+
portable: issues.length === 0,
|
|
169
|
+
tsconfig: setup.tsconfig ? relative(cwd, setup.tsconfig) : null
|
|
170
|
+
};
|
|
171
|
+
};
|
|
172
|
+
const createConfigTypesReport = (cwd = process.cwd(), options = {}) => {
|
|
173
|
+
const projectRequire = resolveProjectRequire(cwd);
|
|
174
|
+
let typescript;
|
|
175
|
+
try {
|
|
176
|
+
typescript = projectRequire("typescript");
|
|
177
|
+
} catch {
|
|
178
|
+
throw new Error("TypeScript is required for config-types. Install it in the consumer project first.");
|
|
179
|
+
}
|
|
180
|
+
const configPaths = options.files && options.files.length > 0 ? options.files.map((file) => resolve(cwd, file)) : ESLINT_CONFIG_FILENAMES.map((file) => join(cwd, file)).filter((file) => existsSync(file));
|
|
181
|
+
if (configPaths.length === 0) {
|
|
182
|
+
throw new Error("No eslint.config.* file was found. Pass --file for a project-scoped config.");
|
|
183
|
+
}
|
|
184
|
+
for (const configPath of configPaths) {
|
|
185
|
+
if (!existsSync(configPath)) throw new Error(`Config file does not exist: ${relative(cwd, configPath)}`);
|
|
186
|
+
}
|
|
187
|
+
const files = configPaths.map((configPath) => emitConfigDeclarations(typescript, cwd, configPath));
|
|
188
|
+
return {
|
|
189
|
+
files,
|
|
190
|
+
portable: files.every((file) => file.portable),
|
|
191
|
+
typescriptVersion: typescript.version
|
|
192
|
+
};
|
|
193
|
+
};
|
|
194
|
+
const handleConfigTypes = (cwd = process.cwd(), options = {}) => {
|
|
195
|
+
const report = createConfigTypesReport(cwd, options);
|
|
196
|
+
if (options.json) {
|
|
197
|
+
console.log(JSON.stringify(report, null, 2));
|
|
198
|
+
} else {
|
|
199
|
+
console.log([
|
|
200
|
+
`ESLint config declaration portability: ${report.portable ? "passed" : "failed"}`,
|
|
201
|
+
`- TypeScript: ${report.typescriptVersion}`,
|
|
202
|
+
...report.files.flatMap((file) => [
|
|
203
|
+
`- ${file.file}: ${file.portable ? "portable" : "not portable"} (tsconfig: ${file.tsconfig ?? "compiler defaults"})`,
|
|
204
|
+
...file.issues.map((issue) => ` - ${issue}`)
|
|
205
|
+
])
|
|
206
|
+
].join("\n"));
|
|
207
|
+
}
|
|
208
|
+
if (!report.portable) process.exitCode = 1;
|
|
209
|
+
};
|
|
55
210
|
const readJson = (filePath) => {
|
|
56
211
|
if (!existsSync(filePath)) return null;
|
|
57
212
|
try {
|
|
@@ -60,7 +215,6 @@ const readJson = (filePath) => {
|
|
|
60
215
|
return null;
|
|
61
216
|
}
|
|
62
217
|
};
|
|
63
|
-
const resolveProjectRequire = (cwd) => createRequire(join(cwd, "package.json"));
|
|
64
218
|
const resolveEslintCli = (cwd) => {
|
|
65
219
|
const projectRequire = resolveProjectRequire(cwd);
|
|
66
220
|
const packagePath = projectRequire.resolve("eslint/package.json");
|
|
@@ -310,30 +464,31 @@ const getObjectKeys = (value) => {
|
|
|
310
464
|
if (!value || typeof value !== "object" || Array.isArray(value)) return [];
|
|
311
465
|
return Object.keys(value).sort();
|
|
312
466
|
};
|
|
313
|
-
const normalizeConfig = (config) => {
|
|
467
|
+
const normalizeConfig = (config, scope) => {
|
|
314
468
|
const resolved = config && typeof config === "object" ? config : {};
|
|
315
469
|
return {
|
|
316
|
-
globals: normalizeSerializableObject(resolved.languageOptions?.globals),
|
|
317
|
-
languageOptions: {
|
|
470
|
+
globals: scope === "rules" ? {} : normalizeSerializableObject(resolved.languageOptions?.globals),
|
|
471
|
+
languageOptions: scope === "rules" ? {} : {
|
|
318
472
|
ecmaVersion: resolved.languageOptions?.ecmaVersion,
|
|
319
473
|
sourceType: resolved.languageOptions?.sourceType
|
|
320
474
|
},
|
|
321
|
-
plugins: getObjectKeys(resolved.plugins),
|
|
475
|
+
plugins: scope === "rules" ? [] : getObjectKeys(resolved.plugins),
|
|
322
476
|
rules: normalizeSerializableObject(resolved.rules)
|
|
323
477
|
};
|
|
324
478
|
};
|
|
325
|
-
const createConfigSnapshot = async (cwd, files, eslint = loadProjectEslint(cwd)) => {
|
|
479
|
+
const createConfigSnapshot = async (cwd, files, eslint = loadProjectEslint(cwd), scope = "all") => {
|
|
326
480
|
const representativeFiles = files?.length ? files : await findUnignoredRepresentativeFiles(cwd, eslint);
|
|
327
481
|
if (representativeFiles.length === 0) {
|
|
328
482
|
throw new Error("No representative source files were found. Pass one or more --file paths.");
|
|
329
483
|
}
|
|
330
484
|
const entries = await Promise.all(representativeFiles.map(async (filePath) => {
|
|
331
485
|
const config = await eslint.calculateConfigForFile(filePath);
|
|
332
|
-
return [filePath, normalizeConfig(config)];
|
|
486
|
+
return [filePath, normalizeConfig(config, scope)];
|
|
333
487
|
}));
|
|
334
488
|
return {
|
|
335
489
|
files: Object.fromEntries(entries),
|
|
336
|
-
|
|
490
|
+
...scope === "rules" ? { scope } : {},
|
|
491
|
+
version: scope === "rules" ? 2 : 1
|
|
337
492
|
};
|
|
338
493
|
};
|
|
339
494
|
const sameValue = (left, right) => JSON.stringify(left) === JSON.stringify(right);
|
|
@@ -394,14 +549,19 @@ const handleSnapshot = async (cwd = process.cwd(), options = {}, eslint) => {
|
|
|
394
549
|
return;
|
|
395
550
|
}
|
|
396
551
|
const files = options.files?.length ? options.files : Object.keys(previous.files);
|
|
397
|
-
const current2 = await createConfigSnapshot(cwd, files, eslint);
|
|
552
|
+
const current2 = await createConfigSnapshot(cwd, files, eslint, previous.scope ?? "all");
|
|
398
553
|
const diffs = diffConfigSnapshots(previous, current2);
|
|
399
554
|
if (options.json) console.log(JSON.stringify({ diffs, snapshotPath }, null, 2));
|
|
400
555
|
else outputSnapshotDiff(diffs);
|
|
401
556
|
if (diffs.length > 0) process.exitCode = 1;
|
|
402
557
|
return;
|
|
403
558
|
}
|
|
404
|
-
const current = await createConfigSnapshot(
|
|
559
|
+
const current = await createConfigSnapshot(
|
|
560
|
+
cwd,
|
|
561
|
+
options.files,
|
|
562
|
+
eslint,
|
|
563
|
+
options.rulesOnly ? "rules" : "all"
|
|
564
|
+
);
|
|
405
565
|
writeFileSync(snapshotPath, `${JSON.stringify(current, null, 2)}
|
|
406
566
|
`);
|
|
407
567
|
if (options.json) {
|
|
@@ -418,7 +578,7 @@ const handleSnapshotDiff = async (cwd = process.cwd(), options = {}, eslint) =>
|
|
|
418
578
|
const previous = readJson(snapshotPath);
|
|
419
579
|
if (!previous) throw new Error(`Snapshot is missing: ${relative(cwd, snapshotPath)}. Run basic-eslint snapshot first.`);
|
|
420
580
|
const files = options.files?.length ? options.files : Object.keys(previous.files);
|
|
421
|
-
const current = await createConfigSnapshot(cwd, files, eslint);
|
|
581
|
+
const current = await createConfigSnapshot(cwd, files, eslint, previous.scope ?? "all");
|
|
422
582
|
const diffs = diffConfigSnapshots(previous, current);
|
|
423
583
|
if (options.json) console.log(JSON.stringify({ diffs, snapshotPath }, null, 2));
|
|
424
584
|
else outputSnapshotDiff(diffs);
|
|
@@ -433,10 +593,12 @@ const isDirectory = (path) => {
|
|
|
433
593
|
};
|
|
434
594
|
export {
|
|
435
595
|
createConfigSnapshot,
|
|
596
|
+
createConfigTypesReport,
|
|
436
597
|
defaultCommandRunner,
|
|
437
598
|
diffConfigSnapshots,
|
|
438
599
|
findRepresentativeFiles,
|
|
439
600
|
handleBaseline,
|
|
601
|
+
handleConfigTypes,
|
|
440
602
|
handleProfile,
|
|
441
603
|
handleSnapshot,
|
|
442
604
|
handleSnapshotDiff,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli-workflows.ts"],"sourcesContent":["/* eslint-disable complexity -- workflow handlers intentionally cover CLI output and compatibility branches */\n/* eslint-disable no-console -- CLI handlers own user-facing terminal output */\nimport { spawnSync } from 'node:child_process'\nimport { existsSync, readdirSync, readFileSync, statSync, writeFileSync } from 'node:fs'\nimport { createRequire } from 'node:module'\nimport { basename, dirname, extname, join, relative, resolve } from 'node:path'\n\nexport interface CommandResult {\n status: number\n stderr: string\n stdout: string\n}\n\nexport type CommandRunner = (\n executable: string,\n args: string[],\n cwd: string\n) => CommandResult\n\nexport interface BaselineOptions {\n json?: boolean\n preset?: string\n prune?: boolean\n}\n\nexport interface ProfileOptions {\n concurrency?: string\n files?: string[]\n json?: boolean\n maxDurationMs?: number\n maxRuleTimeMs?: number\n maxWarnings?: number\n}\n\nexport interface SnapshotOptions {\n check?: boolean\n files?: string[]\n json?: boolean\n snapshotPath?: string\n}\n\nexport interface SnapshotDiff {\n added: string[]\n changed: { after: unknown, before: unknown, rule: string }[]\n file: string\n removed: string[]\n}\n\ninterface EslintSnapshotFile {\n globals: Record<string, unknown>\n languageOptions: {\n ecmaVersion?: unknown\n sourceType?: unknown\n }\n plugins: string[]\n rules: Record<string, unknown>\n}\n\ninterface EslintSnapshot {\n files: Record<string, EslintSnapshotFile>\n version: 1\n}\n\ninterface EslintStats {\n times?: {\n passes?: {\n fix?: { total?: number }\n parse?: { total?: number }\n rules?: Record<string, { total?: number }>\n total?: number\n }[]\n }\n}\n\ninterface EslintResult {\n errorCount?: number\n filePath?: string\n fatalErrorCount?: number\n stats?: EslintStats\n warningCount?: number\n}\n\ninterface ProfileRun {\n concurrency: string\n durationMs: number\n errorCount: number\n fatalErrorCount: number\n fileCount: number\n parseMs: number\n ruleMs: number\n slowestRules: { rule: string, timeMs: number }[]\n status: number\n warningCount: number\n}\n\ninterface ProjectEslint {\n calculateConfigForFile: (filePath: string) => Promise<unknown>\n isPathIgnored?: (filePath: string) => Promise<boolean>\n}\n\ntype ProjectEslintConstructor = new(options: { cwd: string }) => ProjectEslint\n\nconst SNAPSHOT_FILENAME = '.eslint-config-snapshot.json'\n\nconst SOURCE_EXTENSIONS = new Set([\n '.astro',\n '.cjs',\n '.css',\n '.cts',\n '.gql',\n '.graphql',\n '.html',\n '.js',\n '.json',\n '.json5',\n '.jsonc',\n '.jsx',\n '.md',\n '.mdx',\n '.mjs',\n '.mts',\n '.svelte',\n '.toml',\n '.ts',\n '.tsx',\n '.vue',\n '.yaml',\n '.yml'\n])\n\nconst IGNORED_DIRECTORIES = new Set([\n '.git',\n '.next',\n '.nuxt',\n '.output',\n '.turbo',\n 'build',\n 'coverage',\n 'dist',\n 'node_modules'\n])\n\nexport const defaultCommandRunner: CommandRunner = (executable, args, cwd) => {\n const result = spawnSync(executable, args, {\n cwd,\n encoding: 'utf8',\n env: process.env,\n maxBuffer: 50 * 1024 * 1024\n })\n\n return {\n status: result.status ?? 1,\n stderr: result.stderr,\n stdout: result.stdout\n }\n}\n\nconst readJson = (filePath: string): unknown => {\n if (!existsSync(filePath)) return null\n\n try {\n return JSON.parse(readFileSync(filePath, 'utf8')) as unknown\n } catch {\n return null\n }\n}\n\nconst resolveProjectRequire = (cwd: string) => createRequire(join(cwd, 'package.json'))\n\nconst resolveEslintCli = (cwd: string): string => {\n const projectRequire = resolveProjectRequire(cwd)\n const packagePath = projectRequire.resolve('eslint/package.json')\n const metadata = readJson(packagePath) as null | { bin?: string | Record<string, string> }\n const bin = typeof metadata?.bin === 'string' ? metadata.bin : metadata?.bin?.eslint\n\n if (!bin) throw new Error('The project ESLint CLI could not be resolved. Install eslint before running this command.')\n\n return resolve(dirname(packagePath), bin)\n}\n\nconst runEslint = (\n cwd: string,\n args: string[],\n runner: CommandRunner\n): CommandResult => runner(process.execPath, [resolveEslintCli(cwd), ...args], cwd)\n\nconst outputCommandFailure = (label: string, result: CommandResult): never => {\n const details = result.stderr.trim() || result.stdout.trim() || `exit code ${result.status}`\n\n throw new Error(`${label} failed: ${details}`)\n}\n\nconst createBackupPath = (filePath: string, suffix: string): string => {\n const preferred = `${filePath}.${suffix}.bak`\n\n if (!existsSync(preferred)) return preferred\n\n let index = 2\n\n while (existsSync(`${preferred}.${index}`)) index++\n\n return `${preferred}.${index}`\n}\n\nconst updateConfigStrictPreset = (cwd: string, preset: string): null | string => {\n if (!['ci', 'pedantic'].includes(preset)) {\n throw new Error(`Unsupported baseline preset \"${preset}\". Use \"ci\" or \"pedantic\".`)\n }\n\n const configPath = [\n 'eslint.config.js',\n 'eslint.config.mjs',\n 'eslint.config.cjs',\n 'eslint.config.ts',\n 'eslint.config.mts',\n 'eslint.config.cts'\n ].map(name => join(cwd, name)).find(path => existsSync(path))\n\n if (!configPath) throw new Error('No eslint.config.* file was found. Run basic-eslint init first.')\n\n const content = readFileSync(configPath, 'utf8')\n\n if (new RegExp(`strict\\\\s*:\\\\s*['\"]${preset}['\"]`).test(content)) return null\n\n const zeroArgumentPattern = /\\bdefineConfig\\(\\s*\\)/\n\n if (!zeroArgumentPattern.test(content)) {\n throw new Error(\n `Cannot safely add strict: \"${preset}\" to a customized config. ` +\n 'Add it manually, then run basic-eslint baseline without --preset.'\n )\n }\n\n const backupPath = createBackupPath(configPath, 'baseline')\n\n writeFileSync(backupPath, content)\n\n writeFileSync(configPath, content.replace(zeroArgumentPattern, `defineConfig({ strict: '${preset}' })`))\n\n return basename(backupPath)\n}\n\nexport const handleBaseline = (\n cwd: string = process.cwd(),\n options: BaselineOptions = {},\n runner: CommandRunner = defaultCommandRunner\n): void => {\n const backup = options.preset ? updateConfigStrictPreset(cwd, options.preset) : null\n\n const args = options.prune ?\n ['.', '--prune-suppressions'] :\n ['.', '--fix', '--suppress-all']\n\n const result = runEslint(cwd, args, runner)\n\n if (result.status !== 0) outputCommandFailure('ESLint baseline', result)\n\n const payload = {\n action: options.prune ? 'pruned' : 'created',\n backup,\n preset: options.preset ?? null,\n suppressionsFile: join(cwd, 'eslint-suppressions.json')\n }\n\n if (options.json) {\n console.log(JSON.stringify(payload, null, 2))\n\n return\n }\n\n console.log(options.prune ?\n '✅ Pruned unused ESLint suppressions.' :\n '✅ Created or refreshed eslint-suppressions.json for existing violations.')\n\n if (backup) console.log(`📦 Backed up the previous config to ${backup}.`)\n}\n\nconst getStatsPasses = (result: EslintResult) => result.stats?.times?.passes ?? []\n\nconst summarizeProfileResults = (\n concurrency: string,\n results: EslintResult[],\n durationMs: number,\n status: number\n): ProfileRun => {\n const ruleTimes = new Map<string, number>()\n let parseMs = 0\n let ruleMs = 0\n\n for (const result of results) {\n for (const pass of getStatsPasses(result)) {\n parseMs += pass.parse?.total ?? 0\n\n for (const [rule, timing] of Object.entries(pass.rules ?? {})) {\n const time = timing.total ?? 0\n\n ruleMs += time\n\n ruleTimes.set(rule, (ruleTimes.get(rule) ?? 0) + time)\n }\n }\n }\n\n return {\n concurrency,\n durationMs,\n errorCount: results.reduce((total, result) => total + (result.errorCount ?? 0), 0),\n fatalErrorCount: results.reduce((total, result) => total + (result.fatalErrorCount ?? 0), 0),\n fileCount: results.length,\n parseMs,\n ruleMs,\n slowestRules: [...ruleTimes.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, 15)\n .map(([rule, timeMs]) => ({ rule, timeMs })),\n status,\n warningCount: results.reduce((total, result) => total + (result.warningCount ?? 0), 0)\n }\n}\n\nconst runProfile = (\n cwd: string,\n files: string[],\n concurrency: string,\n runner: CommandRunner\n): ProfileRun => {\n const startedAt = performance.now()\n\n const result = runEslint(\n cwd,\n [...files, '--stats', '--format', 'json', '--concurrency', concurrency],\n runner\n )\n\n const durationMs = performance.now() - startedAt\n let parsed: EslintResult[] = []\n\n try {\n parsed = JSON.parse(result.stdout) as EslintResult[]\n } catch {\n outputCommandFailure('ESLint profile', result)\n }\n\n return summarizeProfileResults(concurrency, parsed, durationMs, result.status)\n}\n\nconst round = (value: number): number => Math.round(value * 100) / 100\n\nexport const handleProfile = (\n cwd: string = process.cwd(),\n options: ProfileOptions = {},\n runner: CommandRunner = defaultCommandRunner\n): void => {\n for (const [name, value] of [\n ['max-duration', options.maxDurationMs],\n ['max-rule-time', options.maxRuleTimeMs],\n ['max-warnings', options.maxWarnings]\n ] as const) {\n if (value !== undefined && (!Number.isFinite(value) || value < 0)) {\n throw new Error(`--${name} must be a non-negative number.`)\n }\n }\n\n const files = options.files?.length ? options.files : ['.']\n const concurrencyModes = options.concurrency ? [options.concurrency] : ['off', 'auto']\n const runs = concurrencyModes.map(concurrency => runProfile(cwd, files, concurrency, runner))\n const successfulRuns = runs.filter(run => run.fatalErrorCount === 0 && run.status < 2)\n\n const recommendation = successfulRuns.length > 0 ?\n successfulRuns.toSorted((a, b) => a.durationMs - b.durationMs)[0].concurrency :\n null\n\n const budgetRun = successfulRuns.toSorted((a, b) => a.durationMs - b.durationMs)[0] ?? runs[0]\n\n const violations: string[] = successfulRuns.length === 0 ?\n ['ESLint profiling did not produce a successful run.'] :\n []\n\n if (options.maxDurationMs !== undefined && budgetRun.durationMs > options.maxDurationMs) {\n violations.push(\n `Duration ${round(budgetRun.durationMs)}ms exceeds the ${options.maxDurationMs}ms budget.`\n )\n }\n\n if (options.maxWarnings !== undefined && budgetRun.warningCount > options.maxWarnings) {\n violations.push(\n `Warnings ${budgetRun.warningCount} exceed the ${options.maxWarnings} warning budget.`\n )\n }\n\n const slowestRule = budgetRun.slowestRules.at(0)\n\n if (options.maxRuleTimeMs !== undefined && slowestRule && slowestRule.timeMs > options.maxRuleTimeMs) {\n violations.push(\n `${slowestRule.rule} took ${round(slowestRule.timeMs)}ms, exceeding the ${options.maxRuleTimeMs}ms rule budget.`\n )\n }\n\n const payload = {\n budget: {\n limits: {\n maxDurationMs: options.maxDurationMs ?? null,\n maxRuleTimeMs: options.maxRuleTimeMs ?? null,\n maxWarnings: options.maxWarnings ?? null\n },\n passed: violations.length === 0,\n violations\n },\n recommendation,\n runs: runs.map(run => ({\n ...run,\n durationMs: round(run.durationMs),\n parseMs: round(run.parseMs),\n ruleMs: round(run.ruleMs),\n slowestRules: run.slowestRules.map(item => ({ ...item, timeMs: round(item.timeMs) }))\n }))\n }\n\n if (options.json) {\n console.log(JSON.stringify(payload, null, 2))\n\n if (!payload.budget.passed) process.exitCode = 1\n\n return\n }\n\n console.log('ESLint performance profile:')\n\n for (const run of payload.runs) {\n console.log(\n `- concurrency=${run.concurrency}: ${run.durationMs}ms, ${run.fileCount} files, ` +\n `${run.errorCount} errors, ${run.warningCount} warnings`\n )\n }\n\n if (payload.recommendation) console.log(`- Recommended concurrency: ${payload.recommendation}`)\n\n if (!payload.budget.passed) {\n console.log('Budget violations:')\n\n for (const violation of payload.budget.violations) console.log(`- ${violation}`)\n\n process.exitCode = 1\n }\n\n const slowestRules = payload.runs[0]?.slowestRules ?? []\n\n if (slowestRules.length > 0) {\n console.log('Slowest rules:')\n\n for (const item of slowestRules.slice(0, 10)) {\n console.log(`- ${item.rule}: ${item.timeMs}ms`)\n }\n }\n}\n\nconst walkSourceFiles = (cwd: string, directory = cwd, output: string[] = []): string[] => {\n if (output.length >= 5000) return output\n\n for (const entry of readdirSync(directory, { withFileTypes: true })) {\n if (output.length >= 5000) break\n\n if (entry.isDirectory()) {\n if (!IGNORED_DIRECTORIES.has(entry.name)) {\n walkSourceFiles(cwd, join(directory, entry.name), output)\n }\n\n continue\n }\n\n if (SOURCE_EXTENSIONS.has(extname(entry.name))) {\n output.push(relative(cwd, join(directory, entry.name)))\n }\n }\n\n return output\n}\n\nconst classifyRepresentativeFile = (filePath: string): string => {\n if (/eslint\\.config\\.[cm]?[jt]s$/.test(filePath)) return 'config'\n\n if (/\\.(test|spec)\\.[cm]?[jt]sx?$/.test(filePath)) return 'test'\n\n return extname(filePath)\n}\n\nexport const findRepresentativeFiles = (cwd: string): string[] => {\n const selected = new Map<string, string>()\n\n for (const filePath of walkSourceFiles(cwd)) {\n const category = classifyRepresentativeFile(filePath)\n\n if (!selected.has(category)) selected.set(category, filePath)\n }\n\n return [...selected.values()].sort()\n}\n\nconst findUnignoredRepresentativeFiles = async (\n cwd: string,\n eslint: ProjectEslint\n): Promise<string[]> => {\n const selected = new Map<string, string>()\n\n for (const filePath of walkSourceFiles(cwd)) {\n const category = classifyRepresentativeFile(filePath)\n\n if (selected.has(category)) continue\n\n const config = eslint.isPathIgnored ?\n undefined :\n await eslint.calculateConfigForFile(filePath)\n\n const ignored = eslint.isPathIgnored ?\n await eslint.isPathIgnored(filePath) :\n config === null || config === undefined\n\n if (!ignored) selected.set(category, filePath)\n }\n\n return [...selected.values()].sort()\n}\n\nconst loadProjectEslint = (cwd: string): ProjectEslint => {\n const projectRequire = resolveProjectRequire(cwd)\n const eslintModule = projectRequire('eslint') as { ESLint?: ProjectEslintConstructor }\n\n if (!eslintModule.ESLint) throw new Error('The installed eslint package does not expose the ESLint API.')\n\n return new eslintModule.ESLint({ cwd })\n}\n\nconst normalizeSerializableObject = (value: unknown): Record<string, unknown> => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return {}\n\n return Object.fromEntries(\n Object.entries(value)\n .filter(([, entry]) => {\n try {\n JSON.stringify(entry)\n\n return true\n } catch {\n return false\n }\n })\n .sort(([a], [b]) => a.localeCompare(b))\n )\n}\n\nconst getObjectKeys = (value: unknown): string[] => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return []\n\n return Object.keys(value).sort()\n}\n\nconst normalizeConfig = (config: unknown): EslintSnapshotFile => {\n const resolved = config && typeof config === 'object' ?\n config as {\n languageOptions?: {\n ecmaVersion?: unknown\n globals?: unknown\n sourceType?: unknown\n }\n plugins?: unknown\n rules?: unknown\n } :\n {}\n\n return {\n globals: normalizeSerializableObject(resolved.languageOptions?.globals),\n languageOptions: {\n ecmaVersion: resolved.languageOptions?.ecmaVersion,\n sourceType: resolved.languageOptions?.sourceType\n },\n plugins: getObjectKeys(resolved.plugins),\n rules: normalizeSerializableObject(resolved.rules)\n }\n}\n\nexport const createConfigSnapshot = async (\n cwd: string,\n files?: string[],\n eslint: ProjectEslint = loadProjectEslint(cwd)\n): Promise<EslintSnapshot> => {\n const representativeFiles = files?.length ?\n files :\n await findUnignoredRepresentativeFiles(cwd, eslint)\n\n if (representativeFiles.length === 0) {\n throw new Error('No representative source files were found. Pass one or more --file paths.')\n }\n\n const entries = await Promise.all(representativeFiles.map(async filePath => {\n const config = await eslint.calculateConfigForFile(filePath)\n\n return [filePath, normalizeConfig(config)] as const\n }))\n\n return {\n files: Object.fromEntries(entries),\n version: 1\n }\n}\n\nconst sameValue = (left: unknown, right: unknown): boolean => JSON.stringify(left) === JSON.stringify(right)\n\nconst getSnapshotValues = (snapshot?: EslintSnapshotFile): Record<string, unknown> => {\n if (!snapshot) return {}\n\n return {\n ...snapshot.rules,\n ...Object.fromEntries(\n Object.entries(snapshot.globals).map(([name, value]) => [`globals:${name}`, value])\n ),\n ...Object.fromEntries(\n Object.entries(snapshot.languageOptions)\n .filter(([, value]) => value !== undefined)\n .map(([name, value]) => [`languageOptions:${name}`, value])\n ),\n ...Object.fromEntries(snapshot.plugins.map(name => [`plugins:${name}`, true]))\n }\n}\n\nexport const diffConfigSnapshots = (\n previous: EslintSnapshot,\n current: EslintSnapshot\n): SnapshotDiff[] => {\n const files = new Set([...Object.keys(previous.files), ...Object.keys(current.files)])\n const diffs: SnapshotDiff[] = []\n\n for (const file of [...files].sort()) {\n const before = getSnapshotValues(previous.files[file])\n const after = getSnapshotValues(current.files[file])\n const added = Object.keys(after).filter(rule => !(rule in before)).sort()\n const removed = Object.keys(before).filter(rule => !(rule in after)).sort()\n\n const changed = Object.keys(after)\n .filter(rule => rule in before && !sameValue(before[rule], after[rule]))\n .sort()\n .map(rule => ({ after: after[rule], before: before[rule], rule }))\n\n if (added.length > 0 || removed.length > 0 || changed.length > 0) {\n diffs.push({ added, changed, file, removed })\n }\n }\n\n return diffs\n}\n\nconst outputSnapshotDiff = (diffs: SnapshotDiff[]): void => {\n if (diffs.length === 0) {\n console.log('✅ Effective ESLint configuration matches the saved snapshot.')\n\n return\n }\n\n console.log(`ESLint configuration changed for ${diffs.length} representative file(s):`)\n\n for (const diff of diffs) {\n console.log(`- ${diff.file}`)\n\n if (diff.added.length > 0) console.log(` Added: ${diff.added.join(', ')}`)\n\n if (diff.removed.length > 0) console.log(` Removed: ${diff.removed.join(', ')}`)\n\n for (const change of diff.changed) {\n console.log(` Changed ${change.rule}: ${JSON.stringify(change.before)} → ${JSON.stringify(change.after)}`)\n }\n }\n}\n\nexport const handleSnapshot = async (\n cwd: string = process.cwd(),\n options: SnapshotOptions = {},\n eslint?: ProjectEslint\n): Promise<void> => {\n const snapshotPath = resolve(cwd, options.snapshotPath ?? SNAPSHOT_FILENAME)\n const previous = readJson(snapshotPath) as EslintSnapshot | null\n\n if (options.check) {\n if (!previous) {\n if (options.json) {\n console.log(JSON.stringify({ exists: false, snapshotPath }, null, 2))\n } else {\n console.error(`❌ Snapshot is missing: ${relative(cwd, snapshotPath)}`)\n }\n\n process.exitCode = 1\n\n return\n }\n\n const files = options.files?.length ? options.files : Object.keys(previous.files)\n const current = await createConfigSnapshot(cwd, files, eslint)\n const diffs = diffConfigSnapshots(previous, current)\n\n if (options.json) console.log(JSON.stringify({ diffs, snapshotPath }, null, 2))\n else outputSnapshotDiff(diffs)\n\n if (diffs.length > 0) process.exitCode = 1\n\n return\n }\n\n const current = await createConfigSnapshot(cwd, options.files, eslint)\n\n writeFileSync(snapshotPath, `${JSON.stringify(current, null, 2)}\\n`)\n\n if (options.json) {\n console.log(JSON.stringify({\n files: Object.keys(current.files),\n snapshotPath\n }, null, 2))\n } else {\n console.log(`✅ Saved effective ESLint configuration to ${relative(cwd, snapshotPath)}.`)\n }\n}\n\nexport const handleSnapshotDiff = async (\n cwd: string = process.cwd(),\n options: SnapshotOptions = {},\n eslint?: ProjectEslint\n): Promise<void> => {\n const snapshotPath = resolve(cwd, options.snapshotPath ?? SNAPSHOT_FILENAME)\n const previous = readJson(snapshotPath) as EslintSnapshot | null\n\n if (!previous) throw new Error(`Snapshot is missing: ${relative(cwd, snapshotPath)}. Run basic-eslint snapshot first.`)\n\n const files = options.files?.length ? options.files : Object.keys(previous.files)\n const current = await createConfigSnapshot(cwd, files, eslint)\n const diffs = diffConfigSnapshots(previous, current)\n\n if (options.json) console.log(JSON.stringify({ diffs, snapshotPath }, null, 2))\n else outputSnapshotDiff(diffs)\n\n if (diffs.length > 0) process.exitCode = 1\n}\n\nexport const isDirectory = (path: string): boolean => {\n try {\n return statSync(path).isDirectory()\n } catch {\n return false\n }\n}\n"],"mappings":"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","names":["current"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli-workflows.ts"],"sourcesContent":["/* eslint-disable complexity -- workflow handlers intentionally cover CLI output and compatibility branches */\n/* eslint-disable no-console -- CLI handlers own user-facing terminal output */\nimport { spawnSync } from 'node:child_process'\nimport { existsSync, readdirSync, readFileSync, statSync, writeFileSync } from 'node:fs'\nimport { createRequire } from 'node:module'\nimport { basename, dirname, extname, join, relative, resolve } from 'node:path'\n\nimport type * as TypeScript from 'typescript'\nimport type { CompilerOptions, Diagnostic, Program } from 'typescript'\n\ntype TypeScriptApi = typeof TypeScript\n\nexport interface CommandResult {\n status: number\n stderr: string\n stdout: string\n}\n\nexport type CommandRunner = (\n executable: string,\n args: string[],\n cwd: string\n) => CommandResult\n\nexport interface BaselineOptions {\n json?: boolean\n preset?: string\n prune?: boolean\n}\n\nexport interface ProfileOptions {\n concurrency?: string\n files?: string[]\n json?: boolean\n maxDurationMs?: number\n maxRuleTimeMs?: number\n maxWarnings?: number\n}\n\nexport interface SnapshotOptions {\n check?: boolean\n files?: string[]\n json?: boolean\n rulesOnly?: boolean\n snapshotPath?: string\n}\n\nexport interface ConfigTypesOptions {\n files?: string[]\n json?: boolean\n}\n\ninterface ConfigTypeFileResult {\n declarations: string[]\n file: string\n issues: string[]\n portable: boolean\n tsconfig: null | string\n}\n\ninterface ConfigTypesReport {\n files: ConfigTypeFileResult[]\n portable: boolean\n typescriptVersion: string\n}\n\nexport interface SnapshotDiff {\n added: string[]\n changed: { after: unknown, before: unknown, rule: string }[]\n file: string\n removed: string[]\n}\n\ninterface EslintSnapshotFile {\n globals: Record<string, unknown>\n languageOptions: {\n ecmaVersion?: unknown\n sourceType?: unknown\n }\n plugins: string[]\n rules: Record<string, unknown>\n}\n\ninterface EslintSnapshot {\n files: Record<string, EslintSnapshotFile>\n scope?: 'rules'\n version: 1 | 2\n}\n\ninterface EslintStats {\n times?: {\n passes?: {\n fix?: { total?: number }\n parse?: { total?: number }\n rules?: Record<string, { total?: number }>\n total?: number\n }[]\n }\n}\n\ninterface EslintResult {\n errorCount?: number\n filePath?: string\n fatalErrorCount?: number\n stats?: EslintStats\n warningCount?: number\n}\n\ninterface ProfileRun {\n concurrency: string\n durationMs: number\n errorCount: number\n fatalErrorCount: number\n fileCount: number\n parseMs: number\n ruleMs: number\n slowestRules: { rule: string, timeMs: number }[]\n status: number\n warningCount: number\n}\n\ninterface ProjectEslint {\n calculateConfigForFile: (filePath: string) => Promise<unknown>\n isPathIgnored?: (filePath: string) => Promise<boolean>\n}\n\ntype ProjectEslintConstructor = new(options: { cwd: string }) => ProjectEslint\n\nconst SNAPSHOT_FILENAME = '.eslint-config-snapshot.json'\n\nconst ESLINT_CONFIG_FILENAMES = [\n 'eslint.config.js',\n 'eslint.config.mjs',\n 'eslint.config.cjs',\n 'eslint.config.ts',\n 'eslint.config.mts',\n 'eslint.config.cts'\n]\n\nconst NON_PORTABLE_DECLARATION_PATTERNS = [\n { label: 'a pnpm-internal installation path', pattern: /(?:^|[\\\\/])\\.pnpm(?:[\\\\/]|$)/m },\n { label: 'the transitive typescript-eslint package', pattern: /[\"']typescript-eslint[\"']/m }\n]\n\nconst SOURCE_EXTENSIONS = new Set([\n '.astro',\n '.cjs',\n '.css',\n '.cts',\n '.gql',\n '.graphql',\n '.html',\n '.js',\n '.json',\n '.json5',\n '.jsonc',\n '.jsx',\n '.md',\n '.mdx',\n '.mjs',\n '.mts',\n '.svelte',\n '.toml',\n '.ts',\n '.tsx',\n '.vue',\n '.yaml',\n '.yml'\n])\n\nconst IGNORED_DIRECTORIES = new Set([\n '.git',\n '.next',\n '.nuxt',\n '.output',\n '.turbo',\n 'build',\n 'coverage',\n 'dist',\n 'node_modules'\n])\n\nexport const defaultCommandRunner: CommandRunner = (executable, args, cwd) => {\n const result = spawnSync(executable, args, {\n cwd,\n encoding: 'utf8',\n env: process.env,\n maxBuffer: 50 * 1024 * 1024\n })\n\n return {\n status: result.status ?? 1,\n stderr: result.stderr,\n stdout: result.stdout\n }\n}\n\nconst resolveProjectRequire = (cwd: string) => createRequire(join(cwd, 'package.json'))\n\nconst formatTypeScriptDiagnostic = (\n typescript: TypeScriptApi,\n diagnostic: Diagnostic,\n cwd: string\n): string => {\n const message = typescript.flattenDiagnosticMessageText(diagnostic.messageText, '\\n')\n\n if (!diagnostic.file || diagnostic.start === undefined) return `TS${diagnostic.code}: ${message}`\n\n const position = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start)\n\n return `${relative(cwd, diagnostic.file.fileName)}:${position.line + 1}:${position.character + 1} ` +\n `TS${diagnostic.code}: ${message}`\n}\n\nconst getConfigAmbientOptions = (\n configPath: string\n): Pick<CompilerOptions, 'typeRoots' | 'types'> => {\n const content = readFileSync(configPath, 'utf8')\n\n const usesNodeGlobals = (\n /\\b(?:Buffer|NodeJS|process|require|module|__dirname|__filename)\\b/.test(content) ||\n /\\bimport\\.meta\\.(?:dirname|filename)\\b/.test(content)\n )\n\n if (!usesNodeGlobals) return { types: [] }\n\n try {\n const nodeManifest = createRequire(configPath).resolve('@types/node/package.json')\n\n return {\n typeRoots: [dirname(dirname(nodeManifest))],\n types: ['node']\n }\n } catch {\n return { types: [] }\n }\n}\n\nconst getConfigCompilerOptions = (\n typescript: TypeScriptApi,\n configPath: string\n): { diagnostics: Diagnostic[], options: CompilerOptions, tsconfig: null | string } => {\n const tsconfig = typescript.findConfigFile(\n dirname(configPath),\n fileName => typescript.sys.fileExists(fileName)\n )\n\n const diagnostics: Diagnostic[] = []\n let options: CompilerOptions = {}\n\n if (tsconfig) {\n const readResult = typescript.readConfigFile(\n tsconfig,\n fileName => typescript.sys.readFile(fileName)\n )\n\n if (readResult.error) {\n diagnostics.push(readResult.error)\n } else {\n const parsed = typescript.parseJsonConfigFileContent(\n readResult.config,\n typescript.sys,\n dirname(tsconfig)\n )\n\n diagnostics.push(...parsed.errors.filter(diagnostic => ![18002, 18003].includes(diagnostic.code)))\n\n options = parsed.options\n }\n }\n\n return {\n diagnostics,\n options: {\n ...options,\n ...getConfigAmbientOptions(configPath),\n allowJs: true,\n checkJs: false,\n composite: false,\n declaration: true,\n declarationDir: undefined,\n emitDeclarationOnly: true,\n incremental: false,\n ...(Number(typescript.versionMajorMinor.split('.')[0]) >= 6 ? { ignoreDeprecations: '6.0' } : {}),\n module: options.module ?? typescript.ModuleKind.NodeNext,\n moduleResolution: options.moduleResolution ?? typescript.ModuleResolutionKind.NodeNext,\n noEmit: false,\n noEmitOnError: false,\n outDir: undefined,\n rootDir: undefined,\n skipLibCheck: true,\n target: options.target ?? typescript.ScriptTarget.ES2022,\n tsBuildInfoFile: undefined\n },\n tsconfig: tsconfig ?? null\n }\n}\n\nconst emitConfigDeclarations = (\n typescript: TypeScriptApi,\n cwd: string,\n configPath: string\n): ConfigTypeFileResult => {\n const setup = getConfigCompilerOptions(typescript, configPath)\n const program: Program = typescript.createProgram([configPath], setup.options)\n const outputs = new Map<string, string>()\n\n const emitResult = program.emit(\n undefined,\n (fileName, content) => outputs.set(fileName, content),\n undefined,\n true\n )\n\n const diagnostics = [\n ...setup.diagnostics,\n ...typescript.getPreEmitDiagnostics(program),\n ...emitResult.diagnostics\n ].filter(diagnostic => diagnostic.category === typescript.DiagnosticCategory.Error)\n\n const declarationStem = `${basename(configPath, extname(configPath))}.d.`\n\n const declarations = [...outputs.entries()]\n .filter(([fileName]) => (\n basename(fileName).startsWith(declarationStem) && /\\.d\\.(?:cts|mts|ts)$/.test(fileName)\n ))\n\n const issues = [...new Set(\n diagnostics.map(diagnostic => formatTypeScriptDiagnostic(typescript, diagnostic, cwd))\n )]\n\n if (declarations.length === 0) issues.push('TypeScript did not emit a declaration for this config.')\n\n for (const [fileName, content] of declarations) {\n for (const { label, pattern } of NON_PORTABLE_DECLARATION_PATTERNS) {\n if (pattern.test(content)) issues.push(`${relative(cwd, fileName)} references ${label}.`)\n }\n }\n\n return {\n declarations: declarations.map(([fileName]) => relative(cwd, fileName)).sort(),\n file: relative(cwd, configPath),\n issues,\n portable: issues.length === 0,\n tsconfig: setup.tsconfig ? relative(cwd, setup.tsconfig) : null\n }\n}\n\nexport const createConfigTypesReport = (\n cwd: string = process.cwd(),\n options: ConfigTypesOptions = {}\n): ConfigTypesReport => {\n const projectRequire = resolveProjectRequire(cwd)\n let typescript: TypeScriptApi\n\n try {\n typescript = projectRequire('typescript') as TypeScriptApi\n } catch {\n throw new Error('TypeScript is required for config-types. Install it in the consumer project first.')\n }\n\n const configPaths = (options.files && options.files.length > 0 ?\n options.files.map(file => resolve(cwd, file)) :\n ESLINT_CONFIG_FILENAMES.map(file => join(cwd, file)).filter(file => existsSync(file)))\n\n if (configPaths.length === 0) {\n throw new Error('No eslint.config.* file was found. Pass --file for a project-scoped config.')\n }\n\n for (const configPath of configPaths) {\n if (!existsSync(configPath)) throw new Error(`Config file does not exist: ${relative(cwd, configPath)}`)\n }\n\n const files = configPaths.map(configPath => emitConfigDeclarations(typescript, cwd, configPath))\n\n return {\n files,\n portable: files.every(file => file.portable),\n typescriptVersion: typescript.version\n }\n}\n\nexport const handleConfigTypes = (\n cwd: string = process.cwd(),\n options: ConfigTypesOptions = {}\n): void => {\n const report = createConfigTypesReport(cwd, options)\n\n if (options.json) {\n console.log(JSON.stringify(report, null, 2))\n } else {\n console.log([\n `ESLint config declaration portability: ${report.portable ? 'passed' : 'failed'}`,\n `- TypeScript: ${report.typescriptVersion}`,\n ...report.files.flatMap(file => [\n `- ${file.file}: ${file.portable ? 'portable' : 'not portable'} ` +\n `(tsconfig: ${file.tsconfig ?? 'compiler defaults'})`,\n ...file.issues.map(issue => ` - ${issue}`)\n ])\n ].join('\\n'))\n }\n\n if (!report.portable) process.exitCode = 1\n}\n\nconst readJson = (filePath: string): unknown => {\n if (!existsSync(filePath)) return null\n\n try {\n return JSON.parse(readFileSync(filePath, 'utf8')) as unknown\n } catch {\n return null\n }\n}\n\nconst resolveEslintCli = (cwd: string): string => {\n const projectRequire = resolveProjectRequire(cwd)\n const packagePath = projectRequire.resolve('eslint/package.json')\n const metadata = readJson(packagePath) as null | { bin?: string | Record<string, string> }\n const bin = typeof metadata?.bin === 'string' ? metadata.bin : metadata?.bin?.eslint\n\n if (!bin) throw new Error('The project ESLint CLI could not be resolved. Install eslint before running this command.')\n\n return resolve(dirname(packagePath), bin)\n}\n\nconst runEslint = (\n cwd: string,\n args: string[],\n runner: CommandRunner\n): CommandResult => runner(process.execPath, [resolveEslintCli(cwd), ...args], cwd)\n\nconst outputCommandFailure = (label: string, result: CommandResult): never => {\n const details = result.stderr.trim() || result.stdout.trim() || `exit code ${result.status}`\n\n throw new Error(`${label} failed: ${details}`)\n}\n\nconst createBackupPath = (filePath: string, suffix: string): string => {\n const preferred = `${filePath}.${suffix}.bak`\n\n if (!existsSync(preferred)) return preferred\n\n let index = 2\n\n while (existsSync(`${preferred}.${index}`)) index++\n\n return `${preferred}.${index}`\n}\n\nconst updateConfigStrictPreset = (cwd: string, preset: string): null | string => {\n if (!['ci', 'pedantic'].includes(preset)) {\n throw new Error(`Unsupported baseline preset \"${preset}\". Use \"ci\" or \"pedantic\".`)\n }\n\n const configPath = [\n 'eslint.config.js',\n 'eslint.config.mjs',\n 'eslint.config.cjs',\n 'eslint.config.ts',\n 'eslint.config.mts',\n 'eslint.config.cts'\n ].map(name => join(cwd, name)).find(path => existsSync(path))\n\n if (!configPath) throw new Error('No eslint.config.* file was found. Run basic-eslint init first.')\n\n const content = readFileSync(configPath, 'utf8')\n\n if (new RegExp(`strict\\\\s*:\\\\s*['\"]${preset}['\"]`).test(content)) return null\n\n const zeroArgumentPattern = /\\bdefineConfig\\(\\s*\\)/\n\n if (!zeroArgumentPattern.test(content)) {\n throw new Error(\n `Cannot safely add strict: \"${preset}\" to a customized config. ` +\n 'Add it manually, then run basic-eslint baseline without --preset.'\n )\n }\n\n const backupPath = createBackupPath(configPath, 'baseline')\n\n writeFileSync(backupPath, content)\n\n writeFileSync(configPath, content.replace(zeroArgumentPattern, `defineConfig({ strict: '${preset}' })`))\n\n return basename(backupPath)\n}\n\nexport const handleBaseline = (\n cwd: string = process.cwd(),\n options: BaselineOptions = {},\n runner: CommandRunner = defaultCommandRunner\n): void => {\n const backup = options.preset ? updateConfigStrictPreset(cwd, options.preset) : null\n\n const args = options.prune ?\n ['.', '--prune-suppressions'] :\n ['.', '--fix', '--suppress-all']\n\n const result = runEslint(cwd, args, runner)\n\n if (result.status !== 0) outputCommandFailure('ESLint baseline', result)\n\n const payload = {\n action: options.prune ? 'pruned' : 'created',\n backup,\n preset: options.preset ?? null,\n suppressionsFile: join(cwd, 'eslint-suppressions.json')\n }\n\n if (options.json) {\n console.log(JSON.stringify(payload, null, 2))\n\n return\n }\n\n console.log(options.prune ?\n '✅ Pruned unused ESLint suppressions.' :\n '✅ Created or refreshed eslint-suppressions.json for existing violations.')\n\n if (backup) console.log(`📦 Backed up the previous config to ${backup}.`)\n}\n\nconst getStatsPasses = (result: EslintResult) => result.stats?.times?.passes ?? []\n\nconst summarizeProfileResults = (\n concurrency: string,\n results: EslintResult[],\n durationMs: number,\n status: number\n): ProfileRun => {\n const ruleTimes = new Map<string, number>()\n let parseMs = 0\n let ruleMs = 0\n\n for (const result of results) {\n for (const pass of getStatsPasses(result)) {\n parseMs += pass.parse?.total ?? 0\n\n for (const [rule, timing] of Object.entries(pass.rules ?? {})) {\n const time = timing.total ?? 0\n\n ruleMs += time\n\n ruleTimes.set(rule, (ruleTimes.get(rule) ?? 0) + time)\n }\n }\n }\n\n return {\n concurrency,\n durationMs,\n errorCount: results.reduce((total, result) => total + (result.errorCount ?? 0), 0),\n fatalErrorCount: results.reduce((total, result) => total + (result.fatalErrorCount ?? 0), 0),\n fileCount: results.length,\n parseMs,\n ruleMs,\n slowestRules: [...ruleTimes.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, 15)\n .map(([rule, timeMs]) => ({ rule, timeMs })),\n status,\n warningCount: results.reduce((total, result) => total + (result.warningCount ?? 0), 0)\n }\n}\n\nconst runProfile = (\n cwd: string,\n files: string[],\n concurrency: string,\n runner: CommandRunner\n): ProfileRun => {\n const startedAt = performance.now()\n\n const result = runEslint(\n cwd,\n [...files, '--stats', '--format', 'json', '--concurrency', concurrency],\n runner\n )\n\n const durationMs = performance.now() - startedAt\n let parsed: EslintResult[] = []\n\n try {\n parsed = JSON.parse(result.stdout) as EslintResult[]\n } catch {\n outputCommandFailure('ESLint profile', result)\n }\n\n return summarizeProfileResults(concurrency, parsed, durationMs, result.status)\n}\n\nconst round = (value: number): number => Math.round(value * 100) / 100\n\nexport const handleProfile = (\n cwd: string = process.cwd(),\n options: ProfileOptions = {},\n runner: CommandRunner = defaultCommandRunner\n): void => {\n for (const [name, value] of [\n ['max-duration', options.maxDurationMs],\n ['max-rule-time', options.maxRuleTimeMs],\n ['max-warnings', options.maxWarnings]\n ] as const) {\n if (value !== undefined && (!Number.isFinite(value) || value < 0)) {\n throw new Error(`--${name} must be a non-negative number.`)\n }\n }\n\n const files = options.files?.length ? options.files : ['.']\n const concurrencyModes = options.concurrency ? [options.concurrency] : ['off', 'auto']\n const runs = concurrencyModes.map(concurrency => runProfile(cwd, files, concurrency, runner))\n const successfulRuns = runs.filter(run => run.fatalErrorCount === 0 && run.status < 2)\n\n const recommendation = successfulRuns.length > 0 ?\n successfulRuns.toSorted((a, b) => a.durationMs - b.durationMs)[0].concurrency :\n null\n\n const budgetRun = successfulRuns.toSorted((a, b) => a.durationMs - b.durationMs)[0] ?? runs[0]\n\n const violations: string[] = successfulRuns.length === 0 ?\n ['ESLint profiling did not produce a successful run.'] :\n []\n\n if (options.maxDurationMs !== undefined && budgetRun.durationMs > options.maxDurationMs) {\n violations.push(\n `Duration ${round(budgetRun.durationMs)}ms exceeds the ${options.maxDurationMs}ms budget.`\n )\n }\n\n if (options.maxWarnings !== undefined && budgetRun.warningCount > options.maxWarnings) {\n violations.push(\n `Warnings ${budgetRun.warningCount} exceed the ${options.maxWarnings} warning budget.`\n )\n }\n\n const slowestRule = budgetRun.slowestRules.at(0)\n\n if (options.maxRuleTimeMs !== undefined && slowestRule && slowestRule.timeMs > options.maxRuleTimeMs) {\n violations.push(\n `${slowestRule.rule} took ${round(slowestRule.timeMs)}ms, exceeding the ${options.maxRuleTimeMs}ms rule budget.`\n )\n }\n\n const payload = {\n budget: {\n limits: {\n maxDurationMs: options.maxDurationMs ?? null,\n maxRuleTimeMs: options.maxRuleTimeMs ?? null,\n maxWarnings: options.maxWarnings ?? null\n },\n passed: violations.length === 0,\n violations\n },\n recommendation,\n runs: runs.map(run => ({\n ...run,\n durationMs: round(run.durationMs),\n parseMs: round(run.parseMs),\n ruleMs: round(run.ruleMs),\n slowestRules: run.slowestRules.map(item => ({ ...item, timeMs: round(item.timeMs) }))\n }))\n }\n\n if (options.json) {\n console.log(JSON.stringify(payload, null, 2))\n\n if (!payload.budget.passed) process.exitCode = 1\n\n return\n }\n\n console.log('ESLint performance profile:')\n\n for (const run of payload.runs) {\n console.log(\n `- concurrency=${run.concurrency}: ${run.durationMs}ms, ${run.fileCount} files, ` +\n `${run.errorCount} errors, ${run.warningCount} warnings`\n )\n }\n\n if (payload.recommendation) console.log(`- Recommended concurrency: ${payload.recommendation}`)\n\n if (!payload.budget.passed) {\n console.log('Budget violations:')\n\n for (const violation of payload.budget.violations) console.log(`- ${violation}`)\n\n process.exitCode = 1\n }\n\n const slowestRules = payload.runs[0]?.slowestRules ?? []\n\n if (slowestRules.length > 0) {\n console.log('Slowest rules:')\n\n for (const item of slowestRules.slice(0, 10)) {\n console.log(`- ${item.rule}: ${item.timeMs}ms`)\n }\n }\n}\n\nconst walkSourceFiles = (cwd: string, directory = cwd, output: string[] = []): string[] => {\n if (output.length >= 5000) return output\n\n for (const entry of readdirSync(directory, { withFileTypes: true })) {\n if (output.length >= 5000) break\n\n if (entry.isDirectory()) {\n if (!IGNORED_DIRECTORIES.has(entry.name)) {\n walkSourceFiles(cwd, join(directory, entry.name), output)\n }\n\n continue\n }\n\n if (SOURCE_EXTENSIONS.has(extname(entry.name))) {\n output.push(relative(cwd, join(directory, entry.name)))\n }\n }\n\n return output\n}\n\nconst classifyRepresentativeFile = (filePath: string): string => {\n if (/eslint\\.config\\.[cm]?[jt]s$/.test(filePath)) return 'config'\n\n if (/\\.(test|spec)\\.[cm]?[jt]sx?$/.test(filePath)) return 'test'\n\n return extname(filePath)\n}\n\nexport const findRepresentativeFiles = (cwd: string): string[] => {\n const selected = new Map<string, string>()\n\n for (const filePath of walkSourceFiles(cwd)) {\n const category = classifyRepresentativeFile(filePath)\n\n if (!selected.has(category)) selected.set(category, filePath)\n }\n\n return [...selected.values()].sort()\n}\n\nconst findUnignoredRepresentativeFiles = async (\n cwd: string,\n eslint: ProjectEslint\n): Promise<string[]> => {\n const selected = new Map<string, string>()\n\n for (const filePath of walkSourceFiles(cwd)) {\n const category = classifyRepresentativeFile(filePath)\n\n if (selected.has(category)) continue\n\n const config = eslint.isPathIgnored ?\n undefined :\n await eslint.calculateConfigForFile(filePath)\n\n const ignored = eslint.isPathIgnored ?\n await eslint.isPathIgnored(filePath) :\n config === null || config === undefined\n\n if (!ignored) selected.set(category, filePath)\n }\n\n return [...selected.values()].sort()\n}\n\nconst loadProjectEslint = (cwd: string): ProjectEslint => {\n const projectRequire = resolveProjectRequire(cwd)\n const eslintModule = projectRequire('eslint') as { ESLint?: ProjectEslintConstructor }\n\n if (!eslintModule.ESLint) throw new Error('The installed eslint package does not expose the ESLint API.')\n\n return new eslintModule.ESLint({ cwd })\n}\n\nconst normalizeSerializableObject = (value: unknown): Record<string, unknown> => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return {}\n\n return Object.fromEntries(\n Object.entries(value)\n .filter(([, entry]) => {\n try {\n JSON.stringify(entry)\n\n return true\n } catch {\n return false\n }\n })\n .sort(([a], [b]) => a.localeCompare(b))\n )\n}\n\nconst getObjectKeys = (value: unknown): string[] => {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return []\n\n return Object.keys(value).sort()\n}\n\nconst normalizeConfig = (\n config: unknown,\n scope: 'all' | 'rules'\n): EslintSnapshotFile => {\n const resolved = config && typeof config === 'object' ?\n config as {\n languageOptions?: {\n ecmaVersion?: unknown\n globals?: unknown\n sourceType?: unknown\n }\n plugins?: unknown\n rules?: unknown\n } :\n {}\n\n return {\n globals: scope === 'rules' ? {} : normalizeSerializableObject(resolved.languageOptions?.globals),\n languageOptions: scope === 'rules' ?\n {} :\n {\n ecmaVersion: resolved.languageOptions?.ecmaVersion,\n sourceType: resolved.languageOptions?.sourceType\n },\n plugins: scope === 'rules' ? [] : getObjectKeys(resolved.plugins),\n rules: normalizeSerializableObject(resolved.rules)\n }\n}\n\nexport const createConfigSnapshot = async (\n cwd: string,\n files?: string[],\n eslint: ProjectEslint = loadProjectEslint(cwd),\n scope: 'all' | 'rules' = 'all'\n): Promise<EslintSnapshot> => {\n const representativeFiles = files?.length ?\n files :\n await findUnignoredRepresentativeFiles(cwd, eslint)\n\n if (representativeFiles.length === 0) {\n throw new Error('No representative source files were found. Pass one or more --file paths.')\n }\n\n const entries = await Promise.all(representativeFiles.map(async filePath => {\n const config = await eslint.calculateConfigForFile(filePath)\n\n return [filePath, normalizeConfig(config, scope)] as const\n }))\n\n return {\n files: Object.fromEntries(entries),\n ...(scope === 'rules' ? { scope } : {}),\n version: scope === 'rules' ? 2 : 1\n }\n}\n\nconst sameValue = (left: unknown, right: unknown): boolean => JSON.stringify(left) === JSON.stringify(right)\n\nconst getSnapshotValues = (snapshot?: EslintSnapshotFile): Record<string, unknown> => {\n if (!snapshot) return {}\n\n return {\n ...snapshot.rules,\n ...Object.fromEntries(\n Object.entries(snapshot.globals).map(([name, value]) => [`globals:${name}`, value])\n ),\n ...Object.fromEntries(\n Object.entries(snapshot.languageOptions)\n .filter(([, value]) => value !== undefined)\n .map(([name, value]) => [`languageOptions:${name}`, value])\n ),\n ...Object.fromEntries(snapshot.plugins.map(name => [`plugins:${name}`, true]))\n }\n}\n\nexport const diffConfigSnapshots = (\n previous: EslintSnapshot,\n current: EslintSnapshot\n): SnapshotDiff[] => {\n const files = new Set([...Object.keys(previous.files), ...Object.keys(current.files)])\n const diffs: SnapshotDiff[] = []\n\n for (const file of [...files].sort()) {\n const before = getSnapshotValues(previous.files[file])\n const after = getSnapshotValues(current.files[file])\n const added = Object.keys(after).filter(rule => !(rule in before)).sort()\n const removed = Object.keys(before).filter(rule => !(rule in after)).sort()\n\n const changed = Object.keys(after)\n .filter(rule => rule in before && !sameValue(before[rule], after[rule]))\n .sort()\n .map(rule => ({ after: after[rule], before: before[rule], rule }))\n\n if (added.length > 0 || removed.length > 0 || changed.length > 0) {\n diffs.push({ added, changed, file, removed })\n }\n }\n\n return diffs\n}\n\nconst outputSnapshotDiff = (diffs: SnapshotDiff[]): void => {\n if (diffs.length === 0) {\n console.log('✅ Effective ESLint configuration matches the saved snapshot.')\n\n return\n }\n\n console.log(`ESLint configuration changed for ${diffs.length} representative file(s):`)\n\n for (const diff of diffs) {\n console.log(`- ${diff.file}`)\n\n if (diff.added.length > 0) console.log(` Added: ${diff.added.join(', ')}`)\n\n if (diff.removed.length > 0) console.log(` Removed: ${diff.removed.join(', ')}`)\n\n for (const change of diff.changed) {\n console.log(` Changed ${change.rule}: ${JSON.stringify(change.before)} → ${JSON.stringify(change.after)}`)\n }\n }\n}\n\nexport const handleSnapshot = async (\n cwd: string = process.cwd(),\n options: SnapshotOptions = {},\n eslint?: ProjectEslint\n): Promise<void> => {\n const snapshotPath = resolve(cwd, options.snapshotPath ?? SNAPSHOT_FILENAME)\n const previous = readJson(snapshotPath) as EslintSnapshot | null\n\n if (options.check) {\n if (!previous) {\n if (options.json) {\n console.log(JSON.stringify({ exists: false, snapshotPath }, null, 2))\n } else {\n console.error(`❌ Snapshot is missing: ${relative(cwd, snapshotPath)}`)\n }\n\n process.exitCode = 1\n\n return\n }\n\n const files = options.files?.length ? options.files : Object.keys(previous.files)\n const current = await createConfigSnapshot(cwd, files, eslint, previous.scope ?? 'all')\n const diffs = diffConfigSnapshots(previous, current)\n\n if (options.json) console.log(JSON.stringify({ diffs, snapshotPath }, null, 2))\n else outputSnapshotDiff(diffs)\n\n if (diffs.length > 0) process.exitCode = 1\n\n return\n }\n\n const current = await createConfigSnapshot(\n cwd,\n options.files,\n eslint,\n options.rulesOnly ? 'rules' : 'all'\n )\n\n writeFileSync(snapshotPath, `${JSON.stringify(current, null, 2)}\\n`)\n\n if (options.json) {\n console.log(JSON.stringify({\n files: Object.keys(current.files),\n snapshotPath\n }, null, 2))\n } else {\n console.log(`✅ Saved effective ESLint configuration to ${relative(cwd, snapshotPath)}.`)\n }\n}\n\nexport const handleSnapshotDiff = async (\n cwd: string = process.cwd(),\n options: SnapshotOptions = {},\n eslint?: ProjectEslint\n): Promise<void> => {\n const snapshotPath = resolve(cwd, options.snapshotPath ?? SNAPSHOT_FILENAME)\n const previous = readJson(snapshotPath) as EslintSnapshot | null\n\n if (!previous) throw new Error(`Snapshot is missing: ${relative(cwd, snapshotPath)}. Run basic-eslint snapshot first.`)\n\n const files = options.files?.length ? options.files : Object.keys(previous.files)\n const current = await createConfigSnapshot(cwd, files, eslint, previous.scope ?? 'all')\n const diffs = diffConfigSnapshots(previous, current)\n\n if (options.json) console.log(JSON.stringify({ diffs, snapshotPath }, null, 2))\n else outputSnapshotDiff(diffs)\n\n if (diffs.length > 0) process.exitCode = 1\n}\n\nexport const isDirectory = (path: string): boolean => {\n try {\n return statSync(path).isDirectory()\n } catch {\n return false\n }\n}\n"],"mappings":"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","names":["current"]}
|
package/dist/cli.d.ts
CHANGED
|
@@ -31,5 +31,6 @@ declare const handleInstall: (cwd?: string, dryRun?: boolean, runner?: InstallRu
|
|
|
31
31
|
declare const handleDocs: (cwd?: string) => void;
|
|
32
32
|
declare const handleMigrate: (cwd?: string, write?: boolean, json?: boolean, target?: string, check?: boolean, full?: boolean) => void;
|
|
33
33
|
declare const runCli: (argv?: string[], cwd?: string) => void;
|
|
34
|
+
declare const isCliEntrypoint: (entryPath: string, modulePath?: string) => boolean;
|
|
34
35
|
|
|
35
|
-
export { findDuplicateEslint, handleDocs, handleDoctor, handleExplain, handleInit, handleInspect, handleInstall, handleMigrate, handleUpdate, runCli };
|
|
36
|
+
export { findDuplicateEslint, handleDocs, handleDoctor, handleExplain, handleInit, handleInspect, handleInstall, handleMigrate, handleUpdate, isCliEntrypoint, runCli };
|
package/dist/cli.js
CHANGED
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
import { handleExplainPreset } from "./cli-preset.js";
|
|
25
25
|
import {
|
|
26
26
|
handleBaseline,
|
|
27
|
+
handleConfigTypes,
|
|
27
28
|
handleProfile,
|
|
28
29
|
handleSnapshot,
|
|
29
30
|
handleSnapshotDiff
|
|
@@ -414,6 +415,7 @@ const printUsage = () => {
|
|
|
414
415
|
" install Install missing packages for detected v3 features",
|
|
415
416
|
" doctor Check project setup for common v3 adoption issues",
|
|
416
417
|
" compatibility Check runtime and config package compatibility",
|
|
418
|
+
" config-types Emit and verify portable ESLint config declarations",
|
|
417
419
|
" docs Generate ESLINT_STANDARDS.md from detection",
|
|
418
420
|
" migrate Plan or apply v1-to-v2 and v2-to-v3 migrations",
|
|
419
421
|
" baseline Suppress existing violations for incremental adoption",
|
|
@@ -442,6 +444,8 @@ const printUsage = () => {
|
|
|
442
444
|
" --output explain-preset: compatibility override path",
|
|
443
445
|
" --preset baseline: enable ci or pedantic strict mode before suppressing",
|
|
444
446
|
" --prune baseline: remove suppressions for resolved violations",
|
|
447
|
+
" --rules-only snapshot: store only effective rules for compact CI review",
|
|
448
|
+
" --semantic-only explain-preset: preview or write only non-formatting fixes",
|
|
445
449
|
" --snapshot-path snapshot/diff: override .eslint-config-snapshot.json",
|
|
446
450
|
" --to migrate: target version (v2 or v3)",
|
|
447
451
|
" --verbose doctor: print per-project activation details",
|
|
@@ -454,18 +458,27 @@ const printUsage = () => {
|
|
|
454
458
|
const COMMAND_OPTIONS = {
|
|
455
459
|
baseline: ["--json", "--preset", "--prune"],
|
|
456
460
|
compatibility: ["--json"],
|
|
461
|
+
"config-types": ["--file", "--json"],
|
|
457
462
|
diff: ["--file", "--json", "--snapshot-path"],
|
|
458
463
|
docs: [],
|
|
459
464
|
doctor: ["--fix", "--json", "--lite-install", "--verbose"],
|
|
460
465
|
explain: ["--file", "--json"],
|
|
461
|
-
"explain-preset": [
|
|
466
|
+
"explain-preset": [
|
|
467
|
+
"--analyze-source",
|
|
468
|
+
"--compatibility",
|
|
469
|
+
"--file",
|
|
470
|
+
"--json",
|
|
471
|
+
"--output",
|
|
472
|
+
"--semantic-only",
|
|
473
|
+
"--write"
|
|
474
|
+
],
|
|
462
475
|
"generate-skill": ["--check", "--create", "--force", "--with-eslint-mcp"],
|
|
463
476
|
init: ["--check", "--explicit"],
|
|
464
477
|
inspect: ["--json"],
|
|
465
478
|
install: ["--dry-run"],
|
|
466
479
|
migrate: ["--check", "--full", "--json", "--to", "--write"],
|
|
467
480
|
profile: ["--concurrency", "--file", "--json", "--max-duration", "--max-rule-time", "--max-warnings"],
|
|
468
|
-
snapshot: ["--check", "--file", "--json", "--snapshot-path"],
|
|
481
|
+
snapshot: ["--check", "--file", "--json", "--rules-only", "--snapshot-path"],
|
|
469
482
|
update: []
|
|
470
483
|
};
|
|
471
484
|
const VALUE_OPTIONS = /* @__PURE__ */ new Set([
|
|
@@ -1052,6 +1065,9 @@ const getDoctorProjectActivations = async (cwd) => {
|
|
|
1052
1065
|
componentClasses: tailwindComponentClasses,
|
|
1053
1066
|
detected: tailwindDetected,
|
|
1054
1067
|
entryPoint: tailwindEntryPoint,
|
|
1068
|
+
...tailwindDetected ? {
|
|
1069
|
+
exceptionGuidance: tailwindEntryPoint ? "Keep unknown-class exceptions project-scoped with anchored `tailwind.ignore` patterns; use a JSX comment for a one-line MDX directive." : "Set a project-scoped `tailwind.entryPoint` before adding unknown-class exceptions."
|
|
1070
|
+
} : {},
|
|
1055
1071
|
unknownClassPolicy: getTailwindUnknownClassPolicy(
|
|
1056
1072
|
tailwindDetected,
|
|
1057
1073
|
tailwindEntryPoint,
|
|
@@ -1490,10 +1506,23 @@ const dispatchCommand = (command, cwd, flags) => {
|
|
|
1490
1506
|
handleCompatibility(cwd, flags.hasJson);
|
|
1491
1507
|
break;
|
|
1492
1508
|
}
|
|
1509
|
+
case "config-types": {
|
|
1510
|
+
try {
|
|
1511
|
+
handleConfigTypes(cwd, {
|
|
1512
|
+
files: flags.files,
|
|
1513
|
+
json: flags.hasJson
|
|
1514
|
+
});
|
|
1515
|
+
} catch (error) {
|
|
1516
|
+
console.error(`\u274C Failed to check config declaration portability: ${String(error)}`);
|
|
1517
|
+
process.exitCode = 1;
|
|
1518
|
+
}
|
|
1519
|
+
break;
|
|
1520
|
+
}
|
|
1493
1521
|
case "diff": {
|
|
1494
1522
|
handleSnapshotDiff(cwd, {
|
|
1495
1523
|
files: flags.files,
|
|
1496
1524
|
json: flags.hasJson,
|
|
1525
|
+
rulesOnly: flags.hasRulesOnly,
|
|
1497
1526
|
snapshotPath: flags.snapshotPath
|
|
1498
1527
|
}).catch((error) => {
|
|
1499
1528
|
console.error(`\u274C Failed to diff ESLint configuration: ${String(error)}`);
|
|
@@ -1539,7 +1568,9 @@ const dispatchCommand = (command, cwd, flags) => {
|
|
|
1539
1568
|
file: flags.files[0],
|
|
1540
1569
|
files: flags.files,
|
|
1541
1570
|
json: flags.hasJson,
|
|
1542
|
-
output: flags.output
|
|
1571
|
+
output: flags.output,
|
|
1572
|
+
semanticOnly: flags.hasSemanticOnly,
|
|
1573
|
+
write: flags.hasWrite
|
|
1543
1574
|
}).catch((error) => {
|
|
1544
1575
|
console.error(`\u274C Failed to explain preset: ${String(error)}`);
|
|
1545
1576
|
process.exitCode = 1;
|
|
@@ -1609,6 +1640,7 @@ const dispatchCommand = (command, cwd, flags) => {
|
|
|
1609
1640
|
check: flags.hasCheck,
|
|
1610
1641
|
files: flags.files,
|
|
1611
1642
|
json: flags.hasJson,
|
|
1643
|
+
rulesOnly: flags.hasRulesOnly,
|
|
1612
1644
|
snapshotPath: flags.snapshotPath
|
|
1613
1645
|
}).catch((error) => {
|
|
1614
1646
|
console.error(`\u274C Failed to snapshot ESLint configuration: ${String(error)}`);
|
|
@@ -1679,6 +1711,8 @@ const runCli = (argv = process.argv, cwd = process.cwd()) => {
|
|
|
1679
1711
|
hasJson: argv.includes("--json"),
|
|
1680
1712
|
hasLiteInstall: argv.includes("--lite-install"),
|
|
1681
1713
|
hasPrune: argv.includes("--prune"),
|
|
1714
|
+
hasRulesOnly: argv.includes("--rules-only"),
|
|
1715
|
+
hasSemanticOnly: argv.includes("--semantic-only"),
|
|
1682
1716
|
hasVerbose: argv.includes("--verbose"),
|
|
1683
1717
|
hasWithEslintMcp: argv.includes("--with-eslint-mcp"),
|
|
1684
1718
|
hasWrite: argv.includes("--write"),
|
|
@@ -1693,7 +1727,12 @@ const runCli = (argv = process.argv, cwd = process.cwd()) => {
|
|
|
1693
1727
|
target: getFlagValue(argv, "--to")
|
|
1694
1728
|
});
|
|
1695
1729
|
};
|
|
1696
|
-
|
|
1730
|
+
const isCliEntrypoint = (entryPath, modulePath = fileURLToPath(import.meta.url)) => entryPath === modulePath || [
|
|
1731
|
+
"basic-eslint",
|
|
1732
|
+
"cli.js",
|
|
1733
|
+
"cli.ts"
|
|
1734
|
+
].includes(basename(entryPath));
|
|
1735
|
+
if (process.argv[1] && isCliEntrypoint(process.argv[1])) {
|
|
1697
1736
|
runCli();
|
|
1698
1737
|
}
|
|
1699
1738
|
export {
|
|
@@ -1706,6 +1745,7 @@ export {
|
|
|
1706
1745
|
handleInstall,
|
|
1707
1746
|
handleMigrate,
|
|
1708
1747
|
handleUpdate,
|
|
1748
|
+
isCliEntrypoint,
|
|
1709
1749
|
runCli
|
|
1710
1750
|
};
|
|
1711
1751
|
//# sourceMappingURL=cli.js.map
|