@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 CHANGED
@@ -1,5 +1,54 @@
1
1
  # @santi020k/eslint-config-basic
2
2
 
3
+ ## 3.5.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#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
8
+ Astro's supported `project` parser option. TypeScript parser setup no longer
9
+ forwards `projectService` into Astro source files, while Vue, Svelte, and
10
+ virtual TypeScript files retain their existing parser behavior.
11
+
12
+ Add `snapshot --rules-only` for compact committed rule contracts. Rules-only
13
+ snapshots record their scope so subsequent checks and diffs omit globals,
14
+ language options, and plugin metadata automatically.
15
+
16
+ Forward `--rules-only` through the public CLI dispatcher and add an end-to-end
17
+ regression for the saved scope. The option was previously accepted but only
18
+ direct handler calls received it.
19
+
20
+ Add `config-types` to emit ESLint config declarations in memory with the
21
+ consumer's TypeScript context and reject pnpm-internal or transitive
22
+ `typescript-eslint` types. The composite action exposes an opt-in portability
23
+ gate for consumer maintenance workflows.
24
+
25
+ Discover exact selectors from Astro component-local styles and narrow utility
26
+ patterns from explicitly configured Tailwind plugins. Doctor reports the
27
+ smallest project-scoped exception shape when dynamic classes still need an
28
+ allowance.
29
+
30
+ Add semantic-only preset adoption fixes and report scripts that combine source
31
+ file reads with regular-expression parsing. Writing is allowed only in the
32
+ semantic-only mode, keeping formatting churn in a separate review.
33
+
34
+ Run the CLI when pnpm invokes its direct `.bin/basic-eslint` symlink. Older
35
+ entrypoint guards could silently exit successfully because the executable path
36
+ did not end in `cli.js`.
37
+
38
+ ### Patch Changes
39
+
40
+ - Updated dependencies [[`498bb41`](https://github.com/santi020k/eslint-config-basic/commit/498bb418d077e57d3dc71c8441813d9b8a2545ca)]:
41
+ - @santi020k/eslint-config-typescript@3.1.3
42
+
43
+ ## 3.4.0
44
+
45
+ ### Minor Changes
46
+
47
+ - Keep TypeScript 6 declaration inference for JavaScript ESLint configs portable
48
+ under pnpm by returning a package-owned public config-array type. Annotate the
49
+ recommended entry point and verify packed consumers do not expose internal
50
+ `typescript-eslint` dependency paths or report TS2883.
51
+
3
52
  ## 3.3.0
4
53
 
5
54
  ### 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,16 @@ 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
+ "simple-import-sort/exports",
101
+ "simple-import-sort/imports"
102
+ ]);
97
103
  const MULTI_SEGMENT_RULE_PREFIXES = /* @__PURE__ */ new Set(["@next/next"]);
98
104
  const getRulePrefix = (rule) => {
99
105
  const segments = rule.split("/");
@@ -106,7 +112,7 @@ const getRuleGroup = (rule) => {
106
112
  if (prefix === "security" || prefix === "no-secrets" || rule.includes("security") || rule.includes("no-unsanitized")) return "security";
107
113
  if (FRAMEWORK_PREFIXES.has(prefix)) return "framework";
108
114
  if (DOMAIN_PREFIXES.has(prefix)) return "domain";
109
- if (FORMAT_PREFIXES.has(prefix) || rule.includes("format") || rule.includes("spacing")) return "formatting";
115
+ if (FORMAT_PREFIXES.has(prefix) || FORMAT_RULES.has(rule) || rule.includes("format") || rule.includes("spacing")) return "formatting";
110
116
  return "correctness";
111
117
  };
112
118
  const getSeverity = (value) => Array.isArray(value) ? value[0] : value;
@@ -121,7 +127,7 @@ const loadProjectEslint = (cwd, overrideConfig, fix = false) => {
121
127
  if (!eslintModule.ESLint) throw new Error("The installed eslint package does not expose the ESLint API.");
122
128
  return new eslintModule.ESLint({
123
129
  cwd,
124
- ...fix ? { fix: true } : {},
130
+ ...fix ? { fix } : {},
125
131
  ...overrideConfig ? { overrideConfig, overrideConfigFile: true } : {}
126
132
  });
127
133
  };
@@ -237,6 +243,20 @@ const readOriginalSource = (filePath) => {
237
243
  return void 0;
238
244
  }
239
245
  };
246
+ const SOURCE_FILE_READ_PATTERN = /\b(?:Bun\.file|Deno\.readTextFile|readFile|readFileSync|readTextFile)\b/;
247
+ const SOURCE_REGEXP_PATTERN = new RegExp([
248
+ String.raw`\.match(?:All)?\s*\(`,
249
+ String.raw`\.replace(?:All)?\s*\(`,
250
+ String.raw`\.search\s*\(`,
251
+ String.raw`\bRegExp\s*\(`,
252
+ String.raw`\.(?:exec|test)\s*\(`
253
+ ].join("|"));
254
+ const findSourceFormatParserCandidates = (cwd, filePaths) => filePaths.flatMap((filePath) => {
255
+ const content = readOriginalSource(filePath);
256
+ if (!content || !SOURCE_FILE_READ_PATTERN.test(content)) return [];
257
+ const lines = content.split("\n").flatMap((line, index) => SOURCE_REGEXP_PATTERN.test(line) ? [index + 1] : []);
258
+ return lines.length > 0 ? [{ file: relative(cwd, filePath), lines }] : [];
259
+ });
240
260
  const TYPESCRIPT_CONFIG_FILENAMES = [
241
261
  "tsconfig.json",
242
262
  "tsconfig.base.json",
@@ -324,10 +344,11 @@ ${result.stderr}`
324
344
  status: results.some((result) => result.status !== 0) ? "failed" : "passed"
325
345
  };
326
346
  };
327
- const analyzePresetSource = async (cwd, selectedConfig, sourceFiles, configuredProjects, typescriptRunner) => {
347
+ const analyzePresetSource = async (cwd, selectedConfig, sourceFiles, configuredProjects, typescriptRunner, semanticOnly = false, write = false) => {
328
348
  const lintTargets = sourceFiles.length > 0 ? sourceFiles : ["."];
329
349
  const lintResults = await loadProjectEslint(cwd, selectedConfig).lintFiles(lintTargets);
330
- const previewResults = await loadProjectEslint(cwd, selectedConfig, true).lintFiles(lintTargets);
350
+ const fix = semanticOnly ? (message) => message.ruleId === null || getRuleGroup(message.ruleId) !== "formatting" : true;
351
+ const previewResults = await loadProjectEslint(cwd, selectedConfig, fix).lintFiles(lintTargets);
331
352
  const byCategory = {};
332
353
  const byFileType = {};
333
354
  const byRule = {};
@@ -352,6 +373,7 @@ const analyzePresetSource = async (cwd, selectedConfig, sourceFiles, configuredP
352
373
  let estimatedChangedLines = 0;
353
374
  let remainingErrors = 0;
354
375
  let remainingWarnings = 0;
376
+ let writtenFileCount = 0;
355
377
  for (const result of previewResults) {
356
378
  remainingErrors += result.errorCount;
357
379
  remainingWarnings += result.warningCount;
@@ -362,6 +384,10 @@ const analyzePresetSource = async (cwd, selectedConfig, sourceFiles, configuredP
362
384
  changedFiles.push(relative(cwd, result.filePath));
363
385
  const original = readOriginalSource(result.filePath);
364
386
  if (original !== void 0) estimatedChangedLines += estimateChangedLines(original, result.output);
387
+ if (write) {
388
+ writeFileSync(result.filePath, result.output);
389
+ writtenFileCount++;
390
+ }
365
391
  }
366
392
  return {
367
393
  autofixPreview: {
@@ -370,7 +396,9 @@ const analyzePresetSource = async (cwd, selectedConfig, sourceFiles, configuredP
370
396
  estimatedChangedLines,
371
397
  remainingErrors,
372
398
  remainingFixableRules: [...remainingFixableRules].sort(),
373
- remainingWarnings
399
+ remainingWarnings,
400
+ scope: semanticOnly ? "semantic" : "all",
401
+ writtenFileCount
374
402
  },
375
403
  byCategory,
376
404
  byFileType,
@@ -380,6 +408,10 @@ const analyzePresetSource = async (cwd, selectedConfig, sourceFiles, configuredP
380
408
  count: nonFormattingErrors,
381
409
  rules: [...nonFormattingErrorRules].sort()
382
410
  },
411
+ sourceFormatParserCandidates: findSourceFormatParserCandidates(
412
+ cwd,
413
+ [...new Set(lintResults.map((result) => result.filePath))]
414
+ ),
383
415
  typescriptPreflight: createTypeScriptPreflight(cwd, configuredProjects, typescriptRunner),
384
416
  totals: {
385
417
  errors: lintResults.reduce((total, result) => total + result.errorCount, 0),
@@ -401,6 +433,8 @@ const formatSourceAnalysis = (analysis) => {
401
433
  }
402
434
  const nonFormattingRuleSuffix = analysis.nonFormattingErrors.rules.length > 0 ? ` (${analysis.nonFormattingErrors.rules.join(", ")})` : "";
403
435
  const remainingFixableRules = analysis.autofixPreview.remainingFixableRules.length > 0 ? analysis.autofixPreview.remainingFixableRules.join(", ") : "none";
436
+ const parserCandidates = analysis.sourceFormatParserCandidates.length > 0 ? analysis.sourceFormatParserCandidates.map((candidate) => ` - ${candidate.file}:${candidate.lines.join(",")}`) : [" - none"];
437
+ const previewLabel = analysis.autofixPreview.scope === "semantic" ? "Semantic autofix" : "Autofix";
404
438
  const typescriptLines = analysis.typescriptPreflight.status === "failed" ? [
405
439
  `- TypeScript preflight: failed with ${analysis.typescriptPreflight.diagnosticCount} diagnostics`,
406
440
  ...analysis.typescriptPreflight.rootDiagnostics.map((diagnostic) => ` - ${diagnostic.config} ${diagnostic.code}: ${diagnostic.message}`),
@@ -410,14 +444,16 @@ const formatSourceAnalysis = (analysis) => {
410
444
  ];
411
445
  return [
412
446
  "",
413
- "Source analysis (selected preset, no files written):",
447
+ `Source analysis (selected preset, ${analysis.autofixPreview.writtenFileCount > 0 ? `${analysis.autofixPreview.writtenFileCount} files written` : "no files written"}):`,
414
448
  `- Lint targets: ${analysis.lintTargets.join(", ")}`,
415
449
  `- Files analyzed: ${analysis.totals.files}`,
416
450
  `- Findings: ${analysis.totals.findings} (${analysis.totals.errors} errors, ${analysis.totals.warnings} warnings)`,
417
451
  `- Non-formatting errors to resolve first: ${analysis.nonFormattingErrors.count}${nonFormattingRuleSuffix}`,
418
- `- Autofix preview: ${analysis.autofixPreview.changedFileCount} files, about ${analysis.autofixPreview.estimatedChangedLines} changed lines`,
452
+ `- ${previewLabel} preview: ${analysis.autofixPreview.changedFileCount} files, about ${analysis.autofixPreview.estimatedChangedLines} changed lines`,
419
453
  `- Findings remaining after preview: ${analysis.autofixPreview.remainingErrors} errors, ${analysis.autofixPreview.remainingWarnings} warnings`,
420
454
  `- Fixable rules still remaining: ${remainingFixableRules}`,
455
+ "- Formatting-sensitive source-parser candidates:",
456
+ ...parserCandidates,
421
457
  ...typescriptLines
422
458
  ];
423
459
  };
@@ -436,6 +472,9 @@ const formatCompatibilityGuidance = (compatibilityFile) => {
436
472
  ];
437
473
  };
438
474
  const createPresetReport = async (cwd, presetName, file = "eslint.config.js", options = {}) => {
475
+ if (options.write && !options.semanticOnly) {
476
+ throw new Error("Writing preset fixes requires semanticOnly to avoid an unchecked formatting rewrite.");
477
+ }
439
478
  const normalizedPreset = presetName.toLowerCase();
440
479
  if (!PRESETS.has(normalizedPreset)) {
441
480
  throw new Error(
@@ -500,7 +539,9 @@ const createPresetReport = async (cwd, presetName, file = "eslint.config.js", op
500
539
  selectedConfig,
501
540
  options.sourceFiles ?? [],
502
541
  Object.keys(resolvablePresetOptions.projects ?? {}),
503
- options.typescriptRunner ?? defaultCommandRunner
542
+ options.typescriptRunner ?? defaultCommandRunner,
543
+ options.semanticOnly,
544
+ options.write
504
545
  ) : null;
505
546
  return {
506
547
  added,
@@ -521,9 +562,17 @@ const createPresetReport = async (cwd, presetName, file = "eslint.config.js", op
521
562
  };
522
563
  };
523
564
  const handleExplainPreset = async (cwd = process.cwd(), preset, options = {}) => {
565
+ if (options.write && !options.semanticOnly) {
566
+ throw new Error("explain-preset --write requires --semantic-only to avoid an unchecked formatting rewrite.");
567
+ }
568
+ if (options.semanticOnly && !options.analyzeSource) {
569
+ throw new Error("explain-preset --semantic-only requires --analyze-source.");
570
+ }
524
571
  const report = await createPresetReport(cwd, preset, options.file, {
525
572
  analyzeSource: options.analyzeSource,
526
- sourceFiles: options.files
573
+ semanticOnly: options.semanticOnly,
574
+ sourceFiles: options.files,
575
+ write: options.write
527
576
  });
528
577
  let compatibilityFile = null;
529
578
  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 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 | ((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 '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 lintResults = await loadProjectEslint(cwd, selectedConfig).lintFiles(lintTargets)\n\n const fix = semanticOnly ?\n (message: ProjectLintMessage): boolean => (\n message.ruleId === null || 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":"AAEA,SAAS,YAAY,cAAc,qBAAqB;AACxD,SAAS,eAAe,uBAAuB;AAC/C,SAAS,SAAS,SAAS,MAAM,gBAAgB;AACjD,SAAS,qBAAqB;AAE9B;AAAA,EAEE;AAAA,EAEA;AAAA,OACK;AAEP,SAA6B,4BAA4B;AACzD,SAAoC,+BAA+B;AACnE,SAAS,oBAAoB;AAC7B,SAAS,iCAAiC;AAC1C,SAAS,qBAAqB;AAoD9B,MAAM,UAAU,IAAI,IAAY,OAAO,OAAO,MAAM,CAAC;AAErD,MAAM,mBAAmB;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,MAAM,2BAA2B,OAAO,QAA2D;AACjG,QAAM,aAAa,iBAAiB,IAAI,UAAQ,KAAK,KAAK,IAAI,CAAC,EAAE,KAAK,UAAQ,WAAW,IAAI,CAAC;AAE9F,MAAI,CAAC,WAAY,QAAO;AAExB,MAAI;AACF,UAAM,SAAS,MAAM,OAAO,GAAG,cAAc,UAAU,EAAE,IAAI,wBAAwB,KAAK,IAAI,CAAC;AAI/F,WAAO,wBAAwB,MAAM,OAAO,OAAO;AAAA,EACrD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,MAAM,0BAA0B;AAAA,EAC9B,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,WAAW;AAAA,EACX,SAAS;AAAA,EACT,OAAO;AACT;AAEA,MAAM,qBAA4D;AAAA,EAChE,SAAS;AAAA,EACT,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,KAAK;AAAA,EACL,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,OAAO;AAAA,EACP,gBAAgB;AAAA,EAChB,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,kBAAkB;AAAA,EAClB,MAAM;AAAA,EACN,KAAK;AACP;AAEA,MAAM,qBAAqB,oBAAI,IAAI;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,MAAM,kBAAkB,oBAAI,IAAI;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,MAAM,kBAAkB,oBAAI,IAAI;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,MAAM,eAAe,oBAAI,IAAI;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,MAAM,8BAA8B,oBAAI,IAAI,CAAC,YAAY,CAAC;AAE1D,MAAM,gBAAgB,CAAC,SAAyB;AAC9C,QAAM,WAAW,KAAK,MAAM,GAAG;AAE/B,MAAI,CAAC,KAAK,WAAW,GAAG,EAAG,QAAO,SAAS,CAAC;AAE5C,QAAM,qBAAqB,SAAS,MAAM,GAAG,CAAC,EAAE,KAAK,GAAG;AAExD,SAAO,4BAA4B,IAAI,kBAAkB,IAAI,qBAAqB,SAAS,CAAC;AAC9F;AAEA,MAAM,eAAe,CAAC,SAAqF;AACzG,QAAM,SAAS,cAAc,IAAI;AAEjC,MACE,WAAW,cACX,WAAW,gBACX,KAAK,SAAS,UAAU,KACxB,KAAK,SAAS,gBAAgB,EAC9B,QAAO;AAET,MAAI,mBAAmB,IAAI,MAAM,EAAG,QAAO;AAE3C,MAAI,gBAAgB,IAAI,MAAM,EAAG,QAAO;AAExC,MACE,gBAAgB,IAAI,MAAM,KAC1B,aAAa,IAAI,IAAI,KACrB,KAAK,SAAS,QAAQ,KACtB,KAAK,SAAS,SAAS,EACvB,QAAO;AAET,SAAO;AACT;AAEA,MAAM,cAAc,CAAC,UAA4B,MAAM,QAAQ,KAAK,IAAI,MAAM,CAAC,IAAI;AAEnF,MAAM,YAAY,CAAC,UAA4B;AAC7C,QAAM,WAAW,YAAY,KAAK;AAElC,SAAO,aAAa,KAAK,aAAa,SAAS,aAAa;AAC9D;AAEA,MAAM,gBAAgB,CAAC,UAA2B,KAAK,UAAU,KAAK;AAEtE,MAAM,oBAAoB,CACxB,KACA,gBACA,MAA4D,UAC1C;AAClB,QAAM,iBAAiB,cAAc,KAAK,KAAK,cAAc,CAAC;AAC9D,QAAM,eAAe,eAAe,QAAQ;AAE5C,MAAI,CAAC,aAAa,OAAQ,OAAM,IAAI,MAAM,8DAA8D;AAExG,SAAO,IAAI,aAAa,OAAO;AAAA,IAC7B;AAAA,IACA,GAAI,MAAM,EAAE,IAAI,IAAI,CAAC;AAAA,IACrB,GAAI,iBAAiB,EAAE,gBAAgB,oBAAoB,KAAK,IAAI,CAAC;AAAA,EACvE,CAAC;AACH;AAEA,MAAM,6BAA6B,CACjC,KACA,kBACyE;AACzE,QAAM,oBAAoB,cAAc,KAAK,KAAK,cAAc,CAAC;AACjE,QAAM,UAAU,EAAE,GAAG,cAAc;AACnC,QAAM,kBAAkB,qBAAqB,GAAG;AAChD,QAAM,kBAAkB,oBAAI,IAAY;AACxC,QAAM,YAAY,QAAQ;AAC1B,QAAM,oBAAoB,OAAO,cAAc,WAAW,YAAY,CAAC;AAEvE,QAAM,mBAAmB,CAAC,aACxB,cAAc,SAAS,kBAAkB,QAAQ,MAAM;AAGzD,aAAW,CAAC,UAAU,SAAS,KAAK,OAAO,QAAQ,uBAAuB,GAAG;AAC3E,UAAM,cAAc;AACpB,UAAM,WAAW,QAAQ,WAAW;AACpC,UAAM,WAAW,iBAAiB,WAAW,IAAI,gBAAgB,WAAW,IAAI,CAAC;AAEjF,UAAM,WAAW,CAAC,GAAG,oBAAI,IAAI;AAAA,MAC3B,GAAI,MAAM,QAAQ,QAAQ,IAAI,WAAW,CAAC;AAAA,MAC1C,GAAI,MAAM,QAAQ,QAAQ,IAAI,WAAW,CAAC;AAAA,IAC5C,CAAC,CAAC;AAEF,QAAI,SAAS,WAAW,EAAG;AAE3B,QAAI;AACF,sBAAgB,WAAW,iBAAiB;AAAA,IAC9C,SAAS,OAAO;AACd,UAAI,CAAC,0BAA0B,OAAO,SAAS,EAAG,OAAM;AAExD,aAAO,OAAO,SAAS;AAAA,QACrB,CAAC,QAAQ,GAAG,CAAC;AAAA,QACb,WAAW;AAAA,UACT,GAAI,OAAO,QAAQ,cAAc,WAAW,QAAQ,YAAY;AAAA,UAChE,CAAC,QAAQ,GAAG;AAAA,QACd;AAAA,QACA,UAAU;AAAA,UACR,GAAG,QAAQ;AAAA,UACX,GAAG,OAAO,YAAY,SAAS,IAAI,aAAW,CAAC,SAAS,KAAK,CAAC,CAAC;AAAA,QACjE;AAAA,MACF,CAAC;AAED,sBAAgB,IAAI,SAAS;AAAA,IAC/B;AAAA,EACF;AAEA,QAAM,4BAA4B,cAAc,SAAS,kBAAkB,eAAe;AAC1F,QAAM,qBAAqB,4BAA4B,gBAAgB,sBAAsB,CAAC,IAAI,CAAC;AAEnG,QAAM,uBAAuB,OAAO,QAAQ,QAAQ,cAAc,CAAC,CAAC,EACjE,OAAO,CAAC,UAAkD,MAAM,CAAC,MAAM,IAAI,EAC3E,IAAI,CAAC,CAAC,SAAS,MAAM,SAAS;AAEjC,QAAM,qBAAqB,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAG,oBAAoB,GAAG,oBAAoB,CAAC,CAAC;AAExF,QAAM,uBAAuE;AAAA,IAC3E,GAAG,QAAQ;AAAA,EACb;AAEA,aAAW,aAAa,oBAAoB;AAC1C,UAAM,YAAY,mBAAmB,SAAS;AAE9C,QAAI;AACF,sBAAgB,WAAW,iBAAiB;AAE5C,2BAAqB,SAAS,IAAI;AAAA,IACpC,SAAS,OAAO;AACd,UAAI,CAAC,0BAA0B,OAAO,SAAS,EAAG,OAAM;AAExD,cAAQ,eAAe,sBAAsB,SAAS;AAEtD,sBAAgB,IAAI,SAAS;AAAA,IAC/B;AAAA,EACF;AAEA,MAAI,CAAC,qBAAqB,OAAO;AAC/B,WAAO,qBAAqB;AAE5B,WAAO,qBAAqB;AAE5B,WAAO,qBAAqB,cAAc;AAE1C,QAAI,CAAC,qBAAqB,MAAO,QAAO,qBAAqB,gBAAgB;AAAA,EAC/E;AAEA,MAAI,CAAC,qBAAqB,KAAK;AAC7B,WAAO,qBAAqB;AAE5B,WAAO,qBAAqB;AAAA,EAC9B;AAEA,MAAI,mBAAmB,SAAS,GAAG;AACjC,YAAQ,iBAAiB;AAEzB,YAAQ,aAAa;AAAA,EACvB;AAEA,SAAO,EAAE,iBAAiB,CAAC,GAAG,eAAe,GAAG,QAAQ;AAC1D;AAEA,MAAM,4BAA4B,CAChC,QACA,YACA,iBACW;AAAA,EACX,4DAA4D,OAAO,OAAO,CAAC,EAAE,YAAY,CAAC,GAAG,OAAO,MAAM,CAAC,CAAC;AAAA,EAC5G;AAAA,EACA;AAAA,EACA,uCAAuC,MAAM;AAAA,EAC7C;AAAA,EACA,GAAG,OAAO,KAAK,UAAU,EAAE,KAAK,EAAE,IAAI,UAAQ,OAAO,KAAK,UAAU,IAAI,CAAC,UAAU;AAAA,EACnF,GAAG,OAAO,KAAK,YAAY,EAAE,KAAK,EAAE,IAAI,UACtC,OAAO,KAAK,UAAU,IAAI,CAAC,KAAK,KAAK,UAAU,aAAa,IAAI,EAAE,IAAI,CAAC,GACxE;AAAA,EACD;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,IAAI;AASX,MAAM,uBAAuB,OAAuB;AAAA,EAClD,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,OAAO;AAAA,EACP,UAAU;AACZ;AAEA,MAAM,aAAa,CACjB,WACA,KACA,YACS;AACT,QAAM,UAAU,UAAU,GAAG,KAAK,qBAAqB;AAEvD,UAAQ;AAER,MAAI,QAAQ,aAAa,EAAG,SAAQ;AAAA,MAC/B,SAAQ;AAEb,MAAI,QAAQ,QAAQ,OAAW,SAAQ;AAEvC,YAAU,GAAG,IAAI;AACnB;AAEA,MAAM,uBAAuB,CAAC,QAAgB,UAA0B;AACtE,QAAM,cAAc,OAAO,MAAM,IAAI;AACrC,QAAM,aAAa,MAAM,MAAM,IAAI;AACnC,QAAM,kBAAkB,KAAK,IAAI,YAAY,QAAQ,WAAW,MAAM;AACtE,MAAI,UAAU,KAAK,IAAI,YAAY,SAAS,WAAW,MAAM;AAE7D,WAAS,QAAQ,GAAG,QAAQ,iBAAiB,SAAS;AACpD,QAAI,YAAY,KAAK,MAAM,WAAW,KAAK,EAAG;AAAA,EAChD;AAEA,SAAO;AACT;AAEA,MAAM,qBAAqB,CAAC,aAAyC;AACnE,MAAI;AACF,WAAO,aAAa,UAAU,MAAM;AAAA,EACtC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAOA,MAAM,2BAA2B;AAEjC,MAAM,wBAAwB,IAAI,OAAO;AAAA,EACvC,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AACT,EAAE,KAAK,GAAG,CAAC;AAEX,MAAM,mCAAmC,CACvC,KACA,cACkC,UAAU,QAAQ,cAAY;AAChE,QAAM,UAAU,mBAAmB,QAAQ;AAE3C,MAAI,CAAC,WAAW,CAAC,yBAAyB,KAAK,OAAO,EAAG,QAAO,CAAC;AAEjE,QAAM,QAAQ,QAAQ,MAAM,IAAI,EAC7B,QAAQ,CAAC,MAAM,UAAU,sBAAsB,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAE/E,SAAO,MAAM,SAAS,IAAI,CAAC,EAAE,MAAM,SAAS,KAAK,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC;AAC1E,CAAC;AAED,MAAM,8BAA8B;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,MAAM,mCAAmC,oBAAI,IAAI;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,MAAM,uBAAuB,CAAC,QAA+B;AAC3D,MAAI;AACF,UAAM,iBAAiB,cAAc,KAAK,KAAK,cAAc,CAAC;AAC9D,UAAM,cAAc,eAAe,QAAQ,yBAAyB;AAEpE,UAAM,WAAW,KAAK,MAAM,aAAa,aAAa,MAAM,CAAC;AAI7D,UAAM,MAAM,OAAO,SAAS,QAAQ,WAAW,SAAS,MAAM,SAAS,KAAK;AAE5E,WAAO,MAAM,KAAK,QAAQ,WAAW,GAAG,GAAG,IAAI;AAAA,EACjD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,MAAM,uBAAuB,CAC3B,KACA,uBACa;AACb,QAAM,mBAAmB,OAAO,KAAK,qBAAqB,GAAG,EAAE,YAAY,CAAC,CAAC;AAC7E,QAAM,eAAe,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAG,kBAAkB,GAAG,kBAAkB,CAAC,CAAC;AAE9E,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA,GAAG,aAAa,IAAI,aAAW,KAAK,KAAK,OAAO,CAAC;AAAA,EACnD;AAEA,SAAO,CAAC,GAAG,IAAI,IAAI,MAAM,QAAQ,UAAQ;AACvC,UAAM,SAAS,4BAA4B,KAAK,UAAQ,WAAW,KAAK,MAAM,IAAI,CAAC,CAAC;AAEpF,WAAO,SAAS,CAAC,KAAK,MAAM,MAAM,CAAC,IAAI,CAAC;AAAA,EAC1C,CAAC,CAAC,CAAC;AACL;AAQA,MAAM,6BAA6B,CACjC,KACA,QACA,WAC2B,OAC1B,MAAM,OAAO,EACb,QAAQ,UAAQ;AACf,QAAM,QAAQ,2BAA2B,KAAK,IAAI;AAElD,MAAI,CAAC,MAAO,QAAO,CAAC;AAEpB,SAAO,CAAC;AAAA,IACN,MAAM,MAAM,CAAC;AAAA,IACb,QAAQ,SAAS,KAAK,MAAM;AAAA,IAC5B,SAAS,MAAM,CAAC;AAAA,EAClB,CAAC;AACH,CAAC;AAEI,MAAM,4BAA4B,CACvC,KACA,qBAA+B,CAAC,GAChC,SAAwB,yBACrB;AACH,QAAM,aAAa,qBAAqB,GAAG;AAC3C,QAAM,UAAU,qBAAqB,KAAK,kBAAkB;AAE5D,MAAI,CAAC,cAAc,QAAQ,WAAW,GAAG;AACvC,WAAO;AAAA,MACL,SAAS,CAAC;AAAA,MACV,iBAAiB;AAAA,MACjB,iBAAiB,CAAC;AAAA,MAClB,QAAQ;AAAA,IACV;AAAA,EACF;AAEA,QAAM,cAAsC,CAAC;AAE7C,QAAM,UAAU,QAAQ,IAAI,YAAU;AACpC,UAAM,SAAS,OAAO,QAAQ,UAAU;AAAA,MACtC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,GAAG,GAAG;AAEN,gBAAY,KAAK,GAAG;AAAA,MAClB;AAAA,MACA;AAAA,MACA,GAAG,OAAO,MAAM;AAAA,EAAK,OAAO,MAAM;AAAA,IACpC,CAAC;AAED,WAAO;AAAA,MACL,QAAQ,SAAS,KAAK,MAAM;AAAA,MAC5B,QAAQ,OAAO;AAAA,IACjB;AAAA,EACF,CAAC;AAED,QAAM,kBAAkB,YAAY;AAAA,IAClC,gBAAc,iCAAiC,IAAI,WAAW,IAAI;AAAA,EACpE;AAEA,SAAO;AAAA,IACL,SAAS;AAAA,IACT,iBAAiB,YAAY;AAAA,IAC7B,kBAAkB,gBAAgB,SAAS,IAAI,kBAAkB,aAAa,MAAM,GAAG,EAAE;AAAA,IACzF,QAAQ,QAAQ,KAAK,YAAU,OAAO,WAAW,CAAC,IAAI,WAAoB;AAAA,EAC5E;AACF;AAEA,MAAM,sBAAsB,OAC1B,KACA,gBACA,aACA,oBACA,kBACA,eAAe,OACf,QAAQ,UACL;AACH,QAAM,cAAc,YAAY,SAAS,IAAI,cAAc,CAAC,GAAG;AAC/D,QAAM,cAAc,MAAM,kBAAkB,KAAK,cAAc,EAAE,UAAU,WAAW;AAEtF,QAAM,MAAM,eACV,CAAC,YACC,QAAQ,WAAW,QAAQ,aAAa,QAAQ,MAAM,MAAM,eAE9D;AAEF,QAAM,iBAAiB,MAAM,kBAAkB,KAAK,gBAAgB,GAAG,EAAE,UAAU,WAAW;AAC9F,QAAM,aAA6C,CAAC;AACpD,QAAM,aAA6C,CAAC;AACpD,QAAM,SAAyC,CAAC;AAChD,QAAM,0BAA0B,oBAAI,IAAY;AAChD,MAAI,sBAAsB;AAE1B,aAAW,UAAU,aAAa;AAChC,UAAM,WAAW,QAAQ,OAAO,QAAQ,KAAK;AAE7C,eAAW,WAAW,OAAO,UAAU;AACrC,YAAM,OAAO,QAAQ,WAAW,QAAQ,QAAQ,YAAY;AAC5D,YAAM,WAAW,QAAQ,SAAS,aAAa,QAAQ,MAAM,IAAI;AAEjE,iBAAW,YAAY,UAAU,OAAO;AAExC,iBAAW,YAAY,UAAU,OAAO;AAExC,iBAAW,QAAQ,MAAM,OAAO;AAEhC,UAAI,QAAQ,aAAa,KAAK,aAAa,cAAc;AACvD;AAEA,gCAAwB,IAAI,IAAI;AAAA,MAClC;AAAA,IACF;AAAA,EACF;AAEA,QAAM,eAAyB,CAAC;AAChC,QAAM,wBAAwB,oBAAI,IAAY;AAC9C,MAAI,wBAAwB;AAC5B,MAAI,kBAAkB;AACtB,MAAI,oBAAoB;AACxB,MAAI,mBAAmB;AAEvB,aAAW,UAAU,gBAAgB;AACnC,uBAAmB,OAAO;AAE1B,yBAAqB,OAAO;AAE5B,eAAW,WAAW,OAAO,UAAU;AACrC,UAAI,QAAQ,QAAQ,OAAW,uBAAsB,IAAI,QAAQ,UAAU,SAAS;AAAA,IACtF;AAEA,QAAI,OAAO,WAAW,OAAW;AAEjC,iBAAa,KAAK,SAAS,KAAK,OAAO,QAAQ,CAAC;AAEhD,UAAM,WAAW,mBAAmB,OAAO,QAAQ;AAEnD,QAAI,aAAa,OAAW,0BAAyB,qBAAqB,UAAU,OAAO,MAAM;AAEjG,QAAI,OAAO;AACT,oBAAc,OAAO,UAAU,OAAO,MAAM;AAE5C;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,gBAAgB;AAAA,MACd,kBAAkB,aAAa;AAAA,MAC/B,cAAc,aAAa,KAAK;AAAA,MAChC;AAAA,MACA;AAAA,MACA,uBAAuB,CAAC,GAAG,qBAAqB,EAAE,KAAK;AAAA,MACvD;AAAA,MACA,OAAO,eAAe,aAAsB;AAAA,MAC5C;AAAA,IACF;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,qBAAqB;AAAA,MACnB,OAAO;AAAA,MACP,OAAO,CAAC,GAAG,uBAAuB,EAAE,KAAK;AAAA,IAC3C;AAAA,IACA,8BAA8B;AAAA,MAC5B;AAAA,MACA,CAAC,GAAG,IAAI,IAAI,YAAY,IAAI,YAAU,OAAO,QAAQ,CAAC,CAAC;AAAA,IACzD;AAAA,IACA,qBAAqB,0BAA0B,KAAK,oBAAoB,gBAAgB;AAAA,IACxF,QAAQ;AAAA,MACN,QAAQ,YAAY,OAAO,CAAC,OAAO,WAAW,QAAQ,OAAO,YAAY,CAAC;AAAA,MAC1E,OAAO,YAAY;AAAA,MACnB,UAAU,YAAY;AAAA,QACpB,CAAC,OAAO,WAAW,QAAQ,OAAO,aAAa,OAAO;AAAA,QACtD;AAAA,MACF;AAAA,MACA,UAAU,YAAY,OAAO,CAAC,OAAO,WAAW,QAAQ,OAAO,cAAc,CAAC;AAAA,IAChF;AAAA,EACF;AACF;AAIA,MAAM,uBAAuB,CAC3B,aACa;AACb,MAAI,CAAC,UAAU;AACb,WAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,0BAA0B,SAAS,oBAAoB,MAAM,SAAS,IAC1E,KAAK,SAAS,oBAAoB,MAAM,KAAK,IAAI,CAAC,MAClD;AAEF,QAAM,wBAAwB,SAAS,eAAe,sBAAsB,SAAS,IACnF,SAAS,eAAe,sBAAsB,KAAK,IAAI,IACvD;AAEF,QAAM,mBAAmB,SAAS,6BAA6B,SAAS,IACtE,SAAS,6BAA6B,IAAI,eACxC,OAAO,UAAU,IAAI,IAAI,UAAU,MAAM,KAAK,GAAG,CAAC,EACnD,IACD,CAAC,UAAU;AAEb,QAAM,eAAe,SAAS,eAAe,UAAU,aAAa,qBAAqB;AAEzF,QAAM,kBAAkB,SAAS,oBAAoB,WAAW,WAC9D;AAAA,IACE,uCAAuC,SAAS,oBAAoB,eAAe;AAAA,IACnF,GAAG,SAAS,oBAAoB,gBAAgB,IAAI,gBAClD,OAAO,WAAW,MAAM,IAAI,WAAW,IAAI,KAAK,WAAW,OAAO,EACnE;AAAA,IACD;AAAA,EACF,IACA;AAAA,IACE,2BAA2B,SAAS,oBAAoB,MAAM,MAC7D,SAAS,oBAAoB,WAAW,WACvC,KAAK,SAAS,oBAAoB,QAAQ,MAAM,cAChD;AAAA,EACJ;AAEF,SAAO;AAAA,IACL;AAAA,IACA,qCAAqC,SAAS,eAAe,mBAAmB,IAC9E,GAAG,SAAS,eAAe,gBAAgB,mBAC3C,kBAAkB;AAAA,IACpB,mBAAmB,SAAS,YAAY,KAAK,IAAI,CAAC;AAAA,IAClD,qBAAqB,SAAS,OAAO,KAAK;AAAA,IAC1C,eAAe,SAAS,OAAO,QAAQ,KACnC,SAAS,OAAO,MAAM,YAAY,SAAS,OAAO,QAAQ;AAAA,IAC9D,6CAA6C,SAAS,oBAAoB,KAAK,GAAG,uBAAuB;AAAA,IACzG,KAAK,YAAY,aAAa,SAAS,eAAe,gBAAgB,iBAC7D,SAAS,eAAe,qBAAqB;AAAA,IACtD,uCAAuC,SAAS,eAAe,eAAe,YAC3E,SAAS,eAAe,iBAAiB;AAAA,IAC5C,oCAAoC,qBAAqB;AAAA,IACzD;AAAA,IACA,GAAG;AAAA,IACH,GAAG;AAAA,EACL;AACF;AAEA,MAAM,8BAA8B,CAClC,sBACa;AACb,MAAI,mBAAmB;AACrB,WAAO;AAAA,MACL;AAAA,MACA,qCAAqC,iBAAiB;AAAA,MACtD;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEO,MAAM,qBAAqB,OAChC,KACA,YACA,OAAO,oBACP,UAAqC,CAAC,MACnC;AACH,MAAI,QAAQ,SAAS,CAAC,QAAQ,cAAc;AAC1C,UAAM,IAAI,MAAM,sFAAsF;AAAA,EACxG;AAEA,QAAM,mBAAmB,WAAW,YAAY;AAEhD,MAAI,CAAC,QAAQ,IAAI,gBAAgB,GAAG;AAClC,UAAM,IAAI;AAAA,MACR,mBAAmB,UAAU,kBAAkB,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC;AAAA,IAC/E;AAAA,EACF;AAEA,QAAM,SAAS;AACf,QAAM,gBAAgB,cAAc,MAAM;AAC1C,QAAM,UAAU,MAAM,kBAAkB,GAAG,EAAE,uBAAuB,IAAI;AACxE,QAAM,kBAAkB,MAAM,yBAAyB,GAAG;AAC1D,QAAM,iBAAiB,iBAAiB,WAAW,CAAC;AAEpD,QAAM,gBAAgB;AAAA,IACpB,GAAG;AAAA,IACH,GAAG;AAAA,IACH,UAAU;AAAA,MACR,GAAG,cAAc;AAAA,MACjB,GAAG,eAAe;AAAA,IACpB;AAAA,IACA,YAAY;AAAA,MACV,GAAG,cAAc;AAAA,MACjB,GAAG,eAAe;AAAA,IACpB;AAAA,IACA;AAAA,IACA,MAAM,eAAe,QAAQ;AAAA,EAC/B;AAEA,QAAM,EAAE,iBAAiB,SAAS,wBAAwB,IAAI,2BAA2B,KAAK,aAAa;AAE3G,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,wDAAwD,IAAI,uCAAuC;AAAA,EACrH;AAEA,QAAM,iBAAiB,MAAM;AAAA,IAC3B;AAAA,IACA,GAAI,iBAAiB,gBAAgB,CAAC;AAAA,EACxC;AAEA,QAAM,WAAW,MAAM,kBAAkB,KAAK,cAAc,EAAE,uBAAuB,IAAI;AAEzF,MAAI,CAAC,UAAU;AACb,UAAM,IAAI,MAAM,OAAO,gBAAgB,+CAA+C,IAAI,GAAG;AAAA,EAC/F;AAEA,QAAM,eAAe,QAAQ,SAAS,CAAC;AACvC,QAAM,gBAAgB,SAAS,SAAS,CAAC;AACzC,QAAM,QAAiC,CAAC;AACxC,QAAM,UAA0D,CAAC;AACjE,QAAM,UAAmC,CAAC;AAE1C,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,aAAa,GAAG;AACzD,UAAM,eAAe,aAAa,IAAI;AAEtC,QAAI,UAAU,KAAK,KAAK,CAAC,UAAU,YAAY,GAAG;AAChD,YAAM,IAAI,IAAI;AAAA,IAChB,WACE,UAAU,KAAK,KACf,UAAU,YAAY,KACtB,cAAc,KAAK,MAAM,cAAc,YAAY,GACnD;AACA,cAAQ,IAAI,IAAI,EAAE,MAAM,cAAc,IAAI,MAAM;AAAA,IAClD;AAAA,EACF;AAEA,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,YAAY,GAAG;AACxD,QAAI,UAAU,KAAK,KAAK,CAAC,UAAU,cAAc,IAAI,CAAC,EAAG,SAAQ,IAAI,IAAI;AAAA,EAC3E;AAEA,QAAM,SAAS,OAAO;AAAA,IACpB,CAAC,cAAc,eAAe,YAAY,aAAa,QAAQ,EAAE,IAAI,WAAS;AAAA,MAC5E;AAAA,MACA,OAAO,KAAK,KAAK,EAAE,OAAO,UAAQ,aAAa,IAAI,MAAM,KAAK,EAAE,KAAK;AAAA,IACvE,CAAC;AAAA,EACH;AAEA,QAAM,iBAAiB,QAAQ,gBAC7B,MAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,QAAQ,eAAe,CAAC;AAAA,IACxB,OAAO,KAAK,wBAAwB,YAAY,CAAC,CAAC;AAAA,IAClD,QAAQ,oBAAoB;AAAA,IAC5B,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV,IACA;AAEF,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,oBAAoB;AAAA,IACpB;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,MACN,OAAO,OAAO,KAAK,KAAK,EAAE;AAAA,MAC1B,SAAS,OAAO,KAAK,OAAO,EAAE;AAAA,MAC9B,SAAS,OAAO,KAAK,OAAO,EAAE;AAAA,IAChC;AAAA,EACF;AACF;AAEO,MAAM,sBAAsB,OACjC,MAAc,QAAQ,IAAI,GAC1B,QACA,UAAgC,CAAC,MACf;AAClB,MAAI,QAAQ,SAAS,CAAC,QAAQ,cAAc;AAC1C,UAAM,IAAI,MAAM,2FAA2F;AAAA,EAC7G;AAEA,MAAI,QAAQ,gBAAgB,CAAC,QAAQ,eAAe;AAClD,UAAM,IAAI,MAAM,2DAA2D;AAAA,EAC7E;AAEA,QAAM,SAAS,MAAM,mBAAmB,KAAK,QAAQ,QAAQ,MAAM;AAAA,IACjE,eAAe,QAAQ;AAAA,IACvB,cAAc,QAAQ;AAAA,IACtB,aAAa,QAAQ;AAAA,IACrB,OAAO,QAAQ;AAAA,EACjB,CAAC;AAED,MAAI,oBAAmC;AAEvC,MAAI,QAAQ,eAAe;AACzB,UAAM,SAAS,QAAQ,UAAU,kBAAkB,OAAO,MAAM;AAChE,UAAM,aAAa,KAAK,KAAK,MAAM;AAEnC,QAAI,WAAW,UAAU,GAAG;AAC1B,YAAM,IAAI,MAAM,GAAG,MAAM,kEAAkE;AAAA,IAC7F;AAEA,kBAAc,YAAY,0BAA0B,OAAO,QAAQ,OAAO,OAAO,OAAO,OAAO,CAAC;AAEhG,wBAAoB,SAAS,KAAK,UAAU;AAAA,EAC9C;AAEA,QAAM,UAAU,EAAE,GAAG,QAAQ,kBAAkB;AAE/C,MAAI,QAAQ,MAAM;AAChB,YAAQ,IAAI,KAAK,UAAU,SAAS,MAAM,CAAC,CAAC;AAE5C;AAAA,EACF;AAEA,UAAQ,IAAI;AAAA,IACV,2BAA2B,OAAO,MAAM;AAAA,IACxC,0BAA0B,OAAO,IAAI;AAAA,IACrC;AAAA,IACA,0BAA0B,OAAO,OAAO,KAAK;AAAA,IAC7C,2BAA2B,OAAO,OAAO,OAAO;AAAA,IAChD,8BAA8B,OAAO,OAAO,OAAO;AAAA,IACnD,8DAA8D,OAAO,gBAAgB,SAAS,IAAI,OAAO,gBAAgB,KAAK,IAAI,IAAI,MAAM;AAAA,IAC5I;AAAA,IACA,GAAG,OAAO,QAAQ,OAAO,MAAM,EAAE,IAAI,CAAC,CAAC,OAAO,KAAK,MACjD,KAAK,KAAK,KAAK,MAAM,MAAM,GAAG,MAAM,SAAS,IAAI,KAAK,MAAM,KAAK,IAAI,CAAC,MAAM,EAAE,EAC/E;AAAA,IACD,GAAG,qBAAqB,OAAO,cAAc;AAAA,IAC7C,GAAG,4BAA4B,iBAAiB;AAAA,EAClD,EAAE,KAAK,IAAI,CAAC;AACd;","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 };