eslint-config-setup 0.3.2 → 0.4.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/README.md +6 -0
- package/dist/configs/0b23ff88.js +138 -24
- package/dist/configs/12c62446.js +155 -9
- package/dist/configs/196d687e.js +281 -47
- package/dist/configs/1c3f743c.js +157 -9
- package/dist/configs/2f6f3a82.js +303 -39
- package/dist/configs/4eb62e57.js +140 -21
- package/dist/configs/52762a42.js +278 -34
- package/dist/configs/532f50a4.js +476 -49
- package/dist/configs/5a302873.js +301 -39
- package/dist/configs/6bc0d588.js +442 -57
- package/dist/configs/91e82988.js +478 -49
- package/dist/configs/c2fecd3d.js +280 -31
- package/dist/configs/cde010b4.js +309 -16
- package/dist/configs/d537b683.js +444 -54
- package/dist/configs/db69ebb6.js +283 -44
- package/dist/configs/e4b137fa.js +307 -16
- package/dist/index.d.ts +13 -13
- package/dist/index.js +65 -67
- package/dist/index.js.map +1 -1
- package/dist/modules.d.ts +39 -40
- package/dist/modules.js +1136 -1105
- package/dist/modules.js.map +1 -1
- package/dist/oxlint-configs/3047b7d6.json +243 -148
- package/dist/oxlint-configs/58d5e03b.json +242 -148
- package/dist/oxlint-configs/78b40daa.json +274 -158
- package/dist/oxlint-configs/7ff0d87e.json +326 -244
- package/dist/oxlint-configs/85912bf0.json +326 -243
- package/dist/oxlint-configs/9dc42dc3.json +273 -158
- package/dist/oxlint-configs/d46cb9b7.json +351 -246
- package/dist/oxlint-configs/ef643c60.json +352 -246
- package/dist/{types-CAUUIuJR.d.ts → types-CAO1PbsB.d.ts} +7 -7
- package/package.json +32 -31
package/dist/index.js
CHANGED
|
@@ -1,70 +1,3 @@
|
|
|
1
|
-
// src/loader.ts
|
|
2
|
-
import { readFileSync } from "fs";
|
|
3
|
-
import path from "path";
|
|
4
|
-
|
|
5
|
-
// src/hash.ts
|
|
6
|
-
import { createHash } from "crypto";
|
|
7
|
-
function optionsToBitmask(opts) {
|
|
8
|
-
let mask = 0;
|
|
9
|
-
if (opts.react) mask |= 1 << 0;
|
|
10
|
-
if (opts.node) mask |= 1 << 1;
|
|
11
|
-
if (opts.ai) mask |= 1 << 2;
|
|
12
|
-
if (opts.oxlint) mask |= 1 << 3;
|
|
13
|
-
return mask;
|
|
14
|
-
}
|
|
15
|
-
function bitmaskToHash(mask) {
|
|
16
|
-
const input = `effective-eslint-config:${mask}`;
|
|
17
|
-
return createHash("sha1").update(input).digest("hex").slice(0, 8);
|
|
18
|
-
}
|
|
19
|
-
function optionsToFilename(opts) {
|
|
20
|
-
return `${bitmaskToHash(optionsToBitmask(opts))}.js`;
|
|
21
|
-
}
|
|
22
|
-
function oxlintOptionsToBitmask(opts) {
|
|
23
|
-
let mask = 0;
|
|
24
|
-
if (opts.react) mask |= 1 << 0;
|
|
25
|
-
if (opts.node) mask |= 1 << 1;
|
|
26
|
-
if (opts.ai) mask |= 1 << 2;
|
|
27
|
-
return mask;
|
|
28
|
-
}
|
|
29
|
-
function oxlintBitmaskToHash(mask) {
|
|
30
|
-
const input = `eslint-config-setup-oxlint:${mask}`;
|
|
31
|
-
return createHash("sha1").update(input).digest("hex").slice(0, 8);
|
|
32
|
-
}
|
|
33
|
-
function oxlintOptionsToFilename(opts) {
|
|
34
|
-
return `${oxlintBitmaskToHash(oxlintOptionsToBitmask(opts))}.json`;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// src/loader.ts
|
|
38
|
-
async function getEslintConfig(opts = {}) {
|
|
39
|
-
const filename = optionsToFilename(opts);
|
|
40
|
-
const dirname = import.meta.dirname;
|
|
41
|
-
const configPath = path.join(dirname, "configs", filename);
|
|
42
|
-
try {
|
|
43
|
-
const module = await import(
|
|
44
|
-
/* webpackIgnore: true */
|
|
45
|
-
`${configPath}?${Date.now()}`
|
|
46
|
-
);
|
|
47
|
-
return module.default;
|
|
48
|
-
} catch {
|
|
49
|
-
throw new Error(
|
|
50
|
-
`eslint-config-setup: No pre-generated config found for options ${JSON.stringify(opts)}. Expected file: configs/${filename}. Run "npm run generate" in the package to build configs.`
|
|
51
|
-
);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
function getOxlintConfig(opts = {}) {
|
|
55
|
-
const filename = oxlintOptionsToFilename(opts);
|
|
56
|
-
const dirname = import.meta.dirname;
|
|
57
|
-
const configPath = path.join(dirname, "oxlint-configs", filename);
|
|
58
|
-
try {
|
|
59
|
-
const content = readFileSync(configPath, "utf8");
|
|
60
|
-
return JSON.parse(content);
|
|
61
|
-
} catch {
|
|
62
|
-
throw new Error(
|
|
63
|
-
`eslint-config-setup: No pre-generated OxLint config found for options ${JSON.stringify(opts)}. Expected file: oxlint-configs/${filename}. Run "npm run generate" in the package to build configs.`
|
|
64
|
-
);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
1
|
// src/api/rule-helpers.ts
|
|
69
2
|
var CONFIG_PREFIX = "eslint-config-setup/";
|
|
70
3
|
var SCOPE_TO_BLOCK = {
|
|
@@ -145,6 +78,71 @@ function disableAllRulesBut(config, keepRuleName) {
|
|
|
145
78
|
}
|
|
146
79
|
}
|
|
147
80
|
}
|
|
81
|
+
|
|
82
|
+
// src/hash.ts
|
|
83
|
+
import { createHash } from "crypto";
|
|
84
|
+
function optionsToBitmask(opts) {
|
|
85
|
+
let mask = 0;
|
|
86
|
+
if (opts.react) mask |= 1 << 0;
|
|
87
|
+
if (opts.node) mask |= 1 << 1;
|
|
88
|
+
if (opts.ai) mask |= 1 << 2;
|
|
89
|
+
if (opts.oxlint) mask |= 1 << 3;
|
|
90
|
+
return mask;
|
|
91
|
+
}
|
|
92
|
+
function bitmaskToHash(mask) {
|
|
93
|
+
const input = `effective-eslint-config:${mask}`;
|
|
94
|
+
return createHash("sha1").update(input).digest("hex").slice(0, 8);
|
|
95
|
+
}
|
|
96
|
+
function optionsToFilename(opts) {
|
|
97
|
+
return `${bitmaskToHash(optionsToBitmask(opts))}.js`;
|
|
98
|
+
}
|
|
99
|
+
function oxlintOptionsToBitmask(opts) {
|
|
100
|
+
let mask = 0;
|
|
101
|
+
if (opts.react) mask |= 1 << 0;
|
|
102
|
+
if (opts.node) mask |= 1 << 1;
|
|
103
|
+
if (opts.ai) mask |= 1 << 2;
|
|
104
|
+
return mask;
|
|
105
|
+
}
|
|
106
|
+
function oxlintBitmaskToHash(mask) {
|
|
107
|
+
const input = `eslint-config-setup-oxlint:${mask}`;
|
|
108
|
+
return createHash("sha1").update(input).digest("hex").slice(0, 8);
|
|
109
|
+
}
|
|
110
|
+
function oxlintOptionsToFilename(opts) {
|
|
111
|
+
return `${oxlintBitmaskToHash(oxlintOptionsToBitmask(opts))}.json`;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// src/loader.ts
|
|
115
|
+
import { readFileSync } from "fs";
|
|
116
|
+
import path from "path";
|
|
117
|
+
async function getEslintConfig(opts = {}) {
|
|
118
|
+
const filename = optionsToFilename(opts);
|
|
119
|
+
const dirname = import.meta.dirname;
|
|
120
|
+
const configPath = path.join(dirname, "configs", filename);
|
|
121
|
+
try {
|
|
122
|
+
const module = await import(
|
|
123
|
+
/* webpackIgnore: true */
|
|
124
|
+
`${configPath}?${Date.now()}`
|
|
125
|
+
);
|
|
126
|
+
return module.default;
|
|
127
|
+
} catch {
|
|
128
|
+
throw new Error(
|
|
129
|
+
`eslint-config-setup: No pre-generated config found for options ${JSON.stringify(opts)}. Expected file: configs/${filename}. Run "npm run generate" in the package to build configs.`
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
function getOxlintConfig(opts = {}) {
|
|
134
|
+
const filename = oxlintOptionsToFilename(opts);
|
|
135
|
+
const dirname = import.meta.dirname;
|
|
136
|
+
const configPath = path.join(dirname, "oxlint-configs", filename);
|
|
137
|
+
try {
|
|
138
|
+
const content = readFileSync(configPath, "utf8");
|
|
139
|
+
return JSON.parse(content);
|
|
140
|
+
} catch {
|
|
141
|
+
throw new Error(
|
|
142
|
+
`eslint-config-setup: No pre-generated OxLint config found for options ${JSON.stringify(opts)}. Expected file: oxlint-configs/${filename}. Run "npm run generate" in the package to build configs.`
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
148
146
|
export {
|
|
149
147
|
addRule,
|
|
150
148
|
bitmaskToHash,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/loader.ts","../src/hash.ts","../src/api/rule-helpers.ts"],"sourcesContent":["/* eslint-disable security/detect-non-literal-fs-filename -- Paths are computed from deterministic hashes in dist/, not from user input. */\nimport { readFileSync } from \"node:fs\"\nimport path from \"node:path\"\n\nimport type { ConfigOptions, FlatConfigArray, OxlintConfigOptions, OxlintConfigResult } from \"./types\"\n\nimport { optionsToFilename, oxlintOptionsToFilename } from \"./hash\"\n\n/**\n * Loads a pre-generated ESLint config by dynamically importing the hashed file.\n * The hash is computed from the options using the same algorithm as the build.\n */\nexport async function getEslintConfig(\n opts: ConfigOptions = {},\n): Promise<FlatConfigArray> {\n const filename = optionsToFilename(opts)\n const dirname = import.meta.dirname\n const configPath = path.join(dirname, \"configs\", filename)\n\n try {\n const module = (await import(\n /* webpackIgnore: true */\n `${configPath}?${Date.now()}`\n )) as { default: FlatConfigArray }\n return module.default\n } catch {\n throw new Error(\n `eslint-config-setup: No pre-generated config found for options ${JSON.stringify(opts)}. ` +\n `Expected file: configs/${filename}. Run \"npm run generate\" in the package to build configs.`,\n )\n }\n}\n\n/**\n * Loads a pre-generated OxLint config from the hashed JSON file.\n * Only `react`, `node`, and `ai` flags are relevant — `oxlint` is ignored.\n */\nexport function getOxlintConfig(\n opts: OxlintConfigOptions = {},\n): OxlintConfigResult {\n const filename = oxlintOptionsToFilename(opts)\n const dirname = import.meta.dirname\n const configPath = path.join(dirname, \"oxlint-configs\", filename)\n\n try {\n const content = readFileSync(configPath, \"utf8\")\n return JSON.parse(content) as OxlintConfigResult\n } catch {\n throw new Error(\n `eslint-config-setup: No pre-generated OxLint config found for options ${JSON.stringify(opts)}. ` +\n `Expected file: oxlint-configs/${filename}. Run \"npm run generate\" in the package to build configs.`,\n )\n }\n}\n","import { createHash } from \"node:crypto\"\n\nimport type { ConfigOptions, OxlintConfigOptions } from \"./types\"\n\n/**\n * Converts config options to a deterministic bitmask.\n * Bit order is fixed and must never change (would break published configs).\n */\nexport function optionsToBitmask(opts: ConfigOptions): number {\n let mask = 0\n if (opts.react) mask |= 1 << 0\n if (opts.node) mask |= 1 << 1\n if (opts.ai) mask |= 1 << 2\n if (opts.oxlint) mask |= 1 << 3\n return mask\n}\n\n/**\n * Converts a bitmask to a short deterministic hash (8 hex chars).\n * The same hash is produced at build-time (generate) and run-time (getConfig).\n */\nexport function bitmaskToHash(mask: number): string {\n const input = `effective-eslint-config:${mask}`\n return createHash(\"sha1\").update(input).digest(\"hex\").slice(0, 8)\n}\n\n/** Convenience: options → filename (without path prefix). */\nexport function optionsToFilename(opts: ConfigOptions): string {\n return `${bitmaskToHash(optionsToBitmask(opts))}.js`\n}\n\n/** Total number of permutations (2^4 = 16). */\nexport const TOTAL_PERMUTATIONS = 16\n\n/** Iterate all possible option combinations. */\nexport function* allPermutations(): Generator<ConfigOptions> {\n for (let mask = 0; mask < TOTAL_PERMUTATIONS; mask++) {\n yield {\n react: Boolean(mask & (1 << 0)),\n node: Boolean(mask & (1 << 1)),\n ai: Boolean(mask & (1 << 2)),\n oxlint: Boolean(mask & (1 << 3)),\n }\n }\n}\n\n// --- OxLint config permutations (3 flags → 8 combos) ---\n\n/** Converts OxLint-relevant options to a 3-bit bitmask (react, node, ai). */\nexport function oxlintOptionsToBitmask(opts: OxlintConfigOptions): number {\n let mask = 0\n if (opts.react) mask |= 1 << 0\n if (opts.node) mask |= 1 << 1\n if (opts.ai) mask |= 1 << 2\n return mask\n}\n\n/** Deterministic hash for OxLint configs (different salt to avoid collisions). */\nexport function oxlintBitmaskToHash(mask: number): string {\n const input = `eslint-config-setup-oxlint:${mask}`\n return createHash(\"sha1\").update(input).digest(\"hex\").slice(0, 8)\n}\n\n/** OxLint options → filename (without path prefix). */\nexport function oxlintOptionsToFilename(opts: OxlintConfigOptions): string {\n return `${oxlintBitmaskToHash(oxlintOptionsToBitmask(opts))}.json`\n}\n\n/** Total number of OxLint permutations (2^3 = 8). */\nexport const TOTAL_OXLINT_PERMUTATIONS = 8\n\n/** Iterate all OxLint option combinations. */\nexport function* allOxlintPermutations(): Generator<OxlintConfigOptions> {\n for (let mask = 0; mask < TOTAL_OXLINT_PERMUTATIONS; mask++) {\n yield {\n react: Boolean(mask & (1 << 0)),\n node: Boolean(mask & (1 << 1)),\n ai: Boolean(mask & (1 << 2)),\n }\n }\n}\n","/* eslint-disable max-params, complexity -- Public API: config + ruleName + severity + options is the natural signature. Options objects would hurt ergonomics for one-liner calls. */\nimport type { Linter } from \"eslint\"\n\nimport type {\n FlatConfigArray,\n RuleOptions,\n RuleSeverity,\n} from \"../types\"\n\nconst CONFIG_PREFIX = \"eslint-config-setup/\"\n\n/** Maps user-facing scope names to config block name segments. */\nconst SCOPE_TO_BLOCK: Record<string, string> = {\n configs: \"config-files\",\n}\n\n/**\n * Check if a config block matches a given scope.\n * A block matches if its name is `eslint-config-setup/{segment}` or starts with `eslint-config-setup/{segment}-`.\n */\nfunction blockMatchesScope(\n block: Linter.Config,\n scope: string,\n): boolean {\n const name = block.name\n if (name == null) return false\n const segment = SCOPE_TO_BLOCK[scope] ?? scope\n const target = `${CONFIG_PREFIX}${segment}`\n return name === target || name.startsWith(`${target}-`)\n}\n\n/**\n * Change the severity of a rule across all config blocks, preserving options.\n */\nexport function setRuleSeverity(\n config: FlatConfigArray,\n ruleName: string,\n severity: RuleSeverity,\n options?: RuleOptions,\n): void {\n for (const block of config) {\n if (options?.scope !== undefined && !blockMatchesScope(block, options.scope)) continue\n if (block.rules?.[ruleName] == null) continue\n\n const current = block.rules[ruleName]\n if (Array.isArray(current)) {\n block.rules[ruleName] = [severity, ...current.slice(1)] as Linter.RuleEntry\n } else {\n block.rules[ruleName] = severity\n }\n }\n}\n\n/**\n * Update the options of a rule across all config blocks, preserving severity.\n */\nexport function configureRule(\n config: FlatConfigArray,\n ruleName: string,\n options: unknown[],\n ruleOptions?: RuleOptions,\n): void {\n for (const block of config) {\n if (ruleOptions?.scope !== undefined && !blockMatchesScope(block, ruleOptions.scope))\n continue\n if (block.rules?.[ruleName] == null) continue\n\n const current = block.rules[ruleName]\n const severity = Array.isArray(current) ? current[0] : current\n block.rules[ruleName] = [severity, ...options] as Linter.RuleEntry\n }\n}\n\n/**\n * Completely disable a rule across all config blocks.\n * With scope: disables in the first matching block (creates entry if needed).\n */\nexport function disableRule(\n config: FlatConfigArray,\n ruleName: string,\n options?: RuleOptions,\n): void {\n if (options?.scope != null) {\n const { scope } = options\n const block = config.find((b) => blockMatchesScope(b, scope))\n if (!block) return\n block.rules ??= {}\n block.rules[ruleName] = \"off\"\n return\n }\n\n for (const block of config) {\n if (block.rules?.[ruleName] == null) continue\n block.rules[ruleName] = \"off\"\n }\n}\n\n/**\n * Add a new rule to the first (base) config block.\n * With scope: adds to the first matching block instead.\n */\nexport function addRule(\n config: FlatConfigArray,\n ruleName: string,\n severity: RuleSeverity,\n options?: RuleOptions | unknown[],\n ruleOptions?: RuleOptions,\n): void {\n // Handle overloaded signatures: addRule(config, rule, severity, options?, ruleOptions?)\n // When options is a plain object with scope, it's actually ruleOptions\n let ruleOpts: undefined | unknown[]\n let scopeOpts: RuleOptions | undefined\n\n if (Array.isArray(options)) {\n ruleOpts = options\n scopeOpts = ruleOptions\n } else if (options && typeof options === \"object\" && \"scope\" in options) {\n scopeOpts = options\n } else if (options === undefined) {\n scopeOpts = ruleOptions\n }\n\n let target: Linter.Config | undefined\n if (scopeOpts?.scope != null) {\n const { scope } = scopeOpts\n target = config.find((b) => blockMatchesScope(b, scope))\n } else {\n target = config[0]\n }\n\n if (!target) return\n\n target.rules ??= {}\n target.rules[ruleName] = ruleOpts\n ? ([severity, ...ruleOpts] as Linter.RuleEntry)\n : severity\n}\n\n/**\n * Disable all rules except the specified one — useful for debugging.\n */\nexport function disableAllRulesBut(\n config: FlatConfigArray,\n keepRuleName: string,\n): void {\n for (const block of config) {\n if (!block.rules) continue\n for (const ruleName of Object.keys(block.rules)) {\n if (ruleName !== keepRuleName) {\n block.rules[ruleName] = \"off\"\n }\n }\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/api/rule-helpers.ts","../src/hash.ts","../src/loader.ts"],"sourcesContent":["/* eslint-disable max-params, complexity -- Public API: config + ruleName + severity + options is the natural signature. Options objects would hurt ergonomics for one-liner calls. */\nimport type { Linter } from \"eslint\"\n\nimport type {\n FlatConfigArray,\n RuleOptions,\n RuleSeverity,\n} from \"../types\"\n\nconst CONFIG_PREFIX = \"eslint-config-setup/\"\n\n/** Maps user-facing scope names to config block name segments. */\nconst SCOPE_TO_BLOCK: Record<string, string> = {\n configs: \"config-files\",\n}\n\n/**\n * Check if a config block matches a given scope.\n * A block matches if its name is `eslint-config-setup/{segment}` or starts with `eslint-config-setup/{segment}-`.\n */\nfunction blockMatchesScope(\n block: Linter.Config,\n scope: string,\n): boolean {\n const name = block.name\n if (name == null) return false\n const segment = SCOPE_TO_BLOCK[scope] ?? scope\n const target = `${CONFIG_PREFIX}${segment}`\n return name === target || name.startsWith(`${target}-`)\n}\n\n/**\n * Change the severity of a rule across all config blocks, preserving options.\n */\nexport function setRuleSeverity(\n config: FlatConfigArray,\n ruleName: string,\n severity: RuleSeverity,\n options?: RuleOptions,\n): void {\n for (const block of config) {\n if (options?.scope !== undefined && !blockMatchesScope(block, options.scope)) continue\n if (block.rules?.[ruleName] == null) continue\n\n const current = block.rules[ruleName]\n if (Array.isArray(current)) {\n block.rules[ruleName] = [severity, ...current.slice(1)] as Linter.RuleEntry\n } else {\n block.rules[ruleName] = severity\n }\n }\n}\n\n/**\n * Update the options of a rule across all config blocks, preserving severity.\n */\nexport function configureRule(\n config: FlatConfigArray,\n ruleName: string,\n options: unknown[],\n ruleOptions?: RuleOptions,\n): void {\n for (const block of config) {\n if (ruleOptions?.scope !== undefined && !blockMatchesScope(block, ruleOptions.scope))\n continue\n if (block.rules?.[ruleName] == null) continue\n\n const current = block.rules[ruleName]\n const severity = Array.isArray(current) ? current[0] : current\n block.rules[ruleName] = [severity, ...options] as Linter.RuleEntry\n }\n}\n\n/**\n * Completely disable a rule across all config blocks.\n * With scope: disables in the first matching block (creates entry if needed).\n */\nexport function disableRule(\n config: FlatConfigArray,\n ruleName: string,\n options?: RuleOptions,\n): void {\n if (options?.scope != null) {\n const { scope } = options\n const block = config.find((b) => blockMatchesScope(b, scope))\n if (!block) return\n block.rules ??= {}\n block.rules[ruleName] = \"off\"\n return\n }\n\n for (const block of config) {\n if (block.rules?.[ruleName] == null) continue\n block.rules[ruleName] = \"off\"\n }\n}\n\n/**\n * Add a new rule to the first (base) config block.\n * With scope: adds to the first matching block instead.\n */\nexport function addRule(\n config: FlatConfigArray,\n ruleName: string,\n severity: RuleSeverity,\n options?: RuleOptions | unknown[],\n ruleOptions?: RuleOptions,\n): void {\n // Handle overloaded signatures: addRule(config, rule, severity, options?, ruleOptions?)\n // When options is a plain object with scope, it's actually ruleOptions\n let ruleOpts: undefined | unknown[]\n let scopeOpts: RuleOptions | undefined\n\n if (Array.isArray(options)) {\n ruleOpts = options\n scopeOpts = ruleOptions\n } else if (options && typeof options === \"object\" && \"scope\" in options) {\n scopeOpts = options\n } else if (options === undefined) {\n scopeOpts = ruleOptions\n }\n\n let target: Linter.Config | undefined\n if (scopeOpts?.scope != null) {\n const { scope } = scopeOpts\n target = config.find((b) => blockMatchesScope(b, scope))\n } else {\n target = config[0]\n }\n\n if (!target) return\n\n target.rules ??= {}\n target.rules[ruleName] = ruleOpts\n ? ([severity, ...ruleOpts] as Linter.RuleEntry)\n : severity\n}\n\n/**\n * Disable all rules except the specified one — useful for debugging.\n */\nexport function disableAllRulesBut(\n config: FlatConfigArray,\n keepRuleName: string,\n): void {\n for (const block of config) {\n if (!block.rules) continue\n for (const ruleName of Object.keys(block.rules)) {\n if (ruleName !== keepRuleName) {\n block.rules[ruleName] = \"off\"\n }\n }\n }\n}\n","import { createHash } from \"node:crypto\"\n\nimport type { ConfigOptions, OxlintConfigOptions } from \"./types\"\n\n/**\n * Converts config options to a deterministic bitmask.\n * Bit order is fixed and must never change (would break published configs).\n */\nexport function optionsToBitmask(opts: ConfigOptions): number {\n let mask = 0\n if (opts.react) mask |= 1 << 0\n if (opts.node) mask |= 1 << 1\n if (opts.ai) mask |= 1 << 2\n if (opts.oxlint) mask |= 1 << 3\n return mask\n}\n\n/**\n * Converts a bitmask to a short deterministic hash (8 hex chars).\n * The same hash is produced at build-time (generate) and run-time (getConfig).\n */\nexport function bitmaskToHash(mask: number): string {\n const input = `effective-eslint-config:${mask}`\n return createHash(\"sha1\").update(input).digest(\"hex\").slice(0, 8)\n}\n\n/** Convenience: options → filename (without path prefix). */\nexport function optionsToFilename(opts: ConfigOptions): string {\n return `${bitmaskToHash(optionsToBitmask(opts))}.js`\n}\n\n/** Total number of permutations (2^4 = 16). */\nexport const TOTAL_PERMUTATIONS = 16\n\n/** Iterate all possible option combinations. */\nexport function* allPermutations(): Generator<ConfigOptions> {\n for (let mask = 0; mask < TOTAL_PERMUTATIONS; mask++) {\n yield {\n react: Boolean(mask & (1 << 0)),\n node: Boolean(mask & (1 << 1)),\n ai: Boolean(mask & (1 << 2)),\n oxlint: Boolean(mask & (1 << 3)),\n }\n }\n}\n\n// --- OxLint config permutations (3 flags → 8 combos) ---\n\n/** Converts OxLint-relevant options to a 3-bit bitmask (react, node, ai). */\nexport function oxlintOptionsToBitmask(opts: OxlintConfigOptions): number {\n let mask = 0\n if (opts.react) mask |= 1 << 0\n if (opts.node) mask |= 1 << 1\n if (opts.ai) mask |= 1 << 2\n return mask\n}\n\n/** Deterministic hash for OxLint configs (different salt to avoid collisions). */\nexport function oxlintBitmaskToHash(mask: number): string {\n const input = `eslint-config-setup-oxlint:${mask}`\n return createHash(\"sha1\").update(input).digest(\"hex\").slice(0, 8)\n}\n\n/** OxLint options → filename (without path prefix). */\nexport function oxlintOptionsToFilename(opts: OxlintConfigOptions): string {\n return `${oxlintBitmaskToHash(oxlintOptionsToBitmask(opts))}.json`\n}\n\n/** Total number of OxLint permutations (2^3 = 8). */\nexport const TOTAL_OXLINT_PERMUTATIONS = 8\n\n/** Iterate all OxLint option combinations. */\nexport function* allOxlintPermutations(): Generator<OxlintConfigOptions> {\n for (let mask = 0; mask < TOTAL_OXLINT_PERMUTATIONS; mask++) {\n yield {\n react: Boolean(mask & (1 << 0)),\n node: Boolean(mask & (1 << 1)),\n ai: Boolean(mask & (1 << 2)),\n }\n }\n}\n","/* eslint-disable security/detect-non-literal-fs-filename, @typescript-eslint/no-unsafe-type-assertion -- Paths are computed from deterministic hashes in dist/, not from user input. */\nimport { readFileSync } from \"node:fs\"\nimport path from \"node:path\"\n\nimport type { ConfigOptions, FlatConfigArray, OxlintConfigOptions, OxlintConfigResult } from \"./types\"\n\nimport { optionsToFilename, oxlintOptionsToFilename } from \"./hash\"\n\n/**\n * Loads a pre-generated ESLint config by dynamically importing the hashed file.\n * The hash is computed from the options using the same algorithm as the build.\n */\nexport async function getEslintConfig(\n opts: ConfigOptions = {},\n): Promise<FlatConfigArray> {\n const filename = optionsToFilename(opts)\n const dirname = import.meta.dirname\n const configPath = path.join(dirname, \"configs\", filename)\n\n try {\n const module = (await import(\n /* webpackIgnore: true */\n `${configPath}?${Date.now()}`\n )) as { default: FlatConfigArray }\n return module.default\n } catch {\n throw new Error(\n `eslint-config-setup: No pre-generated config found for options ${JSON.stringify(opts)}. ` +\n `Expected file: configs/${filename}. Run \"npm run generate\" in the package to build configs.`,\n )\n }\n}\n\n/**\n * Loads a pre-generated OxLint config from the hashed JSON file.\n * Only `react`, `node`, and `ai` flags are relevant — `oxlint` is ignored.\n */\nexport function getOxlintConfig(\n opts: OxlintConfigOptions = {},\n): OxlintConfigResult {\n const filename = oxlintOptionsToFilename(opts)\n const dirname = import.meta.dirname\n const configPath = path.join(dirname, \"oxlint-configs\", filename)\n\n try {\n const content = readFileSync(configPath, \"utf8\")\n return JSON.parse(content) as OxlintConfigResult\n } catch {\n throw new Error(\n `eslint-config-setup: No pre-generated OxLint config found for options ${JSON.stringify(opts)}. ` +\n `Expected file: oxlint-configs/${filename}. Run \"npm run generate\" in the package to build configs.`,\n )\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/modules.d.ts
CHANGED
|
@@ -1,21 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { C as ConfigOptions, F as FlatConfigArray } from './types-CAO1PbsB.js';
|
|
2
2
|
import 'eslint';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
*
|
|
8
|
-
* These rules would traditionally be considered "too strict" for humans,
|
|
9
|
-
* but since most code is now AI-generated, they serve as effective
|
|
10
|
-
* guardrails that the AI cannot ignore (unlike documentation).
|
|
11
|
-
*
|
|
12
|
-
* No plugin preset is used — all rules are hand-picked from existing plugins
|
|
13
|
-
* and tightened beyond their defaults for AI-generated code.
|
|
14
|
-
* @see ADR-0006: docs/adr/0006-ai-mode-as-dedicated-flag.md
|
|
15
|
-
*/
|
|
16
|
-
declare function aiConfig(opts?: {
|
|
17
|
-
react?: boolean;
|
|
18
|
-
}): FlatConfigArray;
|
|
4
|
+
declare function composeConfig(opts: ConfigOptions): FlatConfigArray;
|
|
5
|
+
|
|
6
|
+
declare function aiConfig(): FlatConfigArray;
|
|
19
7
|
|
|
20
8
|
/**
|
|
21
9
|
* Base ESLint config — extends `eslint.configs.recommended` with additional
|
|
@@ -27,7 +15,9 @@ declare function aiConfig(opts?: {
|
|
|
27
15
|
* Preset: `@eslint/js` recommended
|
|
28
16
|
* @see https://eslint.org/docs/latest/rules/
|
|
29
17
|
*/
|
|
30
|
-
declare function baseConfig(
|
|
18
|
+
declare function baseConfig(opts?: {
|
|
19
|
+
ai?: boolean;
|
|
20
|
+
}): FlatConfigArray;
|
|
31
21
|
|
|
32
22
|
/**
|
|
33
23
|
* CSpell config — spell checking for identifiers and comments.
|
|
@@ -72,7 +62,9 @@ declare function importsConfig(): FlatConfigArray;
|
|
|
72
62
|
* - param/return descriptions downgraded to warn — helpful but not blocking
|
|
73
63
|
* @see https://github.com/gajus/eslint-plugin-jsdoc#rules
|
|
74
64
|
*/
|
|
75
|
-
declare function jsdocConfig(
|
|
65
|
+
declare function jsdocConfig(opts?: {
|
|
66
|
+
ai?: boolean;
|
|
67
|
+
}): FlatConfigArray;
|
|
76
68
|
|
|
77
69
|
/**
|
|
78
70
|
* JSON/JSONC config — native JSON linting using the official `@eslint/json` plugin.
|
|
@@ -103,7 +95,9 @@ declare function markdownConfig(): FlatConfigArray;
|
|
|
103
95
|
*
|
|
104
96
|
* @see https://github.com/eslint-community/eslint-plugin-n#-rules
|
|
105
97
|
*/
|
|
106
|
-
declare function nodeConfig(
|
|
98
|
+
declare function nodeConfig(opts?: {
|
|
99
|
+
ai?: boolean;
|
|
100
|
+
}): FlatConfigArray;
|
|
107
101
|
|
|
108
102
|
/**
|
|
109
103
|
* Package.json config — semantic validation of package.json files.
|
|
@@ -168,19 +162,21 @@ declare function prettierCompatConfig(): FlatConfigArray;
|
|
|
168
162
|
* React config — React 19+, Hooks, JSX accessibility, and Web API leak detection.
|
|
169
163
|
*
|
|
170
164
|
* Uses `@eslint-react` (eslint-plugin-react-x) as the primary React linting plugin,
|
|
171
|
-
* replacing the unmaintained eslint-plugin-react.
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
* and `node` (eslint-plugin-n).
|
|
165
|
+
* replacing the unmaintained eslint-plugin-react. All rules — including DOM, Web API,
|
|
166
|
+
* naming-convention, and RSC sub-plugins — are registered under a single `react/`
|
|
167
|
+
* namespace via the react-compat plugin for maximum OxLint compatibility.
|
|
175
168
|
*
|
|
176
|
-
*
|
|
169
|
+
* Base rule severities come from the `recommended` + `strict` presets via
|
|
170
|
+
* `createConfig`. When `ai: true`, preset "warn" rules that AI should always
|
|
171
|
+
* get right are promoted to "error" — validated at build time.
|
|
177
172
|
*
|
|
178
173
|
* @see https://eslint-react.xyz/docs/rules/overview
|
|
179
|
-
* @see https://github.com/facebook/react/tree/main/packages/eslint-plugin-react-hooks
|
|
180
174
|
* @see https://github.com/ArnaudBarre/eslint-plugin-react-refresh
|
|
181
175
|
* @see https://github.com/jsx-eslint/eslint-plugin-jsx-a11y#supported-rules
|
|
182
176
|
*/
|
|
183
|
-
declare function reactConfig(
|
|
177
|
+
declare function reactConfig(opts?: {
|
|
178
|
+
ai?: boolean;
|
|
179
|
+
}): FlatConfigArray;
|
|
184
180
|
|
|
185
181
|
/**
|
|
186
182
|
* React effect config — catches unnecessary useEffect anti-patterns.
|
|
@@ -204,7 +200,9 @@ declare function reactEffectConfig(): FlatConfigArray;
|
|
|
204
200
|
* @see https://ota-meshi.github.io/eslint-plugin-regexp/
|
|
205
201
|
* @see https://ota-meshi.github.io/eslint-plugin-regexp/rules/
|
|
206
202
|
*/
|
|
207
|
-
declare function regexpConfig(
|
|
203
|
+
declare function regexpConfig(opts?: {
|
|
204
|
+
ai?: boolean;
|
|
205
|
+
}): FlatConfigArray;
|
|
208
206
|
|
|
209
207
|
/**
|
|
210
208
|
* Security config — Node.js security patterns from eslint-plugin-security.
|
|
@@ -223,7 +221,9 @@ declare function securityConfig(): FlatConfigArray;
|
|
|
223
221
|
*
|
|
224
222
|
* @see https://github.com/SonarSource/SonarJS/tree/master/packages/jsts/src/rules#readme
|
|
225
223
|
*/
|
|
226
|
-
declare function sonarjsConfig(
|
|
224
|
+
declare function sonarjsConfig(opts?: {
|
|
225
|
+
ai?: boolean;
|
|
226
|
+
}): FlatConfigArray;
|
|
227
227
|
|
|
228
228
|
/**
|
|
229
229
|
* TypeScript config — extends typescript-eslint strict presets with project-wide type checking.
|
|
@@ -238,7 +238,10 @@ declare function sonarjsConfig(): FlatConfigArray;
|
|
|
238
238
|
* @see https://typescript-eslint.io/getting-started/
|
|
239
239
|
* @see https://typescript-eslint.io/rules/
|
|
240
240
|
*/
|
|
241
|
-
declare function typescriptConfig(
|
|
241
|
+
declare function typescriptConfig(opts?: {
|
|
242
|
+
ai?: boolean;
|
|
243
|
+
react?: boolean;
|
|
244
|
+
}): FlatConfigArray;
|
|
242
245
|
|
|
243
246
|
/**
|
|
244
247
|
* Unicorn config — modern JavaScript idioms and best practices.
|
|
@@ -248,7 +251,9 @@ declare function typescriptConfig(): FlatConfigArray;
|
|
|
248
251
|
*
|
|
249
252
|
* @see https://github.com/sindresorhus/eslint-plugin-unicorn#rules
|
|
250
253
|
*/
|
|
251
|
-
declare function unicornConfig(
|
|
254
|
+
declare function unicornConfig(opts?: {
|
|
255
|
+
ai?: boolean;
|
|
256
|
+
}): FlatConfigArray;
|
|
252
257
|
|
|
253
258
|
/**
|
|
254
259
|
* Config file overrides — relaxed rules for tool configuration files.
|
|
@@ -304,13 +309,6 @@ declare function storiesOverride(): FlatConfigArray;
|
|
|
304
309
|
*/
|
|
305
310
|
declare function testsOverride(): FlatConfigArray;
|
|
306
311
|
|
|
307
|
-
/**
|
|
308
|
-
* Complexity preset — limits for production code that encourage small,
|
|
309
|
-
* focused functions and aggressive extraction of helper functions.
|
|
310
|
-
* @see https://eslint.org/docs/latest/rules/#suggestions (complexity rules)
|
|
311
|
-
*/
|
|
312
|
-
declare function standardComplexity(): FlatConfigArray;
|
|
313
|
-
|
|
314
312
|
/**
|
|
315
313
|
* Appends eslint-plugin-oxlint configs that disable all ESLint rules
|
|
316
314
|
* already covered by OxLint. Must be the LAST config in the array.
|
|
@@ -321,9 +319,10 @@ declare function standardComplexity(): FlatConfigArray;
|
|
|
321
319
|
declare function oxlintIntegration(opts: ConfigOptions): FlatConfigArray;
|
|
322
320
|
|
|
323
321
|
/**
|
|
324
|
-
*
|
|
325
|
-
*
|
|
322
|
+
* Complexity preset — limits for production code that encourage small,
|
|
323
|
+
* focused functions and aggressive extraction of helper functions.
|
|
324
|
+
* @see https://eslint.org/docs/latest/rules/#suggestions (complexity rules)
|
|
326
325
|
*/
|
|
327
|
-
declare function
|
|
326
|
+
declare function standardComplexity(): FlatConfigArray;
|
|
328
327
|
|
|
329
328
|
export { aiConfig as ai, baseConfig as base, composeConfig, configFilesOverride as configFiles, cspellConfig as cspell, deMorganConfig as deMorgan, declarationsOverride as declarations, e2eOverride as e2e, importsConfig as imports, jsdocConfig as jsdoc, jsonConfig as json, markdownConfig as markdown, nodeConfig as node, oxlintIntegration as oxlint, packageJsonConfig as packageJson, packageJsonAiConfig as packageJsonAi, perfectionistConfig as perfectionist, perfectionistAiConfig as perfectionistAi, prettierCompatConfig as prettier, reactConfig as react, reactEffectConfig as reactEffect, regexpConfig as regexp, scriptsOverride as scripts, securityConfig as security, sonarjsConfig as sonarjs, standardComplexity, storiesOverride as stories, testsOverride as tests, typescriptConfig as typescript, unicornConfig as unicorn };
|