@shayanthenerd/eslint-config 0.14.0 → 0.15.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.
Files changed (51) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +187 -178
  3. package/dist/configs/base.mjs +13 -9
  4. package/dist/configs/css.mjs +2 -2
  5. package/dist/configs/cypress.mjs +2 -2
  6. package/dist/configs/html.mjs +2 -2
  7. package/dist/configs/importX.mjs +2 -2
  8. package/dist/configs/oxlintOverrides.mjs +16 -11
  9. package/dist/configs/perfectionist.mjs +2 -2
  10. package/dist/configs/playwright.mjs +2 -2
  11. package/dist/configs/restrictedExports.mjs +1 -1
  12. package/dist/configs/storybook.mjs +2 -2
  13. package/dist/configs/stylistic.mjs +2 -2
  14. package/dist/configs/tailwind.mjs +4 -4
  15. package/dist/configs/typescript.mjs +2 -2
  16. package/dist/configs/vitest.mjs +2 -2
  17. package/dist/configs/vue.mjs +2 -2
  18. package/dist/configs/vueComponentNames.mjs +1 -1
  19. package/dist/configs/vueServerComponents.mjs +1 -1
  20. package/dist/configs/zod.mjs +2 -2
  21. package/dist/{utils → helpers}/globs.mjs +1 -1
  22. package/dist/{utils → helpers}/ignores/defaultIgnorePatterns.mjs +1 -1
  23. package/dist/{utils → helpers}/ignores/getIgnorePatterns.mjs +1 -1
  24. package/dist/{utils → helpers}/ignores/resolveGitignorePatterns.mjs +1 -1
  25. package/dist/{utils → helpers}/isPackageDetected.mjs +1 -1
  26. package/dist/{utils → helpers}/options/defaultOptions.mjs +13 -7
  27. package/dist/{utils → helpers}/options/enableDetectedConfigs.mjs +1 -3
  28. package/dist/{utils → helpers}/options/mergeWithDefaults.mjs +4 -5
  29. package/dist/{utils → helpers}/vue/getRestrictedVueElements.mjs +1 -1
  30. package/dist/{utils → helpers}/vue/getRestrictedVueInputs.mjs +1 -1
  31. package/dist/index.mjs +3 -3
  32. package/dist/oxlint.config.jsonc +209 -206
  33. package/dist/prettier.config.mjs +1 -1
  34. package/dist/rules/css.mjs +1 -1
  35. package/dist/rules/html.mjs +3 -3
  36. package/dist/rules/importX.mjs +1 -1
  37. package/dist/rules/javascript.mjs +1 -2
  38. package/dist/rules/perfectionist.mjs +2 -2
  39. package/dist/rules/stylistic.mjs +10 -7
  40. package/dist/rules/tailwind.mjs +4 -4
  41. package/dist/rules/typescript.mjs +2 -2
  42. package/dist/rules/vue.mjs +6 -6
  43. package/dist/rules/vueAccessibility.mjs +1 -1
  44. package/dist/types/configOptions/base.d.mts +8 -8
  45. package/dist/types/configOptions/nuxt.d.mts +3 -3
  46. package/dist/types/configOptions/stylistic.d.mts +0 -15
  47. package/dist/types/configOptions/test.d.mts +4 -4
  48. package/dist/types/configOptions/vue.d.mts +1 -1
  49. package/dist/types/eslint-schema.d.mts +549 -201
  50. package/dist/types/index.d.mts +36 -19
  51. package/package.json +139 -124
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 Shayan Zamani
3
+ Copyright (c) 2026 Shayan Zamani
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -35,6 +35,13 @@ npm i -D @shayanthenerd/eslint-config
35
35
  ```
36
36
 
37
37
  OXLint and all necessary ESLint plugins and parsers will be installed automatically.
38
+ > [!important]
39
+ > If you're using PNPM without `shamefullyHoist: true`, make sure to install `eslint` and `oxlint` separately with `pnpm i -D eslint oxlint`, or hoist them in _pnpm-workspace.yaml_:
40
+ > ```yaml
41
+ > publicHoistPattern:
42
+ > - eslint
43
+ > - oxlint
44
+ > ```
38
45
 
39
46
  2. Create an ESLint config file (_eslint.config.js_) at the root of your project:
40
47
  ```js
@@ -64,7 +71,7 @@ export default eslintConfigNuxt(eslintConfig);
64
71
  > [!NOTE]
65
72
  > The Nuxt config relies on the Vue config, so make sure it's enabled (either automatically or manually).
66
73
 
67
- 3. Create an OXLint config file (_.oxlintrc.json_) in the root of your project:
74
+ 3. If you're not using OXLint, set `configs.oxlint` to `false` in your ESLint config and skip this step. Otherwise, create an OXLint config file (_.oxlintrc.json_) in the root of your project:
68
75
  ```jsonc
69
76
  {
70
77
  "$schema": "./node_modules/oxlint/configuration_schema.json", // Optional
@@ -122,11 +129,15 @@ npm run lint:inspect
122
129
  ```
123
130
 
124
131
  ## Automatic Dependency Detection
125
- By default, this config automatically detects dependencies in your project, and enables the appropriate ESLint configurations. This is powered by [local-pkg](https://github.com/antfu-collective/local-pkg), which scans your _node_modules_ directory instead of _package.json_. <br />
126
- For instance, if you install a package "A" that depends on another package "B", your package manager will install both. Even if "B" isn't listed in your _package.json_ file, it will be present in _node_modules_. Consequently, this config will detect both "A" and "B" and enable the appropriate ESLint configurations for them. <br />
132
+ This package automatically detects dependencies in your project and enables the corresponding ESLint configurations for them. This is powered by [local-pkg](https://github.com/antfu-collective/local-pkg), which scans your _node_modules_ directory instead of _package.json_. <br />
133
+ > [!IMPORTANT]
134
+ > This behavior is particularly noticeable with package managers that use a flat _node_modules_ structure, such as **NPM** or **Bun**. <br />
135
+ A concrete example is `eslint-plugin-storybook`, which is a dependency of this package. Since the plugin transitively depends on `storybook`, NPM and Bun hoist `storybook` to the root of your _node_modules_. As a result, the ESLint configuration for `storybook` will be automatically enabled, even if you haven't explicitly installed it. <br />
136
+ Using a package manager with strict dependency resolution, such as **PNPM**, prevents this issue by hiding transitive dependencies from the root of your _node_modules_.
137
+
127
138
  To opt out of this behavior, you can either set `autoDetectDeps: false` in the options object or explicitly disable any unwanted configurations that were automatically enabled.
128
139
 
129
- Unlike other plugins, the configurations for Tailwind aren't automatically enabled upon dependency detection. This is because you must explicitly provide the path to your Tailwind config file or entry point.
140
+ Unlike other plugins, the configuration for Tailwind isn't automatically enabled upon dependency detection, because you must explicitly provide the path to your Tailwind entry point (config file), or the ESLint configuration won't work as expected.
130
141
 
131
142
  Stylistic, Perfectionist, ImportX, and core (JavaScript) rules are enabled by default.
132
143
 
@@ -149,7 +160,7 @@ export default {
149
160
  };
150
161
  ```
151
162
 
152
- Or if you prefer using TypeScrpit (_prettier.config.ts_):
163
+ Or if you prefer using TypeScript (_prettier.config.ts_):
153
164
  ```ts
154
165
  import type { Config } from 'prettier';
155
166
 
@@ -170,7 +181,7 @@ export default {
170
181
  }
171
182
  ```
172
183
 
173
- For IDE setup guidance, refer to [VS Code Integration](#vs-code-integration).
184
+ For IDE setup guidance, see [VS Code Integration](#vs-code-integration).
174
185
 
175
186
  ## VS Code Integration
176
187
  Install VS Code extensions for [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint), [OXLint](https://marketplace.visualstudio.com/items?itemName=oxc.oxc-vscode), and [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode). Then, add the following in the _.vscode/settings.json_ file of your project:
@@ -181,7 +192,7 @@ Install VS Code extensions for [ESLint](https://marketplace.visualstudio.com/ite
181
192
 
182
193
  /* Enforce either tabs or spaces for indentation. */
183
194
  "editor.tabSize": 2,
184
- "editor.insertSpaces": false,
195
+ "editor.insertSpaces": true,
185
196
  "editor.detectIndentation": false,
186
197
 
187
198
  "editor.codeActionsOnSave": {
@@ -269,8 +280,7 @@ Since OXLint and ESLint use separate config files, customizations made in your E
269
280
  ```
270
281
 
271
282
  ### ESLint
272
-
273
- `defineConfig` takes the `options` object as the first argument. `options` is thoroughly documented with JSDoc, and provides many options for rule customizations. In addition, each config object in `options.configs` accepts an `overrides` option:
283
+ `defineConfig` takes the `options` object as the first argument. `options` is thoroughly documented with JSDoc and provides many options for rule customizations. In addition, each config object in `options.configs` accepts an `overrides` option:
274
284
  ```ts
275
285
  interface Overrides {
276
286
  name: '',
@@ -312,7 +322,7 @@ export default defineConfig(
312
322
 
313
323
  /* ESLint Flat Configs: */
314
324
  {
315
- files: ['**/*.yaml', '**/*.yml'],
325
+ files: ['**/*.yaml', '**/*.yml'],
316
326
  ignores: ['**/*.schema.yaml', '**/*.schema.yml'],
317
327
  extends: [pluginYaml.configs.recommended],
318
328
  },
@@ -322,187 +332,186 @@ export default defineConfig(
322
332
 
323
333
  ## API Reference
324
334
  <details>
325
- <summary>The API reference</summary>
326
- Some types are omitted or aliased for brevity.
327
-
328
- ```ts
329
- interface options {
330
- autoDetectDeps?: boolean | 'verbose',
331
- gitignore?: false | string,
332
- packageDir?: string,
333
- env?: 'bun' | 'node',
334
- tsConfig?: {
335
- rootDir: string,
336
- filename?: string,
337
- },
335
+ <summary>The API reference</summary>
336
+ Some types are omitted or aliased for brevity.
337
+
338
+ ```ts
339
+ interface Options {
340
+ autoDetectDeps?: boolean | 'verbose',
341
+ gitignore?: false | string,
342
+ packageDir?: string,
343
+ env?: 'bun' | 'node',
344
+ tsConfig?: {
345
+ rootDir: string,
346
+ filename?: string,
347
+ },
338
348
 
339
- global?: {
340
- name?: string,
341
- basePath?: string,
342
- ignores?: string[],
343
- globals?: {
344
- node?: boolean,
345
- commonjs?: boolean,
346
- browser?: boolean,
347
- worker?: boolean,
348
- serviceworker?: boolean,
349
- webextension?: boolean,
350
- custom?: {
351
- [key: string]: boolean | 'off' | 'readonly' | 'readable' | 'writable' | 'writeable',
349
+ global?: {
350
+ name?: string,
351
+ basePath?: string,
352
+ ignores?: string[],
353
+ globals?: {
354
+ node?: boolean,
355
+ commonjs?: boolean,
356
+ browser?: boolean,
357
+ worker?: boolean,
358
+ serviceworker?: boolean,
359
+ webextension?: boolean,
360
+ custom?: {
361
+ [key: string]: boolean | 'off' | 'readonly' | 'readable' | 'writable' | 'writeable',
362
+ },
363
+ }
364
+ linterOptions?: {
365
+ noInlineConfig?: boolean,
366
+ reportUnusedInlineConfigs?: 'error' | 'off' | 'warn',
367
+ reportUnusedDisableDirectives?: 'error' | 'off' | 'warn',
352
368
  },
353
- }
354
- linterOptions?: {
355
- noInlineConfig?: boolean,
356
- reportUnusedInlineConfigs?: 'error' | 'off' | 'warn',
357
- reportUnusedDisableDirectives?: 'error' | 'off' | 'warn',
369
+ settings?: {
370
+ [name: string]: unknown,
371
+ }
372
+ rules?: Linter.RulesRecord,
358
373
  },
359
- settings?: {
360
- [name: string]: unknown,
361
- }
362
- rules?: Linter.RulesRecord,
363
- },
364
374
 
365
- configs?: {
366
- oxlint?: false | string,
367
- base?: {
368
- maxDepth?: number,
369
- maxNestedCallbacks?: number,
370
- preferNamedExports?: boolean,
371
- functionStyle?: 'declaration' | 'expression',
372
- overrides?: {},
373
- },
374
- stylistic?: boolean | {
375
- semi?: 'always' | 'never',
376
- trailingComma?: 'always' | 'never' | 'always-multiline' | 'only-multiline',
377
- memberDelimiterStyle?: 'semi' | 'comma',
378
- quotes?: 'single' | 'double' | 'backtick',
379
- jsxQuotes?: 'prefer-single' | 'prefer-double',
380
- arrowParens?: 'always' | 'as-needed',
381
- useTabs?: boolean,
382
- indent?: number,
383
- maxConsecutiveEmptyLines?: number,
384
- maxLineLength?: number,
385
- maxAttributesPerLine?: number,
386
- selfCloseVoidHTMLElements?: 'never' | 'always',
387
- overrides?: {},
388
- },
389
- html?: boolean | {
390
- useBaseline?: number | false | 'widely' | 'newly',
391
- idNamingConvention?: 'camelCase' | 'snake_case' | 'PascalCase' | 'kebab-case',
392
- overrides?: {},
393
- },
394
- css?: boolean | {
395
- useBaseline?: number | false | 'widely' | 'newly',
396
- allowedRelativeFontUnits?: ('%' | 'cap' | 'ch' | 'em' | 'ex' | 'ic' | 'lh' | 'rcap' | 'rch' | 'rem' | 'rex' | 'ric' | 'rlh')[],
397
- overrides?: {},
398
- },
399
- tailwind?: false | {
400
- config: string,
401
- entryPoint?: string,
402
- multilineSort?: boolean,
403
- ignoredUnregisteredClasses?: string[],
404
- overrides?: {},
405
- } | {
406
- config?: string,
407
- entryPoint: string,
408
- multilineSort?: boolean,
409
- ignoredUnregisteredClasses?: string[],
410
- overrides?: {},
411
- },
412
- typescript?: boolean | {
413
- allowedDefaultProjects?: string[],
414
- methodSignatureStyle?: 'property' | 'method',
415
- typeDefinitionStyle?: 'interface' | 'type',
416
- overrides?: {},
417
- },
418
- importX?: boolean | {
419
- removeUnusedImports?: boolean,
420
- overrides?: {},
421
- },
422
- perfectionist?: boolean | {
423
- sortType?: 'custom' | 'natural' | 'alphabetical' | 'line-length' | 'unsorted',
424
- overrides?: {},
425
- },
426
- vue?: boolean | {
427
- accessibility?: boolean | {
428
- anchorComponents?: string[],
429
- imageComponents?: string[],
430
- accessibleChildComponents?: string[],
375
+ configs?: {
376
+ oxlint?: false | string,
377
+ base?: {
378
+ maxDepth?: number,
379
+ maxNestedCallbacks?: number,
380
+ preferNamedExports?: boolean,
381
+ functionStyle?: 'declaration' | 'expression',
382
+ overrides?: {},
431
383
  },
432
- blockOrder?: (
433
- | 'docs'
434
- | 'template'
435
- | 'script[setup]'
436
- | 'style[scoped]'
437
- | 'i18n[locale=en]'
438
- | 'script:not([setup])'
439
- | 'style:not([scoped])'
440
- | 'i18n:not([locale=en])'
441
- )[],
442
- macrosOrder?: (
443
- | 'definePage'
444
- | 'defineModel'
445
- | 'defineProps'
446
- | 'defineEmits'
447
- | 'defineSlots'
448
- | 'defineCustom'
449
- | 'defineExpose'
450
- | 'defineOptions'
451
- )[],
452
- attributesOrder?: RuleOptions<'vue/attributes-order'>['order'],
453
- attributeHyphenation?: 'never' | 'always',
454
- preferVBindSameNameShorthand?: 'never' | 'always',
455
- preferVBindTrueShorthand?: 'never' | 'always',
456
- allowedStyleAttributes?: ['module' | 'plain' | 'scoped', 'module' | 'plain' | 'scoped'],
457
- blockLang?: {
458
- style?: 'css' | 'implicit' | 'scss' | 'postcss',
459
- script?: 'js' | 'ts' | 'jsx' | 'tsx' | 'implicit',
384
+ stylistic?: boolean | {
385
+ semi?: 'always' | 'never',
386
+ trailingComma?: 'always' | 'never' | 'always-multiline' | 'only-multiline',
387
+ memberDelimiterStyle?: 'semi' | 'comma',
388
+ quotes?: 'single' | 'double' | 'backtick',
389
+ jsxQuotes?: 'prefer-single' | 'prefer-double',
390
+ arrowParens?: 'always' | 'as-needed',
391
+ indent?: number,
392
+ maxConsecutiveEmptyLines?: number,
393
+ maxLineLength?: number,
394
+ maxAttributesPerLine?: number,
395
+ selfCloseVoidHTMLElements?: 'never' | 'always',
396
+ overrides?: {},
460
397
  },
461
- destructureProps?: 'never' | 'always',
462
- componentNameCaseInTemplate?: 'PascalCase' | 'kebab-case',
463
- vForDelimiterStyle?: 'in' | 'of',
464
- vOnHandlerStyle?: 'inline' | 'inline-function' | ['method', 'inline' | 'inline-function'],
465
- restrictedElements?: (string | {
466
- element: string | string[],
467
- message: string,
468
- })[],
469
- restrictedStaticAttributes?: (string | {
470
- key: string,
471
- value?: string | true,
472
- element: string,
473
- message: string,
474
- })[],
475
- ignoredUndefinedComponents?: string[],
476
- overrides?: {},
477
- },
478
- nuxt?: boolean | {
479
- image?: boolean,
480
- icon?: boolean | {
481
- component?: string,
482
- }
483
- ui?: boolean | {
484
- prefix?: string,
485
- }
486
- },
487
- test?: {
488
- storybook?: boolean | {
398
+ html?: boolean | {
399
+ useBaseline?: number | false | 'widely' | 'newly',
400
+ idNamingConvention?: 'camelCase' | 'snake_case' | 'PascalCase' | 'kebab-case',
489
401
  overrides?: {},
490
402
  },
491
- vitest?: boolean | {
403
+ css?: boolean | {
404
+ useBaseline?: number | false | 'widely' | 'newly',
405
+ allowedRelativeFontUnits?: ('%' | 'cap' | 'ch' | 'em' | 'ex' | 'ic' | 'lh' | 'rcap' | 'rch' | 'rem' | 'rex' | 'ric' | 'rlh')[],
406
+ overrides?: {},
407
+ },
408
+ tailwind?: false | {
409
+ config: string,
410
+ entryPoint?: string,
411
+ multilineSort?: boolean,
412
+ ignoredUnregisteredClasses?: string[],
413
+ overrides?: {},
414
+ } | {
415
+ config?: string,
416
+ entryPoint: string,
417
+ multilineSort?: boolean,
418
+ ignoredUnregisteredClasses?: string[],
492
419
  overrides?: {},
493
420
  },
494
- playwright?: boolean | {
421
+ typescript?: boolean | {
422
+ allowedDefaultProjects?: string[],
423
+ methodSignatureStyle?: 'property' | 'method',
424
+ typeDefinitionStyle?: 'interface' | 'type',
495
425
  overrides?: {},
496
426
  },
497
- cypress?: boolean | {
427
+ importX?: boolean | {
428
+ removeUnusedImports?: boolean,
429
+ overrides?: {},
430
+ },
431
+ perfectionist?: boolean | {
432
+ sortType?: 'custom' | 'natural' | 'alphabetical' | 'line-length' | 'unsorted',
433
+ overrides?: {},
434
+ },
435
+ vue?: boolean | {
436
+ accessibility?: boolean | {
437
+ anchorComponents?: string[],
438
+ imageComponents?: string[],
439
+ accessibleChildComponents?: string[],
440
+ },
441
+ blockOrder?: (
442
+ | 'docs'
443
+ | 'template'
444
+ | 'script[setup]'
445
+ | 'style[scoped]'
446
+ | 'i18n[locale=en]'
447
+ | 'script:not([setup])'
448
+ | 'style:not([scoped])'
449
+ | 'i18n:not([locale=en])'
450
+ )[],
451
+ macrosOrder?: (
452
+ | 'definePage'
453
+ | 'defineModel'
454
+ | 'defineProps'
455
+ | 'defineEmits'
456
+ | 'defineSlots'
457
+ | 'defineCustom'
458
+ | 'defineExpose'
459
+ | 'defineOptions'
460
+ )[],
461
+ attributesOrder?: RuleOptions<'vue/attributes-order'>['order'],
462
+ attributeHyphenation?: 'never' | 'always',
463
+ preferVBindSameNameShorthand?: 'never' | 'always',
464
+ preferVBindTrueShorthand?: 'never' | 'always',
465
+ allowedStyleAttributes?: ['module' | 'plain' | 'scoped', 'module' | 'plain' | 'scoped'],
466
+ blockLang?: {
467
+ style?: 'css' | 'implicit' | 'scss' | 'postcss',
468
+ script?: 'js' | 'ts' | 'jsx' | 'tsx' | 'implicit',
469
+ },
470
+ destructureProps?: 'never' | 'always',
471
+ componentNameCaseInTemplate?: 'PascalCase' | 'kebab-case',
472
+ vForDelimiterStyle?: 'in' | 'of',
473
+ vOnHandlerStyle?: 'inline' | 'inline-function' | ['method', 'inline' | 'inline-function'],
474
+ restrictedElements?: (string | {
475
+ element: string | string[],
476
+ message: string,
477
+ })[],
478
+ restrictedStaticAttributes?: (string | {
479
+ key: string,
480
+ value?: string | true,
481
+ element: string,
482
+ message: string,
483
+ })[],
484
+ ignoredUndefinedComponents?: string[],
498
485
  overrides?: {},
499
486
  },
500
- testFunction?: 'test' | 'it',
501
- maxNestedDescribe?: number,
487
+ nuxt?: boolean | {
488
+ image?: boolean,
489
+ icon?: boolean | {
490
+ component?: string,
491
+ }
492
+ ui?: boolean | {
493
+ prefix?: string,
494
+ }
495
+ },
496
+ test?: {
497
+ storybook?: boolean | {
498
+ overrides?: {},
499
+ },
500
+ vitest?: boolean | {
501
+ overrides?: {},
502
+ },
503
+ playwright?: boolean | {
504
+ overrides?: {},
505
+ },
506
+ cypress?: boolean | {
507
+ overrides?: {},
508
+ },
509
+ testFunction?: 'test' | 'it',
510
+ maxNestedDescribe?: number,
511
+ },
502
512
  },
503
- },
504
- }
505
- ```
513
+ }
514
+ ```
506
515
  </details>
507
516
 
508
517
  ## Versioning Policy
@@ -521,10 +530,10 @@ You can find a list of all available versions and their changelogs on the [relea
521
530
  - [ ] Develop a starter wizard to automate the setup of OXLint, ESLint, Prettier, and other configurations.
522
531
 
523
532
  ## Contribution Guide
524
- Any form of contribution is always appreciated! Please refer to the [CONTRIBUTING.md](CONTRIBUTING.md) file.
533
+ Any form of contribution is always appreciated! Please chekc out the [CONTRIBUTING.md](CONTRIBUTING.md) file.
525
534
 
526
535
  ## Credits
527
- This project was inspired by the work of [Anthony Fu](https://github.com/antfu), whose generous contributions to the JavaScript and ESLint ecosystem were instrumental in making it possible.
536
+ This project was inspired by the work of [Anthony Fu](https://github.com/antfu), whose generous contributions to the JavaScript and the ESLint ecosystem were instrumental in making it possible.
528
537
 
529
538
  ## License
530
539
  [MIT](LICENSE) License © 2025-PRESENT — [Shayan Zamani](https://github.com/ShayanTheNerd)
@@ -1,4 +1,4 @@
1
- import { globs } from "../utils/globs.mjs";
1
+ import { globs } from "../helpers/globs.mjs";
2
2
  import { isEnabled } from "../utils/isEnabled.mjs";
3
3
  import { getJavaScriptRules } from "../rules/javascript.mjs";
4
4
  import { mergeConfigs } from "eslint-flat-config-utils";
@@ -7,7 +7,7 @@ import globals from "globals";
7
7
 
8
8
  //#region src/configs/base.ts
9
9
  function getBaseConfig(options) {
10
- const { configs: { vue, test: { vitest }, base: { overrides } }, global: { globals: { node, worker, browser, commonjs, webextension, serviceworker, custom: userGlobals } } } = options;
10
+ const { env, configs: { vue, base: { overrides } }, global: { globals: { bun, node, deno, vitest, worker, browser, commonjs, nodeBuiltin, audioWorklet, webextension, sharedWorker, serviceworker, vue: vueGlobals, custom: userGlobals } } } = options;
11
11
  return mergeConfigs({
12
12
  name: "shayanthenerd/base",
13
13
  files: isEnabled(vue) ? [globs.src, globs.vue] : [globs.src],
@@ -23,15 +23,19 @@ function getBaseConfig(options) {
23
23
  globals: {
24
24
  ...globals.builtin,
25
25
  ...globals.es2026,
26
+ ...worker && globals.worker,
26
27
  ...commonjs && globals.commonjs,
28
+ ...bun && env === "bun" && globals.bunBuiltin,
29
+ ...deno && env === "deno" && globals.denoBuiltin,
27
30
  ...node && globals.node,
28
- ...node && globals.nodeBuiltin,
29
- ...browser && globals.browser,
30
- ...worker && globals.worker,
31
- ...serviceworker && globals.serviceworker,
32
- ...webextension && globals.webextensions,
33
- ...isEnabled(vue) && globals.vue,
34
- ...isEnabled(vitest) && globals.vitest,
31
+ ...nodeBuiltin && env === "node" && globals.nodeBuiltin,
32
+ ...browser && env === "browser" && globals.browser,
33
+ ...sharedWorker && env === "browser" && globals.sharedWorker,
34
+ ...serviceworker && env === "browser" && globals.serviceworker,
35
+ ...webextension && env === "browser" && globals.webextensions,
36
+ ...audioWorklet && env === "browser" && globals.audioWorklet,
37
+ ...vitest && globals.vitest,
38
+ ...vueGlobals && isEnabled(vue) && globals.vue,
35
39
  ...userGlobals
36
40
  }
37
41
  },
@@ -1,6 +1,6 @@
1
- import { globs } from "../utils/globs.mjs";
1
+ import { globs } from "../helpers/globs.mjs";
2
2
  import { isEnabled } from "../utils/isEnabled.mjs";
3
- import { defaultOptions } from "../utils/options/defaultOptions.mjs";
3
+ import { defaultOptions } from "../helpers/options/defaultOptions.mjs";
4
4
  import { getCSSRules } from "../rules/css.mjs";
5
5
  import eslintPluginCSS from "@eslint/css";
6
6
  import { mergeConfigs } from "eslint-flat-config-utils";
@@ -1,6 +1,6 @@
1
- import { globs } from "../utils/globs.mjs";
1
+ import { globs } from "../helpers/globs.mjs";
2
2
  import { isEnabled } from "../utils/isEnabled.mjs";
3
- import { defaultOptions } from "../utils/options/defaultOptions.mjs";
3
+ import { defaultOptions } from "../helpers/options/defaultOptions.mjs";
4
4
  import { getCypressRules } from "../rules/cypress.mjs";
5
5
  import { mergeConfigs } from "eslint-flat-config-utils";
6
6
  import eslintPluginCypress from "eslint-plugin-cypress";
@@ -1,6 +1,6 @@
1
- import { globs } from "../utils/globs.mjs";
1
+ import { globs } from "../helpers/globs.mjs";
2
2
  import { isEnabled } from "../utils/isEnabled.mjs";
3
- import { defaultOptions } from "../utils/options/defaultOptions.mjs";
3
+ import { defaultOptions } from "../helpers/options/defaultOptions.mjs";
4
4
  import { getHTMLRules } from "../rules/html.mjs";
5
5
  import { mergeConfigs } from "eslint-flat-config-utils";
6
6
  import eslintPluginHTML from "@html-eslint/eslint-plugin";
@@ -1,6 +1,6 @@
1
- import { globs } from "../utils/globs.mjs";
1
+ import { globs } from "../helpers/globs.mjs";
2
2
  import { isEnabled } from "../utils/isEnabled.mjs";
3
- import { defaultOptions } from "../utils/options/defaultOptions.mjs";
3
+ import { defaultOptions } from "../helpers/options/defaultOptions.mjs";
4
4
  import { getImportXRules } from "../rules/importX.mjs";
5
5
  import { mergeConfigs } from "eslint-flat-config-utils";
6
6
  import eslintPluginImportX from "eslint-plugin-import-x";
@@ -1,21 +1,26 @@
1
- import { globs } from "../utils/globs.mjs";
1
+ import { globs } from "../helpers/globs.mjs";
2
2
  import { isEnabled } from "../utils/isEnabled.mjs";
3
- import { getJavaScriptRules } from "../rules/javascript.mjs";
4
- import { getVitestRules } from "../rules/vitest.mjs";
5
- import { getPlaywrightRules } from "../rules/playwright.mjs";
6
- import { getTypeScriptRules } from "../rules/typescript.mjs";
3
+ import { getVueConfig } from "./vue.mjs";
4
+ import { getBaseConfig } from "./base.mjs";
5
+ import { getVitestConfig } from "./vitest.mjs";
6
+ import { getPlaywrightConfig } from "./playwright.mjs";
7
+ import { getTypeScriptConfig } from "./typescript.mjs";
7
8
  import typescriptESLint from "typescript-eslint";
8
9
  import eslintPluginVitest from "@vitest/eslint-plugin";
9
10
  import eslintPluginImportX from "eslint-plugin-import-x";
10
11
  import eslintPluginPlaywright from "eslint-plugin-playwright";
11
12
 
12
13
  //#region src/configs/oxlintOverrides.ts
14
+ /**
15
+ * Prevent OXLint from overriding rules that are customizable via the configuration options.
16
+ */
13
17
  function getOXLintOverridesConfig(options) {
14
18
  const { vue, importX, typescript, test: { vitest, playwright } } = options.configs;
15
- const vitestRules = getVitestRules(options);
16
- const javascriptRules = getJavaScriptRules(options);
17
- const typescriptRules = getTypeScriptRules(options);
18
- const playwrightRules = getPlaywrightRules(options);
19
+ const vueRules = getVueConfig(options).rules;
20
+ const vitestRules = getVitestConfig(options).rules;
21
+ const javascriptRules = getBaseConfig(options).rules;
22
+ const typescriptRules = getTypeScriptConfig(options).rules;
23
+ const playwrightRules = getPlaywrightConfig(options).rules;
19
24
  return {
20
25
  name: "shayanthenerd/oxlint/overrides",
21
26
  files: [
@@ -33,11 +38,11 @@ function getOXLintOverridesConfig(options) {
33
38
  "max-depth": javascriptRules["max-depth"],
34
39
  "func-style": javascriptRules["func-style"],
35
40
  "max-nested-callbacks": javascriptRules["max-nested-callbacks"],
36
- "@typescript-eslint/explicit-module-boundary-types": typescriptRules["@typescript-eslint/explicit-module-boundary-types"],
37
41
  "@typescript-eslint/consistent-type-definitions": isEnabled(typescript) ? typescriptRules["@typescript-eslint/consistent-type-definitions"] : "off",
38
42
  "playwright/max-nested-describe": isEnabled(playwright) ? playwrightRules["playwright/max-nested-describe"] : "off",
39
43
  "vitest/consistent-test-it": isEnabled(vitest) ? vitestRules["vitest/consistent-test-it"] : "off",
40
- "vitest/max-nested-describe": isEnabled(vitest) ? vitestRules["vitest/max-nested-describe"] : "off"
44
+ "vitest/max-nested-describe": isEnabled(vitest) ? vitestRules["vitest/max-nested-describe"] : "off",
45
+ "vue/define-props-destructuring": isEnabled(vue) ? vueRules["vue/define-props-destructuring"] : "off"
41
46
  }
42
47
  };
43
48
  }
@@ -1,6 +1,6 @@
1
- import { globs } from "../utils/globs.mjs";
1
+ import { globs } from "../helpers/globs.mjs";
2
2
  import { isEnabled } from "../utils/isEnabled.mjs";
3
- import { defaultOptions } from "../utils/options/defaultOptions.mjs";
3
+ import { defaultOptions } from "../helpers/options/defaultOptions.mjs";
4
4
  import { getPerfectionistRules } from "../rules/perfectionist.mjs";
5
5
  import { mergeConfigs } from "eslint-flat-config-utils";
6
6
  import eslintPluginPerfectionist from "eslint-plugin-perfectionist";
@@ -1,6 +1,6 @@
1
- import { globs } from "../utils/globs.mjs";
1
+ import { globs } from "../helpers/globs.mjs";
2
2
  import { isEnabled } from "../utils/isEnabled.mjs";
3
- import { defaultOptions } from "../utils/options/defaultOptions.mjs";
3
+ import { defaultOptions } from "../helpers/options/defaultOptions.mjs";
4
4
  import { getPlaywrightRules } from "../rules/playwright.mjs";
5
5
  import { mergeConfigs } from "eslint-flat-config-utils";
6
6
  import eslintPluginPlaywright from "eslint-plugin-playwright";
@@ -1,4 +1,4 @@
1
- import { globs } from "../utils/globs.mjs";
1
+ import { globs } from "../helpers/globs.mjs";
2
2
 
3
3
  //#region src/configs/restrictedExports.ts
4
4
  function getRestrictedExports() {
@@ -1,6 +1,6 @@
1
- import { globs } from "../utils/globs.mjs";
1
+ import { globs } from "../helpers/globs.mjs";
2
2
  import { isEnabled } from "../utils/isEnabled.mjs";
3
- import { defaultOptions } from "../utils/options/defaultOptions.mjs";
3
+ import { defaultOptions } from "../helpers/options/defaultOptions.mjs";
4
4
  import { getStorybookRules } from "../rules/storybook.mjs";
5
5
  import { mergeConfigs } from "eslint-flat-config-utils";
6
6
  import eslintPluginStorybook from "eslint-plugin-storybook";
@@ -1,6 +1,6 @@
1
- import { globs } from "../utils/globs.mjs";
1
+ import { globs } from "../helpers/globs.mjs";
2
2
  import { isEnabled } from "../utils/isEnabled.mjs";
3
- import { defaultOptions } from "../utils/options/defaultOptions.mjs";
3
+ import { defaultOptions } from "../helpers/options/defaultOptions.mjs";
4
4
  import { getStylisticRules } from "../rules/stylistic.mjs";
5
5
  import { mergeConfigs } from "eslint-flat-config-utils";
6
6
  import eslintPluginStylistic from "@stylistic/eslint-plugin";