@fullstacksjs/eslint-config 14.8.1 → 15.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.
Files changed (55) hide show
  1. package/README.md +1 -20
  2. package/dist/index.mjs +1894 -0
  3. package/package.json +44 -46
  4. package/src/index.mjs +5 -5
  5. package/src/modules/base.mjs +10 -2
  6. package/src/modules/cypress.mjs +1 -0
  7. package/src/modules/imports.mjs +1 -0
  8. package/src/modules/jest.mjs +1 -0
  9. package/src/modules/next.mjs +1 -0
  10. package/src/modules/node.mjs +3 -0
  11. package/src/modules/perfectionist.mjs +1 -0
  12. package/src/modules/playwright.mjs +1 -0
  13. package/src/modules/prettier.mjs +1 -0
  14. package/src/modules/promise.mjs +1 -0
  15. package/src/modules/react.mjs +2 -0
  16. package/src/modules/regex.mjs +1 -0
  17. package/src/modules/storybook.mjs +1 -0
  18. package/src/modules/stylistic.mjs +1 -0
  19. package/src/modules/tailwind.mjs +1 -0
  20. package/src/modules/tests.mjs +4 -1
  21. package/src/modules/typescript.mjs +22 -4
  22. package/src/modules/vitest.mjs +1 -0
  23. package/src/utils/nextAllowExportNames.mjs +7 -0
  24. package/cjs/index.js +0 -137
  25. package/cjs/modules/base.js +0 -235
  26. package/cjs/modules/cypress.js +0 -39
  27. package/cjs/modules/ignore.js +0 -26
  28. package/cjs/modules/imports.js +0 -124
  29. package/cjs/modules/jest.js +0 -102
  30. package/cjs/modules/next.js +0 -48
  31. package/cjs/modules/node.js +0 -76
  32. package/cjs/modules/perfectionist.js +0 -54
  33. package/cjs/modules/playwright.js +0 -89
  34. package/cjs/modules/prettier.js +0 -97
  35. package/cjs/modules/promise.js +0 -45
  36. package/cjs/modules/react.js +0 -190
  37. package/cjs/modules/regex.js +0 -122
  38. package/cjs/modules/storybook.js +0 -49
  39. package/cjs/modules/stylistic.js +0 -94
  40. package/cjs/modules/tailwind.js +0 -56
  41. package/cjs/modules/tests.js +0 -52
  42. package/cjs/modules/typescript.js +0 -277
  43. package/cjs/modules/vitest.js +0 -116
  44. package/cjs/types/index.d.ts +0 -143
  45. package/cjs/types/modules/import.d.ts +0 -7
  46. package/cjs/types/modules/react.d.ts +0 -10
  47. package/cjs/types/modules/regex.d.ts +0 -5
  48. package/cjs/types/modules/tailwind.d.ts +0 -13
  49. package/cjs/types/modules/typescript.d.ts +0 -38
  50. package/cjs/utils/conditions.js +0 -25
  51. package/cjs/utils/getGitignorePatterns.js +0 -35
  52. package/cjs/utils/globs.js +0 -37
  53. package/cjs/utils/naming-convention.js +0 -63
  54. package/cjs/utils/nextAllowExportNames.js +0 -7
  55. package/cjs/utils/objectOrEmpty.js +0 -14
package/dist/index.mjs ADDED
@@ -0,0 +1,1894 @@
1
+ import merge from "deepmerge";
2
+ import { defineConfig as defineConfig$1, globalIgnores } from "eslint/config";
3
+ import { isPackageExists } from "local-pkg";
4
+ import { mergeConfigs } from "eslint-flat-config-utils";
5
+ import globals from "globals";
6
+ import plugin from "eslint-plugin-cypress";
7
+ import { includeIgnoreFile } from "@eslint/compat";
8
+ import fs from "node:fs";
9
+ import path from "node:path";
10
+ import plugin$1 from "eslint-plugin-import-x";
11
+ import plugin$2 from "eslint-plugin-jest";
12
+ import plugin$3 from "@next/eslint-plugin-next";
13
+ import plugin$4 from "eslint-plugin-n";
14
+ import plugin$5 from "eslint-plugin-perfectionist";
15
+ import plugin$6 from "eslint-plugin-playwright";
16
+ import plugin$7 from "eslint-plugin-prettier";
17
+ import plugin$8 from "eslint-plugin-promise";
18
+ import reactPlugin from "@eslint-react/eslint-plugin";
19
+ import a11yPlugin from "eslint-plugin-jsx-a11y";
20
+ import { reactRefresh } from "eslint-plugin-react-refresh";
21
+ import { parser, plugin as plugin$9 } from "typescript-eslint";
22
+ import * as plugin$12 from "eslint-plugin-regexp";
23
+ import plugin$10 from "eslint-plugin-storybook";
24
+ import stylisticPlugin from "@stylistic/eslint-plugin";
25
+ import plugin$11 from "@vitest/eslint-plugin";
26
+ //#region src/utils/conditions.mjs
27
+ /**
28
+ * @param {{strict?: boolean}} options
29
+ * @param {import('eslint').Linter.RuleEntry} config
30
+ * @returns {import('eslint').Linter.RuleEntry}
31
+ */
32
+ const strict = (options, config) => {
33
+ return options.strict ? config : "off";
34
+ };
35
+ /**
36
+ * @param {boolean} options
37
+ * @param {import('eslint').Linter.RulesRecord} config
38
+ * @returns {import('eslint').Linter.RulesRecord | undefined}
39
+ */
40
+ const predicate = (condition, config) => {
41
+ return condition ? config : void 0;
42
+ };
43
+ //#endregion
44
+ //#region src/utils/objectOrEmpty.mjs
45
+ /**
46
+ * @template T
47
+ * @param {T | null | undefined} value
48
+ * @returns {T | {}}
49
+ */
50
+ function objectOrEmpty(value) {
51
+ return typeof value === "object" && value !== null ? value : {};
52
+ }
53
+ //#endregion
54
+ //#region src/modules/base.mjs
55
+ /**
56
+ * @param { import('../types').Options } options
57
+ * @return { import('eslint').Linter.Config }
58
+ */
59
+ function base(options = {}) {
60
+ const overrides = objectOrEmpty(options.base.overrides);
61
+ /**
62
+ * @type { import('eslint/config').ConfigObject }
63
+ */
64
+ const baseConfig = {
65
+ name: "base",
66
+ languageOptions: {
67
+ ecmaVersion: "latest",
68
+ sourceType: "module",
69
+ globals: {
70
+ ...globals.browser,
71
+ ...globals.node,
72
+ ...globals.es2025
73
+ },
74
+ parserOptions: {
75
+ ecmaVersion: "latest",
76
+ ecmaFeatures: { jsx: true }
77
+ }
78
+ },
79
+ rules: {
80
+ "accessor-pairs": "error",
81
+ "array-callback-return": "error",
82
+ "block-scoped-var": "error",
83
+ "camelcase": ["warn", { properties: "always" }],
84
+ "complexity": ["error", 14],
85
+ "constructor-super": "error",
86
+ "default-case-last": "error",
87
+ "default-case": "error",
88
+ "default-param-last": "warn",
89
+ "dot-notation": "error",
90
+ "eqeqeq": ["error", "smart"],
91
+ "for-direction": "error",
92
+ "func-name-matching": "error",
93
+ "func-names": "error",
94
+ "getter-return": ["error", { allowImplicit: true }],
95
+ "guard-for-in": "error",
96
+ "max-depth": ["error", 4],
97
+ "max-lines-per-function": ["error", 150],
98
+ "max-lines": ["error", {
99
+ max: 2500,
100
+ skipBlankLines: false,
101
+ skipComments: false
102
+ }],
103
+ "max-nested-callbacks": ["error", 7],
104
+ "max-params": ["error", 3],
105
+ "max-statements": ["error", 40],
106
+ "no-alert": "error",
107
+ "no-array-constructor": "error",
108
+ "no-await-in-loop": "error",
109
+ "no-bitwise": "error",
110
+ "no-caller": "error",
111
+ "no-case-declarations": "error",
112
+ "no-class-assign": "error",
113
+ "no-compare-neg-zero": "error",
114
+ "no-cond-assign": "error",
115
+ "no-const-assign": "error",
116
+ "no-constant-binary-expression": "warn",
117
+ "no-constant-condition": "error",
118
+ "no-constructor-return": "error",
119
+ "no-control-regex": "error",
120
+ "no-debugger": "error",
121
+ "no-delete-var": "error",
122
+ "no-div-regex": "error",
123
+ "no-dupe-args": "error",
124
+ "no-dupe-class-members": "error",
125
+ "no-dupe-else-if": "error",
126
+ "no-dupe-keys": "error",
127
+ "no-duplicate-case": "error",
128
+ "no-duplicate-imports": "error",
129
+ "no-empty-character-class": "error",
130
+ "no-empty-function": "warn",
131
+ "no-empty-pattern": "error",
132
+ "no-empty-static-block": "warn",
133
+ "no-empty": "error",
134
+ "no-eval": "error",
135
+ "no-ex-assign": "error",
136
+ "no-extend-native": "error",
137
+ "no-extra-bind": "error",
138
+ "no-extra-label": "error",
139
+ "no-fallthrough": ["error", { allowEmptyCase: true }],
140
+ "no-func-assign": "error",
141
+ "no-global-assign": "error",
142
+ "no-implicit-globals": "error",
143
+ "no-implied-eval": "error",
144
+ "no-import-assign": "error",
145
+ "no-inner-declarations": "error",
146
+ "no-invalid-regexp": "error",
147
+ "no-invalid-this": "warn",
148
+ "no-irregular-whitespace": "error",
149
+ "no-iterator": "error",
150
+ "no-label-var": "error",
151
+ "no-labels": "error",
152
+ "no-lone-blocks": "error",
153
+ "no-lonely-if": "error",
154
+ "no-loop-func": "error",
155
+ "no-loss-of-precision": "warn",
156
+ "no-misleading-character-class": ["error", { allowEscape: true }],
157
+ "no-multi-assign": "error",
158
+ "no-multi-str": "error",
159
+ "no-new-func": "error",
160
+ "no-new-native-nonconstructor": "error",
161
+ "no-new-wrappers": "error",
162
+ "no-new": "error",
163
+ "no-nonoctal-decimal-escape": "error",
164
+ "no-obj-calls": "error",
165
+ "no-object-constructor": "error",
166
+ "no-octal-escape": "error",
167
+ "no-octal": "error",
168
+ "no-promise-executor-return": "error",
169
+ "no-proto": "error",
170
+ "no-redeclare": "error",
171
+ "no-regex-spaces": "error",
172
+ "no-restricted-globals": ["error", {
173
+ name: "event",
174
+ message: "Use local parameter instead."
175
+ }],
176
+ "no-restricted-syntax": ["error", "WithStatement"],
177
+ "no-return-assign": "error",
178
+ "no-script-url": "error",
179
+ "no-self-assign": "error",
180
+ "no-self-compare": "error",
181
+ "no-sequences": "error",
182
+ "no-setter-return": "error",
183
+ "no-shadow-restricted-names": "error",
184
+ "no-shadow": "error",
185
+ "no-sparse-arrays": "error",
186
+ "no-this-before-super": "error",
187
+ "no-throw-literal": "error",
188
+ "no-undef-init": "error",
189
+ "no-undef": "error",
190
+ "no-unexpected-multiline": "error",
191
+ "no-unmodified-loop-condition": "error",
192
+ "no-unneeded-ternary": "error",
193
+ "no-unreachable-loop": "error",
194
+ "no-unreachable": "error",
195
+ "no-unsafe-finally": "error",
196
+ "no-unsafe-negation": "error",
197
+ "no-unsafe-optional-chaining": "error",
198
+ "no-unused-labels": "error",
199
+ "no-unused-private-class-members": "warn",
200
+ "no-unused-vars": ["error", {
201
+ argsIgnorePattern: "^_",
202
+ varsIgnorePattern: "^ignore(d)?",
203
+ args: "after-used",
204
+ ignoreRestSiblings: true
205
+ }],
206
+ "no-use-before-define": ["error", "nofunc"],
207
+ "no-useless-assignment": "warn",
208
+ "no-useless-backreference": "error",
209
+ "no-useless-call": "error",
210
+ "no-useless-catch": "error",
211
+ "no-useless-computed-key": "error",
212
+ "no-useless-concat": "error",
213
+ "no-useless-constructor": "error",
214
+ "no-useless-escape": "error",
215
+ "no-useless-rename": "error",
216
+ "no-useless-return": "error",
217
+ "no-var": "warn",
218
+ "no-warning-comments": ["warn", {
219
+ terms: ["fixme"],
220
+ location: "anywhere"
221
+ }],
222
+ "object-shorthand": ["error", "properties"],
223
+ "one-var": ["error", {
224
+ uninitialized: "never",
225
+ initialized: "never"
226
+ }],
227
+ "prefer-arrow-callback": ["warn", {
228
+ allowNamedFunctions: true,
229
+ allowUnboundThis: true
230
+ }],
231
+ "prefer-const": "warn",
232
+ "preserve-caught-error": strict(options, ["warn", { requireCatchParameter: true }]),
233
+ "prefer-destructuring": ["warn", {
234
+ object: true,
235
+ array: false
236
+ }],
237
+ "prefer-exponentiation-operator": "warn",
238
+ "prefer-numeric-literals": "error",
239
+ "prefer-object-has-own": "warn",
240
+ "prefer-rest-params": "error",
241
+ "prefer-spread": "error",
242
+ "prefer-template": "error",
243
+ "prefer-promise-reject-errors": "warn",
244
+ "radix": "error",
245
+ "require-await": "error",
246
+ "require-yield": "error",
247
+ "strict": "error",
248
+ "symbol-description": "error",
249
+ "use-isnan": "error",
250
+ "valid-typeof": "error",
251
+ "vars-on-top": "error",
252
+ "yoda": "error",
253
+ "require-atomic-updates": "warn",
254
+ "no-async-promise-executor": "warn",
255
+ "grouped-accessor-pairs": "warn",
256
+ "no-extra-boolean-cast": "warn",
257
+ "no-param-reassign": "warn",
258
+ "no-plusplus": ["warn", { allowForLoopAfterthoughts: true }],
259
+ "prefer-regex-literals": ["warn", { disallowRedundantWrapping: true }],
260
+ "no-console": strict(options, "warn")
261
+ }
262
+ };
263
+ return mergeConfigs(baseConfig, overrides);
264
+ }
265
+ //#endregion
266
+ //#region src/utils/globs.mjs
267
+ const srcExt = "?([cm])[jt]s?(x)";
268
+ const globs = {
269
+ src: `**/*.${srcExt}`,
270
+ js: "**/*.?([cm])js",
271
+ jsx: "**/*.?([cm])jsx",
272
+ ts: "**/*.?([cm])ts",
273
+ tsx: "**/*.?([cm])tsx",
274
+ style: "**/*.{css,less,scss}",
275
+ css: "**/*.css",
276
+ postcss: "**/*.postcss",
277
+ less: "**/*.less",
278
+ scss: "**/*.scss",
279
+ json: "**/*.json",
280
+ json5: "**/*.json5",
281
+ jsonc: "**/*.jsonc",
282
+ allJson: "**/*.json?([c5])",
283
+ md: "**/*.md",
284
+ svelte: "**/*.svelte",
285
+ vue: "**/*.vue",
286
+ yaml: "**/*.{yml,yaml}",
287
+ toml: "**/*.toml",
288
+ xml: "**/*.xml",
289
+ html: "**/*.html",
290
+ astro: "**/*.astro",
291
+ graphql: "**/*.{gql,graphql}",
292
+ storybook: ["**/*.stories.{js,mjs,cjs,jsx,ts,tsx}"],
293
+ test: [
294
+ `**/__tests__/*.${srcExt}`,
295
+ `**/*.spec.${srcExt}`,
296
+ `**/*.test.${srcExt}`
297
+ ],
298
+ e2e: [`**/e2e/*.${srcExt}`]
299
+ };
300
+ globs.src, globs.style, globs.allJson, globs.md, globs.svelte, globs.vue, globs.yaml, globs.xml, globs.html;
301
+ const ignoreGlobs = [
302
+ "**/node_modules",
303
+ "**/dist",
304
+ "**/package-lock.json",
305
+ "**/yarn.lock",
306
+ "**/pnpm-lock.yaml",
307
+ "**/bun.lockb",
308
+ "**/output",
309
+ "**/coverage",
310
+ "**/temp",
311
+ "**/.temp",
312
+ "**/tmp",
313
+ "**/.tmp",
314
+ "**/.nx",
315
+ "**/.history",
316
+ "**/.vitepress/cache",
317
+ "**/.nuxt",
318
+ "**/.next",
319
+ "**/.vercel",
320
+ "**/.changeset",
321
+ "**/.idea",
322
+ "**/.cache",
323
+ "**/.output",
324
+ "**/.vite-inspect",
325
+ "**/.yarn",
326
+ "**/LICENSE*",
327
+ "**/*.min.*",
328
+ "**/__snapshots__"
329
+ ];
330
+ //#endregion
331
+ //#region src/modules/cypress.mjs
332
+ /**
333
+ * @param { import('../types').Options } options
334
+ * @return { import('eslint').Linter.Config }
335
+ */
336
+ function cypress(options = {}) {
337
+ const overrides = objectOrEmpty(options.cypress.overrides);
338
+ /** @type { import('eslint/config').ConfigObject } */
339
+ const cypressConfig = {
340
+ name: "cypress",
341
+ files: globs.e2e,
342
+ plugins: { cypress: plugin },
343
+ rules: {
344
+ "cypress/assertion-before-screenshot": "warn",
345
+ "cypress/no-assigning-return-values": "error",
346
+ "cypress/no-async-tests": "error",
347
+ "cypress/no-force": "warn",
348
+ "cypress/no-pause": "error",
349
+ "cypress/no-unnecessary-waiting": "error",
350
+ "cypress/require-data-selectors": "off",
351
+ "cypress/unsafe-to-chain-command": "error",
352
+ "cypress/no-chained-get": "error",
353
+ "@typescript-eslint/no-namespace": "off"
354
+ }
355
+ };
356
+ return mergeConfigs(cypressConfig, overrides);
357
+ }
358
+ //#endregion
359
+ //#region src/utils/getGitignorePatterns.mjs
360
+ const warningMessage = "\x1B[38;2;229;229;14mWarning:\x1B[0m";
361
+ const fallbackMessage = "Falling back to default ignore patterns. You can suppress this warning by setting \x1B[48;5;234m`gitignore: false`\x1B[0m in the config.";
362
+ /**
363
+ * @param {string} gitignorePath relative path to the .gitignore file
364
+ * @returns {string[]}
365
+ */
366
+ function getGitignorePatterns(gitignorePath) {
367
+ const gitignoreAbsolutePath = path.resolve(process.cwd(), gitignorePath);
368
+ const gitignoreExists = fs.existsSync(gitignoreAbsolutePath);
369
+ const gitignorePatterns = [];
370
+ if (!gitignoreExists) {
371
+ console.warn(warningMessage, `No .gitignore file found at "${gitignoreAbsolutePath}".`, fallbackMessage);
372
+ return gitignorePatterns;
373
+ }
374
+ const ignorePatterns = includeIgnoreFile(gitignoreAbsolutePath).ignores ?? [];
375
+ if (ignorePatterns.length > 0) gitignorePatterns.push(...ignorePatterns);
376
+ else console.warn(warningMessage, `No patterns found in .gitignore file at "${gitignoreAbsolutePath}".`, fallbackMessage);
377
+ return gitignorePatterns;
378
+ }
379
+ //#endregion
380
+ //#region src/modules/ignore.mjs
381
+ /**
382
+ * @param { import('../types').Options } options
383
+ * @return { import('eslint').Linter.Config }
384
+ */
385
+ function ignores(options = {}) {
386
+ const ignorePatterns = [...ignoreGlobs, ...options.ignores ?? []];
387
+ if (options.gitignore && options.gitignore.length > 0) {
388
+ const gitignorePatterns = getGitignorePatterns(options.gitignore);
389
+ if (gitignorePatterns.length > 0) ignorePatterns.push(...gitignorePatterns);
390
+ }
391
+ const uniqueIgnorePatterns = [...new Set(ignorePatterns)];
392
+ return globalIgnores(uniqueIgnorePatterns, "ignores");
393
+ }
394
+ //#endregion
395
+ //#region src/modules/imports.mjs
396
+ const tsExtensions = [
397
+ ".ts",
398
+ ".tsx",
399
+ ".cts",
400
+ ".mts",
401
+ ".ctsx",
402
+ ".mtsx"
403
+ ];
404
+ const jsExtensions = [
405
+ ".mjs",
406
+ ".js",
407
+ ".jsx",
408
+ ".cjs"
409
+ ];
410
+ const allExtensions = [...jsExtensions, ...tsExtensions];
411
+ /**
412
+ * @param { import('../types').Options } options
413
+ * @return { import('eslint').Linter.Config }
414
+ */
415
+ function imports(options = {}) {
416
+ const isObject = typeof options.import === "object";
417
+ const overrides = objectOrEmpty(options.import.overrides);
418
+ /** @type { import('eslint/config').ConfigObject } */
419
+ const importsConfig = {
420
+ name: "imports",
421
+ plugins: { import: plugin$1 },
422
+ settings: {
423
+ "import-x/extensions": jsExtensions,
424
+ "import-x/ignore": ["node_modules", "\\.(scss|css|svg|json|mdx)$"],
425
+ ...predicate(options.typescript, {
426
+ "import-x/parsers": { "@typescript-eslint/parser": tsExtensions },
427
+ "import-x/extensions": allExtensions
428
+ }),
429
+ ...predicate(isObject && "internalRegExp" in options.import, { "import-x/internal-regex": options.import.internalRegExp }),
430
+ ...predicate(isObject && "lifetime" in options.import, { "import-x/cache": { lifetime: options.import.lifetime } })
431
+ },
432
+ rules: {
433
+ "import/consistent-type-specifier-style": ["warn", "prefer-top-level"],
434
+ "import/first": "error",
435
+ "import/newline-after-import": "warn",
436
+ "import/no-absolute-path": "error",
437
+ "import/no-amd": "error",
438
+ "import/no-duplicates": "error",
439
+ "import/no-empty-named-blocks": "error",
440
+ "import/no-extraneous-dependencies": ["error", { devDependencies: true }],
441
+ "import/no-mutable-exports": "error",
442
+ "import/no-named-as-default": "error",
443
+ "import/no-named-default": "error",
444
+ "import/no-relative-packages": "error",
445
+ "import/no-self-import": "error",
446
+ "import/no-unresolved": ["error", { caseSensitiveStrict: true }],
447
+ "import/no-useless-path-segments": "warn",
448
+ "import/no-webpack-loader-syntax": "error",
449
+ "import/order": "off",
450
+ ...predicate(!options.disableExpensiveRules, {
451
+ "import/default": "error",
452
+ "import/export": "error",
453
+ "import/named": "error",
454
+ "import/namespace": "error",
455
+ "import/no-cycle": ["error", { maxDepth: Infinity }],
456
+ "import/no-deprecated": "warn",
457
+ "import/no-named-as-default-member": "error"
458
+ }),
459
+ "import/dynamic-import-chunkname": "off",
460
+ "import/exports-last": "off",
461
+ "import/group-exports": "off",
462
+ "import/max-dependencies": "off",
463
+ "import/no-anonymous-default-export": "off",
464
+ "import/no-commonjs": "off",
465
+ "import/no-default-export": "off",
466
+ "import/no-dynamic-require": "off",
467
+ "import/no-import-module-exports": "off",
468
+ "import/no-internal-modules": "off",
469
+ "import/no-named-export": "off",
470
+ "import/no-namespace": "off",
471
+ "import/no-nodejs-modules": "off",
472
+ "import/no-relative-parent-imports": "off",
473
+ "import/no-restricted-paths": "off",
474
+ "import/no-unassigned-import": "off",
475
+ "import/no-unused-modules": "off",
476
+ "import/prefer-default-export": "off",
477
+ "import/unambiguous": "off",
478
+ ...predicate(options.typescript, {
479
+ "import/default": "off",
480
+ "import/named": "off",
481
+ "import/no-named-as-default-member": "off",
482
+ "import/no-unresolved": "off"
483
+ })
484
+ }
485
+ };
486
+ return mergeConfigs(importsConfig, overrides);
487
+ }
488
+ //#endregion
489
+ //#region src/modules/jest.mjs
490
+ /**
491
+ * @param { import('../types').Options } options
492
+ * @return { import('eslint').Linter.Config } */
493
+ function jest(options = {}) {
494
+ const projectService = options.typescript && options.typescript.tsconfigRootDir && options.typescript.projectService;
495
+ const overrides = objectOrEmpty(options.jest.overrides);
496
+ /** @type { import('eslint/config').ConfigObject } */
497
+ const jestConfig = {
498
+ name: "jest",
499
+ files: globs.test,
500
+ plugins: { jest: plugin$2 },
501
+ languageOptions: { globals: { ...globals.jest } },
502
+ rules: {
503
+ "jest/consistent-test-it": "off",
504
+ "jest/expect-expect": "off",
505
+ "jest/lowercase-name": "off",
506
+ "jest/max-nested-describe": ["error", { max: 2 }],
507
+ "jest/no-alias-methods": "error",
508
+ "jest/no-commented-out-tests": "warn",
509
+ "jest/no-conditional-expect": "error",
510
+ "jest/no-conditional-in-test": "error",
511
+ "jest/no-confusing-set-timeout": "warn",
512
+ "jest/no-done-callback": "warn",
513
+ "jest/no-expect-resolves": "off",
514
+ "jest/no-export": "error",
515
+ ...predicate(projectService, {
516
+ "jest/no-error-equal": "error",
517
+ "jest/no-unnecessary-assertion": "warn"
518
+ }),
519
+ "jest/no-hooks": "off",
520
+ "jest/no-interpolation-in-snapshots": "error",
521
+ "jest/no-jasmine-globals": "off",
522
+ "jest/no-large-snapshots": ["warn", { maxSize: 300 }],
523
+ "jest/no-mocks-import": "error",
524
+ "jest/no-restricted-jest-methods": "off",
525
+ "jest/no-restricted-matchers": "error",
526
+ "jest/no-standalone-expect": "off",
527
+ "jest/no-test-callback": "off",
528
+ "jest/no-test-prefixes": "error",
529
+ "jest/no-test-return-statement": "off",
530
+ "jest/no-unneeded-async-expect-function": "warn",
531
+ "jest/no-truthy-falsy": "off",
532
+ "jest/prefer-called-with": "error",
533
+ "jest/prefer-each": "warn",
534
+ "jest/prefer-expect-assertions": "off",
535
+ "jest/prefer-expect-resolves": "warn",
536
+ "jest/prefer-hooks-on-top": "error",
537
+ "jest/prefer-inline-snapshots": "off",
538
+ "jest/prefer-lowercase-title": "off",
539
+ "jest/prefer-mock-promise-shorthand": "warn",
540
+ "jest/prefer-mock-return-shorthand": "warn",
541
+ "jest/prefer-snapshot-hint": "warn",
542
+ "jest/prefer-spy-on": "off",
543
+ "jest/prefer-strict-equal": "off",
544
+ "jest/prefer-to-be-null": "off",
545
+ "jest/prefer-to-be-undefined": "off",
546
+ "jest/prefer-to-be": "warn",
547
+ "jest/prefer-to-contain": "warn",
548
+ "jest/prefer-to-have-length": "warn",
549
+ "jest/prefer-todo": "warn",
550
+ "jest/require-hook": "off",
551
+ "jest/require-to-throw-message": "off",
552
+ "jest/require-top-level-describe": "off",
553
+ "jest/valid-describe-callback": "error",
554
+ "jest/valid-expect-in-promise": "error",
555
+ "jest/valid-expect": "error",
556
+ "jest/valid-title": "warn",
557
+ "jest/no-deprecated-functions": "error",
558
+ "jest/valid-mock-module-path": "warn"
559
+ }
560
+ };
561
+ return mergeConfigs(jestConfig, overrides);
562
+ }
563
+ //#endregion
564
+ //#region src/modules/next.mjs
565
+ /**
566
+ * @param { import('../types').Options } options
567
+ * @return { import('eslint').Linter.Config }
568
+ */
569
+ function next(options = {}) {
570
+ const overrides = objectOrEmpty(options.next.overrides);
571
+ return mergeConfigs({
572
+ name: "next",
573
+ plugins: { next: plugin$3 },
574
+ rules: {
575
+ "next/google-font-display": "warn",
576
+ "next/google-font-preconnect": "warn",
577
+ "next/inline-script-id": "warn",
578
+ "next/next-script-for-ga": "warn",
579
+ "next/no-assign-module-variable": "warn",
580
+ "next/no-async-client-component": "warn",
581
+ "next/no-before-interactive-script-outside-document": "warn",
582
+ "next/no-css-tags": "warn",
583
+ "next/no-document-import-in-page": "warn",
584
+ "next/no-duplicate-head": "warn",
585
+ "next/no-head-element": "warn",
586
+ "next/no-head-import-in-document": "warn",
587
+ "next/no-html-link-for-pages": "warn",
588
+ "next/no-img-element": "warn",
589
+ "next/no-page-custom-font": "warn",
590
+ "next/no-script-component-in-head": "warn",
591
+ "next/no-styled-jsx-in-document": "warn",
592
+ "next/no-sync-scripts": "warn",
593
+ "next/no-title-in-document-head": "warn",
594
+ "next/no-typos": "warn",
595
+ "next/no-unwanted-polyfillio": "warn"
596
+ }
597
+ }, overrides);
598
+ }
599
+ //#endregion
600
+ //#region src/modules/node.mjs
601
+ /**
602
+ * @param { import('../types').Options } options
603
+ * @return { import('eslint').Linter.Config }
604
+ */
605
+ function node(options = {}) {
606
+ const overrides = objectOrEmpty(options.node.overrides);
607
+ /** @type { import('eslint/config').ConfigObject } */
608
+ const nodeConfig = {
609
+ name: "node",
610
+ plugins: { n: plugin$4 },
611
+ rules: {
612
+ "n/callback-return": "off",
613
+ "n/exports-style": [
614
+ "error",
615
+ "module.exports",
616
+ { allowBatchAssign: false }
617
+ ],
618
+ "n/global-require": "warn",
619
+ "n/handle-callback-err": "warn",
620
+ "n/hashbang": "off",
621
+ "n/no-callback-literal": "off",
622
+ "n/no-deprecated-api": "error",
623
+ "n/no-exports-assign": "error",
624
+ "n/no-mixed-requires": "warn",
625
+ "n/no-new-require": "error",
626
+ "n/no-path-concat": "error",
627
+ "n/no-process-env": "error",
628
+ "n/no-process-exit": "off",
629
+ "n/no-restricted-import": "off",
630
+ "n/no-restricted-require": "off",
631
+ "n/no-sync": strict(options, "warn"),
632
+ "n/no-top-level-await": "off",
633
+ "n/no-unpublished-bin": "warn",
634
+ "n/no-unpublished-import": "off",
635
+ "n/no-unpublished-require": "warn",
636
+ "n/no-unsupported-features/es-builtins": "off",
637
+ "n/no-unsupported-features/es-syntax": "off",
638
+ "n/no-unsupported-features/node-builtins": "off",
639
+ "n/prefer-global/buffer": "warn",
640
+ "n/prefer-global/console": "warn",
641
+ "n/prefer-global/crypto": "warn",
642
+ "n/prefer-global/text-decoder": "warn",
643
+ "n/prefer-global/text-encoder": "warn",
644
+ "n/prefer-global/timers": "warn",
645
+ "n/prefer-global/url-search-params": "warn",
646
+ "n/prefer-global/url": "warn",
647
+ "/prefer-import/assert-strict": "warn",
648
+ "n/prefer-node-protocol": "warn",
649
+ "n/prefer-process-get-builtin-module": "warn",
650
+ "n/prefer-promises/dns": "warn",
651
+ "n/prefer-promises/fs": "warn",
652
+ "n/process-exit-as-throw": "error",
653
+ "n/prefer-global/process": "off",
654
+ "n/file-extension-in-import": "off",
655
+ "n/no-extraneous-import": "off",
656
+ "n/no-extraneous-require": "off",
657
+ "n/no-missing-import": "off",
658
+ "n/no-missing-require": "off"
659
+ }
660
+ };
661
+ return mergeConfigs(nodeConfig, overrides);
662
+ }
663
+ //#endregion
664
+ //#region src/modules/perfectionist.mjs
665
+ /**
666
+ * @param { import('../types').Options } options
667
+ * @return { Promise<import('eslint').Linter.Config> }
668
+ */
669
+ function perfectionist(options = {}) {
670
+ const overrides = objectOrEmpty(options.sort.overrides);
671
+ return mergeConfigs({
672
+ name: "perfectionist",
673
+ plugins: { perfectionist: plugin$5 },
674
+ rules: {
675
+ "perfectionist/sort-array-includes": "warn",
676
+ "perfectionist/sort-arrays": "off",
677
+ "perfectionist/sort-classes": "off",
678
+ "perfectionist/sort-decorators": "off",
679
+ "perfectionist/sort-enums": "off",
680
+ "perfectionist/sort-export-attributes": "warn",
681
+ "perfectionist/sort-exports": "warn",
682
+ "perfectionist/sort-heritage-clauses": "warn",
683
+ "perfectionist/sort-import-attributes": "warn",
684
+ "perfectionist/sort-imports": "warn",
685
+ "perfectionist/sort-interfaces": "off",
686
+ "perfectionist/sort-modules": "off",
687
+ "perfectionist/sort-intersection-types": ["warn", { groups: [
688
+ "conditional",
689
+ "function",
690
+ "import",
691
+ "intersection",
692
+ "keyword",
693
+ "literal",
694
+ "named",
695
+ "object",
696
+ "operator",
697
+ "tuple",
698
+ "union",
699
+ "nullish"
700
+ ] }],
701
+ "perfectionist/sort-jsx-props": "off",
702
+ "perfectionist/sort-maps": "off",
703
+ "perfectionist/sort-named-exports": "warn",
704
+ "perfectionist/sort-named-imports": "warn",
705
+ "perfectionist/sort-object-types": "off",
706
+ "perfectionist/sort-objects": "off",
707
+ "perfectionist/sort-sets": "warn",
708
+ "perfectionist/sort-switch-case": "off",
709
+ "perfectionist/sort-union-types": ["warn", { groups: [
710
+ "conditional",
711
+ "function",
712
+ "import",
713
+ "intersection",
714
+ "keyword",
715
+ "literal",
716
+ "named",
717
+ "object",
718
+ "operator",
719
+ "tuple",
720
+ "union",
721
+ "nullish"
722
+ ] }],
723
+ "perfectionist/sort-variable-declarations": "warn"
724
+ }
725
+ }, overrides);
726
+ }
727
+ //#endregion
728
+ //#region src/modules/playwright.mjs
729
+ /**
730
+ * @param { import('../types').Options } options
731
+ * @return { Promise<import('eslint').Linter.Config> }
732
+ */
733
+ function playwright(options = {}) {
734
+ const overrides = objectOrEmpty(options.playwright.overrides);
735
+ /** @type { import('eslint/config').ConfigObject } */
736
+ const playwrightConfig = {
737
+ name: "playwright",
738
+ plugins: { playwright: plugin$6 },
739
+ files: globs.e2e,
740
+ rules: {
741
+ "playwright/consistent-spacing-between-blocks": "warn",
742
+ "playwright/expect-expect": "error",
743
+ "playwright/max-expects": "off",
744
+ "playwright/max-nested-describe": ["warn", { max: 5 }],
745
+ "playwright/missing-playwright-await": "error",
746
+ "playwright/no-commented-out-tests": "warn",
747
+ "playwright/no-conditional-expect": "warn",
748
+ "playwright/no-conditional-in-test": "warn",
749
+ "playwright/no-duplicate-hooks": "error",
750
+ "playwright/no-duplicate-slow": "off",
751
+ "playwright/no-element-handle": "warn",
752
+ "playwright/no-eval": "warn",
753
+ "playwright/no-focused-test": "warn",
754
+ "playwright/no-force-option": "warn",
755
+ "playwright/no-get-by-title": "off",
756
+ "playwright/no-hooks": "off",
757
+ "playwright/no-nested-step": "warn",
758
+ "playwright/no-networkidle": "warn",
759
+ "playwright/no-nth-methods": "off",
760
+ "playwright/no-page-pause": "warn",
761
+ "playwright/no-raw-locators": "off",
762
+ "playwright/no-restricted-locators": "off",
763
+ "playwright/no-restricted-matchers": "off",
764
+ "playwright/no-restricted-roles": "off",
765
+ "playwright/no-skipped-test": "warn",
766
+ "playwright/no-slowed-test": "warn",
767
+ "playwright/no-standalone-expect": "warn",
768
+ "playwright/no-unsafe-references": "warn",
769
+ "playwright/no-unused-locators": "warn",
770
+ "playwright/no-useless-await": "error",
771
+ "playwright/no-useless-not": "warn",
772
+ "playwright/no-wait-for-navigation": "warn",
773
+ "playwright/no-wait-for-selector": "warn",
774
+ "playwright/no-wait-for-timeout": "warn",
775
+ "playwright/prefer-comparison-matcher": "off",
776
+ "playwright/prefer-equality-matcher": "off",
777
+ "playwright/prefer-hooks-in-order": "off",
778
+ "playwright/prefer-hooks-on-top": "off",
779
+ "playwright/prefer-locator": "off",
780
+ "playwright/prefer-lowercase-title": "off",
781
+ "playwright/prefer-native-locators": "off",
782
+ "playwright/prefer-strict-equal": "off",
783
+ "playwright/prefer-to-be": "off",
784
+ "playwright/prefer-to-contain": "off",
785
+ "playwright/prefer-to-have-count": "off",
786
+ "playwright/prefer-to-have-length": "off",
787
+ "playwright/prefer-web-first-assertions": "warn",
788
+ "playwright/require-hook": "off",
789
+ "playwright/require-soft-assertions": "off",
790
+ "playwright/require-tags": "off",
791
+ "playwright/require-to-pass-timeout": "off",
792
+ "playwright/require-to-throw-message": "off",
793
+ "playwright/require-top-level-describe": "off",
794
+ "playwright/valid-describe-callback": "warn",
795
+ "playwright/valid-expect-in-promise": "warn",
796
+ "playwright/valid-expect": "warn",
797
+ "playwright/valid-test-tags": "off",
798
+ "playwright/valid-title": "warn"
799
+ }
800
+ };
801
+ return mergeConfigs(playwrightConfig, overrides);
802
+ }
803
+ //#endregion
804
+ //#region src/modules/prettier.mjs
805
+ /**
806
+ * @param { import('../types').Options } options
807
+ * @return { Promise<import('eslint').Linter.Config> }
808
+ */
809
+ function prettier(options = {}) {
810
+ const overrides = objectOrEmpty(options.prettier.overrides);
811
+ return mergeConfigs({
812
+ name: "prettier",
813
+ plugins: { prettier: plugin$7 },
814
+ rules: {
815
+ "prettier/prettier": "error",
816
+ "curly": "off",
817
+ "no-unexpected-multiline": "off",
818
+ "@typescript-eslint/lines-around-comment": "off",
819
+ "@typescript-eslint/quotes": "off",
820
+ "@typescript-eslint/block-spacing": "off",
821
+ "@typescript-eslint/comma-dangle": "off",
822
+ "@typescript-eslint/comma-spacing": "off",
823
+ "@typescript-eslint/func-call-spacing": "off",
824
+ "@typescript-eslint/indent": "off",
825
+ "@typescript-eslint/keyword-spacing": "off",
826
+ "@typescript-eslint/member-delimiter-style": "off",
827
+ "@typescript-eslint/no-extra-parens": "off",
828
+ "@typescript-eslint/no-extra-semi": "off",
829
+ "@typescript-eslint/semi": "off",
830
+ "@typescript-eslint/space-before-function-paren": "off",
831
+ "@typescript-eslint/space-infix-ops": "off",
832
+ "@typescript-eslint/type-annotation-spacing": "off",
833
+ "@stylistic/jsx-child-element-spacing": "off",
834
+ "@stylistic/jsx-closing-bracket-location": "off",
835
+ "@stylistic/jsx-closing-tag-location": "off",
836
+ "@stylistic/jsx-curly-newline": "off",
837
+ "@stylistic/jsx-curly-spacing": "off",
838
+ "@stylistic/jsx-equals-spacing": "off",
839
+ "@stylistic/jsx-first-prop-new-line": "off",
840
+ "@stylistic/jsx-indent-props": "off",
841
+ "@stylistic/jsx-max-props-per-line": "off",
842
+ "@stylistic/jsx-newline": "off",
843
+ "@stylistic/jsx-one-expression-per-line": "off",
844
+ "@stylistic/jsx-tag-spacing": "off",
845
+ "@stylistic/jsx-wrap-multilines": "off",
846
+ "vue/html-self-closing": "off",
847
+ "vue/max-len": "off",
848
+ "vue/array-bracket-newline": "off",
849
+ "vue/array-bracket-spacing": "off",
850
+ "vue/array-element-newline": "off",
851
+ "vue/arrow-spacing": "off",
852
+ "vue/block-spacing": "off",
853
+ "vue/block-tag-newline": "off",
854
+ "vue/brace-style": "off",
855
+ "vue/comma-dangle": "off",
856
+ "vue/comma-spacing": "off",
857
+ "vue/comma-style": "off",
858
+ "vue/dot-location": "off",
859
+ "vue/func-call-spacing": "off",
860
+ "vue/html-closing-bracket-newline": "off",
861
+ "vue/html-closing-bracket-spacing": "off",
862
+ "vue/html-end-tags": "off",
863
+ "vue/html-indent": "off",
864
+ "vue/html-quotes": "off",
865
+ "vue/key-spacing": "off",
866
+ "vue/keyword-spacing": "off",
867
+ "vue/max-attributes-per-line": "off",
868
+ "vue/multiline-html-element-content-newline": "off",
869
+ "vue/multiline-ternary": "off",
870
+ "vue/mustache-interpolation-spacing": "off",
871
+ "vue/no-extra-parens": "off",
872
+ "vue/no-multi-spaces": "off",
873
+ "vue/no-spaces-around-equal-signs-in-attribute": "off",
874
+ "vue/object-curly-newline": "off",
875
+ "vue/object-curly-spacing": "off",
876
+ "vue/object-property-newline": "off",
877
+ "vue/operator-linebreak": "off",
878
+ "vue/quote-props": "off",
879
+ "vue/script-indent": "off",
880
+ "vue/singleline-html-element-content-newline": "off",
881
+ "vue/space-in-parens": "off",
882
+ "vue/space-infix-ops": "off",
883
+ "vue/space-unary-ops": "off",
884
+ "vue/template-curly-spacing": "off"
885
+ }
886
+ }, overrides);
887
+ }
888
+ //#endregion
889
+ //#region src/modules/promise.mjs
890
+ /**
891
+ * @param { import('../types').Options } options
892
+ * @return { Promise<import('eslint').Linter.Config> }
893
+ */
894
+ function promise(options = {}) {
895
+ const overrides = objectOrEmpty(options.promise.overrides);
896
+ /** @type { import('eslint/config').ConfigObject } */
897
+ const promiseConfig = {
898
+ name: "promise",
899
+ plugins: { promise: plugin$8 },
900
+ rules: {
901
+ "promise/always-return": "off",
902
+ "promise/avoid-new": "off",
903
+ "promise/catch-or-return": "off",
904
+ "promise/no-callback-in-promise": "off",
905
+ "promise/no-native": "off",
906
+ "promise/no-nesting": "off",
907
+ "promise/no-new-statics": "error",
908
+ "promise/no-promise-in-callback": "error",
909
+ "promise/no-return-in-finally": "warn",
910
+ "promise/no-return-wrap": "error",
911
+ "promise/param-names": "warn",
912
+ "promise/prefer-await-to-callbacks": "off",
913
+ "promise/prefer-await-to-then": "off",
914
+ "promise/prefer-catch": strict(options, "warn"),
915
+ "promise/valid-params": "warn",
916
+ "promise/no-multiple-resolved": "warn",
917
+ "promise/spec-only": "warn"
918
+ }
919
+ };
920
+ return mergeConfigs(promiseConfig, overrides);
921
+ }
922
+ //#endregion
923
+ //#region src/utils/nextAllowExportNames.mjs
924
+ const nextAllowExportNames = [
925
+ "experimental_ppr",
926
+ "dynamic",
927
+ "dynamicParams",
928
+ "revalidate",
929
+ "fetchCache",
930
+ "runtime",
931
+ "preferredRegion",
932
+ "maxDuration",
933
+ "metadata",
934
+ "generateMetadata",
935
+ "viewport",
936
+ "generateViewport",
937
+ "generateImageMetadata",
938
+ "generateSitemaps",
939
+ "generateStaticParams",
940
+ "instant"
941
+ ];
942
+ //#endregion
943
+ //#region src/modules/react.mjs
944
+ /**
945
+ * @param { import('../types').Options } options
946
+ * @return { Promise<import('eslint').Linter.Config> }
947
+ */
948
+ function react(options = {}) {
949
+ const projectService = options.typescript && options.typescript.tsconfigRootDir && options.typescript.projectService;
950
+ const isObject = typeof options.react === "object";
951
+ const overrides = objectOrEmpty(options.react.overrides);
952
+ /** @type { import('eslint/config').ConfigObject } */
953
+ const reactConfig = {
954
+ name: "react",
955
+ files: [
956
+ globs.js,
957
+ globs.jsx,
958
+ globs.ts,
959
+ globs.tsx
960
+ ],
961
+ plugins: {
962
+ ...reactPlugin.configs.all.plugins,
963
+ "jsx-a11y": a11yPlugin,
964
+ "react-refresh": reactRefresh.plugin
965
+ },
966
+ ...predicate(projectService, { languageOptions: {
967
+ parser,
968
+ parserOptions: { ...options.typescript }
969
+ } }),
970
+ settings: { "react-x": {
971
+ ...predicate(isObject && "version" in options.react, { version: options.react.version }),
972
+ ...predicate(isObject && "importSource" in options.react, { importSource: options.react.importSource }),
973
+ ...predicate(isObject && "compilationMode" in options.react, { compilationMode: options.react.compilationMode }),
974
+ ...predicate(isObject && "polymorphicPropName" in options.react, { polymorphicPropName: options.react.polymorphicPropName }),
975
+ ...predicate(isObject && "additionalStateHooks" in options.react, { additionalStateHooks: options.react.additionalStateHooks }),
976
+ ...predicate(isObject && "additionalEffectHooks" in options.react, { additionalEffectHooks: options.react.additionalEffectHooks })
977
+ } },
978
+ rules: {
979
+ "@eslint-react/dom-no-void-elements-with-children": "warn",
980
+ "@eslint-react/dom-no-dangerously-set-innerhtml-with-children": "error",
981
+ "@eslint-react/dom-no-dangerously-set-innerhtml": "off",
982
+ "@eslint-react/dom-no-find-dom-node": "error",
983
+ "@eslint-react/dom-no-flush-sync": "off",
984
+ "@eslint-react/dom-no-use-form-state": "warn",
985
+ "@eslint-react/dom-no-hydrate": "warn",
986
+ "@eslint-react/dom-no-missing-button-type": "warn",
987
+ "@eslint-react/dom-no-missing-iframe-sandbox": "warn",
988
+ "@eslint-react/dom-no-render-return-value": "error",
989
+ "@eslint-react/dom-no-render": "warn",
990
+ "@eslint-react/dom-no-script-url": "warn",
991
+ "@eslint-react/dom-no-string-style-prop": "error",
992
+ "@eslint-react/dom-no-unsafe-iframe-sandbox": "warn",
993
+ "@eslint-react/dom-no-unsafe-target-blank": "warn",
994
+ "@eslint-react/jsx-no-comment-textnodes": "warn",
995
+ "@eslint-react/jsx-no-children-prop": "warn",
996
+ "@eslint-react/jsx-no-children-prop-with-children": "warn",
997
+ "@eslint-react/jsx-no-key-after-spread": "error",
998
+ "@eslint-react/no-leaked-dollar": "error",
999
+ "@eslint-react/jsx-no-useless-fragment": "warn",
1000
+ "@eslint-react/jsx-no-namespace": "error",
1001
+ "@eslint-react/no-access-state-in-setstate": "error",
1002
+ "@eslint-react/no-array-index-key": "warn",
1003
+ "@eslint-react/no-children-count": "warn",
1004
+ "@eslint-react/no-children-for-each": "warn",
1005
+ "@eslint-react/no-children-map": "warn",
1006
+ "@eslint-react/no-children-only": "warn",
1007
+ "@eslint-react/no-children-to-array": "warn",
1008
+ "@eslint-react/no-clone-element": "warn",
1009
+ "@eslint-react/no-component-will-mount": "error",
1010
+ "@eslint-react/no-component-will-receive-props": "error",
1011
+ "@eslint-react/no-component-will-update": "error",
1012
+ "@eslint-react/no-context-provider": "warn",
1013
+ "@eslint-react/no-create-ref": "error",
1014
+ "@eslint-react/no-direct-mutation-state": "error",
1015
+ "@eslint-react/no-duplicate-key": "error",
1016
+ "@eslint-react/no-forward-ref": "warn",
1017
+ "@eslint-react/no-missing-context-display-name": "warn",
1018
+ "@eslint-react/no-missing-key": "error",
1019
+ "@eslint-react/no-misused-capture-owner-stack": "error",
1020
+ "@eslint-react/no-nested-component-definitions": "warn",
1021
+ "@eslint-react/no-nested-lazy-component-declarations": "error",
1022
+ "@eslint-react/no-set-state-in-component-did-mount": "warn",
1023
+ "@eslint-react/no-set-state-in-component-did-update": "warn",
1024
+ "@eslint-react/no-set-state-in-component-will-update": "warn",
1025
+ "@eslint-react/no-unsafe-component-will-mount": "warn",
1026
+ "@eslint-react/no-unsafe-component-will-receive-props": "warn",
1027
+ "@eslint-react/no-unsafe-component-will-update": "warn",
1028
+ "@eslint-react/no-unstable-context-value": "error",
1029
+ "@eslint-react/no-unstable-default-props": "error",
1030
+ "@eslint-react/no-unused-class-component-members": "warn",
1031
+ "@eslint-react/no-unused-state": "warn",
1032
+ "@eslint-react/no-use-context": "warn",
1033
+ "@eslint-react/no-unnecessary-use-prefix": "warn",
1034
+ "@eslint-react/naming-convention-context-name": "warn",
1035
+ "@eslint-react/naming-convention-id-name": "warn",
1036
+ "@eslint-react/naming-convention-ref-name": "warn",
1037
+ "@eslint-react/use-state": ["warn", {
1038
+ enforceAssignment: true,
1039
+ enforceSetterName: false,
1040
+ enforceLazyInitialization: true
1041
+ }],
1042
+ "@eslint-react/web-api-no-leaked-timeout": "error",
1043
+ "@eslint-react/web-api-no-leaked-event-listener": "error",
1044
+ "@eslint-react/web-api-no-leaked-interval": "error",
1045
+ "@eslint-react/web-api-no-leaked-resize-observer": "error",
1046
+ "@eslint-react/web-api-no-leaked-fetch": "error",
1047
+ "@eslint-react/web-api-no-leaked-intersection-observer": "error",
1048
+ "@eslint-react/rsc-function-definition": "error",
1049
+ "@eslint-react/rules-of-hooks": "error",
1050
+ "@eslint-react/exhaustive-deps": "error",
1051
+ "@eslint-react/error-boundaries": "error",
1052
+ "@eslint-react/globals": "error",
1053
+ "@eslint-react/immutability": "error",
1054
+ "@eslint-react/purity": "error",
1055
+ "@eslint-react/refs": "error",
1056
+ "@eslint-react/set-state-in-effect": strict("error"),
1057
+ "@eslint-react/set-state-in-render": "error",
1058
+ "@eslint-react/static-components": strict("error"),
1059
+ "@eslint-react/unsupported-syntax": "error",
1060
+ "@eslint-react/use-memo": "error",
1061
+ "jsx-a11y/alt-text": "warn",
1062
+ "jsx-a11y/anchor-has-content": "error",
1063
+ "jsx-a11y/anchor-is-valid": "error",
1064
+ "jsx-a11y/aria-activedescendant-has-tabindex": "error",
1065
+ "jsx-a11y/aria-props": "error",
1066
+ "jsx-a11y/aria-proptypes": "error",
1067
+ "jsx-a11y/aria-role": "error",
1068
+ "jsx-a11y/aria-unsupported-elements": "error",
1069
+ "jsx-a11y/autocomplete-valid": "off",
1070
+ "jsx-a11y/click-events-have-key-events": "error",
1071
+ "jsx-a11y/control-has-associated-label": "off",
1072
+ "jsx-a11y/heading-has-content": "error",
1073
+ "jsx-a11y/html-has-lang": "error",
1074
+ "jsx-a11y/iframe-has-title": "error",
1075
+ "jsx-a11y/img-redundant-alt": "error",
1076
+ "jsx-a11y/interactive-supports-focus": "warn",
1077
+ "jsx-a11y/label-has-associated-control": "error",
1078
+ "jsx-a11y/lang": "error",
1079
+ "jsx-a11y/media-has-caption": "warn",
1080
+ "jsx-a11y/mouse-events-have-key-events": "error",
1081
+ "jsx-a11y/no-access-key": "error",
1082
+ "jsx-a11y/no-aria-hidden-on-focusable": "warn",
1083
+ "jsx-a11y/no-autofocus": "off",
1084
+ "jsx-a11y/no-distracting-elements": "error",
1085
+ "jsx-a11y/no-interactive-element-to-noninteractive-role": "warn",
1086
+ "jsx-a11y/no-noninteractive-element-interactions": "warn",
1087
+ "jsx-a11y/no-noninteractive-element-to-interactive-role": "warn",
1088
+ "jsx-a11y/no-noninteractive-tabindex": "off",
1089
+ "jsx-a11y/no-redundant-roles": "error",
1090
+ "jsx-a11y/no-static-element-interactions": "off",
1091
+ "jsx-a11y/role-has-required-aria-props": "error",
1092
+ "jsx-a11y/role-supports-aria-props": "error",
1093
+ "jsx-a11y/scope": "error",
1094
+ "jsx-a11y/tabindex-no-positive": "warn",
1095
+ "jsx-a11y/anchor-ambiguous-text": "off",
1096
+ "jsx-a11y/prefer-tag-over-role": "off",
1097
+ "react-refresh/only-export-components": ["error", {
1098
+ allowExportNames: isPackageExists("next") ? nextAllowExportNames : [],
1099
+ allowConstantExport: isPackageExists("vite")
1100
+ }]
1101
+ }
1102
+ };
1103
+ return mergeConfigs(reactConfig, overrides);
1104
+ }
1105
+ //#endregion
1106
+ //#region src/modules/regex.mjs
1107
+ /**
1108
+ * @param { import('../types').Options } options
1109
+ * @return { Promise<import('eslint').Linter.Config> }
1110
+ */
1111
+ function regex(options = {}) {
1112
+ const isObject = typeof options.regex === "object";
1113
+ const overrides = objectOrEmpty(options.regex.overrides);
1114
+ /** @type { import('eslint/config').ConfigObject } */
1115
+ const regexConfig = {
1116
+ name: "regex",
1117
+ plugins: { regexp: plugin$12 },
1118
+ settings: { regexp: { ...predicate(isObject && "allowedCharacterRanges" in options.regex, { allowedCharacterRanges: options.regex.allowedCharacterRanges }) } },
1119
+ rules: {
1120
+ "regexp/confusing-quantifier": "warn",
1121
+ "regexp/control-character-escape": "error",
1122
+ "regexp/grapheme-string-literal": "off",
1123
+ "regexp/hexadecimal-escape": "warn",
1124
+ "regexp/letter-case": "warn",
1125
+ "regexp/match-any": "error",
1126
+ "regexp/negation": "error",
1127
+ "regexp/no-contradiction-with-assertion": "error",
1128
+ "regexp/no-control-character": "off",
1129
+ "regexp/no-dupe-characters-character-class": "error",
1130
+ "regexp/no-dupe-disjunctions": "error",
1131
+ "regexp/no-empty-alternative": "warn",
1132
+ "regexp/no-empty-capturing-group": "error",
1133
+ "regexp/no-empty-character-class": "error",
1134
+ "regexp/no-empty-group": "error",
1135
+ "regexp/no-empty-lookarounds-assertion": "error",
1136
+ "regexp/no-empty-string-literal": "error",
1137
+ "regexp/no-escape-backspace": "error",
1138
+ "regexp/no-extra-lookaround-assertions": "error",
1139
+ "regexp/no-invalid-regexp": "error",
1140
+ "regexp/no-invisible-character": "error",
1141
+ "regexp/no-lazy-ends": "warn",
1142
+ "regexp/no-legacy-features": "error",
1143
+ "regexp/no-misleading-capturing-group": "error",
1144
+ "regexp/no-misleading-unicode-character": "error",
1145
+ "regexp/no-missing-g-flag": "error",
1146
+ "regexp/no-non-standard-flag": "error",
1147
+ "regexp/no-obscure-range": "error",
1148
+ "regexp/no-octal": "off",
1149
+ "regexp/no-optional-assertion": "error",
1150
+ "regexp/no-potentially-useless-backreference": "warn",
1151
+ "regexp/no-standalone-backslash": "warn",
1152
+ "regexp/no-super-linear-backtracking": "error",
1153
+ "regexp/no-super-linear-move": "off",
1154
+ "regexp/no-trivially-nested-assertion": "error",
1155
+ "regexp/no-trivially-nested-quantifier": "error",
1156
+ "regexp/no-unused-capturing-group": "error",
1157
+ "regexp/no-useless-assertions": "error",
1158
+ "regexp/no-useless-backreference": "error",
1159
+ "regexp/no-useless-character-class": "error",
1160
+ "regexp/no-useless-dollar-replacements": "error",
1161
+ "regexp/no-useless-escape": "error",
1162
+ "regexp/no-useless-flag": "warn",
1163
+ "regexp/no-useless-lazy": "error",
1164
+ "regexp/no-useless-non-capturing-group": "error",
1165
+ "regexp/no-useless-quantifier": "error",
1166
+ "regexp/no-useless-range": "error",
1167
+ "regexp/no-useless-set-operand": "error",
1168
+ "regexp/no-useless-string-literal": "error",
1169
+ "regexp/no-useless-two-nums-quantifier": "error",
1170
+ "regexp/no-zero-quantifier": "error",
1171
+ "regexp/optimal-lookaround-quantifier": "warn",
1172
+ "regexp/optimal-quantifier-concatenation": "error",
1173
+ "regexp/prefer-character-class": "error",
1174
+ "regexp/prefer-d": "error",
1175
+ "regexp/prefer-escape-replacement-dollar-char": "warn",
1176
+ "regexp/prefer-lookaround": "off",
1177
+ "regexp/prefer-named-backreference": "warn",
1178
+ "regexp/prefer-named-capture-group": "off",
1179
+ "regexp/prefer-named-replacement": "off",
1180
+ "regexp/prefer-plus-quantifier": "error",
1181
+ "regexp/prefer-predefined-assertion": "error",
1182
+ "regexp/prefer-quantifier": "off",
1183
+ "regexp/prefer-question-quantifier": "error",
1184
+ "regexp/prefer-range": "error",
1185
+ "regexp/prefer-regexp-exec": "warn",
1186
+ "regexp/prefer-regexp-test": "warn",
1187
+ "regexp/prefer-result-array-groups": "warn",
1188
+ "regexp/prefer-set-operation": "error",
1189
+ "regexp/prefer-star-quantifier": "error",
1190
+ "regexp/prefer-unicode-codepoint-escapes": "error",
1191
+ "regexp/prefer-w": "error",
1192
+ "regexp/require-unicode-regexp": "off",
1193
+ "regexp/require-unicode-sets-regexp": "off",
1194
+ "regexp/simplify-set-operations": "error",
1195
+ "regexp/sort-alternatives": "warn",
1196
+ "regexp/sort-character-class-elements": "warn",
1197
+ "regexp/sort-flags": "warn",
1198
+ "regexp/strict": "error",
1199
+ "regexp/unicode-escape": "warn",
1200
+ "regexp/unicode-property": "warn",
1201
+ "regexp/use-ignore-case": "error",
1202
+ "no-invalid-regexp": "off",
1203
+ "no-useless-backreference": "off",
1204
+ "no-empty-character-class": "off"
1205
+ }
1206
+ };
1207
+ return mergeConfigs(regexConfig, overrides);
1208
+ }
1209
+ //#endregion
1210
+ //#region src/modules/storybook.mjs
1211
+ /**
1212
+ * @param { import('../types').Options } options
1213
+ * @return { Promise<import('eslint').Linter.Config> }
1214
+ */
1215
+ function storybook(options = {}) {
1216
+ const overrides = objectOrEmpty(options.storybook.overrides);
1217
+ /** @type { import('eslint/config').ConfigObject } */
1218
+ const storybookConfig = {
1219
+ name: "storybook",
1220
+ files: globs.storybook,
1221
+ plugins: { storybook: plugin$10 },
1222
+ rules: {
1223
+ "storybook/await-interactions": "error",
1224
+ "storybook/context-in-play-function": "error",
1225
+ "storybook/default-exports": "error",
1226
+ "storybook/hierarchy-separator": "warn",
1227
+ "storybook/meta-satisfies-type": "warn",
1228
+ "storybook/no-redundant-story-name": "warn",
1229
+ "storybook/no-renderer-packages": "warn",
1230
+ "storybook/no-uninstalled-addons": "error",
1231
+ "storybook/prefer-pascal-case": "warn",
1232
+ "storybook/story-exports": "error",
1233
+ "storybook/use-storybook-expect": "error",
1234
+ "storybook/use-storybook-testing-library": "error",
1235
+ "storybook/csf-component": "warn",
1236
+ "storybook/meta-inline-properties": "off",
1237
+ "storybook/no-stories-of": "warn",
1238
+ "storybook/no-title-property-in-meta": "off",
1239
+ "@typescript-eslint/no-confusing-void-expression": "off",
1240
+ "@eslint-react/no-useless-fragment": "off",
1241
+ "react-hooks/rules-of-hooks": "off"
1242
+ }
1243
+ };
1244
+ return mergeConfigs(storybookConfig, overrides);
1245
+ }
1246
+ //#endregion
1247
+ //#region src/modules/stylistic.mjs
1248
+ /**
1249
+ * @param { import('../types').Options } options
1250
+ * @return { Promise<import('eslint').Linter.Config> }
1251
+ */
1252
+ function stylistic(options = {}) {
1253
+ const overrides = objectOrEmpty(options.stylistic.overrides);
1254
+ return mergeConfigs({
1255
+ name: "stylistic",
1256
+ plugins: { "@stylistic": stylisticPlugin },
1257
+ rules: {
1258
+ "@stylistic/jsx-curly-brace-presence": ["warn", {
1259
+ props: "never",
1260
+ children: "never",
1261
+ propElementValues: "always"
1262
+ }],
1263
+ "@stylistic/jsx-self-closing-comp": ["warn", {
1264
+ component: true,
1265
+ html: true
1266
+ }],
1267
+ "@stylistic/no-mixed-operators": "off",
1268
+ "@stylistic/padding-line-between-statements": [
1269
+ "warn",
1270
+ {
1271
+ blankLine: "always",
1272
+ prev: ["case", "default"],
1273
+ next: "*"
1274
+ },
1275
+ {
1276
+ blankLine: "always",
1277
+ prev: "*",
1278
+ next: "multiline-block-like"
1279
+ },
1280
+ {
1281
+ blankLine: "always",
1282
+ prev: "multiline-block-like",
1283
+ next: "*"
1284
+ },
1285
+ {
1286
+ blankLine: "always",
1287
+ prev: ["type", "interface"],
1288
+ next: "*"
1289
+ },
1290
+ {
1291
+ blankLine: "always",
1292
+ prev: "directive",
1293
+ next: "*"
1294
+ },
1295
+ {
1296
+ blankLine: "never",
1297
+ prev: "directive",
1298
+ next: "directive"
1299
+ },
1300
+ {
1301
+ blankLine: "always",
1302
+ prev: "import",
1303
+ next: "*"
1304
+ },
1305
+ {
1306
+ blankLine: "any",
1307
+ prev: "*",
1308
+ next: "import"
1309
+ },
1310
+ {
1311
+ blankLine: "always",
1312
+ prev: "directive",
1313
+ next: "import"
1314
+ },
1315
+ {
1316
+ blankLine: "any",
1317
+ prev: ["if"],
1318
+ next: ["if"]
1319
+ }
1320
+ ],
1321
+ "@stylistic/lines-between-class-members": ["warn", { enforce: [
1322
+ {
1323
+ blankLine: "never",
1324
+ prev: "field",
1325
+ next: "field"
1326
+ },
1327
+ {
1328
+ blankLine: "always",
1329
+ prev: "*",
1330
+ next: "method"
1331
+ },
1332
+ {
1333
+ blankLine: "always",
1334
+ prev: "method",
1335
+ next: "*"
1336
+ }
1337
+ ] }]
1338
+ }
1339
+ }, overrides);
1340
+ }
1341
+ //#endregion
1342
+ //#region src/modules/tailwind.mjs
1343
+ /**
1344
+ * @param { import('../types').Options } options
1345
+ * @return { Promise<import('eslint').Linter.Config> }
1346
+ */
1347
+ async function tailwind(options = {}) {
1348
+ const plugin = await import("eslint-plugin-better-tailwindcss");
1349
+ const isObject = typeof options.tailwind === "object";
1350
+ const overrides = objectOrEmpty(options.tailwind.overrides);
1351
+ /** @type { import('eslint/config').ConfigObject } */
1352
+ const tailwindConfig = {
1353
+ name: "tailwind",
1354
+ plugins: { "better-tailwindcss": plugin.default ?? plugin },
1355
+ settings: { "better-tailwindcss": {
1356
+ ...predicate(isObject && "entryPoint" in options.tailwind, { entryPoint: options.tailwind.entryPoint }),
1357
+ ...predicate(isObject && "tailwindConfig" in options.tailwind, { tailwindConfig: options.tailwind.tailwindConfig }),
1358
+ callees: [["^class|classnames|classNames|cva|ctl|clsx|cn|cns|cx|cc|clb|cnb|dcnb|objstr|tv|twJoin|twMerge$", [{ match: "strings" }]]]
1359
+ } },
1360
+ rules: {
1361
+ "better-tailwindcss/enforce-canonical-classes": "warn",
1362
+ "better-tailwindcss/enforce-consistent-class-order": "warn",
1363
+ "better-tailwindcss/enforce-consistent-important-position": "warn",
1364
+ "better-tailwindcss/enforce-consistent-line-wrapping": "off",
1365
+ "better-tailwindcss/enforce-consistent-variable-syntax": "error",
1366
+ "better-tailwindcss/enforce-consistent-variant-order": "warn",
1367
+ "better-tailwindcss/enforce-logical-properties": strict("warn"),
1368
+ "better-tailwindcss/enforce-shorthand-classes": "warn",
1369
+ "better-tailwindcss/no-concatenated-classes": "error",
1370
+ "better-tailwindcss/no-conflicting-classes": "error",
1371
+ "better-tailwindcss/no-deprecated-classes": "warn",
1372
+ "better-tailwindcss/no-duplicate-classes": "error",
1373
+ "better-tailwindcss/no-restricted-classes": "warn",
1374
+ "better-tailwindcss/no-unknown-classes": strict("warn"),
1375
+ "better-tailwindcss/no-unnecessary-whitespace": "warn"
1376
+ }
1377
+ };
1378
+ return mergeConfigs(tailwindConfig, overrides);
1379
+ }
1380
+ //#endregion
1381
+ //#region src/modules/tests.mjs
1382
+ /**
1383
+ * @param { import('../types').Options } options
1384
+ * @return { import('eslint').Linter.Config }
1385
+ */
1386
+ function tests(options = {}) {
1387
+ const overrides = objectOrEmpty(options.test.overrides);
1388
+ /** @type { import('eslint/config').ConfigObject } */
1389
+ const testsConfug = {
1390
+ name: "tests",
1391
+ files: [...globs.test, ...globs.e2e],
1392
+ plugins: { vitest: plugin$11 },
1393
+ languageOptions: { globals: { ...globals["shared-node-browser"] } },
1394
+ rules: {
1395
+ "max-lines-per-function": "off",
1396
+ "no-sparse-arrays": "off",
1397
+ "no-empty-function": "off",
1398
+ "vitest/padding-around-all": "warn",
1399
+ ...predicate(options.react, { "@eslint-react/no-unstable-context-value": "off" }),
1400
+ ...predicate(options.typescript, {
1401
+ "@typescript-eslint/method-signature-style": "off",
1402
+ "@typescript-eslint/no-namespace": "off",
1403
+ "@typescript-eslint/unbound-method": "off",
1404
+ "@typescript-eslint/no-empty-function": "off",
1405
+ "@typescript-eslint/no-floating-promises": "off",
1406
+ "@typescript-eslint/prefer-promise-reject-errors": "off"
1407
+ })
1408
+ }
1409
+ };
1410
+ return mergeConfigs(testsConfug, overrides);
1411
+ }
1412
+ //#endregion
1413
+ //#region src/utils/naming-convention.mjs
1414
+ const namingConvention = [
1415
+ {
1416
+ selector: "default",
1417
+ format: ["camelCase"],
1418
+ filter: {
1419
+ regex: "^_+$",
1420
+ match: false
1421
+ }
1422
+ },
1423
+ {
1424
+ selector: "import",
1425
+ format: null
1426
+ },
1427
+ {
1428
+ selector: "function",
1429
+ format: ["camelCase", "PascalCase"]
1430
+ },
1431
+ {
1432
+ selector: "variable",
1433
+ format: [
1434
+ "camelCase",
1435
+ "UPPER_CASE",
1436
+ "PascalCase"
1437
+ ],
1438
+ filter: {
1439
+ regex: "^_+$",
1440
+ match: false
1441
+ }
1442
+ },
1443
+ {
1444
+ selector: "parameter",
1445
+ format: ["camelCase", "PascalCase"],
1446
+ leadingUnderscore: "allow",
1447
+ filter: {
1448
+ regex: "^_+$",
1449
+ match: false
1450
+ }
1451
+ },
1452
+ {
1453
+ selector: "memberLike",
1454
+ format: null
1455
+ },
1456
+ {
1457
+ selector: "memberLike",
1458
+ modifiers: ["static"],
1459
+ format: ["camelCase", "PascalCase"],
1460
+ leadingUnderscore: "allow"
1461
+ },
1462
+ {
1463
+ selector: "memberLike",
1464
+ modifiers: ["private"],
1465
+ format: ["camelCase"],
1466
+ leadingUnderscore: "allow"
1467
+ },
1468
+ {
1469
+ selector: "typeLike",
1470
+ format: ["PascalCase"]
1471
+ },
1472
+ {
1473
+ selector: "enumMember",
1474
+ format: ["PascalCase"]
1475
+ },
1476
+ {
1477
+ selector: "interface",
1478
+ format: ["PascalCase"],
1479
+ custom: {
1480
+ regex: "^I[A-Z]",
1481
+ match: false
1482
+ }
1483
+ }
1484
+ ];
1485
+ //#endregion
1486
+ //#region src/modules/typescript.mjs
1487
+ /**
1488
+ * @param { import('../types').Options } options
1489
+ * @return { import('eslint').Linter.Config }
1490
+ */
1491
+ function typescript(options = {}) {
1492
+ const projectService = options.typescript && options.typescript.tsconfigRootDir && options.typescript.projectService;
1493
+ const overrides = objectOrEmpty(options.typescript.overrides);
1494
+ /** @type { import('eslint/config').ConfigObject } */
1495
+ const typescriptConfig = {
1496
+ name: "typescript",
1497
+ files: [globs.ts, globs.tsx],
1498
+ plugins: { "@typescript-eslint": plugin$9 },
1499
+ languageOptions: {
1500
+ parser,
1501
+ parserOptions: { ...options.typescript }
1502
+ },
1503
+ rules: {
1504
+ "@typescript-eslint/adjacent-overload-signatures": "error",
1505
+ "@typescript-eslint/array-type": "error",
1506
+ "@typescript-eslint/ban-ts-comment": ["error", {
1507
+ "ts-expect-error": "allow-with-description",
1508
+ "ts-ignore": "allow-with-description",
1509
+ "ts-nocheck": "allow-with-description",
1510
+ "ts-check": "allow-with-description",
1511
+ "minimumDescriptionLength": 3
1512
+ }],
1513
+ "@typescript-eslint/ban-tslint-comment": "off",
1514
+ "@typescript-eslint/camelcase": "off",
1515
+ "@typescript-eslint/class-literal-property-style": ["error", "getters"],
1516
+ "@typescript-eslint/consistent-generic-constructors": ["warn", "constructor"],
1517
+ "@typescript-eslint/consistent-indexed-object-style": "warn",
1518
+ "@typescript-eslint/consistent-type-assertions": "error",
1519
+ "@typescript-eslint/consistent-type-definitions": ["error", "interface"],
1520
+ "@typescript-eslint/consistent-type-imports": ["warn", {
1521
+ prefer: "type-imports",
1522
+ disallowTypeAnnotations: false,
1523
+ fixStyle: "separate-type-imports"
1524
+ }],
1525
+ "@typescript-eslint/default-param-last": "warn",
1526
+ "@typescript-eslint/explicit-function-return-type": "off",
1527
+ "@typescript-eslint/explicit-member-accessibility": "off",
1528
+ "@typescript-eslint/explicit-module-boundary-types": "off",
1529
+ "@typescript-eslint/generic-type-naming": "off",
1530
+ "@typescript-eslint/init-declarations": "off",
1531
+ "@typescript-eslint/member-naming": "off",
1532
+ "@typescript-eslint/member-ordering": "off",
1533
+ "@typescript-eslint/method-signature-style": ["warn", "property"],
1534
+ "@typescript-eslint/naming-convention": [
1535
+ "warn",
1536
+ ...namingConvention,
1537
+ ...projectService ? [{
1538
+ selector: "variable",
1539
+ types: ["boolean"],
1540
+ format: ["PascalCase"],
1541
+ prefix: [
1542
+ "is",
1543
+ "should",
1544
+ "has",
1545
+ "can",
1546
+ "did",
1547
+ "will",
1548
+ "enable",
1549
+ "loading"
1550
+ ]
1551
+ }] : []
1552
+ ],
1553
+ "@typescript-eslint/no-array-constructor": "error",
1554
+ "@typescript-eslint/no-confusing-non-null-assertion": "error",
1555
+ "@typescript-eslint/no-dupe-class-members": "error",
1556
+ "@typescript-eslint/no-duplicate-enum-values": "error",
1557
+ "@typescript-eslint/no-dynamic-delete": "error",
1558
+ "@typescript-eslint/no-empty-function": "error",
1559
+ "@typescript-eslint/no-empty-object-type": ["warn", { allowInterfaces: "with-single-extends" }],
1560
+ "@typescript-eslint/no-explicit-any": strict(options, "warn"),
1561
+ "@typescript-eslint/no-extra-non-null-assertion": "error",
1562
+ "@typescript-eslint/no-extraneous-class": ["warn", { allowWithDecorator: true }],
1563
+ "@typescript-eslint/no-import-type-side-effects": "warn",
1564
+ "@typescript-eslint/no-inferrable-types": "off",
1565
+ "@typescript-eslint/no-invalid-this": ["error", { capIsConstructor: false }],
1566
+ "@typescript-eslint/no-invalid-void-type": "error",
1567
+ "@typescript-eslint/no-loop-func": "error",
1568
+ "@typescript-eslint/no-magic-numbers": ["off", { ignoreEnums: true }],
1569
+ "@typescript-eslint/no-misused-new": "error",
1570
+ "@typescript-eslint/no-namespace": "error",
1571
+ "@typescript-eslint/no-non-null-asserted-nullish-coalescing": "error",
1572
+ "@typescript-eslint/no-non-null-asserted-optional-chain": "error",
1573
+ "@typescript-eslint/no-non-null-assertion": "off",
1574
+ ...predicate(options.strict, { "@typescript-eslint/no-non-null-assertion": "warn" }),
1575
+ "@typescript-eslint/no-redeclare": ["off", { ignoreDeclarationMerge: true }],
1576
+ "@typescript-eslint/no-require-imports": "error",
1577
+ "@typescript-eslint/no-restricted-imports": "off",
1578
+ "@typescript-eslint/no-shadow": "error",
1579
+ "@typescript-eslint/no-this-alias": "error",
1580
+ "@typescript-eslint/no-unnecessary-type-constraint": "warn",
1581
+ "@typescript-eslint/no-unsafe-argument": strict(options, "warn"),
1582
+ "@typescript-eslint/no-unsafe-assignment": strict(options, "warn"),
1583
+ "@typescript-eslint/no-unsafe-call": strict(options, "warn"),
1584
+ "@typescript-eslint/no-unsafe-declaration-merging": "warn",
1585
+ "@typescript-eslint/no-unsafe-member-access": strict(options, ["warn", { allowOptionalChaining: true }]),
1586
+ "@typescript-eslint/no-unsafe-return": strict(options, "warn"),
1587
+ "@typescript-eslint/no-untyped-public-signature": "off",
1588
+ "@typescript-eslint/no-unused-expressions": "error",
1589
+ "@typescript-eslint/no-unused-vars": ["warn", {
1590
+ argsIgnorePattern: "^_",
1591
+ varsIgnorePattern: "^([iI]gnore(d)?)|(_+)",
1592
+ caughtErrorsIgnorePattern: "^_",
1593
+ destructuredArrayIgnorePattern: "^_",
1594
+ args: "after-used",
1595
+ caughtErrors: "all",
1596
+ ignoreRestSiblings: true
1597
+ }],
1598
+ "@typescript-eslint/no-use-before-define": ["error", {
1599
+ functions: false,
1600
+ classes: true
1601
+ }],
1602
+ "@typescript-eslint/no-useless-constructor": "error",
1603
+ "@typescript-eslint/no-useless-default-assignment": "warn",
1604
+ "@typescript-eslint/no-useless-empty-export": "warn",
1605
+ "@typescript-eslint/parameter-properties": "off",
1606
+ "@typescript-eslint/prefer-as-const": "warn",
1607
+ "@typescript-eslint/prefer-enum-initializers": "off",
1608
+ "@typescript-eslint/prefer-for-of": "warn",
1609
+ "@typescript-eslint/prefer-function-type": "warn",
1610
+ "@typescript-eslint/prefer-literal-enum-member": ["error", { allowBitwiseExpressions: true }],
1611
+ "@typescript-eslint/prefer-namespace-keyword": "error",
1612
+ "@typescript-eslint/prefer-readonly-parameter-types": ["off", {
1613
+ checkParameterProperties: true,
1614
+ ignoreInferredTypes: false,
1615
+ treatMethodsAsReadonly: true
1616
+ }],
1617
+ "@typescript-eslint/prefer-readonly": "off",
1618
+ "@typescript-eslint/prefer-readonlysemi": "off",
1619
+ "@typescript-eslint/promise-function-async": "off",
1620
+ "@typescript-eslint/restrict-plus-operands": "warn",
1621
+ "@typescript-eslint/strict-boolean-expressions": "off",
1622
+ "@typescript-eslint/triple-slash-reference": "error",
1623
+ "@typescript-eslint/unified-signatures": "error",
1624
+ ...predicate(projectService, {
1625
+ "@typescript-eslint/await-thenable": "error",
1626
+ "@typescript-eslint/consistent-return": "off",
1627
+ "@typescript-eslint/consistent-type-exports": "warn",
1628
+ "@typescript-eslint/dot-notation": ["warn", {
1629
+ allowPrivateClassPropertyAccess: false,
1630
+ allowProtectedClassPropertyAccess: false,
1631
+ allowIndexSignaturePropertyAccess: true
1632
+ }],
1633
+ "@typescript-eslint/no-base-to-string": "error",
1634
+ "@typescript-eslint/no-confusing-void-expression": ["off", {
1635
+ ignoreArrowShorthand: true,
1636
+ ignoreVoidOperator: true
1637
+ }],
1638
+ "@typescript-eslint/no-duplicate-type-constituents": "warn",
1639
+ "@typescript-eslint/no-deprecated": "error",
1640
+ "@typescript-eslint/no-for-in-array": "error",
1641
+ "@typescript-eslint/no-implied-eval": "error",
1642
+ "@typescript-eslint/no-meaningless-void-operator": ["warn", { checkNever: false }],
1643
+ ...predicate(!options.disableExpensiveRules, {
1644
+ "@typescript-eslint/no-floating-promises": ["error", { ignoreVoid: true }],
1645
+ "@typescript-eslint/no-misused-promises": ["warn", { checksVoidReturn: { attributes: false } }]
1646
+ }),
1647
+ "@typescript-eslint/no-misused-spread": "error",
1648
+ "@typescript-eslint/no-mixed-enums": "error",
1649
+ "@typescript-eslint/no-redundant-type-constituents": "warn",
1650
+ "@typescript-eslint/no-unnecessary-type-conversion": "error",
1651
+ "@typescript-eslint/no-unnecessary-boolean-literal-compare": "error",
1652
+ "@typescript-eslint/no-unsafe-enum-comparison": "warn",
1653
+ "@typescript-eslint/no-unsafe-function-type": "warn",
1654
+ "@typescript-eslint/no-unnecessary-condition": ["warn", { allowConstantLoopConditions: false }],
1655
+ "@typescript-eslint/no-unnecessary-qualifier": "error",
1656
+ "@typescript-eslint/no-unnecessary-template-expression": "warn",
1657
+ "@typescript-eslint/no-unnecessary-type-arguments": "error",
1658
+ "@typescript-eslint/no-unnecessary-type-assertion": "error",
1659
+ "@typescript-eslint/no-unsafe-unary-minus": "error",
1660
+ "@typescript-eslint/no-unused-private-class-members": "warn",
1661
+ "@typescript-eslint/non-nullable-type-assertion-style": "warn",
1662
+ "@typescript-eslint/only-throw-error": ["warn", { allowRethrowing: true }],
1663
+ "@typescript-eslint/prefer-includes": "warn",
1664
+ "@typescript-eslint/prefer-optional-chain": "warn",
1665
+ "@typescript-eslint/prefer-reduce-type-parameter": "warn",
1666
+ "@typescript-eslint/prefer-nullish-coalescing": ["warn", {
1667
+ ignoreConditionalTests: false,
1668
+ ignoreTernaryTests: false,
1669
+ ignoreMixedLogicalExpressions: true
1670
+ }],
1671
+ "@typescript-eslint/prefer-regexp-exec": "warn",
1672
+ "@typescript-eslint/prefer-promise-reject-errors": "warn",
1673
+ "@typescript-eslint/prefer-return-this-type": "warn",
1674
+ "@typescript-eslint/prefer-string-starts-ends-with": "warn",
1675
+ "@typescript-eslint/restrict-template-expressions": ["warn", {
1676
+ allowNumber: true,
1677
+ allowBoolean: false,
1678
+ allowAny: false,
1679
+ allowNullish: false,
1680
+ allowRegExp: false,
1681
+ allowNever: false
1682
+ }],
1683
+ "@typescript-eslint/related-getter-setter-pairs": "error",
1684
+ "@typescript-eslint/require-array-sort-compare": ["error", { ignoreStringArrays: true }],
1685
+ "@typescript-eslint/require-await": "error",
1686
+ "@typescript-eslint/return-await": "error",
1687
+ "@typescript-eslint/switch-exhaustiveness-check": "error",
1688
+ "@typescript-eslint/unbound-method": ["error", { ignoreStatic: true }],
1689
+ "prefer-promise-reject-errors": "off",
1690
+ "consistent-return": "off"
1691
+ }),
1692
+ "no-unused-private-class-members": "off",
1693
+ "no-empty-function": "off",
1694
+ "default-case": "off",
1695
+ "import/named": "off",
1696
+ "import/namespace": "off",
1697
+ "import/default": "off",
1698
+ "import/no-named-as-default-member": "off",
1699
+ "camelcase": "off",
1700
+ "default-param-last": "off",
1701
+ "init-declarations": "off",
1702
+ "no-invalid-this": "off",
1703
+ "no-loop-func": "off",
1704
+ "no-redeclare": "off",
1705
+ "no-restricted-imports": "off",
1706
+ "no-shadow": "off",
1707
+ "no-unused-vars": "off",
1708
+ "no-use-before-define": "off",
1709
+ "no-useless-constructor": "off",
1710
+ "dot-notation": "off",
1711
+ "no-throw-literal": "off",
1712
+ "require-await": "off",
1713
+ "no-undef": "off",
1714
+ "no-duplicate-imports": "off"
1715
+ }
1716
+ };
1717
+ return mergeConfigs(typescriptConfig, overrides);
1718
+ }
1719
+ //#endregion
1720
+ //#region src/modules/vitest.mjs
1721
+ /**
1722
+ * @param { import('../types').Options } options
1723
+ * @return { import('eslint').Linter.Config }
1724
+ */
1725
+ function vitest(options = {}) {
1726
+ const overrides = objectOrEmpty(options.vitest.overrides);
1727
+ /** @type { import('eslint/config').ConfigObject } */
1728
+ const vitestConfig = {
1729
+ name: "vitest",
1730
+ files: globs.test,
1731
+ plugins: { vitest: plugin$11 },
1732
+ languageOptions: { globals: {
1733
+ suite: "writable",
1734
+ test: "writable",
1735
+ describe: "writable",
1736
+ it: "writable",
1737
+ expectTypeOf: "writable",
1738
+ assertType: "writable",
1739
+ expect: "writable",
1740
+ assert: "writable",
1741
+ chai: "writable",
1742
+ vitest: "writable",
1743
+ vi: "writable",
1744
+ beforeAll: "writable",
1745
+ afterAll: "writable",
1746
+ beforeEach: "writable",
1747
+ afterEach: "writable",
1748
+ onTestFailed: "writable",
1749
+ onTestFinished: "writable"
1750
+ } },
1751
+ rules: {
1752
+ "vitest/consistent-test-filename": "off",
1753
+ "vitest/consistent-test-it": "warn",
1754
+ "vitest/consistent-vitest-vi": "warn",
1755
+ "vitest/expect-expect": "warn",
1756
+ "vitest/max-expects": "off",
1757
+ "vitest/max-nested-describe": "off",
1758
+ "vitest/no-alias-methods": "off",
1759
+ "vitest/no-commented-out-tests": "warn",
1760
+ "vitest/no-conditional-expect": "warn",
1761
+ "vitest/no-conditional-in-test": "off",
1762
+ "vitest/no-conditional-tests": "warn",
1763
+ "vitest/no-disabled-tests": "warn",
1764
+ "vitest/no-duplicate-hooks": "error",
1765
+ "vitest/no-focused-tests": "warn",
1766
+ "vitest/no-hooks": "off",
1767
+ "vitest/no-identical-title": "error",
1768
+ "vitest/no-import-node-test": "error",
1769
+ "vitest/no-importing-vitest-globals": "off",
1770
+ "vitest/no-interpolation-in-snapshots": "warn",
1771
+ "vitest/no-large-snapshots": "warn",
1772
+ "vitest/no-mocks-import": "warn",
1773
+ "vitest/no-restricted-matchers": "warn",
1774
+ "vitest/no-restricted-vi-methods": "warn",
1775
+ "vitest/no-standalone-expect": "warn",
1776
+ "vitest/no-test-prefixes": "warn",
1777
+ "vitest/no-test-return-statement": "warn",
1778
+ "vitest/no-unneeded-async-expect-function": "warn",
1779
+ "vitest/prefer-called-once": "warn",
1780
+ "vitest/prefer-called-times": "off",
1781
+ "vitest/prefer-called-with": "warn",
1782
+ "vitest/prefer-comparison-matcher": "warn",
1783
+ "vitest/prefer-describe-function-title": "off",
1784
+ "vitest/prefer-each": "warn",
1785
+ "vitest/prefer-equality-matcher": "warn",
1786
+ "vitest/prefer-expect-assertions": "off",
1787
+ "vitest/prefer-expect-resolves": "warn",
1788
+ "vitest/prefer-hooks-in-order": "warn",
1789
+ "vitest/prefer-hooks-on-top": "warn",
1790
+ "vitest/prefer-importing-vitest-globals": "off",
1791
+ "vitest/prefer-lowercase-title": "off",
1792
+ "vitest/prefer-mock-promise-shorthand": "warn",
1793
+ "vitest/prefer-mock-return-shorthand": "warn",
1794
+ "vitest/prefer-snapshot-hint": "warn",
1795
+ "vitest/prefer-spy-on": "warn",
1796
+ "vitest/prefer-strict-boolean-matchers": "off",
1797
+ "vitest/prefer-strict-equal": "off",
1798
+ "vitest/prefer-to-be": "warn",
1799
+ "vitest/prefer-to-be-falsy": "off",
1800
+ "vitest/prefer-to-be-object": "warn",
1801
+ "vitest/prefer-to-be-truthy": "off",
1802
+ "vitest/prefer-to-contain": "warn",
1803
+ "vitest/prefer-to-have-length": "warn",
1804
+ "vitest/prefer-todo": "warn",
1805
+ "vitest/prefer-vi-mocked": "warn",
1806
+ "vitest/require-hook": "off",
1807
+ "vitest/require-local-test-context-for-concurrent-snapshots": "warn",
1808
+ "vitest/require-mock-type-parameters": "off",
1809
+ "vitest/require-to-throw-message": "warn",
1810
+ "vitest/require-top-level-describe": "off",
1811
+ "vitest/valid-describe-callback": "warn",
1812
+ "vitest/valid-expect": "warn",
1813
+ "vitest/valid-expect-in-promise": "warn",
1814
+ "vitest/valid-title": ["warn", { allowArguments: true }],
1815
+ "vitest/warn-todo": "warn"
1816
+ }
1817
+ };
1818
+ return mergeConfigs(vitestConfig, overrides);
1819
+ }
1820
+ //#endregion
1821
+ //#region src/index.mjs
1822
+ /**
1823
+ * @typedef {import('eslint').Linter.Config} Config
1824
+ * @typedef {import('./types').Options} Options
1825
+ * /
1826
+
1827
+ /** @type {Options} */
1828
+ const defaultOptions = {
1829
+ base: true,
1830
+ promise: true,
1831
+ stylistic: true,
1832
+ cypress: isPackageExists("cypress"),
1833
+ disableExpensiveRules: false,
1834
+ esm: false,
1835
+ ignores: [],
1836
+ gitignore: "./.gitignore",
1837
+ import: {},
1838
+ jest: isPackageExists("jest"),
1839
+ next: isPackageExists("next"),
1840
+ node: false,
1841
+ sort: true,
1842
+ playwright: isPackageExists("@playwright/test"),
1843
+ prettier: isPackageExists("prettier"),
1844
+ react: isPackageExists("react"),
1845
+ storybook: isPackageExists("storybook"),
1846
+ strict: false,
1847
+ tailwind: false,
1848
+ test: [
1849
+ "jest",
1850
+ "vitest",
1851
+ "cypress",
1852
+ "@playwright/test"
1853
+ ].some((p) => isPackageExists(p)),
1854
+ typescript: isPackageExists("typescript") ? { projectService: true } : false,
1855
+ vitest: isPackageExists("vitest"),
1856
+ regex: { allowedCharacterRanges: ["all"] }
1857
+ };
1858
+ /**
1859
+ * Initialize eslint config
1860
+ * @param {Options} initOptions
1861
+ * @param {...Config} extend
1862
+ * @returns {Config[]}
1863
+ */
1864
+ function defineConfig(initOptions = {}, ...extend) {
1865
+ const options = merge(defaultOptions, initOptions);
1866
+ if (options.import === true) options.import = {};
1867
+ if (options.regex === true) options.regex = { allowedCharacterRanges: ["all"] };
1868
+ if (options.typescript === true) options.typescript = { projectService: true };
1869
+ const { base: enableBase, promise: enablePromise, stylistic: enableStylistic, sort: enableSort, cypress: enableCypress, disableExpensiveRules: _disableExpensiveRules, esm: _enableEsm, ignores: _enableIgnores, gitignore: _gitignore, import: enableImport, jest: enableJest, next: enableNext, node: enableNode, playwright: enablePlaywright, prettier: enablePrettier, react: enableReact, storybook: enableStorybook, strict: _enableStrict, tailwind: enableTailwind, test: enableTest, typescript: enableTypescript, vitest: enableVitest, regex: enableRegex, ...eslintOptions } = options;
1870
+ const rules = [ignores(options)];
1871
+ if (enableBase) rules.push(base(options));
1872
+ if (enablePromise) rules.push(promise(options));
1873
+ if (enableStylistic) rules.push(stylistic(options));
1874
+ if (enableSort) rules.push(perfectionist(options));
1875
+ if (enableImport) rules.push(imports(options));
1876
+ if (enableTailwind) rules.push(tailwind(options));
1877
+ if (enableNode) rules.push(node(options));
1878
+ if (enableReact) rules.push(react(options));
1879
+ if (enableStorybook) rules.push(storybook(options));
1880
+ if (enableTypescript) rules.push(typescript(options));
1881
+ if (enableNext) rules.push(next(options));
1882
+ if (enablePrettier) rules.push(prettier(options));
1883
+ if (enableJest) rules.push(jest(options));
1884
+ if (enableVitest) rules.push(vitest(options));
1885
+ if (enableTest) rules.push(tests(options));
1886
+ if (enableCypress) rules.push(cypress(options));
1887
+ if (enablePlaywright) rules.push(playwright(options));
1888
+ if (enableRegex) rules.push(regex(options));
1889
+ if (Object.keys(eslintOptions).length > 0) rules.push(eslintOptions);
1890
+ if (extend) Array.prototype.push.apply(rules, extend);
1891
+ return defineConfig$1(rules);
1892
+ }
1893
+ //#endregion
1894
+ export { defineConfig };