/** * The ONE answer to "which ESLint rules exist in this repo, which are enabled * where, and did the config load" — read from ESLint itself. * * Three callers used to ask ESLint three different ways, and each saw a * different repo: `generate types` probed one representative path per * (directory, extension) (#352), `enforce()` verification probed one path per * config block `files` glob (#351), and the routing catalog asked about * `src/index.ts` alone. The same rule could be enabled for one caller and * absent for another. This module owns the probe; every caller reads the same * {@link EslintInventory}. * * This module is the pure half (the probe's script, its wire schema, and every * question asked of the answer); `eslintInventory` in `linters.ts` runs the * probe beside the other linter subprocesses, cached per project. * * HOW: a child `node -e` process runs in the project's directory, so `eslint` * and the config's own imports resolve from the project exactly as `npx eslint` * would, and nothing of the project's config loads into our process. The child * lists the config's blocks (plugins they register, rules they mention, a probe * path synthesized from each `files` glob), adds one representative path per * (directory, name shape) of the project's files, and asks * `calculateConfigForFile` for each. A rule is `enabled` if any probe has it on, * `disabled` if every probe that sets it has it off. * * LIMITS, named: a block naming one exact file that shares directory and * extension with siblings is reached only if its glob synthesizes that path; a * config in a SUBDIRECTORY (v10 looks configs up per file) is not listed; a * `files` entry given as a function is not probed. A rule that a block mentions * but no probe reached reads `unknown`, never `unconfigured`. */ import type { ConfigEnabledStatus } from "./linter-adapter.js"; /** What ESLint's resolved config says about the repo, when it loaded. */ export interface EslintConfigView { /** ESLint's built-in rule ids. */ readonly core: ReadonlySet; /** plugin namespace → its rule names, from the plugin objects ESLint holds. */ readonly plugins: ReadonlyMap>; /** rule id → state, merged over every probe path. */ readonly rules: ReadonlyMap; /** rule ids some block sets, whether or not a probe reached that block. */ readonly mentioned: ReadonlySet; /** every block of the config was listed, so an unmentioned rule is unset. */ readonly complete: boolean; } /** * The inventory. Separate members because each is a different instruction to * the user: no ESLint, no config, a config that throws, a config that loads and * switches nothing on, a config with rules. */ export type EslintInventory = { readonly kind: "not-installed"; } | { readonly kind: "no-config"; } | { readonly kind: "failed"; readonly error: string; } | { readonly kind: "empty"; readonly view: EslintConfigView; } | { readonly kind: "loaded"; readonly view: EslintConfigView; }; /** * One representative path per distinct (directory, name shape) pair of the * project's files. A flat-config `files` glob selects on the directory and the * name's extension chain, so one file per pair sees every block any file of * that pair could match — without linting a single file. */ export declare function representativePaths(files: readonly string[]): readonly string[]; /** The files `representativePaths` picks from: everything but dependencies and git. */ export declare const PROJECT_FILES_GLOB: { readonly pattern: "**/*"; readonly ignore: readonly ["**/node_modules/**", "**/.git/**"]; }; export declare const ESLINT_PROBE_SCRIPT: string; /** * Turn the child's stdout into an inventory. Pure, so every shape of answer is * testable without spawning ESLint. @internal */ export declare function parseEslintInventory(stdout: string): EslintInventory; /** The view, when the config loaded (with or without enabled rules). */ export declare function configView(inv: EslintInventory): EslintConfigView | null; /** Ids of every rule the config switches on somewhere, sorted. */ export declare function enabledRuleIds(view: EslintConfigView): readonly string[]; /** Enabled state of one rule id across every block of the config. */ export declare function eslintRuleState(inv: EslintInventory, ruleId: string): ConfigEnabledStatus; /** * Does the plugin the config REGISTERS under `ruleId`'s namespace define the * rule? null when the config registers no plugin under that namespace (or did * not load). The namespace is everything before the LAST slash — ESLint's own * split, so `@scope/plugin/rule` works. */ export declare function registeredPluginHasRule(inv: EslintInventory, ruleId: string): boolean | null; //# sourceMappingURL=eslint-inventory.d.ts.map