xo 2.0.2 → 3.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/dist/cli.d.ts +0 -59
- package/dist/cli.js +139 -88
- package/dist/lib/config.js +2 -407
- package/dist/lib/constants.d.ts +1 -8
- package/dist/lib/constants.js +1 -18
- package/dist/lib/eslint-adapter.d.ts +3 -0
- package/dist/lib/eslint-adapter.js +58 -0
- package/dist/lib/handle-ts-files.d.ts +4 -1
- package/dist/lib/handle-ts-files.js +34 -5
- package/dist/lib/resolve-config.js +8 -7
- package/dist/lib/types.d.ts +10 -5
- package/dist/lib/utils.d.ts +10 -3
- package/dist/lib/utils.js +46 -31
- package/dist/lib/xo-to-eslint.d.ts +2 -6
- package/dist/lib/xo-to-eslint.js +31 -77
- package/dist/lib/xo.d.ts +21 -88
- package/dist/lib/xo.js +383 -261
- package/package.json +25 -64
- package/readme.md +135 -59
- package/dist/lib/rules/no-use-extend-native.d.ts +0 -3
- package/dist/lib/rules/no-use-extend-native.js +0 -386
package/dist/lib/config.js
CHANGED
|
@@ -1,411 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import pluginUnicorn from 'eslint-plugin-unicorn';
|
|
3
|
-
import pluginImport from 'eslint-plugin-import-x';
|
|
4
|
-
import pluginN from 'eslint-plugin-n';
|
|
5
|
-
import pluginComments from '@eslint-community/eslint-plugin-eslint-comments';
|
|
6
|
-
/// import pluginPromise from 'eslint-plugin-promise';
|
|
7
|
-
import configXoTypescript from 'eslint-config-xo-typescript';
|
|
8
|
-
import globals from 'globals';
|
|
9
|
-
import { fixupPluginRules } from '@eslint/compat';
|
|
10
|
-
import { defaultIgnores, tsExtensions, tsFilesGlob, allFilesGlob, jsExtensions, allExtensions, } from './constants.js';
|
|
11
|
-
import noUseExtendNativeRule from './rules/no-use-extend-native.js';
|
|
12
|
-
if (!configXoTypescript[4]) {
|
|
13
|
-
throw new Error('Invalid eslint-config-xo-typescript');
|
|
14
|
-
}
|
|
15
|
-
const baseLanguageOptions = configXoTypescript[0]?.languageOptions;
|
|
16
|
-
const baseParserOptions = baseLanguageOptions?.parserOptions ?? {};
|
|
17
|
-
const typescriptLanguageOptions = (configXoTypescript[4]?.languageOptions ?? {});
|
|
18
|
-
const typescriptParserOptions = typescriptLanguageOptions.parserOptions ?? {};
|
|
19
|
-
const pluginNoUseExtendNative = {
|
|
20
|
-
rules: {
|
|
21
|
-
'no-use-extend-native': noUseExtendNativeRule,
|
|
22
|
-
},
|
|
23
|
-
};
|
|
24
|
-
// TODO: Remove `fixupPluginRules` wrapping when these plugins support ESLint 10 natively.
|
|
25
|
-
const fixedUpBasePlugins = Object.fromEntries(Object.entries(configXoTypescript[0]?.plugins ?? {}).map(([key, plugin]) => [key, fixupPluginRules(plugin)]));
|
|
26
|
-
const fixedUpTypescriptPlugins = Object.fromEntries(Object.entries(configXoTypescript[4]?.plugins ?? {}).map(([key, plugin]) => [key, fixupPluginRules(plugin)]));
|
|
1
|
+
import eslintConfigXo from 'eslint-config-xo';
|
|
27
2
|
/**
|
|
28
3
|
The base config that XO builds on top of from user options.
|
|
29
4
|
*/
|
|
30
|
-
export const config =
|
|
31
|
-
{
|
|
32
|
-
name: 'xo/ignores',
|
|
33
|
-
ignores: defaultIgnores,
|
|
34
|
-
},
|
|
35
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
36
|
-
...pluginAva.configs['recommended'],
|
|
37
|
-
{
|
|
38
|
-
name: 'xo/base',
|
|
39
|
-
files: [allFilesGlob],
|
|
40
|
-
plugins: {
|
|
41
|
-
...fixedUpBasePlugins,
|
|
42
|
-
...fixedUpTypescriptPlugins,
|
|
43
|
-
'no-use-extend-native': pluginNoUseExtendNative,
|
|
44
|
-
ava: pluginAva,
|
|
45
|
-
unicorn: pluginUnicorn,
|
|
46
|
-
'import-x': pluginImport,
|
|
47
|
-
'@eslint-community/eslint-comments': pluginComments,
|
|
48
|
-
// TODO: Remove `fixupPluginRules` wrapping when these plugins support ESLint 10 natively.
|
|
49
|
-
n: fixupPluginRules(pluginN),
|
|
50
|
-
/// promise: fixupPluginRules(pluginPromise),
|
|
51
|
-
},
|
|
52
|
-
languageOptions: {
|
|
53
|
-
globals: {
|
|
54
|
-
...globals.es2021,
|
|
55
|
-
...globals.node,
|
|
56
|
-
},
|
|
57
|
-
ecmaVersion: baseLanguageOptions?.ecmaVersion,
|
|
58
|
-
sourceType: baseLanguageOptions?.sourceType,
|
|
59
|
-
parserOptions: {
|
|
60
|
-
...baseParserOptions,
|
|
61
|
-
},
|
|
62
|
-
},
|
|
63
|
-
settings: {
|
|
64
|
-
'import-x/extensions': allExtensions,
|
|
65
|
-
'import-x/core-modules': [
|
|
66
|
-
'electron',
|
|
67
|
-
'atom',
|
|
68
|
-
],
|
|
69
|
-
'import-x/parsers': {
|
|
70
|
-
espree: jsExtensions,
|
|
71
|
-
'@typescript-eslint/parser': tsExtensions,
|
|
72
|
-
},
|
|
73
|
-
'import-x/external-module-folders': [
|
|
74
|
-
'node_modules',
|
|
75
|
-
'node_modules/@types',
|
|
76
|
-
],
|
|
77
|
-
'import-x/resolver': {
|
|
78
|
-
node: allExtensions,
|
|
79
|
-
},
|
|
80
|
-
},
|
|
81
|
-
/**
|
|
82
|
-
These are the base rules that are always applied to all js and ts file types
|
|
83
|
-
*/
|
|
84
|
-
rules: {
|
|
85
|
-
...pluginUnicorn.configs?.recommended?.rules,
|
|
86
|
-
'no-use-extend-native/no-use-extend-native': 'error',
|
|
87
|
-
// TODO: Remove this override at some point.
|
|
88
|
-
// It's just here to ease users into readable variable names.
|
|
89
|
-
'unicorn/prevent-abbreviations': [
|
|
90
|
-
'error',
|
|
91
|
-
{
|
|
92
|
-
checkFilenames: false,
|
|
93
|
-
checkDefaultAndNamespaceImports: false,
|
|
94
|
-
checkShorthandImports: false,
|
|
95
|
-
extendDefaultReplacements: false,
|
|
96
|
-
replacements: {
|
|
97
|
-
// https://thenextweb.com/dd/2020/07/13/linux-kernel-will-no-longer-use-terms-blacklist-and-slave/
|
|
98
|
-
whitelist: {
|
|
99
|
-
include: true,
|
|
100
|
-
},
|
|
101
|
-
blacklist: {
|
|
102
|
-
exclude: true,
|
|
103
|
-
},
|
|
104
|
-
master: {
|
|
105
|
-
main: true,
|
|
106
|
-
},
|
|
107
|
-
slave: {
|
|
108
|
-
secondary: true,
|
|
109
|
-
},
|
|
110
|
-
// Not part of `eslint-plugin-unicorn`
|
|
111
|
-
application: {
|
|
112
|
-
app: true,
|
|
113
|
-
},
|
|
114
|
-
applications: {
|
|
115
|
-
apps: true,
|
|
116
|
-
},
|
|
117
|
-
// Part of `eslint-plugin-unicorn`
|
|
118
|
-
arr: {
|
|
119
|
-
array: true,
|
|
120
|
-
},
|
|
121
|
-
e: {
|
|
122
|
-
error: true,
|
|
123
|
-
event: true,
|
|
124
|
-
},
|
|
125
|
-
el: {
|
|
126
|
-
element: true,
|
|
127
|
-
},
|
|
128
|
-
elem: {
|
|
129
|
-
element: true,
|
|
130
|
-
},
|
|
131
|
-
len: {
|
|
132
|
-
length: true,
|
|
133
|
-
},
|
|
134
|
-
msg: {
|
|
135
|
-
message: true,
|
|
136
|
-
},
|
|
137
|
-
num: {
|
|
138
|
-
number: true,
|
|
139
|
-
},
|
|
140
|
-
obj: {
|
|
141
|
-
object: true,
|
|
142
|
-
},
|
|
143
|
-
opts: {
|
|
144
|
-
options: true,
|
|
145
|
-
},
|
|
146
|
-
param: {
|
|
147
|
-
parameter: true,
|
|
148
|
-
},
|
|
149
|
-
params: {
|
|
150
|
-
parameters: true,
|
|
151
|
-
},
|
|
152
|
-
prev: {
|
|
153
|
-
previous: true,
|
|
154
|
-
},
|
|
155
|
-
req: {
|
|
156
|
-
request: true,
|
|
157
|
-
},
|
|
158
|
-
res: {
|
|
159
|
-
response: true,
|
|
160
|
-
result: true,
|
|
161
|
-
},
|
|
162
|
-
ret: {
|
|
163
|
-
returnValue: true,
|
|
164
|
-
},
|
|
165
|
-
str: {
|
|
166
|
-
string: true,
|
|
167
|
-
},
|
|
168
|
-
temp: {
|
|
169
|
-
temporary: true,
|
|
170
|
-
},
|
|
171
|
-
tmp: {
|
|
172
|
-
temporary: true,
|
|
173
|
-
},
|
|
174
|
-
val: {
|
|
175
|
-
value: true,
|
|
176
|
-
},
|
|
177
|
-
err: {
|
|
178
|
-
error: true,
|
|
179
|
-
},
|
|
180
|
-
},
|
|
181
|
-
},
|
|
182
|
-
],
|
|
183
|
-
// TODO: Restore when it becomes safer: https://github.com/sindresorhus/eslint-plugin-unicorn/issues/681
|
|
184
|
-
// 'unicorn/string-content': [
|
|
185
|
-
// 'error',
|
|
186
|
-
// {
|
|
187
|
-
// patterns: {
|
|
188
|
-
// '': '’',
|
|
189
|
-
// [/\.\.\./.source]: '…',
|
|
190
|
-
// '->': '→',
|
|
191
|
-
// [/^http:\/\//.source]: 'http://'
|
|
192
|
-
// }
|
|
193
|
-
// }
|
|
194
|
-
// ],
|
|
195
|
-
// The character class sorting is a bit buggy at the moment.
|
|
196
|
-
'unicorn/better-regex': [
|
|
197
|
-
'error',
|
|
198
|
-
{
|
|
199
|
-
sortCharacterClasses: false,
|
|
200
|
-
},
|
|
201
|
-
],
|
|
202
|
-
// TODO: Disabled for now until it becomes more stable: https://github.com/sindresorhus/eslint-plugin-unicorn/search?q=consistent-destructuring+is:issue&state=open&type=issues
|
|
203
|
-
'unicorn/consistent-destructuring': 'off',
|
|
204
|
-
// TODO: Disabled for now as I don't have time to deal with the backslash that might come from this. Try to enable this rule in 2021.
|
|
205
|
-
'unicorn/no-null': 'off',
|
|
206
|
-
// We only enforce it for single-line statements to not be too opinionated.
|
|
207
|
-
'unicorn/prefer-ternary': ['error', 'only-single-line'],
|
|
208
|
-
// It will be disabled in the next version of eslint-plugin-unicorn.
|
|
209
|
-
'unicorn/prefer-json-parse-buffer': 'off',
|
|
210
|
-
// TODO: Remove this override when the rule is more stable.
|
|
211
|
-
'unicorn/consistent-function-scoping': 'off',
|
|
212
|
-
// TODO: Temporarily disabled until it becomes more mature.
|
|
213
|
-
'unicorn/no-useless-undefined': 'off',
|
|
214
|
-
// TODO: Temporarily disabled as the rule is buggy.
|
|
215
|
-
'function-call-argument-newline': 'off',
|
|
216
|
-
// Commented out because it's not ready for ESLint 10.
|
|
217
|
-
// 'promise/param-names': 'error',
|
|
218
|
-
// 'promise/no-return-wrap': [
|
|
219
|
-
// 'error',
|
|
220
|
-
// {
|
|
221
|
-
// allowReject: true,
|
|
222
|
-
// },
|
|
223
|
-
// ],
|
|
224
|
-
// 'promise/no-new-statics': 'error',
|
|
225
|
-
// 'promise/no-return-in-finally': 'error',
|
|
226
|
-
// 'promise/prefer-await-to-then': [
|
|
227
|
-
// 'error',
|
|
228
|
-
// {
|
|
229
|
-
// strict: true,
|
|
230
|
-
// },
|
|
231
|
-
// ],
|
|
232
|
-
// 'promise/prefer-catch': 'error',
|
|
233
|
-
// 'promise/valid-params': 'error',
|
|
234
|
-
'import-x/default': 'error',
|
|
235
|
-
'import-x/export': 'error',
|
|
236
|
-
'import-x/extensions': [
|
|
237
|
-
'error',
|
|
238
|
-
'always',
|
|
239
|
-
{
|
|
240
|
-
ignorePackages: true,
|
|
241
|
-
},
|
|
242
|
-
],
|
|
243
|
-
'import-x/first': 'error',
|
|
244
|
-
// Enabled, but disabled on TypeScript (https://github.com/xojs/xo/issues/576)
|
|
245
|
-
'import-x/named': 'error',
|
|
246
|
-
'import-x/namespace': [
|
|
247
|
-
'error',
|
|
248
|
-
{
|
|
249
|
-
allowComputed: true,
|
|
250
|
-
},
|
|
251
|
-
],
|
|
252
|
-
'import-x/no-absolute-path': 'error',
|
|
253
|
-
'import-x/no-anonymous-default-export': 'error',
|
|
254
|
-
'import-x/no-named-default': 'error',
|
|
255
|
-
'import-x/no-webpack-loader-syntax': 'error',
|
|
256
|
-
'import-x/no-self-import': 'error',
|
|
257
|
-
'import-x/no-cycle': [
|
|
258
|
-
'error',
|
|
259
|
-
{
|
|
260
|
-
ignoreExternal: true,
|
|
261
|
-
},
|
|
262
|
-
],
|
|
263
|
-
'import-x/no-useless-path-segments': 'error',
|
|
264
|
-
'import-x/newline-after-import': [
|
|
265
|
-
'error',
|
|
266
|
-
{
|
|
267
|
-
// TODO: Buggy.
|
|
268
|
-
// considerComments: true,
|
|
269
|
-
},
|
|
270
|
-
],
|
|
271
|
-
'import-x/no-amd': 'error',
|
|
272
|
-
'import-x/no-duplicates': [
|
|
273
|
-
'error',
|
|
274
|
-
{
|
|
275
|
-
'prefer-inline': true,
|
|
276
|
-
},
|
|
277
|
-
],
|
|
278
|
-
// We use `unicorn/prefer-module` instead.
|
|
279
|
-
// 'import-x/no-commonjs': 'error',
|
|
280
|
-
// Looks useful, but too unstable at the moment
|
|
281
|
-
// 'import-x/no-deprecated': 'error',
|
|
282
|
-
'import-x/no-empty-named-blocks': 'error',
|
|
283
|
-
'import-x/no-extraneous-dependencies': [
|
|
284
|
-
'error',
|
|
285
|
-
{
|
|
286
|
-
includeTypes: true,
|
|
287
|
-
},
|
|
288
|
-
],
|
|
289
|
-
'import-x/no-mutable-exports': 'error',
|
|
290
|
-
'import-x/no-named-as-default-member': 'error',
|
|
291
|
-
'import-x/no-named-as-default': 'error',
|
|
292
|
-
// Disabled because it's buggy and it also doesn't work with TypeScript
|
|
293
|
-
// 'import-x/no-unresolved': [
|
|
294
|
-
// 'error',
|
|
295
|
-
// {
|
|
296
|
-
// commonjs: false
|
|
297
|
-
// }
|
|
298
|
-
// ],
|
|
299
|
-
'import-x/order': [
|
|
300
|
-
'error',
|
|
301
|
-
{
|
|
302
|
-
groups: ['builtin', 'external', 'parent', 'sibling', 'index'],
|
|
303
|
-
'newlines-between': 'never',
|
|
304
|
-
warnOnUnassignedImports: true,
|
|
305
|
-
},
|
|
306
|
-
],
|
|
307
|
-
'import-x/no-unassigned-import': [
|
|
308
|
-
'error',
|
|
309
|
-
{
|
|
310
|
-
allow: [
|
|
311
|
-
'@babel/polyfill',
|
|
312
|
-
'**/register',
|
|
313
|
-
'**/register.*',
|
|
314
|
-
'**/register/**',
|
|
315
|
-
'**/register/**.*',
|
|
316
|
-
'**/*.css',
|
|
317
|
-
'**/*.scss',
|
|
318
|
-
'**/*.sass',
|
|
319
|
-
'**/*.less',
|
|
320
|
-
],
|
|
321
|
-
},
|
|
322
|
-
],
|
|
323
|
-
// Redundant with `import-x/no-extraneous-dependencies`.
|
|
324
|
-
'n/no-extraneous-import': 'error',
|
|
325
|
-
// 'n/no-extraneous-require': 'error',
|
|
326
|
-
// Redundant with `import-x/no-unresolved`.
|
|
327
|
-
// 'n/no-missing-import': 'error', // This rule is also buggy and doesn't support `node:`.
|
|
328
|
-
// 'n/no-missing-require': 'error',
|
|
329
|
-
'n/no-unpublished-bin': 'error',
|
|
330
|
-
// We have this enabled in addition to `import-x/extensions` as this one has an auto-fix.
|
|
331
|
-
'n/file-extension-in-import': [
|
|
332
|
-
'error',
|
|
333
|
-
'always',
|
|
334
|
-
{
|
|
335
|
-
// TypeScript doesn't yet support using extensions and fails with error TS2691.
|
|
336
|
-
'.ts': 'never', // eslint-disable-line @typescript-eslint/naming-convention
|
|
337
|
-
'.tsx': 'never', // eslint-disable-line @typescript-eslint/naming-convention
|
|
338
|
-
},
|
|
339
|
-
],
|
|
340
|
-
'n/no-mixed-requires': [
|
|
341
|
-
'error',
|
|
342
|
-
{
|
|
343
|
-
grouping: true,
|
|
344
|
-
allowCall: true,
|
|
345
|
-
},
|
|
346
|
-
],
|
|
347
|
-
'n/no-new-require': 'error',
|
|
348
|
-
'n/no-path-concat': 'error',
|
|
349
|
-
'n/process-exit-as-throw': 'error',
|
|
350
|
-
'n/no-deprecated-api': 'error',
|
|
351
|
-
'n/prefer-global/buffer': ['error', 'never'],
|
|
352
|
-
'n/prefer-global/console': ['error', 'always'],
|
|
353
|
-
'n/prefer-global/process': ['error', 'never'],
|
|
354
|
-
'n/prefer-global/text-decoder': ['error', 'always'],
|
|
355
|
-
'n/prefer-global/text-encoder': ['error', 'always'],
|
|
356
|
-
'n/prefer-global/url-search-params': ['error', 'always'],
|
|
357
|
-
'n/prefer-global/url': ['error', 'always'],
|
|
358
|
-
'n/prefer-promises/dns': 'error',
|
|
359
|
-
'n/prefer-promises/fs': 'error',
|
|
360
|
-
'@eslint-community/eslint-comments/disable-enable-pair': [
|
|
361
|
-
'error',
|
|
362
|
-
{
|
|
363
|
-
allowWholeFile: true,
|
|
364
|
-
},
|
|
365
|
-
],
|
|
366
|
-
'@eslint-community/eslint-comments/no-aggregating-enable': 'error',
|
|
367
|
-
'@eslint-community/eslint-comments/no-duplicate-disable': 'error',
|
|
368
|
-
// Disabled as it's already covered by the `unicorn/no-abusive-eslint-disable` rule.
|
|
369
|
-
// 'eslint-comments/no-unlimited-disable': 'error',
|
|
370
|
-
'@eslint-community/eslint-comments/no-unused-disable': 'error',
|
|
371
|
-
'@eslint-community/eslint-comments/no-unused-enable': 'error',
|
|
372
|
-
...configXoTypescript[0]?.rules,
|
|
373
|
-
},
|
|
374
|
-
},
|
|
375
|
-
{
|
|
376
|
-
name: 'xo/typescript',
|
|
377
|
-
plugins: fixedUpTypescriptPlugins,
|
|
378
|
-
files: [tsFilesGlob],
|
|
379
|
-
languageOptions: {
|
|
380
|
-
...typescriptLanguageOptions,
|
|
381
|
-
parserOptions: {
|
|
382
|
-
...typescriptParserOptions,
|
|
383
|
-
// This needs to be explicitly set to `true`
|
|
384
|
-
projectService: true,
|
|
385
|
-
},
|
|
386
|
-
},
|
|
387
|
-
/**
|
|
388
|
-
This turns on rules in `typescript-eslint`` and turns off rules from ESLint that conflict.
|
|
389
|
-
*/
|
|
390
|
-
rules: {
|
|
391
|
-
...configXoTypescript[4]?.rules,
|
|
392
|
-
'unicorn/import-style': 'off',
|
|
393
|
-
'n/file-extension-in-import': 'off',
|
|
394
|
-
// Disabled because of https://github.com/benmosher/eslint-plugin-import-x/issues/1590
|
|
395
|
-
'import-x/export': 'off',
|
|
396
|
-
// Does not work when the TS definition exports a default const.
|
|
397
|
-
'import-x/default': 'off',
|
|
398
|
-
// Disabled as it doesn't work with TypeScript.
|
|
399
|
-
// This issue and some others: https://github.com/benmosher/eslint-plugin-import-x/issues/1341
|
|
400
|
-
'import-x/named': 'off',
|
|
401
|
-
},
|
|
402
|
-
},
|
|
403
|
-
...configXoTypescript.slice(5),
|
|
404
|
-
{
|
|
405
|
-
files: ['xo.config.{js,ts}'],
|
|
406
|
-
rules: {
|
|
407
|
-
'import-x/no-anonymous-default-export': 'off',
|
|
408
|
-
},
|
|
409
|
-
},
|
|
410
|
-
];
|
|
5
|
+
export const config = eslintConfigXo();
|
|
411
6
|
//# sourceMappingURL=config.js.map
|
package/dist/lib/constants.d.ts
CHANGED
|
@@ -1,17 +1,10 @@
|
|
|
1
1
|
import { type TsConfigJsonResolved } from 'get-tsconfig';
|
|
2
|
-
export
|
|
2
|
+
export { tsExtensions, jsExtensions, frameworkExtensions, allExtensions, jsFilesGlob, tsFilesGlob, allFilesGlob, defaultIgnores, } from 'eslint-config-xo';
|
|
3
3
|
/**
|
|
4
4
|
List of options that values will be concatenanted during option merge.
|
|
5
5
|
|
|
6
6
|
Only applies to options defined as an Array.
|
|
7
7
|
*/
|
|
8
|
-
export declare const tsExtensions: string[];
|
|
9
|
-
export declare const jsExtensions: string[];
|
|
10
|
-
export declare const frameworkExtensions: string[];
|
|
11
|
-
export declare const jsFilesGlob: string;
|
|
12
|
-
export declare const tsFilesGlob: string;
|
|
13
|
-
export declare const allExtensions: string[];
|
|
14
|
-
export declare const allFilesGlob: string;
|
|
15
8
|
export declare const moduleName = "xo";
|
|
16
9
|
export declare const tsconfigDefaults: TsConfigJsonResolved;
|
|
17
10
|
export declare const cacheDirName = "xo-linter";
|
package/dist/lib/constants.js
CHANGED
|
@@ -1,26 +1,9 @@
|
|
|
1
|
-
export
|
|
2
|
-
'**/node_modules/**',
|
|
3
|
-
'**/bower_components/**',
|
|
4
|
-
'flow-typed/**',
|
|
5
|
-
'coverage/**',
|
|
6
|
-
'{tmp,temp}/**',
|
|
7
|
-
'**/*.min.js',
|
|
8
|
-
'vendor/**',
|
|
9
|
-
'dist/**',
|
|
10
|
-
'tap-snapshots/*.{cjs,js}',
|
|
11
|
-
];
|
|
1
|
+
export { tsExtensions, jsExtensions, frameworkExtensions, allExtensions, jsFilesGlob, tsFilesGlob, allFilesGlob, defaultIgnores, } from 'eslint-config-xo';
|
|
12
2
|
/**
|
|
13
3
|
List of options that values will be concatenanted during option merge.
|
|
14
4
|
|
|
15
5
|
Only applies to options defined as an Array.
|
|
16
6
|
*/
|
|
17
|
-
export const tsExtensions = ['ts', 'tsx', 'cts', 'mts'];
|
|
18
|
-
export const jsExtensions = ['js', 'jsx', 'mjs', 'cjs'];
|
|
19
|
-
export const frameworkExtensions = ['vue', 'svelte', 'astro'];
|
|
20
|
-
export const jsFilesGlob = `**/*.{${jsExtensions.join(',')}}`;
|
|
21
|
-
export const tsFilesGlob = `**/*.{${tsExtensions.join(',')}}`;
|
|
22
|
-
export const allExtensions = [...jsExtensions, ...tsExtensions, ...frameworkExtensions];
|
|
23
|
-
export const allFilesGlob = `**/*.{${allExtensions.join(',')}}`;
|
|
24
7
|
export const moduleName = 'xo';
|
|
25
8
|
export const tsconfigDefaults = {
|
|
26
9
|
compilerOptions: {
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import process from 'node:process';
|
|
4
|
+
import { Xo } from './xo.js';
|
|
5
|
+
const eslintConfigNames = [
|
|
6
|
+
'eslint.config.js',
|
|
7
|
+
'eslint.config.mjs',
|
|
8
|
+
'eslint.config.cjs',
|
|
9
|
+
'eslint.config.ts',
|
|
10
|
+
'eslint.config.mts',
|
|
11
|
+
'eslint.config.cts',
|
|
12
|
+
];
|
|
13
|
+
function findEslintConfigDirectory(cwd) {
|
|
14
|
+
let currentDirectory = cwd;
|
|
15
|
+
for (;;) {
|
|
16
|
+
for (const configName of eslintConfigNames) {
|
|
17
|
+
if (fs.existsSync(path.join(currentDirectory, configName))) {
|
|
18
|
+
return currentDirectory;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
const parentDirectory = path.dirname(currentDirectory);
|
|
22
|
+
if (parentDirectory === currentDirectory) {
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
currentDirectory = parentDirectory;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function resolveConfigPathFromArgv() {
|
|
29
|
+
const { argv } = process;
|
|
30
|
+
for (const [index, argument] of argv.entries()) {
|
|
31
|
+
if (argument === '--config' || argument === '-c') {
|
|
32
|
+
return argv[index + 1];
|
|
33
|
+
}
|
|
34
|
+
if (argument.startsWith('--config=')) {
|
|
35
|
+
return argument.slice('--config='.length);
|
|
36
|
+
}
|
|
37
|
+
if (argument.startsWith('-c=')) {
|
|
38
|
+
return argument.slice('-c='.length);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
function resolveAdapterCwd() {
|
|
44
|
+
const configPath = resolveConfigPathFromArgv();
|
|
45
|
+
if (configPath !== undefined && configPath !== '') {
|
|
46
|
+
return path.dirname(path.resolve(process.cwd(), configPath));
|
|
47
|
+
}
|
|
48
|
+
return findEslintConfigDirectory(process.cwd()) ?? process.cwd();
|
|
49
|
+
}
|
|
50
|
+
/*
|
|
51
|
+
Keep the adapter small: resolve XO relative to the ESLint config location, then reuse XO's existing project config pipeline.
|
|
52
|
+
|
|
53
|
+
The project files are resolved once when this module is imported; files added afterwards are not picked up until ESLint reloads the config.
|
|
54
|
+
*/
|
|
55
|
+
// `ts: true` keeps XO's TypeScript fallback so TS files are linted even without a `tsconfig.json`, matching the CLI.
|
|
56
|
+
const eslintConfig = await new Xo({ cwd: resolveAdapterCwd(), ts: true }).getProjectEslintConfig();
|
|
57
|
+
export default eslintConfig;
|
|
58
|
+
//# sourceMappingURL=eslint-adapter.js.map
|
|
@@ -4,7 +4,10 @@ This function checks if the files are matched by the tsconfig include, exclude,
|
|
|
4
4
|
|
|
5
5
|
If no tsconfig is found, it will create an in-memory TypeScript Program for type-aware linting.
|
|
6
6
|
|
|
7
|
-
@param options
|
|
7
|
+
@param options - The options for handling the tsconfig.
|
|
8
|
+
@param options.files - The TypeScript files to check against the tsconfig.
|
|
9
|
+
@param options.cwd - The current working directory.
|
|
10
|
+
@param options.cacheLocation - The cache directory used to detect virtual/stdin files.
|
|
8
11
|
@returns The unmatched files and an in-memory TypeScript Program.
|
|
9
12
|
*/
|
|
10
13
|
export declare function handleTsconfig({ files, cwd, cacheLocation }: {
|
|
@@ -1,8 +1,34 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import fs from 'node:fs';
|
|
3
|
+
import { createRequire } from 'node:module';
|
|
3
4
|
import ts from 'typescript';
|
|
4
5
|
import { getTsconfig, createFilesMatcher } from 'get-tsconfig';
|
|
5
6
|
import { tsconfigDefaults } from './constants.js';
|
|
7
|
+
let hasWarnedAboutTypeScriptVersion = false;
|
|
8
|
+
/**
|
|
9
|
+
Warns once if the project's own TypeScript is an older major than the version XO bundles. Mixing TypeScript versions in one process can crash type-aware linting (notably under pnpm), because the TypeFlags enum was renumbered in TypeScript 6.
|
|
10
|
+
*/
|
|
11
|
+
const warnOnOutdatedProjectTypeScript = (cwd) => {
|
|
12
|
+
if (hasWarnedAboutTypeScriptVersion) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
let projectVersion;
|
|
16
|
+
try {
|
|
17
|
+
const require = createRequire(path.join(cwd, 'noop.js'));
|
|
18
|
+
({ version: projectVersion } = require('typescript/package.json'));
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
// No project-level TypeScript resolvable; XO's bundled version is used, so there is no mismatch.
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const projectMajor = Number(projectVersion.split('.', 1)[0]);
|
|
25
|
+
const bundledMajor = Number(ts.version.split('.', 1)[0]);
|
|
26
|
+
if (projectMajor >= bundledMajor) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
hasWarnedAboutTypeScriptVersion = true;
|
|
30
|
+
console.warn(`XO bundles TypeScript ${ts.version}, but your project has TypeScript ${projectVersion}. Mixing TypeScript versions in one process can crash type-aware linting (notably with pnpm). Upgrade your project's \`typescript\` to ${bundledMajor} or later, or pin it (for example, a pnpm \`overrides\` entry).`);
|
|
31
|
+
};
|
|
6
32
|
const createInMemoryProgram = (files, cwd) => {
|
|
7
33
|
if (files.length === 0) {
|
|
8
34
|
return undefined;
|
|
@@ -51,10 +77,14 @@ This function checks if the files are matched by the tsconfig include, exclude,
|
|
|
51
77
|
|
|
52
78
|
If no tsconfig is found, it will create an in-memory TypeScript Program for type-aware linting.
|
|
53
79
|
|
|
54
|
-
@param options
|
|
80
|
+
@param options - The options for handling the tsconfig.
|
|
81
|
+
@param options.files - The TypeScript files to check against the tsconfig.
|
|
82
|
+
@param options.cwd - The current working directory.
|
|
83
|
+
@param options.cacheLocation - The cache directory used to detect virtual/stdin files.
|
|
55
84
|
@returns The unmatched files and an in-memory TypeScript Program.
|
|
56
85
|
*/
|
|
57
86
|
export function handleTsconfig({ files, cwd, cacheLocation }) {
|
|
87
|
+
warnOnOutdatedProjectTypeScript(cwd);
|
|
58
88
|
const unincludedFiles = [];
|
|
59
89
|
const filesMatcherCache = new Map();
|
|
60
90
|
for (const filePath of files) {
|
|
@@ -63,7 +93,7 @@ export function handleTsconfig({ files, cwd, cacheLocation }) {
|
|
|
63
93
|
unincludedFiles.push(filePath);
|
|
64
94
|
continue;
|
|
65
95
|
}
|
|
66
|
-
const cacheKey = result.path ? path.resolve(result.path)
|
|
96
|
+
const cacheKey = result.path === '' ? filePath : path.resolve(result.path);
|
|
67
97
|
let filesMatcher = filesMatcherCache.get(cacheKey);
|
|
68
98
|
if (!filesMatcher) {
|
|
69
99
|
filesMatcher = createFilesMatcher(result);
|
|
@@ -83,15 +113,14 @@ export function handleTsconfig({ files, cwd, cacheLocation }) {
|
|
|
83
113
|
const existingFiles = [];
|
|
84
114
|
const virtualFiles = [];
|
|
85
115
|
for (const file of unincludedFiles) {
|
|
86
|
-
const fileExists = fs.existsSync(file);
|
|
87
116
|
// Files that don't exist are always virtual
|
|
88
|
-
if (!
|
|
117
|
+
if (!fs.existsSync(file)) {
|
|
89
118
|
virtualFiles.push(file);
|
|
90
119
|
continue;
|
|
91
120
|
}
|
|
92
121
|
// Check if file is in cache directory (like stdin files)
|
|
93
122
|
// These need tsconfig treatment even though they exist on disk
|
|
94
|
-
if (cacheLocation) {
|
|
123
|
+
if (cacheLocation !== undefined) {
|
|
95
124
|
const absolutePath = path.resolve(file);
|
|
96
125
|
const cacheRoot = path.resolve(cacheLocation);
|
|
97
126
|
const relativeToCache = path.relative(cacheRoot, absolutePath);
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import process from 'node:process';
|
|
3
|
-
import { cosmiconfig
|
|
3
|
+
import { cosmiconfig } from 'cosmiconfig';
|
|
4
4
|
import arrify from 'arrify';
|
|
5
|
+
import { createJiti } from 'jiti';
|
|
5
6
|
import { moduleName } from './constants.js';
|
|
7
|
+
const jiti = createJiti(import.meta.url, { moduleCache: false });
|
|
8
|
+
const loadTypeScriptConfig = async (filepath) => jiti.import(filepath, { default: true });
|
|
6
9
|
/**
|
|
7
10
|
Finds the XO config file.
|
|
8
11
|
*/
|
|
@@ -22,7 +25,8 @@ export async function resolveXoConfig(options) {
|
|
|
22
25
|
`${moduleName}.config.mts`,
|
|
23
26
|
],
|
|
24
27
|
loaders: {
|
|
25
|
-
'.
|
|
28
|
+
'.ts': loadTypeScriptConfig,
|
|
29
|
+
'.mts': loadTypeScriptConfig,
|
|
26
30
|
},
|
|
27
31
|
stopDir: stopDirectory,
|
|
28
32
|
cache: true,
|
|
@@ -30,10 +34,8 @@ export async function resolveXoConfig(options) {
|
|
|
30
34
|
options.filePath &&= path.resolve(options.cwd, options.filePath);
|
|
31
35
|
const searchPath = options.filePath ?? options.cwd;
|
|
32
36
|
let { config: flatOptions = [], filepath: flatConfigPath = '', // eslint-disable-line @typescript-eslint/no-useless-default-assignment
|
|
33
|
-
} = await (options.configPath
|
|
34
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
37
|
+
} = await (options.configPath !== undefined && options.configPath !== ''
|
|
35
38
|
? flatConfigExplorer.load(path.resolve(options.cwd, options.configPath))
|
|
36
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
37
39
|
: flatConfigExplorer.search(searchPath)) ?? {};
|
|
38
40
|
flatOptions = arrify(flatOptions);
|
|
39
41
|
return {
|
|
@@ -42,8 +44,7 @@ export async function resolveXoConfig(options) {
|
|
|
42
44
|
};
|
|
43
45
|
}
|
|
44
46
|
catch (error) {
|
|
45
|
-
|
|
46
|
-
throw new AggregateError([error], 'Error resolving XO config, there is likely an issue with your config file. Please check the file for mistakes.');
|
|
47
|
+
throw new Error('Error resolving XO config, there is likely an issue with your config file. Please check the file for mistakes.', { cause: error });
|
|
47
48
|
}
|
|
48
49
|
}
|
|
49
50
|
export default resolveXoConfig;
|