@santi020k/eslint-config-basic 0.7.1 → 1.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,96 @@
1
1
  # @santi020k/eslint-config-basic
2
2
 
3
+ ## 1.0.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#66](https://github.com/santi020k/eslint-config-basic/pull/66) [`6f2f473`](https://github.com/santi020k/eslint-config-basic/commit/6f2f4733642087eb9eac22a7b6193b71453f375d) Thanks [@santi020k](https://github.com/santi020k)! - # v0.10.0 Release
8
+
9
+ ## Major Changes
10
+
11
+ - **Migration to pnpm**: Full migration of the monorepo from npm to pnpm workspaces (pnpm v10+). This includes better performance, stricter dependency management, and corepack integration.
12
+ - **neostandard removal**: Removed `neostandard` dependency to provide more granular control and modularity in core rules.
13
+ - **Stylistic v4 -> v5**: Upgraded to `@stylistic/eslint-plugin` version 5.x for improved formatting rules and TypeScript 5.7+ support.
14
+ - **GraphQL Integration**: Added comprehensive support for GraphQL schemas and operations. This includes automated project detection for GraphQL files and specialized linting rules for both schema definitions and operation documents.
15
+ - **React 19 Support**: Updated React detection logic and configurations to support React 19.
16
+
17
+ ## Framework Updates
18
+
19
+ - **Qwik & Remix Support**: Added comprehensive ESLint configurations and functional playground environments for both Qwik and Remix frameworks.
20
+ - **Dependency Alignment**: Resolved critical `typescript-eslint` dependency issues in Astro, Svelte, and Vue packages to ensure proper rule resolution and type safety.
21
+ - **Consistency Refinements**: Standardized `disable-type-checked` rule blocks across all framework-specific configurations.
22
+ - **Documentation Overhaul**: Major documentation refresh in root `README.md` and VitePress documentation. Added clarity on configuration priority, framework auto-detection, and full-settings examples.
23
+
24
+ ## Maintenance
25
+
26
+ - **Corepack Enablement**: Added `corepack` support for automated package manager version management.
27
+ - **Turbo Update**: Bumped Turborepo to v2.9+ for faster builds and improved task caching.
28
+ - **Turbo Optimizations**: Configured Turborepo to output in `errors-only` mode with `errorsOnlyShowHash` enabled, significantly reducing terminal noise during build and lint tasks.
29
+ - **Integration Test Improvements**: Enhanced integration tests to be more robust, including proper `tsconfigRootDir` handling and better React version validation.
30
+ - **Playground Synchronization**: Updated all playground packages to maintain parity with the latest framework rules.
31
+
32
+ - [#55](https://github.com/santi020k/eslint-config-basic/pull/55) [`d8e4b4a`](https://github.com/santi020k/eslint-config-basic/commit/d8e4b4a61c2739dbffa3c823d8742ea234c5b731) Thanks [@santi020k](https://github.com/santi020k)! - feat: add standard ESLint configuration and resolve typecheck/hook failures
33
+
34
+ This release introduces a new standard configuration in `@santi020k/eslint-config-core` and addresses several technical issues:
35
+
36
+ - Fixed global typecheck failures across the monorepo.
37
+ - Resolved pre-commit hook issues with cspell.
38
+ - Fixed pre-push hook failures related to publint in the playground package.
39
+ - Added missing test coverage scripts and fixed CI build failures.
40
+
41
+ ### Patch Changes
42
+
43
+ - Updated dependencies [[`6f2f473`](https://github.com/santi020k/eslint-config-basic/commit/6f2f4733642087eb9eac22a7b6193b71453f375d), [`d8e4b4a`](https://github.com/santi020k/eslint-config-basic/commit/d8e4b4a61c2739dbffa3c823d8742ea234c5b731)]:
44
+ - @santi020k/eslint-config-angular@1.0.0
45
+ - @santi020k/eslint-config-astro@1.0.0
46
+ - @santi020k/eslint-config-core@1.0.0
47
+ - @santi020k/eslint-config-expo@1.0.0
48
+ - @santi020k/eslint-config-nest@1.0.0
49
+ - @santi020k/eslint-config-next@1.0.0
50
+ - @santi020k/eslint-config-optionals@1.0.0
51
+ - @santi020k/eslint-config-qwik@0.8.2
52
+ - @santi020k/eslint-config-react@1.0.0
53
+ - @santi020k/eslint-config-remix@0.8.2
54
+ - @santi020k/eslint-config-solid@1.0.0
55
+ - @santi020k/eslint-config-svelte@1.0.0
56
+ - @santi020k/eslint-config-typescript@1.0.0
57
+ - @santi020k/eslint-config-vue@1.0.0
58
+
59
+ ## 0.8.1
60
+
61
+ ### Minor Changes
62
+
63
+ - 13e8e5a: # Release 0.8.0
64
+
65
+ - **Snippet Fixes**: Resolved ESLint parsing errors in virtual TypeScript files within Markdown, Astro, and VitePress code blocks by disabling type-aware rules for those snippets.
66
+ - **Standalone TS Support**: Restored `disableTypeChecked` configuration in the TypeScript package, ensuring it remains fully functional and parsing-error-free when used without the main composer.
67
+ - **Documentation Reorganization**: Significantly expanded and restructured the documentation site, adding new pages for the Inspector, CLI Tooling, Extensions, and better framework-specific guides.
68
+ - **Branding Update**: Updated the author link label from "Website" to "Author" across all documentation files for improved brand identity.
69
+ - **Composition Improvements**: Refactored the configuration composer to be more robust when handling virtual snippets and framework contracts.
70
+
71
+ ### Patch Changes
72
+
73
+ - # CI & Workflow Stabilization
74
+
75
+ - Fixed invalid `actions/setup-node` version from `@v6` to `@v4` in Release and Docs workflows.
76
+ - Improved CLI test performance and reliability by refactoring integration tests into fast in-memory unit tests.
77
+ - Enabled Turborepo caching in GitHub Actions to significantly reduce PR build times.
78
+
79
+ - Updated dependencies
80
+ - Updated dependencies [13e8e5a]
81
+ - @santi020k/eslint-config-...@0.8.1
82
+ - @santi020k/eslint-config-...@0.8.1
83
+ - @santi020k/eslint-config-...@0.8.1
84
+ - @santi020k/eslint-config-...@0.8.1
85
+ - @santi020k/eslint-config-...@0.8.1
86
+ - @santi020k/eslint-config-...@0.8.1
87
+ - @santi020k/eslint-config-...@0.8.1
88
+ - @santi020k/eslint-config-...@0.8.1
89
+ - @santi020k/eslint-config-...@0.8.1
90
+ - @santi020k/eslint-config-...@0.8.1
91
+ - @santi020k/eslint-config-...@0.8.1
92
+ - @santi020k/eslint-config-...@0.8.1
93
+
3
94
  ## 0.7.1
4
95
 
5
96
  ### Patch Changes
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 santi020k
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -3,329 +3,101 @@
3
3
  [![CI](https://github.com/santi020k/eslint-config-basic/actions/workflows/build.yml/badge.svg)](https://github.com/santi020k/eslint-config-basic/actions/workflows/build.yml)
4
4
  [![npm version](https://img.shields.io/npm/v/@santi020k/eslint-config-basic.svg)](https://www.npmjs.com/package/@santi020k/eslint-config-basic)
5
5
  [![npm downloads](https://img.shields.io/npm/dm/@santi020k/eslint-config-basic.svg)](https://www.npmjs.com/package/@santi020k/eslint-config-basic)
6
- [![Docs](https://img.shields.io/badge/docs-TypeDoc-blue.svg)](https://santi020k.github.io/eslint-config-basic/)
7
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+ [![Docs](https://img.shields.io/badge/docs-VitePress-114d66.svg)](https://eslint.santi020k.me/)
7
+ [![license](https://img.shields.io/npm/l/@santi020k/eslint-config-basic.svg)](https://github.com/santi020k/eslint-config-basic/blob/main/LICENSE)
8
8
 
9
- Welcome to **@santi020k/eslint-config-basic**, a comprehensive and opinionated ESLint configuration package for JavaScript, TypeScript, React, and other frameworks. Born from a desire to eliminate bad practices and ensure high-quality code, this configuration automates code quality checks and reduces cognitive load during code reviews by enforcing a consistent coding style across your projects.
9
+ Composable ESLint 10+ flat-config tooling for JavaScript and TypeScript projects, with optional framework packages for React, Next.js, Astro, Vue, Svelte, Solid, Angular, NestJS, Expo, Qwik, and Remix.
10
10
 
11
- ## Why Use This Configuration?
11
+ ## Canonical Docs
12
12
 
13
- - **Consistency:** Enforces a uniform coding style, reducing code discrepancies and easing collaboration.
14
- - **Quality:** Promotes best practices and helps avoid common pitfalls in JavaScript, TypeScript, Frameworks, Libraries, Tools and more.
15
- - **Automation:** Catches issues early in the development process, minimizing manual code review effort.
16
- - **Customization:** While it comes with strong opinions, you can tailor it to suit your project's specific needs.
13
+ - Docs site: [eslint.santi020k.me](https://eslint.santi020k.me/)
14
+ - Repository: [github.com/santi020k/eslint-config-basic](https://github.com/santi020k/eslint-config-basic)
15
+ - Author: [santi020k](https://santi020k.me)
17
16
 
18
- ## Installation
17
+ ## ✨ Key Features
19
18
 
20
- Before installing, make sure you have ESLint (version 9.0.0 or 10.0.0 or later) installed:
19
+ - **🎯 Composable & Modular**: Mix and match configurations for different frameworks and tools using a clean, options-based API.
20
+ - **🔍 Deep Auto-Detection**: Automatically detects your project's frameworks, libraries, and tools. Core features like TypeScript and runtime presets are enabled by default if detected.
21
+ - **⚡ Lazy Loading**: Framework-specific configurations are loaded only when needed, ensuring maximum performance and avoiding unnecessary peer dependency conflicts.
22
+ - **🛡️ Strict Mode**: Opt-in `strict: true` to promote all warnings to errors, perfect for CI/CD and maintaining high code standards.
23
+ - **🌐 Smart Runtime Support**: Built-in support for Node.js, Browser, or Universal runtimes with appropriate globals and rules.
24
+ - **💅 Prettier Integrated**: Seamlessly integrated with Prettier out of the box for consistent code formatting.
25
+ - **🧩 Extensive Plugin Support**: Tailored rules for Tailwind CSS, Vitest, Testing Library, Storybook, TanStack (Query/Router), and more.
21
26
 
22
- ```bash
23
- npm install eslint --save-dev
24
- ```
27
+ ## 🚀 Quick Start
25
28
 
26
- Then, install the configuration package. **Important:** I recommend using a fixed version (do not use `^` or `~`), as any new functionality or change may introduce new linter errors that require manual updates.
29
+ ### Installation
27
30
 
28
31
  ```bash
29
- npm install @santi020k/eslint-config-basic --save-dev
32
+ npm install -D eslint @santi020k/eslint-config-basic
30
33
  ```
31
34
 
32
- ## Usage
33
-
34
- Create an `eslint.config.js` file (or update your existing one) and extend **@santi020k/eslint-config-basic** based on your project type.
35
+ ### Usage
35
36
 
36
- ### Basic Usage
37
-
38
- For a basic JavaScript/Node.js project:
37
+ Create an `eslint.config.js` in your project root. By default, it will detect your project settings:
39
38
 
40
39
  ```js
41
40
  import { eslintConfig } from '@santi020k/eslint-config-basic'
42
41
 
43
- export default [
44
- ...eslintConfig()
45
- // Your custom config
46
- ]
42
+ export default eslintConfig()
47
43
  ```
48
44
 
49
- ### Advanced Usage
45
+ ### Comprehensive Example
50
46
 
51
- For projects that require specific configurations (e.g., TypeScript, React, Next.js, ...Etc), use the appropriate options:
47
+ Here is an example with many features activated. Note that many of these are automatically detected if the corresponding packages are in your `package.json`.
52
48
 
53
49
  ```js
54
- import { ConfigOption, eslintConfig } from '@santi020k/eslint-config-basic'
55
-
56
- // TypeScript project
57
- export default [
58
- ...eslintConfig({ config: [ConfigOption.Ts] })
59
- // Your custom config
60
- ]
61
-
62
- // React project
63
- export default [
64
- ...eslintConfig({ config: [ConfigOption.React] })
65
- // Your custom config
66
- ]
67
-
68
- // TypeScript and React project
69
- export default [
70
- ...eslintConfig({ config: [ConfigOption.React, ConfigOption.Ts] })
71
- // Your custom config
72
- ]
73
-
74
- // Next.js project
75
- export default [
76
- ...eslintConfig({ config: [ConfigOption.Next] })
77
- // Your custom config
78
- ]
79
-
80
- // Expo project
81
- export default [
82
- ...eslintConfig({ config: [ConfigOption.Expo] })
83
- // Your custom config
84
- ]
85
-
86
- // Astro project (supports Astro with React)
87
- export default [
88
- ...eslintConfig({ config: [ConfigOption.Astro] })
89
- // Your custom config
90
- ]
91
-
92
- // NestJS project
93
- export default [
94
- ...eslintConfig({ config: [ConfigOption.Nest] })
95
- // Your custom config
96
- ]
97
-
98
- // Vue project
99
- export default [
100
- ...eslintConfig({ config: [ConfigOption.Vue] })
101
- // Your custom config
102
- ]
50
+ import { eslintConfig, Extension, Format, Library, Testing, Tool } from '@santi020k/eslint-config-basic'
51
+ import next from '@santi020k/eslint-config-next'
52
+ import react from '@santi020k/eslint-config-react'
53
+
54
+ export default eslintConfig({
55
+ // Explicitly enable TypeScript (auto-detected if tsconfig.json exists)
56
+ typescript: true,
57
+
58
+ // Strict mode: warnings become errors
59
+ strict: true,
60
+
61
+ // Frameworks (imports are lazy-loaded)
62
+ frameworks: {
63
+ react,
64
+ next
65
+ },
66
+
67
+ // Optional integrations
68
+ libraries: [Library.Tailwind, Library.TanstackQuery],
69
+ testing: [Testing.Vitest, Testing.Playwright, Testing.TestingLibrary],
70
+ formats: [Format.Mdx, Format.Jsonc, Format.Graphql],
71
+ tools: [Tool.Prettier, Tool.Cspell],
72
+ extensions: [Extension.Unicorn, Extension.Sonarjs, Extension.Perfectionist]
73
+ })
103
74
  ```
104
75
 
105
- ### Optional Usage
106
-
107
- There are additional optional parameters to add support for other front-end/back-end technologies. This enables you to extend support as needed:
108
-
109
- ```js
110
- import { ConfigOption, eslintConfig, OptionalOption } from '@santi020k/eslint-config-basic'
111
-
112
- export default [
113
- ...eslintConfig({
114
- config: [ConfigOption.Next, ConfigOption.Ts],
115
- optionals: [
116
- // Spell checker
117
- OptionalOption.Cspell,
118
- // TailwindCss
119
- OptionalOption.Tailwind,
120
- // Vitest and testing-library
121
- OptionalOption.Vitest,
122
- // I18next
123
- OptionalOption.I18next,
124
- // Mdx
125
- OptionalOption.Mdx,
126
- // Markdown
127
- OptionalOption.Markdown,
128
- // SonarJS
129
- OptionalOption.Sonarjs,
130
- // Stencil
131
- OptionalOption.Stencil,
132
- // Playwright
133
- OptionalOption.Playwright,
134
- // Prettier
135
- OptionalOption.Prettier
136
- ]
137
- })
138
- // Your custom config
139
- ]
140
- ```
141
-
142
- ### Settings Usage (Experimental)
143
-
144
- This experimental option allows ESLint to honor your `.gitignore` file:
145
-
146
- ```js
147
- import { eslintConfig, SettingOption } from '@santi020k/eslint-config-basic'
148
-
149
- export default [
150
- ...eslintConfig({
151
- // ESLint will ignore files specified in .gitignore
152
- settings: [SettingOption.Gitignore]
153
- })
154
- // Your custom config
155
- ]
156
- ```
157
-
158
- ## AI Agent Capabilities
159
-
160
- This project is optimized for AI agents and LLM-based tools. It includes an `.agent/skills/` directory containing specialized workflows, guidelines, and context specific to this monorepo. Agents can automatically use these skills to assist with development, testing, and release processes.
161
-
162
- ## Monorepo Structure
163
-
164
- This project is a monorepo managed with **Turbo** and **npm Workspaces**.
165
-
166
- - `packages/basic`: Main package entry point.
167
- - `packages/core`: Core logic and shared types.
168
- - `packages/typescript`: TypeScript specific rules.
169
- - `packages/react`: React and Hooks rules.
170
- - `packages/next`: Next.js rules.
171
- - `packages/astro`: Astro rules.
172
- - `packages/expo`: Expo/React Native rules.
173
- - `packages/optionals`: Optional configurations (Tailwind, Vitest, etc.).
174
- - `packages/tests`: Integration tests.
175
- - `packages/playground`: Testing playground for local development.
76
+ ## Framework packages
77
+
78
+ - TypeScript: [`@santi020k/eslint-config-typescript`](https://eslint.santi020k.me/frameworks/typescript.html)
79
+ - React: [`@santi020k/eslint-config-react`](https://eslint.santi020k.me/frameworks/react.html)
80
+ - Next.js: [`@santi020k/eslint-config-next`](https://eslint.santi020k.me/frameworks/next.html)
81
+ - Astro: [`@santi020k/eslint-config-astro`](https://eslint.santi020k.me/frameworks/astro.html)
82
+ - Vue: [`@santi020k/eslint-config-vue`](https://eslint.santi020k.me/frameworks/vue.html)
83
+ - Svelte: [`@santi020k/eslint-config-svelte`](https://eslint.santi020k.me/frameworks/svelte.html)
84
+ - Solid: [`@santi020k/eslint-config-solid`](https://eslint.santi020k.me/frameworks/solid.html)
85
+ - Angular: [`@santi020k/eslint-config-angular`](https://eslint.santi020k.me/frameworks/angular.html)
86
+ - NestJS: [`@santi020k/eslint-config-nest`](https://eslint.santi020k.me/frameworks/nest.html)
87
+ - Expo: [`@santi020k/eslint-config-expo`](https://eslint.santi020k.me/frameworks/expo.html)
88
+ - Qwik: [`@santi020k/eslint-config-qwik`](https://eslint.santi020k.me/frameworks/qwik.html)
89
+ - Remix: [`@santi020k/eslint-config-remix`](https://eslint.santi020k.me/frameworks/remix.html)
176
90
 
177
91
  ## Development
178
92
 
179
- If you want to contribute or modify the configurations:
180
-
181
- ### Prerequisites
182
-
183
- - Node.js (version specified in `.nvmrc`)
184
- - npm
185
-
186
- ### Setup
187
-
188
93
  ```bash
189
- npm install
94
+ pnpm install # Install dependencies
95
+ pnpm run build # Build all packages
96
+ pnpm run test # Run integration tests
97
+ pnpm run lint # Run linting checks
98
+ pnpm run ok # Run all checks
190
99
  ```
191
100
 
192
- ### Useful Commands
193
- ```bash
194
- npm run build # Build all packages using Turbo
195
- npm run lint # Lint all packages
196
- npm run test # Run integration tests
197
- npm run dev # Development mode with watch
198
- npm run inspector # Open ESLint config inspector
199
- npm run docs # Generate API documentation
200
- ```
201
-
202
- ### Publishing Workflow
203
-
204
- This repository uses **Changesets** (`@changesets/cli`) to automatically handle workspace dependency versioning and publishing to npm.
205
-
206
- To publish a new version of the packages:
207
-
208
- 1. Make sure you are authenticated with npm in your terminal (`npm login`).
209
- 2. Generate a changeset summarizing your changes:
210
- ```bash
211
- npm run changeset
212
- ```
213
- 3. Consume the changeset to bump package versions automatically:
214
- ```bash
215
- npm run version-packages
216
- ```
217
- 4. Build all packages and publish them to npm:
218
- ```bash
219
- npm run release
220
- ```
221
-
222
- ### ESLint Config Inspector
223
-
224
- You can visually inspect the generated ESLint configuration using the built-in inspector:
225
-
226
- ```bash
227
- npm run inspector
228
- ```
229
-
230
- This opens an interactive UI where you can see all active rules, plugins, and config layers. It's useful for debugging which rules are applied and understanding the final merged configuration.
231
-
232
- ### API Documentation
233
-
234
- Auto-generated API docs are available online:
235
- [**https://santi020k.github.io/eslint-config-basic/**](https://santi020k.github.io/eslint-config-basic/)
236
-
237
- You can also generate them locally:
238
-
239
- ```bash
240
- npm run docs
241
- ```
242
-
243
- This outputs markdown documentation to the `docs/` directory.
244
-
245
- ## Compatibility & Known Issues
246
-
247
- ### Astro 5+
248
-
249
- This package includes robust defaults for Astro projects, including:
250
-
251
- - Automatic detection of virtual scripts inside `.astro` files.
252
- - Disabled `react/jsx-no-undef` (Astro handles this).
253
- - Enforced `never` comma-dangle for Astro templates.
254
- - Support for JSX/TSX inside Astro components.
255
-
256
- ## Opinionated but Flexible
257
-
258
- This ESLint configuration is based on my personal preferences and practices, and it may evolve over time. **Important:** I recommend using a fixed version to avoid unexpected changes that might introduce new linter errors. To ensure stability, do not use `^` or `~` when specifying the version. If a rule feels too strict, consider changing it from an error to a warning to allow more flexibility during development.
259
-
260
- ## Scripts
261
-
262
- Add the following useful scripts to your `package.json`:
263
-
264
- ```json
265
- "scripts": {
266
- "lint": "eslint . --report-unused-disable-directives",
267
- "lint:fix": "npm run lint -- --fix"
268
- }
269
- ```
270
-
271
- ## How to Implement in an Existing Project
272
-
273
- 1. Install the Dependencies: Ensure that both ESLint and this configuration package are installed.
274
- 2. Update Your ESLint Configuration: Extend **@santi020k/eslint-config-basic** in your ESLint configuration file as shown above.
275
- 3. Run ESLint: Lint your project files and automatically fix issues if possible:
276
-
277
- ```bash
278
- npm run lint
279
- npm run lint:fix
280
- ```
281
-
282
- 4. **Adjust as Necessary:** Review and modify the linting rules based on your project's needs. Some rules might be too strict or not applicable; feel free to disable or adjust them.
283
-
284
- ## Future Features
285
-
286
- - [x] Testing
287
- - [x] Refactored rules structure (Monorepo transition)
288
- - [x] Astro and Expo support
289
- - [x] Enhanced documentation
290
- - [x] Additional framework support (contributions welcome!):
291
- - [x] Vue
292
- - [ ] Angular
293
- - [x] NestJS
294
-
295
- ## Contributing
296
-
297
- Contributions are welcome! Please read the [Contributing Guide](CONTRIBUTING.md) for details on setting up the project, adding new configurations, and submitting pull requests.
298
-
299
- ## Acknowledgements
300
-
301
- Special thanks to the developers and maintainers of the following libraries, which form the backbone of this ESLint configuration:
302
-
303
- - [eslint-config-standard](https://www.npmjs.com/package/eslint-config-standard)
304
- - [eslint-plugin-import](https://www.npmjs.com/package/eslint-plugin-import)
305
- - [eslint-plugin-n](https://www.npmjs.com/package/eslint-plugin-n)
306
- - [eslint-plugin-promise](https://www.npmjs.com/package/eslint-plugin-promise)
307
- - [eslint-plugin-react](https://www.npmjs.com/package/eslint-plugin-react)
308
- - [eslint-plugin-react-hooks](https://www.npmjs.com/package/eslint-plugin-react-hooks)
309
- - [eslint-plugin-jsx-a11y](https://www.npmjs.com/package/eslint-plugin-jsx-a11y)
310
- - [eslint-plugin-simple-import-sort](https://www.npmjs.com/package/eslint-plugin-simple-import-sort)
311
- - [eslint-plugin-sonarjs](https://www.npmjs.com/package/eslint-plugin-sonarjs)
312
- - [eslint-plugin-unused-imports](https://www.npmjs.com/package/eslint-plugin-unused-imports)
313
- - [@stylistic/eslint-plugin](https://www.npmjs.com/package/@stylistic/eslint-plugin)
314
- - [@typescript-eslint](https://www.npmjs.com/package/@typescript-eslint/eslint-plugin)
315
- - [@cspell/eslint-plugin](https://www.npmjs.com/package/@cspell/eslint-plugin)
316
- - [eslint-plugin-better-tailwindcss](https://www.npmjs.com/package/eslint-plugin-better-tailwindcss)
317
- - [eslint-plugin-vitest](https://www.npmjs.com/package/eslint-plugin-vitest)
318
- - [eslint-plugin-astro](https://www.npmjs.com/package/eslint-plugin-astro)
319
- - [eslint-plugin-next](https://www.npmjs.com/package/eslint-plugin-next)
320
- - [eslint-plugin-vue](https://www.npmjs.com/package/eslint-plugin-vue)
321
- - [eslint-plugin-unicorn](https://www.npmjs.com/package/eslint-plugin-unicorn)
322
- - [eslint-plugin-regexp](https://www.npmjs.com/package/eslint-plugin-regexp)
323
- - [eslint-plugin-i18next](https://www.npmjs.com/package/eslint-plugin-i18next)
324
- - [eslint-plugin-mdx](https://www.npmjs.com/package/eslint-plugin-mdx)
325
- - [eslint-config-prettier](https://www.npmjs.com/package/eslint-config-prettier)
326
- - [eslint-config-expo](https://www.npmjs.com/package/eslint-config-expo)
327
- - ...and many others
328
-
329
- Their ongoing contributions help maintain the high standards of code quality we all strive for.
101
+ ---
330
102
 
331
- Thank you for using **@santi020k/eslint-config-basic**. Together, let's write cleaner, more maintainable code!
103
+ *Authored with ❤️ by [santi020k](https://santi020k.me)*
package/dist/cli.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+ declare const handleInit: (cwd?: string) => void;
3
+ declare const handleUpdate: (cwd?: string) => void;
4
+
5
+ export { handleInit, handleUpdate };
package/dist/cli.js ADDED
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env node
2
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
3
+ import { basename, join } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { detectProjectOptions } from "./index.js";
6
+ const getDefaultConfigFilename = (cwd) => {
7
+ const packageJsonPath = join(cwd, "package.json");
8
+ if (!existsSync(packageJsonPath)) return "eslint.config.mjs";
9
+ try {
10
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
11
+ return packageJson.type === "module" ? "eslint.config.js" : "eslint.config.mjs";
12
+ } catch {
13
+ return "eslint.config.mjs";
14
+ }
15
+ };
16
+ const resolveConfigPath = (cwd) => {
17
+ const existingConfigPath = [
18
+ "eslint.config.js",
19
+ "eslint.config.mjs"
20
+ ].map((filename) => join(cwd, filename)).find(existsSync);
21
+ return existingConfigPath ?? join(cwd, getDefaultConfigFilename(cwd));
22
+ };
23
+ const getFrameworkKeys = (frameworks) => {
24
+ const frameworkKeys = new Set(Object.keys(frameworks ?? {}));
25
+ if (frameworkKeys.has("next") || frameworkKeys.has("expo")) {
26
+ frameworkKeys.add("react");
27
+ }
28
+ return [...frameworkKeys];
29
+ };
30
+ const createConfigContent = (cwd) => {
31
+ const options = detectProjectOptions(cwd);
32
+ const frameworkKeys = getFrameworkKeys(options.frameworks);
33
+ const imports = ["import { eslintConfig } from '@santi020k/eslint-config-basic'"];
34
+ frameworkKeys.forEach((key) => {
35
+ imports.push(`import ${key} from '@santi020k/eslint-config-${key}'`);
36
+ });
37
+ const configContent = `${imports.join("\n")}
38
+
39
+ export default eslintConfig({
40
+ typescript: ${JSON.stringify(options.typescript ?? false)},
41
+ frameworks: {
42
+ ${frameworkKeys.map((key) => `${key}: ${key}`).join(",\n ")}
43
+ },
44
+ libraries: ${JSON.stringify(options.libraries ?? [], null, 2)},
45
+ testing: ${JSON.stringify(options.testing ?? [], null, 2)},
46
+ formats: ${JSON.stringify(options.formats ?? [], null, 2)},
47
+ tools: ${JSON.stringify(options.tools ?? [], null, 2)},
48
+ extensions: ${JSON.stringify(options.extensions ?? [], null, 2)},
49
+ runtime: ${JSON.stringify(options.runtime ?? "universal")},
50
+ settings: ${JSON.stringify(options.settings ?? [], null, 2)}
51
+ })
52
+ `;
53
+ return {
54
+ configPath: resolveConfigPath(cwd),
55
+ configContent
56
+ };
57
+ };
58
+ const handleInit = (cwd = process.cwd()) => {
59
+ const configPath = resolveConfigPath(cwd);
60
+ if (existsSync(configPath)) {
61
+ console.warn(`\u26A0\uFE0F ${basename(configPath)} already exists. Skipping...`);
62
+ return;
63
+ }
64
+ console.log("\u{1F50D} Detecting project settings...");
65
+ const { configContent } = createConfigContent(cwd);
66
+ writeFileSync(configPath, configContent);
67
+ console.log(`\u2705 Created ${basename(configPath)} with auto-detected settings!`);
68
+ console.log("\u{1F680} Ready to lint!");
69
+ };
70
+ const handleUpdate = (cwd = process.cwd()) => {
71
+ console.log("\u{1F50D} Detecting project settings...");
72
+ const { configPath, configContent } = createConfigContent(cwd);
73
+ writeFileSync(configPath, configContent);
74
+ console.log(`\u2705 Updated ${basename(configPath)} with auto-detected settings!`);
75
+ console.log("\u{1F680} Ready to lint!");
76
+ };
77
+ const run = () => {
78
+ const command = process.argv[2];
79
+ if (command === "init") {
80
+ handleInit();
81
+ } else if (command === "update") {
82
+ handleUpdate();
83
+ } else {
84
+ console.log("Usage: basic-eslint <init|update>");
85
+ }
86
+ };
87
+ if (process.argv[1] && (process.argv[1] === fileURLToPath(import.meta.url) || process.argv[1].endsWith("cli.js") || process.argv[1].endsWith("cli.ts"))) {
88
+ run();
89
+ }
90
+ export {
91
+ handleInit,
92
+ handleUpdate
93
+ };
@@ -0,0 +1,8 @@
1
+ import { FlatConfigArray } from '@santi020k/eslint-config-core';
2
+
3
+ /**
4
+ * Applies strict mode by promoting all 'warn' rules to 'error'.
5
+ */
6
+ declare const applyStrictMode: (configs: FlatConfigArray, strict: boolean) => FlatConfigArray;
7
+
8
+ export { applyStrictMode };
@@ -0,0 +1,23 @@
1
+ const promoteRuleSeverity = (value) => {
2
+ if (value === void 0) return void 0;
3
+ if (value === "warn" || value === 1) return "error";
4
+ if (Array.isArray(value) && (value[0] === "warn" || value[0] === 1)) {
5
+ return ["error", ...value.slice(1)];
6
+ }
7
+ return value;
8
+ };
9
+ const applyStrictMode = (configs, strict) => {
10
+ if (!strict) return configs;
11
+ return configs.map((config) => {
12
+ if (config.rules) {
13
+ const strictRules = Object.fromEntries(
14
+ Object.entries(config.rules).map(([key, value]) => [key, promoteRuleSeverity(value)])
15
+ );
16
+ return { ...config, rules: strictRules };
17
+ }
18
+ return config;
19
+ });
20
+ };
21
+ export {
22
+ applyStrictMode
23
+ };
package/dist/index.d.ts CHANGED
@@ -1,13 +1,7 @@
1
1
  import { EslintConfigOptions, FlatConfigArray } from '@santi020k/eslint-config-core';
2
- export { ConfigOption, EslintConfigOptions, FlatConfigArray, OptionalOption, ReactConfigs, SettingOption, applyConfigIfOptionPresent, coreConfig, gitignore, hasReactConfig, jsConfig } from '@santi020k/eslint-config-core';
2
+ export { EslintConfigOptions, Extension, FlatConfigArray, Format, ImportedFramework, Library, NextMode, Preset, ReactConfigKeys, Runtime, Setting, Testing, Tool, coreConfig, createCoreConfig, detectProjectOptions, getGlobalsForRuntime, gitignore, hasReactConfig, jsConfig } from '@santi020k/eslint-config-core';
3
3
  export { tsConfig, typescriptConfig } from '@santi020k/eslint-config-typescript';
4
- export { reactConfig } from '@santi020k/eslint-config-react';
5
- export { nextConfig } from '@santi020k/eslint-config-next';
6
- export { astroConfig } from '@santi020k/eslint-config-astro';
7
- export { expoConfig } from '@santi020k/eslint-config-expo';
8
- export { nestConfig } from '@santi020k/eslint-config-nest';
9
- export { vueConfig } from '@santi020k/eslint-config-vue';
10
- export { cspell, i18next, markdown, mdx, playwright, prettier, regexp, sonarjs, stencil, tailwind, unicorn, vitest } from '@santi020k/eslint-config-optionals';
4
+ export { cspell, cypress, graphql, i18next, jest, jsdoc, jsonc, markdown, mdx, perfectionist, playwright, prettier, regexp, security, sonarjs, stencil, storybook, swagger, tailwind, tanstackQuery, tanstackRouter, testingLibrary, toml, unicorn, vitest, yaml } from '@santi020k/eslint-config-optionals';
11
5
 
12
6
  /**
13
7
  * Generates the ESLint configuration array, applying configurations
@@ -16,6 +10,6 @@ export { cspell, i18next, markdown, mdx, playwright, prettier, regexp, sonarjs,
16
10
  * @param {EslintConfigOptions} options - Configuration and optional settings
17
11
  * @returns {FlatConfigArray} The final ESLint configuration array
18
12
  */
19
- declare const eslintConfig: ({ config, optionals, settings }?: EslintConfigOptions) => FlatConfigArray;
13
+ declare const eslintConfig: (options?: EslintConfigOptions) => FlatConfigArray;
20
14
 
21
15
  export { eslintConfig };
package/dist/index.js CHANGED
@@ -1,135 +1,204 @@
1
- // src/index.ts
1
+ import { applyStrictMode } from "./compose.js";
2
+ import { getOptionalConfigs, getPrettierConfig } from "./optionals.js";
3
+ import { resolveFramework, resolvePreset } from "./resolvers.js";
2
4
  import {
3
- ConfigOption,
4
- OptionalOption,
5
- SettingOption,
6
- ReactConfigs,
7
- applyConfigIfOptionPresent,
8
- hasReactConfig,
9
5
  coreConfig,
6
+ createCoreConfig,
7
+ detectProjectOptions,
8
+ gitignore,
9
+ hasReactConfig,
10
+ NextMode,
11
+ Runtime,
12
+ Setting
13
+ } from "@santi020k/eslint-config-core";
14
+ import { createTypescriptConfig } from "@santi020k/eslint-config-typescript";
15
+ import {
16
+ Library,
17
+ Tool,
18
+ Extension,
19
+ Setting as Setting2,
20
+ Runtime as Runtime2,
21
+ Preset,
22
+ Testing,
23
+ Format,
24
+ NextMode as NextMode2,
25
+ ReactConfigKeys,
26
+ hasReactConfig as hasReactConfig2,
27
+ coreConfig as coreConfig2,
28
+ createCoreConfig as createCoreConfig2,
29
+ getGlobalsForRuntime,
10
30
  jsConfig,
11
- gitignore
31
+ gitignore as gitignore2,
32
+ detectProjectOptions as detectProjectOptions2
12
33
  } from "@santi020k/eslint-config-core";
13
34
  import { typescriptConfig, tsConfig } from "@santi020k/eslint-config-typescript";
14
- import { reactConfig } from "@santi020k/eslint-config-react";
15
- import { nextConfig } from "@santi020k/eslint-config-next";
16
- import { astroConfig } from "@santi020k/eslint-config-astro";
17
- import { expoConfig } from "@santi020k/eslint-config-expo";
18
- import { nestConfig } from "@santi020k/eslint-config-nest";
19
- import { vueConfig } from "@santi020k/eslint-config-vue";
20
35
  import {
21
36
  cspell,
37
+ cypress,
38
+ graphql,
22
39
  i18next,
40
+ jest,
41
+ jsdoc,
42
+ jsonc,
23
43
  markdown,
24
44
  mdx,
45
+ perfectionist,
46
+ playwright,
25
47
  prettier,
26
48
  regexp,
49
+ security,
50
+ sonarjs,
27
51
  stencil,
52
+ storybook,
53
+ swagger,
28
54
  tailwind,
55
+ tanstackQuery,
56
+ tanstackRouter,
57
+ testingLibrary,
58
+ toml,
29
59
  unicorn,
30
60
  vitest,
31
- playwright,
32
- sonarjs
61
+ yaml
33
62
  } from "@santi020k/eslint-config-optionals";
34
- import { astroConfig as astroConfig2 } from "@santi020k/eslint-config-astro";
35
- import {
36
- applyConfigIfOptionPresent as applyConfigIfOptionPresent2,
37
- ConfigOption as ConfigOption2,
38
- coreConfig as coreConfig2,
39
- gitignore as gitignore2,
40
- hasReactConfig as hasReactConfig2,
41
- OptionalOption as OptionalOption2,
42
- SettingOption as SettingOption2
43
- } from "@santi020k/eslint-config-core";
44
- import { expoConfig as expoConfig2 } from "@santi020k/eslint-config-expo";
45
- import { nestConfig as nestConfig2 } from "@santi020k/eslint-config-nest";
46
- import { nextConfig as nextConfig2 } from "@santi020k/eslint-config-next";
47
- import {
48
- cspell as cspell2,
49
- i18next as i18next2,
50
- markdown as markdown2,
51
- mdx as mdx2,
52
- playwright as playwright2,
53
- prettier as prettier2,
54
- regexp as regexp2,
55
- sonarjs as sonarjs2,
56
- stencil as stencil2,
57
- tailwind as tailwind2,
58
- unicorn as unicorn2,
59
- vitest as vitest2
60
- } from "@santi020k/eslint-config-optionals";
61
- import { reactConfig as reactConfig2 } from "@santi020k/eslint-config-react";
62
- import { typescriptConfig as typescriptConfig2 } from "@santi020k/eslint-config-typescript";
63
- import { vueConfig as vueConfig2 } from "@santi020k/eslint-config-vue";
64
- var eslintConfig = ({
65
- config = [],
66
- optionals = [],
67
- settings = []
68
- } = {}) => {
69
- const uniqueConfig = [...new Set(config)];
70
- const uniqueOptionals = [...new Set(optionals)];
63
+ const eslintConfig = (options) => {
64
+ const detected = detectProjectOptions();
65
+ const preset = options?.preset ?? detected.preset;
66
+ const presetDefaults = preset ? resolvePreset(preset) : {};
67
+ const {
68
+ typescript = presetDefaults.typescript ?? detected.typescript ?? false,
69
+ libraries = presetDefaults.libraries ?? detected.libraries ?? [],
70
+ testing = presetDefaults.testing ?? detected.testing ?? [],
71
+ formats = presetDefaults.formats ?? detected.formats ?? [],
72
+ tools = presetDefaults.tools ?? detected.tools ?? [],
73
+ extensions = presetDefaults.extensions ?? detected.extensions ?? [],
74
+ settings = options?.settings ?? detected.settings ?? [],
75
+ strict = options?.strict ?? false,
76
+ runtime = presetDefaults.runtime ?? detected.runtime ?? Runtime.Universal,
77
+ tsconfigRootDir = options?.tsconfigRootDir,
78
+ nextMode = presetDefaults.nextMode ?? detected.nextMode ?? NextMode.Pages,
79
+ frameworks = { ...presetDefaults.frameworks, ...options?.frameworks }
80
+ } = options ?? {};
81
+ const uniqueLibraries = [...new Set(libraries)];
82
+ const uniqueTesting = [...new Set(testing)];
83
+ const uniqueFormats = [...new Set(formats)];
84
+ const uniqueTools = [...new Set(tools)];
85
+ const uniqueExtensions = [...new Set(extensions)];
71
86
  const uniqueSettings = [...new Set(settings)];
72
- const hasReact = hasReactConfig2(uniqueConfig);
73
- const useGitignore = !uniqueSettings.includes(SettingOption2.NoGitignore);
74
- return [
87
+ if ((frameworks.next || frameworks.expo) && !frameworks.react) {
88
+ throw new TypeError(
89
+ "Next and Expo configurations require frameworks.react. Import @santi020k/eslint-config-react and pass it via frameworks.react."
90
+ );
91
+ }
92
+ const reactParam = resolveFramework("react", frameworks.react);
93
+ const nextParam = resolveFramework("next", frameworks.next);
94
+ const astroParam = resolveFramework("astro", frameworks.astro);
95
+ const expoParam = resolveFramework("expo", frameworks.expo);
96
+ const nestParam = resolveFramework("nest", frameworks.nest);
97
+ const vueParam = resolveFramework("vue", frameworks.vue);
98
+ const svelteParam = resolveFramework("svelte", frameworks.svelte);
99
+ const solidParam = resolveFramework("solid", frameworks.solid);
100
+ const angularParam = resolveFramework("angular", frameworks.angular);
101
+ const qwikParam = resolveFramework("qwik", frameworks.qwik);
102
+ const remixParam = resolveFramework("remix", frameworks.remix);
103
+ const hasReact = hasReactConfig({ frameworks });
104
+ const useGitignore = !uniqueSettings.includes(Setting.NoGitignore);
105
+ const runtimeCoreConfig = runtime !== Runtime.Universal ? createCoreConfig(runtime) : coreConfig;
106
+ const configs = [
75
107
  // Settings
76
- ...useGitignore ? gitignore2 : [],
77
- // Core JS config (always included)
78
- ...coreConfig2,
79
- // React config (included if any React-based framework is used)
80
- ...hasReact ? reactConfig2 : [],
81
- // Framework-specific configs
82
- ...applyConfigIfOptionPresent2(uniqueConfig, ConfigOption2.Ts, typescriptConfig2),
83
- ...applyConfigIfOptionPresent2(uniqueConfig, ConfigOption2.Next, nextConfig2),
84
- ...applyConfigIfOptionPresent2(uniqueConfig, ConfigOption2.Astro, astroConfig2),
85
- ...applyConfigIfOptionPresent2(uniqueConfig, ConfigOption2.Expo, expoConfig2),
86
- ...applyConfigIfOptionPresent2(uniqueConfig, ConfigOption2.Nest, nestConfig2),
87
- ...applyConfigIfOptionPresent2(uniqueConfig, ConfigOption2.Vue, vueConfig2),
108
+ ...useGitignore ? gitignore : [],
109
+ // Global TSConfig Root Dir fix
110
+ ...tsconfigRootDir ? [{
111
+ name: "eslint-config-basic/tsconfig-root-dir",
112
+ languageOptions: {
113
+ parserOptions: {
114
+ tsconfigRootDir
115
+ }
116
+ }
117
+ }] : [],
118
+ // Core JS config with runtime-aware globals
119
+ ...runtimeCoreConfig,
120
+ // React config (included if any React-based framework is used/passed)
121
+ ...hasReact ? reactParam : [],
122
+ // Framework-specific configs (Modularized)
123
+ ...typescript ? createTypescriptConfig({ tsconfigRootDir }) : [],
124
+ ...nextParam,
125
+ // Next.js App Router overrides (#12)
126
+ ...frameworks.next && nextMode === NextMode.AppRouter ? [
127
+ {
128
+ name: "eslint-config-next/app-router-overrides",
129
+ files: ["app/**/*.{ts,tsx}"],
130
+ rules: {
131
+ "@next/next/no-html-link-for-pages": "off"
132
+ }
133
+ }
134
+ ] : [],
135
+ ...astroParam,
136
+ ...expoParam,
137
+ ...nestParam,
138
+ ...vueParam,
139
+ ...svelteParam,
140
+ ...solidParam,
141
+ ...angularParam,
142
+ ...qwikParam,
143
+ ...remixParam,
88
144
  // Optionals
89
- ...uniqueOptionals.includes(OptionalOption2.Cspell) ? cspell2 : [],
90
- ...uniqueOptionals.includes(OptionalOption2.Tailwind) ? tailwind2 : [],
91
- ...uniqueOptionals.includes(OptionalOption2.Vitest) ? vitest2 : [],
92
- ...uniqueOptionals.includes(OptionalOption2.I18next) ? i18next2 : [],
93
- ...uniqueOptionals.includes(OptionalOption2.Stencil) ? stencil2 : [],
94
- ...uniqueOptionals.includes(OptionalOption2.Regexp) ? regexp2 : [],
95
- ...uniqueOptionals.includes(OptionalOption2.Mdx) ? mdx2 : [],
96
- ...uniqueOptionals.includes(OptionalOption2.Markdown) ? markdown2 : [],
97
- ...uniqueOptionals.includes(OptionalOption2.Unicorn) ? unicorn2 : [],
98
- ...uniqueOptionals.includes(OptionalOption2.Sonarjs) ? sonarjs2 : [],
99
- ...uniqueOptionals.includes(OptionalOption2.Playwright) ? playwright2 : [],
100
- // Prettier must be last to override stylistic rules
101
- ...uniqueOptionals.includes(OptionalOption2.Prettier) ? prettier2 : []
145
+ ...getOptionalConfigs(
146
+ uniqueLibraries,
147
+ uniqueTools,
148
+ uniqueTesting,
149
+ uniqueFormats,
150
+ uniqueExtensions
151
+ ),
152
+ // Prettier always last
153
+ ...getPrettierConfig(uniqueTools)
102
154
  ];
155
+ return applyStrictMode(configs, strict);
103
156
  };
104
157
  export {
105
- ConfigOption,
106
- OptionalOption,
107
- ReactConfigs,
108
- SettingOption,
109
- applyConfigIfOptionPresent,
110
- astroConfig,
111
- coreConfig,
158
+ Extension,
159
+ Format,
160
+ Library,
161
+ NextMode2 as NextMode,
162
+ Preset,
163
+ ReactConfigKeys,
164
+ Runtime2 as Runtime,
165
+ Setting2 as Setting,
166
+ Testing,
167
+ Tool,
168
+ coreConfig2 as coreConfig,
169
+ createCoreConfig2 as createCoreConfig,
112
170
  cspell,
171
+ cypress,
172
+ detectProjectOptions2 as detectProjectOptions,
113
173
  eslintConfig,
114
- expoConfig,
115
- gitignore,
116
- hasReactConfig,
174
+ getGlobalsForRuntime,
175
+ gitignore2 as gitignore,
176
+ graphql,
177
+ hasReactConfig2 as hasReactConfig,
117
178
  i18next,
179
+ jest,
118
180
  jsConfig,
181
+ jsdoc,
182
+ jsonc,
119
183
  markdown,
120
184
  mdx,
121
- nestConfig,
122
- nextConfig,
185
+ perfectionist,
123
186
  playwright,
124
187
  prettier,
125
- reactConfig,
126
188
  regexp,
189
+ security,
127
190
  sonarjs,
128
191
  stencil,
192
+ storybook,
193
+ swagger,
129
194
  tailwind,
195
+ tanstackQuery,
196
+ tanstackRouter,
197
+ testingLibrary,
198
+ toml,
130
199
  tsConfig,
131
200
  typescriptConfig,
132
201
  unicorn,
133
202
  vitest,
134
- vueConfig
203
+ yaml
135
204
  };
@@ -0,0 +1,13 @@
1
+ import { Library, Tool, Testing, Format, Extension, FlatConfigArray } from '@santi020k/eslint-config-core';
2
+
3
+ /**
4
+ * Gets the optional configurations based on selected options.
5
+ * This function maintains the recommended ordering (e.g. Prettier last).
6
+ */
7
+ declare const getOptionalConfigs: (libraries: Library[], tools: Tool[], testing: Testing[], formats: Format[], extensions: Extension[]) => FlatConfigArray;
8
+ /**
9
+ * Returns the Prettier configuration if selected.
10
+ */
11
+ declare const getPrettierConfig: (tools: Tool[]) => FlatConfigArray;
12
+
13
+ export { getOptionalConfigs, getPrettierConfig };
@@ -0,0 +1,69 @@
1
+ import {
2
+ Extension,
3
+ Format,
4
+ Library,
5
+ Testing,
6
+ Tool
7
+ } from "@santi020k/eslint-config-core";
8
+ import {
9
+ cspell,
10
+ cypress,
11
+ graphql,
12
+ i18next,
13
+ jest,
14
+ jsdoc,
15
+ jsonc,
16
+ markdown,
17
+ mdx,
18
+ perfectionist,
19
+ playwright,
20
+ prettier,
21
+ regexp,
22
+ security,
23
+ sonarjs,
24
+ stencil,
25
+ storybook,
26
+ swagger,
27
+ tailwind,
28
+ tanstackQuery,
29
+ tanstackRouter,
30
+ testingLibrary,
31
+ toml,
32
+ unicorn,
33
+ vitest,
34
+ yaml
35
+ } from "@santi020k/eslint-config-optionals";
36
+ const getOptionalConfigs = (libraries, tools, testing, formats, extensions) => {
37
+ const configs = [];
38
+ if (tools.includes(Tool.Cspell)) configs.push(...cspell);
39
+ if (libraries.includes(Library.Tailwind)) configs.push(...tailwind);
40
+ if (libraries.includes(Library.I18next)) configs.push(...i18next);
41
+ if (libraries.includes(Library.Stencil)) configs.push(...stencil);
42
+ if (libraries.includes(Library.TanstackQuery)) configs.push(...tanstackQuery);
43
+ if (libraries.includes(Library.TanstackRouter)) configs.push(...tanstackRouter);
44
+ if (libraries.includes(Library.Storybook)) configs.push(...storybook);
45
+ if (testing.includes(Testing.Vitest)) configs.push(...vitest);
46
+ if (testing.includes(Testing.Playwright)) configs.push(...playwright);
47
+ if (testing.includes(Testing.Jest)) configs.push(...jest);
48
+ if (testing.includes(Testing.Cypress)) configs.push(...cypress);
49
+ if (testing.includes(Testing.TestingLibrary)) configs.push(...testingLibrary);
50
+ if (formats.includes(Format.Mdx)) configs.push(...mdx);
51
+ if (formats.includes(Format.Markdown)) configs.push(...markdown);
52
+ if (formats.includes(Format.Jsonc)) configs.push(...jsonc);
53
+ if (formats.includes(Format.Yaml)) configs.push(...yaml);
54
+ if (formats.includes(Format.Toml)) configs.push(...toml);
55
+ if (formats.includes(Format.Graphql)) configs.push(...graphql);
56
+ if (extensions.includes(Extension.Regexp)) configs.push(...regexp);
57
+ if (extensions.includes(Extension.Unicorn)) configs.push(...unicorn);
58
+ if (extensions.includes(Extension.Sonarjs)) configs.push(...sonarjs);
59
+ if (extensions.includes(Extension.Security)) configs.push(...security);
60
+ if (extensions.includes(Extension.Perfectionist)) configs.push(...perfectionist);
61
+ if (tools.includes(Tool.Jsdoc)) configs.push(...jsdoc);
62
+ if (tools.includes(Tool.Swagger)) configs.push(...swagger);
63
+ return configs;
64
+ };
65
+ const getPrettierConfig = (tools) => tools.includes(Tool.Prettier) ? prettier : [];
66
+ export {
67
+ getOptionalConfigs,
68
+ getPrettierConfig
69
+ };
@@ -0,0 +1,12 @@
1
+ import { ImportedFramework, FlatConfigArray, Preset, EslintConfigOptions } from '@santi020k/eslint-config-core';
2
+
3
+ /**
4
+ * Resolves an imported framework (either array or default export) into a config array.
5
+ */
6
+ declare const resolveFramework: (frameworkName: string, framework?: ImportedFramework) => FlatConfigArray;
7
+ /**
8
+ * Resolves a preset into options
9
+ */
10
+ declare const resolvePreset: (preset: Preset) => Partial<EslintConfigOptions>;
11
+
12
+ export { resolveFramework, resolvePreset };
@@ -0,0 +1,50 @@
1
+ import {
2
+ Extension,
3
+ Format,
4
+ Library,
5
+ Preset,
6
+ Runtime,
7
+ Testing,
8
+ Tool
9
+ } from "@santi020k/eslint-config-core";
10
+ const resolveFramework = (frameworkName, framework) => {
11
+ if (!framework) return [];
12
+ if (framework === true) {
13
+ throw new TypeError(
14
+ `Framework "${frameworkName}" requires an imported config. Install @santi020k/eslint-config-${frameworkName} and pass it via frameworks.${frameworkName}.`
15
+ );
16
+ }
17
+ return Array.isArray(framework) ? framework : framework.default;
18
+ };
19
+ const resolvePreset = (preset) => {
20
+ switch (preset) {
21
+ case Preset.Basic:
22
+ return { runtime: Runtime.Universal };
23
+ case Preset.Node:
24
+ return {
25
+ typescript: true,
26
+ runtime: Runtime.Node
27
+ };
28
+ case Preset.Browser:
29
+ return {
30
+ typescript: true,
31
+ runtime: Runtime.Browser
32
+ };
33
+ case Preset.All:
34
+ return {
35
+ typescript: true,
36
+ libraries: Object.values(Library),
37
+ tools: Object.values(Tool),
38
+ testing: Object.values(Testing),
39
+ formats: Object.values(Format),
40
+ extensions: Object.values(Extension),
41
+ runtime: Runtime.Universal
42
+ };
43
+ default:
44
+ return {};
45
+ }
46
+ };
47
+ export {
48
+ resolveFramework,
49
+ resolvePreset
50
+ };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@santi020k/eslint-config-basic",
3
- "version": "0.7.1",
4
- "description": "A comprehensive ESLint configuration package for JavaScript, TypeScript, and React projects.",
3
+ "version": "1.0.0",
4
+ "description": "A composable ESLint 9/10+ Flat Config package for JavaScript, TypeScript, React, Next.js, Vue, Svelte, Solid, Angular, Astro, Expo, NestJS, Qwik, and Remix.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "module": "./dist/index.js",
@@ -17,46 +17,88 @@
17
17
  "README.md",
18
18
  "CHANGELOG.md"
19
19
  ],
20
- "scripts": {
21
- "build": "tsup",
22
- "build:pack": "npm pack",
23
- "dev": "tsup --watch",
24
- "clean": "rm -rf dist",
25
- "check:exports": "publint",
26
- "prepack": "rm -f README.md && cp ../../README.md ./README.md",
27
- "postpack": "rm -f README.md && ln -s ../../README.md ./README.md"
20
+ "bin": {
21
+ "basic-eslint": "./dist/cli.js"
28
22
  },
29
23
  "dependencies": {
30
- "@santi020k/eslint-config-astro": "^0.7.1",
31
- "@santi020k/eslint-config-core": "^0.7.1",
32
- "@santi020k/eslint-config-expo": "^0.7.1",
33
- "@santi020k/eslint-config-nest": "^0.7.1",
34
- "@santi020k/eslint-config-next": "^0.7.1",
35
- "@santi020k/eslint-config-optionals": "^0.7.1",
36
- "@santi020k/eslint-config-react": "^0.7.1",
37
- "@santi020k/eslint-config-typescript": "^0.7.1",
38
- "@santi020k/eslint-config-vue": "^0.7.1",
39
- "@eslint/compat": "^2.0.3",
40
- "@eslint/js": "^10.0.1",
41
- "@typescript-eslint/eslint-plugin": "^8.57.0",
42
- "@typescript-eslint/type-utils": "^8.57.0",
43
- "cross-dirname": "^0.1.0",
44
- "eslint": "^10.0.3",
45
- "typescript-eslint": "^8.57.0"
24
+ "@typescript-eslint/utils": "^8.57.0",
25
+ "@santi020k/eslint-config-core": "^1.0.0",
26
+ "@santi020k/eslint-config-optionals": "^1.0.0",
27
+ "@santi020k/eslint-config-typescript": "^1.0.0"
28
+ },
29
+ "peerDependencies": {
30
+ "eslint": "^9.0.0 || ^10.0.0",
31
+ "@santi020k/eslint-config-angular": "^1.0.0",
32
+ "@santi020k/eslint-config-astro": "^1.0.0",
33
+ "@santi020k/eslint-config-expo": "^1.0.0",
34
+ "@santi020k/eslint-config-nest": "^1.0.0",
35
+ "@santi020k/eslint-config-next": "^1.0.0",
36
+ "@santi020k/eslint-config-react": "^1.0.0",
37
+ "@santi020k/eslint-config-solid": "^1.0.0",
38
+ "@santi020k/eslint-config-svelte": "^1.0.0",
39
+ "@santi020k/eslint-config-vue": "^1.0.0",
40
+ "@santi020k/eslint-config-qwik": "^0.8.2",
41
+ "@santi020k/eslint-config-remix": "^0.8.2"
42
+ },
43
+ "peerDependenciesMeta": {
44
+ "@santi020k/eslint-config-angular": {
45
+ "optional": true
46
+ },
47
+ "@santi020k/eslint-config-astro": {
48
+ "optional": true
49
+ },
50
+ "@santi020k/eslint-config-expo": {
51
+ "optional": true
52
+ },
53
+ "@santi020k/eslint-config-nest": {
54
+ "optional": true
55
+ },
56
+ "@santi020k/eslint-config-next": {
57
+ "optional": true
58
+ },
59
+ "@santi020k/eslint-config-react": {
60
+ "optional": true
61
+ },
62
+ "@santi020k/eslint-config-solid": {
63
+ "optional": true
64
+ },
65
+ "@santi020k/eslint-config-svelte": {
66
+ "optional": true
67
+ },
68
+ "@santi020k/eslint-config-vue": {
69
+ "optional": true
70
+ },
71
+ "@santi020k/eslint-config-qwik": {
72
+ "optional": true
73
+ },
74
+ "@santi020k/eslint-config-remix": {
75
+ "optional": true
76
+ }
46
77
  },
47
78
  "devDependencies": {
79
+ "publint": "^0.3.18",
48
80
  "tsup": "^8.5.1",
49
- "typescript": "^5.9.3",
50
- "@typescript-eslint/utils": "^8.57.0"
81
+ "typescript": "^5.9.3"
51
82
  },
52
83
  "publishConfig": {
53
84
  "access": "public"
54
85
  },
86
+ "engines": {
87
+ "node": ">=22.12.0"
88
+ },
55
89
  "license": "MIT",
56
90
  "author": "santi020k",
57
91
  "repository": {
58
92
  "type": "git",
59
93
  "url": "git+https://github.com/santi020k/eslint-config-basic.git",
60
94
  "directory": "packages/basic"
95
+ },
96
+ "scripts": {
97
+ "build": "tsup",
98
+ "build:pack": "npm pack",
99
+ "dev": "tsup --watch",
100
+ "clean": "rm -rf dist",
101
+ "check:exports": "publint",
102
+ "typecheck": "tsc --noEmit"
61
103
  }
62
- }
104
+ }