@santi020k/eslint-config-basic 3.4.0 → 3.5.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/CHANGELOG.md CHANGED
@@ -1,5 +1,53 @@
1
1
  # @santi020k/eslint-config-basic
2
2
 
3
+ ## 3.5.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#118](https://github.com/santi020k/eslint-config-basic/pull/118) [`355dfcd`](https://github.com/santi020k/eslint-config-basic/commit/355dfcd5c6b3baaf472178953d836b9e1e417476) Thanks [@santi020k](https://github.com/santi020k)! - Preserve Bun ambient types in config declaration checks, classify semantic-only
8
+ autofixes with ESLint rule metadata while excluding sorting fixes, and follow
9
+ local CSS imports declared inside Astro component style blocks.
10
+
11
+ ## 3.5.0
12
+
13
+ ### Minor Changes
14
+
15
+ - [#116](https://github.com/santi020k/eslint-config-basic/pull/116) [`498bb41`](https://github.com/santi020k/eslint-config-basic/commit/498bb418d077e57d3dc71c8441813d9b8a2545ca) Thanks [@santi020k](https://github.com/santi020k)! - Keep Astro lint runs warning-free by leaving `projectService` ownership with
16
+ Astro's supported `project` parser option. TypeScript parser setup no longer
17
+ forwards `projectService` into Astro source files, while Vue, Svelte, and
18
+ virtual TypeScript files retain their existing parser behavior.
19
+
20
+ Add `snapshot --rules-only` for compact committed rule contracts. Rules-only
21
+ snapshots record their scope so subsequent checks and diffs omit globals,
22
+ language options, and plugin metadata automatically.
23
+
24
+ Forward `--rules-only` through the public CLI dispatcher and add an end-to-end
25
+ regression for the saved scope. The option was previously accepted but only
26
+ direct handler calls received it.
27
+
28
+ Add `config-types` to emit ESLint config declarations in memory with the
29
+ consumer's TypeScript context and reject pnpm-internal or transitive
30
+ `typescript-eslint` types. The composite action exposes an opt-in portability
31
+ gate for consumer maintenance workflows.
32
+
33
+ Discover exact selectors from Astro component-local styles and narrow utility
34
+ patterns from explicitly configured Tailwind plugins. Doctor reports the
35
+ smallest project-scoped exception shape when dynamic classes still need an
36
+ allowance.
37
+
38
+ Add semantic-only preset adoption fixes and report scripts that combine source
39
+ file reads with regular-expression parsing. Writing is allowed only in the
40
+ semantic-only mode, keeping formatting churn in a separate review.
41
+
42
+ Run the CLI when pnpm invokes its direct `.bin/basic-eslint` symlink. Older
43
+ entrypoint guards could silently exit successfully because the executable path
44
+ did not end in `cli.js`.
45
+
46
+ ### Patch Changes
47
+
48
+ - Updated dependencies [[`498bb41`](https://github.com/santi020k/eslint-config-basic/commit/498bb418d077e57d3dc71c8441813d9b8a2545ca)]:
49
+ - @santi020k/eslint-config-typescript@3.1.3
50
+
3
51
  ## 3.4.0
4
52
 
5
53
  ### Minor Changes
@@ -8,11 +8,15 @@ interface ExplainPresetOptions {
8
8
  files?: string[];
9
9
  json?: boolean;
10
10
  output?: string;
11
+ semanticOnly?: boolean;
12
+ write?: boolean;
11
13
  }
12
14
  interface CreatePresetReportOptions {
13
15
  analyzeSource?: boolean;
16
+ semanticOnly?: boolean;
14
17
  sourceFiles?: string[];
15
18
  typescriptRunner?: CommandRunner;
19
+ write?: boolean;
16
20
  }
17
21
  interface FindingSummary {
18
22
  errors: number;
@@ -20,6 +24,10 @@ interface FindingSummary {
20
24
  total: number;
21
25
  warnings: number;
22
26
  }
27
+ interface SourceFormatParserCandidate {
28
+ file: string;
29
+ lines: number[];
30
+ }
23
31
  interface TypeScriptDiagnostic {
24
32
  code: string;
25
33
  config: string;
@@ -37,7 +45,7 @@ declare const createTypeScriptPreflight: (cwd: string, configuredProjects?: stri
37
45
  }[];
38
46
  diagnosticCount: number;
39
47
  rootDiagnostics: TypeScriptDiagnostic[];
40
- status: "failed" | "passed";
48
+ status: "passed" | "failed";
41
49
  };
42
50
  declare const createPresetReport: (cwd: string, presetName: string, file?: string, options?: CreatePresetReportOptions) => Promise<{
43
51
  added: Record<string, unknown>;
@@ -62,6 +70,8 @@ declare const createPresetReport: (cwd: string, presetName: string, file?: strin
62
70
  remainingErrors: number;
63
71
  remainingFixableRules: string[];
64
72
  remainingWarnings: number;
73
+ scope: "all" | "semantic";
74
+ writtenFileCount: number;
65
75
  };
66
76
  byCategory: Record<string, FindingSummary>;
67
77
  byFileType: Record<string, FindingSummary>;
@@ -71,6 +81,7 @@ declare const createPresetReport: (cwd: string, presetName: string, file?: strin
71
81
  count: number;
72
82
  rules: string[];
73
83
  };
84
+ sourceFormatParserCandidates: SourceFormatParserCandidate[];
74
85
  typescriptPreflight: {
75
86
  configs: never[];
76
87
  diagnosticCount: number;
@@ -83,7 +94,7 @@ declare const createPresetReport: (cwd: string, presetName: string, file?: strin
83
94
  }[];
84
95
  diagnosticCount: number;
85
96
  rootDiagnostics: TypeScriptDiagnostic[];
86
- status: "failed" | "passed";
97
+ status: "passed" | "failed";
87
98
  };
88
99
  totals: {
89
100
  errors: number;
@@ -90,10 +90,17 @@ const FORMAT_PREFIXES = /* @__PURE__ */ new Set([
90
90
  "jsonc",
91
91
  "markdown",
92
92
  "mdx",
93
+ "perfectionist",
93
94
  "prettier",
94
95
  "toml",
95
96
  "yaml"
96
97
  ]);
98
+ const FORMAT_RULES = /* @__PURE__ */ new Set([
99
+ "import/first",
100
+ "sort-imports",
101
+ "simple-import-sort/exports",
102
+ "simple-import-sort/imports"
103
+ ]);
97
104
  const MULTI_SEGMENT_RULE_PREFIXES = /* @__PURE__ */ new Set(["@next/next"]);
98
105
  const getRulePrefix = (rule) => {
99
106
  const segments = rule.split("/");
@@ -106,7 +113,7 @@ const getRuleGroup = (rule) => {
106
113
  if (prefix === "security" || prefix === "no-secrets" || rule.includes("security") || rule.includes("no-unsanitized")) return "security";
107
114
  if (FRAMEWORK_PREFIXES.has(prefix)) return "framework";
108
115
  if (DOMAIN_PREFIXES.has(prefix)) return "domain";
109
- if (FORMAT_PREFIXES.has(prefix) || rule.includes("format") || rule.includes("spacing")) return "formatting";
116
+ if (FORMAT_PREFIXES.has(prefix) || FORMAT_RULES.has(rule) || rule.includes("format") || rule.includes("spacing")) return "formatting";
110
117
  return "correctness";
111
118
  };
112
119
  const getSeverity = (value) => Array.isArray(value) ? value[0] : value;
@@ -121,7 +128,7 @@ const loadProjectEslint = (cwd, overrideConfig, fix = false) => {
121
128
  if (!eslintModule.ESLint) throw new Error("The installed eslint package does not expose the ESLint API.");
122
129
  return new eslintModule.ESLint({
123
130
  cwd,
124
- ...fix ? { fix: true } : {},
131
+ ...fix ? { fix } : {},
125
132
  ...overrideConfig ? { overrideConfig, overrideConfigFile: true } : {}
126
133
  });
127
134
  };
@@ -237,6 +244,20 @@ const readOriginalSource = (filePath) => {
237
244
  return void 0;
238
245
  }
239
246
  };
247
+ const SOURCE_FILE_READ_PATTERN = /\b(?:Bun\.file|Deno\.readTextFile|readFile|readFileSync|readTextFile)\b/;
248
+ const SOURCE_REGEXP_PATTERN = new RegExp([
249
+ String.raw`\.match(?:All)?\s*\(`,
250
+ String.raw`\.replace(?:All)?\s*\(`,
251
+ String.raw`\.search\s*\(`,
252
+ String.raw`\bRegExp\s*\(`,
253
+ String.raw`\.(?:exec|test)\s*\(`
254
+ ].join("|"));
255
+ const findSourceFormatParserCandidates = (cwd, filePaths) => filePaths.flatMap((filePath) => {
256
+ const content = readOriginalSource(filePath);
257
+ if (!content || !SOURCE_FILE_READ_PATTERN.test(content)) return [];
258
+ const lines = content.split("\n").flatMap((line, index) => SOURCE_REGEXP_PATTERN.test(line) ? [index + 1] : []);
259
+ return lines.length > 0 ? [{ file: relative(cwd, filePath), lines }] : [];
260
+ });
240
261
  const TYPESCRIPT_CONFIG_FILENAMES = [
241
262
  "tsconfig.json",
242
263
  "tsconfig.base.json",
@@ -324,10 +345,18 @@ ${result.stderr}`
324
345
  status: results.some((result) => result.status !== 0) ? "failed" : "passed"
325
346
  };
326
347
  };
327
- const analyzePresetSource = async (cwd, selectedConfig, sourceFiles, configuredProjects, typescriptRunner) => {
348
+ const analyzePresetSource = async (cwd, selectedConfig, sourceFiles, configuredProjects, typescriptRunner, semanticOnly = false, write = false) => {
328
349
  const lintTargets = sourceFiles.length > 0 ? sourceFiles : ["."];
329
- const lintResults = await loadProjectEslint(cwd, selectedConfig).lintFiles(lintTargets);
330
- const previewResults = await loadProjectEslint(cwd, selectedConfig, true).lintFiles(lintTargets);
350
+ const analysisEslint = loadProjectEslint(cwd, selectedConfig);
351
+ const lintResults = await analysisEslint.lintFiles(lintTargets);
352
+ const rulesMeta = analysisEslint.getRulesMetaForResults(lintResults);
353
+ const fix = semanticOnly ? (message) => {
354
+ if (message.ruleId === null) return false;
355
+ const metadata = rulesMeta[message.ruleId];
356
+ if (metadata?.type === "layout" || metadata?.fixable === "whitespace") return false;
357
+ return getRuleGroup(message.ruleId) !== "formatting";
358
+ } : true;
359
+ const previewResults = await loadProjectEslint(cwd, selectedConfig, fix).lintFiles(lintTargets);
331
360
  const byCategory = {};
332
361
  const byFileType = {};
333
362
  const byRule = {};
@@ -352,6 +381,7 @@ const analyzePresetSource = async (cwd, selectedConfig, sourceFiles, configuredP
352
381
  let estimatedChangedLines = 0;
353
382
  let remainingErrors = 0;
354
383
  let remainingWarnings = 0;
384
+ let writtenFileCount = 0;
355
385
  for (const result of previewResults) {
356
386
  remainingErrors += result.errorCount;
357
387
  remainingWarnings += result.warningCount;
@@ -362,6 +392,10 @@ const analyzePresetSource = async (cwd, selectedConfig, sourceFiles, configuredP
362
392
  changedFiles.push(relative(cwd, result.filePath));
363
393
  const original = readOriginalSource(result.filePath);
364
394
  if (original !== void 0) estimatedChangedLines += estimateChangedLines(original, result.output);
395
+ if (write) {
396
+ writeFileSync(result.filePath, result.output);
397
+ writtenFileCount++;
398
+ }
365
399
  }
366
400
  return {
367
401
  autofixPreview: {
@@ -370,7 +404,9 @@ const analyzePresetSource = async (cwd, selectedConfig, sourceFiles, configuredP
370
404
  estimatedChangedLines,
371
405
  remainingErrors,
372
406
  remainingFixableRules: [...remainingFixableRules].sort(),
373
- remainingWarnings
407
+ remainingWarnings,
408
+ scope: semanticOnly ? "semantic" : "all",
409
+ writtenFileCount
374
410
  },
375
411
  byCategory,
376
412
  byFileType,
@@ -380,6 +416,10 @@ const analyzePresetSource = async (cwd, selectedConfig, sourceFiles, configuredP
380
416
  count: nonFormattingErrors,
381
417
  rules: [...nonFormattingErrorRules].sort()
382
418
  },
419
+ sourceFormatParserCandidates: findSourceFormatParserCandidates(
420
+ cwd,
421
+ [...new Set(lintResults.map((result) => result.filePath))]
422
+ ),
383
423
  typescriptPreflight: createTypeScriptPreflight(cwd, configuredProjects, typescriptRunner),
384
424
  totals: {
385
425
  errors: lintResults.reduce((total, result) => total + result.errorCount, 0),
@@ -401,6 +441,8 @@ const formatSourceAnalysis = (analysis) => {
401
441
  }
402
442
  const nonFormattingRuleSuffix = analysis.nonFormattingErrors.rules.length > 0 ? ` (${analysis.nonFormattingErrors.rules.join(", ")})` : "";
403
443
  const remainingFixableRules = analysis.autofixPreview.remainingFixableRules.length > 0 ? analysis.autofixPreview.remainingFixableRules.join(", ") : "none";
444
+ const parserCandidates = analysis.sourceFormatParserCandidates.length > 0 ? analysis.sourceFormatParserCandidates.map((candidate) => ` - ${candidate.file}:${candidate.lines.join(",")}`) : [" - none"];
445
+ const previewLabel = analysis.autofixPreview.scope === "semantic" ? "Semantic autofix" : "Autofix";
404
446
  const typescriptLines = analysis.typescriptPreflight.status === "failed" ? [
405
447
  `- TypeScript preflight: failed with ${analysis.typescriptPreflight.diagnosticCount} diagnostics`,
406
448
  ...analysis.typescriptPreflight.rootDiagnostics.map((diagnostic) => ` - ${diagnostic.config} ${diagnostic.code}: ${diagnostic.message}`),
@@ -410,14 +452,16 @@ const formatSourceAnalysis = (analysis) => {
410
452
  ];
411
453
  return [
412
454
  "",
413
- "Source analysis (selected preset, no files written):",
455
+ `Source analysis (selected preset, ${analysis.autofixPreview.writtenFileCount > 0 ? `${analysis.autofixPreview.writtenFileCount} files written` : "no files written"}):`,
414
456
  `- Lint targets: ${analysis.lintTargets.join(", ")}`,
415
457
  `- Files analyzed: ${analysis.totals.files}`,
416
458
  `- Findings: ${analysis.totals.findings} (${analysis.totals.errors} errors, ${analysis.totals.warnings} warnings)`,
417
459
  `- Non-formatting errors to resolve first: ${analysis.nonFormattingErrors.count}${nonFormattingRuleSuffix}`,
418
- `- Autofix preview: ${analysis.autofixPreview.changedFileCount} files, about ${analysis.autofixPreview.estimatedChangedLines} changed lines`,
460
+ `- ${previewLabel} preview: ${analysis.autofixPreview.changedFileCount} files, about ${analysis.autofixPreview.estimatedChangedLines} changed lines`,
419
461
  `- Findings remaining after preview: ${analysis.autofixPreview.remainingErrors} errors, ${analysis.autofixPreview.remainingWarnings} warnings`,
420
462
  `- Fixable rules still remaining: ${remainingFixableRules}`,
463
+ "- Formatting-sensitive source-parser candidates:",
464
+ ...parserCandidates,
421
465
  ...typescriptLines
422
466
  ];
423
467
  };
@@ -436,6 +480,9 @@ const formatCompatibilityGuidance = (compatibilityFile) => {
436
480
  ];
437
481
  };
438
482
  const createPresetReport = async (cwd, presetName, file = "eslint.config.js", options = {}) => {
483
+ if (options.write && !options.semanticOnly) {
484
+ throw new Error("Writing preset fixes requires semanticOnly to avoid an unchecked formatting rewrite.");
485
+ }
439
486
  const normalizedPreset = presetName.toLowerCase();
440
487
  if (!PRESETS.has(normalizedPreset)) {
441
488
  throw new Error(
@@ -500,7 +547,9 @@ const createPresetReport = async (cwd, presetName, file = "eslint.config.js", op
500
547
  selectedConfig,
501
548
  options.sourceFiles ?? [],
502
549
  Object.keys(resolvablePresetOptions.projects ?? {}),
503
- options.typescriptRunner ?? defaultCommandRunner
550
+ options.typescriptRunner ?? defaultCommandRunner,
551
+ options.semanticOnly,
552
+ options.write
504
553
  ) : null;
505
554
  return {
506
555
  added,
@@ -521,9 +570,17 @@ const createPresetReport = async (cwd, presetName, file = "eslint.config.js", op
521
570
  };
522
571
  };
523
572
  const handleExplainPreset = async (cwd = process.cwd(), preset, options = {}) => {
573
+ if (options.write && !options.semanticOnly) {
574
+ throw new Error("explain-preset --write requires --semantic-only to avoid an unchecked formatting rewrite.");
575
+ }
576
+ if (options.semanticOnly && !options.analyzeSource) {
577
+ throw new Error("explain-preset --semantic-only requires --analyze-source.");
578
+ }
524
579
  const report = await createPresetReport(cwd, preset, options.file, {
525
580
  analyzeSource: options.analyzeSource,
526
- sourceFiles: options.files
581
+ semanticOnly: options.semanticOnly,
582
+ sourceFiles: options.files,
583
+ write: options.write
527
584
  });
528
585
  let compatibilityFile = null;
529
586
  if (options.compatibility) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli-preset.ts"],"sourcesContent":["/* eslint-disable no-console -- CLI handlers own user-facing terminal output */\n/* eslint-disable complexity -- report comparison and formatting intentionally cover multiple result branches */\nimport { existsSync, readFileSync, writeFileSync } from 'node:fs'\nimport { createRequire, findPackageJSON } from 'node:module'\nimport { dirname, extname, join, relative } from 'node:path'\nimport { pathToFileURL } from 'node:url'\n\nimport {\n type DetectedFrameworkName,\n detectProjectOptions,\n type EslintConfigOptions,\n Preset\n} from '@santi020k/eslint-config-core'\n\nimport { type CommandRunner, defaultCommandRunner } from './cli-workflows.js'\nimport { type DefineConfigMetadata, getDefineConfigMetadata } from './define-config-metadata.js'\nimport { defineConfig } from './index.js'\nimport { isMissingRequestedPackage } from './optional-package-errors.js'\nimport { resolvePreset } from './resolvers.js'\n\ninterface EffectiveConfig {\n rules?: Partial<Record<string, unknown>>\n}\n\ninterface ProjectLintMessage {\n fatal?: boolean\n fix?: unknown\n ruleId: null | string\n severity: number\n}\n\ninterface ProjectLintResult {\n errorCount: number\n filePath: string\n messages: ProjectLintMessage[]\n output?: string\n warningCount: number\n}\n\ninterface ProjectEslint {\n calculateConfigForFile: (filePath: string) => Promise<EffectiveConfig | null>\n lintFiles: (patterns: string[]) => Promise<ProjectLintResult[]>\n}\n\ntype ProjectEslintConstructor = new(options: {\n cwd: string\n fix?: boolean\n overrideConfig?: unknown\n overrideConfigFile?: boolean\n}) => ProjectEslint\n\nexport interface ExplainPresetOptions {\n analyzeSource?: boolean\n compatibility?: boolean\n file?: string\n files?: string[]\n json?: boolean\n output?: string\n}\n\ninterface CreatePresetReportOptions {\n analyzeSource?: boolean\n sourceFiles?: string[]\n typescriptRunner?: CommandRunner\n}\n\nconst PRESETS = new Set<string>(Object.values(Preset))\n\nconst 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 loadDefineConfigMetadata = async (cwd: string): Promise<DefineConfigMetadata | undefined> => {\n const configPath = CONFIG_FILENAMES.map(name => join(cwd, name)).find(path => existsSync(path))\n\n if (!configPath) return undefined\n\n try {\n const loaded = await import(`${pathToFileURL(configPath).href}?basic-eslint-preset=${Date.now()}`) as {\n default?: unknown\n }\n\n return getDefineConfigMetadata(await loaded.default)\n } catch {\n return undefined\n }\n}\n\nconst PRESET_FEATURE_PACKAGES = {\n extensions: '@santi020k/eslint-config-extensions',\n formats: '@santi020k/eslint-config-formats',\n libraries: '@santi020k/eslint-config-libraries',\n testing: '@santi020k/eslint-config-testing',\n tools: '@santi020k/eslint-config-tools'\n} as const\n\nconst FRAMEWORK_PACKAGES: Record<DetectedFrameworkName, string> = {\n angular: '@santi020k/eslint-config-angular',\n astro: '@santi020k/eslint-config-astro',\n expo: '@santi020k/eslint-config-expo',\n hono: '@santi020k/eslint-config-hono',\n lit: '@santi020k/eslint-config-lit',\n nest: '@santi020k/eslint-config-nest',\n next: '@santi020k/eslint-config-next',\n nuxt: '@santi020k/eslint-config-nuxt',\n preact: '@santi020k/eslint-config-preact',\n qwik: '@santi020k/eslint-config-qwik',\n react: '@santi020k/eslint-config-react',\n 'react-router': '@santi020k/eslint-config-react-router',\n slidev: '@santi020k/eslint-config-slidev',\n solid: '@santi020k/eslint-config-solid',\n svelte: '@santi020k/eslint-config-svelte',\n 'tanstack-start': '@santi020k/eslint-config-tanstack-start',\n vite: '@santi020k/eslint-config-vite',\n vue: '@santi020k/eslint-config-vue'\n}\n\nconst FRAMEWORK_PREFIXES = new Set([\n '@angular-eslint',\n '@eslint-react',\n '@next/next',\n 'astro',\n 'lit',\n 'qwik',\n 'react',\n 'react-hooks',\n 'react-refresh',\n 'solid',\n 'svelte',\n 'vue'\n])\n\nconst DOMAIN_PREFIXES = new Set([\n 'better-tailwindcss',\n 'drizzle',\n 'graphql-eslint',\n 'i18next',\n 'prisma',\n 'storybook',\n 'tailwindcss',\n 'tanstack-query',\n 'turbo',\n 'zod'\n])\n\nconst FORMAT_PREFIXES = new Set([\n '@stylistic',\n 'css',\n 'html',\n 'jsonc',\n 'markdown',\n 'mdx',\n 'prettier',\n 'toml',\n 'yaml'\n])\n\nconst MULTI_SEGMENT_RULE_PREFIXES = new Set(['@next/next'])\n\nconst getRulePrefix = (rule: string): string => {\n const segments = rule.split('/')\n\n if (!rule.startsWith('@')) return segments[0]\n\n const multiSegmentPrefix = segments.slice(0, 2).join('/')\n\n return MULTI_SEGMENT_RULE_PREFIXES.has(multiSegmentPrefix) ? multiSegmentPrefix : segments[0]\n}\n\nconst getRuleGroup = (rule: string): 'correctness' | 'domain' | 'formatting' | 'framework' | 'security' => {\n const prefix = getRulePrefix(rule)\n\n if (\n prefix === 'security' ||\n prefix === 'no-secrets' ||\n rule.includes('security') ||\n rule.includes('no-unsanitized')\n ) return 'security'\n\n if (FRAMEWORK_PREFIXES.has(prefix)) return 'framework'\n\n if (DOMAIN_PREFIXES.has(prefix)) return 'domain'\n\n if (FORMAT_PREFIXES.has(prefix) || rule.includes('format') || rule.includes('spacing')) return 'formatting'\n\n return 'correctness'\n}\n\nconst getSeverity = (value: unknown): unknown => Array.isArray(value) ? value[0] : value\n\nconst isEnabled = (value: unknown): boolean => {\n const severity = getSeverity(value)\n\n return severity !== 0 && severity !== 'off' && severity !== undefined\n}\n\nconst normalizeRule = (value: unknown): string => JSON.stringify(value)\n\nconst loadProjectEslint = (\n cwd: string,\n overrideConfig?: unknown,\n fix = false\n): ProjectEslint => {\n const projectRequire = createRequire(join(cwd, 'package.json'))\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({\n cwd,\n ...(fix ? { fix: true } : {}),\n ...(overrideConfig ? { overrideConfig, overrideConfigFile: true } : {})\n })\n}\n\nconst getResolvablePresetOptions = (\n cwd: string,\n presetOptions: Partial<EslintConfigOptions>\n): { missingPackages: string[], options: Partial<EslintConfigOptions> } => {\n const projectPackageUrl = pathToFileURL(join(cwd, 'package.json'))\n const options = { ...presetOptions }\n const detectedOptions = detectProjectOptions(cwd)\n const missingPackages = new Set<string>()\n const detection = options.detection\n const detectionControls = typeof detection === 'object' ? detection : {}\n\n const detectionEnabled = (category: keyof typeof PRESET_FEATURE_PACKAGES): boolean => (\n detection !== false && detectionControls[category] !== false\n )\n\n for (const [category, specifier] of Object.entries(PRESET_FEATURE_PACKAGES)) {\n const categoryKey = category as keyof typeof PRESET_FEATURE_PACKAGES\n const explicit = options[categoryKey]\n const detected = detectionEnabled(categoryKey) ? detectedOptions[categoryKey] : []\n\n const selected = [...new Set([\n ...(Array.isArray(explicit) ? explicit : []),\n ...(Array.isArray(detected) ? detected : [])\n ])]\n\n if (selected.length === 0) continue\n\n try {\n findPackageJSON(specifier, projectPackageUrl)\n } catch (error) {\n if (!isMissingRequestedPackage(error, specifier)) throw error\n\n Object.assign(options, {\n [category]: [],\n detection: {\n ...(typeof options.detection === 'object' ? options.detection : detectionControls),\n [category]: false\n },\n features: {\n ...options.features,\n ...Object.fromEntries(selected.map(feature => [feature, false]))\n }\n })\n\n missingPackages.add(specifier)\n }\n }\n\n const frameworkDetectionEnabled = detection !== false && detectionControls.frameworks !== false\n const detectedFrameworks = frameworkDetectionEnabled ? detectedOptions.detectedFrameworks ?? [] : []\n\n const configuredFrameworks = Object.entries(options.frameworks ?? {})\n .filter((entry): entry is [DetectedFrameworkName, true] => entry[1] === true)\n .map(([framework]) => framework)\n\n const selectedFrameworks = [...new Set([...detectedFrameworks, ...configuredFrameworks])]\n\n const resolvableFrameworks: NonNullable<EslintConfigOptions['frameworks']> = {\n ...options.frameworks\n }\n\n for (const framework of selectedFrameworks) {\n const specifier = FRAMEWORK_PACKAGES[framework]\n\n try {\n findPackageJSON(specifier, projectPackageUrl)\n\n resolvableFrameworks[framework] = true\n } catch (error) {\n if (!isMissingRequestedPackage(error, specifier)) throw error\n\n Reflect.deleteProperty(resolvableFrameworks, framework)\n\n missingPackages.add(specifier)\n }\n }\n\n if (!resolvableFrameworks.react) {\n delete resolvableFrameworks.expo\n\n delete resolvableFrameworks.next\n\n delete resolvableFrameworks['react-router']\n\n if (!resolvableFrameworks.solid) delete resolvableFrameworks['tanstack-start']\n }\n\n if (!resolvableFrameworks.vue) {\n delete resolvableFrameworks.nuxt\n\n delete resolvableFrameworks.slidev\n }\n\n if (selectedFrameworks.length > 0) {\n options.autoFrameworks = false\n\n options.frameworks = resolvableFrameworks\n }\n\n return { missingPackages: [...missingPackages], options }\n}\n\nconst createCompatibilityConfig = (\n preset: string,\n addedRules: Record<string, unknown>,\n changedRules: Record<string, { from: unknown, to: unknown }>\n): string => [\n `// Temporary compatibility override generated for Preset.${preset.charAt(0).toUpperCase()}${preset.slice(1)}.`,\n '// Remove entries as the project adopts the preset findings.',\n 'export default {',\n ` name: 'eslint-config-basic/preset-${preset}-compatibility',`,\n ' rules: {',\n ...Object.keys(addedRules).sort().map(rule => ` ${JSON.stringify(rule)}: 'off',`),\n ...Object.keys(changedRules).sort().map(rule => (\n ` ${JSON.stringify(rule)}: ${JSON.stringify(changedRules[rule].from)},`\n )),\n ' },',\n '}',\n ''\n].join('\\n')\n\ninterface FindingSummary {\n errors: number\n fixable: number\n total: number\n warnings: number\n}\n\nconst createFindingSummary = (): FindingSummary => ({\n errors: 0,\n fixable: 0,\n total: 0,\n warnings: 0\n})\n\nconst addFinding = (\n summaries: Record<string, FindingSummary>,\n key: string,\n message: ProjectLintMessage\n): void => {\n const summary = summaries[key] ?? createFindingSummary()\n\n summary.total++\n\n if (message.severity === 2) summary.errors++\n else summary.warnings++\n\n if (message.fix !== undefined) summary.fixable++\n\n summaries[key] = summary\n}\n\nconst estimateChangedLines = (before: string, after: string): number => {\n const beforeLines = before.split('\\n')\n const afterLines = after.split('\\n')\n const comparableLines = Math.min(beforeLines.length, afterLines.length)\n let changed = Math.abs(beforeLines.length - afterLines.length)\n\n for (let index = 0; index < comparableLines; index++) {\n if (beforeLines[index] !== afterLines[index]) changed++\n }\n\n return changed\n}\n\nconst readOriginalSource = (filePath: string): string | undefined => {\n try {\n return readFileSync(filePath, 'utf8')\n } catch {\n return undefined\n }\n}\n\nconst TYPESCRIPT_CONFIG_FILENAMES = [\n 'tsconfig.json',\n 'tsconfig.base.json',\n 'tsconfig.app.json',\n 'tsconfig.node.json',\n 'tsconfig.eslint.json'\n]\n\nconst TYPESCRIPT_ROOT_DIAGNOSTIC_CODES = new Set([\n 'TS2307',\n 'TS2688',\n 'TS2792',\n 'TS6053'\n])\n\nconst resolveTypeScriptCli = (cwd: string): null | string => {\n try {\n const projectRequire = createRequire(join(cwd, 'package.json'))\n const packagePath = projectRequire.resolve('typescript/package.json')\n\n const manifest = JSON.parse(readFileSync(packagePath, 'utf8')) as {\n bin?: Record<string, string> | string\n }\n\n const bin = typeof manifest.bin === 'string' ? manifest.bin : manifest.bin?.tsc\n\n return bin ? join(dirname(packagePath), bin) : null\n } catch {\n return null\n }\n}\n\nconst getTypeScriptConfigs = (\n cwd: string,\n configuredProjects: string[]\n): string[] => {\n const detectedProjects = Object.keys(detectProjectOptions(cwd).projects ?? {})\n const projectRoots = [...new Set([...detectedProjects, ...configuredProjects])]\n\n const roots = [\n cwd,\n ...projectRoots.map(project => join(cwd, project))\n ]\n\n return [...new Set(roots.flatMap(root => {\n const config = TYPESCRIPT_CONFIG_FILENAMES.find(file => existsSync(join(root, file)))\n\n return config ? [join(root, config)] : []\n }))]\n}\n\ninterface TypeScriptDiagnostic {\n code: string\n config: string\n message: string\n}\n\nconst parseTypeScriptDiagnostics = (\n cwd: string,\n config: string,\n output: string\n): TypeScriptDiagnostic[] => output\n .split(/\\r?\\n/)\n .flatMap(line => {\n const match = /\\berror (TS\\d+):\\s*(.+)$/.exec(line)\n\n if (!match) return []\n\n return [{\n code: match[1],\n config: relative(cwd, config),\n message: match[2]\n }]\n })\n\nexport const createTypeScriptPreflight = (\n cwd: string,\n configuredProjects: string[] = [],\n runner: CommandRunner = defaultCommandRunner\n) => {\n const executable = resolveTypeScriptCli(cwd)\n const configs = getTypeScriptConfigs(cwd, configuredProjects)\n\n if (!executable || configs.length === 0) {\n return {\n configs: [],\n diagnosticCount: 0,\n rootDiagnostics: [] as TypeScriptDiagnostic[],\n status: 'skipped' as const\n }\n }\n\n const diagnostics: TypeScriptDiagnostic[] = []\n\n const results = configs.map(config => {\n const result = runner(process.execPath, [\n executable,\n '--noEmit',\n '--pretty',\n 'false',\n '--project',\n config\n ], cwd)\n\n diagnostics.push(...parseTypeScriptDiagnostics(\n cwd,\n config,\n `${result.stdout}\\n${result.stderr}`\n ))\n\n return {\n config: relative(cwd, config),\n status: result.status\n }\n })\n\n const rootDiagnostics = diagnostics.filter(\n diagnostic => TYPESCRIPT_ROOT_DIAGNOSTIC_CODES.has(diagnostic.code)\n )\n\n return {\n configs: results,\n diagnosticCount: diagnostics.length,\n rootDiagnostics: (rootDiagnostics.length > 0 ? rootDiagnostics : diagnostics).slice(0, 20),\n status: results.some(result => result.status !== 0) ? 'failed' as const : 'passed' as const\n }\n}\n\nconst analyzePresetSource = async (\n cwd: string,\n selectedConfig: unknown,\n sourceFiles: string[],\n configuredProjects: string[],\n typescriptRunner: CommandRunner\n) => {\n const lintTargets = sourceFiles.length > 0 ? sourceFiles : ['.']\n const lintResults = await loadProjectEslint(cwd, selectedConfig).lintFiles(lintTargets)\n const previewResults = await loadProjectEslint(cwd, selectedConfig, true).lintFiles(lintTargets)\n const byCategory: Record<string, FindingSummary> = {}\n const byFileType: Record<string, FindingSummary> = {}\n const byRule: Record<string, FindingSummary> = {}\n const nonFormattingErrorRules = new Set<string>()\n let nonFormattingErrors = 0\n\n for (const result of lintResults) {\n const fileType = extname(result.filePath) || '[no extension]'\n\n for (const message of result.messages) {\n const rule = message.ruleId ?? (message.fatal ? '[fatal]' : '[unknown]')\n const category = message.ruleId ? getRuleGroup(message.ruleId) : 'correctness'\n\n addFinding(byCategory, category, message)\n\n addFinding(byFileType, fileType, message)\n\n addFinding(byRule, rule, message)\n\n if (message.severity === 2 && category !== 'formatting') {\n nonFormattingErrors++\n\n nonFormattingErrorRules.add(rule)\n }\n }\n }\n\n const changedFiles: string[] = []\n const remainingFixableRules = new Set<string>()\n let estimatedChangedLines = 0\n let remainingErrors = 0\n let remainingWarnings = 0\n\n for (const result of previewResults) {\n remainingErrors += result.errorCount\n\n remainingWarnings += result.warningCount\n\n for (const message of result.messages) {\n if (message.fix !== undefined) remainingFixableRules.add(message.ruleId ?? '[fatal]')\n }\n\n if (result.output === undefined) continue\n\n changedFiles.push(relative(cwd, result.filePath))\n\n const original = readOriginalSource(result.filePath)\n\n if (original !== undefined) estimatedChangedLines += estimateChangedLines(original, result.output)\n }\n\n return {\n autofixPreview: {\n changedFileCount: changedFiles.length,\n changedFiles: changedFiles.sort(),\n estimatedChangedLines,\n remainingErrors,\n remainingFixableRules: [...remainingFixableRules].sort(),\n remainingWarnings\n },\n byCategory,\n byFileType,\n byRule,\n lintTargets,\n nonFormattingErrors: {\n count: nonFormattingErrors,\n rules: [...nonFormattingErrorRules].sort()\n },\n typescriptPreflight: createTypeScriptPreflight(cwd, configuredProjects, typescriptRunner),\n totals: {\n errors: lintResults.reduce((total, result) => total + result.errorCount, 0),\n files: lintResults.length,\n findings: lintResults.reduce(\n (total, result) => total + result.errorCount + result.warningCount,\n 0\n ),\n warnings: lintResults.reduce((total, result) => total + result.warningCount, 0)\n }\n }\n}\n\ntype PresetSourceAnalysis = Awaited<ReturnType<typeof analyzePresetSource>>\n\nconst formatSourceAnalysis = (\n analysis: null | PresetSourceAnalysis\n): string[] => {\n if (!analysis) {\n return [\n '',\n 'Pass --analyze-source to lint with the selected preset and preview autofix without writing files.'\n ]\n }\n\n const nonFormattingRuleSuffix = analysis.nonFormattingErrors.rules.length > 0 ?\n ` (${analysis.nonFormattingErrors.rules.join(', ')})` :\n ''\n\n const remainingFixableRules = analysis.autofixPreview.remainingFixableRules.length > 0 ?\n analysis.autofixPreview.remainingFixableRules.join(', ') :\n 'none'\n\n const typescriptLines = analysis.typescriptPreflight.status === 'failed' ?\n [\n `- TypeScript preflight: failed with ${analysis.typescriptPreflight.diagnosticCount} diagnostics`,\n ...analysis.typescriptPreflight.rootDiagnostics.map(diagnostic => (\n ` - ${diagnostic.config} ${diagnostic.code}: ${diagnostic.message}`\n )),\n '- Fix TypeScript compiler errors before reviewing cascading type-aware unsafe-rule findings.'\n ] :\n [\n `- TypeScript preflight: ${analysis.typescriptPreflight.status}` +\n (analysis.typescriptPreflight.status === 'passed' ?\n ` (${analysis.typescriptPreflight.configs.length} configs)` :\n ' (TypeScript or a supported tsconfig was not found)')\n ]\n\n return [\n '',\n 'Source analysis (selected preset, no files written):',\n `- Lint targets: ${analysis.lintTargets.join(', ')}`,\n `- Files analyzed: ${analysis.totals.files}`,\n `- Findings: ${analysis.totals.findings} ` +\n `(${analysis.totals.errors} errors, ${analysis.totals.warnings} warnings)`,\n `- Non-formatting errors to resolve first: ${analysis.nonFormattingErrors.count}${nonFormattingRuleSuffix}`,\n `- Autofix preview: ${analysis.autofixPreview.changedFileCount} files, ` +\n `about ${analysis.autofixPreview.estimatedChangedLines} changed lines`,\n `- Findings remaining after preview: ${analysis.autofixPreview.remainingErrors} errors, ` +\n `${analysis.autofixPreview.remainingWarnings} warnings`,\n `- Fixable rules still remaining: ${remainingFixableRules}`,\n ...typescriptLines\n ]\n}\n\nconst formatCompatibilityGuidance = (\n compatibilityFile: null | string\n): string[] => {\n if (compatibilityFile) {\n return [\n '',\n `Compatibility override written to ${compatibilityFile}. Import it after the preset config.`,\n 'It preserves the current effective configuration, not existing source violations.'\n ]\n }\n\n return [\n '',\n 'Pass --compatibility to write a temporary override that disables newly enabled rules.',\n 'Compatibility output preserves effective configuration, not current source behavior.'\n ]\n}\n\nexport const createPresetReport = async (\n cwd: string,\n presetName: string,\n file = 'eslint.config.js',\n options: CreatePresetReportOptions = {}\n) => {\n const normalizedPreset = presetName.toLowerCase()\n\n if (!PRESETS.has(normalizedPreset)) {\n throw new Error(\n `Unknown preset \"${presetName}\". Use one of: ${[...PRESETS].sort().join(', ')}.`\n )\n }\n\n const preset = normalizedPreset as Preset\n const presetOptions = resolvePreset(preset)\n const current = await loadProjectEslint(cwd).calculateConfigForFile(file)\n const currentMetadata = await loadDefineConfigMetadata(cwd)\n const currentOptions = currentMetadata?.options ?? {}\n\n const targetOptions = {\n ...presetOptions,\n ...currentOptions,\n features: {\n ...presetOptions.features,\n ...currentOptions.features\n },\n frameworks: {\n ...presetOptions.frameworks,\n ...currentOptions.frameworks\n },\n preset,\n root: currentOptions.root ?? cwd\n }\n\n const { missingPackages, options: resolvablePresetOptions } = getResolvablePresetOptions(cwd, targetOptions)\n\n if (!current) {\n throw new Error(`ESLint did not calculate a current configuration for ${file}. Check that the file is not ignored.`)\n }\n\n const selectedConfig = await defineConfig(\n resolvablePresetOptions,\n ...(currentMetadata?.extraConfigs ?? [])\n )\n\n const selected = await loadProjectEslint(cwd, selectedConfig).calculateConfigForFile(file)\n\n if (!selected) {\n throw new Error(`The ${normalizedPreset} preset did not produce a configuration for ${file}.`)\n }\n\n const currentRules = current.rules ?? {}\n const selectedRules = selected.rules ?? {}\n const added: Record<string, unknown> = {}\n const changed: Record<string, { from: unknown, to: unknown }> = {}\n const removed: Record<string, unknown> = {}\n\n for (const [rule, value] of Object.entries(selectedRules)) {\n const currentValue = currentRules[rule]\n\n if (isEnabled(value) && !isEnabled(currentValue)) {\n added[rule] = value\n } else if (\n isEnabled(value) &&\n isEnabled(currentValue) &&\n normalizeRule(value) !== normalizeRule(currentValue)\n ) {\n changed[rule] = { from: currentValue, to: value }\n }\n }\n\n for (const [rule, value] of Object.entries(currentRules)) {\n if (isEnabled(value) && !isEnabled(selectedRules[rule])) removed[rule] = value\n }\n\n const groups = Object.fromEntries(\n ['formatting', 'correctness', 'security', 'framework', 'domain'].map(group => [\n group,\n Object.keys(added).filter(rule => getRuleGroup(rule) === group).sort()\n ])\n )\n\n const sourceAnalysis = options.analyzeSource ?\n await analyzePresetSource(\n cwd,\n selectedConfig,\n options.sourceFiles ?? [],\n Object.keys(resolvablePresetOptions.projects ?? {}),\n options.typescriptRunner ?? defaultCommandRunner\n ) :\n null\n\n return {\n added,\n changed,\n compatibilityScope: 'effective-config',\n file,\n groups,\n missingPackages,\n preset: normalizedPreset,\n presetOptions,\n removed,\n sourceAnalysis,\n totals: {\n added: Object.keys(added).length,\n changed: Object.keys(changed).length,\n removed: Object.keys(removed).length\n }\n }\n}\n\nexport const handleExplainPreset = async (\n cwd: string = process.cwd(),\n preset: string,\n options: ExplainPresetOptions = {}\n): Promise<void> => {\n const report = await createPresetReport(cwd, preset, options.file, {\n analyzeSource: options.analyzeSource,\n sourceFiles: options.files\n })\n\n let compatibilityFile: null | string = null\n\n if (options.compatibility) {\n const output = options.output ?? `.eslint-preset-${report.preset}-compat.mjs`\n const outputPath = join(cwd, output)\n\n if (existsSync(outputPath)) {\n throw new Error(`${output} already exists; remove it or choose another path with --output.`)\n }\n\n writeFileSync(outputPath, createCompatibilityConfig(report.preset, report.added, report.changed))\n\n compatibilityFile = relative(cwd, outputPath)\n }\n\n const payload = { ...report, compatibilityFile }\n\n if (options.json) {\n console.log(JSON.stringify(payload, null, 2))\n\n return\n }\n\n console.log([\n `Preset adoption report: ${report.preset}`,\n `- Representative file: ${report.file}`,\n '- Config comparison: effective rules and options',\n `- Newly enabled rules: ${report.totals.added}`,\n `- Changed rule options: ${report.totals.changed}`,\n `- Rules no longer enabled: ${report.totals.removed}`,\n `- Optional packs not installed (excluded from comparison): ${report.missingPackages.length > 0 ? report.missingPackages.join(', ') : 'none'}`,\n '',\n ...Object.entries(report.groups).map(([group, rules]) => (\n `- ${group}: ${rules.length}${rules.length > 0 ? ` (${rules.join(', ')})` : ''}`\n )),\n ...formatSourceAnalysis(report.sourceAnalysis),\n ...formatCompatibilityGuidance(compatibilityFile)\n ].join('\\n'))\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/cli-preset.ts"],"sourcesContent":["/* eslint-disable no-console -- CLI handlers own user-facing terminal output */\n/* eslint-disable complexity -- report comparison and formatting intentionally cover multiple result branches */\nimport { existsSync, readFileSync, writeFileSync } from 'node:fs'\nimport { createRequire, findPackageJSON } from 'node:module'\nimport { dirname, extname, join, relative } from 'node:path'\nimport { pathToFileURL } from 'node:url'\n\nimport {\n type DetectedFrameworkName,\n detectProjectOptions,\n type EslintConfigOptions,\n Preset\n} from '@santi020k/eslint-config-core'\n\nimport { type CommandRunner, defaultCommandRunner } from './cli-workflows.js'\nimport { type DefineConfigMetadata, getDefineConfigMetadata } from './define-config-metadata.js'\nimport { defineConfig } from './index.js'\nimport { isMissingRequestedPackage } from './optional-package-errors.js'\nimport { resolvePreset } from './resolvers.js'\n\ninterface EffectiveConfig {\n rules?: Partial<Record<string, unknown>>\n}\n\ninterface ProjectLintMessage {\n fatal?: boolean\n fix?: unknown\n ruleId: null | string\n severity: number\n}\n\ninterface ProjectRuleMetadata {\n fixable?: 'code' | 'whitespace'\n type?: 'layout' | 'problem' | 'suggestion'\n}\n\ninterface ProjectLintResult {\n errorCount: number\n filePath: string\n messages: ProjectLintMessage[]\n output?: string\n warningCount: number\n}\n\ninterface ProjectEslint {\n calculateConfigForFile: (filePath: string) => Promise<EffectiveConfig | null>\n getRulesMetaForResults: (results: ProjectLintResult[]) => Record<string, ProjectRuleMetadata | undefined>\n lintFiles: (patterns: string[]) => Promise<ProjectLintResult[]>\n}\n\ntype ProjectEslintConstructor = new(options: {\n cwd: string\n fix?: boolean | ((message: ProjectLintMessage) => boolean)\n overrideConfig?: unknown\n overrideConfigFile?: boolean\n}) => ProjectEslint\n\nexport interface ExplainPresetOptions {\n analyzeSource?: boolean\n compatibility?: boolean\n file?: string\n files?: string[]\n json?: boolean\n output?: string\n semanticOnly?: boolean\n write?: boolean\n}\n\ninterface CreatePresetReportOptions {\n analyzeSource?: boolean\n semanticOnly?: boolean\n sourceFiles?: string[]\n typescriptRunner?: CommandRunner\n write?: boolean\n}\n\nconst PRESETS = new Set<string>(Object.values(Preset))\n\nconst 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 loadDefineConfigMetadata = async (cwd: string): Promise<DefineConfigMetadata | undefined> => {\n const configPath = CONFIG_FILENAMES.map(name => join(cwd, name)).find(path => existsSync(path))\n\n if (!configPath) return undefined\n\n try {\n const loaded = await import(`${pathToFileURL(configPath).href}?basic-eslint-preset=${Date.now()}`) as {\n default?: unknown\n }\n\n return getDefineConfigMetadata(await loaded.default)\n } catch {\n return undefined\n }\n}\n\nconst PRESET_FEATURE_PACKAGES = {\n extensions: '@santi020k/eslint-config-extensions',\n formats: '@santi020k/eslint-config-formats',\n libraries: '@santi020k/eslint-config-libraries',\n testing: '@santi020k/eslint-config-testing',\n tools: '@santi020k/eslint-config-tools'\n} as const\n\nconst FRAMEWORK_PACKAGES: Record<DetectedFrameworkName, string> = {\n angular: '@santi020k/eslint-config-angular',\n astro: '@santi020k/eslint-config-astro',\n expo: '@santi020k/eslint-config-expo',\n hono: '@santi020k/eslint-config-hono',\n lit: '@santi020k/eslint-config-lit',\n nest: '@santi020k/eslint-config-nest',\n next: '@santi020k/eslint-config-next',\n nuxt: '@santi020k/eslint-config-nuxt',\n preact: '@santi020k/eslint-config-preact',\n qwik: '@santi020k/eslint-config-qwik',\n react: '@santi020k/eslint-config-react',\n 'react-router': '@santi020k/eslint-config-react-router',\n slidev: '@santi020k/eslint-config-slidev',\n solid: '@santi020k/eslint-config-solid',\n svelte: '@santi020k/eslint-config-svelte',\n 'tanstack-start': '@santi020k/eslint-config-tanstack-start',\n vite: '@santi020k/eslint-config-vite',\n vue: '@santi020k/eslint-config-vue'\n}\n\nconst FRAMEWORK_PREFIXES = new Set([\n '@angular-eslint',\n '@eslint-react',\n '@next/next',\n 'astro',\n 'lit',\n 'qwik',\n 'react',\n 'react-hooks',\n 'react-refresh',\n 'solid',\n 'svelte',\n 'vue'\n])\n\nconst DOMAIN_PREFIXES = new Set([\n 'better-tailwindcss',\n 'drizzle',\n 'graphql-eslint',\n 'i18next',\n 'prisma',\n 'storybook',\n 'tailwindcss',\n 'tanstack-query',\n 'turbo',\n 'zod'\n])\n\nconst FORMAT_PREFIXES = new Set([\n '@stylistic',\n 'css',\n 'html',\n 'jsonc',\n 'markdown',\n 'mdx',\n 'perfectionist',\n 'prettier',\n 'toml',\n 'yaml'\n])\n\nconst FORMAT_RULES = new Set([\n 'import/first',\n 'sort-imports',\n 'simple-import-sort/exports',\n 'simple-import-sort/imports'\n])\n\nconst MULTI_SEGMENT_RULE_PREFIXES = new Set(['@next/next'])\n\nconst getRulePrefix = (rule: string): string => {\n const segments = rule.split('/')\n\n if (!rule.startsWith('@')) return segments[0]\n\n const multiSegmentPrefix = segments.slice(0, 2).join('/')\n\n return MULTI_SEGMENT_RULE_PREFIXES.has(multiSegmentPrefix) ? multiSegmentPrefix : segments[0]\n}\n\nconst getRuleGroup = (rule: string): 'correctness' | 'domain' | 'formatting' | 'framework' | 'security' => {\n const prefix = getRulePrefix(rule)\n\n if (\n prefix === 'security' ||\n prefix === 'no-secrets' ||\n rule.includes('security') ||\n rule.includes('no-unsanitized')\n ) return 'security'\n\n if (FRAMEWORK_PREFIXES.has(prefix)) return 'framework'\n\n if (DOMAIN_PREFIXES.has(prefix)) return 'domain'\n\n if (\n FORMAT_PREFIXES.has(prefix) ||\n FORMAT_RULES.has(rule) ||\n rule.includes('format') ||\n rule.includes('spacing')\n ) return 'formatting'\n\n return 'correctness'\n}\n\nconst getSeverity = (value: unknown): unknown => Array.isArray(value) ? value[0] : value\n\nconst isEnabled = (value: unknown): boolean => {\n const severity = getSeverity(value)\n\n return severity !== 0 && severity !== 'off' && severity !== undefined\n}\n\nconst normalizeRule = (value: unknown): string => JSON.stringify(value)\n\nconst loadProjectEslint = (\n cwd: string,\n overrideConfig?: unknown,\n fix: boolean | ((message: ProjectLintMessage) => boolean) = false\n): ProjectEslint => {\n const projectRequire = createRequire(join(cwd, 'package.json'))\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({\n cwd,\n ...(fix ? { fix } : {}),\n ...(overrideConfig ? { overrideConfig, overrideConfigFile: true } : {})\n })\n}\n\nconst getResolvablePresetOptions = (\n cwd: string,\n presetOptions: Partial<EslintConfigOptions>\n): { missingPackages: string[], options: Partial<EslintConfigOptions> } => {\n const projectPackageUrl = pathToFileURL(join(cwd, 'package.json'))\n const options = { ...presetOptions }\n const detectedOptions = detectProjectOptions(cwd)\n const missingPackages = new Set<string>()\n const detection = options.detection\n const detectionControls = typeof detection === 'object' ? detection : {}\n\n const detectionEnabled = (category: keyof typeof PRESET_FEATURE_PACKAGES): boolean => (\n detection !== false && detectionControls[category] !== false\n )\n\n for (const [category, specifier] of Object.entries(PRESET_FEATURE_PACKAGES)) {\n const categoryKey = category as keyof typeof PRESET_FEATURE_PACKAGES\n const explicit = options[categoryKey]\n const detected = detectionEnabled(categoryKey) ? detectedOptions[categoryKey] : []\n\n const selected = [...new Set([\n ...(Array.isArray(explicit) ? explicit : []),\n ...(Array.isArray(detected) ? detected : [])\n ])]\n\n if (selected.length === 0) continue\n\n try {\n findPackageJSON(specifier, projectPackageUrl)\n } catch (error) {\n if (!isMissingRequestedPackage(error, specifier)) throw error\n\n Object.assign(options, {\n [category]: [],\n detection: {\n ...(typeof options.detection === 'object' ? options.detection : detectionControls),\n [category]: false\n },\n features: {\n ...options.features,\n ...Object.fromEntries(selected.map(feature => [feature, false]))\n }\n })\n\n missingPackages.add(specifier)\n }\n }\n\n const frameworkDetectionEnabled = detection !== false && detectionControls.frameworks !== false\n const detectedFrameworks = frameworkDetectionEnabled ? detectedOptions.detectedFrameworks ?? [] : []\n\n const configuredFrameworks = Object.entries(options.frameworks ?? {})\n .filter((entry): entry is [DetectedFrameworkName, true] => entry[1] === true)\n .map(([framework]) => framework)\n\n const selectedFrameworks = [...new Set([...detectedFrameworks, ...configuredFrameworks])]\n\n const resolvableFrameworks: NonNullable<EslintConfigOptions['frameworks']> = {\n ...options.frameworks\n }\n\n for (const framework of selectedFrameworks) {\n const specifier = FRAMEWORK_PACKAGES[framework]\n\n try {\n findPackageJSON(specifier, projectPackageUrl)\n\n resolvableFrameworks[framework] = true\n } catch (error) {\n if (!isMissingRequestedPackage(error, specifier)) throw error\n\n Reflect.deleteProperty(resolvableFrameworks, framework)\n\n missingPackages.add(specifier)\n }\n }\n\n if (!resolvableFrameworks.react) {\n delete resolvableFrameworks.expo\n\n delete resolvableFrameworks.next\n\n delete resolvableFrameworks['react-router']\n\n if (!resolvableFrameworks.solid) delete resolvableFrameworks['tanstack-start']\n }\n\n if (!resolvableFrameworks.vue) {\n delete resolvableFrameworks.nuxt\n\n delete resolvableFrameworks.slidev\n }\n\n if (selectedFrameworks.length > 0) {\n options.autoFrameworks = false\n\n options.frameworks = resolvableFrameworks\n }\n\n return { missingPackages: [...missingPackages], options }\n}\n\nconst createCompatibilityConfig = (\n preset: string,\n addedRules: Record<string, unknown>,\n changedRules: Record<string, { from: unknown, to: unknown }>\n): string => [\n `// Temporary compatibility override generated for Preset.${preset.charAt(0).toUpperCase()}${preset.slice(1)}.`,\n '// Remove entries as the project adopts the preset findings.',\n 'export default {',\n ` name: 'eslint-config-basic/preset-${preset}-compatibility',`,\n ' rules: {',\n ...Object.keys(addedRules).sort().map(rule => ` ${JSON.stringify(rule)}: 'off',`),\n ...Object.keys(changedRules).sort().map(rule => (\n ` ${JSON.stringify(rule)}: ${JSON.stringify(changedRules[rule].from)},`\n )),\n ' },',\n '}',\n ''\n].join('\\n')\n\ninterface FindingSummary {\n errors: number\n fixable: number\n total: number\n warnings: number\n}\n\nconst createFindingSummary = (): FindingSummary => ({\n errors: 0,\n fixable: 0,\n total: 0,\n warnings: 0\n})\n\nconst addFinding = (\n summaries: Record<string, FindingSummary>,\n key: string,\n message: ProjectLintMessage\n): void => {\n const summary = summaries[key] ?? createFindingSummary()\n\n summary.total++\n\n if (message.severity === 2) summary.errors++\n else summary.warnings++\n\n if (message.fix !== undefined) summary.fixable++\n\n summaries[key] = summary\n}\n\nconst estimateChangedLines = (before: string, after: string): number => {\n const beforeLines = before.split('\\n')\n const afterLines = after.split('\\n')\n const comparableLines = Math.min(beforeLines.length, afterLines.length)\n let changed = Math.abs(beforeLines.length - afterLines.length)\n\n for (let index = 0; index < comparableLines; index++) {\n if (beforeLines[index] !== afterLines[index]) changed++\n }\n\n return changed\n}\n\nconst readOriginalSource = (filePath: string): string | undefined => {\n try {\n return readFileSync(filePath, 'utf8')\n } catch {\n return undefined\n }\n}\n\ninterface SourceFormatParserCandidate {\n file: string\n lines: number[]\n}\n\nconst SOURCE_FILE_READ_PATTERN = /\\b(?:Bun\\.file|Deno\\.readTextFile|readFile|readFileSync|readTextFile)\\b/\n\nconst SOURCE_REGEXP_PATTERN = new RegExp([\n String.raw`\\.match(?:All)?\\s*\\(`,\n String.raw`\\.replace(?:All)?\\s*\\(`,\n String.raw`\\.search\\s*\\(`,\n String.raw`\\bRegExp\\s*\\(`,\n String.raw`\\.(?:exec|test)\\s*\\(`\n].join('|'))\n\nconst findSourceFormatParserCandidates = (\n cwd: string,\n filePaths: string[]\n): SourceFormatParserCandidate[] => filePaths.flatMap(filePath => {\n const content = readOriginalSource(filePath)\n\n if (!content || !SOURCE_FILE_READ_PATTERN.test(content)) return []\n\n const lines = content.split('\\n')\n .flatMap((line, index) => SOURCE_REGEXP_PATTERN.test(line) ? [index + 1] : [])\n\n return lines.length > 0 ? [{ file: relative(cwd, filePath), lines }] : []\n})\n\nconst TYPESCRIPT_CONFIG_FILENAMES = [\n 'tsconfig.json',\n 'tsconfig.base.json',\n 'tsconfig.app.json',\n 'tsconfig.node.json',\n 'tsconfig.eslint.json'\n]\n\nconst TYPESCRIPT_ROOT_DIAGNOSTIC_CODES = new Set([\n 'TS2307',\n 'TS2688',\n 'TS2792',\n 'TS6053'\n])\n\nconst resolveTypeScriptCli = (cwd: string): null | string => {\n try {\n const projectRequire = createRequire(join(cwd, 'package.json'))\n const packagePath = projectRequire.resolve('typescript/package.json')\n\n const manifest = JSON.parse(readFileSync(packagePath, 'utf8')) as {\n bin?: Record<string, string> | string\n }\n\n const bin = typeof manifest.bin === 'string' ? manifest.bin : manifest.bin?.tsc\n\n return bin ? join(dirname(packagePath), bin) : null\n } catch {\n return null\n }\n}\n\nconst getTypeScriptConfigs = (\n cwd: string,\n configuredProjects: string[]\n): string[] => {\n const detectedProjects = Object.keys(detectProjectOptions(cwd).projects ?? {})\n const projectRoots = [...new Set([...detectedProjects, ...configuredProjects])]\n\n const roots = [\n cwd,\n ...projectRoots.map(project => join(cwd, project))\n ]\n\n return [...new Set(roots.flatMap(root => {\n const config = TYPESCRIPT_CONFIG_FILENAMES.find(file => existsSync(join(root, file)))\n\n return config ? [join(root, config)] : []\n }))]\n}\n\ninterface TypeScriptDiagnostic {\n code: string\n config: string\n message: string\n}\n\nconst parseTypeScriptDiagnostics = (\n cwd: string,\n config: string,\n output: string\n): TypeScriptDiagnostic[] => output\n .split(/\\r?\\n/)\n .flatMap(line => {\n const match = /\\berror (TS\\d+):\\s*(.+)$/.exec(line)\n\n if (!match) return []\n\n return [{\n code: match[1],\n config: relative(cwd, config),\n message: match[2]\n }]\n })\n\nexport const createTypeScriptPreflight = (\n cwd: string,\n configuredProjects: string[] = [],\n runner: CommandRunner = defaultCommandRunner\n) => {\n const executable = resolveTypeScriptCli(cwd)\n const configs = getTypeScriptConfigs(cwd, configuredProjects)\n\n if (!executable || configs.length === 0) {\n return {\n configs: [],\n diagnosticCount: 0,\n rootDiagnostics: [] as TypeScriptDiagnostic[],\n status: 'skipped' as const\n }\n }\n\n const diagnostics: TypeScriptDiagnostic[] = []\n\n const results = configs.map(config => {\n const result = runner(process.execPath, [\n executable,\n '--noEmit',\n '--pretty',\n 'false',\n '--project',\n config\n ], cwd)\n\n diagnostics.push(...parseTypeScriptDiagnostics(\n cwd,\n config,\n `${result.stdout}\\n${result.stderr}`\n ))\n\n return {\n config: relative(cwd, config),\n status: result.status\n }\n })\n\n const rootDiagnostics = diagnostics.filter(\n diagnostic => TYPESCRIPT_ROOT_DIAGNOSTIC_CODES.has(diagnostic.code)\n )\n\n return {\n configs: results,\n diagnosticCount: diagnostics.length,\n rootDiagnostics: (rootDiagnostics.length > 0 ? rootDiagnostics : diagnostics).slice(0, 20),\n status: results.some(result => result.status !== 0) ? 'failed' as const : 'passed' as const\n }\n}\n\nconst analyzePresetSource = async (\n cwd: string,\n selectedConfig: unknown,\n sourceFiles: string[],\n configuredProjects: string[],\n typescriptRunner: CommandRunner,\n semanticOnly = false,\n write = false\n) => {\n const lintTargets = sourceFiles.length > 0 ? sourceFiles : ['.']\n const analysisEslint = loadProjectEslint(cwd, selectedConfig)\n const lintResults = await analysisEslint.lintFiles(lintTargets)\n const rulesMeta = analysisEslint.getRulesMetaForResults(lintResults)\n\n const fix = semanticOnly ?\n (message: ProjectLintMessage): boolean => {\n if (message.ruleId === null) return false\n\n const metadata = rulesMeta[message.ruleId]\n\n if (metadata?.type === 'layout' || metadata?.fixable === 'whitespace') return false\n\n return getRuleGroup(message.ruleId) !== 'formatting'\n } :\n true\n\n const previewResults = await loadProjectEslint(cwd, selectedConfig, fix).lintFiles(lintTargets)\n const byCategory: Record<string, FindingSummary> = {}\n const byFileType: Record<string, FindingSummary> = {}\n const byRule: Record<string, FindingSummary> = {}\n const nonFormattingErrorRules = new Set<string>()\n let nonFormattingErrors = 0\n\n for (const result of lintResults) {\n const fileType = extname(result.filePath) || '[no extension]'\n\n for (const message of result.messages) {\n const rule = message.ruleId ?? (message.fatal ? '[fatal]' : '[unknown]')\n const category = message.ruleId ? getRuleGroup(message.ruleId) : 'correctness'\n\n addFinding(byCategory, category, message)\n\n addFinding(byFileType, fileType, message)\n\n addFinding(byRule, rule, message)\n\n if (message.severity === 2 && category !== 'formatting') {\n nonFormattingErrors++\n\n nonFormattingErrorRules.add(rule)\n }\n }\n }\n\n const changedFiles: string[] = []\n const remainingFixableRules = new Set<string>()\n let estimatedChangedLines = 0\n let remainingErrors = 0\n let remainingWarnings = 0\n let writtenFileCount = 0\n\n for (const result of previewResults) {\n remainingErrors += result.errorCount\n\n remainingWarnings += result.warningCount\n\n for (const message of result.messages) {\n if (message.fix !== undefined) remainingFixableRules.add(message.ruleId ?? '[fatal]')\n }\n\n if (result.output === undefined) continue\n\n changedFiles.push(relative(cwd, result.filePath))\n\n const original = readOriginalSource(result.filePath)\n\n if (original !== undefined) estimatedChangedLines += estimateChangedLines(original, result.output)\n\n if (write) {\n writeFileSync(result.filePath, result.output)\n\n writtenFileCount++\n }\n }\n\n return {\n autofixPreview: {\n changedFileCount: changedFiles.length,\n changedFiles: changedFiles.sort(),\n estimatedChangedLines,\n remainingErrors,\n remainingFixableRules: [...remainingFixableRules].sort(),\n remainingWarnings,\n scope: semanticOnly ? 'semantic' as const : 'all' as const,\n writtenFileCount\n },\n byCategory,\n byFileType,\n byRule,\n lintTargets,\n nonFormattingErrors: {\n count: nonFormattingErrors,\n rules: [...nonFormattingErrorRules].sort()\n },\n sourceFormatParserCandidates: findSourceFormatParserCandidates(\n cwd,\n [...new Set(lintResults.map(result => result.filePath))]\n ),\n typescriptPreflight: createTypeScriptPreflight(cwd, configuredProjects, typescriptRunner),\n totals: {\n errors: lintResults.reduce((total, result) => total + result.errorCount, 0),\n files: lintResults.length,\n findings: lintResults.reduce(\n (total, result) => total + result.errorCount + result.warningCount,\n 0\n ),\n warnings: lintResults.reduce((total, result) => total + result.warningCount, 0)\n }\n }\n}\n\ntype PresetSourceAnalysis = Awaited<ReturnType<typeof analyzePresetSource>>\n\nconst formatSourceAnalysis = (\n analysis: null | PresetSourceAnalysis\n): string[] => {\n if (!analysis) {\n return [\n '',\n 'Pass --analyze-source to lint with the selected preset and preview autofix without writing files.'\n ]\n }\n\n const nonFormattingRuleSuffix = analysis.nonFormattingErrors.rules.length > 0 ?\n ` (${analysis.nonFormattingErrors.rules.join(', ')})` :\n ''\n\n const remainingFixableRules = analysis.autofixPreview.remainingFixableRules.length > 0 ?\n analysis.autofixPreview.remainingFixableRules.join(', ') :\n 'none'\n\n const parserCandidates = analysis.sourceFormatParserCandidates.length > 0 ?\n analysis.sourceFormatParserCandidates.map(candidate => (\n ` - ${candidate.file}:${candidate.lines.join(',')}`\n )) :\n [' - none']\n\n const previewLabel = analysis.autofixPreview.scope === 'semantic' ? 'Semantic autofix' : 'Autofix'\n\n const typescriptLines = analysis.typescriptPreflight.status === 'failed' ?\n [\n `- TypeScript preflight: failed with ${analysis.typescriptPreflight.diagnosticCount} diagnostics`,\n ...analysis.typescriptPreflight.rootDiagnostics.map(diagnostic => (\n ` - ${diagnostic.config} ${diagnostic.code}: ${diagnostic.message}`\n )),\n '- Fix TypeScript compiler errors before reviewing cascading type-aware unsafe-rule findings.'\n ] :\n [\n `- TypeScript preflight: ${analysis.typescriptPreflight.status}` +\n (analysis.typescriptPreflight.status === 'passed' ?\n ` (${analysis.typescriptPreflight.configs.length} configs)` :\n ' (TypeScript or a supported tsconfig was not found)')\n ]\n\n return [\n '',\n `Source analysis (selected preset, ${analysis.autofixPreview.writtenFileCount > 0 ?\n `${analysis.autofixPreview.writtenFileCount} files written` :\n 'no files written'}):`,\n `- Lint targets: ${analysis.lintTargets.join(', ')}`,\n `- Files analyzed: ${analysis.totals.files}`,\n `- Findings: ${analysis.totals.findings} ` +\n `(${analysis.totals.errors} errors, ${analysis.totals.warnings} warnings)`,\n `- Non-formatting errors to resolve first: ${analysis.nonFormattingErrors.count}${nonFormattingRuleSuffix}`,\n `- ${previewLabel} preview: ${analysis.autofixPreview.changedFileCount} files, ` +\n `about ${analysis.autofixPreview.estimatedChangedLines} changed lines`,\n `- Findings remaining after preview: ${analysis.autofixPreview.remainingErrors} errors, ` +\n `${analysis.autofixPreview.remainingWarnings} warnings`,\n `- Fixable rules still remaining: ${remainingFixableRules}`,\n '- Formatting-sensitive source-parser candidates:',\n ...parserCandidates,\n ...typescriptLines\n ]\n}\n\nconst formatCompatibilityGuidance = (\n compatibilityFile: null | string\n): string[] => {\n if (compatibilityFile) {\n return [\n '',\n `Compatibility override written to ${compatibilityFile}. Import it after the preset config.`,\n 'It preserves the current effective configuration, not existing source violations.'\n ]\n }\n\n return [\n '',\n 'Pass --compatibility to write a temporary override that disables newly enabled rules.',\n 'Compatibility output preserves effective configuration, not current source behavior.'\n ]\n}\n\nexport const createPresetReport = async (\n cwd: string,\n presetName: string,\n file = 'eslint.config.js',\n options: CreatePresetReportOptions = {}\n) => {\n if (options.write && !options.semanticOnly) {\n throw new Error('Writing preset fixes requires semanticOnly to avoid an unchecked formatting rewrite.')\n }\n\n const normalizedPreset = presetName.toLowerCase()\n\n if (!PRESETS.has(normalizedPreset)) {\n throw new Error(\n `Unknown preset \"${presetName}\". Use one of: ${[...PRESETS].sort().join(', ')}.`\n )\n }\n\n const preset = normalizedPreset as Preset\n const presetOptions = resolvePreset(preset)\n const current = await loadProjectEslint(cwd).calculateConfigForFile(file)\n const currentMetadata = await loadDefineConfigMetadata(cwd)\n const currentOptions = currentMetadata?.options ?? {}\n\n const targetOptions = {\n ...presetOptions,\n ...currentOptions,\n features: {\n ...presetOptions.features,\n ...currentOptions.features\n },\n frameworks: {\n ...presetOptions.frameworks,\n ...currentOptions.frameworks\n },\n preset,\n root: currentOptions.root ?? cwd\n }\n\n const { missingPackages, options: resolvablePresetOptions } = getResolvablePresetOptions(cwd, targetOptions)\n\n if (!current) {\n throw new Error(`ESLint did not calculate a current configuration for ${file}. Check that the file is not ignored.`)\n }\n\n const selectedConfig = await defineConfig(\n resolvablePresetOptions,\n ...(currentMetadata?.extraConfigs ?? [])\n )\n\n const selected = await loadProjectEslint(cwd, selectedConfig).calculateConfigForFile(file)\n\n if (!selected) {\n throw new Error(`The ${normalizedPreset} preset did not produce a configuration for ${file}.`)\n }\n\n const currentRules = current.rules ?? {}\n const selectedRules = selected.rules ?? {}\n const added: Record<string, unknown> = {}\n const changed: Record<string, { from: unknown, to: unknown }> = {}\n const removed: Record<string, unknown> = {}\n\n for (const [rule, value] of Object.entries(selectedRules)) {\n const currentValue = currentRules[rule]\n\n if (isEnabled(value) && !isEnabled(currentValue)) {\n added[rule] = value\n } else if (\n isEnabled(value) &&\n isEnabled(currentValue) &&\n normalizeRule(value) !== normalizeRule(currentValue)\n ) {\n changed[rule] = { from: currentValue, to: value }\n }\n }\n\n for (const [rule, value] of Object.entries(currentRules)) {\n if (isEnabled(value) && !isEnabled(selectedRules[rule])) removed[rule] = value\n }\n\n const groups = Object.fromEntries(\n ['formatting', 'correctness', 'security', 'framework', 'domain'].map(group => [\n group,\n Object.keys(added).filter(rule => getRuleGroup(rule) === group).sort()\n ])\n )\n\n const sourceAnalysis = options.analyzeSource ?\n await analyzePresetSource(\n cwd,\n selectedConfig,\n options.sourceFiles ?? [],\n Object.keys(resolvablePresetOptions.projects ?? {}),\n options.typescriptRunner ?? defaultCommandRunner,\n options.semanticOnly,\n options.write\n ) :\n null\n\n return {\n added,\n changed,\n compatibilityScope: 'effective-config',\n file,\n groups,\n missingPackages,\n preset: normalizedPreset,\n presetOptions,\n removed,\n sourceAnalysis,\n totals: {\n added: Object.keys(added).length,\n changed: Object.keys(changed).length,\n removed: Object.keys(removed).length\n }\n }\n}\n\nexport const handleExplainPreset = async (\n cwd: string = process.cwd(),\n preset: string,\n options: ExplainPresetOptions = {}\n): Promise<void> => {\n if (options.write && !options.semanticOnly) {\n throw new Error('explain-preset --write requires --semantic-only to avoid an unchecked formatting rewrite.')\n }\n\n if (options.semanticOnly && !options.analyzeSource) {\n throw new Error('explain-preset --semantic-only requires --analyze-source.')\n }\n\n const report = await createPresetReport(cwd, preset, options.file, {\n analyzeSource: options.analyzeSource,\n semanticOnly: options.semanticOnly,\n sourceFiles: options.files,\n write: options.write\n })\n\n let compatibilityFile: null | string = null\n\n if (options.compatibility) {\n const output = options.output ?? `.eslint-preset-${report.preset}-compat.mjs`\n const outputPath = join(cwd, output)\n\n if (existsSync(outputPath)) {\n throw new Error(`${output} already exists; remove it or choose another path with --output.`)\n }\n\n writeFileSync(outputPath, createCompatibilityConfig(report.preset, report.added, report.changed))\n\n compatibilityFile = relative(cwd, outputPath)\n }\n\n const payload = { ...report, compatibilityFile }\n\n if (options.json) {\n console.log(JSON.stringify(payload, null, 2))\n\n return\n }\n\n console.log([\n `Preset adoption report: ${report.preset}`,\n `- Representative file: ${report.file}`,\n '- Config comparison: effective rules and options',\n `- Newly enabled rules: ${report.totals.added}`,\n `- Changed rule options: ${report.totals.changed}`,\n `- Rules no longer enabled: ${report.totals.removed}`,\n `- Optional packs not installed (excluded from comparison): ${report.missingPackages.length > 0 ? report.missingPackages.join(', ') : 'none'}`,\n '',\n ...Object.entries(report.groups).map(([group, rules]) => (\n `- ${group}: ${rules.length}${rules.length > 0 ? ` (${rules.join(', ')})` : ''}`\n )),\n ...formatSourceAnalysis(report.sourceAnalysis),\n ...formatCompatibilityGuidance(compatibilityFile)\n ].join('\\n'))\n}\n"],"mappings":"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","names":[]}
@@ -21,8 +21,25 @@ interface SnapshotOptions {
21
21
  check?: boolean;
22
22
  files?: string[];
23
23
  json?: boolean;
24
+ rulesOnly?: boolean;
24
25
  snapshotPath?: string;
25
26
  }
27
+ interface ConfigTypesOptions {
28
+ files?: string[];
29
+ json?: boolean;
30
+ }
31
+ interface ConfigTypeFileResult {
32
+ declarations: string[];
33
+ file: string;
34
+ issues: string[];
35
+ portable: boolean;
36
+ tsconfig: null | string;
37
+ }
38
+ interface ConfigTypesReport {
39
+ files: ConfigTypeFileResult[];
40
+ portable: boolean;
41
+ typescriptVersion: string;
42
+ }
26
43
  interface SnapshotDiff {
27
44
  added: string[];
28
45
  changed: {
@@ -44,20 +61,23 @@ interface EslintSnapshotFile {
44
61
  }
45
62
  interface EslintSnapshot {
46
63
  files: Record<string, EslintSnapshotFile>;
47
- version: 1;
64
+ scope?: 'rules';
65
+ version: 1 | 2;
48
66
  }
49
67
  interface ProjectEslint {
50
68
  calculateConfigForFile: (filePath: string) => Promise<unknown>;
51
69
  isPathIgnored?: (filePath: string) => Promise<boolean>;
52
70
  }
53
71
  declare const defaultCommandRunner: CommandRunner;
72
+ declare const createConfigTypesReport: (cwd?: string, options?: ConfigTypesOptions) => ConfigTypesReport;
73
+ declare const handleConfigTypes: (cwd?: string, options?: ConfigTypesOptions) => void;
54
74
  declare const handleBaseline: (cwd?: string, options?: BaselineOptions, runner?: CommandRunner) => void;
55
75
  declare const handleProfile: (cwd?: string, options?: ProfileOptions, runner?: CommandRunner) => void;
56
76
  declare const findRepresentativeFiles: (cwd: string) => string[];
57
- declare const createConfigSnapshot: (cwd: string, files?: string[], eslint?: ProjectEslint) => Promise<EslintSnapshot>;
77
+ declare const createConfigSnapshot: (cwd: string, files?: string[], eslint?: ProjectEslint, scope?: "all" | "rules") => Promise<EslintSnapshot>;
58
78
  declare const diffConfigSnapshots: (previous: EslintSnapshot, current: EslintSnapshot) => SnapshotDiff[];
59
79
  declare const handleSnapshot: (cwd?: string, options?: SnapshotOptions, eslint?: ProjectEslint) => Promise<void>;
60
80
  declare const handleSnapshotDiff: (cwd?: string, options?: SnapshotOptions, eslint?: ProjectEslint) => Promise<void>;
61
81
  declare const isDirectory: (path: string) => boolean;
62
82
 
63
- export { type BaselineOptions, type CommandResult, type CommandRunner, type ProfileOptions, type SnapshotDiff, type SnapshotOptions, createConfigSnapshot, defaultCommandRunner, diffConfigSnapshots, findRepresentativeFiles, handleBaseline, handleProfile, handleSnapshot, handleSnapshotDiff, isDirectory };
83
+ export { type BaselineOptions, type CommandResult, type CommandRunner, type ConfigTypesOptions, type ProfileOptions, type SnapshotDiff, type SnapshotOptions, createConfigSnapshot, createConfigTypesReport, defaultCommandRunner, diffConfigSnapshots, findRepresentativeFiles, handleBaseline, handleConfigTypes, handleProfile, handleSnapshot, handleSnapshotDiff, isDirectory };