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.
@@ -1,411 +1,6 @@
1
- import pluginAva from 'eslint-plugin-ava';
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
@@ -1,17 +1,10 @@
1
1
  import { type TsConfigJsonResolved } from 'get-tsconfig';
2
- export declare const defaultIgnores: string[];
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";
@@ -1,26 +1,9 @@
1
- export const defaultIgnores = [
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,3 @@
1
+ import { type Linter } from 'eslint';
2
+ declare const eslintConfig: Linter.Config[];
3
+ export default eslintConfig;
@@ -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) : filePath;
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 (!fileExists) {
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, defaultLoaders } from '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
- '.mts': defaultLoaders['.ts'], // eslint-disable-line @typescript-eslint/naming-convention
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
- // eslint-disable-next-line preserve-caught-error
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;