@santi020k/eslint-config-basic 2.1.1 → 3.0.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,21 @@
1
1
  # @santi020k/eslint-config-basic
2
2
 
3
+ ## 3.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - Make the lean dependency model the default. Framework and integration config
8
+ packages are optional peers instead of hard dependencies.
9
+ - Add `@santi020k/eslint-config-basic/recommended` for a one-line zero-config
10
+ `eslint.config.*` file.
11
+ - Move integration factory exports to
12
+ `@santi020k/eslint-config-integrations`; the new
13
+ `@santi020k/eslint-config-full` package re-exports the batteries-included API.
14
+ - Make `Preset.Basic` dependency-free beyond core and TypeScript support.
15
+ - Make `basic-eslint init` generate the one-line recommended config.
16
+
17
+ See the [v2 to v3 migration guide](https://eslint.santi020k.com/guide/migration-v2-to-v3/).
18
+
3
19
  ## 2.1.1
4
20
 
5
21
  ### Patch Changes
package/README.md CHANGED
@@ -1,11 +1,19 @@
1
1
  # @santi020k/eslint-config-basic
2
2
 
3
- The primary entry point that composes all feature-specific configurations.
3
+ The lean v3 default for ESLint 10 flat config.
4
4
 
5
- This package is part of the [`@santi020k/eslint-config-basic`](https://github.com/santi020k/eslint-config-basic) monorepo.
5
+ ```sh
6
+ npm install -D eslint @santi020k/eslint-config-basic
7
+ ```
6
8
 
7
- - Docs: [Main package](https://eslint.santi020k.com/packages/basic)
8
- - Repository: [santi020k/eslint-config-basic](https://github.com/santi020k/eslint-config-basic)
9
- - Author: [santi020k](https://santi020k.com)
9
+ ```js
10
+ export { default } from '@santi020k/eslint-config-basic/recommended'
11
+ ```
10
12
 
11
- The canonical documentation lives on the Starlight site, so this README intentionally stays short to avoid duplication.
13
+ Add only the framework packages and `@santi020k/eslint-config-integrations`
14
+ that the project uses. Choose `@santi020k/eslint-config-full` for the
15
+ batteries-included dependency model.
16
+
17
+ - [Documentation](https://eslint.santi020k.com/)
18
+ - [Migration from v2](https://eslint.santi020k.com/guide/migration-v2-to-v3/)
19
+ - [Repository](https://github.com/santi020k/eslint-config-basic)
@@ -105,6 +105,9 @@ const FEATURE_MAP = [
105
105
  ["eslint-config-preact/", "frameworks", "Preact"],
106
106
  ["eslint-config-slidev/", "frameworks", "Slidev"],
107
107
  ["eslint-config-vite/", "frameworks", "Vite"],
108
+ // Extensions
109
+ ["eslint-config-integrations/astro-doctor", "extensions", "Astro Doctor"],
110
+ ["astro-doctor/", "extensions", "Astro Doctor"],
108
111
  // Testing
109
112
  ["integrations/vitest", "testing", "Vitest"],
110
113
  ["integrations/jest", "testing", "Jest"],
package/dist/cli.js CHANGED
@@ -56,6 +56,7 @@ const FRAMEWORK_KEY_TO_PACKAGE = Object.fromEntries(
56
56
  );
57
57
  const LITE_PACKAGE_NAME = "@santi020k/eslint-config-lite";
58
58
  const INTEGRATIONS_PACKAGE_NAME = "@santi020k/eslint-config-integrations";
59
+ const ASTRO_DOCTOR_PACKAGE_NAME = "@santi020k/eslint-plugin-astro-doctor";
59
60
  const TYPESCRIPT_PACKAGE_NAME = "typescript";
60
61
  const getConfigPathIfPresent = (cwd) => {
61
62
  const configPath = [
@@ -177,39 +178,8 @@ const detectWorkspaceProjects = (cwd) => {
177
178
  ];
178
179
  return [...new Set(patterns.flatMap((pattern) => expandWorkspacePattern(cwd, pattern)))].sort();
179
180
  };
180
- const getDetectionValues = (options) => ({
181
- extensions: options.extensions ?? [],
182
- formats: options.formats ?? [],
183
- libraries: options.libraries ?? [],
184
- runtime: options.runtime ?? "universal",
185
- settings: options.settings ?? [],
186
- testing: options.testing ?? [],
187
- tools: options.tools ?? [],
188
- typescript: options.typescript ?? false
189
- });
190
181
  const createConfigContent = (cwd) => {
191
- const options = detectProjectOptions(cwd);
192
- const values = getDetectionValues(options);
193
- const frameworkKeys = getFrameworkKeys(options.detectedFrameworks);
194
- const imports = ["import { eslintConfig } from '@santi020k/eslint-config-basic'"];
195
- const presetLine = options.preset && options.preset !== "basic" ? ` preset: ${JSON.stringify(options.preset)},
196
- ` : "";
197
- const configContent = `${imports.join("\n")}
198
-
199
- export default await eslintConfig({
200
- ${presetLine} typescript: ${JSON.stringify(values.typescript)},
201
- frameworks: {
202
- ${frameworkKeys.map((key) => `${toPropertyKey(key)}: true`).join(",\n ")}
203
- },
204
- libraries: ${JSON.stringify(values.libraries, null, 2)},
205
- testing: ${JSON.stringify(values.testing, null, 2)},
206
- formats: ${JSON.stringify(values.formats, null, 2)},
207
- tools: ${JSON.stringify(values.tools, null, 2)},
208
- extensions: ${JSON.stringify(values.extensions, null, 2)},
209
- runtime: ${JSON.stringify(values.runtime)},
210
- settings: ${JSON.stringify(values.settings, null, 2)}
211
- })
212
- `;
182
+ const configContent = "export { default } from '@santi020k/eslint-config-basic/recommended'\n";
213
183
  return {
214
184
  configContent,
215
185
  configPath: resolveConfigPath(cwd)
@@ -284,9 +254,9 @@ const printUsage = () => {
284
254
  "Commands:",
285
255
  " init Create eslint.config.js/mjs if missing",
286
256
  " update Regenerate eslint.config.js/mjs from detection",
287
- " explain Print detected v2 config inputs",
257
+ " explain Print detected v3 config inputs",
288
258
  " inspect Print detected inputs and active config features",
289
- " doctor Check project setup for common v2 adoption issues",
259
+ " doctor Check project setup for common v3 adoption issues",
290
260
  " docs Generate ESLINT_STANDARDS.md from detection",
291
261
  " migrate Report v1-to-v2 migration suggestions",
292
262
  " generate-skill Generate AI agent standards files",
@@ -386,6 +356,58 @@ const handleInspect = async (cwd = process.cwd(), json = false) => {
386
356
  `- Workspace projects: ${formatList(summary.workspaceProjects)}`
387
357
  ].join("\n"));
388
358
  };
359
+ const semver = createRequire(import.meta.url)("semver");
360
+ const readPackageMetadataFromMain = (mainPath, packageName) => {
361
+ let directory = dirname(mainPath);
362
+ for (let depth = 0; depth < 4; depth++) {
363
+ const packagePath = join(directory, "package.json");
364
+ if (existsSync(packagePath)) {
365
+ const metadata = JSON.parse(readFileSync(packagePath, "utf8"));
366
+ if (metadata.name === packageName) return metadata;
367
+ }
368
+ directory = dirname(directory);
369
+ }
370
+ return null;
371
+ };
372
+ const resolvePackageMetadata = (cwd, packageName) => {
373
+ try {
374
+ const projectRequire = createRequire(join(cwd, "package.json"));
375
+ try {
376
+ return readPackageMetadataFromMain(projectRequire.resolve(packageName), packageName);
377
+ } catch {
378
+ const integrationsMain = projectRequire.resolve(INTEGRATIONS_PACKAGE_NAME);
379
+ const integrationsRequire = createRequire(integrationsMain);
380
+ return readPackageMetadataFromMain(integrationsRequire.resolve(packageName), packageName);
381
+ }
382
+ } catch {
383
+ return null;
384
+ }
385
+ };
386
+ const getAstroDoctorNodeWarning = (metadata) => {
387
+ const nodeRange = metadata.engines?.node;
388
+ if (!nodeRange || semver.satisfies(process.versions.node, nodeRange)) return null;
389
+ return `Astro Doctor ${metadata.version ?? ""} requires Node ${nodeRange}, but the current runtime is ${process.versions.node}.`;
390
+ };
391
+ const getAstroDoctorEslintWarning = (metadata, eslintMetadata) => {
392
+ const eslintRange = metadata.peerDependencies?.eslint;
393
+ const eslintVersion = eslintMetadata?.version;
394
+ if (!eslintRange || !eslintVersion || semver.satisfies(eslintVersion, eslintRange)) return null;
395
+ return `Astro Doctor ${metadata.version ?? ""} requires ESLint ${eslintRange}, but this project resolves ${eslintVersion}.`;
396
+ };
397
+ const getAstroDoctorCompatibilityWarnings = (cwd, enabled) => {
398
+ if (!enabled) return [];
399
+ const pluginMetadata = resolvePackageMetadata(cwd, ASTRO_DOCTOR_PACKAGE_NAME);
400
+ if (!pluginMetadata) {
401
+ return [
402
+ `Astro Doctor is enabled, but ${ASTRO_DOCTOR_PACKAGE_NAME} could not be resolved. Reinstall dependencies or disable the \`astro-doctor\` feature.`
403
+ ];
404
+ }
405
+ const eslintMetadata = resolvePackageMetadata(cwd, "eslint");
406
+ return [
407
+ getAstroDoctorNodeWarning(pluginMetadata),
408
+ getAstroDoctorEslintWarning(pluginMetadata, eslintMetadata)
409
+ ].filter((warning) => warning !== null);
410
+ };
389
411
  const findDuplicateEslint = (cwd = process.cwd()) => {
390
412
  try {
391
413
  const projectRequire = createRequire(join(cwd, "package.json"));
@@ -430,7 +452,7 @@ const validateConfigContent = (configContent, hasV1FrameworkImports, declaredDep
430
452
  }
431
453
  return warnings;
432
454
  };
433
- const buildDoctorDiagnosis = (cwd, configPath, configContent, hasV1FrameworkImports, activeConfig, declaredDependencies, summary) => {
455
+ const validateProjectSetup = (cwd, configPath, activeConfig, hasV1FrameworkImports) => {
434
456
  const issues = [];
435
457
  const warnings = [];
436
458
  if (!readPackageJson(cwd)) {
@@ -444,15 +466,47 @@ const buildDoctorDiagnosis = (cwd, configPath, configContent, hasV1FrameworkImpo
444
466
  if (!hasLintScript(cwd)) {
445
467
  warnings.push("No `lint` script found in package.json.");
446
468
  }
447
- if (configContent) {
448
- warnings.push(...validateConfigContent(configContent, hasV1FrameworkImports, declaredDependencies, summary));
469
+ return { issues, warnings };
470
+ };
471
+ const isAstroDoctorConfigured = (activeConfig, configContent) => [
472
+ activeConfig?.extensions.includes("Astro Doctor") ?? false,
473
+ configContent?.includes("astro-doctor") ?? false,
474
+ configContent?.includes("AstroDoctor") ?? false
475
+ ].includes(true);
476
+ const isAstroConfigured = (activeConfig, summary) => [
477
+ activeConfig?.frameworks.includes("Astro") ?? false,
478
+ summary.frameworks.includes("astro")
479
+ ].some(Boolean);
480
+ const checkAstroDoctorStatus = (activeConfig, configContent, summary, warnings) => {
481
+ const astroDoctorEnabled = isAstroDoctorConfigured(activeConfig, configContent);
482
+ const astroEnabled = isAstroConfigured(activeConfig, summary);
483
+ if (astroDoctorEnabled && !astroEnabled) {
484
+ warnings.push(
485
+ "Astro Doctor is enabled without Astro. Enable `frameworks: { astro: true }` or remove the `astro-doctor` feature."
486
+ );
487
+ } else if (astroEnabled && !astroDoctorEnabled) {
488
+ warnings.push(
489
+ 'Astro was detected without Astro Doctor. Enable `features: { "astro-doctor": true }` for additional Astro diagnostics.'
490
+ );
449
491
  }
492
+ return astroDoctorEnabled;
493
+ };
494
+ const checkDuplicateEslint = (cwd, warnings) => {
450
495
  const duplicateEslint = findDuplicateEslint(cwd);
451
496
  if (duplicateEslint) {
452
497
  warnings.push(
453
498
  `Two ESLint copies are installed: the project resolves ${duplicateEslint.projectVersion} while the config packages resolve ${duplicateEslint.configVersion}. Only ESLint 10 is supported, and parallel copies can apply different rule behavior between your editor and CLI. Align the project's eslint version with the config's (or dedupe via your package manager).`
454
499
  );
455
500
  }
501
+ };
502
+ const buildDoctorDiagnosis = (cwd, configPath, configContent, hasV1FrameworkImports, activeConfig, declaredDependencies, summary) => {
503
+ const { issues, warnings } = validateProjectSetup(cwd, configPath, activeConfig, hasV1FrameworkImports);
504
+ if (configContent) {
505
+ warnings.push(...validateConfigContent(configContent, hasV1FrameworkImports, declaredDependencies, summary));
506
+ }
507
+ const astroDoctorEnabled = checkAstroDoctorStatus(activeConfig, configContent, summary, warnings);
508
+ warnings.push(...getAstroDoctorCompatibilityWarnings(cwd, astroDoctorEnabled));
509
+ checkDuplicateEslint(cwd, warnings);
456
510
  return { issues, warnings };
457
511
  };
458
512
  const outputDoctorResult = (json, configPath, packageManager, summary, liteInstallCommand, issues, warnings) => {
@@ -547,7 +601,7 @@ const processConfigMigration = (configPath, write, suggestions) => {
547
601
  const backupPath = `${configPath}.bak`;
548
602
  writeFileSync(backupPath, configContent);
549
603
  writeFileSync(configPath, result.content);
550
- const message = `Rewrote ${basename(configPath)} with v2 framework booleans: ${result.frameworks.join(", ")}. Original backed up to ${basename(backupPath)}.`;
604
+ const message = `Rewrote ${basename(configPath)} with framework booleans: ${result.frameworks.join(", ")}. Original backed up to ${basename(backupPath)}.`;
551
605
  applied.push(message);
552
606
  suggestions.push(`- ${message}`);
553
607
  } else {
@@ -562,8 +616,8 @@ const handleMigrate = (cwd = process.cwd(), write = false, json = false) => {
562
616
  "- Install only @santi020k/eslint-config-basic for the public config API.",
563
617
  "- Replace framework imports with bundled booleans such as frameworks: { react: true, next: true }.",
564
618
  "- Remove app-level @santi020k/eslint-config-react/next/vue/etc. config package imports.",
565
- "- Try eslintConfig() first; v2 auto-detects supported frameworks and integrations.",
566
- "- Use basic-eslint explain to review what v2 detects before committing the migration."
619
+ "- Try eslintConfig() first; v3 auto-detects supported frameworks and integrations.",
620
+ "- Use basic-eslint explain to review what v3 detects before committing the migration."
567
621
  ];
568
622
  const applied = processConfigMigration(configPath, write, suggestions);
569
623
  if (json) {
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, 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';
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
3
  export { AGENT_TARGETS, AgentTarget, EslintConfigFeatures, GenerateSkillOptions, GenerateSkillResult, generateAgentSkills, generateSkillContent } from './agent-skill-generator.js';
4
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 { a11y, aiSdk, autogen, bestPractices, biome, boundaries, command, compat, cspell, css, cypress, deMorgan, depend, docker, drizzle, githubActions, googleGenAi, graphql, html, i18next, jest, jestDom, jsdoc, jsonc, langchain, llamaIndex, markdown, mastra, mcp, mdx, mikroOrm, noOnlyTests, node, nx, openAiAgents, oxlint, packageJson, perfectionist, playwright, pnpm, prettier, prisma, regexp, security, sequelize, sonarjs, stencil, storybook, swagger, tailwind, tanstackQuery, tanstackRouter, testingLibrary, toml, turbo, typeorm, unicorn, vitest, yaml, zod } from '@santi020k/eslint-config-integrations';
6
5
  export { tsConfig, typescriptConfig } from '@santi020k/eslint-config-typescript';
7
6
 
8
7
  /**
package/dist/index.js CHANGED
@@ -16,6 +16,7 @@ import {
16
16
  Library,
17
17
  mergeFrameworkOption,
18
18
  mergeOptionalBucket,
19
+ mergeProjectOptions,
19
20
  NextMode,
20
21
  patchImportGroups,
21
22
  Preset,
@@ -26,11 +27,11 @@ import {
26
27
  Setting,
27
28
  Testing
28
29
  } from "@santi020k/eslint-config-core";
29
- import { tailwind as tailwindIntegration } from "@santi020k/eslint-config-integrations";
30
30
  import { createTypescriptConfig } from "@santi020k/eslint-config-typescript";
31
31
  import { createDetectedFrameworkFlags } from "./frameworks.js";
32
32
  import { getIntegrationConfigs, getPrettierConfig } from "./integrations.js";
33
33
  import { resolveFramework, resolvePreset } from "./resolvers.js";
34
+ import { buildTailwindSettingsConfig } from "./tailwind.js";
34
35
  import {
35
36
  AGENT_TARGETS,
36
37
  generateAgentSkills,
@@ -87,109 +88,20 @@ import {
87
88
  Testing as Testing2,
88
89
  Tool
89
90
  } from "@santi020k/eslint-config-core";
90
- import {
91
- a11y,
92
- aiSdk,
93
- autogen,
94
- bestPractices,
95
- biome,
96
- boundaries,
97
- command,
98
- compat,
99
- cspell,
100
- css,
101
- cypress,
102
- deMorgan,
103
- depend,
104
- docker,
105
- drizzle,
106
- githubActions,
107
- googleGenAi,
108
- graphql,
109
- html,
110
- i18next,
111
- jest,
112
- jestDom,
113
- jsdoc,
114
- jsonc,
115
- langchain,
116
- llamaIndex,
117
- markdown,
118
- mastra,
119
- mcp,
120
- mdx,
121
- mikroOrm,
122
- node,
123
- noOnlyTests,
124
- nx,
125
- openAiAgents,
126
- oxlint,
127
- packageJson,
128
- perfectionist,
129
- playwright,
130
- pnpm,
131
- prettier,
132
- prisma,
133
- regexp,
134
- security,
135
- sequelize,
136
- sonarjs,
137
- stencil,
138
- storybook,
139
- swagger,
140
- tailwind,
141
- tanstackQuery,
142
- tanstackRouter,
143
- testingLibrary,
144
- toml,
145
- turbo,
146
- typeorm,
147
- unicorn,
148
- vitest,
149
- yaml,
150
- zod
151
- } from "@santi020k/eslint-config-integrations";
152
91
  import { tsConfig, typescriptConfig } from "@santi020k/eslint-config-typescript";
153
- const buildTailwindResult = (options, entryPoint) => ({
92
+ const buildTailwindResult = (options, entryPoint, rootDir) => ({
93
+ cwd: options.cwd ?? rootDir,
154
94
  detectComponentClasses: options.detectComponentClasses ?? true,
155
95
  ...entryPoint ? { entryPoint } : {},
156
96
  ...options.ignore?.length ? { ignore: options.ignore } : {},
157
97
  ...options.noUnknownClasses === void 0 ? {} : { noUnknownClasses: options.noUnknownClasses }
158
98
  });
159
- const resolveTailwindOptions = (rootDir, tailwind2) => {
160
- if (tailwind2 === false) return void 0;
161
- const options = tailwind2 ?? {};
99
+ const resolveTailwindOptions = (rootDir, tailwind) => {
100
+ if (tailwind === false) return void 0;
101
+ const options = tailwind ?? {};
162
102
  const entryPoint = options.entryPoint ?? findTailwindEntryPoint(rootDir);
163
- if (!entryPoint && options.detectComponentClasses === void 0 && !options.ignore?.length && options.noUnknownClasses === void 0) return void 0;
164
- return buildTailwindResult(options, entryPoint);
165
- };
166
- const createNoUnknownClassesRule = (tailwindOptions, unknownClassOptions, hasUnknownClassOptions) => {
167
- if (!hasUnknownClassOptions && tailwindOptions.noUnknownClasses === void 0) return void 0;
168
- const severity = tailwindOptions.noUnknownClasses ?? "error";
169
- if (severity === false) return "off";
170
- return hasUnknownClassOptions ? [severity, unknownClassOptions] : severity;
171
- };
172
- const loadTailwindPlugins = async () => {
173
- const tailwindConfigs = await tailwindIntegration();
174
- const pluginConfig = tailwindConfigs.find((config) => config.plugins?.["better-tailwindcss"]);
175
- return pluginConfig?.plugins ?? {};
176
- };
177
- const createTailwindSettingsConfig = async (tailwindOptions) => {
178
- const { noUnknownClasses: _noUnknownClasses, ...settingsOptions } = tailwindOptions;
179
- const unknownClassOptions = {
180
- ...tailwindOptions.entryPoint ? { entryPoint: tailwindOptions.entryPoint } : {},
181
- ...tailwindOptions.ignore?.length ? { ignore: tailwindOptions.ignore } : {}
182
- };
183
- const hasUnknownClassOptions = Object.keys(unknownClassOptions).length > 0;
184
- const noUnknownClassesRule = createNoUnknownClassesRule(tailwindOptions, unknownClassOptions, hasUnknownClassOptions);
185
- return {
186
- name: "eslint-config-basic/tailwind-settings",
187
- plugins: await loadTailwindPlugins(),
188
- ...noUnknownClassesRule === void 0 ? {} : { rules: { "better-tailwindcss/no-unknown-classes": noUnknownClassesRule } },
189
- settings: {
190
- "better-tailwindcss": settingsOptions
191
- }
192
- };
103
+ if (!entryPoint && options.cwd === void 0 && options.detectComponentClasses === void 0 && !options.ignore?.length && options.noUnknownClasses === void 0) return void 0;
104
+ return buildTailwindResult(options, entryPoint, rootDir);
193
105
  };
194
106
  const TESTING_CONFIG_NAMES = {
195
107
  [Testing.Cypress]: ["integrations/cypress"],
@@ -204,9 +116,7 @@ const applyTestingFileOverrides = (configs, testingFiles) => {
204
116
  const entries = Object.entries(testingFiles).filter(([, files]) => files.length > 0);
205
117
  if (entries.length === 0) return configs;
206
118
  return configs.map((config) => {
207
- const match = entries.find(
208
- ([testingName]) => (TESTING_CONFIG_NAMES[testingName] ?? []).includes(config.name ?? "")
209
- );
119
+ const match = entries.find(([testingName]) => (TESTING_CONFIG_NAMES[testingName] ?? []).includes(config.name ?? ""));
210
120
  if (!match) return config;
211
121
  const [, files] = match;
212
122
  return {
@@ -221,10 +131,10 @@ const resolveConfigSetup = (options) => ({
221
131
  optionMergeStrategy: options?.optionMergeStrategy ?? "merge",
222
132
  requestedPreset: options?.preset
223
133
  });
224
- const resolveUniqueLibraries = (libraries, tailwind2) => {
134
+ const resolveUniqueLibraries = (libraries, tailwind) => {
225
135
  const uniqueLibraries = [...new Set(libraries)];
226
- if (tailwind2 === false) return uniqueLibraries.filter((library) => library !== Library.Tailwind);
227
- if (!tailwind2) return uniqueLibraries;
136
+ if (tailwind === false) return uniqueLibraries.filter((library) => library !== Library.Tailwind);
137
+ if (!tailwind) return uniqueLibraries;
228
138
  return [.../* @__PURE__ */ new Set([...uniqueLibraries, Library.Tailwind])];
229
139
  };
230
140
  const resolvePresetMeta = (requestedPreset, detected, autoFrameworks) => {
@@ -270,19 +180,23 @@ const buildIgnoresConfig = (useDefaultIgnores, useGeneratedCodeIgnores, useGitig
270
180
  }] : []
271
181
  });
272
182
  const FRAMEWORK_EXTRA_OPTS = {
273
- astro: (ctx) => ({ hasReact: ctx.hasReact, hasSolid: ctx.hasSolid, hasSvelte: ctx.hasSvelte, hasVue: ctx.hasVue }),
183
+ astro: (ctx) => ({
184
+ hasReact: ctx.hasReact,
185
+ hasSolid: ctx.hasSolid,
186
+ hasSvelte: ctx.hasSvelte,
187
+ hasVue: ctx.hasVue,
188
+ tsconfigRootDir: ctx.tsconfigRootDir
189
+ }),
274
190
  hono: (ctx) => ({ runtime: ctx.runtime }),
275
191
  slidev: (ctx) => ({ runtime: ctx.runtime }),
276
192
  vite: (ctx) => ({ runtime: ctx.runtime })
277
193
  };
278
194
  const resolveEnabledFrameworks = async (frameworks, ctx) => {
279
195
  const entries = await Promise.all(
280
- Object.entries(frameworks).filter((entry) => Boolean(entry[1])).map(
281
- ([name, value]) => (
282
- // eslint-disable-next-line security/detect-object-injection
283
- resolveFramework(name, value, FRAMEWORK_EXTRA_OPTS[name]?.(ctx)).then((config) => [name, config])
284
- )
285
- )
196
+ Object.entries(frameworks).filter((entry) => Boolean(entry[1])).map(([name, value]) => (
197
+ // eslint-disable-next-line security/detect-object-injection
198
+ resolveFramework(name, value, FRAMEWORK_EXTRA_OPTS[name]?.(ctx)).then((config) => [name, config])
199
+ ))
286
200
  );
287
201
  return Object.fromEntries(entries);
288
202
  };
@@ -308,7 +222,10 @@ const buildEslintConfigs = async (params) => {
308
222
  userIgnores
309
223
  } = params;
310
224
  const { hasReact, hasSolid, hasSvelte, hasVue } = astroOptions;
311
- const fw = await resolveEnabledFrameworks(resolvedFrameworks, { hasReact, hasSolid, hasSvelte, hasVue, runtime });
225
+ const fw = await resolveEnabledFrameworks(
226
+ resolvedFrameworks,
227
+ { hasReact, hasSolid, hasSvelte, hasVue, runtime, tsconfigRootDir }
228
+ );
312
229
  const get = (name) => fw[name] ?? [];
313
230
  return [
314
231
  ...defaultIgnores,
@@ -373,7 +290,7 @@ const buildEslintConfigs = async (params) => {
373
290
  ...uniqueExtensions.includes(Extension.Security) ? { "security/detect-non-literal-fs-filename": "off" } : {}
374
291
  }
375
292
  },
376
- ...tailwindOptions ? [await createTailwindSettingsConfig(tailwindOptions)] : [],
293
+ ...tailwindOptions ? [buildTailwindSettingsConfig(tailwindOptions)] : [],
377
294
  ...await getPrettierConfig(uniqueTools)
378
295
  ];
379
296
  };
@@ -417,6 +334,47 @@ const emitBasicWarnings = (options) => {
417
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.');
418
335
  }
419
336
  };
337
+ const emitAstroDoctorWarning = (extensions, frameworks) => {
338
+ if (!extensions.includes(Extension.AstroDoctor) || frameworks.astro) return;
339
+ process.emitWarning(
340
+ "[eslint-config-basic] Warning: Astro Doctor is enabled without the Astro framework config. Enable `frameworks: { astro: true }` or remove the `astro-doctor` feature."
341
+ );
342
+ };
343
+ const resolveProjectConfigs = async (configuredProjects, projectDefaults, detectRootDir, autoFrameworks) => Promise.all(
344
+ Object.entries(configuredProjects).map(async ([projectPath, projectOptions]) => {
345
+ const projectRoot = join(detectRootDir ?? process.cwd(), projectPath);
346
+ const inheritedOptions = mergeProjectOptions(projectDefaults ?? {}, projectOptions);
347
+ const scopedConfigs = await eslintConfig({
348
+ autoFrameworks,
349
+ ...inheritedOptions,
350
+ detectRootDir: inheritedOptions.detectRootDir ?? projectRoot,
351
+ projectDefaults: void 0,
352
+ projects: void 0,
353
+ tsconfigRootDir: inheritedOptions.tsconfigRootDir ?? projectRoot
354
+ });
355
+ return scopedConfigs.map((config) => scopeConfigToProject(config, projectPath));
356
+ })
357
+ );
358
+ const getConfigsParams = (options, rootDir, runtime, uniqueLibraries, uniqueSettings, resolvedFrameworks) => {
359
+ const hasReact = !!resolvedFrameworks.react;
360
+ const hasVue = !!resolvedFrameworks.vue;
361
+ const hasSvelte = !!resolvedFrameworks.svelte;
362
+ const hasSolid = !!resolvedFrameworks.solid;
363
+ const useGitignore = !uniqueSettings.includes(Setting.NoGitignore);
364
+ const useDefaultIgnores = !uniqueSettings.includes(Setting.NoDefaultIgnores);
365
+ const useGeneratedCodeIgnores = !uniqueSettings.includes(Setting.NoGeneratedCodeIgnores);
366
+ const tailwindOptions = uniqueLibraries.includes(Library.Tailwind) ? resolveTailwindOptions(rootDir, options?.tailwind) : void 0;
367
+ const runtimeCoreConfig = runtime === Runtime.Universal ? coreConfig : createCoreConfig(runtime);
368
+ const { defaultIgnores, gitignoreConfig, userIgnores } = buildIgnoresConfig(useDefaultIgnores, useGeneratedCodeIgnores, useGitignore, options);
369
+ return {
370
+ astroOptions: { hasReact, hasSolid, hasSvelte, hasVue },
371
+ defaultIgnores,
372
+ gitignoreConfig,
373
+ runtimeCoreConfig,
374
+ tailwindOptions,
375
+ userIgnores
376
+ };
377
+ };
420
378
  const eslintConfig = async (options, ...extraConfigs) => {
421
379
  emitBasicWarnings(options);
422
380
  const {
@@ -498,27 +456,19 @@ const eslintConfig = async (options, ...extraConfigs) => {
498
456
  const uniqueTools = [...new Set(tools)];
499
457
  const uniqueExtensions = [...new Set(extensions)];
500
458
  const uniqueSettings = [...new Set(settings)];
501
- const hasReact = !!resolvedFrameworks.react;
502
- const hasVue = !!resolvedFrameworks.vue;
503
- const hasSvelte = !!resolvedFrameworks.svelte;
504
- const hasSolid = !!resolvedFrameworks.solid;
505
- const useGitignore = !uniqueSettings.includes(Setting.NoGitignore);
506
- const useDefaultIgnores = !uniqueSettings.includes(Setting.NoDefaultIgnores);
507
- const useGeneratedCodeIgnores = !uniqueSettings.includes(Setting.NoGeneratedCodeIgnores);
508
- const tailwindOptions = uniqueLibraries.includes(Library.Tailwind) ? resolveTailwindOptions(rootDir, options?.tailwind) : void 0;
509
- const runtimeCoreConfig = runtime === Runtime.Universal ? coreConfig : createCoreConfig(runtime);
510
- const { defaultIgnores, gitignoreConfig, userIgnores } = buildIgnoresConfig(useDefaultIgnores, useGeneratedCodeIgnores, useGitignore, options);
459
+ emitAstroDoctorWarning(uniqueExtensions, resolvedFrameworks);
460
+ const params = getConfigsParams(options, rootDir, runtime, uniqueLibraries, uniqueSettings, resolvedFrameworks);
511
461
  const configs = await buildEslintConfigs({
512
- astroOptions: { hasReact, hasSolid, hasSvelte, hasVue },
513
- defaultIgnores,
514
- gitignoreConfig,
462
+ astroOptions: params.astroOptions,
463
+ defaultIgnores: params.defaultIgnores,
464
+ gitignoreConfig: params.gitignoreConfig,
515
465
  nextMode,
516
466
  resolvedFrameworks,
517
467
  resolvedTypescript,
518
468
  rootDir,
519
469
  runtime,
520
- runtimeCoreConfig,
521
- tailwindOptions,
470
+ runtimeCoreConfig: params.runtimeCoreConfig,
471
+ tailwindOptions: params.tailwindOptions,
522
472
  testingFiles: options?.testingFiles,
523
473
  tsconfigRootDir,
524
474
  uniqueExtensions,
@@ -526,7 +476,7 @@ const eslintConfig = async (options, ...extraConfigs) => {
526
476
  uniqueLibraries,
527
477
  uniqueTesting,
528
478
  uniqueTools,
529
- userIgnores
479
+ userIgnores: params.userIgnores
530
480
  });
531
481
  logEslintDebug({
532
482
  autoFrameworks,
@@ -544,18 +494,11 @@ const eslintConfig = async (options, ...extraConfigs) => {
544
494
  uniqueTesting,
545
495
  uniqueTools
546
496
  });
547
- const projectConfigs = await Promise.all(
548
- Object.entries(configuredProjects).map(async ([projectPath, projectOptions]) => {
549
- const projectRoot = join(detectRootDir ?? process.cwd(), projectPath);
550
- const scopedConfigs = await eslintConfig({
551
- autoFrameworks: options?.autoFrameworks,
552
- ...projectOptions,
553
- detectRootDir: projectOptions.detectRootDir ?? projectRoot,
554
- projects: void 0,
555
- tsconfigRootDir: projectOptions.tsconfigRootDir ?? projectRoot
556
- });
557
- return scopedConfigs.map((config) => scopeConfigToProject(config, projectPath));
558
- })
497
+ const projectConfigs = await resolveProjectConfigs(
498
+ configuredProjects,
499
+ options?.projectDefaults,
500
+ detectRootDir,
501
+ options?.autoFrameworks
559
502
  );
560
503
  const allConfigs = [...configs, ...projectConfigs.flat(), ...flattenConfigInputs(extraConfigs)];
561
504
  const patchedConfigs = workspacePrefixes?.length ? patchImportGroups(allConfigs, workspacePrefixes) : allConfigs;
@@ -574,107 +517,47 @@ export {
574
517
  Setting2 as Setting,
575
518
  Testing2 as Testing,
576
519
  Tool,
577
- a11y,
578
- aiSdk,
579
520
  angular,
580
521
  angularConfig,
581
522
  astro,
582
- autogen,
583
- bestPractices,
584
- biome,
585
- boundaries,
586
- command,
587
- compat,
588
523
  coreConfig2 as coreConfig,
589
524
  createCoreConfig2 as createCoreConfig,
590
525
  createImportGroups,
591
- cspell,
592
- css,
593
- cypress,
594
- deMorgan,
595
526
  defineConfig,
596
- depend,
597
527
  detectProjectOptions2 as detectProjectOptions,
598
- docker,
599
- drizzle,
600
528
  eslintConfig,
601
529
  expo,
602
530
  expoConfig,
603
531
  generateAgentSkills,
604
532
  generateSkillContent,
605
533
  getGlobalsForRuntime,
606
- githubActions,
607
534
  gitignore2 as gitignore,
608
- googleGenAi,
609
- graphql,
610
535
  groups,
611
536
  hasReactConfig,
612
537
  hono,
613
- html,
614
- i18next,
615
- jest,
616
- jestDom,
617
538
  jsConfig,
618
- jsdoc,
619
- jsonc,
620
- langchain,
621
539
  lit,
622
- llamaIndex,
623
- markdown,
624
- mastra,
625
- mcp,
626
- mdx,
627
- mikroOrm,
628
540
  nest,
629
541
  nestConfig,
630
542
  next,
631
543
  nextConfig,
632
- noOnlyTests,
633
- node,
634
544
  nuxt,
635
- nx,
636
- openAiAgents,
637
- oxlint,
638
- packageJson,
639
- perfectionist,
640
- playwright,
641
- pnpm,
642
545
  preact,
643
546
  preactConfig,
644
- prettier,
645
- prisma,
646
547
  qwik,
647
548
  react,
648
549
  reactConfig,
649
550
  reactRouter,
650
- regexp,
651
551
  remix,
652
- security,
653
- sequelize,
654
552
  slidev,
655
553
  solid,
656
554
  solidConfig,
657
- sonarjs,
658
- stencil,
659
- storybook,
660
555
  svelte,
661
556
  svelteConfig,
662
- swagger,
663
- tailwind,
664
- tanstackQuery,
665
- tanstackRouter,
666
557
  tanstackStart,
667
- testingLibrary,
668
- toml,
669
558
  tsConfig,
670
- turbo,
671
- typeorm,
672
559
  typescriptConfig,
673
- unicorn,
674
560
  vite,
675
- vitest,
676
561
  vue,
677
- vueConfig,
678
- yaml,
679
- zod
562
+ vueConfig
680
563
  };
@@ -1 +1,6 @@
1
- export { getIntegrationConfigs, getPrettierConfig } from '@santi020k/eslint-config-integrations';
1
+ import { Library, Tool, Testing, Format, Extension, FlatConfigArray } from '@santi020k/eslint-config-core';
2
+
3
+ declare const getIntegrationConfigs: (libraries: Library[], tools: Tool[], testing: Testing[], formats: Format[], extensions: Extension[]) => Promise<FlatConfigArray>;
4
+ declare const getPrettierConfig: (tools: Tool[]) => Promise<FlatConfigArray>;
5
+
6
+ export { getIntegrationConfigs, getPrettierConfig };
@@ -1,4 +1,41 @@
1
- import { getIntegrationConfigs, getPrettierConfig } from "@santi020k/eslint-config-integrations";
1
+ import {
2
+ createModuleLoader,
3
+ Tool
4
+ } from "@santi020k/eslint-config-core";
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");
9
+ try {
10
+ return await integrationsModule;
11
+ } catch (error) {
12
+ integrationsModule = void 0;
13
+ throw new Error(
14
+ 'Unable to load optional package "@santi020k/eslint-config-integrations". Install it for integrations, or remove the selected integration options.',
15
+ { cause: error }
16
+ );
17
+ }
18
+ };
19
+ 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);
28
+ };
29
+ 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);
38
+ };
2
39
  export {
3
40
  getIntegrationConfigs,
4
41
  getPrettierConfig
@@ -0,0 +1,5 @@
1
+ import * as typescript_eslint from 'typescript-eslint';
2
+
3
+ declare const _default: typescript_eslint.FlatConfig.ConfigArray;
4
+
5
+ export { _default as default };
@@ -0,0 +1,5 @@
1
+ import { defineConfig } from "./index.js";
2
+ var recommended_default = await defineConfig();
3
+ export {
4
+ recommended_default as default
5
+ };
package/dist/resolvers.js CHANGED
@@ -47,12 +47,7 @@ const resolvePreset = (preset) => {
47
47
  typescript: true
48
48
  };
49
49
  case Preset.Basic:
50
- return {
51
- extensions: [Extension.Unicorn, Extension.Perfectionist, Extension.Security],
52
- formats: [Format.Mdx, Format.Markdown, Format.Jsonc, Format.Yaml, Format.Toml],
53
- runtime: Runtime.Universal,
54
- tools: [Tool.Prettier]
55
- };
50
+ return { runtime: Runtime.Universal };
56
51
  case Preset.Browser:
57
52
  return {
58
53
  runtime: Runtime.Browser,
@@ -0,0 +1,6 @@
1
+ import { TailwindOptions } from '@santi020k/eslint-config-core';
2
+ import { TSESLint } from '@typescript-eslint/utils';
3
+
4
+ declare const buildTailwindSettingsConfig: (tailwindOptions: TailwindOptions) => TSESLint.FlatConfig.Config;
5
+
6
+ export { buildTailwindSettingsConfig };
@@ -0,0 +1,25 @@
1
+ const buildTailwindSettingsConfig = (tailwindOptions) => {
2
+ const { noUnknownClasses, ...settingsOptions } = tailwindOptions;
3
+ const unknownClassOptions = {
4
+ ...tailwindOptions.entryPoint ? { entryPoint: tailwindOptions.entryPoint } : {},
5
+ ...tailwindOptions.ignore?.length ? { ignore: tailwindOptions.ignore } : {}
6
+ };
7
+ const hasUnknownClassOptions = Object.keys(unknownClassOptions).length > 0;
8
+ const severity = noUnknownClasses ?? "error";
9
+ let noUnknownClassesRule;
10
+ if (hasUnknownClassOptions || noUnknownClasses !== void 0) {
11
+ if (severity === false) {
12
+ noUnknownClassesRule = "off";
13
+ } else {
14
+ noUnknownClassesRule = hasUnknownClassOptions ? [severity, unknownClassOptions] : severity;
15
+ }
16
+ }
17
+ return {
18
+ name: "eslint-config-basic/tailwind-settings",
19
+ ...noUnknownClassesRule === void 0 ? {} : { rules: { "better-tailwindcss/no-unknown-classes": noUnknownClassesRule } },
20
+ settings: { "better-tailwindcss": settingsOptions }
21
+ };
22
+ };
23
+ export {
24
+ buildTailwindSettingsConfig
25
+ };
package/package.json CHANGED
@@ -1,20 +1,26 @@
1
1
  {
2
2
  "name": "@santi020k/eslint-config-basic",
3
- "version": "2.1.1",
3
+ "version": "3.0.0",
4
4
  "publishConfig": {
5
5
  "access": "public",
6
6
  "provenance": true
7
7
  },
8
- "description": "A composable ESLint 10+ Flat Config package for JavaScript, TypeScript, React, Next.js, Vue, Nuxt, Svelte, Solid, Angular, Astro, Expo, NestJS, Hono, Preact, Qwik, React Router, TanStack Start, Lit, Vite, and Slidev.",
8
+ "description": "Lean, auto-detecting ESLint 10 flat config with opt-in framework and integration packages.",
9
9
  "type": "module",
10
10
  "main": "./dist/index.js",
11
11
  "module": "./dist/index.js",
12
12
  "types": "./dist/index.d.ts",
13
- "sideEffects": false,
13
+ "sideEffects": [
14
+ "./dist/recommended.js"
15
+ ],
14
16
  "exports": {
15
17
  ".": {
16
18
  "types": "./dist/index.d.ts",
17
19
  "import": "./dist/index.js"
20
+ },
21
+ "./recommended": {
22
+ "types": "./dist/recommended.d.ts",
23
+ "import": "./dist/recommended.js"
18
24
  }
19
25
  },
20
26
  "files": [
@@ -26,41 +32,122 @@
26
32
  "basic-eslint": "./dist/cli.js"
27
33
  },
28
34
  "dependencies": {
29
- "@typescript-eslint/utils": "^8.61.1",
30
- "@santi020k/eslint-config-angular": "^2.1.1",
31
- "@santi020k/eslint-config-astro": "^2.1.1",
32
- "@santi020k/eslint-config-core": "^2.1.1",
33
- "@santi020k/eslint-config-expo": "^2.1.1",
34
- "@santi020k/eslint-config-hono": "^2.1.1",
35
- "@santi020k/eslint-config-integrations": "^2.1.1",
36
- "@santi020k/eslint-config-lit": "^2.1.1",
37
- "@santi020k/eslint-config-nest": "^2.1.1",
38
- "@santi020k/eslint-config-next": "^2.1.1",
39
- "@santi020k/eslint-config-nuxt": "^2.1.1",
40
- "@santi020k/eslint-config-preact": "^2.1.1",
41
- "@santi020k/eslint-config-qwik": "^2.1.1",
42
- "@santi020k/eslint-config-react": "^2.1.1",
43
- "@santi020k/eslint-config-react-router": "^2.1.1",
44
- "@santi020k/eslint-config-remix": "^2.1.1",
45
- "@santi020k/eslint-config-slidev": "^2.1.1",
46
- "@santi020k/eslint-config-solid": "^2.1.1",
47
- "@santi020k/eslint-config-svelte": "^2.1.1",
48
- "@santi020k/eslint-config-tanstack-start": "^2.1.1",
49
- "@santi020k/eslint-config-typescript": "^2.1.1",
50
- "@santi020k/eslint-config-vite": "^2.1.1",
51
- "@santi020k/eslint-config-vue": "^2.1.1"
35
+ "@typescript-eslint/utils": "^8.65.0",
36
+ "semver": "^7.8.5",
37
+ "@santi020k/eslint-config-core": "^3.0.0",
38
+ "@santi020k/eslint-config-typescript": "^3.0.0"
52
39
  },
53
40
  "devDependencies": {
54
- "@types/node": "^26.0.0",
55
- "publint": "^0.3.21",
41
+ "@types/node": "^26.1.1",
42
+ "publint": "^0.3.22",
56
43
  "tsup": "^8.5.1",
57
- "typescript": "^6.0.3"
44
+ "typescript": "^6.0.2",
45
+ "@santi020k/eslint-config-angular": "^3.0.0",
46
+ "@santi020k/eslint-config-astro": "^3.0.0",
47
+ "@santi020k/eslint-config-expo": "^3.0.0",
48
+ "@santi020k/eslint-config-hono": "^3.0.0",
49
+ "@santi020k/eslint-config-integrations": "^3.0.0",
50
+ "@santi020k/eslint-config-lit": "^3.0.0",
51
+ "@santi020k/eslint-config-nest": "^3.0.0",
52
+ "@santi020k/eslint-config-next": "^3.0.0",
53
+ "@santi020k/eslint-config-nuxt": "^3.0.0",
54
+ "@santi020k/eslint-config-preact": "^3.0.0",
55
+ "@santi020k/eslint-config-qwik": "^3.0.0",
56
+ "@santi020k/eslint-config-react": "^3.0.0",
57
+ "@santi020k/eslint-config-react-router": "^3.0.0",
58
+ "@santi020k/eslint-config-remix": "^3.0.0",
59
+ "@santi020k/eslint-config-slidev": "^3.0.0",
60
+ "@santi020k/eslint-config-solid": "^3.0.0",
61
+ "@santi020k/eslint-config-svelte": "^3.0.0",
62
+ "@santi020k/eslint-config-tanstack-start": "^3.0.0",
63
+ "@santi020k/eslint-config-vite": "^3.0.0",
64
+ "@santi020k/eslint-config-vue": "^3.0.0"
58
65
  },
59
66
  "peerDependencies": {
60
67
  "eslint": "^10.0.0",
61
- "typescript": ">=5.0.0"
68
+ "typescript": ">=5.0.0",
69
+ "@santi020k/eslint-config-angular": "^3.0.0",
70
+ "@santi020k/eslint-config-astro": "^3.0.0",
71
+ "@santi020k/eslint-config-expo": "^3.0.0",
72
+ "@santi020k/eslint-config-hono": "^3.0.0",
73
+ "@santi020k/eslint-config-integrations": "^3.0.0",
74
+ "@santi020k/eslint-config-lit": "^3.0.0",
75
+ "@santi020k/eslint-config-nest": "^3.0.0",
76
+ "@santi020k/eslint-config-next": "^3.0.0",
77
+ "@santi020k/eslint-config-nuxt": "^3.0.0",
78
+ "@santi020k/eslint-config-preact": "^3.0.0",
79
+ "@santi020k/eslint-config-qwik": "^3.0.0",
80
+ "@santi020k/eslint-config-react": "^3.0.0",
81
+ "@santi020k/eslint-config-react-router": "^3.0.0",
82
+ "@santi020k/eslint-config-remix": "^3.0.0",
83
+ "@santi020k/eslint-config-slidev": "^3.0.0",
84
+ "@santi020k/eslint-config-solid": "^3.0.0",
85
+ "@santi020k/eslint-config-svelte": "^3.0.0",
86
+ "@santi020k/eslint-config-tanstack-start": "^3.0.0",
87
+ "@santi020k/eslint-config-vite": "^3.0.0",
88
+ "@santi020k/eslint-config-vue": "^3.0.0"
62
89
  },
63
90
  "peerDependenciesMeta": {
91
+ "@santi020k/eslint-config-angular": {
92
+ "optional": true
93
+ },
94
+ "@santi020k/eslint-config-astro": {
95
+ "optional": true
96
+ },
97
+ "@santi020k/eslint-config-expo": {
98
+ "optional": true
99
+ },
100
+ "@santi020k/eslint-config-hono": {
101
+ "optional": true
102
+ },
103
+ "@santi020k/eslint-config-integrations": {
104
+ "optional": true
105
+ },
106
+ "@santi020k/eslint-config-lit": {
107
+ "optional": true
108
+ },
109
+ "@santi020k/eslint-config-nest": {
110
+ "optional": true
111
+ },
112
+ "@santi020k/eslint-config-next": {
113
+ "optional": true
114
+ },
115
+ "@santi020k/eslint-config-nuxt": {
116
+ "optional": true
117
+ },
118
+ "@santi020k/eslint-config-preact": {
119
+ "optional": true
120
+ },
121
+ "@santi020k/eslint-config-qwik": {
122
+ "optional": true
123
+ },
124
+ "@santi020k/eslint-config-react": {
125
+ "optional": true
126
+ },
127
+ "@santi020k/eslint-config-react-router": {
128
+ "optional": true
129
+ },
130
+ "@santi020k/eslint-config-remix": {
131
+ "optional": true
132
+ },
133
+ "@santi020k/eslint-config-slidev": {
134
+ "optional": true
135
+ },
136
+ "@santi020k/eslint-config-solid": {
137
+ "optional": true
138
+ },
139
+ "@santi020k/eslint-config-svelte": {
140
+ "optional": true
141
+ },
142
+ "@santi020k/eslint-config-tanstack-start": {
143
+ "optional": true
144
+ },
145
+ "@santi020k/eslint-config-vite": {
146
+ "optional": true
147
+ },
148
+ "@santi020k/eslint-config-vue": {
149
+ "optional": true
150
+ },
64
151
  "typescript": {
65
152
  "optional": true
66
153
  }