xo 0.43.0 → 0.44.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/cli.js CHANGED
@@ -173,8 +173,8 @@ if (options.nodeVersion) {
173
173
  }
174
174
 
175
175
  (async () => {
176
- if (options.printConfig) {
177
- if (input.length > 0) {
176
+ if (typeof options.printConfig === 'string') {
177
+ if (input.length > 0 || options.printConfig === '') {
178
178
  console.error('The `--print-config` flag must be used with exactly one filename');
179
179
  process.exit(1);
180
180
  }
package/index.js CHANGED
@@ -1,169 +1,92 @@
1
- import process from 'node:process';
2
1
  import path from 'node:path';
3
2
  import {ESLint} from 'eslint';
4
3
  import {globby, isGitIgnoredSync} from 'globby';
5
4
  import {isEqual} from 'lodash-es';
6
5
  import micromatch from 'micromatch';
7
6
  import arrify from 'arrify';
8
- import pReduce from 'p-reduce';
9
- import pMap from 'p-map';
10
- import {cosmiconfig, defaultLoaders} from 'cosmiconfig';
11
- import defineLazyProperty from 'define-lazy-prop';
12
- import pFilter from 'p-filter';
13
7
  import slash from 'slash';
14
- import {CONFIG_FILES, MODULE_NAME, DEFAULT_IGNORES} from './lib/constants.js';
15
8
  import {
16
- normalizeOptions,
9
+ parseOptions,
17
10
  getIgnores,
18
11
  mergeWithFileConfig,
19
- mergeWithFileConfigs,
20
- buildConfig,
21
- mergeOptions,
22
12
  } from './lib/options-manager.js';
23
-
24
- /** Merge multiple reports into a single report */
25
- const mergeReports = reports => {
26
- const report = {
27
- results: [],
28
- errorCount: 0,
29
- warningCount: 0,
30
- };
31
-
32
- for (const currentReport of reports) {
33
- report.results.push(...currentReport.results);
34
- report.errorCount += currentReport.errorCount;
35
- report.warningCount += currentReport.warningCount;
13
+ import {mergeReports, processReport, getIgnoredReport} from './lib/report.js';
14
+
15
+ const runEslint = async (lint, options) => {
16
+ const {filePath, eslintOptions, isQuiet} = options;
17
+ const {cwd, baseConfig: {ignorePatterns}} = eslintOptions;
18
+
19
+ if (
20
+ filePath
21
+ && (
22
+ micromatch.isMatch(path.relative(cwd, filePath), ignorePatterns)
23
+ || isGitIgnoredSync({cwd, ignore: ignorePatterns})(filePath)
24
+ )
25
+ ) {
26
+ return getIgnoredReport(filePath);
36
27
  }
37
28
 
38
- return report;
39
- };
29
+ const eslint = new ESLint(eslintOptions);
40
30
 
41
- const getReportStatistics = results => {
42
- const statistics = {
43
- errorCount: 0,
44
- warningCount: 0,
45
- fixableErrorCount: 0,
46
- fixableWarningCount: 0,
47
- };
48
-
49
- for (const result of results) {
50
- statistics.errorCount += result.errorCount;
51
- statistics.warningCount += result.warningCount;
52
- statistics.fixableErrorCount += result.fixableErrorCount;
53
- statistics.fixableWarningCount += result.fixableWarningCount;
31
+ if (filePath && await eslint.isPathIgnored(filePath)) {
32
+ return getIgnoredReport(filePath);
54
33
  }
55
34
 
56
- return statistics;
35
+ const report = await lint(eslint);
36
+ return processReport(report, {isQuiet});
57
37
  };
58
38
 
59
- const processReport = (report, {isQuiet = false} = {}) => {
60
- if (isQuiet) {
61
- report = ESLint.getErrorResults(report);
62
- }
63
-
64
- const result = {
65
- results: report,
66
- ...getReportStatistics(report),
67
- };
39
+ const globFiles = async (patterns, options) => {
40
+ const {ignores, extensions, cwd} = (await mergeWithFileConfig(options)).options;
68
41
 
69
- defineLazyProperty(result, 'usedDeprecatedRules', () => {
70
- const seenRules = new Set();
71
- const rules = [];
72
-
73
- for (const {usedDeprecatedRules} of report) {
74
- for (const rule of usedDeprecatedRules) {
75
- if (seenRules.has(rule.ruleId)) {
76
- continue;
77
- }
78
-
79
- seenRules.add(rule.ruleId);
80
- rules.push(rule);
81
- }
82
- }
83
-
84
- return rules;
85
- });
86
-
87
- return result;
88
- };
42
+ patterns = patterns.length === 0
43
+ ? [`**/*.{${extensions.join(',')}}`]
44
+ : arrify(patterns).map(pattern => slash(pattern));
89
45
 
90
- const runEslint = async (paths, options, processorOptions) => {
91
- const engine = new ESLint(options);
46
+ const files = await globby(
47
+ patterns,
48
+ {ignore: ignores, gitignore: true, absolute: true, cwd},
49
+ );
92
50
 
93
- const report = await engine.lintFiles(await pFilter(paths, async path => !(await engine.isPathIgnored(path))));
94
- return processReport(report, processorOptions);
51
+ return files.filter(file => extensions.includes(path.extname(file).slice(1)));
95
52
  };
96
53
 
97
- const globFiles = async (patterns, {ignores, extensions, cwd}) => (
98
- await globby(
99
- patterns.length === 0 ? [`**/*.{${extensions.join(',')}}`] : arrify(patterns).map(pattern => slash(pattern)),
100
- {ignore: ignores, gitignore: true, absolute: true, cwd},
101
- )).filter(file => extensions.includes(path.extname(file).slice(1)));
102
-
103
54
  const getConfig = async options => {
104
- const {options: foundOptions, prettierOptions} = mergeWithFileConfig(normalizeOptions(options));
105
- const {filePath, warnIgnored, ...eslintOptions} = buildConfig(foundOptions, prettierOptions);
55
+ const {filePath, eslintOptions} = await parseOptions(options);
106
56
  const engine = new ESLint(eslintOptions);
107
57
  return engine.calculateConfigForFile(filePath);
108
58
  };
109
59
 
110
- const lintText = async (string, inputOptions = {}) => {
111
- const {options: foundOptions, prettierOptions} = mergeWithFileConfig(normalizeOptions(inputOptions));
112
- const options = buildConfig(foundOptions, prettierOptions);
60
+ const lintText = async (string, options) => {
61
+ options = await parseOptions(options);
62
+ const {filePath, warnIgnored, eslintOptions} = options;
63
+ const {ignorePatterns} = eslintOptions.baseConfig;
113
64
 
114
- if (options.baseConfig.ignorePatterns && !isEqual(getIgnores({}), options.baseConfig.ignorePatterns) && typeof options.filePath !== 'string') {
65
+ if (typeof filePath !== 'string' && !isEqual(getIgnores({}), ignorePatterns)) {
115
66
  throw new Error('The `ignores` option requires the `filePath` option to be defined.');
116
67
  }
117
68
 
118
- const {filePath, warnIgnored, ...eslintOptions} = options;
119
- const engine = new ESLint(eslintOptions);
69
+ return runEslint(
70
+ eslint => eslint.lintText(string, {filePath, warnIgnored}),
71
+ options,
72
+ );
73
+ };
120
74
 
121
- if (filePath) {
122
- const filename = path.relative(options.cwd, filePath);
123
-
124
- if (
125
- micromatch.isMatch(filename, options.baseConfig.ignorePatterns)
126
- || isGitIgnoredSync({cwd: options.cwd, ignore: options.baseConfig.ignorePatterns})(filePath)
127
- || await engine.isPathIgnored(filePath)
128
- ) {
129
- return {
130
- errorCount: 0,
131
- warningCount: 0,
132
- results: [{
133
- errorCount: 0,
134
- filePath: filename,
135
- messages: [],
136
- warningCount: 0,
137
- }],
138
- };
139
- }
140
- }
75
+ const lintFile = async (filePath, options) => runEslint(
76
+ eslint => eslint.lintFiles([filePath]),
77
+ await parseOptions({...options, filePath}),
78
+ );
141
79
 
142
- const report = await engine.lintText(string, {filePath, warnIgnored});
80
+ const lintFiles = async (patterns, options) => {
81
+ const files = await globFiles(patterns, options);
143
82
 
144
- return processReport(report, {isQuiet: inputOptions.quiet});
145
- };
83
+ const reports = await Promise.all(
84
+ files.map(filePath => lintFile(filePath, options)),
85
+ );
146
86
 
147
- const lintFiles = async (patterns, inputOptions = {}) => {
148
- inputOptions.cwd = path.resolve(inputOptions.cwd || process.cwd());
149
- const configExplorer = cosmiconfig(MODULE_NAME, {searchPlaces: CONFIG_FILES, loaders: {noExt: defaultLoaders['.json']}, stopDir: inputOptions.cwd});
150
-
151
- const configFiles = (await Promise.all(
152
- (await globby(
153
- CONFIG_FILES.map(configFile => `**/${configFile}`),
154
- {ignore: DEFAULT_IGNORES, gitignore: true, absolute: true, cwd: inputOptions.cwd},
155
- )).map(configFile => configExplorer.load(configFile)),
156
- )).filter(Boolean);
157
-
158
- const paths = configFiles.length > 0
159
- ? await pReduce(
160
- configFiles,
161
- async (paths, {filepath, config}) =>
162
- [...paths, ...(await globFiles(patterns, {...mergeOptions(inputOptions, config), cwd: path.dirname(filepath)}))],
163
- [])
164
- : await globFiles(patterns, mergeOptions(inputOptions));
165
-
166
- return mergeReports(await pMap(await mergeWithFileConfigs([...new Set(paths)], inputOptions, configFiles), async ({files, options, prettierOptions}) => runEslint(files, buildConfig(options, prettierOptions), {isQuiet: options.quiet})));
87
+ const report = mergeReports(reports.filter(({isIgnored}) => !isIgnored));
88
+
89
+ return report;
167
90
  };
168
91
 
169
92
  const getFormatter = async name => {
@@ -3,21 +3,19 @@ import os from 'node:os';
3
3
  import path from 'node:path';
4
4
  import fsExtra from 'fs-extra';
5
5
  import arrify from 'arrify';
6
- import {mergeWith, groupBy, flow, pick} from 'lodash-es';
6
+ import {mergeWith, flow, pick} from 'lodash-es';
7
7
  import pathExists from 'path-exists';
8
8
  import findUp from 'find-up';
9
9
  import findCacheDir from 'find-cache-dir';
10
10
  import prettier from 'prettier';
11
11
  import semver from 'semver';
12
- import {cosmiconfig, cosmiconfigSync, defaultLoaders} from 'cosmiconfig';
13
- import pReduce from 'p-reduce';
12
+ import {cosmiconfig, defaultLoaders} from 'cosmiconfig';
14
13
  import micromatch from 'micromatch';
15
14
  import JSON5 from 'json5';
16
15
  import toAbsoluteGlob from 'to-absolute-glob';
17
16
  import stringify from 'json-stable-stringify-without-jsonify';
18
17
  import murmur from 'imurmurhash';
19
- import isPathInside from 'is-path-inside';
20
- import eslintrc from '@eslint/eslintrc';
18
+ import {Legacy} from '@eslint/eslintrc';
21
19
  import createEsmUtils from 'esm-utils';
22
20
  import {
23
21
  DEFAULT_IGNORES,
@@ -33,10 +31,8 @@ import {
33
31
  } from './constants.js';
34
32
 
35
33
  const {__dirname, json, require} = createEsmUtils(import.meta);
36
- const pkg = json.loadSync('../package.json');
37
- const {outputJson, outputJsonSync} = fsExtra;
38
- const {normalizePackageName} = eslintrc.Legacy.naming;
39
- const resolveModule = eslintrc.Legacy.ModuleResolver.resolve;
34
+ const {normalizePackageName} = Legacy.naming;
35
+ const resolveModule = Legacy.ModuleResolver.resolve;
40
36
 
41
37
  const resolveFrom = (moduleId, fromDirectory = process.cwd()) => resolveModule(moduleId, path.join(fromDirectory, '__placeholder__.js'));
42
38
 
@@ -105,18 +101,18 @@ const isTypescript = file => TYPESCRIPT_EXTENSION.includes(path.extname(file).sl
105
101
  Find config for `lintText`.
106
102
  The config files are searched starting from `options.filePath` if defined or `options.cwd` otherwise.
107
103
  */
108
- const mergeWithFileConfig = options => {
104
+ const mergeWithFileConfig = async options => {
109
105
  options.cwd = path.resolve(options.cwd || process.cwd());
110
- const configExplorer = cosmiconfigSync(MODULE_NAME, {searchPlaces: CONFIG_FILES, loaders: {noExt: defaultLoaders['.json']}, stopDir: options.cwd});
111
- const pkgConfigExplorer = cosmiconfigSync('engines', {searchPlaces: ['package.json'], stopDir: options.cwd});
106
+ const configExplorer = cosmiconfig(MODULE_NAME, {searchPlaces: CONFIG_FILES, loaders: {noExt: defaultLoaders['.json']}, stopDir: options.cwd});
107
+ const pkgConfigExplorer = cosmiconfig('engines', {searchPlaces: ['package.json'], stopDir: options.cwd});
112
108
  if (options.filePath) {
113
109
  options.filePath = path.resolve(options.cwd, options.filePath);
114
110
  }
115
111
 
116
112
  const searchPath = options.filePath || options.cwd;
117
113
 
118
- const {config: xoOptions, filepath: xoConfigPath} = configExplorer.search(searchPath) || {};
119
- const {config: enginesOptions} = pkgConfigExplorer.search(searchPath) || {};
114
+ const {config: xoOptions, filepath: xoConfigPath} = (await configExplorer.search(searchPath)) || {};
115
+ const {config: enginesOptions} = (await pkgConfigExplorer.search(searchPath)) || {};
120
116
 
121
117
  options = mergeOptions(options, xoOptions, enginesOptions);
122
118
  options.cwd = xoConfigPath && path.dirname(xoConfigPath) !== options.cwd ? path.resolve(options.cwd, path.dirname(xoConfigPath)) : options.cwd;
@@ -125,91 +121,31 @@ const mergeWithFileConfig = options => {
125
121
  ({options} = applyOverrides(options.filePath, options));
126
122
  }
127
123
 
128
- const prettierOptions = options.prettier ? prettier.resolveConfig.sync(searchPath, {editorconfig: true}) || {} : {};
124
+ const prettierOptions = options.prettier ? await prettier.resolveConfig(searchPath, {editorconfig: true}) || {} : {};
129
125
 
130
126
  if (options.filePath && isTypescript(options.filePath)) {
131
- const tsConfigExplorer = cosmiconfigSync([], {searchPlaces: ['tsconfig.json'], loaders: {'.json': (_, content) => JSON5.parse(content)}});
132
- const {config: tsConfig, filepath: tsConfigPath} = tsConfigExplorer.search(options.filePath) || {};
127
+ const tsConfigExplorer = cosmiconfig([], {searchPlaces: ['tsconfig.json'], loaders: {'.json': (_, content) => JSON5.parse(content)}});
128
+ const {config: tsConfig, filepath: tsConfigPath} = (await tsConfigExplorer.search(options.filePath)) || {};
133
129
 
134
- options.tsConfigPath = getTsConfigCachePath([options.filePath], options.tsConfigPath, options.cwd);
130
+ options.tsConfigPath = await getTsConfigCachePath([options.filePath], options.tsConfigPath, options.cwd);
135
131
  options.ts = true;
136
- outputJsonSync(options.tsConfigPath, makeTSConfig(tsConfig, tsConfigPath, [options.filePath]));
132
+ await fsExtra.outputJson(options.tsConfigPath, makeTSConfig(tsConfig, tsConfigPath, [options.filePath]));
137
133
  }
138
134
 
139
135
  return {options, prettierOptions};
140
136
  };
141
137
 
142
- /**
143
- Find config for each files found by `lintFiles`.
144
- The config files are searched starting from each files.
145
- */
146
- const mergeWithFileConfigs = async (files, options, configFiles) => {
147
- configFiles = configFiles.sort((a, b) => b.filepath.split(path.sep).length - a.filepath.split(path.sep).length);
148
- const tsConfigs = {};
149
-
150
- const groups = [...(await pReduce(files, async (configs, file) => {
151
- const pkgConfigExplorer = cosmiconfig('engines', {searchPlaces: ['package.json'], stopDir: options.cwd});
152
-
153
- const {config: xoOptions, filepath: xoConfigPath} = findApplicableConfig(file, configFiles) || {};
154
- const {config: enginesOptions, filepath: enginesConfigPath} = await pkgConfigExplorer.search(file) || {};
155
-
156
- let fileOptions = mergeOptions(options, xoOptions, enginesOptions);
157
- fileOptions.cwd = xoConfigPath && path.dirname(xoConfigPath) !== fileOptions.cwd ? path.resolve(fileOptions.cwd, path.dirname(xoConfigPath)) : fileOptions.cwd;
158
-
159
- const {hash, options: optionsWithOverrides} = applyOverrides(file, fileOptions);
160
- fileOptions = optionsWithOverrides;
161
-
162
- const prettierOptions = fileOptions.prettier ? await prettier.resolveConfig(file, {editorconfig: true}) || {} : {};
163
-
164
- let tsConfigPath;
165
- if (isTypescript(file)) {
166
- let tsConfig;
167
- const tsConfigExplorer = cosmiconfig([], {searchPlaces: ['tsconfig.json'], loaders: {'.json': (_, content) => JSON5.parse(content)}});
168
- ({config: tsConfig, filepath: tsConfigPath} = await tsConfigExplorer.search(file) || {});
169
-
170
- fileOptions.tsConfigPath = tsConfigPath;
171
- tsConfigs[tsConfigPath || ''] = tsConfig;
172
- fileOptions.ts = true;
173
- }
174
-
175
- const cacheKey = stringify({xoConfigPath, enginesConfigPath, prettierOptions, hash, tsConfigPath: fileOptions.tsConfigPath, ts: fileOptions.ts});
176
- const cachedGroup = configs.get(cacheKey);
177
-
178
- configs.set(cacheKey, {
179
- files: [file, ...(cachedGroup ? cachedGroup.files : [])],
180
- options: cachedGroup ? cachedGroup.options : fileOptions,
181
- prettierOptions,
182
- });
183
-
184
- return configs;
185
- }, new Map())).values()];
186
-
187
- await Promise.all(Object.entries(groupBy(groups.filter(({options}) => Boolean(options.ts)), group => group.options.tsConfigPath || '')).map(
188
- ([tsConfigPath, groups]) => {
189
- const files = groups.flatMap(group => group.files);
190
- const cachePath = getTsConfigCachePath(files, tsConfigPath, options.cwd);
191
-
192
- for (const group of groups) {
193
- group.options.tsConfigPath = cachePath;
194
- }
195
-
196
- return outputJson(cachePath, makeTSConfig(tsConfigs[tsConfigPath], tsConfigPath, files));
197
- },
198
- ));
199
-
200
- return groups;
201
- };
202
-
203
- const findApplicableConfig = (file, configFiles) => configFiles.find(({filepath}) => isPathInside(file, path.dirname(filepath)));
204
-
205
138
  /**
206
139
  Generate a unique and consistent path for the temporary `tsconfig.json`.
207
140
  Hashing based on https://github.com/eslint/eslint/blob/cf38d0d939b62f3670cdd59f0143fd896fccd771/lib/cli-engine/lint-result-cache.js#L30
208
141
  */
209
- const getTsConfigCachePath = (files, tsConfigPath, cwd) => path.join(
210
- cacheLocation(cwd),
211
- `tsconfig.${murmur(`${pkg.version}_${nodeVersion}_${stringify({files: files.sort(), tsConfigPath})}`).result().toString(36)}.json`,
212
- );
142
+ const getTsConfigCachePath = async (files, tsConfigPath, cwd) => {
143
+ const {version} = await json.load('../package.json');
144
+ return path.join(
145
+ cacheLocation(cwd),
146
+ `tsconfig.${murmur(`${version}_${nodeVersion}_${stringify({files: files.sort(), tsConfigPath})}`).result().toString(36)}.json`,
147
+ );
148
+ };
213
149
 
214
150
  const makeTSConfig = (tsConfig, tsConfigPath, files) => {
215
151
  const config = {files: files.filter(file => isTypescript(file))};
@@ -493,7 +429,7 @@ const mergeWithPrettierConfig = (options, prettierOptions) => {
493
429
  singleQuote: true,
494
430
  bracketSpacing: false,
495
431
  jsxBracketSameLine: false,
496
- trailingComma: 'none',
432
+ trailingComma: 'all',
497
433
  tabWidth: normalizeSpaces(options),
498
434
  useTabs: !options.space,
499
435
  semi: options.semicolon !== false,
@@ -604,14 +540,27 @@ const gatherImportResolvers = options => {
604
540
  return resolvers;
605
541
  };
606
542
 
543
+ const parseOptions = async options => {
544
+ options = normalizeOptions(options);
545
+ const {options: foundOptions, prettierOptions} = await mergeWithFileConfig(options);
546
+ const {filePath, warnIgnored, ...eslintOptions} = buildConfig(foundOptions, prettierOptions);
547
+ return {
548
+ filePath,
549
+ warnIgnored,
550
+ isQuiet: options.quiet,
551
+ eslintOptions,
552
+ };
553
+ };
554
+
607
555
  export {
556
+ parseOptions,
557
+ getIgnores,
558
+ mergeWithFileConfig,
559
+
560
+ // For tests
561
+ applyOverrides,
608
562
  findApplicableOverrides,
609
563
  mergeWithPrettierConfig,
610
564
  normalizeOptions,
611
- getIgnores,
612
- mergeWithFileConfigs,
613
- mergeWithFileConfig,
614
565
  buildConfig,
615
- applyOverrides,
616
- mergeOptions,
617
566
  };
package/lib/report.js ADDED
@@ -0,0 +1,84 @@
1
+ import defineLazyProperty from 'define-lazy-prop';
2
+ import {ESLint} from 'eslint';
3
+
4
+ /** Merge multiple reports into a single report */
5
+ const mergeReports = reports => {
6
+ const report = {
7
+ results: [],
8
+ errorCount: 0,
9
+ warningCount: 0,
10
+ };
11
+
12
+ for (const currentReport of reports) {
13
+ report.results.push(...currentReport.results);
14
+ report.errorCount += currentReport.errorCount;
15
+ report.warningCount += currentReport.warningCount;
16
+ }
17
+
18
+ return report;
19
+ };
20
+
21
+ const processReport = (report, {isQuiet = false} = {}) => {
22
+ if (isQuiet) {
23
+ report = ESLint.getErrorResults(report);
24
+ }
25
+
26
+ const result = {
27
+ results: report,
28
+ ...getReportStatistics(report),
29
+ };
30
+
31
+ defineLazyProperty(result, 'usedDeprecatedRules', () => {
32
+ const seenRules = new Set();
33
+ const rules = [];
34
+
35
+ for (const {usedDeprecatedRules} of report) {
36
+ for (const rule of usedDeprecatedRules) {
37
+ if (seenRules.has(rule.ruleId)) {
38
+ continue;
39
+ }
40
+
41
+ seenRules.add(rule.ruleId);
42
+ rules.push(rule);
43
+ }
44
+ }
45
+
46
+ return rules;
47
+ });
48
+
49
+ return result;
50
+ };
51
+
52
+ const getReportStatistics = results => {
53
+ const statistics = {
54
+ errorCount: 0,
55
+ warningCount: 0,
56
+ fixableErrorCount: 0,
57
+ fixableWarningCount: 0,
58
+ };
59
+
60
+ for (const result of results) {
61
+ statistics.errorCount += result.errorCount;
62
+ statistics.warningCount += result.warningCount;
63
+ statistics.fixableErrorCount += result.fixableErrorCount;
64
+ statistics.fixableWarningCount += result.fixableWarningCount;
65
+ }
66
+
67
+ return statistics;
68
+ };
69
+
70
+ const getIgnoredReport = filePath => ({
71
+ errorCount: 0,
72
+ warningCount: 0,
73
+ results: [
74
+ {
75
+ errorCount: 0,
76
+ warningCount: 0,
77
+ filePath,
78
+ messages: [],
79
+ },
80
+ ],
81
+ isIgnored: true,
82
+ });
83
+
84
+ export {mergeReports, processReport, getIgnoredReport};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xo",
3
- "version": "0.43.0",
3
+ "version": "0.44.0",
4
4
  "description": "JavaScript/TypeScript linter (ESLint wrapper) with great defaults",
5
5
  "license": "MIT",
6
6
  "repository": "xojs/xo",
@@ -16,7 +16,7 @@
16
16
  "node": ">=12.20"
17
17
  },
18
18
  "scripts": {
19
- "test": "eslint --quiet . --ext .js,.cjs && nyc ava"
19
+ "test": "node cli.js && nyc ava"
20
20
  },
21
21
  "files": [
22
22
  "config",
@@ -52,7 +52,7 @@
52
52
  "typescript"
53
53
  ],
54
54
  "dependencies": {
55
- "@eslint/eslintrc": "^0.4.3",
55
+ "@eslint/eslintrc": "^1.0.0",
56
56
  "@typescript-eslint/eslint-plugin": "^4.29.0",
57
57
  "@typescript-eslint/parser": "^4.29.0",
58
58
  "arrify": "^3.0.0",
@@ -61,8 +61,8 @@
61
61
  "define-lazy-prop": "^3.0.0",
62
62
  "eslint": "^7.32.0",
63
63
  "eslint-config-prettier": "^8.3.0",
64
- "eslint-config-xo": "^0.37.0",
65
- "eslint-config-xo-typescript": "^0.43.0",
64
+ "eslint-config-xo": "^0.38.0",
65
+ "eslint-config-xo-typescript": "^0.44.0",
66
66
  "eslint-formatter-pretty": "^4.1.0",
67
67
  "eslint-import-resolver-webpack": "^0.13.1",
68
68
  "eslint-plugin-ava": "^12.0.0",
@@ -72,7 +72,7 @@
72
72
  "eslint-plugin-node": "^11.1.0",
73
73
  "eslint-plugin-prettier": "^3.4.0",
74
74
  "eslint-plugin-promise": "^5.1.0",
75
- "eslint-plugin-unicorn": "^34.0.1",
75
+ "eslint-plugin-unicorn": "^35.0.0",
76
76
  "esm-utils": "^1.1.0",
77
77
  "find-cache-dir": "^3.3.1",
78
78
  "find-up": "^5.0.0",
@@ -87,9 +87,6 @@
87
87
  "meow": "^10.1.1",
88
88
  "micromatch": "^4.0.4",
89
89
  "open-editor": "^3.0.0",
90
- "p-filter": "^2.1.0",
91
- "p-map": "^5.1.0",
92
- "p-reduce": "^3.0.0",
93
90
  "path-exists": "^4.0.0",
94
91
  "prettier": "^2.3.2",
95
92
  "semver": "^7.3.5",
@@ -106,20 +103,15 @@
106
103
  "nyc": "^15.1.0",
107
104
  "proxyquire": "^2.1.3",
108
105
  "temp-write": "^5.0.0",
109
- "webpack": "^5.48.0"
106
+ "webpack": "^5.49.0"
110
107
  },
111
- "eslintConfig": {
112
- "extends": [
113
- "eslint-config-xo",
114
- "./config/plugins.cjs",
115
- "./config/overrides.cjs"
108
+ "xo": {
109
+ "ignores": [
110
+ "test/fixtures",
111
+ "test/temp",
112
+ "coverage"
116
113
  ]
117
114
  },
118
- "eslintIgnore": [
119
- "test/fixtures",
120
- "test/temp",
121
- "coverage"
122
- ],
123
115
  "ava": {
124
116
  "files": [
125
117
  "!test/temp"
package/readme.md CHANGED
@@ -225,7 +225,7 @@ The [Prettier options](https://prettier.io/docs/en/options.html) will be read fr
225
225
  - [semi](https://prettier.io/docs/en/options.html#semicolons): based on [semicolon](#semicolon) option
226
226
  - [useTabs](https://prettier.io/docs/en/options.html#tabs): based on [space](#space) option
227
227
  - [tabWidth](https://prettier.io/docs/en/options.html#tab-width): based on [space](#space) option
228
- - [trailingComma](https://prettier.io/docs/en/options.html#trailing-commas): `none`
228
+ - [trailingComma](https://prettier.io/docs/en/options.html#trailing-commas): `all`
229
229
  - [singleQuote](https://prettier.io/docs/en/options.html#quotes): `true`
230
230
  - [bracketSpacing](https://prettier.io/docs/en/options.html#bracket-spacing): `false`
231
231
  - [jsxBracketSameLine](https://prettier.io/docs/en/options.html#jsx-brackets): `false`