@gitlab/eslint-plugin 22.0.0 → 23.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,87 @@
1
1
  # @gitlab/eslint-plugin
2
2
 
3
+ ## 23.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - 8dfb811: Replace `eslint-plugin-import` with `eslint-plugin-import-x`.
8
+
9
+ `eslint-plugin-import` does not support ESLint 10. `eslint-plugin-import-x` is a maintained fork with
10
+ the same rules that supports ESLint 8, 9 and 10. Every config this package exports now registers
11
+ `eslint-plugin-import-x` under the `import-x` namespace instead of `eslint-plugin-import` under
12
+ `import`. The rules we enable and their options are unchanged; only their names and the settings
13
+ that drive them move.
14
+
15
+ ## Breaking changes
16
+
17
+ 1. **Every import rule is renamed from `import/<rule>` to `import-x/<rule>`.** Rule overrides in
18
+ your `eslint.config.js` must be renamed:
19
+
20
+ ```diff
21
+ module.exports = [
22
+ ...gitlab.configs.default,
23
+ {
24
+ rules: {
25
+ - 'import/no-cycle': 'off',
26
+ + 'import-x/no-cycle': 'off',
27
+ },
28
+ },
29
+ ];
30
+ ```
31
+
32
+ 2. **Disable comments must be renamed too.** An `// eslint-disable-next-line import/no-cycle`
33
+ comment now refers to a rule ESLint cannot find, which it reports as an error. Rename them to
34
+ `import-x/...`. This rewrites `import/` to `import-x/` on ESLint directive lines only, leaving
35
+ import paths alone (review the diff before committing):
36
+
37
+ ```bash
38
+ git grep -lE 'eslint-(disable|enable)|/\* *eslint ' -- '*.js' '*.mjs' '*.cjs' '*.ts' '*.vue' \
39
+ | xargs perl -pi -e 's#(?<=[\s,])import/(?=[a-z])#import-x/#g if m{eslint-(disable|enable)|/\*\s*eslint\s}'
40
+ ```
41
+
42
+ 3. **Import settings are renamed from `import/*` to `import-x/*`.** `eslint-plugin-import-x` only
43
+ reads `import-x/`-prefixed settings and silently ignores the old names, so a leftover
44
+ `import/resolver`, `import/core-modules`, `import/ignore` or `import/internal-regex` stops having
45
+ any effect without an error. Rename each key.
46
+
47
+ 4. **In the `typescript` config, custom resolvers must go in `import-x/resolver-next`.** That config
48
+ sets `import-x/resolver-next` so `.ts` and `.tsx` files resolve, and when that key is present
49
+ `eslint-plugin-import-x` ignores `import-x/resolver`. ESLint also replaces arrays in `settings`
50
+ rather than merging them, so your `import-x/resolver-next` replaces ours. If you need `tsconfig.json`
51
+ `paths` aliases, use `eslint-import-resolver-typescript`, which also resolves everything ours does:
52
+
53
+ ```js
54
+ const { createTypeScriptImportResolver } = require('eslint-import-resolver-typescript');
55
+
56
+ module.exports = [
57
+ ...gitlab.configs.typescript,
58
+ {
59
+ settings: {
60
+ 'import-x/resolver-next': [createTypeScriptImportResolver()],
61
+ },
62
+ },
63
+ ];
64
+ ```
65
+
66
+ The other configs set no resolver, so a custom one there only needs its key renamed (point 3).
67
+
68
+ ## Other changes
69
+
70
+ - The configs other than `typescript` no longer set a resolver and rely on `eslint-plugin-import-x`'s
71
+ default node resolver. It resolves the same files as before, plus `.cjs` and `.node`.
72
+ - `import-x/core-modules` and the stylesheet/asset patterns in `import-x/ignore` are no longer set.
73
+ Neither had an effect: the first was the default value, and files with those extensions were
74
+ already skipped because they aren't listed in `import-x/extensions`. `node_modules` is still
75
+ ignored.
76
+ - `import/imports-first` is no longer configured. It was already disabled, and it is deprecated in
77
+ favour of `import-x/first`, which stays enabled.
78
+ - The `typescript` config no longer relies on `eslint-plugin-import`'s TypeScript preset. It sets the
79
+ equivalent settings itself: `.ts`, `.cts`, `.mts` and `.tsx` files are resolved by the node
80
+ resolver, `node_modules/@types` is treated as external, and `import-x/named` is disabled for
81
+ TypeScript files as before.
82
+ - If your own config also uses `eslint-plugin-import`, it can now coexist with this package: the two
83
+ plugins register under different names.
84
+
3
85
  ## 22.0.0
4
86
 
5
87
  ### Major Changes
@@ -48,7 +48,7 @@ module.exports = {
48
48
 
49
49
  // disallow importing from the same path more than once
50
50
  // https://eslint.org/docs/rules/no-duplicate-imports
51
- // replaced by https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-duplicates.md
51
+ // replaced by https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-duplicates.md
52
52
  'no-duplicate-imports': 'off',
53
53
 
54
54
  // disallow symbol constructor
@@ -1,55 +1,49 @@
1
1
  module.exports = {
2
2
  settings: {
3
- 'import/resolver': {
4
- node: {
5
- extensions: ['.mjs', '.js', '.json'],
6
- },
7
- },
8
- 'import/extensions': ['.js', '.mjs', '.jsx'],
9
- 'import/core-modules': [],
10
- 'import/ignore': ['node_modules', '\\.(coffee|scss|css|less|hbs|svg|json)$'],
3
+ 'import-x/extensions': ['.js', '.mjs', '.jsx'],
4
+ 'import-x/ignore': ['node_modules'],
11
5
  },
12
6
 
13
7
  rules: {
14
8
  // Static analysis:
15
9
 
16
10
  // ensure imports point to files/modules that can be resolved
17
- // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-unresolved.md
18
- 'import/no-unresolved': ['error', { commonjs: true, caseSensitive: true }],
11
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-unresolved.md
12
+ 'import-x/no-unresolved': ['error', { commonjs: true, caseSensitive: true }],
19
13
 
20
14
  // ensure named imports coupled with named exports
21
- // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/named.md#when-not-to-use-it
22
- 'import/named': 'error',
15
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/named.md#when-not-to-use-it
16
+ 'import-x/named': 'error',
23
17
 
24
18
  // ensure default import coupled with default export
25
- // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/default.md#when-not-to-use-it
26
- 'import/default': 'off',
19
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/default.md#when-not-to-use-it
20
+ 'import-x/default': 'off',
27
21
 
28
- // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/namespace.md
29
- 'import/namespace': 'off',
22
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/namespace.md
23
+ 'import-x/namespace': 'off',
30
24
 
31
25
  // Helpful warnings:
32
26
 
33
27
  // disallow invalid exports, e.g. multiple defaults
34
- // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/export.md
35
- 'import/export': 'error',
28
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/export.md
29
+ 'import-x/export': 'error',
36
30
 
37
31
  // do not allow a default import name to match a named export
38
- // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-named-as-default.md
39
- 'import/no-named-as-default': 'error',
32
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-named-as-default.md
33
+ 'import-x/no-named-as-default': 'error',
40
34
 
41
35
  // warn on accessing default export property names that are also named exports
42
- // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-named-as-default-member.md
43
- 'import/no-named-as-default-member': 'error',
36
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-named-as-default-member.md
37
+ 'import-x/no-named-as-default-member': 'error',
44
38
 
45
39
  // disallow use of jsdoc-marked-deprecated imports
46
- // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-deprecated.md
47
- 'import/no-deprecated': 'off',
40
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-deprecated.md
41
+ 'import-x/no-deprecated': 'off',
48
42
 
49
43
  // Forbid the use of extraneous packages
50
- // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-extraneous-dependencies.md
44
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-extraneous-dependencies.md
51
45
  // paths are treated both as absolute paths, and relative to process.cwd()
52
- 'import/no-extraneous-dependencies': [
46
+ 'import-x/no-extraneous-dependencies': [
53
47
  'error',
54
48
  {
55
49
  devDependencies: [
@@ -81,47 +75,42 @@ module.exports = {
81
75
  ],
82
76
 
83
77
  // Forbid mutable exports
84
- // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-mutable-exports.md
85
- 'import/no-mutable-exports': 'error',
78
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-mutable-exports.md
79
+ 'import-x/no-mutable-exports': 'error',
86
80
 
87
81
  // Module systems:
88
82
 
89
83
  // disallow require()
90
- // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-commonjs.md
91
- 'import/no-commonjs': 'off',
84
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-commonjs.md
85
+ 'import-x/no-commonjs': 'off',
92
86
 
93
87
  // disallow AMD require/define
94
- // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-amd.md
95
- 'import/no-amd': 'error',
88
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-amd.md
89
+ 'import-x/no-amd': 'error',
96
90
 
97
91
  // No Node.js builtin modules
98
- // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-nodejs-modules.md
92
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-nodejs-modules.md
99
93
  // TODO: enable?
100
- 'import/no-nodejs-modules': 'off',
94
+ 'import-x/no-nodejs-modules': 'off',
101
95
 
102
96
  // Style guide:
103
97
 
104
98
  // disallow non-import statements appearing before import statements
105
- // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/first.md
106
- 'import/first': 'error',
107
-
108
- // disallow non-import statements appearing before import statements
109
- // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/imports-first.md
110
- // deprecated: use `import/first`
111
- 'import/imports-first': 'off',
99
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/first.md
100
+ 'import-x/first': 'error',
112
101
 
113
102
  // disallow duplicate imports
114
- // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-duplicates.md
115
- 'import/no-duplicates': 'error',
103
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-duplicates.md
104
+ 'import-x/no-duplicates': 'error',
116
105
 
117
106
  // disallow namespace imports
118
107
  // TODO: enable?
119
- // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-namespace.md
120
- 'import/no-namespace': 'off',
108
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-namespace.md
109
+ 'import-x/no-namespace': 'off',
121
110
 
122
111
  // Ensure consistent use of file extension within the import path
123
- // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/extensions.md
124
- 'import/extensions': [
112
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/extensions.md
113
+ 'import-x/extensions': [
125
114
  'error',
126
115
  'ignorePackages',
127
116
  {
@@ -132,37 +121,37 @@ module.exports = {
132
121
  ],
133
122
 
134
123
  // ensure absolute imports are above relative imports and that unassigned imports are ignored
135
- // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/order.md
124
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/order.md
136
125
  // TODO: enforce a stricter convention in module import order?
137
- 'import/order': ['error', { groups: [['builtin', 'external', 'internal']] }],
126
+ 'import-x/order': ['error', { groups: [['builtin', 'external', 'internal']] }],
138
127
 
139
128
  // Require a newline after the last import/require in a group
140
- // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/newline-after-import.md
141
- 'import/newline-after-import': 'error',
129
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/newline-after-import.md
130
+ 'import-x/newline-after-import': 'error',
142
131
 
143
132
  // Require modules with a single export to use a default export
144
- // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/prefer-default-export.md
145
- 'import/prefer-default-export': 'error',
133
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/prefer-default-export.md
134
+ 'import-x/prefer-default-export': 'error',
146
135
 
147
136
  // Restrict which files can be imported in a given folder
148
- // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-restricted-paths.md
149
- 'import/no-restricted-paths': 'off',
137
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-restricted-paths.md
138
+ 'import-x/no-restricted-paths': 'off',
150
139
 
151
140
  // Forbid modules to have too many dependencies
152
- // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/max-dependencies.md
153
- 'import/max-dependencies': ['off', { max: 10 }],
141
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/max-dependencies.md
142
+ 'import-x/max-dependencies': ['off', { max: 10 }],
154
143
 
155
144
  // Forbid import of modules using absolute paths
156
- // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-absolute-path.md
157
- 'import/no-absolute-path': 'error',
145
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-absolute-path.md
146
+ 'import-x/no-absolute-path': 'error',
158
147
 
159
148
  // Forbid require() calls with expressions
160
- // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-dynamic-require.md
161
- 'import/no-dynamic-require': 'error',
149
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-dynamic-require.md
150
+ 'import-x/no-dynamic-require': 'error',
162
151
 
163
152
  // prevent importing the submodules of other modules
164
- // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-internal-modules.md
165
- 'import/no-internal-modules': [
153
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-internal-modules.md
154
+ 'import-x/no-internal-modules': [
166
155
  'off',
167
156
  {
168
157
  allow: [],
@@ -171,27 +160,27 @@ module.exports = {
171
160
 
172
161
  // Warn if a module could be mistakenly parsed as a script by a consumer
173
162
  // leveraging Unambiguous JavaScript Grammar
174
- // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/unambiguous.md
163
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/unambiguous.md
175
164
  // this should not be enabled until this proposal has at least been *presented* to TC39.
176
165
  // At the moment, it's not a thing.
177
- 'import/unambiguous': 'off',
166
+ 'import-x/unambiguous': 'off',
178
167
 
179
168
  // Forbid Webpack loader syntax in imports
180
- // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-webpack-loader-syntax.md
181
- 'import/no-webpack-loader-syntax': 'error',
169
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-webpack-loader-syntax.md
170
+ 'import-x/no-webpack-loader-syntax': 'error',
182
171
 
183
172
  // Prevent unassigned imports
184
- // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-unassigned-import.md
173
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-unassigned-import.md
185
174
  // importing for side effects is perfectly acceptable, if you need side effects.
186
- 'import/no-unassigned-import': 'off',
175
+ 'import-x/no-unassigned-import': 'off',
187
176
 
188
177
  // Prevent importing the default as if it were named
189
- // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-named-default.md
190
- 'import/no-named-default': 'error',
178
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-named-default.md
179
+ 'import-x/no-named-default': 'error',
191
180
 
192
181
  // Reports if a module's default export is unnamed
193
- // https://github.com/benmosher/eslint-plugin-import/blob/d9b712ac7fd1fddc391f7b234827925c160d956f/docs/rules/no-anonymous-default-export.md
194
- 'import/no-anonymous-default-export': [
182
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-anonymous-default-export.md
183
+ 'import-x/no-anonymous-default-export': [
195
184
  'off',
196
185
  {
197
186
  allowArray: false,
@@ -204,39 +193,39 @@ module.exports = {
204
193
  ],
205
194
 
206
195
  // This rule enforces that all exports are declared at the bottom of the file.
207
- // https://github.com/benmosher/eslint-plugin-import/blob/98acd6afd04dcb6920b81330114e146dc8532ea4/docs/rules/exports-last.md
196
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/exports-last.md
208
197
  // TODO: enable?
209
- 'import/exports-last': 'off',
198
+ 'import-x/exports-last': 'off',
210
199
 
211
200
  // Reports when named exports are not grouped together in a single export declaration
212
201
  // or when multiple assignments to CommonJS module.exports or exports object are present
213
202
  // in a single file.
214
- // https://github.com/benmosher/eslint-plugin-import/blob/44a038c06487964394b1e15b64f3bd34e5d40cde/docs/rules/group-exports.md
215
- 'import/group-exports': 'off',
203
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/group-exports.md
204
+ 'import-x/group-exports': 'off',
216
205
 
217
206
  // forbid default exports. this is a terrible rule, do not use it.
218
- // https://github.com/benmosher/eslint-plugin-import/blob/44a038c06487964394b1e15b64f3bd34e5d40cde/docs/rules/no-default-export.md
219
- 'import/no-default-export': 'off',
207
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-default-export.md
208
+ 'import-x/no-default-export': 'off',
220
209
 
221
210
  // Prohibit named exports. this is a terrible rule, do not use it.
222
- // https://github.com/benmosher/eslint-plugin-import/blob/1ec80fa35fa1819e2d35a70e68fb6a149fb57c5e/docs/rules/no-named-export.md
223
- 'import/no-named-export': 'off',
211
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-named-export.md
212
+ 'import-x/no-named-export': 'off',
224
213
 
225
214
  // Forbid a module from importing itself
226
- // https://github.com/benmosher/eslint-plugin-import/blob/44a038c06487964394b1e15b64f3bd34e5d40cde/docs/rules/no-self-import.md
227
- 'import/no-self-import': 'error',
215
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-self-import.md
216
+ 'import-x/no-self-import': 'error',
228
217
 
229
218
  // Forbid cyclical dependencies between modules
230
- // https://github.com/benmosher/eslint-plugin-import/blob/d81f48a2506182738409805f5272eff4d77c9348/docs/rules/no-cycle.md
231
- 'import/no-cycle': ['error', { maxDepth: '∞' }],
219
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-cycle.md
220
+ 'import-x/no-cycle': ['error', { maxDepth: '∞' }],
232
221
 
233
222
  // Ensures that there are no useless path segments
234
- // https://github.com/benmosher/eslint-plugin-import/blob/ebafcbf59ec9f653b2ac2a0156ca3bcba0a7cf57/docs/rules/no-useless-path-segments.md
235
- 'import/no-useless-path-segments': ['error', { commonjs: true }],
223
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-useless-path-segments.md
224
+ 'import-x/no-useless-path-segments': ['error', { commonjs: true }],
236
225
 
237
226
  // dynamic imports require a leading comment with a webpackChunkName
238
- // https://github.com/benmosher/eslint-plugin-import/blob/ebafcbf59ec9f653b2ac2a0156ca3bcba0a7cf57/docs/rules/dynamic-import-chunkname.md
239
- 'import/dynamic-import-chunkname': [
227
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/dynamic-import-chunkname.md
228
+ 'import-x/dynamic-import-chunkname': [
240
229
  'off',
241
230
  {
242
231
  importFunctions: [],
@@ -245,13 +234,13 @@ module.exports = {
245
234
  ],
246
235
 
247
236
  // Use this rule to prevent imports to folders in relative parent paths.
248
- // https://github.com/benmosher/eslint-plugin-import/blob/c34f14f67f077acd5a61b3da9c0b0de298d20059/docs/rules/no-relative-parent-imports.md
249
- 'import/no-relative-parent-imports': 'off',
237
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-relative-parent-imports.md
238
+ 'import-x/no-relative-parent-imports': 'off',
250
239
 
251
240
  // Reports modules without any exports, or with unused exports
252
- // https://github.com/benmosher/eslint-plugin-import/blob/f63dd261809de6883b13b6b5b960e6d7f42a7813/docs/rules/no-unused-modules.md
241
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-unused-modules.md
253
242
  // TODO: enable once it supports CJS
254
- 'import/no-unused-modules': [
243
+ 'import-x/no-unused-modules': [
255
244
  'off',
256
245
  {
257
246
  ignoreExports: [],
@@ -261,8 +250,8 @@ module.exports = {
261
250
  ],
262
251
 
263
252
  // Reports the use of import declarations with CommonJS exports in any module except for the main module.
264
- // https://github.com/benmosher/eslint-plugin-import/blob/1012eb951767279ce3b540a4ec4f29236104bb5b/docs/rules/no-import-module-exports.md
265
- 'import/no-import-module-exports': [
253
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-import-module-exports.md
254
+ 'import-x/no-import-module-exports': [
266
255
  'error',
267
256
  {
268
257
  exceptions: [],
@@ -270,7 +259,7 @@ module.exports = {
270
259
  ],
271
260
 
272
261
  // Use this rule to prevent importing packages through relative paths.
273
- // https://github.com/benmosher/eslint-plugin-import/blob/1012eb951767279ce3b540a4ec4f29236104bb5b/docs/rules/no-relative-packages.md
274
- 'import/no-relative-packages': 'error',
262
+ // https://github.com/un-ts/eslint-plugin-import-x/blob/master/docs/rules/no-relative-packages.md
263
+ 'import-x/no-relative-packages': 'error',
275
264
  },
276
265
  };
@@ -1,7 +1,7 @@
1
1
  const globals = require('globals');
2
2
  const unicornPlugin = require('eslint-plugin-unicorn');
3
3
  const promisePlugin = require('eslint-plugin-promise');
4
- const importPlugin = require('eslint-plugin-import');
4
+ const importPlugin = require('eslint-plugin-import-x');
5
5
 
6
6
  const confusingBrowserGlobals = require('../confusing-browser-globals');
7
7
  const gitlabPlugin = require('../plugin.js');
@@ -35,7 +35,7 @@ module.exports = [
35
35
  plugins: {
36
36
  unicorn: unicornPlugin,
37
37
  promise: promisePlugin,
38
- import: importPlugin,
38
+ 'import-x': importPlugin,
39
39
  '@gitlab': gitlabPlugin,
40
40
  },
41
41
  settings: imports.settings,
@@ -63,10 +63,10 @@ module.exports = [
63
63
  'arrow-body-style': 'off',
64
64
  'unicorn/filename-case': ['error', { case: 'snakeCase' }],
65
65
  'unicorn/no-array-callback-reference': 'error',
66
- 'import/prefer-default-export': 'off',
67
- 'import/no-default-export': 'error',
68
- 'import/no-deprecated': 'error',
69
- 'import/no-dynamic-require': ['error', { esmodule: true }],
66
+ 'import-x/prefer-default-export': 'off',
67
+ 'import-x/no-default-export': 'error',
68
+ 'import-x/no-deprecated': 'error',
69
+ 'import-x/no-dynamic-require': ['error', { esmodule: true }],
70
70
  'no-implicit-coercion': ['error', { boolean: true, number: true, string: true }],
71
71
  'no-param-reassign': [
72
72
  'error',
@@ -109,7 +109,7 @@ module.exports = [
109
109
  "The global `unescape` function is unsafe. Did you mean to use `decodeURI`, `decodeURIComponent` or lodash's `unescape` instead?",
110
110
  },
111
111
  ].concat(confusingBrowserGlobals),
112
- 'import/order': [
112
+ 'import-x/order': [
113
113
  'error',
114
114
  {
115
115
  groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'],
@@ -1,7 +1,7 @@
1
1
  const js = require('@eslint/js');
2
2
  const tsPlugin = require('@typescript-eslint/eslint-plugin');
3
3
  const tsParser = require('@typescript-eslint/parser');
4
- const importPlugin = require('eslint-plugin-import');
4
+ const importPlugin = require('eslint-plugin-import-x');
5
5
  const globals = require('globals');
6
6
 
7
7
  const base = require('./base');
@@ -23,7 +23,24 @@ const base = require('./base');
23
23
  */
24
24
  const tsEslintRecommended = tsPlugin.configs['flat/eslint-recommended'];
25
25
  const tsStrict = tsPlugin.configs.strict;
26
- const importTypescript = importPlugin.flatConfigs.typescript;
26
+ /*
27
+ Mirrors eslint-plugin-import's `typescript` preset. import-x's own
28
+ `flatConfigs.typescript` isn't used because its resolver needs
29
+ eslint-import-resolver-typescript.
30
+
31
+ Unlike base, this sets a resolver: import-x's default one doesn't know the
32
+ TypeScript extensions, so `import './foo'` wouldn't find `foo.ts`. Consumers
33
+ who need `paths` aliases replace it with eslint-import-resolver-typescript,
34
+ which also resolves everything this one does.
35
+ */
36
+ const TS_EXTENSIONS = ['.ts', '.cts', '.mts', '.tsx'];
37
+ const ALL_EXTENSIONS = [...TS_EXTENSIONS, '.js', '.jsx', '.mjs', '.cjs'];
38
+ const importTypescriptSettings = {
39
+ 'import-x/extensions': ALL_EXTENSIONS,
40
+ 'import-x/external-module-folders': ['node_modules', 'node_modules/@types'],
41
+ 'import-x/parsers': { '@typescript-eslint/parser': TS_EXTENSIONS },
42
+ 'import-x/resolver-next': [importPlugin.createNodeResolver({ extensions: ALL_EXTENSIONS })],
43
+ };
27
44
 
28
45
  module.exports = [
29
46
  ...base,
@@ -36,7 +53,7 @@ module.exports = [
36
53
  },
37
54
  },
38
55
  rules: {
39
- 'import/extensions': [
56
+ 'import-x/extensions': [
40
57
  'error',
41
58
  'ignorePackages',
42
59
  { js: 'never', jsx: 'never', ts: 'never', tsx: 'never' },
@@ -54,17 +71,17 @@ module.exports = [
54
71
  },
55
72
  plugins: {
56
73
  '@typescript-eslint': tsPlugin,
57
- import: importPlugin,
74
+ 'import-x': importPlugin,
58
75
  },
59
76
  linterOptions: {
60
77
  reportUnusedDisableDirectives: true,
61
78
  },
62
- settings: importTypescript.settings,
79
+ settings: importTypescriptSettings,
63
80
  rules: {
64
81
  ...js.configs.recommended.rules,
65
82
  ...tsEslintRecommended.rules,
66
83
  ...tsStrict.rules,
67
- ...importTypescript.rules,
84
+ 'import-x/named': 'off',
68
85
  semi: [2, 'always'],
69
86
  'max-params': 'off',
70
87
  'no-throw-literal': 'off',
@@ -79,7 +96,7 @@ module.exports = [
79
96
  '@typescript-eslint/no-floating-promises': 'error',
80
97
  '@typescript-eslint/explicit-member-accessibility': ['error', { accessibility: 'no-public' }],
81
98
  'class-methods-use-this': 'off',
82
- 'import/no-cycle': 'error',
99
+ 'import-x/no-cycle': 'error',
83
100
  'promise/param-names': 'off',
84
101
  'no-use-before-define': ['warn', 'nofunc'],
85
102
  'no-restricted-syntax': [
@@ -46,7 +46,7 @@ module.exports = {
46
46
  hasRenderFn,
47
47
  });
48
48
  }),
49
- 'Program:exit'(node) {
49
+ 'Program:exit'() {
50
50
  for (const { node, templateOption, hasRenderFn } of vues) {
51
51
  if (templateOption) {
52
52
  // Components can define a render function _and_ a template option,
@@ -92,7 +92,7 @@ module.exports = {
92
92
  }
93
93
 
94
94
  function stripVariables(value) {
95
- return value ? value.replace(/(\%{[\w-]+})/g, '') : '';
95
+ return value ? value.replace(/(%{[\w-]+})/g, '') : '';
96
96
  }
97
97
 
98
98
  function getCallExpressionString(node, callee) {
@@ -143,7 +143,7 @@ module.exports = {
143
143
 
144
144
  function isMemberExpressionIdentifier(expression) {
145
145
  if (expression.type !== 'MemberExpression') return false;
146
- if (!!expression.property.quasis) {
146
+ if (expression.property.quasis) {
147
147
  return /^\w+$/.test(getTemplateLiteralString(expression.property));
148
148
  }
149
149
  return /^\w+$/.test(expression.property.value);
@@ -164,14 +164,14 @@ module.exports = {
164
164
  }
165
165
 
166
166
  function isObjectMethod(node) {
167
- if (!!node.callee.property) {
167
+ if (node.callee.property) {
168
168
  return objectMethods.has(node.callee.property.name);
169
169
  }
170
170
  return false;
171
171
  }
172
172
 
173
173
  function isHtmlCall(node) {
174
- if (!!node.callee.property) {
174
+ if (node.callee.property) {
175
175
  return htmlCalls.has(node.callee.property.name);
176
176
  }
177
177
  return htmlCalls.has(node.callee.name);
@@ -13,7 +13,7 @@ class Rule {
13
13
  #context;
14
14
 
15
15
  constructor(context, options) {
16
- this.#vmWrapperNameParts = options.wrapperNames || commonVmWrapperNameParts;
16
+ this.#vmWrapperNameParts = options.wrapperNames;
17
17
  this.#context = context;
18
18
  }
19
19
 
@@ -24,7 +24,6 @@ module.exports = {
24
24
  },
25
25
 
26
26
  create(context) {
27
- const sourceCode = context.getSourceCode();
28
27
  const caseType = 'kebab-case';
29
28
 
30
29
  let hasInvalidEOF = false;
@@ -96,7 +96,7 @@ function isHardCodedUrl(context, value) {
96
96
 
97
97
  // Check for path-like patterns:
98
98
  // Starts with / followed by word characters
99
- const urlPathPattern = /^\/(?![#?])[\/\.a-zA-Z0-9_-]+/;
99
+ const urlPathPattern = /^\/(?![#?])[/.a-zA-Z0-9_-]+/;
100
100
 
101
101
  return urlPathPattern.test(value);
102
102
  }
@@ -6,13 +6,11 @@ function isFileName(value) {
6
6
  }
7
7
 
8
8
  function isPath(value) {
9
- return /^([\w-_]*|\.{1,2})[\/\~]+[\w-_\/]*/.test(value);
9
+ return /^([\w-_]*|\.{1,2})[/~]+[\w-_/]*/.test(value);
10
10
  }
11
11
 
12
12
  function isUrl(value) {
13
- return (
14
- /[a-zA-Z0-9]*(:\/\/)+[a-zA-Z0-9\.]*/.test(value) || /(http){1}[s:\/a-zA-Z0-9.]*/.test(value)
15
- );
13
+ return /[a-zA-Z0-9]*(:\/\/)+[a-zA-Z0-9.]*/.test(value) || /(http){1}[s:/a-zA-Z0-9.]*/.test(value);
16
14
  }
17
15
 
18
16
  function isMailto(str) {
@@ -39,11 +37,11 @@ function isListOfCssProperties(value) {
39
37
 
40
38
  function isCssSelector(value) {
41
39
  return (
42
- /^,?\s?[\.\#\*\@]\w+.*/.test(value) ||
43
- /^[a-zA-Z]+[a-zA-Z-]*[\.\#\*]+[a-zA-Z]+[a-zA-Z-]*/.test(value) ||
40
+ /^,?\s?[.#*@]\w+.*/.test(value) ||
41
+ /^[a-zA-Z]+[a-zA-Z-]*[.#*]+[a-zA-Z]+[a-zA-Z-]*/.test(value) ||
44
42
  /[a-zA-Z][a-zA-Z-]+[a-zA-Z]\.\w/.test(value) ||
45
43
  /([a-zA-Z]+[a-zA-Z-]*|\*)\[.*\]/.test(value) ||
46
- /^[a-zA-Z]+[a-zA-Z-]*[\#\*]$/.test(value) ||
44
+ /^[a-zA-Z]+[a-zA-Z-]*[#*]$/.test(value) ||
47
45
  /^(?:[0-9]+[a-z]|[a-z]+[0-9])[a-z0-9]*\s[a-z0-9][a-z0-9]+-[a-z0-9-]*$/.test(value) ||
48
46
  isListOfCssProperties(value) ||
49
47
  isListOfHtmlElements(value)
@@ -104,7 +102,7 @@ function containsAssignment(value) {
104
102
  }
105
103
 
106
104
  function isSpecial(value) {
107
- return /^[\:\%\_\&\#\?\[\$].*[^.]/.test(value) || /.*[\*\+]+$/.test(value);
105
+ return /^[:%_&#?[$].*[^.]/.test(value) || /.*[*+]+$/.test(value);
108
106
  }
109
107
 
110
108
  function isVariableName(value) {
@@ -3,7 +3,7 @@ const vueParser = require('vue-eslint-parser');
3
3
  const globals = require('globals');
4
4
  const unicornPlugin = require('eslint-plugin-unicorn');
5
5
  const promisePlugin = require('eslint-plugin-promise');
6
- const importPlugin = require('eslint-plugin-import');
6
+ const importPlugin = require('eslint-plugin-import-x');
7
7
 
8
8
  const gitlabPlugin = require('./plugin.js');
9
9
 
@@ -36,7 +36,7 @@ const presetAndSetup = [
36
36
  plugins: {
37
37
  unicorn: unicornPlugin,
38
38
  promise: promisePlugin,
39
- import: importPlugin,
39
+ 'import-x': importPlugin,
40
40
  '@gitlab': gitlabPlugin,
41
41
  },
42
42
  },
@@ -66,7 +66,7 @@ const gitlabRules = [
66
66
  '@gitlab/vue-prefer-dollar-scopedslots': 'error',
67
67
  '@gitlab/vue-slot-name-casing': 'error',
68
68
  '@gitlab/no-runtime-template-compiler': 'error',
69
- 'import/order': [
69
+ 'import-x/order': [
70
70
  'error',
71
71
  {
72
72
  groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'],
@@ -103,7 +103,7 @@ const gitlabRules = [
103
103
  name: '@gitlab/vue/sfc-overrides',
104
104
  files: ['**/*.vue'],
105
105
  rules: {
106
- 'import/no-default-export': 'off',
106
+ 'import-x/no-default-export': 'off',
107
107
  },
108
108
  },
109
109
  ];
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "@gitlab/eslint-plugin",
3
- "version": "22.0.0",
3
+ "version": "23.0.0",
4
4
  "description": "GitLab package for our custom eslint rules",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {
7
7
  "createRule": "./scripts/createRule.js && yarn update",
8
8
  "update": "./scripts/updateFiles.js && prettier --write lib/plugin.js lib/index.js",
9
9
  "commit": "npx git-cz",
10
+ "lint": "eslint .",
10
11
  "test": "mocha"
11
12
  },
12
13
  "repository": "https://gitlab.com/gitlab-org/frontend/eslint-plugin.git",
@@ -32,7 +33,7 @@
32
33
  "dependencies": {
33
34
  "@eslint/js": "^9.0.0",
34
35
  "eslint-config-prettier": "^10.0.0",
35
- "eslint-plugin-import": "^2.29.1",
36
+ "eslint-plugin-import-x": "^4.17.1",
36
37
  "eslint-plugin-jest": "^29.0.0",
37
38
  "eslint-plugin-promise": "^7.0.0",
38
39
  "eslint-plugin-tailwindcss": "^3.18.3",
@@ -37,7 +37,7 @@ for (let i = 0, len = allStrings.length; i < len; i++) {
37
37
 
38
38
  try {
39
39
  result = testFn(allStrings[i]) ? 'TRUE' : 'FALSE';
40
- } catch (e) {
40
+ } catch {
41
41
  result = 'TIMEOUT';
42
42
  }
43
43
 
@@ -6,8 +6,10 @@ const configsDir = path.join(__dirname, '../../lib/flat-configs');
6
6
  /*
7
7
  lib/flat-configs/ is a closed set: this glob decides what `yarn update`
8
8
  publishes as `plugin.configs[<basename>]`, so a shared helper dropped in that
9
- directory becomes a bogus public config. That is why lib/prettier-rules.js and
10
- lib/vue-fragments.js sit at the lib/ root instead; put new shared code there.
9
+ directory becomes a bogus public config, which tests/lib/configs/exports.spec.js
10
+ fails on once `yarn update` has regenerated lib/index.js. That is why
11
+ lib/prettier-rules.js and lib/vue-fragments.js sit at the lib/ root instead;
12
+ put new shared code there.
11
13
 
12
14
  No `.meta` spread, unlike getRules.js: a flat config exports an array.
13
15
  */
@@ -170,7 +170,6 @@ async function createReleases({ changesets, releases }) {
170
170
 
171
171
  if (type) {
172
172
  releaseDescriptionObject[type].push(
173
- // eslint-disable-next-line no-await-in-loop
174
173
  await defaultChangelogFunctions.getReleaseLine(changeset, type),
175
174
  );
176
175
  }
@@ -181,7 +180,6 @@ async function createReleases({ changesets, releases }) {
181
180
  .map(([type, lines]) => releaseSection(type, lines))
182
181
  .join('\n\n');
183
182
 
184
- // eslint-disable-next-line no-await-in-loop
185
183
  await createRelease({ tag: `v${release.newVersion}`, description });
186
184
  }
187
185
  }
@@ -1,75 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * ONE-SHOT generator. Resolves each eslintrc config in lib/configs/ into a
4
- * flat map of rule -> [severity, ...options] and writes it to
5
- * tests/fixtures/rule-maps/. Run once, on ESLint 8, BEFORE the flat-config
6
- * migration. Committed for reviewability; not wired into CI.
7
- *
8
- * Its inputs are gone and it no longer runs. Kept only as the provenance of
9
- * the frozen fixtures; deleted at the end of this stack.
10
- */
11
- const fs = require('fs');
12
- const path = require('path');
13
- const { ESLint } = require('eslint');
14
-
15
- const CONFIG_DIR = path.join(__dirname, '../lib/configs');
16
- const OUT_DIR = path.join(__dirname, '../tests/fixtures/rule-maps');
17
-
18
- // Top level only: lib/configs/base/ holds rule fragments, not configs.
19
- const CONFIGS = fs
20
- .readdirSync(CONFIG_DIR)
21
- .filter((file) => file.endsWith('.js'))
22
- .map((file) => path.basename(file, '.js'));
23
- const SAMPLES = ['sample.js', 'sample.vue', 'sample.ts', 'sample.test.ts'];
24
-
25
- const SEVERITIES = ['off', 'warn', 'error'];
26
-
27
- /** Normalise [2, opts] / 'error' / ['error', opts] into 'error' or ['error', ...opts]. */
28
- function normalizeEntry(entry) {
29
- const value = Array.isArray(entry) ? entry : [entry];
30
- const [severity, ...options] = value;
31
- const name = typeof severity === 'number' ? SEVERITIES[severity] : severity;
32
- return options.length > 0 ? [name, ...options] : name;
33
- }
34
-
35
- function normalizeRules(rules) {
36
- return Object.fromEntries(
37
- Object.keys(rules)
38
- .sort()
39
- .map((name) => [name, normalizeEntry(rules[name])]),
40
- );
41
- }
42
-
43
- async function mapForConfig(configName) {
44
- const configPath = require.resolve(`../lib/configs/${configName}.js`);
45
- const eslint = new ESLint({
46
- useEslintrc: false,
47
- // The plugin cannot resolve itself by name from inside its own repo.
48
- plugins: { '@gitlab': require('../lib/index.js') },
49
- baseConfig: { extends: [configPath] },
50
- });
51
-
52
- const resolved = await Promise.all(
53
- SAMPLES.map((sample) => eslint.calculateConfigForFile(path.join(process.cwd(), sample))),
54
- );
55
- return Object.fromEntries(
56
- SAMPLES.map((sample, index) => [sample, normalizeRules(resolved[index].rules || {})]),
57
- );
58
- }
59
-
60
- async function main() {
61
- fs.mkdirSync(OUT_DIR, { recursive: true });
62
- for (const name of CONFIGS) {
63
- // eslint-disable-next-line no-await-in-loop
64
- const map = await mapForConfig(name);
65
- const file = path.join(OUT_DIR, `${name}.json`);
66
- fs.writeFileSync(file, `${JSON.stringify(map, null, 2)}\n`);
67
- const counts = SAMPLES.map((sample) => `${sample} ${Object.keys(map[sample]).length}`);
68
- console.log(`Wrote ${path.relative(process.cwd(), file)} (${counts.join(', ')})`);
69
- }
70
- }
71
-
72
- main().catch((error) => {
73
- console.error(error);
74
- process.exit(1);
75
- });