@w5s/eslint-config 3.3.0 → 3.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@w5s/eslint-config",
3
- "version": "3.3.0",
3
+ "version": "3.3.2",
4
4
  "description": "ESLint configuration presets",
5
5
  "keywords": [
6
6
  "eslint",
@@ -62,8 +62,8 @@
62
62
  "@typescript-eslint/eslint-plugin": "^8.0.0",
63
63
  "@typescript-eslint/parser": "^8.0.0",
64
64
  "@vitest/eslint-plugin": "^1.0.0",
65
- "@w5s/dev": "^3.1.2",
66
- "@w5s/prettier-config": "^3.0.4",
65
+ "@w5s/dev": "^3.1.4",
66
+ "@w5s/prettier-config": "^3.0.5",
67
67
  "eslint-plugin-import": "^2.25.0",
68
68
  "eslint-plugin-jsdoc": "^62.0.0",
69
69
  "eslint-plugin-jsonc": "^2.4.0",
@@ -80,10 +80,10 @@
80
80
  "@types/eslint": "9.6.1",
81
81
  "@types/parse-gitignore": "1.0.2",
82
82
  "@types/react": "19.2.14",
83
- "@typescript-eslint/parser": "8.55.0",
83
+ "@typescript-eslint/parser": "8.56.0",
84
84
  "eslint": "9.39.2",
85
85
  "eslint-find-rules": "5.0.0",
86
- "eslint-typegen": "2.3.0",
86
+ "eslint-typegen": "2.3.1",
87
87
  "react": "19.2.4",
88
88
  "vite": "7.3.1",
89
89
  "vitest": "4.0.18"
@@ -108,5 +108,5 @@
108
108
  "access": "public"
109
109
  },
110
110
  "sideEffect": false,
111
- "gitHead": "1339ba15448ca7c3aea9f0afa0ece486f4693961"
111
+ "gitHead": "6d0fd278d32187d231f63936bc50b87baebcf34c"
112
112
  }
package/src/config/es.ts CHANGED
@@ -3,14 +3,11 @@ import eslintConfig from '@eslint/js';
3
3
  import { Project } from '@w5s/dev';
4
4
  import { type PluginOptionsBase, type Config } from '../type.js';
5
5
  import type { RuleOptions } from '../typegen/jsonc.js';
6
- import { createRules } from './createRules.js';
7
6
  import { esRules } from '../rules/esRules.js';
8
7
 
9
8
  const defaultFiles = [`**/${Project.extensionsToGlob(Project.queryExtensions(['javascript', 'javascriptreact']))}`];
10
9
 
11
- export async function es(
12
- options: es.Options,
13
- ) {
10
+ export async function es(options: es.Options) {
14
11
  const { rules = {} } = options;
15
12
 
16
13
  return [
@@ -47,7 +44,6 @@ export async function es(
47
44
  files: defaultFiles,
48
45
  rules: {
49
46
  ...eslintConfig.configs.recommended.rules,
50
- ...createRules(''),
51
47
  ...esRules(),
52
48
  ...rules,
53
49
  },
@@ -1,22 +1,28 @@
1
+ import { interopDefault } from '@w5s/dev';
1
2
  import { PluginOptionsBase, StylisticConfig, type Config } from '../type.js';
2
- import type { RuleOptions } from '../typegen/import.js';
3
- // @ts-ignore
4
- import importPlugin from 'eslint-plugin-import';
5
-
6
- const importConfig = importPlugin.flatConfigs['recommended'];
3
+ import { type RuleOptions } from '../typegen/import.js';
7
4
 
8
5
  export async function imports(options: imports.Options = {}) {
9
6
  const { rules = {}, stylistic = true } = options;
10
7
  const { enabled: stylisticEnabled } = StylisticConfig.from(stylistic);
8
+ const [importPlugin] = await Promise.all([interopDefault(import('eslint-plugin-import'))] as const);
11
9
  return [
12
10
  {
13
11
  name: 'w5s/import/rules',
14
- plugins: importConfig.plugins ?? {},
12
+ plugins: {
13
+ import: importPlugin,
14
+ },
15
15
  rules: {
16
- ...(importConfig?.rules),
16
+ // 'import/consistent-type-specifier-style': ['error', 'prefer-inline'],
17
+ 'import/first': 'error',
18
+ 'import/no-duplicates': 'error',
19
+ 'import/no-mutable-exports': 'error',
20
+ 'import/no-named-default': 'error',
21
+
17
22
  ...(stylisticEnabled
18
23
  ? {
19
24
  // Stylistic rules
25
+ 'import/newline-after-import': ['error', { count: 1 }],
20
26
  }
21
27
  : {}),
22
28
  ...rules,
@@ -3,9 +3,7 @@ import { StylisticConfig, type PluginOptionsBase, type Config } from '../type.js
3
3
  import type { RuleOptions } from '../typegen/jsdoc.js';
4
4
 
5
5
  export async function jsdoc(options: jsdoc.Options = {}): Promise<readonly Config[]> {
6
- const [jsdocPlugin] = await Promise.all([
7
- interopDefault(import('eslint-plugin-jsdoc')),
8
- ] as const);
6
+ const [jsdocPlugin] = await Promise.all([interopDefault(import('eslint-plugin-jsdoc'))] as const);
9
7
  const { rules = {}, stylistic = true } = options;
10
8
  const { enabled: stylisticEnabled } = StylisticConfig.from(stylistic);
11
9
 
@@ -19,20 +17,21 @@ export async function jsdoc(options: jsdoc.Options = {}): Promise<readonly Confi
19
17
  {
20
18
  name: 'w5s/jsdoc/rules',
21
19
  rules: {
22
- ...(jsdocPlugin.configs['flat/recommended'].rules),
20
+ ...jsdocPlugin.configs['flat/recommended-typescript-flavor'].rules,
23
21
  'jsdoc/no-undefined-types': 'off', // https://github.com/gajus/eslint-plugin-jsdoc/issues/839
24
22
  'jsdoc/require-hyphen-before-param-description': ['warn', 'always'],
25
23
  'jsdoc/require-jsdoc': 'off',
26
24
  'jsdoc/require-param-description': 'off',
25
+ 'jsdoc/require-param-type': 'off',
27
26
  'jsdoc/require-returns': 'off',
28
- 'jsdoc/tag-lines': ['warn', 'any', { startLines: 1 }],
29
27
  'jsdoc/valid-types': 'off', // FIXME: reports lots of false positive
30
28
  // 'strict': ['error', 'safe'],
31
29
  ...(stylisticEnabled
32
30
  ? {
33
- // ...(jsdocPlugin.configs['flat/stylistic'].rules),
31
+ ...jsdocPlugin.configs['flat/stylistic-typescript'].rules,
34
32
  'jsdoc/check-alignment': 'warn',
35
33
  'jsdoc/multiline-blocks': 'warn',
34
+ 'jsdoc/tag-lines': ['warn', 'any', { startLines: 1 }],
36
35
  }
37
36
  : {}),
38
37
  ...rules,
package/src/config/ts.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  import { ESLintConfig, interopDefault, Project } from '@w5s/dev';
3
3
  import { StylisticConfig, type PluginOptionsBase, type Config } from '../type.js';
4
4
  import type { RuleOptions } from '../typegen/ts.js';
5
- import { createRules } from './createRules.js';
5
+ import { tsRules } from '../rules/tsRules.js';
6
6
 
7
7
  const defaultFiles = [`**/${Project.extensionsToGlob(Project.queryExtensions(['typescript', 'typescriptreact']))}`];
8
8
 
@@ -45,48 +45,26 @@ export async function ts(options: ts.Options = {}) {
45
45
  },
46
46
  name: 'w5s/ts/rules',
47
47
  rules: {
48
- ...ESLintConfig.renameRules(
49
- tsRecommendedRules,
50
- { '@typescript-eslint': 'ts' },
51
- ),
52
- ...ESLintConfig.renameRules(
53
- tsStrictRules,
54
- { '@typescript-eslint': 'ts' },
55
- ),
56
- 'ts/ban-ts-comment': [
57
- 'warn',
58
- {
59
- 'minimumDescriptionLength': 3,
60
- 'ts-check': false,
61
- 'ts-expect-error': 'allow-with-description',
62
- 'ts-ignore': 'allow-with-description',
63
- 'ts-nocheck': true,
64
- },
65
- ],
66
- 'ts/no-empty-object-type': 'off',
67
- 'ts/no-explicit-any': 'off', // if any is explicit then it's wanted
68
- 'ts/no-namespace': 'off', // We don't agree with community, namespaces are great and not deprecated
69
- ...createRules('ts/'),
70
- ...(stylisticEnabled
71
- ? {}
72
- : {}),
48
+ ...ESLintConfig.renameRules(tsRecommendedRules, { '@typescript-eslint': 'ts' }),
49
+ ...ESLintConfig.renameRules(tsStrictRules, { '@typescript-eslint': 'ts' }),
50
+ ...tsRules(),
51
+ ...(stylisticEnabled ? {} : {}),
73
52
  ...rules,
74
53
  },
75
54
  },
76
55
  ...(typeChecked
77
- ? [{
78
- files: defaultFiles,
79
- // ignores: ignoresTypeAware,
80
- name: 'w5s/ts/rules-type-checked',
81
- rules: {
82
- ...ESLintConfig.renameRules(
83
- tsTypeCheckedRules,
84
- { '@typescript-eslint': 'ts' },
85
- ),
56
+ ? ([
57
+ {
58
+ files: defaultFiles,
59
+ // ignores: ignoresTypeAware,
60
+ name: 'w5s/ts/rules-type-checked',
61
+ rules: {
62
+ ...ESLintConfig.renameRules(tsTypeCheckedRules, { '@typescript-eslint': 'ts' }),
63
+ },
86
64
  },
87
- }] as const
65
+ ] as const)
88
66
  : []),
89
- ] as ([Config, Config] | [Config, Config, Config]) satisfies Array<Config>;
67
+ ] as [Config, Config] | [Config, Config, Config] satisfies Array<Config>;
90
68
  }
91
69
  export namespace ts {
92
70
  export type Rules = RuleOptions;
@@ -14,9 +14,15 @@ export interface DefineConfigOptions extends ignores.Options {
14
14
  }
15
15
 
16
16
  export async function defineConfig(options: DefineConfigOptions = {}) {
17
- const stylisticOptions = typeof options.stylistic === 'boolean' ? { enabled: options.stylistic } : { enabled: true, ...options.stylistic };
18
- const withDefaultStylistic = <T>(options: T) => ({ stylistic: stylisticOptions, ...options });
19
- const toOption = <T extends {}>(optionsOrBoolean: T | boolean | undefined) => withDefaultStylistic((typeof optionsOrBoolean === 'boolean' ? { enabled: optionsOrBoolean } : ({ enabled: true, ...optionsOrBoolean })) as T & { enabled: boolean });
17
+ const stylisticOptions =
18
+ typeof options.stylistic === 'boolean' ? { enabled: options.stylistic } : { enabled: true, ...options.stylistic };
19
+ const withDefaultStylistic = <T>(_options: T) => ({ stylistic: stylisticOptions, ..._options });
20
+ const toOption = <T extends {}>(optionsOrBoolean: T | boolean | undefined) =>
21
+ withDefaultStylistic(
22
+ (typeof optionsOrBoolean === 'boolean'
23
+ ? { enabled: optionsOrBoolean }
24
+ : { enabled: true, ...optionsOrBoolean }) as T & { enabled: boolean },
25
+ );
20
26
  const esOptions = toOption(options.es);
21
27
  const importOptions = toOption(options.import);
22
28
  const jsdocOptions = toOption(options.jsdoc);
@@ -0,0 +1,132 @@
1
+ import { ESLintConfig } from '@w5s/dev';
2
+ import { esRules } from './esRules.js';
3
+
4
+ export const tsRules = () => {
5
+ const baseRules = esRules();
6
+
7
+ return ESLintConfig.renameRules(
8
+ {
9
+ // '@typescript-eslint/comma-dangle': [
10
+ // baseRules['comma-dangle'][0],
11
+ // {
12
+ // ...baseRules['comma-dangle'][1],
13
+ // enums: baseRules['comma-dangle'][1].arrays,
14
+ // generics: baseRules['comma-dangle'][1].arrays,
15
+ // tuples: baseRules['comma-dangle'][1].arrays,
16
+ // },
17
+ // ],
18
+ '@typescript-eslint/adjacent-overload-signatures': 'error',
19
+ '@typescript-eslint/ban-ts-comment': [
20
+ 'warn',
21
+ {
22
+ 'minimumDescriptionLength': 3,
23
+ 'ts-check': false,
24
+ 'ts-expect-error': 'allow-with-description',
25
+ 'ts-ignore': 'allow-with-description',
26
+ 'ts-nocheck': true,
27
+ },
28
+ ],
29
+ // '@typescript-eslint/brace-style': baseRules['brace-style'],
30
+ // '@typescript-eslint/comma-dangle': [
31
+ // baseRules['comma-dangle'][0],
32
+ // {
33
+ // ...baseRules['comma-dangle'][1],
34
+ // enums: baseRules['comma-dangle'][1].arrays,
35
+ // generics: baseRules['comma-dangle'][1].arrays,
36
+ // tuples: baseRules['comma-dangle'][1].arrays,
37
+ // },
38
+ // ],
39
+ // '@typescript-eslint/comma-spacing': baseRules['comma-spacing'],
40
+ '@typescript-eslint/consistent-type-assertions': [
41
+ 'error',
42
+ { assertionStyle: 'as', objectLiteralTypeAssertions: 'never' },
43
+ ],
44
+ '@typescript-eslint/default-param-last': baseRules['default-param-last'],
45
+ // '@typescript-eslint/dot-notation': baseRules['dot-notation'], // TODO: Stylistic typechecked
46
+ '@typescript-eslint/explicit-function-return-type': 'off',
47
+ '@typescript-eslint/explicit-module-boundary-types': 'off',
48
+ // '@typescript-eslint/func-call-spacing': baseRules['func-call-spacing'],
49
+ // '@typescript-eslint/indent': baseRules.indent,
50
+ // '@typescript-eslint/keyword-spacing': baseRules['keyword-spacing'],
51
+ // '@typescript-eslint/lines-between-class-members': baseRules['lines-between-class-members'],
52
+ // '@typescript-eslint/member-delimiter-style': 'error', // TODO: @stylistic/member-delimiter-style
53
+ '@typescript-eslint/naming-convention': [
54
+ 'error',
55
+ // {
56
+ // format: ['PascalCase', 'camelCase'],
57
+ // leadingUnderscore: 'allow',
58
+ // selector: 'default',
59
+ // trailingUnderscore: 'allow',
60
+ // },
61
+ {
62
+ format: ['PascalCase', 'camelCase', 'UPPER_CASE'],
63
+ leadingUnderscore: 'allow',
64
+ selector: 'variable',
65
+ trailingUnderscore: 'allow',
66
+ },
67
+ // {
68
+ // format: ['PascalCase', 'camelCase', 'UPPER_CASE'],
69
+ // leadingUnderscore: 'allowSingleOrDouble',
70
+ // selector: 'memberLike',
71
+ // trailingUnderscore: 'allowDouble',
72
+ // },
73
+ {
74
+ format: ['PascalCase'],
75
+ selector: 'typeLike',
76
+ },
77
+ ],
78
+ // '@typescript-eslint/no-array-constructor': baseRules['no-array-constructor'],
79
+ // '@typescript-eslint/no-base-to-string': 'error', // TODO: require type check
80
+ '@typescript-eslint/no-dupe-class-members': baseRules['no-dupe-class-members'],
81
+ '@typescript-eslint/no-empty-function': baseRules['no-empty-function'],
82
+ '@typescript-eslint/no-empty-interface': ['error', { allowSingleExtends: true }],
83
+ '@typescript-eslint/no-empty-object-type': 'off',
84
+ '@typescript-eslint/no-explicit-any': 'off', // if any is explicit then it's wanted
85
+ '@typescript-eslint/no-extra-parens': baseRules['no-extra-parens'],
86
+ // '@typescript-eslint/no-extra-semi': baseRules['no-extra-semi'], // TODO: @stylistic/no-extra-semi
87
+ '@typescript-eslint/no-inferrable-types': 'error',
88
+ '@typescript-eslint/no-loop-func': baseRules['no-loop-func'],
89
+ '@typescript-eslint/no-loss-of-precision': baseRules['no-loss-of-precision'],
90
+ '@typescript-eslint/no-magic-numbers': baseRules['no-magic-numbers'],
91
+ '@typescript-eslint/no-misused-new': 'error',
92
+ '@typescript-eslint/no-namespace': 'off', // We don't agree with community, namespaces are great and not deprecated
93
+ '@typescript-eslint/no-non-null-assertion': 'error',
94
+ '@typescript-eslint/no-redeclare': ESLintConfig.fixme(baseRules['no-redeclare']),
95
+ '@typescript-eslint/no-require-imports': 'error',
96
+ '@typescript-eslint/no-shadow': baseRules['no-shadow'],
97
+ '@typescript-eslint/no-this-alias': 'error',
98
+ // '@typescript-eslint/no-unnecessary-condition': 'error',// TODO: require type check
99
+ // '@typescript-eslint/no-unsafe-argument': 'error', // TODO: recommended type check
100
+ '@typescript-eslint/no-unused-expressions': baseRules['no-unused-expressions'],
101
+ '@typescript-eslint/no-unused-vars': baseRules['no-unused-vars'],
102
+ '@typescript-eslint/no-use-before-define': baseRules['no-use-before-define'],
103
+ '@typescript-eslint/no-useless-constructor': baseRules['no-useless-constructor'],
104
+ '@typescript-eslint/no-var-requires': 'error',
105
+ '@typescript-eslint/no-wrapper-object-types': 'error',
106
+ // '@typescript-eslint/object-curly-spacing': baseRules['object-curly-spacing'],
107
+ // '@typescript-eslint/only-throw-error': baseRules['no-throw-literal'], //TODO: Recommended type check
108
+ '@typescript-eslint/prefer-namespace-keyword': 'error',
109
+ // '@typescript-eslint/prefer-reduce-type-parameter': 'error', // TODO: strict type check
110
+ // '@typescript-eslint/quotes': baseRules.quotes,
111
+ '@typescript-eslint/require-await': baseRules['require-await'],
112
+ // '@typescript-eslint/return-await': baseRules['no-return-await'], // TODO: strict type check
113
+ // '@typescript-eslint/semi': baseRules.semi,
114
+ // '@typescript-eslint/space-before-function-paren': baseRules['space-before-function-paren'],
115
+ // '@typescript-eslint/space-infix-ops': baseRules['space-infix-ops'],
116
+ // '@typescript-eslint/strict-boolean-expressions': [
117
+ // 'error',
118
+ // {
119
+ // allowNullableObject: false,
120
+ // allowNumber: false,
121
+ // allowString: false,
122
+ // },
123
+ // ], //TODO: require typing
124
+ // '@typescript-eslint/switch-exhaustiveness-check': 'error',//TODO: require type check
125
+ '@typescript-eslint/triple-slash-reference': 'error',
126
+ // '@typescript-eslint/type-annotation-spacing': 'error',// TODO: @stylistic/type-annotation-spacing
127
+ },
128
+ {
129
+ '@typescript-eslint': 'ts',
130
+ },
131
+ );
132
+ };
@@ -3,10 +3,12 @@ import type { StylisticParameters } from './StylisticConfig.js';
3
3
 
4
4
  export interface PluginOptionsBase<Rules> {
5
5
  files?: Linter.Config['files'];
6
+
6
7
  /**
7
8
  * Plugin rules
8
9
  */
9
10
  rules?: Rules;
11
+
10
12
  /**
11
13
  * Stylistic options
12
14
  */
@@ -1,9 +0,0 @@
1
- import { ESLintConfig } from '@w5s/dev';
2
-
3
- export function createRules(prefix: string) {
4
- return ESLintConfig.renameRules({
5
- 'no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
6
- }, {
7
- '': prefix,
8
- });
9
- }