@fullstacksjs/eslint-config 14.6.0 → 14.8.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 (48) hide show
  1. package/README.md +1 -1
  2. package/cjs/modules/base.js +3 -1
  3. package/cjs/modules/cypress.js +3 -1
  4. package/cjs/modules/imports.js +3 -1
  5. package/cjs/modules/jest.js +3 -1
  6. package/cjs/modules/next.js +3 -1
  7. package/cjs/modules/node.js +4 -2
  8. package/cjs/modules/perfectionist.js +3 -1
  9. package/cjs/modules/playwright.js +3 -1
  10. package/cjs/modules/prettier.js +3 -7
  11. package/cjs/modules/promise.js +3 -1
  12. package/cjs/modules/react.js +46 -28
  13. package/cjs/modules/regex.js +8 -2
  14. package/cjs/modules/storybook.js +3 -1
  15. package/cjs/modules/stylistic.js +3 -1
  16. package/cjs/modules/tailwind.js +11 -3
  17. package/cjs/modules/tests.js +3 -1
  18. package/cjs/modules/typescript.js +4 -12
  19. package/cjs/modules/vitest.js +3 -2
  20. package/cjs/types/modules/react.d.ts +5 -0
  21. package/cjs/types/modules/regex.d.ts +1 -1
  22. package/cjs/types/modules/tailwind.d.ts +2 -9
  23. package/cjs/utils/nextAllowExportNames.js +7 -0
  24. package/cjs/utils/objectOrEmpty.js +14 -0
  25. package/package.json +26 -26
  26. package/src/modules/base.mjs +4 -1
  27. package/src/modules/cypress.mjs +4 -1
  28. package/src/modules/imports.mjs +3 -1
  29. package/src/modules/jest.mjs +3 -1
  30. package/src/modules/next.mjs +5 -1
  31. package/src/modules/node.mjs +5 -2
  32. package/src/modules/perfectionist.mjs +5 -1
  33. package/src/modules/playwright.mjs +4 -1
  34. package/src/modules/prettier.mjs +5 -7
  35. package/src/modules/promise.mjs +4 -1
  36. package/src/modules/react.mjs +49 -27
  37. package/src/modules/regex.mjs +10 -2
  38. package/src/modules/storybook.mjs +4 -1
  39. package/src/modules/stylistic.mjs +5 -1
  40. package/src/modules/tailwind.mjs +13 -4
  41. package/src/modules/tests.mjs +4 -1
  42. package/src/modules/typescript.mjs +3 -8
  43. package/src/modules/vitest.mjs +4 -2
  44. package/src/types/modules/react.d.ts +5 -0
  45. package/src/types/modules/regex.d.ts +1 -1
  46. package/src/types/modules/tailwind.d.ts +2 -9
  47. package/src/utils/nextAllowExportNames.mjs +17 -0
  48. package/src/utils/objectOrEmpty.mjs +8 -0
@@ -2,12 +2,15 @@ import { mergeConfigs } from 'eslint-flat-config-utils';
2
2
  import plugin from 'eslint-plugin-storybook';
3
3
 
4
4
  import { globs } from '../utils/globs.mjs';
5
+ import { objectOrEmpty } from '../utils/objectOrEmpty.mjs';
5
6
 
6
7
  /**
7
8
  * @param { import('../types').Options } options
8
9
  * @return { Promise<import('eslint').Linter.Config> }
9
10
  */
10
11
  function storybook(options = {}) {
12
+ const overrides = objectOrEmpty(options.storybook.overrides);
13
+
11
14
  const storybookConfig = {
12
15
  name: 'storybook',
13
16
  files: globs.storybook,
@@ -38,7 +41,7 @@ function storybook(options = {}) {
38
41
  },
39
42
  };
40
43
 
41
- return mergeConfigs(storybookConfig, options.storybook.overrides ?? {});
44
+ return mergeConfigs(storybookConfig, overrides);
42
45
  }
43
46
 
44
47
  export default storybook;
@@ -1,11 +1,15 @@
1
1
  import stylisticPlugin from '@stylistic/eslint-plugin';
2
2
  import { mergeConfigs } from 'eslint-flat-config-utils';
3
3
 
4
+ import { objectOrEmpty } from '../utils/objectOrEmpty.mjs';
5
+
4
6
  /**
5
7
  * @param { import('../types').Options } options
6
8
  * @return { Promise<import('eslint').Linter.Config> }
7
9
  */
8
10
  function stylistic(options = {}) {
11
+ const overrides = objectOrEmpty(options.stylistic.overrides);
12
+
9
13
  const stylisticConfig = {
10
14
  name: 'stylistic',
11
15
  plugins: { '@stylistic': stylisticPlugin },
@@ -44,7 +48,7 @@ function stylistic(options = {}) {
44
48
  ],
45
49
  },
46
50
  };
47
- return mergeConfigs(stylisticConfig, options.stylistic.overrides ?? {});
51
+ return mergeConfigs(stylisticConfig, overrides);
48
52
  }
49
53
 
50
54
  export default stylistic;
@@ -1,6 +1,7 @@
1
1
  import { mergeConfigs } from 'eslint-flat-config-utils';
2
2
 
3
- import { strict } from '../utils/conditions.mjs';
3
+ import { predicate, strict } from '../utils/conditions.mjs';
4
+ import { objectOrEmpty } from '../utils/objectOrEmpty.mjs';
4
5
 
5
6
  /**
6
7
  * @param { import('../types').Options } options
@@ -8,13 +9,20 @@ import { strict } from '../utils/conditions.mjs';
8
9
  */
9
10
  async function tailwind(options = {}) {
10
11
  const plugin = await import('eslint-plugin-better-tailwindcss');
12
+ const isObject = typeof options.tailwind === 'object';
13
+ const overrides = objectOrEmpty(options.tailwind.overrides);
14
+
11
15
  const tailwindConfig = {
12
16
  name: 'tailwind',
13
17
  plugins: { 'better-tailwindcss': plugin.default ?? plugin },
14
18
  settings: {
15
19
  'better-tailwindcss': {
16
- entryPoint: options.tailwind.entryPoint,
17
- tailwindConfig: options.tailwind.tailwindConfig,
20
+ ...predicate(isObject && 'entryPoint' in options.tailwind, {
21
+ entryPoint: options.tailwind.entryPoint,
22
+ }),
23
+ ...predicate(isObject && 'tailwindConfig' in options.tailwind, {
24
+ tailwindConfig: options.tailwind.tailwindConfig,
25
+ }),
18
26
  callees: [
19
27
  ['^class|classnames|classNames|cva|ctl|clsx|cn|cns|cx|cc|clb|cnb|dcnb|objstr|tv|twJoin|twMerge$', [{ match: 'strings' }]],
20
28
  ],
@@ -29,6 +37,7 @@ async function tailwind(options = {}) {
29
37
  'better-tailwindcss/enforce-consistent-variant-order': 'warn',
30
38
  'better-tailwindcss/enforce-logical-properties': strict('warn'),
31
39
  'better-tailwindcss/enforce-shorthand-classes': 'warn',
40
+ 'better-tailwindcss/no-concatenated-classes': 'error',
32
41
  'better-tailwindcss/no-conflicting-classes': 'error',
33
42
  'better-tailwindcss/no-deprecated-classes': 'warn',
34
43
  'better-tailwindcss/no-duplicate-classes': 'error',
@@ -38,7 +47,7 @@ async function tailwind(options = {}) {
38
47
  },
39
48
  };
40
49
 
41
- return mergeConfigs(tailwindConfig, options.tailwind.overrides ?? {});
50
+ return mergeConfigs(tailwindConfig, overrides);
42
51
  }
43
52
 
44
53
  export default tailwind;
@@ -4,6 +4,7 @@ import globals from 'globals';
4
4
 
5
5
  import { predicate } from '../utils/conditions.mjs';
6
6
  import { globs } from '../utils/globs.mjs';
7
+ import { objectOrEmpty } from '../utils/objectOrEmpty.mjs';
7
8
 
8
9
  /**
9
10
  * @param { import('../types').Options } options
@@ -11,6 +12,8 @@ import { globs } from '../utils/globs.mjs';
11
12
  */
12
13
 
13
14
  function tests(options = {}) {
15
+ const overrides = objectOrEmpty(options.test.overrides);
16
+
14
17
  const testsConfug = {
15
18
  name: 'tests',
16
19
  files: [...globs.test, ...globs.e2e],
@@ -40,7 +43,7 @@ function tests(options = {}) {
40
43
  },
41
44
  };
42
45
 
43
- return mergeConfigs(testsConfug, options.test.overrides ?? {});
46
+ return mergeConfigs(testsConfug, overrides);
44
47
  }
45
48
 
46
49
  export default tests;
@@ -4,6 +4,7 @@ import { parser, plugin } from 'typescript-eslint';
4
4
  import { predicate, strict } from '../utils/conditions.mjs';
5
5
  import { globs } from '../utils/globs.mjs';
6
6
  import { namingConvention } from '../utils/naming-convention.mjs';
7
+ import { objectOrEmpty } from '../utils/objectOrEmpty.mjs';
7
8
 
8
9
  /**
9
10
  * @param { import('../types').Options } options
@@ -11,6 +12,7 @@ import { namingConvention } from '../utils/naming-convention.mjs';
11
12
  */
12
13
  function typescript(options = {}) {
13
14
  const projectService = options.typescript && options.typescript.tsconfigRootDir && options.typescript.projectService;
15
+ const overrides = objectOrEmpty(options.typescript.overrides);
14
16
 
15
17
  const typescriptConfig = {
16
18
  name: 'typescript',
@@ -137,12 +139,9 @@ function typescript(options = {}) {
137
139
  '@typescript-eslint/promise-function-async': 'off', // Breaks react component when return type is React.ReactNode
138
140
  '@typescript-eslint/restrict-plus-operands': 'warn',
139
141
  '@typescript-eslint/strict-boolean-expressions': 'off', // Annoying
140
- '@typescript-eslint/space-before-blocks': 'off',
141
142
 
142
143
  '@typescript-eslint/triple-slash-reference': 'error',
143
- '@typescript-eslint/typedef': ['error', { parameter: false, arrowParameter: false, variableDeclaration: false }],
144
144
  '@typescript-eslint/unified-signatures': 'error',
145
- '@typescript-eslint/key-spacing': 'off',
146
145
 
147
146
  ...predicate(projectService, {
148
147
  '@typescript-eslint/await-thenable': 'error',
@@ -227,7 +226,6 @@ function typescript(options = {}) {
227
226
  'import/namespace': 'off',
228
227
  'import/default': 'off',
229
228
  'import/no-named-as-default-member': 'off',
230
- 'key-spacing': 'off',
231
229
  'camelcase': 'off',
232
230
  'default-param-last': 'off',
233
231
  'init-declarations': 'off',
@@ -239,9 +237,6 @@ function typescript(options = {}) {
239
237
  'no-unused-vars': 'off',
240
238
  'no-use-before-define': 'off',
241
239
  'no-useless-constructor': 'off',
242
- 'object-curly-spacing': 'off',
243
- 'padding-line-between-statements': 'off',
244
- 'space-before-blocks': 'off',
245
240
  'dot-notation': 'off',
246
241
  'no-throw-literal': 'off',
247
242
  'require-await': 'off',
@@ -250,7 +245,7 @@ function typescript(options = {}) {
250
245
  },
251
246
  };
252
247
 
253
- return mergeConfigs(typescriptConfig, options.typescript.overrides ?? {});
248
+ return mergeConfigs(typescriptConfig, overrides);
254
249
  }
255
250
 
256
251
  export default typescript;
@@ -2,12 +2,15 @@ import plugin from '@vitest/eslint-plugin';
2
2
  import { mergeConfigs } from 'eslint-flat-config-utils';
3
3
 
4
4
  import { globs } from '../utils/globs.mjs';
5
+ import { objectOrEmpty } from '../utils/objectOrEmpty.mjs';
5
6
 
6
7
  /**
7
8
  * @param { import('../types').Options } options
8
9
  * @return { import('eslint').Linter.Config }
9
10
  */
10
11
  function vitest(options = {}) {
12
+ const overrides = objectOrEmpty(options.vitest.overrides);
13
+
11
14
  const vitestConfig = {
12
15
  name: 'vitest',
13
16
  files: globs.test,
@@ -46,7 +49,6 @@ function vitest(options = {}) {
46
49
  'vitest/no-conditional-in-test': 'off',
47
50
  'vitest/no-conditional-tests': 'warn',
48
51
  'vitest/no-disabled-tests': 'warn',
49
- 'vitest/no-done-callback': 'off',
50
52
  'vitest/no-duplicate-hooks': 'error',
51
53
  'vitest/no-focused-tests': 'warn',
52
54
  'vitest/no-hooks': 'off',
@@ -103,7 +105,7 @@ function vitest(options = {}) {
103
105
  },
104
106
  };
105
107
 
106
- return mergeConfigs(vitestConfig, options.vitest.overrides ?? {});
108
+ return mergeConfigs(vitestConfig, overrides);
107
109
  }
108
110
 
109
111
  export default vitest;
@@ -1,5 +1,10 @@
1
1
  import type { ConfigWithOverrides } from '..';
2
2
 
3
3
  interface ReactOptions extends ConfigWithOverrides {
4
+ version?: string;
5
+ importSource?: string;
6
+ compilationMode?: 'all' | 'annotation' | 'infer' | 'syntax'; // Use the same compilationMode as the React Compiler config for consistent analysis
7
+ polymorphicPropName?: string;
8
+ additionalStateHooks?: string;
4
9
  additionalEffectHooks?: string;
5
10
  }
@@ -1,5 +1,5 @@
1
1
  import type { ConfigWithOverrides } from '..';
2
2
 
3
3
  interface RegexOptions extends ConfigWithOverrides {
4
- allowedCharacterRanges: string[];
4
+ allowedCharacterRanges?: string[];
5
5
  }
@@ -1,18 +1,11 @@
1
1
  import type { ConfigWithOverrides } from '..';
2
2
 
3
- interface TailwindOptionsBase extends ConfigWithOverrides {
4
- callees?: string[];
5
- variables?: string[];
6
- attributes?: string[];
7
- tags?: string[];
8
- }
9
-
10
- interface TailwindOptionsWithEntryPoint extends TailwindOptionsBase {
3
+ interface TailwindOptionsWithEntryPoint extends ConfigWithOverrides {
11
4
  entryPoint: string;
12
5
  tailwindConfig?: string;
13
6
  }
14
7
 
15
- interface TailwindOptionsWithConfig extends TailwindOptionsBase {
8
+ interface TailwindOptionsWithConfig extends ConfigWithOverrides {
16
9
  entryPoint?: string;
17
10
  tailwindConfig: string;
18
11
  }
@@ -0,0 +1,17 @@
1
+ export const nextAllowExportNames = [
2
+ 'experimental_ppr',
3
+ 'dynamic',
4
+ 'dynamicParams',
5
+ 'revalidate',
6
+ 'fetchCache',
7
+ 'runtime',
8
+ 'preferredRegion',
9
+ 'maxDuration',
10
+ 'metadata',
11
+ 'generateMetadata',
12
+ 'viewport',
13
+ 'generateViewport',
14
+ 'generateImageMetadata',
15
+ 'generateSitemaps',
16
+ 'generateStaticParams',
17
+ ];
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @template T
3
+ * @param {T | null | undefined} value
4
+ * @returns {T | {}}
5
+ */
6
+ export function objectOrEmpty(value) {
7
+ return typeof value === 'object' && value !== null ? value : {};
8
+ }