@santi020k/eslint-config-basic 3.1.0 → 3.2.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 +26 -0
- package/IMPROVEMENTS.md +270 -0
- package/dist/cli-migration.js +367 -15
- package/dist/cli-preset.d.ts +31 -0
- package/dist/cli-preset.js +315 -0
- package/dist/cli.d.ts +13 -1
- package/dist/cli.js +359 -49
- package/dist/define-config-metadata.d.ts +10 -0
- package/dist/define-config-metadata.js +18 -0
- package/dist/frameworks.js +4 -1
- package/dist/index.d.ts +8 -2
- package/dist/index.js +63 -6
- package/dist/integrations.js +3 -1
- package/dist/optional-package-errors.d.ts +3 -0
- package/dist/optional-package-errors.js +14 -0
- package/package.json +8 -7
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
|
-
import { EslintConfigOptions, ConfigInput
|
|
1
|
+
import { FlatConfigArray, EslintConfigOptions, ConfigInput } from '@santi020k/eslint-config-core';
|
|
2
2
|
export { DetectedFrameworkName, DetectionOptions, EslintConfigOptions, Extension, ExtensionName, ExtensionOption, FlatConfigArray, Format, FormatName, FormatOption, ImportGroupOptions, ImportedFramework, Library, LibraryName, LibraryOption, NextMode, NextModeName, NextModeOption, OptionalConfigMap, OptionalConfigName, Preset, PresetName, PresetOption, ProjectConfigOptions, ReactConfigKeys, Runtime, RuntimeName, RuntimeOption, Setting, SettingName, SettingOption, StrictMode, Testing, TestingName, TestingOption, Tool, ToolName, ToolOption, TypeScriptMode, TypeScriptOptions, coreConfig, createCoreConfig, createGitignoreConfig, createImportGroups, detectProjectOptions, getGlobalsForRuntime, groups, hasReactConfig } from '@santi020k/eslint-config-core';
|
|
3
3
|
export { angular, astro, expo, hono, lit, nest, next, nuxt, preact, qwik, react, reactRouter, slidev, solid, svelte, tanstackStart, vite, vue } from './frameworks.js';
|
|
4
4
|
export { typescriptConfig } from '@santi020k/eslint-config-typescript';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Copies already-loaded plugin objects onto rule blocks that reference them.
|
|
8
|
+
* ESLint 10 validates plugin availability per effective config object, while
|
|
9
|
+
* feature packs often keep plugin setup and consumer overrides separate.
|
|
10
|
+
*/
|
|
11
|
+
declare const attachReferencedPlugins: (configs: FlatConfigArray) => FlatConfigArray;
|
|
6
12
|
/**
|
|
7
13
|
* Generates the ESLint configuration array, applying configurations
|
|
8
14
|
* and integration settings based on the input configuration.
|
|
@@ -13,4 +19,4 @@ export { typescriptConfig } from '@santi020k/eslint-config-typescript';
|
|
|
13
19
|
*/
|
|
14
20
|
declare const defineConfig: (options?: EslintConfigOptions, ...extraConfigs: ConfigInput[]) => Promise<FlatConfigArray>;
|
|
15
21
|
|
|
16
|
-
export { defineConfig };
|
|
22
|
+
export { attachReferencedPlugins, defineConfig };
|
package/dist/index.js
CHANGED
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
Testing
|
|
30
30
|
} from "@santi020k/eslint-config-core";
|
|
31
31
|
import { createTypescriptConfig } from "@santi020k/eslint-config-typescript";
|
|
32
|
+
import { attachDefineConfigMetadata } from "./define-config-metadata.js";
|
|
32
33
|
import { createDetectedFrameworkFlags } from "./frameworks.js";
|
|
33
34
|
import { getIntegrationConfigs, getPrettierConfig } from "./integrations.js";
|
|
34
35
|
import { resolveFramework, resolvePreset } from "./resolvers.js";
|
|
@@ -266,6 +267,16 @@ const buildEslintConfigs = async (params) => {
|
|
|
266
267
|
{ hasReact, hasSolid, hasSvelte, hasVue, runtime, tsconfigRootDir }
|
|
267
268
|
);
|
|
268
269
|
const get = (name) => fw[name] ?? [];
|
|
270
|
+
const typescriptConfigs = resolvedTypescript ? createTypescriptConfig({
|
|
271
|
+
...resolvedTypescript,
|
|
272
|
+
tsconfigRootDir: resolvedTypescript.tsconfigRootDir ?? tsconfigRootDir
|
|
273
|
+
}) : [];
|
|
274
|
+
const untypedTypescriptConfigs = typescriptConfigs.filter(
|
|
275
|
+
(config) => config.name === "eslint-config-typescript/untyped-files"
|
|
276
|
+
);
|
|
277
|
+
const typedTypescriptConfigs = typescriptConfigs.filter(
|
|
278
|
+
(config) => config.name !== "eslint-config-typescript/untyped-files"
|
|
279
|
+
);
|
|
269
280
|
return [
|
|
270
281
|
...defaultIgnores,
|
|
271
282
|
...userIgnores,
|
|
@@ -306,10 +317,7 @@ const buildEslintConfigs = async (params) => {
|
|
|
306
317
|
...get("lit"),
|
|
307
318
|
...get("slidev"),
|
|
308
319
|
...get("vite"),
|
|
309
|
-
...
|
|
310
|
-
...resolvedTypescript,
|
|
311
|
-
tsconfigRootDir: resolvedTypescript.tsconfigRootDir ?? tsconfigRootDir
|
|
312
|
-
}) : [],
|
|
320
|
+
...typedTypescriptConfigs,
|
|
313
321
|
...get("astro"),
|
|
314
322
|
...resolvedFrameworks.next && nextMode === NextMode.AppRouter ? [{
|
|
315
323
|
files: ["app/**/*.{ts,tsx}", "src/**/*.{ts,tsx}"],
|
|
@@ -329,6 +337,7 @@ const buildEslintConfigs = async (params) => {
|
|
|
329
337
|
}
|
|
330
338
|
},
|
|
331
339
|
...tailwindOptions ? [buildTailwindSettingsConfig(tailwindOptions)] : [],
|
|
340
|
+
...untypedTypescriptConfigs,
|
|
332
341
|
...await getPrettierConfig(uniqueTools)
|
|
333
342
|
];
|
|
334
343
|
};
|
|
@@ -387,6 +396,52 @@ const resolveProjectConfigs = async (configuredProjects, projectDefaults, detect
|
|
|
387
396
|
return scopedConfigs.map((config) => config.name === "eslint-config/gitignore" ? config : scopeConfigToProject(config, projectPath));
|
|
388
397
|
})
|
|
389
398
|
);
|
|
399
|
+
const resolveInheritedProjectDefaults = (options) => mergeProjectOptions(
|
|
400
|
+
{
|
|
401
|
+
...options?.detection === void 0 ? {} : { detection: options.detection },
|
|
402
|
+
...options?.tailwind === void 0 ? {} : { tailwind: options.tailwind }
|
|
403
|
+
},
|
|
404
|
+
options?.projectDefaults ?? {}
|
|
405
|
+
);
|
|
406
|
+
const getPluginNameFromRule = (ruleName, availablePluginNames) => {
|
|
407
|
+
const segments = ruleName.split("/");
|
|
408
|
+
if (segments.length < 2) return void 0;
|
|
409
|
+
const registeredPrefix = [...availablePluginNames].filter((pluginName) => ruleName.startsWith(`${pluginName}/`)).sort((left, right) => right.length - left.length)[0];
|
|
410
|
+
if (registeredPrefix) return registeredPrefix;
|
|
411
|
+
return ruleName.startsWith("@") && segments.length > 2 ? segments.slice(0, 2).join("/") : segments[0];
|
|
412
|
+
};
|
|
413
|
+
const attachReferencedPlugins = (configs) => {
|
|
414
|
+
const availablePlugins = /* @__PURE__ */ new Map();
|
|
415
|
+
const ambiguousPluginNames = /* @__PURE__ */ new Set();
|
|
416
|
+
for (const config of configs) {
|
|
417
|
+
for (const [pluginName, plugin] of Object.entries(config.plugins ?? {})) {
|
|
418
|
+
const existingPlugin = availablePlugins.get(pluginName);
|
|
419
|
+
if (existingPlugin && existingPlugin !== plugin) {
|
|
420
|
+
availablePlugins.delete(pluginName);
|
|
421
|
+
ambiguousPluginNames.add(pluginName);
|
|
422
|
+
} else if (!ambiguousPluginNames.has(pluginName)) {
|
|
423
|
+
availablePlugins.set(pluginName, plugin);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
return configs.map((config) => {
|
|
428
|
+
const requiredPlugins = new Set(
|
|
429
|
+
Object.keys(config.rules ?? {}).map((ruleName) => getPluginNameFromRule(ruleName, availablePlugins.keys())).filter((pluginName) => pluginName !== void 0)
|
|
430
|
+
);
|
|
431
|
+
const missingPluginEntries = [...requiredPlugins].flatMap((pluginName) => {
|
|
432
|
+
const plugin = availablePlugins.get(pluginName);
|
|
433
|
+
return !Object.hasOwn(config.plugins ?? {}, pluginName) && plugin ? [[pluginName, plugin]] : [];
|
|
434
|
+
});
|
|
435
|
+
if (missingPluginEntries.length === 0) return config;
|
|
436
|
+
return {
|
|
437
|
+
...config,
|
|
438
|
+
plugins: {
|
|
439
|
+
...config.plugins,
|
|
440
|
+
...Object.fromEntries(missingPluginEntries)
|
|
441
|
+
}
|
|
442
|
+
};
|
|
443
|
+
});
|
|
444
|
+
};
|
|
390
445
|
const getConfigsParams = (options, rootDir, runtime, uniqueLibraries, uniqueSettings, resolvedFrameworks) => {
|
|
391
446
|
const hasReact = !!resolvedFrameworks.react;
|
|
392
447
|
const hasVue = !!resolvedFrameworks.vue;
|
|
@@ -528,13 +583,14 @@ const defineConfig = async (options, ...extraConfigs) => {
|
|
|
528
583
|
});
|
|
529
584
|
const projectConfigs = await resolveProjectConfigs(
|
|
530
585
|
configuredProjects,
|
|
531
|
-
options
|
|
586
|
+
resolveInheritedProjectDefaults(options),
|
|
532
587
|
detectRootDir,
|
|
533
588
|
options?.autoFrameworks
|
|
534
589
|
);
|
|
535
590
|
const allConfigs = [...configs, ...projectConfigs.flat(), ...flattenConfigInputs(extraConfigs)];
|
|
536
591
|
const patchedConfigs = workspacePrefixes?.length ? patchImportGroups(allConfigs, workspacePrefixes) : allConfigs;
|
|
537
|
-
|
|
592
|
+
const finalConfig = attachReferencedPlugins(applyStrictMode(patchedConfigs, strict));
|
|
593
|
+
return attachDefineConfigMetadata(finalConfig, { extraConfigs, options });
|
|
538
594
|
};
|
|
539
595
|
export {
|
|
540
596
|
Extension2 as Extension,
|
|
@@ -549,6 +605,7 @@ export {
|
|
|
549
605
|
Tool,
|
|
550
606
|
angular,
|
|
551
607
|
astro,
|
|
608
|
+
attachReferencedPlugins,
|
|
552
609
|
coreConfig2 as coreConfig,
|
|
553
610
|
createCoreConfig2 as createCoreConfig,
|
|
554
611
|
createGitignoreConfig2 as createGitignoreConfig,
|
package/dist/integrations.js
CHANGED
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
createModuleLoader,
|
|
3
3
|
resolveConfigFeatures
|
|
4
4
|
} from "@santi020k/eslint-config-core";
|
|
5
|
+
import { isMissingRequestedPackage } from "./optional-package-errors.js";
|
|
5
6
|
const loadModule = createModuleLoader((specifier) => import.meta.resolve(specifier, import.meta.url));
|
|
6
7
|
const packCache = /* @__PURE__ */ new Map();
|
|
7
8
|
const loadFeaturePack = async (specifier) => {
|
|
@@ -18,8 +19,9 @@ const loadFeaturePack = async (specifier) => {
|
|
|
18
19
|
return module.features;
|
|
19
20
|
} catch (error) {
|
|
20
21
|
packCache.delete(specifier);
|
|
22
|
+
const remediation = isMissingRequestedPackage(error, specifier) ? "Install it for the selected options, or remove those options from defineConfig()." : "The installed feature pack failed while evaluating. Inspect this error's cause for the original dependency or runtime failure.";
|
|
21
23
|
throw new Error(
|
|
22
|
-
`Unable to load optional feature pack "${specifier}".
|
|
24
|
+
`Unable to load optional feature pack "${specifier}". ` + remediation,
|
|
23
25
|
{ cause: error }
|
|
24
26
|
);
|
|
25
27
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const getPackageRoot = (specifier) => {
|
|
2
|
+
const segments = specifier.split("/");
|
|
3
|
+
return specifier.startsWith("@") ? segments.slice(0, 2).join("/") : segments[0];
|
|
4
|
+
};
|
|
5
|
+
const isMissingRequestedPackage = (error, specifier) => {
|
|
6
|
+
if (!(error instanceof Error)) return false;
|
|
7
|
+
const code = "code" in error ? String(error.code) : "";
|
|
8
|
+
if (code !== "ERR_MODULE_NOT_FOUND" && code !== "MODULE_NOT_FOUND") return false;
|
|
9
|
+
const missingSpecifier = /Cannot find (?:module|package) ['"]([^'"]+)['"]/.exec(error.message)?.[1];
|
|
10
|
+
return missingSpecifier !== void 0 && getPackageRoot(missingSpecifier) === getPackageRoot(specifier);
|
|
11
|
+
};
|
|
12
|
+
export {
|
|
13
|
+
isMissingRequestedPackage
|
|
14
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@santi020k/eslint-config-basic",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public",
|
|
6
6
|
"provenance": true
|
|
@@ -30,7 +30,8 @@
|
|
|
30
30
|
"files": [
|
|
31
31
|
"dist",
|
|
32
32
|
"README.md",
|
|
33
|
-
"CHANGELOG.md"
|
|
33
|
+
"CHANGELOG.md",
|
|
34
|
+
"IMPROVEMENTS.md"
|
|
34
35
|
],
|
|
35
36
|
"bin": {
|
|
36
37
|
"basic-eslint": "./dist/cli.js"
|
|
@@ -39,16 +40,16 @@
|
|
|
39
40
|
"@typescript-eslint/utils": "^8.65.0",
|
|
40
41
|
"semver": "^7.8.5",
|
|
41
42
|
"@santi020k/eslint-config-core": "^3.1.0",
|
|
42
|
-
"@santi020k/eslint-config-typescript": "^3.1.
|
|
43
|
+
"@santi020k/eslint-config-typescript": "^3.1.1"
|
|
43
44
|
},
|
|
44
45
|
"devDependencies": {
|
|
45
46
|
"@types/node": "^26.1.2",
|
|
46
47
|
"publint": "^0.3.22",
|
|
47
48
|
"tsup": "^8.5.1",
|
|
48
49
|
"typescript": "^6.0.3",
|
|
49
|
-
"@santi020k/eslint-config-angular": "^3.1.0",
|
|
50
50
|
"@santi020k/eslint-config-astro": "^3.1.0",
|
|
51
51
|
"@santi020k/eslint-config-expo": "^3.1.0",
|
|
52
|
+
"@santi020k/eslint-config-angular": "^3.1.0",
|
|
52
53
|
"@santi020k/eslint-config-extensions": "^3.1.0",
|
|
53
54
|
"@santi020k/eslint-config-formats": "^3.1.0",
|
|
54
55
|
"@santi020k/eslint-config-hono": "^3.1.0",
|
|
@@ -73,9 +74,9 @@
|
|
|
73
74
|
"peerDependencies": {
|
|
74
75
|
"eslint": "^10.0.0",
|
|
75
76
|
"typescript": ">=5.0.0",
|
|
76
|
-
"@santi020k/eslint-config-angular": "^3.1.0",
|
|
77
77
|
"@santi020k/eslint-config-astro": "^3.1.0",
|
|
78
78
|
"@santi020k/eslint-config-expo": "^3.1.0",
|
|
79
|
+
"@santi020k/eslint-config-angular": "^3.1.0",
|
|
79
80
|
"@santi020k/eslint-config-extensions": "^3.1.0",
|
|
80
81
|
"@santi020k/eslint-config-formats": "^3.1.0",
|
|
81
82
|
"@santi020k/eslint-config-hono": "^3.1.0",
|
|
@@ -93,9 +94,9 @@
|
|
|
93
94
|
"@santi020k/eslint-config-svelte": "^3.1.0",
|
|
94
95
|
"@santi020k/eslint-config-tanstack-start": "^3.1.0",
|
|
95
96
|
"@santi020k/eslint-config-testing": "^3.1.0",
|
|
96
|
-
"@santi020k/eslint-config-tools": "^3.1.0",
|
|
97
97
|
"@santi020k/eslint-config-vite": "^3.1.0",
|
|
98
|
-
"@santi020k/eslint-config-vue": "^3.1.0"
|
|
98
|
+
"@santi020k/eslint-config-vue": "^3.1.0",
|
|
99
|
+
"@santi020k/eslint-config-tools": "^3.1.0"
|
|
99
100
|
},
|
|
100
101
|
"peerDependenciesMeta": {
|
|
101
102
|
"@santi020k/eslint-config-angular": {
|