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/types.d.ts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import type { Simplify } from 'type-fest';
|
|
2
2
|
import { type ESLint, type Rule, type Linter } from 'eslint';
|
|
3
3
|
export type Space = boolean | number | string | undefined;
|
|
4
|
+
export type TypeScriptParserOptions = Linter.ParserOptions & {
|
|
5
|
+
project?: string | string[] | boolean;
|
|
6
|
+
projectService?: boolean;
|
|
7
|
+
tsconfigRootDir?: string;
|
|
8
|
+
programs?: unknown[];
|
|
9
|
+
};
|
|
4
10
|
export type XoConfigOptions = {
|
|
5
11
|
/**
|
|
6
12
|
Use spaces for indentation.
|
|
@@ -19,10 +25,6 @@ export type XoConfigOptions = {
|
|
|
19
25
|
*/
|
|
20
26
|
prettier?: boolean | 'compat';
|
|
21
27
|
/**
|
|
22
|
-
Add React support.
|
|
23
|
-
*/
|
|
24
|
-
react?: boolean;
|
|
25
|
-
/**
|
|
26
28
|
Files to ignore, can be a glob or array of globs.
|
|
27
29
|
*/
|
|
28
30
|
ignores?: string | string[];
|
|
@@ -49,13 +51,16 @@ export type LinterOptions = {
|
|
|
49
51
|
|
|
50
52
|
Ensures that TypeScript files are linted with the type-aware parser even if they are not explicitly included in the tsconfig.
|
|
51
53
|
|
|
52
|
-
@private
|
|
53
54
|
*/
|
|
54
55
|
ts?: boolean;
|
|
55
56
|
/**
|
|
56
57
|
Custom path to config to use for the linter.
|
|
57
58
|
*/
|
|
58
59
|
configPath?: string;
|
|
60
|
+
/**
|
|
61
|
+
Path to the ESLint suppressions file. Defaults to `eslint-suppressions.json` in the working directory.
|
|
62
|
+
*/
|
|
63
|
+
suppressionsLocation?: string;
|
|
59
64
|
};
|
|
60
65
|
export type LintTextOptions = {
|
|
61
66
|
/**
|
package/dist/lib/utils.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type Linter } from 'eslint';
|
|
2
|
+
import { typescriptParser } from 'eslint-config-xo';
|
|
2
3
|
import { type XoConfigItem } from './types.js';
|
|
3
|
-
export
|
|
4
|
+
export { typescriptParser };
|
|
4
5
|
/**
|
|
5
6
|
Convert a `xo` config item to an ESLint config item.
|
|
6
7
|
|
|
@@ -8,8 +9,8 @@ In a flat structure these config items represent the config object items.
|
|
|
8
9
|
|
|
9
10
|
Files and rules will always be defined and all other ESLint config properties are preserved.
|
|
10
11
|
|
|
11
|
-
@param xoConfig
|
|
12
|
-
@returns
|
|
12
|
+
@param xoConfig - The XO config item to convert.
|
|
13
|
+
@returns The equivalent ESLint config item.
|
|
13
14
|
*/
|
|
14
15
|
export declare const xoToEslintConfigItem: (xoConfig: XoConfigItem) => Linter.Config;
|
|
15
16
|
/**
|
|
@@ -23,6 +24,12 @@ Function used to match files which should be included in the `tsconfig.json` fil
|
|
|
23
24
|
*/
|
|
24
25
|
export declare const matchFilesForTsConfig: (cwd: string, files: string[] | undefined, globs: string[], ignores: string[]) => string[];
|
|
25
26
|
/**
|
|
27
|
+
Validate an XO config array for legacy ESLint config properties that are not supported in flat config.
|
|
28
|
+
|
|
29
|
+
@param xoConfig - The flat XO config to validate.
|
|
30
|
+
*/
|
|
31
|
+
export declare const validateXoConfig: (xoConfig: XoConfigItem[]) => void;
|
|
32
|
+
/**
|
|
26
33
|
Once a config is resolved, it is pre-processed to ensure that all properties are set correctly.
|
|
27
34
|
|
|
28
35
|
This includes ensuring that user-defined properties can override XO defaults, and that files are parsed correctly and performantly based on the users XO config.
|
package/dist/lib/utils.js
CHANGED
|
@@ -1,16 +1,9 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import micromatch from 'micromatch';
|
|
3
3
|
import arrify from 'arrify';
|
|
4
|
-
import
|
|
4
|
+
import { typescriptParser } from 'eslint-config-xo';
|
|
5
5
|
import { allFilesGlob, jsExtensions, jsFilesGlob, } from './constants.js';
|
|
6
|
-
|
|
7
|
-
const languageOptions = config.languageOptions;
|
|
8
|
-
return languageOptions?.parser;
|
|
9
|
-
});
|
|
10
|
-
export const typescriptParser = typescriptParserConfig?.languageOptions?.parser;
|
|
11
|
-
if (!typescriptParser) {
|
|
12
|
-
throw new Error('XO: Failed to locate TypeScript parser in eslint-config-xo-typescript');
|
|
13
|
-
}
|
|
6
|
+
export { typescriptParser }; // eslint-disable-line unicorn/prefer-export-from -- Also used locally
|
|
14
7
|
/**
|
|
15
8
|
Convert a `xo` config item to an ESLint config item.
|
|
16
9
|
|
|
@@ -18,15 +11,15 @@ In a flat structure these config items represent the config object items.
|
|
|
18
11
|
|
|
19
12
|
Files and rules will always be defined and all other ESLint config properties are preserved.
|
|
20
13
|
|
|
21
|
-
@param xoConfig
|
|
22
|
-
@returns
|
|
14
|
+
@param xoConfig - The XO config item to convert.
|
|
15
|
+
@returns The equivalent ESLint config item.
|
|
23
16
|
*/
|
|
24
17
|
export const xoToEslintConfigItem = (xoConfig) => {
|
|
25
|
-
const { files, rules, space, prettier, ignores, semicolon
|
|
18
|
+
const { files, rules, space, prettier, ignores, semicolon: hasSemicolon, ..._xoConfig } = xoConfig;
|
|
26
19
|
const eslintConfig = {
|
|
27
20
|
..._xoConfig,
|
|
28
|
-
...(xoConfig.files
|
|
29
|
-
...(xoConfig.rules
|
|
21
|
+
...(xoConfig.files !== undefined && { files: arrify(xoConfig.files) }),
|
|
22
|
+
...(xoConfig.rules && { rules: xoConfig.rules }),
|
|
30
23
|
};
|
|
31
24
|
eslintConfig.ignores &&= arrify(xoConfig.ignores);
|
|
32
25
|
return eslintConfig;
|
|
@@ -47,6 +40,37 @@ globs.map(glob => path.normalize(glob)), {
|
|
|
47
40
|
ignore: ignores.map(file => path.normalize(file)),
|
|
48
41
|
cwd,
|
|
49
42
|
}).map(file => path.resolve(cwd, file));
|
|
43
|
+
const legacyPropertyHints = {
|
|
44
|
+
overrides: 'Use an array of config objects with `files` patterns instead.',
|
|
45
|
+
extends: 'Spread the config directly into your XO config array.',
|
|
46
|
+
env: 'Use `languageOptions.globals` instead.',
|
|
47
|
+
globals: 'Move to `languageOptions.globals`.',
|
|
48
|
+
parser: 'Move to `languageOptions.parser`.',
|
|
49
|
+
parserOptions: 'Move to `languageOptions.parserOptions`.',
|
|
50
|
+
root: 'Not needed in flat config.',
|
|
51
|
+
ecmaVersion: 'Move to `languageOptions.ecmaVersion`.',
|
|
52
|
+
sourceType: 'Move to `languageOptions.sourceType`.',
|
|
53
|
+
noInlineConfig: 'Move to `linterOptions.noInlineConfig`.',
|
|
54
|
+
reportUnusedDisableDirectives: 'Move to `linterOptions.reportUnusedDisableDirectives`.',
|
|
55
|
+
ignorePatterns: 'Use `ignores` instead.',
|
|
56
|
+
react: 'Install `eslint-config-xo-react` and spread it into your XO config instead.',
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
Validate an XO config array for legacy ESLint config properties that are not supported in flat config.
|
|
60
|
+
|
|
61
|
+
@param xoConfig - The flat XO config to validate.
|
|
62
|
+
*/
|
|
63
|
+
export const validateXoConfig = (xoConfig) => {
|
|
64
|
+
// Skip the first item (internal base config prepended by XO)
|
|
65
|
+
for (const config of xoConfig.values().drop(1)) {
|
|
66
|
+
for (const key of Object.keys(config)) {
|
|
67
|
+
const hint = legacyPropertyHints[key];
|
|
68
|
+
if (hint !== undefined) {
|
|
69
|
+
throw new Error(`Invalid XO config property \`${key}\`. ${hint}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
};
|
|
50
74
|
/**
|
|
51
75
|
Once a config is resolved, it is pre-processed to ensure that all properties are set correctly.
|
|
52
76
|
|
|
@@ -57,22 +81,18 @@ This includes ensuring that user-defined properties can override XO defaults, an
|
|
|
57
81
|
*/
|
|
58
82
|
// eslint-disable-next-line complexity
|
|
59
83
|
export const preProcessXoConfig = (xoConfig) => {
|
|
84
|
+
validateXoConfig(xoConfig);
|
|
60
85
|
const tsFilesGlob = [];
|
|
61
86
|
const tsFilesIgnoresGlob = [];
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
if (idx === 0) {
|
|
68
|
-
processedConfig.push(config);
|
|
69
|
-
continue;
|
|
70
|
-
}
|
|
87
|
+
// The first config item is the internal base config; push it through unmodified.
|
|
88
|
+
const processedConfig = xoConfig[0] ? [{ ...xoConfig[0] }] : [];
|
|
89
|
+
for (const { ...config } of xoConfig.values().drop(1)) {
|
|
90
|
+
const { languageOptions } = config;
|
|
91
|
+
const parserOptions = languageOptions?.['parserOptions'];
|
|
71
92
|
// Use TS parser/plugin for JS files if the config contains TypeScript rules which are applied to JS files.
|
|
72
93
|
// typescript-eslint rules set to "off" are ignored and not applied to JS files.
|
|
73
94
|
if (config.rules
|
|
74
|
-
|
|
75
|
-
&& !languageOptions?.['parser']
|
|
95
|
+
&& languageOptions?.['parser'] === undefined
|
|
76
96
|
&& parserOptions?.project === undefined
|
|
77
97
|
&& parserOptions?.programs === undefined
|
|
78
98
|
&& !config.plugins?.['@typescript-eslint']) {
|
|
@@ -89,7 +109,7 @@ export const preProcessXoConfig = (xoConfig) => {
|
|
|
89
109
|
});
|
|
90
110
|
if (hasTsRules) {
|
|
91
111
|
let isAppliedToJsFiles = false;
|
|
92
|
-
if (config.files) {
|
|
112
|
+
if (config.files !== undefined) {
|
|
93
113
|
const normalizedFiles = arrify(config.files).flat().map(file => path.normalize(file));
|
|
94
114
|
// Strip the basename off any globs
|
|
95
115
|
const globs = normalizedFiles.map(file => micromatch.scan(file, { dot: true }).glob).filter(Boolean);
|
|
@@ -106,11 +126,6 @@ export const preProcessXoConfig = (xoConfig) => {
|
|
|
106
126
|
? { ...languageOptions, parser: typescriptParser }
|
|
107
127
|
: { parser: typescriptParser };
|
|
108
128
|
config.languageOptions = updatedLanguageOptions;
|
|
109
|
-
config.plugins ??= {};
|
|
110
|
-
config.plugins = {
|
|
111
|
-
...config.plugins,
|
|
112
|
-
...configXoTypescript[1]?.plugins,
|
|
113
|
-
};
|
|
114
129
|
tsFilesGlob.push(...arrify(config.files ?? allFilesGlob).flat());
|
|
115
130
|
tsFilesIgnoresGlob.push(...arrify(config.ignores));
|
|
116
131
|
}
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
import { type Linter } from 'eslint';
|
|
2
|
-
import { type Options } from 'prettier';
|
|
3
2
|
import { type XoConfigItem } from './types.js';
|
|
4
|
-
export type CreateConfigOptions = {
|
|
5
|
-
prettierOptions?: Options;
|
|
6
|
-
};
|
|
7
3
|
/**
|
|
8
|
-
Takes
|
|
4
|
+
Takes an XO flat config and returns an ESLint flat config.
|
|
9
5
|
*/
|
|
10
|
-
export declare function xoToEslintConfig(flatXoConfig: XoConfigItem[] | undefined
|
|
6
|
+
export declare function xoToEslintConfig(flatXoConfig: XoConfigItem[] | undefined): Linter.Config[];
|
|
11
7
|
export default xoToEslintConfig;
|
package/dist/lib/xo-to-eslint.js
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
/* eslint-disable complexity */
|
|
2
|
-
import configXoTypescript from 'eslint-config-xo-typescript';
|
|
1
|
+
/* eslint-disable complexity -- Translating every XO config option into ESLint rules is inherently branchy. */
|
|
3
2
|
import arrify from 'arrify';
|
|
4
|
-
import
|
|
5
|
-
import pluginPrettier from 'eslint-plugin-prettier';
|
|
6
|
-
import eslintConfigPrettier from 'eslint-config-prettier';
|
|
7
|
-
import { fixupConfigRules, fixupPluginRules } from '@eslint/compat';
|
|
3
|
+
import { getPrettierConfig } from 'eslint-config-xo';
|
|
8
4
|
import { config } from './config.js';
|
|
9
5
|
import { xoToEslintConfigItem } from './utils.js';
|
|
10
6
|
/**
|
|
@@ -41,9 +37,9 @@ const hoistPlugins = (configs, userPluginOverrides) => {
|
|
|
41
37
|
];
|
|
42
38
|
};
|
|
43
39
|
/**
|
|
44
|
-
Takes
|
|
40
|
+
Takes an XO flat config and returns an ESLint flat config.
|
|
45
41
|
*/
|
|
46
|
-
export function xoToEslintConfig(flatXoConfig
|
|
42
|
+
export function xoToEslintConfig(flatXoConfig) {
|
|
47
43
|
const baseConfig = [...config];
|
|
48
44
|
const userPluginOverrides = new Map();
|
|
49
45
|
for (const xoConfigItem of flatXoConfig ?? []) {
|
|
@@ -64,12 +60,12 @@ export function xoToEslintConfig(flatXoConfig, { prettierOptions = {} } = {}) {
|
|
|
64
60
|
continue;
|
|
65
61
|
}
|
|
66
62
|
/** Special case global ignores */
|
|
67
|
-
if (xoConfigItem.ignores) {
|
|
63
|
+
if (xoConfigItem.ignores !== undefined) {
|
|
68
64
|
if (keysOfXoConfig.length === 1) {
|
|
69
65
|
baseConfig.push({ ignores: arrify(xoConfigItem.ignores) });
|
|
70
66
|
continue;
|
|
71
67
|
}
|
|
72
|
-
|
|
68
|
+
if (keysOfXoConfig.length === 2 && xoConfigItem.name !== undefined) {
|
|
73
69
|
baseConfig.push({ name: xoConfigItem.name, ignores: arrify(xoConfigItem.ignores) });
|
|
74
70
|
continue;
|
|
75
71
|
}
|
|
@@ -78,91 +74,49 @@ export function xoToEslintConfig(flatXoConfig, { prettierOptions = {} } = {}) {
|
|
|
78
74
|
An ESLint config item derived from the XO config item with rules and files initialized.
|
|
79
75
|
*/
|
|
80
76
|
const eslintConfigItem = xoToEslintConfigItem(xoConfigItem);
|
|
77
|
+
const isUsingSpaces = Boolean(xoConfigItem.space);
|
|
81
78
|
if (xoConfigItem.semicolon === false) {
|
|
82
79
|
eslintConfigItem.rules ??= {};
|
|
83
80
|
eslintConfigItem.rules['@stylistic/semi'] = ['error', 'never'];
|
|
84
|
-
eslintConfigItem.rules['@stylistic/semi-spacing'] = [
|
|
81
|
+
eslintConfigItem.rules['@stylistic/semi-spacing'] = ['error', { before: false, after: true }];
|
|
82
|
+
eslintConfigItem.rules['@stylistic/member-delimiter-style'] = [
|
|
85
83
|
'error',
|
|
86
|
-
{
|
|
84
|
+
{
|
|
85
|
+
multiline: { delimiter: 'none' },
|
|
86
|
+
singleline: { delimiter: 'comma', requireLast: false },
|
|
87
|
+
},
|
|
87
88
|
];
|
|
88
89
|
}
|
|
89
|
-
if (
|
|
90
|
+
if (isUsingSpaces) {
|
|
90
91
|
const spaces = typeof xoConfigItem.space === 'number' ? xoConfigItem.space : 2;
|
|
91
92
|
eslintConfigItem.rules ??= {};
|
|
92
|
-
eslintConfigItem.rules['@stylistic/indent'] = [
|
|
93
|
-
'error',
|
|
94
|
-
spaces,
|
|
95
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
96
|
-
{ SwitchCase: 1 },
|
|
97
|
-
];
|
|
93
|
+
eslintConfigItem.rules['@stylistic/indent'] = ['error', spaces, { SwitchCase: 1 }]; // eslint-disable-line @typescript-eslint/naming-convention
|
|
98
94
|
eslintConfigItem.rules['@stylistic/indent-binary-ops'] = ['error', spaces];
|
|
99
95
|
}
|
|
100
96
|
else if (xoConfigItem.space === false) {
|
|
101
|
-
// If a user sets this to false for a small subset of files for some reason,
|
|
102
|
-
// then we need to set them back to their original values.
|
|
103
97
|
eslintConfigItem.rules ??= {};
|
|
104
|
-
eslintConfigItem.rules['@stylistic/indent'] =
|
|
105
|
-
eslintConfigItem.rules['@stylistic/indent-binary-ops'] =
|
|
106
|
-
}
|
|
107
|
-
if (xoConfigItem.react) {
|
|
108
|
-
// Ensure the files applied to the React config are the same as the config they are derived from
|
|
109
|
-
// TODO: Remove `fixupConfigRules` wrapping when eslint-config-xo-react supports ESLint 10 natively.
|
|
110
|
-
baseConfig.push({ ...fixupConfigRules(configReact)[0], ...(eslintConfigItem.files ? { files: eslintConfigItem.files } : {}), name: 'xo/react' });
|
|
111
|
-
}
|
|
112
|
-
// Prettier should generally be the last config in the array
|
|
113
|
-
if (xoConfigItem.prettier) {
|
|
114
|
-
if (xoConfigItem.prettier === 'compat') {
|
|
115
|
-
baseConfig.push({ ...eslintConfigPrettier, ...(eslintConfigItem.files ? { files: eslintConfigItem.files } : {}) });
|
|
116
|
-
}
|
|
117
|
-
else {
|
|
118
|
-
// Validate that Prettier options match other `xoConfig` options.
|
|
119
|
-
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
|
120
|
-
if ((xoConfigItem.semicolon && prettierOptions.semi === false) || (!xoConfigItem.semicolon && prettierOptions.semi === true)) {
|
|
121
|
-
throw new Error(`The Prettier config \`semi\` is ${prettierOptions.semi} while Xo \`semicolon\` is ${xoConfigItem.semicolon}, also check your .editorconfig for inconsistencies.`);
|
|
122
|
-
}
|
|
123
|
-
if (((xoConfigItem.space ?? typeof xoConfigItem.space === 'number') && prettierOptions.useTabs === true) || (!xoConfigItem.space && prettierOptions.useTabs === false)) {
|
|
124
|
-
throw new Error(`The Prettier config \`useTabs\` is ${prettierOptions.useTabs} while Xo \`space\` is ${xoConfigItem.space}, also check your .editorconfig for inconsistencies.`);
|
|
125
|
-
}
|
|
126
|
-
if (typeof xoConfigItem.space === 'number' && typeof prettierOptions.tabWidth === 'number' && xoConfigItem.space !== prettierOptions.tabWidth) {
|
|
127
|
-
throw new Error(`The Prettier config \`tabWidth\` is ${prettierOptions.tabWidth} while Xo \`space\` is ${xoConfigItem.space}, also check your .editorconfig for inconsistencies.`);
|
|
128
|
-
}
|
|
129
|
-
// Add Prettier plugin
|
|
130
|
-
// TODO: Remove `fixupPluginRules` wrapping when eslint-plugin-prettier supports ESLint 10 natively.
|
|
131
|
-
eslintConfigItem.plugins = {
|
|
132
|
-
...eslintConfigItem.plugins,
|
|
133
|
-
prettier: fixupPluginRules(pluginPrettier),
|
|
134
|
-
};
|
|
135
|
-
const prettierConfig = {
|
|
136
|
-
singleQuote: true,
|
|
137
|
-
bracketSpacing: false,
|
|
138
|
-
bracketSameLine: false,
|
|
139
|
-
trailingComma: 'all',
|
|
140
|
-
tabWidth: typeof xoConfigItem.space === 'number' ? xoConfigItem.space : 2,
|
|
141
|
-
useTabs: !xoConfigItem.space,
|
|
142
|
-
semi: xoConfigItem.semicolon,
|
|
143
|
-
...prettierOptions,
|
|
144
|
-
};
|
|
145
|
-
// Configure Prettier rules
|
|
146
|
-
const rulesWithPrettier = {
|
|
147
|
-
...eslintConfigItem.rules,
|
|
148
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
149
|
-
...pluginPrettier.configs?.['recommended']?.rules,
|
|
150
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
151
|
-
'prettier/prettier': ['error', prettierConfig],
|
|
152
|
-
...eslintConfigPrettier.rules,
|
|
153
|
-
};
|
|
154
|
-
eslintConfigItem.rules = rulesWithPrettier;
|
|
155
|
-
}
|
|
98
|
+
eslintConfigItem.rules['@stylistic/indent'] = ['error', 'tab', { SwitchCase: 1 }]; // eslint-disable-line @typescript-eslint/naming-convention
|
|
99
|
+
eslintConfigItem.rules['@stylistic/indent-binary-ops'] = ['error', 'tab'];
|
|
156
100
|
}
|
|
157
|
-
|
|
101
|
+
// Delegate Prettier integration to `eslint-config-xo`. Its config is pushed after `eslintConfigItem` below so it comes last, disabling the conflicting stylistic rules set above.
|
|
102
|
+
const prettierConfig = getPrettierConfig({
|
|
103
|
+
prettier: xoConfigItem.prettier,
|
|
104
|
+
// `Space` allows `string` for legacy reasons, but Prettier only needs `boolean | number`.
|
|
105
|
+
space: xoConfigItem.space,
|
|
106
|
+
semicolon: xoConfigItem.semicolon,
|
|
107
|
+
files: eslintConfigItem.files,
|
|
108
|
+
});
|
|
109
|
+
if (xoConfigItem.prettier === false) {
|
|
158
110
|
// Turn Prettier off for a subset of files
|
|
159
111
|
eslintConfigItem.rules ??= {};
|
|
160
112
|
eslintConfigItem.rules['prettier/prettier'] = 'off';
|
|
161
113
|
}
|
|
162
|
-
if (Object.keys(eslintConfigItem).length
|
|
163
|
-
|
|
114
|
+
if (Object.keys(eslintConfigItem).length > 0) {
|
|
115
|
+
baseConfig.push(eslintConfigItem);
|
|
116
|
+
}
|
|
117
|
+
if (prettierConfig) {
|
|
118
|
+
baseConfig.push(prettierConfig);
|
|
164
119
|
}
|
|
165
|
-
baseConfig.push(eslintConfigItem);
|
|
166
120
|
}
|
|
167
121
|
// User plugins should always win, even if XO injects plugins later in the config list.
|
|
168
122
|
return hoistPlugins(baseConfig, userPluginOverrides);
|
package/dist/lib/xo.d.ts
CHANGED
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
import { ESLint, type Linter } from 'eslint';
|
|
2
|
-
import
|
|
3
|
-
import { type XoLintResult, type LinterOptions, type LintTextOptions, type XoConfigOptions, type XoConfigItem } from './types.js';
|
|
4
|
-
import { xoToEslintConfig } from './xo-to-eslint.js';
|
|
2
|
+
import { type XoLintResult, type LinterOptions, type LintTextOptions, type XoConfigOptions } from './types.js';
|
|
5
3
|
export declare const ignoredFileWarningMessage = "File ignored because of a matching ignore pattern.";
|
|
4
|
+
export declare const noFilesFoundErrorMessage = "No files matching the pattern were found.";
|
|
6
5
|
export declare class Xo {
|
|
7
|
-
|
|
8
|
-
Static helper to convert an XO config to an ESLint config to be used in `eslint.config.js`.
|
|
9
|
-
*/
|
|
10
|
-
static xoToEslintConfig: typeof xoToEslintConfig;
|
|
6
|
+
#private;
|
|
11
7
|
/**
|
|
12
8
|
Static helper for backwards compatibility and use in editor extensions and other tools.
|
|
13
9
|
*/
|
|
@@ -20,90 +16,33 @@ export declare class Xo {
|
|
|
20
16
|
Write the fixes to disk.
|
|
21
17
|
*/
|
|
22
18
|
static outputFixes(results: XoLintResult): Promise<void>;
|
|
19
|
+
constructor(_linterOptions: LinterOptions, _baseXoConfig?: XoConfigOptions);
|
|
23
20
|
/**
|
|
24
|
-
|
|
25
|
-
*/
|
|
26
|
-
linterOptions: LinterOptions;
|
|
27
|
-
/**
|
|
28
|
-
Base XO config options that allow configuration from CLI or other sources. Not to be confused with the `xoConfig` property which is the resolved XO config from the flat config AND base config.
|
|
29
|
-
*/
|
|
30
|
-
baseXoConfig: XoConfigOptions;
|
|
31
|
-
/**
|
|
32
|
-
File path to the ESLint cache.
|
|
33
|
-
*/
|
|
34
|
-
cacheLocation: string;
|
|
35
|
-
/**
|
|
36
|
-
A re-usable ESLint instance configured with options calculated from the XO config.
|
|
37
|
-
*/
|
|
38
|
-
eslint?: ESLint;
|
|
39
|
-
/**
|
|
40
|
-
XO config derived from both the base config and the resolved flat config.
|
|
41
|
-
*/
|
|
42
|
-
xoConfig?: XoConfigItem[];
|
|
43
|
-
/**
|
|
44
|
-
The ESLint config calculated from the resolved XO config.
|
|
45
|
-
*/
|
|
46
|
-
eslintConfig?: Linter.Config[];
|
|
47
|
-
/**
|
|
48
|
-
The flat XO config path, if there is one.
|
|
49
|
-
*/
|
|
50
|
-
flatConfigPath?: string | undefined;
|
|
51
|
-
/**
|
|
52
|
-
If any user configs contain Prettier, we will need to fetch the Prettier config.
|
|
53
|
-
*/
|
|
54
|
-
prettier?: boolean;
|
|
55
|
-
/**
|
|
56
|
-
The Prettier config if it exists and is needed.
|
|
57
|
-
*/
|
|
58
|
-
prettierConfig?: prettier.Options;
|
|
59
|
-
/**
|
|
60
|
-
The glob pattern for TypeScript files, for which we will handle TS files and tsconfig.
|
|
61
|
-
|
|
62
|
-
We expand this based on the XO config and the files glob patterns.
|
|
63
|
-
*/
|
|
64
|
-
tsFilesGlob: string[];
|
|
65
|
-
/**
|
|
66
|
-
We use this to also add negative glob patterns in case a user overrides the parserOptions in their XO config.
|
|
21
|
+
Initializes the ESLint flat config on the XO instance.
|
|
67
22
|
*/
|
|
68
|
-
|
|
23
|
+
private prepareEslintConfig;
|
|
24
|
+
private discoverFiles;
|
|
69
25
|
/**
|
|
70
|
-
|
|
26
|
+
Add virtual files to the config with a tsconfig approach.
|
|
71
27
|
*/
|
|
72
|
-
private
|
|
28
|
+
private addVirtualFilesToConfig;
|
|
73
29
|
/**
|
|
74
|
-
|
|
75
|
-
Key: file path, Value: config for that file.
|
|
76
|
-
This prevents memory bloat in long-running processes (e.g., language servers).
|
|
30
|
+
Add existing files to the config with an in-memory TypeScript Program.
|
|
77
31
|
*/
|
|
78
|
-
private
|
|
32
|
+
private addExistingFilesToConfig;
|
|
33
|
+
private processReport;
|
|
34
|
+
private getReportStatistics;
|
|
79
35
|
/**
|
|
80
|
-
|
|
81
|
-
These are handled differently from regular files.
|
|
36
|
+
Throws if a suppressions location was provided but the file does not exist.
|
|
82
37
|
*/
|
|
83
|
-
private
|
|
84
|
-
constructor(_linterOptions: LinterOptions, _baseXoConfig?: XoConfigOptions);
|
|
38
|
+
private assertSuppressionsFileExists;
|
|
85
39
|
/**
|
|
86
40
|
Sets the XO config on the XO instance.
|
|
87
|
-
|
|
88
|
-
@private
|
|
89
41
|
*/
|
|
90
42
|
setXoConfig(): Promise<void>;
|
|
91
|
-
|
|
92
|
-
Sets the ESLint config on the XO instance.
|
|
93
|
-
|
|
94
|
-
@private
|
|
95
|
-
*/
|
|
96
|
-
setEslintConfig(): void;
|
|
97
|
-
/**
|
|
98
|
-
Sets the ignores on the XO instance.
|
|
99
|
-
|
|
100
|
-
@private
|
|
101
|
-
*/
|
|
102
|
-
setIgnores(): void;
|
|
43
|
+
setEslintConfig(cliIgnores?: string[], stripDefaultIgnores?: boolean): void;
|
|
103
44
|
/**
|
|
104
45
|
Ensures the cache directory exists. This needs to run once before both tsconfig handling and running ESLint occur.
|
|
105
|
-
|
|
106
|
-
@private
|
|
107
46
|
*/
|
|
108
47
|
ensureCacheDirectory(): Promise<void>;
|
|
109
48
|
/**
|
|
@@ -115,7 +54,11 @@ export declare class Xo {
|
|
|
115
54
|
/**
|
|
116
55
|
Initializes the ESLint instance on the XO instance.
|
|
117
56
|
*/
|
|
118
|
-
initEslint(files?: string[]): Promise<void>;
|
|
57
|
+
initEslint(files?: string[], cliIgnores?: string[], stripDefaultIgnores?: boolean): Promise<void>;
|
|
58
|
+
/**
|
|
59
|
+
Create an ESLint flat config for editor integrations using the same XO pipeline as the CLI.
|
|
60
|
+
*/
|
|
61
|
+
getProjectEslintConfig(): Promise<Linter.Config[]>;
|
|
119
62
|
/**
|
|
120
63
|
Lints the files on the XO instance.
|
|
121
64
|
|
|
@@ -129,15 +72,5 @@ export declare class Xo {
|
|
|
129
72
|
lintText(code: string, lintTextOptions: LintTextOptions): Promise<XoLintResult>;
|
|
130
73
|
calculateConfigForFile(filePath: string): Promise<Linter.Config>;
|
|
131
74
|
getFormatter(name: string): Promise<ESLint.LoadedFormatter>;
|
|
132
|
-
/**
|
|
133
|
-
Add virtual files to the config with a tsconfig approach.
|
|
134
|
-
*/
|
|
135
|
-
private addVirtualFilesToConfig;
|
|
136
|
-
/**
|
|
137
|
-
Add existing files to the config with an in-memory TypeScript Program.
|
|
138
|
-
*/
|
|
139
|
-
private addExistingFilesToConfig;
|
|
140
|
-
private processReport;
|
|
141
|
-
private getReportStatistics;
|
|
142
75
|
}
|
|
143
76
|
export default Xo;
|