@w5s/eslint-config 1.0.0-alpha.3 → 1.0.0-alpha.30

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/es.js CHANGED
@@ -2,6 +2,7 @@
2
2
  module.exports = {
3
3
  extends: [
4
4
  require.resolve('./rules/base'),
5
+ require.resolve('./rules/promise'),
5
6
  require.resolve('./rules/jsdoc'),
6
7
  require.resolve('./rules/import'),
7
8
  require.resolve('./rules/unicorn'),
@@ -11,7 +12,7 @@ module.exports = {
11
12
  parser: '@babel/eslint-parser',
12
13
  parserOptions: {
13
14
  babelOptions: {
14
- plugins: ['@babel/plugin-syntax-class-properties', '@babel/plugin-syntax-jsx'],
15
+ plugins: [],
15
16
  },
16
17
  ecmaFeatures: {
17
18
  jsx: true,
package/functional.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // @see https://github.com/danielnixon/eslint-config-typed-fp/blob/master/src/index.ts
2
2
 
3
- const { off, error } = require('./rules/_rule');
3
+ const { off, error } = require('./rules/_rule.js');
4
4
 
5
5
  module.exports = {
6
6
  overrides: [
package/ignore.js ADDED
@@ -0,0 +1,3 @@
1
+ module.exports = {
2
+ ignorePatterns: ['**/dist/**', '**/lib/**'],
3
+ };
package/index.js CHANGED
@@ -1,11 +1,37 @@
1
1
  // http://eslint.org/docs/user-guide/configuring
2
+ /**
3
+ * @param {string} name
4
+ */
5
+ function tryResolve(name) {
6
+ try {
7
+ require.resolve(name);
8
+ return true;
9
+ } catch {
10
+ return false;
11
+ }
12
+ }
13
+
14
+ /**
15
+ * @template T
16
+ * @param {boolean} condition
17
+ * @param {T} value
18
+ */
19
+ function includeIf(condition, value) {
20
+ return condition ? [value] : [];
21
+ }
22
+
2
23
  module.exports = {
3
- extends: [require.resolve('./es'), require.resolve('./react'), require.resolve('./json')],
24
+ extends: [
25
+ require.resolve('./ignore'),
26
+ require.resolve('./es'),
27
+ require.resolve('./json'),
28
+ ...includeIf(tryResolve('react'), require.resolve('./react')),
29
+ ],
4
30
  overrides: [
5
- {
31
+ ...includeIf(tryResolve('typescript'), {
6
32
  extends: [require.resolve('./ts')],
7
33
  files: ['*.+(ts|tsx)'],
8
- },
34
+ }),
9
35
  {
10
36
  extends: [require.resolve('./jest')],
11
37
  files: [
@@ -13,6 +39,11 @@ module.exports = {
13
39
  '**/__tests__/**/*.+(ts|tsx|js|jsx)',
14
40
  '**/?(*.)+(spec|test).+(ts|tsx|js|jsx)',
15
41
  ],
42
+ settings: {
43
+ jest: {
44
+ version: 'latest',
45
+ },
46
+ },
16
47
  },
17
48
  ],
18
49
  root: true,
package/json.js CHANGED
@@ -1,8 +1,185 @@
1
+ /* cspell:disable */
2
+ // https://github.com/keithamus/sort-package-json/blob/master/defaultRules.md
1
3
  module.exports = {
2
- plugins: ['json-format'],
3
- settings: {
4
- 'json/ignore-files': ['**/package-lock.json'],
5
- 'json/json-with-comments-files': ['**/tsconfig.json', '.vscode/**'],
6
- 'json/sort-package-json': 'standard',
4
+ extends: ['plugin:jsonc/recommended-with-jsonc', 'plugin:jsonc/prettier'],
5
+ overrides: [
6
+ {
7
+ files: ['*.json', '*.json5', '*.jsonc'],
8
+ parser: 'jsonc-eslint-parser',
9
+ },
10
+ {
11
+ files: ['tsconfig*.json'],
12
+ rules: {
13
+ 'jsonc/sort-keys': [
14
+ 'error',
15
+ {
16
+ order: ['$schema', 'display', 'extends', 'compilerOptions', 'include', 'exclude', 'files', 'references'],
17
+ pathPattern: '^$',
18
+ },
19
+ {
20
+ order: { type: 'asc' },
21
+ pathPattern: '.*',
22
+ },
23
+ ],
24
+ },
25
+ },
26
+ {
27
+ files: ['package.json'],
28
+ parser: 'jsonc-eslint-parser',
29
+ rules: {
30
+ 'jsonc/sort-keys': [
31
+ 'error',
32
+ {
33
+ order: [
34
+ '$schema',
35
+ 'name',
36
+ 'displayName',
37
+ 'version',
38
+ 'private',
39
+ 'description',
40
+ 'categories',
41
+ 'keywords',
42
+ 'homepage',
43
+ 'bugs',
44
+ 'repository',
45
+ 'funding',
46
+ 'license',
47
+ 'qna',
48
+ 'author',
49
+ 'maintainers', // Key order (per item): name, email, url
50
+ 'contributors', // Key order (per item): name, email, url
51
+ 'publisher',
52
+ 'sideEffects',
53
+ 'type',
54
+ 'imports',
55
+ 'exports',
56
+ 'main',
57
+ 'svelte',
58
+ 'umd:main',
59
+ 'jsdelivr',
60
+ 'unpkg',
61
+ 'module',
62
+ 'source',
63
+ 'jsnext:main',
64
+ 'browser',
65
+ 'react-native',
66
+ 'types',
67
+ 'typesVersions',
68
+ 'typings',
69
+ 'style',
70
+ 'example',
71
+ 'examplestyle',
72
+ 'assets',
73
+ 'bin',
74
+ 'man',
75
+ 'directories', // Key order: lib, bin, man, doc, example, test
76
+ 'files', // Unique items
77
+ 'workspaces',
78
+ 'binary', // Key order: module_name, module_path, remote_path, package_name, host
79
+ 'scripts', // Script sort
80
+ 'betterScripts', // Script sort
81
+ 'contributes',
82
+ 'activationEvents', // Unique items
83
+ 'husky', // Sorts the hooks field using git hook sort
84
+ 'simple-git-hooks', // Key sort using git hook sort
85
+ 'pre-commit',
86
+ 'commitlint',
87
+ 'lint-staged',
88
+ 'config',
89
+ 'nodemonConfig',
90
+ 'browserify',
91
+ 'babel',
92
+ 'browserslist',
93
+ 'xo',
94
+ 'prettier', // Prettier sort
95
+ 'eslintConfig', // ESLint sort
96
+ 'eslintIgnore',
97
+ 'npmpackagejsonlint', // Key sort (also recognizes: npmPackageJsonLintConfig, npmpkgjsonlint)
98
+ 'release',
99
+ 'remarkConfig',
100
+ 'stylelint',
101
+ 'ava',
102
+ 'jest',
103
+ 'mocha',
104
+ 'nyc',
105
+ 'tap',
106
+ 'resolutions',
107
+ 'dependencies',
108
+ 'devDependencies',
109
+ 'dependenciesMeta', // Key sort (deep)
110
+ 'peerDependencies',
111
+ 'peerDependenciesMeta', // Key sort (deep)
112
+ 'optionalDependencies',
113
+ 'bundledDependencies',
114
+ 'bundleDependencies',
115
+ 'extensionPack',
116
+ 'extensionDependencies',
117
+ 'flat',
118
+ 'packageManager',
119
+ 'engines',
120
+ 'engineStrict',
121
+ 'volta', // Key order: node, npm, yarn
122
+ 'languageName',
123
+ 'os',
124
+ 'cpu',
125
+ 'preferGlobal',
126
+ 'publishConfig',
127
+ 'icon',
128
+ 'badges', // Key order (per item): description, url, href
129
+ 'galleryBanner',
130
+ 'preview',
131
+ 'markdown',
132
+ ],
133
+ pathPattern: '^$',
134
+ },
135
+ {
136
+ order: ['url', 'email'],
137
+ pathPattern: `^bugs$`,
138
+ },
139
+ ...['repository', 'funding', 'license', 'author'].map((key) => ({
140
+ order: ['type', 'name', 'email', 'url'],
141
+ pathPattern: `^${key}$`,
142
+ })),
143
+ ...[
144
+ 'bin',
145
+ 'contributes',
146
+ 'commitlint',
147
+ 'config',
148
+ 'nodemonConfig',
149
+ 'browserify',
150
+ 'babel',
151
+ 'xo',
152
+ 'release',
153
+ 'remarkConfig',
154
+ 'ava',
155
+ 'jest',
156
+ 'mocha',
157
+ 'nyc',
158
+ 'tap',
159
+ 'resolutions',
160
+ 'engines',
161
+ 'engineStrict',
162
+ 'preferGlobal',
163
+ 'publishConfig',
164
+ 'galleryBanner',
165
+ ].map((key) => ({
166
+ order: { type: 'asc' },
167
+ pathPattern: `^${key}$`,
168
+ })),
169
+ {
170
+ order: { type: 'asc' },
171
+ pathPattern: '^(?:dev|peer|optional|bundled|extension)?[Dd]ependencies$',
172
+ },
173
+ {
174
+ order: ['types', 'require', 'import'],
175
+ pathPattern: '^exports.*$',
176
+ },
177
+ ],
178
+ },
179
+ },
180
+ ],
181
+ plugins: ['jsonc'],
182
+ rules: {
183
+ // 'jsonc/sort-keys': 'error',
7
184
  },
8
185
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@w5s/eslint-config",
3
- "version": "1.0.0-alpha.3",
3
+ "version": "1.0.0-alpha.30",
4
4
  "description": "ESLint configuration presets",
5
5
  "keywords": [
6
6
  "eslint",
@@ -13,22 +13,28 @@
13
13
  },
14
14
  "repository": {
15
15
  "type": "git",
16
- "url": "https://github.com/w5s/project-config.git",
16
+ "url": "git@github.com:w5s/project-config.git",
17
17
  "directory": "packages/eslint-config"
18
18
  },
19
19
  "license": "MIT",
20
20
  "author": "Julien Polo <julien.polo@gmail.com>",
21
+ "type": "commonjs",
21
22
  "main": "index.js",
22
23
  "files": [
23
24
  "*.js",
24
25
  "rules/*.js"
25
26
  ],
26
27
  "scripts": {
27
- "build": "npm-run-all -p 'build:*'",
28
+ "build": "concurrently \"npm:build:*\" ",
28
29
  "build:empty": ":",
30
+ "clean": "concurrently \"npm:clean:*\" \":\"",
29
31
  "docs": "md-magic --path '**/*.md' --ignore='node_modules'",
30
- "format": "eslint . --fix",
31
- "lint": "eslint .",
32
+ "format": "concurrently \"npm:format:*\" \":\"",
33
+ "format:src": "eslint . --fix --ext=mjs,cjs,js,jsx,ts,tsx,json",
34
+ "lint": "concurrently \"npm:lint:*\" \":\"",
35
+ "lint:src": "eslint . --ext=mjs,cjs,js,jsx,ts,tsx,json",
36
+ "prepare": "concurrently \"npm:prepare:*\" \":\"",
37
+ "spellcheck": "cspell --no-progress '**'",
32
38
  "test": "scripts/test"
33
39
  },
34
40
  "eslintConfig": {
@@ -40,9 +46,9 @@
40
46
  "__tests__"
41
47
  ],
42
48
  "dependencies": {
43
- "@babel/eslint-parser": "^7.0.0",
44
- "@babel/plugin-syntax-class-properties": "^7.0.0",
45
- "@babel/plugin-syntax-jsx": "^7.0.0",
49
+ "@babel/core": "*",
50
+ "@babel/eslint-parser": "*",
51
+ "@rushstack/eslint-patch": "^1.1.0",
46
52
  "@typescript-eslint/eslint-plugin": "^5.0.0",
47
53
  "@typescript-eslint/parser": "^5.0.0",
48
54
  "eslint-config-airbnb-base": "^15.0.0",
@@ -50,32 +56,42 @@
50
56
  "eslint-plugin-functional": "^4.2.0",
51
57
  "eslint-plugin-import": "^2.25.0",
52
58
  "eslint-plugin-jest": "^26.0.0",
53
- "eslint-plugin-jsdoc": "^37.0.0",
54
- "eslint-plugin-json-format": "^2.0.1",
59
+ "eslint-plugin-jsdoc": "^39.0.0",
60
+ "eslint-plugin-jsonc": "^2.4.0",
55
61
  "eslint-plugin-prettier": "^4.0.0",
62
+ "eslint-plugin-promise": "^6.0.0",
56
63
  "eslint-plugin-react": "^7.28.0",
57
- "eslint-plugin-total-functions": "^5.0.0",
58
- "eslint-plugin-unicorn": "^40.0.0"
64
+ "eslint-plugin-total-functions": "^6.0.0",
65
+ "eslint-plugin-unicorn": "^43.0.0"
59
66
  },
60
67
  "devDependencies": {
61
- "@babel/eslint-parser": "7.17.0",
62
- "@types/eslint": "8.4.1",
63
- "@types/eslint-plugin-prettier": "^3.1.0",
64
- "@types/prettier": "2.4.4",
65
- "@types/react": "17.0.2",
66
- "@typescript-eslint/parser": "5.11.0",
67
- "eslint": "8.9.0",
68
- "eslint-config-prettier": "8.3.0",
68
+ "@babel/eslint-parser": "7.18.9",
69
+ "@types/eslint": "8.4.6",
70
+ "@types/eslint-plugin-prettier": "3.1.0",
71
+ "@types/prettier": "2.7.0",
72
+ "@types/react": "18.0.17",
73
+ "@typescript-eslint/parser": "5.35.1",
74
+ "eslint": "8.23.0",
75
+ "eslint-config-prettier": "8.5.0",
69
76
  "eslint-index": "1.5.0",
70
- "prettier": "2.5.1",
71
- "react": "17.0.2"
77
+ "prettier": "2.7.1",
78
+ "react": "18.2.0"
72
79
  },
73
80
  "peerDependencies": {
74
- "eslint": "5.x || 6.x || 7.x || 8.x",
75
- "prettier": "2.x"
81
+ "eslint": "8.x",
82
+ "prettier": "2.x",
83
+ "typescript": "4.x"
84
+ },
85
+ "peerDependenciesMeta": {
86
+ "typescript": {
87
+ "optional": true
88
+ }
89
+ },
90
+ "engines": {
91
+ "node": ">=16.0.0"
76
92
  },
77
93
  "publishConfig": {
78
94
  "access": "public"
79
95
  },
80
- "gitHead": "9935d3a478d08c3c6c02f467f65c623a16749753"
96
+ "gitHead": "91ea210deb64edee4df9604ec1ca84ba562b69f7"
81
97
  }
package/rules/_rule.js CHANGED
@@ -28,7 +28,7 @@ const off = 'off';
28
28
 
29
29
  /**
30
30
  * @template T
31
- * @type {(value: T[]|T|undefined) => T[]} */
31
+ @type {(value: T[]|T|undefined) => T[]} */
32
32
  function toArray(value) {
33
33
  if (value == null) {
34
34
  return [];
@@ -72,7 +72,7 @@ module.exports = {
72
72
  concatESConfig,
73
73
  error,
74
74
  // eslint-disable-next-line no-unused-vars
75
- fixme: (/** @type {'off'|'warn'|'error'} */ _status) => off,
75
+ fixme: (/** @type {'off'|'warn'|'error'|undefined} */ _status) => off,
76
76
  off,
77
77
  warn,
78
78
  };
package/rules/base.js CHANGED
@@ -1,13 +1,17 @@
1
- const { concatESConfig, off } = require('./_rule');
1
+ const { concatESConfig, off, error } = require('./_rule.js');
2
2
 
3
- module.exports = concatESConfig(
3
+ // Fix eslint shareable config (https://github.com/eslint/eslint/issues/3458)
4
+ // @ts-ignore
5
+ require('@rushstack/eslint-patch/modern-module-resolution.js');
6
+
7
+ const baseConfig = concatESConfig(
4
8
  // @ts-ignore
5
9
  require('eslint-config-airbnb-base/rules/best-practices'),
6
10
  // @ts-ignore
7
11
  require('eslint-config-airbnb-base/rules/errors'),
8
12
  // @ts-ignore
9
13
  require('eslint-config-airbnb-base/rules/es6'),
10
- // we use our own import configuration
14
+ /** {@link ./import.js} */
11
15
  // require('eslint-config-airbnb-base/rules/imports'),
12
16
  // @ts-ignore
13
17
  require('eslint-config-airbnb-base/rules/node'),
@@ -16,13 +20,32 @@ module.exports = concatESConfig(
16
20
  // @ts-ignore
17
21
  require('eslint-config-airbnb-base/rules/style'),
18
22
  // @ts-ignore
19
- require('eslint-config-airbnb-base/rules/variables'),
23
+ require('eslint-config-airbnb-base/rules/variables')
24
+ );
20
25
 
26
+ module.exports = concatESConfig(
27
+ baseConfig,
21
28
  // overrides
22
29
  {
23
30
  rules: {
31
+ // Annoying because it is not always wanted
32
+ 'default-case': off,
24
33
  // Often useful in jsx
25
34
  'no-nested-ternary': off,
35
+ // Too strict, for pure code prefer the functional plugin
36
+ 'no-param-reassign': [error, { props: false }],
37
+ // Allow for-of syntax
38
+ // @ts-ignore
39
+ 'no-restricted-syntax': baseConfig.rules['no-restricted-syntax'].filter(
40
+ // @ts-ignore
41
+ ({ selector }) => selector !== 'ForOfStatement'
42
+ ),
43
+ // underscore is often used (mongodb, etc)
44
+ 'no-underscore-dangle': off,
45
+ // Ignore underscore case arguments
46
+ 'no-unused-vars': [error, { argsIgnorePattern: '^_' }],
47
+ // Allow in some cases https://github.com/airbnb/javascript/issues/1089#issuecomment-1024351821
48
+ 'no-use-before-define': [error, 'nofunc'],
26
49
  },
27
50
  }
28
51
  );
package/rules/import.js CHANGED
@@ -1,4 +1,4 @@
1
- const { off, warn, error } = require('./_rule');
1
+ const { off, warn, error, concatESConfig, fixme } = require('./_rule.js');
2
2
 
3
3
  /**
4
4
  * @see https://github.com/typescript-eslint/typescript-eslint/blob/master/docs/getting-started/linting/FAQ.md#eslint-plugin-import
@@ -7,110 +7,26 @@ const { off, warn, error } = require('./_rule');
7
7
  // eslint-disable-next-line no-unused-vars
8
8
  const performanceIssue = (_status) => off;
9
9
 
10
- module.exports = {
11
- plugins: ['import'],
12
- rules: {
13
- 'import/default': error,
14
- 'import/export': error,
15
- 'import/exports-last': off,
16
- 'import/extensions': [
17
- error,
18
- 'ignorePackages',
19
- {
20
- js: 'never',
21
- json: 'always',
22
- jsx: 'never',
23
- mjs: 'never',
24
- ts: 'never',
25
- tsx: 'never',
26
- },
27
- ],
28
- 'import/first': [error, 'absolute-first'],
29
- 'import/group-exports': off,
30
- 'import/max-dependencies': [
31
- off,
32
- {
33
- max: 10,
34
- },
35
- ],
36
- 'import/named': error,
37
- 'import/namespace': error,
38
- 'import/newline-after-import': error,
39
- 'import/no-absolute-path': error,
40
- 'import/no-amd': error,
41
- 'import/no-anonymous-default-export': off,
42
- 'import/no-commonjs': off, // Still used widely by nodejs programs
43
- 'import/no-cycle': [error, { maxDepth: Number.POSITIVE_INFINITY }], // Elm, ReasonML forbids circular dependency
44
- 'import/no-default-export': off,
45
- 'import/no-deprecated': performanceIssue(warn),
46
- 'import/no-duplicates': error,
47
- 'import/no-dynamic-require': error,
48
- 'import/no-extraneous-dependencies': [
49
- error,
50
- {
51
- // https://github.com/airbnb/javascript/blob/1eadb93e377da1e56c3f91f26610e5d0a00738a9/packages/eslint-config-airbnb-base/rules/imports.js#L71
52
- devDependencies: [
53
- 'test/**', // tape, common npm pattern
54
- 'tests/**', // also common npm pattern
55
- 'spec/**', // mocha, rspec-like pattern
56
- '**/__tests__/**', // jest pattern
57
- '**/__mocks__/**', // jest pattern
58
- 'test.{js,jsx,ts,tsx}', // repos with a single test file
59
- 'test-*.{js,jsx,ts,tsx}', // repos with multiple top-level test files
60
- '**/*{.,_}{test,spec}.{js,jsx,ts,tsx}', // tests where the extension or filename suffix denotes that it is a test
61
- '**/jest.config.{js,ts}', // jest config
62
- '**/jest.setup.{js,ts}', // jest setup
63
- '**/vue.config.{js,ts}', // vue-cli config
64
- '**/webpack.config.js', // webpack config
65
- '**/webpack.config.*.js', // webpack config
66
- '**/rollup.config.js', // rollup config
67
- '**/rollup.config.*.js', // rollup config
68
- '**/gulpfile.js', // gulp config
69
- '**/gulpfile.*.js', // gulp config
70
- '**/Gruntfile{,.js}', // grunt config
71
- '**/protractor.conf.js', // protractor config
72
- '**/protractor.conf.*.js', // protractor config
73
- '**/karma.conf.js', // karma config
74
- '**/.eslintrc.js', // eslint config,
75
- '**/markdown.config.js', // markdown magic config,
76
- ],
77
- optionalDependencies: false,
78
- },
79
- ],
80
- 'import/no-internal-modules': off,
81
- 'import/no-mutable-exports': error,
82
- 'import/no-named-as-default': performanceIssue(error),
83
- 'import/no-named-as-default-member': error,
84
- 'import/no-named-default': error,
85
- 'import/no-named-export': off,
86
- 'import/no-namespace': off,
87
- 'import/no-nodejs-modules': off,
88
- 'import/no-relative-parent-imports': off,
89
- 'import/no-restricted-paths': off,
90
- 'import/no-self-import': error,
91
- 'import/no-unassigned-import': off,
92
- 'import/no-unresolved': [error, { caseSensitive: true, commonjs: true }],
93
- 'import/no-unused-modules': [performanceIssue(error), { unusedExports: true }],
94
- 'import/no-useless-path-segments': error,
95
- 'import/no-webpack-loader-syntax': error,
96
- 'import/order': [
97
- error,
98
- {
99
- groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'],
100
- 'newlines-between': 'never',
101
- },
102
- ],
103
- 'import/prefer-default-export': off,
104
- 'import/unambiguous': off, // Disable because proposal still in progress
105
- },
106
- settings: {
107
- 'import/core-modules': [],
108
- 'import/extensions': ['.js', '.mjs', '.jsx'],
109
- 'import/ignore': ['node_modules', '\\.(coffee|scss|css|less|hbs|svg|json)$'],
110
- 'import/resolver': {
111
- node: {
112
- extensions: ['.mjs', '.js', '.json'],
113
- },
10
+ module.exports = concatESConfig(
11
+ // @ts-ignore
12
+ require('eslint-config-airbnb-base/rules/imports'),
13
+ // Overrides
14
+ {
15
+ rules: {
16
+ 'import/extensions': [
17
+ error,
18
+ 'ignorePackages',
19
+ {
20
+ // js: 'never',
21
+ // jsx: 'never',
22
+ // mjs: 'never',
23
+ },
24
+ ],
25
+ 'import/no-deprecated': performanceIssue(warn),
26
+ 'import/no-named-as-default': performanceIssue(error),
27
+ 'import/no-unused-modules': performanceIssue(error),
28
+ 'import/prefer-default-export': off, // Not aligned, default export does not bring sufficient semantic
29
+ 'import/unambiguous': fixme(off), // Disable because proposal still in progress
114
30
  },
115
- },
116
- };
31
+ }
32
+ );
package/rules/jest.js CHANGED
@@ -1,46 +1,41 @@
1
- const { off, error } = require('./_rule');
1
+ const { off, error, concatESConfig } = require('./_rule.js');
2
2
 
3
- /**
4
- * Typescript config is loose because we often have "hack", "mock" in tests
5
- */
6
- const tsDisabled = {
7
- '@typescript-eslint/no-unsafe-assignment': off,
8
- '@typescript-eslint/no-unsafe-call': off,
9
- '@typescript-eslint/no-unsafe-member-access': off,
10
- '@typescript-eslint/no-unsafe-return': off,
11
- '@typescript-eslint/restrict-template-expressions': off,
12
- '@typescript-eslint/unbound-method': off,
13
- };
14
-
15
- module.exports = {
16
- env: {
17
- jest: true,
18
- },
19
- extends: ['plugin:jest/recommended'],
20
- plugins: ['jest'],
21
- rules: Object.assign(
22
- {
3
+ module.exports = concatESConfig(
4
+ {
5
+ env: {
6
+ jest: true,
7
+ },
8
+ extends: ['plugin:jest/recommended'],
9
+ plugins: ['jest'],
10
+ rules: {
23
11
  'jest/expect-expect': off, // Disabled because it does not handle functions that does the expect
24
12
  'jest/no-alias-methods': error,
25
- 'jest/no-commented-out-tests': error,
26
- 'jest/no-deprecated-functions': off,
27
- 'jest/no-disabled-tests': off,
28
- 'jest/no-done-callback': error,
29
- 'jest/no-export': off,
30
- 'jest/no-focused-tests': error,
31
- 'jest/no-identical-title': error,
32
- 'jest/no-restricted-matchers': [
33
- error,
34
- {
35
- toBeFalsy: 'Avoid `toBeFalsy`',
36
- toBeTruthy: 'Avoid `toBeTruthy`',
37
- },
38
- ],
39
13
  'jest/prefer-spy-on': error,
40
14
  'jest/prefer-to-contain': error,
41
- 'jest/valid-expect': error,
42
15
  'jest/valid-title': [error, { ignoreTypeOfDescribeName: true }],
43
16
  },
44
- tsDisabled
45
- ),
46
- };
17
+ },
18
+ /**
19
+ * Unicorn less strict to help writing tests
20
+ */
21
+ {
22
+ rules: {
23
+ 'unicorn/consistent-function-scoping': off,
24
+ 'unicorn/no-useless-undefined': off,
25
+ 'unicorn/prefer-module': off,
26
+ },
27
+ },
28
+ /**
29
+ * Typescript config is set to be less strict because we often have "hack", "mock" in tests
30
+ */
31
+ {
32
+ rules: {
33
+ '@typescript-eslint/no-unsafe-assignment': off,
34
+ '@typescript-eslint/no-unsafe-call': off,
35
+ '@typescript-eslint/no-unsafe-member-access': off,
36
+ '@typescript-eslint/no-unsafe-return': off,
37
+ '@typescript-eslint/restrict-template-expressions': off,
38
+ '@typescript-eslint/unbound-method': off,
39
+ },
40
+ }
41
+ );
package/rules/jsdoc.js CHANGED
@@ -1,20 +1,20 @@
1
- const { off, warn, error } = require('./_rule');
1
+ const { off, error, warn } = require('./_rule.js');
2
2
 
3
3
  module.exports = {
4
+ extends: ['plugin:jsdoc/recommended'],
4
5
  plugins: ['jsdoc'],
5
6
  rules: {
6
- 'jsdoc/check-param-names': warn,
7
- 'jsdoc/check-tag-names': warn,
8
- 'jsdoc/check-types': warn,
9
- 'jsdoc/newline-after-description': [warn, 'always'],
10
- 'jsdoc/require-description': off,
11
- 'jsdoc/require-description-complete-sentence': off,
12
- 'jsdoc/require-hyphen-before-param-description': off,
13
- 'jsdoc/require-param': off,
7
+ 'jsdoc/no-undefined-types': off, // https://github.com/gajus/eslint-plugin-jsdoc/issues/839
8
+ 'jsdoc/require-hyphen-before-param-description': [warn, 'always'],
9
+ 'jsdoc/require-jsdoc': off,
14
10
  'jsdoc/require-param-description': off,
15
- 'jsdoc/require-param-name': error,
16
- 'jsdoc/require-param-type': off,
17
- 'jsdoc/require-returns-description': off,
18
- 'jsdoc/require-returns-type': off,
11
+ 'jsdoc/require-returns': off,
12
+ 'jsdoc/valid-types': off, // FIXME: reports lots of false positive
13
+ strict: [error, 'safe'],
14
+ },
15
+ settings: {
16
+ jsdoc: {
17
+ mode: 'typescript',
18
+ },
19
19
  },
20
20
  };
package/rules/prettier.js CHANGED
@@ -1,4 +1,4 @@
1
- const { error } = require('./_rule');
1
+ const { error } = require('./_rule.js');
2
2
 
3
3
  module.exports = {
4
4
  plugins: ['prettier'],
@@ -0,0 +1,11 @@
1
+ const { concatESConfig, error, fixme } = require('./_rule.js');
2
+
3
+ module.exports = concatESConfig({
4
+ extends: ['plugin:promise/recommended'],
5
+ plugins: ['promise'],
6
+ rules: {
7
+ // https://github.com/xjamundx/eslint-plugin-promise/issues/212
8
+ 'promise/prefer-await-to-callbacks': fixme(error),
9
+ 'promise/prefer-await-to-then': error,
10
+ },
11
+ });
package/rules/react.js CHANGED
@@ -1,4 +1,4 @@
1
- const { off, warn, error } = require('./_rule');
1
+ const { off, warn, error } = require('./_rule.js');
2
2
 
3
3
  module.exports = {
4
4
  plugins: ['react'],
@@ -1,56 +1,24 @@
1
- const { fixme, off, warn, error } = require('./_rule');
2
- const { rules: _baseRules } = require('./base');
1
+ // Inspired by https://github.com/iamturns/eslint-config-airbnb-typescript/blob/master/lib/shared.js
3
2
 
4
- // Fix : TS pluging seems to modify the rules
5
- const baseRules = JSON.parse(JSON.stringify(_baseRules));
3
+ const { fixme, off, warn, error, concatESConfig } = require('./_rule.js');
4
+ const { rules: _baseRules } = require('./base.js');
5
+ const { rules: _baseImportRules } = require('./import.js');
6
6
 
7
- const duplicateTSC = off; // = "off because tsc already checks that"
7
+ // Fix Hack : TS pluging seems to modify the rules
8
+ const deepClone = (/** @type {Record<string, unknown>} */ anyValue) => JSON.parse(JSON.stringify(anyValue));
9
+ const baseRules = deepClone(_baseRules);
10
+ const baseImportRules = deepClone(_baseImportRules);
8
11
 
9
- // https://github.com/typescript-eslint/typescript-eslint/blob/master/docs/getting-started/linting/FAQ.md#eslint-plugin-import
10
- const ruleDisabled = {
11
- camelcase: off,
12
- 'constructor-super': off,
13
- 'dot-notation': off,
14
- 'getter-return': off,
15
- 'import/default': duplicateTSC,
16
- 'import/export': fixme(error), // https://github.com/benmosher/eslint-plugin-import/issues/1964
17
- 'import/named': duplicateTSC,
18
- 'import/namespace': duplicateTSC,
19
- 'import/no-named-as-default-member': duplicateTSC,
20
- 'import/no-unresolved': duplicateTSC,
21
- 'no-array-constructor': off,
22
- 'no-const-assign': off,
23
- 'no-dupe-args': off,
24
- 'no-dupe-class-members': off,
25
- 'no-dupe-keys': off,
26
- 'no-empty-function': off,
27
- 'no-func-assign': off,
28
- 'no-import-assign': off,
29
- 'no-inner-declarations': fixme(error), // https://github.com/typescript-eslint/typescript-eslint/issues/239
30
- 'no-new-symbol': off,
31
- 'no-obj-calls': off,
32
- 'no-redeclare': off,
33
- 'no-setter-return': off,
34
- 'no-shadow': off, // https://github.com/typescript-eslint/typescript-eslint/issues/2483
35
- 'no-this-before-super': off,
36
- 'no-undef': off,
37
- 'no-unreachable': off,
38
- 'no-unsafe-negation': off,
39
- 'no-unused-vars': off,
40
- 'no-use-before-define': off,
41
- 'no-useless-constructor': off,
42
- 'no-var': error,
43
- 'prefer-const': error,
44
- 'prefer-rest-params': error,
45
- 'prefer-spread': error,
46
- 'valid-typeof': off,
47
- };
12
+ const duplicateTSC = off; // = "off because tsc already checks that"
48
13
 
49
- module.exports = {
50
- extends: ['plugin:@typescript-eslint/recommended-requiring-type-checking'],
51
- plugins: ['@typescript-eslint', 'import'],
52
- rules: Object.assign(
53
- {
14
+ module.exports = concatESConfig(
15
+ /**
16
+ * Plugin rules
17
+ */
18
+ {
19
+ extends: ['plugin:@typescript-eslint/recommended-requiring-type-checking'],
20
+ plugins: ['@typescript-eslint', 'import'],
21
+ rules: {
54
22
  '@typescript-eslint/adjacent-overload-signatures': error,
55
23
  '@typescript-eslint/ban-ts-comment': [
56
24
  warn,
@@ -63,13 +31,29 @@ module.exports = {
63
31
  },
64
32
  ],
65
33
  '@typescript-eslint/ban-types': error,
34
+ '@typescript-eslint/brace-style': baseRules['brace-style'],
35
+ '@typescript-eslint/comma-dangle': [
36
+ baseRules['comma-dangle'][0],
37
+ {
38
+ ...baseRules['comma-dangle'][1],
39
+ enums: baseRules['comma-dangle'][1].arrays,
40
+ generics: baseRules['comma-dangle'][1].arrays,
41
+ tuples: baseRules['comma-dangle'][1].arrays,
42
+ },
43
+ ],
44
+ '@typescript-eslint/comma-spacing': baseRules['comma-spacing'],
66
45
  '@typescript-eslint/consistent-type-assertions': [
67
46
  error,
68
47
  { assertionStyle: 'as', objectLiteralTypeAssertions: 'never' },
69
48
  ],
49
+ '@typescript-eslint/default-param-last': baseRules['default-param-last'],
70
50
  '@typescript-eslint/dot-notation': baseRules['dot-notation'],
71
51
  '@typescript-eslint/explicit-function-return-type': off,
72
52
  '@typescript-eslint/explicit-module-boundary-types': off,
53
+ '@typescript-eslint/func-call-spacing': baseRules['func-call-spacing'],
54
+ '@typescript-eslint/indent': baseRules.indent,
55
+ '@typescript-eslint/keyword-spacing': baseRules['keyword-spacing'],
56
+ '@typescript-eslint/lines-between-class-members': baseRules['lines-between-class-members'],
73
57
  '@typescript-eslint/member-delimiter-style': error,
74
58
  '@typescript-eslint/naming-convention': [
75
59
  error,
@@ -96,28 +80,43 @@ module.exports = {
96
80
  selector: 'typeLike',
97
81
  },
98
82
  ],
99
- '@typescript-eslint/no-array-constructor': error,
83
+ '@typescript-eslint/no-array-constructor': baseRules['no-array-constructor'],
100
84
  '@typescript-eslint/no-base-to-string': error,
85
+ '@typescript-eslint/no-dupe-class-members': baseRules['no-dupe-class-members'],
101
86
  '@typescript-eslint/no-empty-function': baseRules['no-empty-function'],
102
87
  '@typescript-eslint/no-empty-interface': [error, { allowSingleExtends: true }],
103
88
  '@typescript-eslint/no-explicit-any': off, // if any is explicit then it's wanted
89
+ '@typescript-eslint/no-extra-parens': baseRules['no-extra-parens'],
90
+ '@typescript-eslint/no-extra-semi': baseRules['no-extra-semi'],
104
91
  '@typescript-eslint/no-implicit-any-catch': error,
105
92
  '@typescript-eslint/no-inferrable-types': error,
93
+ '@typescript-eslint/no-loop-func': baseRules['no-loop-func'],
94
+ '@typescript-eslint/no-loss-of-precision': baseRules['no-loss-of-precision'],
95
+ '@typescript-eslint/no-magic-numbers': baseRules['no-magic-numbers'],
106
96
  '@typescript-eslint/no-misused-new': error,
107
97
  '@typescript-eslint/no-namespace': off, // We don't agree with community, namespaces are great and not deprecated
108
98
  '@typescript-eslint/no-non-null-assertion': error,
109
- '@typescript-eslint/no-redeclare': fixme(error /* baseRules['no-redeclare'] */), // Error level so it is strongly discouraged
99
+ '@typescript-eslint/no-redeclare': fixme(baseRules['no-redeclare']),
110
100
  '@typescript-eslint/no-require-imports': error,
111
- '@typescript-eslint/no-shadow': baseRules['no-shadow'], // Does not allow to declare type and const with same name
101
+ '@typescript-eslint/no-shadow': baseRules['no-shadow'],
112
102
  '@typescript-eslint/no-this-alias': error,
103
+ '@typescript-eslint/no-throw-literal': baseRules['no-throw-literal'],
113
104
  '@typescript-eslint/no-unnecessary-condition': error,
114
105
  '@typescript-eslint/no-unsafe-argument': error,
106
+ '@typescript-eslint/no-unused-expressions': baseRules['no-unused-expressions'],
115
107
  '@typescript-eslint/no-unused-vars': baseRules['no-unused-vars'],
116
108
  '@typescript-eslint/no-use-before-define': baseRules['no-use-before-define'],
117
109
  '@typescript-eslint/no-useless-constructor': baseRules['no-useless-constructor'],
118
110
  '@typescript-eslint/no-var-requires': error,
111
+ '@typescript-eslint/object-curly-spacing': baseRules['object-curly-spacing'],
119
112
  '@typescript-eslint/prefer-namespace-keyword': error,
120
113
  '@typescript-eslint/prefer-reduce-type-parameter': error,
114
+ '@typescript-eslint/quotes': baseRules.quotes,
115
+ '@typescript-eslint/require-await': baseRules['require-await'],
116
+ '@typescript-eslint/return-await': baseRules['no-return-await'],
117
+ '@typescript-eslint/semi': baseRules.semi,
118
+ '@typescript-eslint/space-before-function-paren': baseRules['space-before-function-paren'],
119
+ '@typescript-eslint/space-infix-ops': baseRules['space-infix-ops'],
121
120
  '@typescript-eslint/strict-boolean-expressions': [
122
121
  error,
123
122
  {
@@ -130,6 +129,118 @@ module.exports = {
130
129
  '@typescript-eslint/triple-slash-reference': error,
131
130
  '@typescript-eslint/type-annotation-spacing': error,
132
131
  },
133
- ruleDisabled
134
- ),
135
- };
132
+ },
133
+ /**
134
+ * JSDoc overrides
135
+ */
136
+ {
137
+ rules: {
138
+ 'jsdoc/no-types': error,
139
+ 'jsdoc/require-param': off,
140
+ 'jsdoc/require-param-type': off,
141
+ 'jsdoc/require-returns': off,
142
+ 'jsdoc/require-returns-type': off,
143
+ },
144
+ },
145
+ /**
146
+ * Import overrides
147
+ */
148
+ {
149
+ rules: {
150
+ 'import/extensions': [
151
+ baseImportRules['import/extensions'][0],
152
+ baseImportRules['import/extensions'][1],
153
+ {
154
+ ...baseImportRules['import/extensions'][2],
155
+ ts: 'never',
156
+ tsx: 'never',
157
+ },
158
+ ],
159
+ 'import/no-extraneous-dependencies': [
160
+ baseImportRules['import/no-extraneous-dependencies'][0],
161
+ {
162
+ ...baseImportRules['import/no-extraneous-dependencies'][1],
163
+ devDependencies: baseImportRules['import/no-extraneous-dependencies'][1].devDependencies.reduce(
164
+ (/** @type {string[]} */ result, /** @type {string} */ devDep) => {
165
+ const toAppend = [devDep];
166
+ const devDepWithTs = devDep.replace(/\bjs(x?)\b/g, 'ts$1');
167
+ if (devDepWithTs !== devDep) {
168
+ toAppend.push(devDepWithTs);
169
+ }
170
+ return [...result, ...toAppend];
171
+ },
172
+ []
173
+ ),
174
+ },
175
+ ],
176
+ },
177
+ },
178
+ /**
179
+ * Disabled rules
180
+ */
181
+ {
182
+ // https://github.com/typescript-eslint/typescript-eslint/blob/master/docs/getting-started/linting/FAQ.md#eslint-plugin-import
183
+ rules: {
184
+ 'brace-style': off,
185
+ camelcase: off,
186
+ 'comma-dangle': off,
187
+ 'comma-spacing': off,
188
+ 'constructor-super': off,
189
+ 'default-param-last': off,
190
+ 'dot-notation': off,
191
+ 'func-call-spacing': off,
192
+ 'getter-return': off,
193
+ 'import/default': duplicateTSC,
194
+ 'import/export': fixme(error), // https://github.com/benmosher/eslint-plugin-import/issues/1964
195
+ 'import/named': duplicateTSC,
196
+ 'import/namespace': duplicateTSC,
197
+ 'import/no-named-as-default-member': duplicateTSC,
198
+ 'import/no-unresolved': duplicateTSC,
199
+ indent: off,
200
+ 'keyword-spacing': off,
201
+ 'lines-between-class-members': off,
202
+ 'no-array-constructor': off,
203
+ 'no-const-assign': off,
204
+ 'no-dupe-args': off,
205
+ 'no-dupe-class-members': off,
206
+ 'no-dupe-keys': off,
207
+ 'no-empty-function': off,
208
+ 'no-extra-parens': off,
209
+ 'no-extra-semi': off,
210
+ 'no-func-assign': off,
211
+ 'no-implied-eval': off,
212
+ 'no-import-assign': off,
213
+ 'no-inner-declarations': fixme(error), // https://github.com/typescript-eslint/typescript-eslint/issues/239
214
+ 'no-loop-func': off,
215
+ 'no-loss-of-precision': off,
216
+ 'no-magic-numbers': off,
217
+ 'no-new-func': off,
218
+ 'no-new-symbol': off,
219
+ 'no-obj-calls': off,
220
+ 'no-redeclare': off,
221
+ 'no-return-await': off,
222
+ 'no-setter-return': off,
223
+ 'no-shadow': off,
224
+ 'no-this-before-super': off,
225
+ 'no-throw-literal': off,
226
+ 'no-undef': off,
227
+ 'no-unreachable': off,
228
+ 'no-unsafe-negation': off,
229
+ 'no-unused-expressions': off,
230
+ 'no-unused-vars': off,
231
+ 'no-use-before-define': off,
232
+ 'no-useless-constructor': off,
233
+ 'no-var': error,
234
+ 'object-curly-spacing': off,
235
+ 'prefer-const': error,
236
+ 'prefer-rest-params': error,
237
+ 'prefer-spread': error,
238
+ quotes: off,
239
+ 'require-await': off,
240
+ semi: off,
241
+ 'space-before-function-paren': off,
242
+ 'space-infix-ops': off,
243
+ 'valid-typeof': off,
244
+ },
245
+ }
246
+ );
package/rules/unicorn.js CHANGED
@@ -1,18 +1,10 @@
1
- const { off, warn, error } = require('./_rule');
1
+ const { off, warn, error, concatESConfig } = require('./_rule.js');
2
2
 
3
- const unsafeRules = {
4
- 'unicorn/consistent-destructuring': off,
5
- 'unicorn/no-array-for-each': off, // This rule could change browser compatibility
6
- 'unicorn/no-object-as-default-parameter': off,
7
- 'unicorn/prefer-default-parameters': off,
8
- 'unicorn/prevent-abbreviations': off, // This rule is so dangerous : it potentially break code while fixing in many cases !!
9
- };
10
-
11
- module.exports = {
12
- extends: ['plugin:unicorn/recommended'],
13
- plugins: ['unicorn'],
14
- rules: Object.assign(
15
- {
3
+ module.exports = concatESConfig(
4
+ {
5
+ extends: ['plugin:unicorn/recommended'],
6
+ plugins: ['unicorn'],
7
+ rules: {
16
8
  'unicode-bom': [error, 'never'],
17
9
  'unicorn/better-regex': error,
18
10
  'unicorn/catch-error-name': [error, { name: error }],
@@ -53,6 +45,18 @@ module.exports = {
53
45
  'unicorn/prefer-type-error': error,
54
46
  'unicorn/throw-new-error': error,
55
47
  },
56
- unsafeRules
57
- ),
58
- };
48
+ },
49
+ {
50
+ rules: {
51
+ 'unicorn/consistent-destructuring': off,
52
+ 'unicorn/consistent-function-scoping': off, // Too many false positive
53
+ 'unicorn/no-array-callback-reference': off, // Many false positive reported
54
+ 'unicorn/no-array-for-each': off, // This rule could change browser compatibility
55
+ 'unicorn/no-array-method-this-argument': off, // Many false positive reported
56
+ 'unicorn/no-array-reduce': off, // Array#reduce can be used
57
+ 'unicorn/no-object-as-default-parameter': off,
58
+ 'unicorn/prefer-default-parameters': off,
59
+ 'unicorn/prevent-abbreviations': off, // This rule is so dangerous : it potentially break code while fixing in many cases !!
60
+ },
61
+ }
62
+ );
package/ts.js CHANGED
@@ -14,4 +14,23 @@ module.exports = {
14
14
  parserOptions: {
15
15
  sourceType: 'module',
16
16
  },
17
+ settings: {
18
+ // Append 'ts' extensions to Airbnb 'import/extensions' setting
19
+ 'import/extensions': ['.js', '.mjs', '.jsx', '.ts', '.tsx', '.d.ts'],
20
+
21
+ // Resolve type definition packages
22
+ 'import/external-module-folders': ['node_modules', 'node_modules/@types'],
23
+
24
+ // Apply special parsing for TypeScript files
25
+ 'import/parsers': {
26
+ '@typescript-eslint/parser': ['.ts', '.tsx', '.d.ts'],
27
+ },
28
+
29
+ // Append 'ts' extensions to Airbnb 'import/resolver' setting
30
+ 'import/resolver': {
31
+ node: {
32
+ extensions: ['.mjs', '.js', '.json', '.ts', '.d.ts'],
33
+ },
34
+ },
35
+ },
17
36
  };