@santi020k/eslint-config-basic 2.0.0-beta.0 → 2.0.0-beta.1

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,37 @@
1
1
  # @santi020k/eslint-config-basic
2
2
 
3
+ ## 2.0.0-beta.1
4
+
5
+ ### Minor Changes
6
+
7
+ - [`dfba51d`](https://github.com/santi020k/eslint-config-basic/commit/dfba51dca7387a71a263af206eb86fd8df15f387) Thanks [@santi020k](https://github.com/santi020k)! - Improve config migration handling and enhance TypeScript options detection
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [[`dfba51d`](https://github.com/santi020k/eslint-config-basic/commit/dfba51dca7387a71a263af206eb86fd8df15f387)]:
12
+ - @santi020k/eslint-config-core@2.0.0-beta.1
13
+ - @santi020k/eslint-config-integrations@2.0.0-beta.1
14
+ - @santi020k/eslint-config-typescript@2.0.0-beta.1
15
+ - @santi020k/eslint-config-angular@2.0.0-beta.1
16
+ - @santi020k/eslint-config-astro@2.0.0-beta.1
17
+ - @santi020k/eslint-config-expo@2.0.0-beta.1
18
+ - @santi020k/eslint-config-hono@2.0.0-beta.1
19
+ - @santi020k/eslint-config-lit@2.0.0-beta.1
20
+ - @santi020k/eslint-config-nest@2.0.0-beta.1
21
+ - @santi020k/eslint-config-next@2.0.0-beta.1
22
+ - @santi020k/eslint-config-nuxt@2.0.0-beta.1
23
+ - @santi020k/eslint-config-qwik@2.0.0-beta.1
24
+ - @santi020k/eslint-config-react@2.0.0-beta.1
25
+ - @santi020k/eslint-config-react-router@2.0.0-beta.1
26
+ - @santi020k/eslint-config-remix@2.0.0-beta.1
27
+ - @santi020k/eslint-config-slidev@2.0.0-beta.1
28
+ - @santi020k/eslint-config-solid@2.0.0-beta.1
29
+ - @santi020k/eslint-config-svelte@2.0.0-beta.1
30
+ - @santi020k/eslint-config-tanstack-start@2.0.0-beta.1
31
+ - @santi020k/eslint-config-vite@2.0.0-beta.1
32
+ - @santi020k/eslint-config-vue@2.0.0-beta.1
33
+ - @santi020k/eslint-config-preact@2.0.0-beta.1
34
+
3
35
  ## 2.0.0-beta.0
4
36
 
5
37
  ### Major Changes
package/dist/index.d.ts CHANGED
@@ -1,21 +1,24 @@
1
1
  import { EslintConfigOptions, FlatConfigArray } 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, 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, GenerateSkillOptions, GenerateSkillResult, generateAgentSkills, generateSkillContent } from './agent-skill-generator.js';
3
+ import { TSESLint } from '@typescript-eslint/utils';
4
+ export { AGENT_TARGETS, AgentTarget, EslintConfigFeatures, GenerateSkillOptions, GenerateSkillResult, generateAgentSkills, generateSkillContent } from './agent-skill-generator.js';
4
5
  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
6
  export { a11y, aiSdk, autogen, bestPractices, biome, 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
7
  export { tsConfig, typescriptConfig } from '@santi020k/eslint-config-typescript';
7
8
 
9
+ type ConfigInput = false | null | TSESLint.FlatConfig.Config | TSESLint.FlatConfig.ConfigArray | undefined;
8
10
  /**
9
11
  * Generates the ESLint configuration array, applying configurations
10
12
  * and integration settings based on the input configuration.
11
13
  *
12
14
  * @param {EslintConfigOptions} options - Configuration and integration settings
15
+ * @param {ConfigInput[]} extraConfigs - Local flat-config overrides appended after generated config
13
16
  * @returns {FlatConfigArray} The final ESLint configuration array
14
17
  */
15
- declare const eslintConfig: (options?: EslintConfigOptions) => Promise<FlatConfigArray>;
18
+ declare const eslintConfig: (options?: EslintConfigOptions, ...extraConfigs: ConfigInput[]) => Promise<FlatConfigArray>;
16
19
  /**
17
20
  * Alias for `eslintConfig()` that reads naturally in `eslint.config.*` files.
18
21
  */
19
- declare const defineConfig: (options?: EslintConfigOptions) => Promise<FlatConfigArray>;
22
+ declare const defineConfig: (options?: EslintConfigOptions, ...extraConfigs: ConfigInput[]) => Promise<FlatConfigArray>;
20
23
 
21
24
  export { defineConfig, eslintConfig };
package/dist/index.js CHANGED
@@ -202,6 +202,10 @@ const OPTIONAL_BUCKETS = {
202
202
  testing: Object.values(Testing),
203
203
  tools: Object.values(Tool)
204
204
  };
205
+ const flattenConfigInputs = (configs) => configs.flatMap((config) => {
206
+ if (!config) return [];
207
+ return Array.isArray(config) ? config : [config];
208
+ });
205
209
  const mergeArrayOption = (detectedValues, presetValues, explicitValues, strategy) => {
206
210
  if (strategy === "replace") {
207
211
  if (explicitValues) return toUniqueArray(explicitValues);
@@ -319,6 +323,32 @@ const resolveTsconfigRootDir = (rootDir, typescript, explicitRootDir) => {
319
323
  const findTailwindEntryPoint = (rootDir) => TAILWIND_ENTRYPOINT_CANDIDATES.find(
320
324
  (candidate) => existsSync(join(rootDir, candidate))
321
325
  );
326
+ const buildTailwindResult = (options, entryPoint) => ({
327
+ detectComponentClasses: options.detectComponentClasses ?? true,
328
+ ...entryPoint ? { entryPoint } : {},
329
+ ...options.ignore?.length ? { ignore: options.ignore } : {}
330
+ });
331
+ const resolveTailwindOptions = (rootDir, tailwind2) => {
332
+ if (tailwind2 === false) return void 0;
333
+ const options = tailwind2 ?? {};
334
+ const entryPoint = options.entryPoint ?? findTailwindEntryPoint(rootDir);
335
+ if (!entryPoint && options.detectComponentClasses === void 0 && !options.ignore?.length) return void 0;
336
+ return buildTailwindResult(options, entryPoint);
337
+ };
338
+ const createTailwindSettingsConfig = (tailwindOptions) => {
339
+ const unknownClassOptions = {
340
+ ...tailwindOptions.entryPoint ? { entryPoint: tailwindOptions.entryPoint } : {},
341
+ ...tailwindOptions.ignore?.length ? { ignore: tailwindOptions.ignore } : {}
342
+ };
343
+ const hasUnknownClassOptions = Object.keys(unknownClassOptions).length > 0;
344
+ return {
345
+ name: "eslint-config-basic/tailwind-settings",
346
+ ...hasUnknownClassOptions ? { rules: { "better-tailwindcss/no-unknown-classes": ["error", unknownClassOptions] } } : {},
347
+ settings: {
348
+ "better-tailwindcss": tailwindOptions
349
+ }
350
+ };
351
+ };
322
352
  const scopeFilePattern = (projectPath, pattern) => {
323
353
  if (typeof pattern === "string") {
324
354
  const isNegated = pattern.startsWith("!");
@@ -370,12 +400,37 @@ const patchImportGroups = (allConfigs, workspacePrefixes) => {
370
400
  (item) => Array.isArray(item) ? item : patchImportGroupsConfig(item, workspacePatterns)
371
401
  );
372
402
  };
403
+ const TESTING_CONFIG_NAMES = {
404
+ [Testing.Playwright]: ["integrations/playwright"]
405
+ };
406
+ const applyTestingFileOverrides = (configs, testingFiles) => {
407
+ if (!testingFiles) return configs;
408
+ const entries = Object.entries(testingFiles).filter(([, files]) => files.length > 0);
409
+ if (entries.length === 0) return configs;
410
+ return configs.map((config) => {
411
+ const match = entries.find(
412
+ ([testingName]) => (TESTING_CONFIG_NAMES[testingName] ?? []).includes(config.name ?? "")
413
+ );
414
+ if (!match) return config;
415
+ const [, files] = match;
416
+ return {
417
+ ...config,
418
+ files
419
+ };
420
+ });
421
+ };
373
422
  const resolveConfigSetup = (options) => ({
374
423
  autoFrameworks: options?.autoFrameworks ?? true,
375
424
  detectRootDir: options?.detectRootDir ?? options?.tsconfigRootDir,
376
425
  optionMergeStrategy: options?.optionMergeStrategy ?? "merge",
377
426
  requestedPreset: options?.preset
378
427
  });
428
+ const resolveUniqueLibraries = (libraries, tailwind2) => {
429
+ const uniqueLibraries = [...new Set(libraries)];
430
+ if (tailwind2 === false) return uniqueLibraries.filter((library) => library !== Library.Tailwind);
431
+ if (!tailwind2) return uniqueLibraries;
432
+ return [.../* @__PURE__ */ new Set([...uniqueLibraries, Library.Tailwind])];
433
+ };
379
434
  const resolvePresetMeta = (requestedPreset, detected, autoFrameworks) => {
380
435
  const preset = requestedPreset ?? detected.preset;
381
436
  const presetDefaults = preset ? resolvePreset(preset) : {};
@@ -429,7 +484,8 @@ const buildEslintConfigs = async (params) => {
429
484
  rootDir: _rootDir,
430
485
  runtime,
431
486
  runtimeCoreConfig,
432
- tailwindEntryPoint,
487
+ tailwindOptions,
488
+ testingFiles,
433
489
  tsconfigRootDir,
434
490
  uniqueExtensions,
435
491
  uniqueFormats,
@@ -531,16 +587,11 @@ const buildEslintConfigs = async (params) => {
531
587
  name: "eslint-config-next/app-router-overrides",
532
588
  rules: { "@next/next/no-html-link-for-pages": "off" }
533
589
  }] : [],
534
- ...await getIntegrationConfigs(uniqueLibraries, uniqueTools, uniqueTesting, uniqueFormats, uniqueExtensions),
535
- ...tailwindEntryPoint ? [{
536
- name: "eslint-config-basic/tailwind-settings",
537
- settings: {
538
- "better-tailwindcss": {
539
- detectComponentClasses: true,
540
- entryPoint: tailwindEntryPoint
541
- }
542
- }
543
- }] : [],
590
+ ...applyTestingFileOverrides(
591
+ await getIntegrationConfigs(uniqueLibraries, uniqueTools, uniqueTesting, uniqueFormats, uniqueExtensions),
592
+ testingFiles
593
+ ),
594
+ ...tailwindOptions ? [createTailwindSettingsConfig(tailwindOptions)] : [],
544
595
  ...await getPrettierConfig(uniqueTools)
545
596
  ];
546
597
  };
@@ -564,7 +615,7 @@ const logEslintDebug = (autoFrameworks, detectRootDir, nextMode, optionMergeStra
564
615
  }, null, 2)}
565
616
  `);
566
617
  };
567
- const eslintConfig = async (options) => {
618
+ const eslintConfig = async (options, ...extraConfigs) => {
568
619
  const {
569
620
  detection,
570
621
  extensions: optExtensions,
@@ -638,7 +689,7 @@ const eslintConfig = async (options) => {
638
689
  const tsconfigRootDir = resolveTsconfigRootDir(rootDir, typescript, optTsconfigRootDir);
639
690
  const extensions = applyStrictProfileDefaults(configuredExtensions, strict);
640
691
  const resolvedFrameworks = applyFrameworkImpliedDeps({ ...frameworks });
641
- const uniqueLibraries = [...new Set(libraries)];
692
+ const uniqueLibraries = resolveUniqueLibraries(libraries, options?.tailwind);
642
693
  const uniqueTesting = [...new Set(testing)];
643
694
  const uniqueFormats = [...new Set(formats)];
644
695
  const uniqueTools = [...new Set(tools)];
@@ -651,7 +702,7 @@ const eslintConfig = async (options) => {
651
702
  const useGitignore = !uniqueSettings.includes(Setting.NoGitignore);
652
703
  const useDefaultIgnores = !uniqueSettings.includes(Setting.NoDefaultIgnores);
653
704
  const useGeneratedCodeIgnores = !uniqueSettings.includes(Setting.NoGeneratedCodeIgnores);
654
- const tailwindEntryPoint = uniqueLibraries.includes(Library.Tailwind) ? findTailwindEntryPoint(rootDir) : void 0;
705
+ const tailwindOptions = uniqueLibraries.includes(Library.Tailwind) ? resolveTailwindOptions(rootDir, options?.tailwind) : void 0;
655
706
  const runtimeCoreConfig = runtime === Runtime.Universal ? coreConfig : createCoreConfig(runtime);
656
707
  const { defaultIgnores, gitignoreConfig, userIgnores } = buildIgnoresConfig(useDefaultIgnores, useGeneratedCodeIgnores, useGitignore, options);
657
708
  const configs = await buildEslintConfigs({
@@ -664,7 +715,8 @@ const eslintConfig = async (options) => {
664
715
  rootDir,
665
716
  runtime,
666
717
  runtimeCoreConfig,
667
- tailwindEntryPoint,
718
+ tailwindOptions,
719
+ testingFiles: options?.testingFiles,
668
720
  tsconfigRootDir,
669
721
  uniqueExtensions,
670
722
  uniqueFormats,
@@ -701,7 +753,7 @@ const eslintConfig = async (options) => {
701
753
  return scopedConfigs.map((config) => scopeConfigToProject(config, projectPath));
702
754
  })
703
755
  );
704
- const allConfigs = [...configs, ...projectConfigs.flat()];
756
+ const allConfigs = [...configs, ...projectConfigs.flat(), ...flattenConfigInputs(extraConfigs)];
705
757
  const patchedConfigs = workspacePrefixes?.length ? patchImportGroups(allConfigs, workspacePrefixes) : allConfigs;
706
758
  return applyStrictMode(patchedConfigs, strict);
707
759
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@santi020k/eslint-config-basic",
3
- "version": "2.0.0-beta.0",
3
+ "version": "2.0.0-beta.1",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -30,30 +30,31 @@
30
30
  },
31
31
  "dependencies": {
32
32
  "@typescript-eslint/utils": "^8.61.1",
33
- "@santi020k/eslint-config-angular": "^2.0.0-beta.0",
34
- "@santi020k/eslint-config-astro": "^2.0.0-beta.0",
35
- "@santi020k/eslint-config-core": "^2.0.0-beta.0",
36
- "@santi020k/eslint-config-expo": "^2.0.0-beta.0",
37
- "@santi020k/eslint-config-hono": "^2.0.0-beta.0",
38
- "@santi020k/eslint-config-integrations": "^2.0.0-beta.0",
39
- "@santi020k/eslint-config-lit": "^2.0.0-beta.0",
40
- "@santi020k/eslint-config-nest": "^2.0.0-beta.0",
41
- "@santi020k/eslint-config-next": "^2.0.0-beta.0",
42
- "@santi020k/eslint-config-nuxt": "^2.0.0-beta.0",
43
- "@santi020k/eslint-config-preact": "^2.0.0-beta.0",
44
- "@santi020k/eslint-config-qwik": "^2.0.0-beta.0",
45
- "@santi020k/eslint-config-react": "^2.0.0-beta.0",
46
- "@santi020k/eslint-config-react-router": "^2.0.0-beta.0",
47
- "@santi020k/eslint-config-remix": "^2.0.0-beta.0",
48
- "@santi020k/eslint-config-slidev": "^2.0.0-beta.0",
49
- "@santi020k/eslint-config-solid": "^2.0.0-beta.0",
50
- "@santi020k/eslint-config-svelte": "^2.0.0-beta.0",
51
- "@santi020k/eslint-config-tanstack-start": "^2.0.0-beta.0",
52
- "@santi020k/eslint-config-typescript": "^2.0.0-beta.0",
53
- "@santi020k/eslint-config-vite": "^2.0.0-beta.0",
54
- "@santi020k/eslint-config-vue": "^2.0.0-beta.0"
33
+ "@santi020k/eslint-config-angular": "^2.0.0-beta.1",
34
+ "@santi020k/eslint-config-astro": "^2.0.0-beta.1",
35
+ "@santi020k/eslint-config-core": "^2.0.0-beta.1",
36
+ "@santi020k/eslint-config-expo": "^2.0.0-beta.1",
37
+ "@santi020k/eslint-config-hono": "^2.0.0-beta.1",
38
+ "@santi020k/eslint-config-integrations": "^2.0.0-beta.1",
39
+ "@santi020k/eslint-config-lit": "^2.0.0-beta.1",
40
+ "@santi020k/eslint-config-nest": "^2.0.0-beta.1",
41
+ "@santi020k/eslint-config-next": "^2.0.0-beta.1",
42
+ "@santi020k/eslint-config-nuxt": "^2.0.0-beta.1",
43
+ "@santi020k/eslint-config-preact": "^2.0.0-beta.1",
44
+ "@santi020k/eslint-config-qwik": "^2.0.0-beta.1",
45
+ "@santi020k/eslint-config-react": "^2.0.0-beta.1",
46
+ "@santi020k/eslint-config-react-router": "^2.0.0-beta.1",
47
+ "@santi020k/eslint-config-remix": "^2.0.0-beta.1",
48
+ "@santi020k/eslint-config-slidev": "^2.0.0-beta.1",
49
+ "@santi020k/eslint-config-solid": "^2.0.0-beta.1",
50
+ "@santi020k/eslint-config-svelte": "^2.0.0-beta.1",
51
+ "@santi020k/eslint-config-tanstack-start": "^2.0.0-beta.1",
52
+ "@santi020k/eslint-config-typescript": "^2.0.0-beta.1",
53
+ "@santi020k/eslint-config-vite": "^2.0.0-beta.1",
54
+ "@santi020k/eslint-config-vue": "^2.0.0-beta.1"
55
55
  },
56
56
  "devDependencies": {
57
+ "@types/node": "^25.9.3",
57
58
  "publint": "^0.3.21",
58
59
  "tsup": "^8.5.1",
59
60
  "typescript": "^6.0.3"