@santi020k/eslint-config-basic 3.0.0 → 3.1.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.
@@ -30,29 +30,5 @@ declare const svelte: (options?: FrameworkOptions) => Promise<FlatConfigArray>;
30
30
  declare const tanstackStart: (options?: FrameworkOptions) => Promise<FlatConfigArray>;
31
31
  declare const vite: (options?: FrameworkOptions) => Promise<FlatConfigArray>;
32
32
  declare const vue: (options?: FrameworkOptions) => Promise<FlatConfigArray>;
33
- /**
34
- * @deprecated Remix merged into React Router v7. Use `reactRouter` (the
35
- * `react-router` framework key) instead. This alias loads the legacy Remix
36
- * config and will be removed in the next major version.
37
- */
38
- declare const remix: (options?: FrameworkOptions) => Promise<FlatConfigArray>;
39
- /** @deprecated Use `angular` instead. */
40
- declare const angularConfig: (options?: FrameworkOptions) => Promise<FlatConfigArray>;
41
- /** @deprecated Use `expo` instead. */
42
- declare const expoConfig: (options?: FrameworkOptions) => Promise<FlatConfigArray>;
43
- /** @deprecated Use `nest` instead. */
44
- declare const nestConfig: (options?: FrameworkOptions) => Promise<FlatConfigArray>;
45
- /** @deprecated Use `next` instead. */
46
- declare const nextConfig: (options?: FrameworkOptions) => Promise<FlatConfigArray>;
47
- /** @deprecated Use `preact` instead. */
48
- declare const preactConfig: (options?: FrameworkOptions) => Promise<FlatConfigArray>;
49
- /** @deprecated Use `react` instead. */
50
- declare const reactConfig: (options?: FrameworkOptions) => Promise<FlatConfigArray>;
51
- /** @deprecated Use `solid` instead. */
52
- declare const solidConfig: (options?: FrameworkOptions) => Promise<FlatConfigArray>;
53
- /** @deprecated Use `svelte` instead. */
54
- declare const svelteConfig: (options?: FrameworkOptions) => Promise<FlatConfigArray>;
55
- /** @deprecated Use `vue` instead. */
56
- declare const vueConfig: (options?: FrameworkOptions) => Promise<FlatConfigArray>;
57
33
 
58
- export { type FrameworkFlags, type FrameworkName, type FrameworkOptions, angular, angularConfig, astro, createDetectedFrameworkFlags, expo, expoConfig, getBundledFrameworkConfig, hono, lit, nest, nestConfig, next, nextConfig, nuxt, preact, preactConfig, qwik, react, reactConfig, reactRouter, remix, slidev, solid, solidConfig, svelte, svelteConfig, tanstackStart, vite, vue, vueConfig };
34
+ export { type FrameworkFlags, type FrameworkName, type FrameworkOptions, angular, astro, createDetectedFrameworkFlags, expo, getBundledFrameworkConfig, hono, lit, nest, next, nuxt, preact, qwik, react, reactRouter, slidev, solid, svelte, tanstackStart, vite, vue };
@@ -18,7 +18,6 @@ const frameworkLoaders = /* @__PURE__ */ new Map([
18
18
  ["qwik", async () => (await loadModule("@santi020k/eslint-config-qwik")).qwik],
19
19
  ["react", async () => (await loadModule("@santi020k/eslint-config-react")).reactConfig],
20
20
  ["react-router", async () => (await loadModule("@santi020k/eslint-config-react-router")).reactRouter],
21
- ["remix", async () => (await loadModule("@santi020k/eslint-config-remix")).default],
22
21
  ["slidev", async () => (await loadModule("@santi020k/eslint-config-slidev")).slidev],
23
22
  ["solid", async () => (await loadModule("@santi020k/eslint-config-solid")).solidConfig],
24
23
  ["svelte", async () => (await loadModule("@santi020k/eslint-config-svelte")).svelteConfig],
@@ -35,7 +34,7 @@ const loadFrameworkConfigInput = (frameworkName) => {
35
34
  const pending = loader().catch((error) => {
36
35
  frameworkConfigCache.delete(frameworkName);
37
36
  throw new Error(
38
- `Unable to load optional framework config "${frameworkName}". Install "@santi020k/eslint-config-${frameworkName}" or remove that framework from your eslintConfig options.`,
37
+ `Unable to load optional framework config "${frameworkName}". Install "@santi020k/eslint-config-${frameworkName}" or remove that framework from your defineConfig options.`,
39
38
  { cause: error }
40
39
  );
41
40
  });
@@ -65,45 +64,25 @@ const svelte = createBundledFramework("svelte");
65
64
  const tanstackStart = createBundledFramework("tanstack-start");
66
65
  const vite = createBundledFramework("vite");
67
66
  const vue = createBundledFramework("vue");
68
- const remix = createBundledFramework("remix");
69
- const angularConfig = angular;
70
- const expoConfig = expo;
71
- const nestConfig = nest;
72
- const nextConfig = next;
73
- const preactConfig = preact;
74
- const reactConfig = react;
75
- const solidConfig = solid;
76
- const svelteConfig = svelte;
77
- const vueConfig = vue;
78
67
  export {
79
68
  angular,
80
- angularConfig,
81
69
  astro,
82
70
  createDetectedFrameworkFlags,
83
71
  expo,
84
- expoConfig,
85
72
  getBundledFrameworkConfig,
86
73
  hono,
87
74
  lit,
88
75
  nest,
89
- nestConfig,
90
76
  next,
91
- nextConfig,
92
77
  nuxt,
93
78
  preact,
94
- preactConfig,
95
79
  qwik,
96
80
  react,
97
- reactConfig,
98
81
  reactRouter,
99
- remix,
100
82
  slidev,
101
83
  solid,
102
- solidConfig,
103
84
  svelte,
104
- svelteConfig,
105
85
  tanstackStart,
106
86
  vite,
107
- vue,
108
- vueConfig
87
+ vue
109
88
  };
package/dist/index.d.ts CHANGED
@@ -1,8 +1,7 @@
1
1
  import { EslintConfigOptions, ConfigInput, FlatConfigArray } from '@santi020k/eslint-config-core';
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, createImportGroups, detectProjectOptions, getGlobalsForRuntime, gitignore, groups, hasReactConfig, jsConfig } from '@santi020k/eslint-config-core';
3
- export { AGENT_TARGETS, AgentTarget, EslintConfigFeatures, GenerateSkillOptions, GenerateSkillResult, generateAgentSkills, generateSkillContent } from './agent-skill-generator.js';
4
- export { angular, angularConfig, astro, expo, expoConfig, hono, lit, nest, nestConfig, next, nextConfig, nuxt, preact, preactConfig, qwik, react, reactConfig, reactRouter, remix, slidev, solid, solidConfig, svelte, svelteConfig, tanstackStart, vite, vue, vueConfig } from './frameworks.js';
5
- export { tsConfig, typescriptConfig } from '@santi020k/eslint-config-typescript';
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
+ export { angular, astro, expo, hono, lit, nest, next, nuxt, preact, qwik, react, reactRouter, slidev, solid, svelte, tanstackStart, vite, vue } from './frameworks.js';
4
+ export { typescriptConfig } from '@santi020k/eslint-config-typescript';
6
5
 
7
6
  /**
8
7
  * Generates the ESLint configuration array, applying configurations
@@ -12,10 +11,6 @@ export { tsConfig, typescriptConfig } from '@santi020k/eslint-config-typescript'
12
11
  * @param {ConfigInput[]} extraConfigs - Local flat-config overrides appended after generated config
13
12
  * @returns {FlatConfigArray} The final ESLint configuration array
14
13
  */
15
- declare const eslintConfig: (options?: EslintConfigOptions, ...extraConfigs: ConfigInput[]) => Promise<FlatConfigArray>;
16
- /**
17
- * Alias for `eslintConfig()` that reads naturally in `eslint.config.*` files.
18
- */
19
14
  declare const defineConfig: (options?: EslintConfigOptions, ...extraConfigs: ConfigInput[]) => Promise<FlatConfigArray>;
20
15
 
21
- export { defineConfig, eslintConfig };
16
+ export { defineConfig };
package/dist/index.js CHANGED
@@ -1,10 +1,12 @@
1
- import { join } from "node:path";
1
+ import { dirname, join } from "node:path";
2
+ import { fileURLToPath } from "node:url";
2
3
  import {
3
4
  applyDetectionControls,
4
5
  applyStrictMode,
5
6
  applyStrictProfileDefaults,
6
7
  coreConfig,
7
8
  createCoreConfig,
9
+ createGitignoreConfig,
8
10
  DEFAULT_IGNORES,
9
11
  detectProjectOptions,
10
12
  Extension,
@@ -12,7 +14,6 @@ import {
12
14
  flattenConfigInputs,
13
15
  GENERATED_CODE_IGNORES,
14
16
  getStrictMode,
15
- gitignore,
16
17
  Library,
17
18
  mergeFrameworkOption,
18
19
  mergeOptionalBucket,
@@ -32,53 +33,37 @@ import { createDetectedFrameworkFlags } from "./frameworks.js";
32
33
  import { getIntegrationConfigs, getPrettierConfig } from "./integrations.js";
33
34
  import { resolveFramework, resolvePreset } from "./resolvers.js";
34
35
  import { buildTailwindSettingsConfig } from "./tailwind.js";
35
- import {
36
- AGENT_TARGETS,
37
- generateAgentSkills,
38
- generateSkillContent
39
- } from "./agent-skill-generator.js";
40
36
  import {
41
37
  angular,
42
- angularConfig,
43
38
  astro,
44
39
  expo,
45
- expoConfig,
46
40
  hono,
47
41
  lit,
48
42
  nest,
49
- nestConfig,
50
43
  next,
51
- nextConfig,
52
44
  nuxt,
53
45
  preact,
54
- preactConfig,
55
46
  qwik,
56
47
  react,
57
- reactConfig,
58
48
  reactRouter,
59
- remix,
60
49
  slidev,
61
50
  solid,
62
- solidConfig,
63
51
  svelte,
64
- svelteConfig,
65
52
  tanstackStart,
66
53
  vite,
67
- vue,
68
- vueConfig
54
+ vue
69
55
  } from "./frameworks.js";
70
56
  import {
71
57
  coreConfig as coreConfig2,
72
58
  createCoreConfig as createCoreConfig2,
59
+ createGitignoreConfig as createGitignoreConfig2,
73
60
  createImportGroups,
74
61
  detectProjectOptions as detectProjectOptions2,
75
62
  Extension as Extension2,
76
63
  Format,
77
64
  getGlobalsForRuntime,
78
- gitignore as gitignore2,
79
65
  groups,
80
66
  hasReactConfig,
81
- jsConfig,
82
67
  Library as Library2,
83
68
  NextMode as NextMode2,
84
69
  Preset as Preset2,
@@ -88,7 +73,7 @@ import {
88
73
  Testing as Testing2,
89
74
  Tool
90
75
  } from "@santi020k/eslint-config-core";
91
- import { tsConfig, typescriptConfig } from "@santi020k/eslint-config-typescript";
76
+ import { typescriptConfig } from "@santi020k/eslint-config-typescript";
92
77
  const buildTailwindResult = (options, entryPoint, rootDir) => ({
93
78
  cwd: options.cwd ?? rootDir,
94
79
  detectComponentClasses: options.detectComponentClasses ?? true,
@@ -125,12 +110,52 @@ const applyTestingFileOverrides = (configs, testingFiles) => {
125
110
  };
126
111
  });
127
112
  };
128
- const resolveConfigSetup = (options) => ({
129
- autoFrameworks: options?.autoFrameworks ?? true,
130
- detectRootDir: options?.detectRootDir ?? options?.tsconfigRootDir,
131
- optionMergeStrategy: options?.optionMergeStrategy ?? "merge",
132
- requestedPreset: options?.preset
133
- });
113
+ const ESLINT_CONFIG_FILENAMES = [
114
+ "eslint.config.js",
115
+ "eslint.config.cjs",
116
+ "eslint.config.mjs",
117
+ "eslint.config.ts",
118
+ "eslint.config.cts",
119
+ "eslint.config.mts"
120
+ ];
121
+ const findConfigRootFromStack = (stack = new Error().stack) => {
122
+ if (!stack) return void 0;
123
+ for (const line of stack.split("\n")) {
124
+ const configFilename = ESLINT_CONFIG_FILENAMES.find((filename) => line.includes(filename));
125
+ if (!configFilename) continue;
126
+ const filenameStart = line.indexOf(configFilename);
127
+ const fileUrlStart = line.lastIndexOf("file://", filenameStart);
128
+ const windowsPathStart = line.slice(0, filenameStart).search(/[A-Za-z]:[\\/]/);
129
+ const absolutePathStart = line.indexOf("/");
130
+ let configPathStart = absolutePathStart;
131
+ if (windowsPathStart >= 0) configPathStart = windowsPathStart;
132
+ if (fileUrlStart >= 0) configPathStart = fileUrlStart;
133
+ try {
134
+ if (configPathStart < 0) continue;
135
+ const configPath = line.slice(configPathStart, filenameStart + configFilename.length);
136
+ return dirname(configPath.startsWith("file:") ? fileURLToPath(configPath) : configPath);
137
+ } catch {
138
+ }
139
+ }
140
+ return void 0;
141
+ };
142
+ const resolveConfigSetup = (options) => {
143
+ const {
144
+ autoFrameworks = true,
145
+ detectRootDir,
146
+ optionMergeStrategy = "merge",
147
+ preset: requestedPreset,
148
+ root,
149
+ tsconfigRootDir
150
+ } = options ?? {};
151
+ const implicitRootDir = root ?? detectRootDir ?? tsconfigRootDir ?? findConfigRootFromStack();
152
+ return {
153
+ autoFrameworks,
154
+ detectRootDir: implicitRootDir,
155
+ optionMergeStrategy,
156
+ requestedPreset
157
+ };
158
+ };
134
159
  const resolveUniqueLibraries = (libraries, tailwind) => {
135
160
  const uniqueLibraries = [...new Set(libraries)];
136
161
  if (tailwind === false) return uniqueLibraries.filter((library) => library !== Library.Tailwind);
@@ -154,12 +179,26 @@ const resolveBucketDefaults = (detected) => ({
154
179
  detectedTesting: detected.testing ?? [],
155
180
  detectedTools: detected.tools ?? []
156
181
  });
182
+ const scopeWorkspaceDetection = (detected, isWorkspace) => isWorkspace ? {
183
+ ...detected,
184
+ detectedFrameworks: [],
185
+ libraries: [],
186
+ nextMode: void 0,
187
+ runtime: Runtime.Universal
188
+ } : detected;
189
+ const resolveDetectedOptions = (detectRootDir, detection, requestedPreset) => {
190
+ const rawDetected = detectProjectOptions(detectRootDir);
191
+ const shouldDetectProjects = requestedPreset === Preset.Monorepo || rawDetected.preset === Preset.Monorepo;
192
+ const detected = applyDetectionControls(rawDetected, detection, { projects: shouldDetectProjects });
193
+ const hasDetectedProjects = Object.keys(detected.projects ?? {}).length > 0;
194
+ return scopeWorkspaceDetection(detected, hasDetectedProjects);
195
+ };
157
196
  const resolveNextModeValue = (options, presetDefaults, detected) => options?.nextMode ?? presetDefaults.nextMode ?? detected.nextMode ?? NextMode.Pages;
158
197
  const resolveRuntimeValue = (options, presetDefaults, detected, usePresetRuntime) => options?.runtime ?? (usePresetRuntime ? presetDefaults.runtime : void 0) ?? detected.runtime ?? Runtime.Universal;
159
198
  const resolveSettingsValue = (options, detected) => options?.settings ?? detected.settings ?? [];
160
199
  const resolveTypescriptValue = (options, presetDefaults, detected) => options?.typescript ?? presetDefaults.typescript ?? detected.typescript ?? false;
161
200
  const needsReactAutoAdd = (frameworks) => Boolean(
162
- frameworks.next ?? frameworks.expo ?? frameworks.remix ?? frameworks["react-router"] ?? (frameworks["tanstack-start"] && !frameworks.solid)
201
+ frameworks.next ?? frameworks.expo ?? frameworks["react-router"] ?? (frameworks["tanstack-start"] && !frameworks.solid)
163
202
  ) && !frameworks.react;
164
203
  const applyFrameworkImpliedDeps = (frameworks) => {
165
204
  const result = { ...frameworks };
@@ -168,12 +207,12 @@ const applyFrameworkImpliedDeps = (frameworks) => {
168
207
  if (result.nuxt && !result.vue) result.vue = true;
169
208
  return result;
170
209
  };
171
- const buildIgnoresConfig = (useDefaultIgnores, useGeneratedCodeIgnores, useGitignore, options) => ({
210
+ const buildIgnoresConfig = (useDefaultIgnores, useGeneratedCodeIgnores, useGitignore, options, rootDir) => ({
172
211
  defaultIgnores: useDefaultIgnores ? [{
173
212
  ignores: [...DEFAULT_IGNORES, ...useGeneratedCodeIgnores ? GENERATED_CODE_IGNORES : []],
174
213
  name: "eslint-config-basic/default-ignores"
175
214
  }] : [],
176
- gitignoreConfig: useGitignore ? gitignore : [],
215
+ gitignoreConfig: useGitignore ? createGitignoreConfig(rootDir) : [],
177
216
  userIgnores: options?.ignores?.length ? [{
178
217
  ignores: options.ignores,
179
218
  name: "eslint-config-basic/ignores"
@@ -260,7 +299,6 @@ const buildEslintConfigs = async (params) => {
260
299
  ...get("solid"),
261
300
  ...get("angular"),
262
301
  ...get("qwik"),
263
- ...get("remix"),
264
302
  ...get("react-router"),
265
303
  ...get("tanstack-start"),
266
304
  ...get("nuxt"),
@@ -329,11 +367,6 @@ const logEslintDebug = ({
329
367
  }, null, 2)}
330
368
  `);
331
369
  };
332
- const emitBasicWarnings = (options) => {
333
- if (options?.frameworks && "remix" in options.frameworks) {
334
- process.emitWarning('[eslint-config-basic] Warning: `frameworks.remix` is deprecated and will be removed in the next major. Please use `frameworks["react-router"]` instead.');
335
- }
336
- };
337
370
  const emitAstroDoctorWarning = (extensions, frameworks) => {
338
371
  if (!extensions.includes(Extension.AstroDoctor) || frameworks.astro) return;
339
372
  process.emitWarning(
@@ -344,15 +377,14 @@ const resolveProjectConfigs = async (configuredProjects, projectDefaults, detect
344
377
  Object.entries(configuredProjects).map(async ([projectPath, projectOptions]) => {
345
378
  const projectRoot = join(detectRootDir ?? process.cwd(), projectPath);
346
379
  const inheritedOptions = mergeProjectOptions(projectDefaults ?? {}, projectOptions);
347
- const scopedConfigs = await eslintConfig({
380
+ const scopedConfigs = await defineConfig({
348
381
  autoFrameworks,
349
382
  ...inheritedOptions,
350
- detectRootDir: inheritedOptions.detectRootDir ?? projectRoot,
351
383
  projectDefaults: void 0,
352
384
  projects: void 0,
353
- tsconfigRootDir: inheritedOptions.tsconfigRootDir ?? projectRoot
385
+ root: inheritedOptions.root ?? inheritedOptions.detectRootDir ?? projectRoot
354
386
  });
355
- return scopedConfigs.map((config) => scopeConfigToProject(config, projectPath));
387
+ return scopedConfigs.map((config) => config.name === "eslint-config/gitignore" ? config : scopeConfigToProject(config, projectPath));
356
388
  })
357
389
  );
358
390
  const getConfigsParams = (options, rootDir, runtime, uniqueLibraries, uniqueSettings, resolvedFrameworks) => {
@@ -365,7 +397,13 @@ const getConfigsParams = (options, rootDir, runtime, uniqueLibraries, uniqueSett
365
397
  const useGeneratedCodeIgnores = !uniqueSettings.includes(Setting.NoGeneratedCodeIgnores);
366
398
  const tailwindOptions = uniqueLibraries.includes(Library.Tailwind) ? resolveTailwindOptions(rootDir, options?.tailwind) : void 0;
367
399
  const runtimeCoreConfig = runtime === Runtime.Universal ? coreConfig : createCoreConfig(runtime);
368
- const { defaultIgnores, gitignoreConfig, userIgnores } = buildIgnoresConfig(useDefaultIgnores, useGeneratedCodeIgnores, useGitignore, options);
400
+ const { defaultIgnores, gitignoreConfig, userIgnores } = buildIgnoresConfig(
401
+ useDefaultIgnores,
402
+ useGeneratedCodeIgnores,
403
+ useGitignore,
404
+ options,
405
+ rootDir
406
+ );
369
407
  return {
370
408
  astroOptions: { hasReact, hasSolid, hasSvelte, hasVue },
371
409
  defaultIgnores,
@@ -375,8 +413,7 @@ const getConfigsParams = (options, rootDir, runtime, uniqueLibraries, uniqueSett
375
413
  userIgnores
376
414
  };
377
415
  };
378
- const eslintConfig = async (options, ...extraConfigs) => {
379
- emitBasicWarnings(options);
416
+ const defineConfig = async (options, ...extraConfigs) => {
380
417
  const {
381
418
  detection,
382
419
  extensions: optExtensions,
@@ -390,12 +427,7 @@ const eslintConfig = async (options, ...extraConfigs) => {
390
427
  workspacePrefixes
391
428
  } = options ?? {};
392
429
  const { autoFrameworks, detectRootDir, optionMergeStrategy, requestedPreset } = resolveConfigSetup(options);
393
- const shouldDefaultProjectDetection = requestedPreset === Preset.Monorepo;
394
- const detected = applyDetectionControls(
395
- detectProjectOptions(detectRootDir),
396
- detection,
397
- { projects: shouldDefaultProjectDetection }
398
- );
430
+ const detected = resolveDetectedOptions(detectRootDir, detection, requestedPreset);
399
431
  const { frameworkDefaults, preset, presetDefaults } = resolvePresetMeta(requestedPreset, detected, autoFrameworks);
400
432
  const configuredProjects = resolveConfiguredProjects(detected, options);
401
433
  const { detectedExtensions, detectedFormats, detectedLibraries, detectedTesting, detectedTools } = resolveBucketDefaults(detected);
@@ -504,9 +536,7 @@ const eslintConfig = async (options, ...extraConfigs) => {
504
536
  const patchedConfigs = workspacePrefixes?.length ? patchImportGroups(allConfigs, workspacePrefixes) : allConfigs;
505
537
  return applyStrictMode(patchedConfigs, strict);
506
538
  };
507
- const defineConfig = eslintConfig;
508
539
  export {
509
- AGENT_TARGETS,
510
540
  Extension2 as Extension,
511
541
  Format,
512
542
  Library2 as Library,
@@ -518,46 +548,31 @@ export {
518
548
  Testing2 as Testing,
519
549
  Tool,
520
550
  angular,
521
- angularConfig,
522
551
  astro,
523
552
  coreConfig2 as coreConfig,
524
553
  createCoreConfig2 as createCoreConfig,
554
+ createGitignoreConfig2 as createGitignoreConfig,
525
555
  createImportGroups,
526
556
  defineConfig,
527
557
  detectProjectOptions2 as detectProjectOptions,
528
- eslintConfig,
529
558
  expo,
530
- expoConfig,
531
- generateAgentSkills,
532
- generateSkillContent,
533
559
  getGlobalsForRuntime,
534
- gitignore2 as gitignore,
535
560
  groups,
536
561
  hasReactConfig,
537
562
  hono,
538
- jsConfig,
539
563
  lit,
540
564
  nest,
541
- nestConfig,
542
565
  next,
543
- nextConfig,
544
566
  nuxt,
545
567
  preact,
546
- preactConfig,
547
568
  qwik,
548
569
  react,
549
- reactConfig,
550
570
  reactRouter,
551
- remix,
552
571
  slidev,
553
572
  solid,
554
- solidConfig,
555
573
  svelte,
556
- svelteConfig,
557
574
  tanstackStart,
558
- tsConfig,
559
575
  typescriptConfig,
560
576
  vite,
561
- vue,
562
- vueConfig
577
+ vue
563
578
  };
@@ -1,40 +1,46 @@
1
1
  import {
2
2
  createModuleLoader,
3
- Tool
3
+ resolveConfigFeatures
4
4
  } from "@santi020k/eslint-config-core";
5
5
  const loadModule = createModuleLoader((specifier) => import.meta.resolve(specifier, import.meta.url));
6
- let integrationsModule;
7
- const loadIntegrations = async () => {
8
- integrationsModule ??= loadModule("@santi020k/eslint-config-integrations");
6
+ const packCache = /* @__PURE__ */ new Map();
7
+ const loadFeaturePack = async (specifier) => {
8
+ let pending = packCache.get(specifier);
9
+ if (!pending) {
10
+ pending = loadModule(specifier);
11
+ packCache.set(specifier, pending);
12
+ }
9
13
  try {
10
- return await integrationsModule;
14
+ const module = await pending;
15
+ if (!module.features) {
16
+ throw new Error(`Installed package "${specifier}" does not export a feature registry.`);
17
+ }
18
+ return module.features;
11
19
  } catch (error) {
12
- integrationsModule = void 0;
20
+ packCache.delete(specifier);
13
21
  throw new Error(
14
- 'Unable to load optional package "@santi020k/eslint-config-integrations". Install it for integrations, or remove the selected integration options.',
22
+ `Unable to load optional feature pack "${specifier}". Install it for the selected options, or remove those options from defineConfig().`,
15
23
  { cause: error }
16
24
  );
17
25
  }
18
26
  };
27
+ const loadSelectedPacks = async (libraries, tools, testing, formats, extensions) => (await Promise.all([
28
+ extensions.length > 0 ? loadFeaturePack("@santi020k/eslint-config-extensions/registry") : [],
29
+ formats.length > 0 ? loadFeaturePack("@santi020k/eslint-config-formats/registry") : [],
30
+ libraries.length > 0 ? loadFeaturePack("@santi020k/eslint-config-libraries/registry") : [],
31
+ testing.length > 0 ? loadFeaturePack("@santi020k/eslint-config-testing/registry") : [],
32
+ tools.length > 0 ? loadFeaturePack("@santi020k/eslint-config-tools/registry") : []
33
+ ])).flat();
19
34
  const getIntegrationConfigs = async (libraries, tools, testing, formats, extensions) => {
20
- if (libraries.length === 0 && tools.length === 0 && testing.length === 0 && formats.length === 0 && extensions.length === 0) return [];
21
- const module = await loadIntegrations();
22
- if (!module.getIntegrationConfigs) {
23
- throw new Error(
24
- 'Installed "@santi020k/eslint-config-integrations" is incompatible. Update it to v3 or newer.'
25
- );
26
- }
27
- return module.getIntegrationConfigs(libraries, tools, testing, formats, extensions);
35
+ const selected = [...libraries, ...tools, ...testing, ...formats, ...extensions];
36
+ if (selected.length === 0) return [];
37
+ const features = await loadSelectedPacks(libraries, tools, testing, formats, extensions);
38
+ return resolveConfigFeatures(features, selected);
28
39
  };
29
40
  const getPrettierConfig = async (tools) => {
30
- if (!tools.includes(Tool.Prettier)) return [];
31
- const module = await loadIntegrations();
32
- if (!module.getPrettierConfig) {
33
- throw new Error(
34
- 'Installed "@santi020k/eslint-config-integrations" is incompatible. Update it to v3 or newer.'
35
- );
36
- }
37
- return module.getPrettierConfig(tools);
41
+ if (tools.length === 0) return [];
42
+ const features = await loadFeaturePack("@santi020k/eslint-config-tools/registry");
43
+ return resolveConfigFeatures(features, tools, "finalizer");
38
44
  };
39
45
  export {
40
46
  getIntegrationConfigs,