@santi020k/eslint-config-basic 2.1.0 → 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 +51 -0
- package/README.md +14 -6
- package/dist/agent-skill-generator.js +9 -6
- package/dist/cli.js +94 -40
- package/dist/index.d.ts +1 -2
- package/dist/index.js +84 -201
- package/dist/integrations.d.ts +6 -1
- package/dist/integrations.js +38 -1
- package/dist/recommended.d.ts +5 -0
- package/dist/recommended.js +5 -0
- package/dist/resolvers.js +1 -6
- package/dist/tailwind.d.ts +6 -0
- package/dist/tailwind.js +25 -0
- package/package.json +117 -30
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,56 @@
|
|
|
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
|
+
|
|
19
|
+
## 2.1.1
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- [#95](https://github.com/santi020k/eslint-config-basic/pull/95) [`2576ec6`](https://github.com/santi020k/eslint-config-basic/commit/2576ec62df6127f5b40821e46a22394bb9dec867) Thanks [@santi020k](https://github.com/santi020k)! - Fix agent skill path convention, Astro virtual JS glob, and TypeScript virtual-file parser setup
|
|
24
|
+
|
|
25
|
+
- Agent skill generator now writes `SKILL.md` inside `skills/eslint-standards/` instead of `eslint-standards.md` inside `skills/`, aligning with the `skill://` URL convention used by Claude Code and other agents
|
|
26
|
+
- Gemini target follows the same convention (was `styleguide.md` at root)
|
|
27
|
+
- Added `**/*.astro/*.js` to `GLOB_VIRTUAL_TS` so Astro virtual JavaScript fragments with TypeScript syntax are parsed correctly
|
|
28
|
+
- Added a dedicated ESLint config block that disables `projectService` / `project` for all virtual TS/JS files, preventing TypeScript project service errors on those fragments
|
|
29
|
+
|
|
30
|
+
- Updated dependencies [[`2576ec6`](https://github.com/santi020k/eslint-config-basic/commit/2576ec62df6127f5b40821e46a22394bb9dec867)]:
|
|
31
|
+
- @santi020k/eslint-config-core@2.1.1
|
|
32
|
+
- @santi020k/eslint-config-typescript@2.1.1
|
|
33
|
+
- @santi020k/eslint-config-integrations@2.1.1
|
|
34
|
+
- @santi020k/eslint-config-angular@2.1.1
|
|
35
|
+
- @santi020k/eslint-config-astro@2.1.1
|
|
36
|
+
- @santi020k/eslint-config-expo@2.1.1
|
|
37
|
+
- @santi020k/eslint-config-hono@2.1.1
|
|
38
|
+
- @santi020k/eslint-config-lit@2.1.1
|
|
39
|
+
- @santi020k/eslint-config-nest@2.1.1
|
|
40
|
+
- @santi020k/eslint-config-next@2.1.1
|
|
41
|
+
- @santi020k/eslint-config-nuxt@2.1.1
|
|
42
|
+
- @santi020k/eslint-config-qwik@2.1.1
|
|
43
|
+
- @santi020k/eslint-config-react@2.1.1
|
|
44
|
+
- @santi020k/eslint-config-react-router@2.1.1
|
|
45
|
+
- @santi020k/eslint-config-remix@2.1.1
|
|
46
|
+
- @santi020k/eslint-config-slidev@2.1.1
|
|
47
|
+
- @santi020k/eslint-config-solid@2.1.1
|
|
48
|
+
- @santi020k/eslint-config-svelte@2.1.1
|
|
49
|
+
- @santi020k/eslint-config-tanstack-start@2.1.1
|
|
50
|
+
- @santi020k/eslint-config-vite@2.1.1
|
|
51
|
+
- @santi020k/eslint-config-vue@2.1.1
|
|
52
|
+
- @santi020k/eslint-config-preact@2.1.1
|
|
53
|
+
|
|
3
54
|
## 2.1.0
|
|
4
55
|
|
|
5
56
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
# @santi020k/eslint-config-basic
|
|
2
2
|
|
|
3
|
-
The
|
|
3
|
+
The lean v3 default for ESLint 10 flat config.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
```sh
|
|
6
|
+
npm install -D eslint @santi020k/eslint-config-basic
|
|
7
|
+
```
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
```js
|
|
10
|
+
export { default } from '@santi020k/eslint-config-basic/recommended'
|
|
11
|
+
```
|
|
10
12
|
|
|
11
|
-
|
|
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)
|
|
@@ -7,15 +7,15 @@ const AGENT_TARGETS = [
|
|
|
7
7
|
format: "frontmatter",
|
|
8
8
|
label: ".agent (generic skill format)",
|
|
9
9
|
markerFolder: ".agent",
|
|
10
|
-
skillFile: "
|
|
11
|
-
skillSubdir: "skills"
|
|
10
|
+
skillFile: "SKILL.md",
|
|
11
|
+
skillSubdir: "skills/eslint-standards"
|
|
12
12
|
},
|
|
13
13
|
{
|
|
14
14
|
format: "frontmatter",
|
|
15
15
|
label: ".agents (generic skill format)",
|
|
16
16
|
markerFolder: ".agents",
|
|
17
|
-
skillFile: "
|
|
18
|
-
skillSubdir: "skills"
|
|
17
|
+
skillFile: "SKILL.md",
|
|
18
|
+
skillSubdir: "skills/eslint-standards"
|
|
19
19
|
},
|
|
20
20
|
{
|
|
21
21
|
format: "plain",
|
|
@@ -56,8 +56,8 @@ const AGENT_TARGETS = [
|
|
|
56
56
|
format: "plain",
|
|
57
57
|
label: "Gemini (.gemini)",
|
|
58
58
|
markerFolder: ".gemini",
|
|
59
|
-
skillFile: "
|
|
60
|
-
skillSubdir: "
|
|
59
|
+
skillFile: "SKILL.md",
|
|
60
|
+
skillSubdir: "skills/eslint-standards"
|
|
61
61
|
},
|
|
62
62
|
{
|
|
63
63
|
format: "plain",
|
|
@@ -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
|
|
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
|
|
257
|
+
" explain Print detected v3 config inputs",
|
|
288
258
|
" inspect Print detected inputs and active config features",
|
|
289
|
-
" doctor Check project setup for common
|
|
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
|
|
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
|
-
|
|
448
|
-
|
|
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
|
|
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;
|
|
566
|
-
"- Use basic-eslint explain to review what
|
|
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,
|
|
160
|
-
if (
|
|
161
|
-
const options =
|
|
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,
|
|
134
|
+
const resolveUniqueLibraries = (libraries, tailwind) => {
|
|
225
135
|
const uniqueLibraries = [...new Set(libraries)];
|
|
226
|
-
if (
|
|
227
|
-
if (!
|
|
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) => ({
|
|
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
|
-
|
|
282
|
-
|
|
283
|
-
|
|
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(
|
|
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 ? [
|
|
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
|
-
|
|
502
|
-
const
|
|
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:
|
|
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
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
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
|
};
|
package/dist/integrations.d.ts
CHANGED
|
@@ -1 +1,6 @@
|
|
|
1
|
-
|
|
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 };
|
package/dist/integrations.js
CHANGED
|
@@ -1,4 +1,41 @@
|
|
|
1
|
-
import {
|
|
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
|
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 };
|
package/dist/tailwind.js
ADDED
|
@@ -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": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public",
|
|
6
6
|
"provenance": true
|
|
7
7
|
},
|
|
8
|
-
"description": "
|
|
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":
|
|
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.
|
|
30
|
-
"
|
|
31
|
-
"@santi020k/eslint-config-
|
|
32
|
-
"@santi020k/eslint-config-
|
|
33
|
-
"@santi020k/eslint-config-expo": "^2.1.0",
|
|
34
|
-
"@santi020k/eslint-config-hono": "^2.1.0",
|
|
35
|
-
"@santi020k/eslint-config-integrations": "^2.1.0",
|
|
36
|
-
"@santi020k/eslint-config-lit": "^2.1.0",
|
|
37
|
-
"@santi020k/eslint-config-nest": "^2.1.0",
|
|
38
|
-
"@santi020k/eslint-config-next": "^2.1.0",
|
|
39
|
-
"@santi020k/eslint-config-nuxt": "^2.1.0",
|
|
40
|
-
"@santi020k/eslint-config-preact": "^2.1.0",
|
|
41
|
-
"@santi020k/eslint-config-qwik": "^2.1.0",
|
|
42
|
-
"@santi020k/eslint-config-react": "^2.1.0",
|
|
43
|
-
"@santi020k/eslint-config-react-router": "^2.1.0",
|
|
44
|
-
"@santi020k/eslint-config-remix": "^2.1.0",
|
|
45
|
-
"@santi020k/eslint-config-slidev": "^2.1.0",
|
|
46
|
-
"@santi020k/eslint-config-solid": "^2.1.0",
|
|
47
|
-
"@santi020k/eslint-config-svelte": "^2.1.0",
|
|
48
|
-
"@santi020k/eslint-config-tanstack-start": "^2.1.0",
|
|
49
|
-
"@santi020k/eslint-config-typescript": "^2.1.0",
|
|
50
|
-
"@santi020k/eslint-config-vite": "^2.1.0",
|
|
51
|
-
"@santi020k/eslint-config-vue": "^2.1.0"
|
|
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.
|
|
55
|
-
"publint": "^0.3.
|
|
41
|
+
"@types/node": "^26.1.1",
|
|
42
|
+
"publint": "^0.3.22",
|
|
56
43
|
"tsup": "^8.5.1",
|
|
57
|
-
"typescript": "^6.0.
|
|
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
|
}
|