xo 0.38.0 → 0.39.1

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-main.js CHANGED
@@ -27,10 +27,10 @@ const cli = meow(`
27
27
  --open Open files with issues in your editor
28
28
  --quiet Show only errors and no warnings
29
29
  --extension Additional extension to lint [Can be set multiple times]
30
- --no-esnext Don't enforce ES2015+ rules
31
30
  --cwd=<dir> Working directory for files
32
31
  --stdin Validate/fix code from stdin
33
32
  --stdin-filename Specify a filename for the --stdin option
33
+ --print-config Print the effective ESLint config for the given file
34
34
 
35
35
  Examples
36
36
  $ xo
@@ -41,6 +41,7 @@ const cli = meow(`
41
41
  $ xo --plugin=react
42
42
  $ xo --plugin=html --extension=html
43
43
  $ echo 'const x=true' | xo --stdin --fix
44
+ $ xo --print-config=index.js
44
45
 
45
46
  Tips
46
47
  - Add XO to your project with \`npm init xo\`.
@@ -97,12 +98,12 @@ const cli = meow(`
97
98
  type: 'string',
98
99
  isMultiple: true
99
100
  },
100
- esnext: {
101
- type: 'boolean'
102
- },
103
101
  cwd: {
104
102
  type: 'string'
105
103
  },
104
+ printConfig: {
105
+ type: 'string'
106
+ },
106
107
  stdin: {
107
108
  type: 'boolean'
108
109
  },
@@ -168,13 +169,27 @@ if (options.nodeVersion) {
168
169
  if (options.nodeVersion === 'false') {
169
170
  options.nodeVersion = false;
170
171
  } else if (!semver.validRange(options.nodeVersion)) {
171
- console.error('The `node-engine` option must be a valid semver range (for example `>=6`)');
172
+ console.error('The `--node-engine` flag must be a valid semver range (for example `>=6`)');
172
173
  process.exit(1);
173
174
  }
174
175
  }
175
176
 
176
177
  (async () => {
177
- if (options.stdin) {
178
+ if (options.printConfig) {
179
+ if (input.length > 0) {
180
+ console.error('The `--print-config` flag must be used with exactly one filename');
181
+ process.exit(1);
182
+ }
183
+
184
+ if (options.stdin) {
185
+ console.error('The `--print-config` flag is not supported on stdin');
186
+ process.exit(1);
187
+ }
188
+
189
+ options.filename = options.printConfig;
190
+ const config = xo.getConfig(options);
191
+ console.log(JSON.stringify(config, undefined, '\t'));
192
+ } else if (options.stdin) {
178
193
  const stdin = await getStdin();
179
194
 
180
195
  if (options.stdinFilename) {
@@ -189,7 +204,7 @@ if (options.nodeVersion) {
189
204
  }
190
205
 
191
206
  if (options.open) {
192
- console.error('The `open` option is not supported on stdin');
207
+ console.error('The `--open` flag is not supported on stdin');
193
208
  process.exit(1);
194
209
  }
195
210
 
package/config/plugins.js CHANGED
@@ -186,20 +186,18 @@ module.exports = {
186
186
  'promise/prefer-await-to-then': 'error',
187
187
  'import/default': 'error',
188
188
  'import/export': 'error',
189
-
190
- // Disabled as we use `node/file-extension-in-import` instead as it has an auto-fix.
191
- // 'import/extensions': [
192
- // 'error',
193
- // 'always',
194
- // {
195
- // ignorePackages: true,
196
- // // TypeScript doesn't yet support using extensions and fails with error TS2691.
197
- // pattern: {
198
- // ts: 'never',
199
- // tsx: 'never'
200
- // }
201
- // }
202
- // ],
189
+ 'import/extensions': [
190
+ 'error',
191
+ 'always',
192
+ {
193
+ ignorePackages: true,
194
+ // TypeScript doesn't yet support using extensions and fails with error TS2691.
195
+ pattern: {
196
+ ts: 'never',
197
+ tsx: 'never'
198
+ }
199
+ }
200
+ ],
203
201
 
204
202
  // Disabled as it causes problems with TypeScript when you use mixed ESM and CommonJS.
205
203
  // TODO: Enable again when I target only ESM.
@@ -283,6 +281,8 @@ module.exports = {
283
281
  // 'node/no-missing-require': 'error',
284
282
 
285
283
  'node/no-unpublished-bin': 'error',
284
+
285
+ // We have this enabled in addition to `import/extensions` as this one has an auto-fix.
286
286
  'node/file-extension-in-import': [
287
287
  'error',
288
288
  'always',
package/index.js CHANGED
@@ -57,6 +57,13 @@ const globFiles = async (patterns, {ignores, extensions, cwd}) => (
57
57
  {ignore: ignores, gitignore: true, cwd}
58
58
  )).filter(file => extensions.includes(path.extname(file).slice(1))).map(file => path.resolve(cwd, file));
59
59
 
60
+ const getConfig = options => {
61
+ const {options: foundOptions, prettierOptions} = mergeWithFileConfig(normalizeOptions(options));
62
+ options = buildConfig(foundOptions, prettierOptions);
63
+ const engine = new eslint.CLIEngine(options);
64
+ return engine.getConfigForFile(options.filename);
65
+ };
66
+
60
67
  const lintText = (string, options) => {
61
68
  const {options: foundOptions, prettierOptions} = mergeWithFileConfig(normalizeOptions(options));
62
69
  options = buildConfig(foundOptions, prettierOptions);
@@ -121,6 +128,7 @@ module.exports = {
121
128
  getFormatter: eslint.CLIEngine.getFormatter,
122
129
  getErrorResults: eslint.CLIEngine.getErrorResults,
123
130
  outputFixes: eslint.CLIEngine.outputFixes,
131
+ getConfig,
124
132
  lintText,
125
133
  lintFiles
126
134
  };
package/lib/constants.js CHANGED
@@ -109,7 +109,6 @@ const ENGINE_RULES = {
109
109
  const PRETTIER_CONFIG_OVERRIDE = {
110
110
  'eslint-plugin-babel': 'prettier/babel',
111
111
  'eslint-plugin-flowtype': 'prettier/flowtype',
112
- 'eslint-plugin-react': 'prettier/react',
113
112
  'eslint-plugin-standard': 'prettier/standard',
114
113
  'eslint-plugin-vue': 'prettier/vue'
115
114
  };
@@ -162,9 +162,11 @@ const mergeWithFileConfigs = async (files, options, configFiles) => {
162
162
  ([tsConfigPath, groups]) => {
163
163
  const files = [].concat(...groups.map(group => group.files));
164
164
  const cachePath = getTsConfigCachePath(files, tsConfigPath);
165
- groups.forEach(group => {
165
+
166
+ for (const group of groups) {
166
167
  group.options.tsConfigPath = cachePath;
167
- });
168
+ }
169
+
168
170
  return outputJson(cachePath, makeTSConfig(tsConfigs[tsConfigPath], tsConfigPath, files));
169
171
  }
170
172
  ));
@@ -180,11 +182,11 @@ Hashing based on https://github.com/eslint/eslint/blob/cf38d0d939b62f3670cdd59f0
180
182
  */
181
183
  const getTsConfigCachePath = (files, tsConfigPath) => path.join(
182
184
  cacheLocation,
183
- `tsconfig.${murmur(`${pkg.version}_${nodeVersion}_${stringify({files: files.sort(), tsConfigPath: tsConfigPath})}`).result().toString(36)}.json`
185
+ `tsconfig.${murmur(`${pkg.version}_${nodeVersion}_${stringify({files: files.sort(), tsConfigPath})}`).result().toString(36)}.json`
184
186
  );
185
187
 
186
188
  const makeTSConfig = (tsConfig, tsConfigPath, files) => {
187
- const config = {files: files.filter(isTypescript)};
189
+ const config = {files: files.filter(file => isTypescript(file))};
188
190
 
189
191
  if (tsConfig) {
190
192
  config.extends = tsConfigPath;
@@ -308,15 +310,15 @@ const buildXOConfig = options => config => {
308
310
  }];
309
311
  }
310
312
 
311
- if (options.esnext !== false) {
312
- config.baseConfig.extends = [
313
- 'xo/esnext',
314
- path.join(__dirname, '../config/plugins.js')
315
- ];
316
- }
317
-
318
313
  if (options.ts) {
319
314
  config.rules['unicorn/import-style'] = 'off';
315
+ config.rules['node/file-extension-in-import'] = 'off';
316
+
317
+ // Disabled because of https://github.com/benmosher/eslint-plugin-import/issues/1590
318
+ config.rules['import/export'] = 'off';
319
+
320
+ // Does not work when the TS definition exports a default const.
321
+ config.rules['import/default'] = 'off';
320
322
  }
321
323
 
322
324
  if (options.rules) {
@@ -382,7 +384,6 @@ const buildPrettierConfig = (options, prettierConfig) => config => {
382
384
 
383
385
  // The prettier config overrides ESLint stylistic rules that are handled by Prettier
384
386
  config.baseConfig.extends = config.baseConfig.extends.concat('prettier');
385
- config.baseConfig.extends = config.baseConfig.extends.concat('prettier/unicorn');
386
387
 
387
388
  // The `prettier/prettier` rule reports errors if the code is not formatted in accordance to Prettier
388
389
  config.rules['prettier/prettier'] = ['error', mergeWithPrettierConfig(options, prettierConfig)];
@@ -394,10 +395,6 @@ const buildPrettierConfig = (options, prettierConfig) => config => {
394
395
  config.baseConfig.extends = config.baseConfig.extends.concat(prettierConfig);
395
396
  }
396
397
  }
397
-
398
- if (options.ts) {
399
- config.baseConfig.extends = config.baseConfig.extends.concat('prettier/@typescript-eslint');
400
- }
401
398
  }
402
399
 
403
400
  return config;
@@ -460,7 +457,7 @@ const applyOverrides = (file, options) => {
460
457
  const {overrides} = options;
461
458
  delete options.overrides;
462
459
 
463
- let {applicable, hash} = findApplicableOverrides(path.relative(options.cwd, file), overrides);
460
+ const {applicable, hash} = findApplicableOverrides(path.relative(options.cwd, file), overrides);
464
461
 
465
462
  options = mergeWith(...[getEmptyOptions(), options].concat(applicable.map(override => normalizeOptions(override)), mergeFn));
466
463
  delete options.files;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "xo",
3
- "version": "0.38.0",
4
- "description": "JavaScript/TypeScript linter with great defaults",
3
+ "version": "0.39.1",
4
+ "description": "JavaScript/TypeScript linter (ESLint wrapper) with great defaults",
5
5
  "license": "MIT",
6
6
  "repository": "xojs/xo",
7
7
  "funding": "https://github.com/sponsors/sindresorhus",
@@ -51,25 +51,25 @@
51
51
  "typescript"
52
52
  ],
53
53
  "dependencies": {
54
- "@typescript-eslint/eslint-plugin": "^4.15.1",
55
- "@typescript-eslint/parser": "^4.15.1",
54
+ "@typescript-eslint/eslint-plugin": "^4.22.0",
55
+ "@typescript-eslint/parser": "^4.22.0",
56
56
  "arrify": "^2.0.1",
57
57
  "cosmiconfig": "^7.0.0",
58
58
  "debug": "^4.3.1",
59
- "eslint": "^7.20.0",
60
- "eslint-config-prettier": "^7.2.0",
61
- "eslint-config-xo": "^0.35.0",
62
- "eslint-config-xo-typescript": "^0.38.0",
59
+ "eslint": "^7.24.0",
60
+ "eslint-config-prettier": "^8.2.0",
61
+ "eslint-config-xo": "^0.36.0",
62
+ "eslint-config-xo-typescript": "^0.39.0",
63
63
  "eslint-formatter-pretty": "^4.0.0",
64
64
  "eslint-import-resolver-webpack": "^0.13.0",
65
- "eslint-plugin-ava": "^11.0.0",
65
+ "eslint-plugin-ava": "^12.0.0",
66
66
  "eslint-plugin-eslint-comments": "^3.2.0",
67
67
  "eslint-plugin-import": "^2.22.1",
68
68
  "eslint-plugin-no-use-extend-native": "^0.5.0",
69
69
  "eslint-plugin-node": "^11.1.0",
70
- "eslint-plugin-prettier": "^3.3.1",
71
- "eslint-plugin-promise": "^4.3.1",
72
- "eslint-plugin-unicorn": "^28.0.2",
70
+ "eslint-plugin-prettier": "^3.4.0",
71
+ "eslint-plugin-promise": "^5.1.0",
72
+ "eslint-plugin-unicorn": "^30.0.0",
73
73
  "find-cache-dir": "^3.3.1",
74
74
  "find-up": "^5.0.0",
75
75
  "fs-extra": "^9.1.0",
@@ -77,28 +77,28 @@
77
77
  "globby": "^9.2.0",
78
78
  "has-flag": "^4.0.0",
79
79
  "imurmurhash": "^0.1.4",
80
- "is-path-inside": "^3.0.2",
80
+ "is-path-inside": "^3.0.3",
81
81
  "json-stable-stringify-without-jsonify": "^1.0.1",
82
82
  "json5": "^2.2.0",
83
- "lodash": "^4.17.20",
83
+ "lodash": "^4.17.21",
84
84
  "meow": "^9.0.0",
85
- "micromatch": "^4.0.2",
85
+ "micromatch": "^4.0.4",
86
86
  "open-editor": "^3.0.0",
87
87
  "p-reduce": "^2.1.0",
88
88
  "path-exists": "^4.0.0",
89
89
  "prettier": "^2.2.1",
90
90
  "resolve-cwd": "^3.0.0",
91
91
  "resolve-from": "^5.0.0",
92
- "semver": "^7.3.4",
92
+ "semver": "^7.3.5",
93
93
  "slash": "^3.0.0",
94
94
  "to-absolute-glob": "^2.0.2",
95
- "typescript": "^4.1.5",
95
+ "typescript": "^4.2.4",
96
96
  "update-notifier": "^5.1.0"
97
97
  },
98
98
  "devDependencies": {
99
99
  "ava": "^3.15.0",
100
- "eslint-config-xo-react": "^0.23.0",
101
- "eslint-plugin-react": "^7.22.0",
100
+ "eslint-config-xo-react": "^0.25.0",
101
+ "eslint-plugin-react": "^7.23.2",
102
102
  "eslint-plugin-react-hooks": "^4.2.0",
103
103
  "esm": "^3.2.25",
104
104
  "execa": "^5.0.0",
@@ -106,7 +106,7 @@
106
106
  "pify": "^5.0.0",
107
107
  "proxyquire": "^2.1.3",
108
108
  "temp-write": "^4.0.0",
109
- "webpack": "^5.23.0"
109
+ "webpack": "^5.34.0"
110
110
  },
111
111
  "eslintConfig": {
112
112
  "extends": "eslint-config-xo",
package/readme.md CHANGED
@@ -6,7 +6,7 @@
6
6
  <br>
7
7
  </h1>
8
8
 
9
- > JavaScript/TypeScript linter with great defaults
9
+ > JavaScript/TypeScript linter (ESLint wrapper) with great defaults
10
10
 
11
11
  [![Coverage Status](https://codecov.io/gh/xojs/xo/branch/main/graph/badge.svg)](https://codecov.io/gh/xojs/xo/branch/main)
12
12
  [![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/xojs/xo)
@@ -68,10 +68,10 @@ $ xo --help
68
68
  --open Open files with issues in your editor
69
69
  --quiet Show only errors and no warnings
70
70
  --extension Additional extension to lint [Can be set multiple times]
71
- --no-esnext Don't enforce ES2015+ rules
72
71
  --cwd=<dir> Working directory for files
73
72
  --stdin Validate/fix code from stdin
74
73
  --stdin-filename Specify a filename for the --stdin option
74
+ --print-config Print the ESLint configuration for the given file
75
75
 
76
76
  Examples
77
77
  $ xo
@@ -82,6 +82,7 @@ $ xo --help
82
82
  $ xo --plugin=react
83
83
  $ xo --plugin=html --extension=html
84
84
  $ echo 'const x=true' | xo --stdin --fix
85
+ $ xo --print-config=index.js
85
86
 
86
87
  Tips
87
88
  - Add XO to your project with `npm init xo`.
@@ -267,15 +268,6 @@ Type: `string`
267
268
 
268
269
  [ESLint processor.](https://eslint.org/docs/user-guide/configuring#specifying-processor)
269
270
 
270
- ### esnext
271
-
272
- Type: `boolean`\
273
- Default: `true`
274
-
275
- Enforce ES2015+ rules. Disabling this will make it not *enforce* ES2015+ syntax and conventions.
276
-
277
- *ES2015+ is parsed even without this option. You can already use ES2017 features like [`async`/`await`](https://github.com/lukehoban/ecmascript-asyncawait).
278
-
279
271
  ### webpack
280
272
 
281
273
  Type: `boolean | object`
@@ -317,12 +309,11 @@ XO makes it easy to override configs for specific files. The `overrides` propert
317
309
  "overrides": [
318
310
  {
319
311
  "files": "test/*.js",
320
- "esnext": false,
321
312
  "space": 3
322
313
  },
323
314
  {
324
315
  "files": "test/foo.js",
325
- "esnext": true
316
+ "semicolon": true
326
317
  }
327
318
  ]
328
319
  }
@@ -331,11 +322,10 @@ XO makes it easy to override configs for specific files. The `overrides` propert
331
322
 
332
323
  - The base configuration is simply `space: 2`, `semicolon: false`. These settings are used for every file unless otherwise noted below.
333
324
 
334
- - For every file in `test/*.js`, the base config is used, but `space` is overridden with `3`, and the `esnext` option is set to `false`. The resulting config is:
325
+ - For every file in `test/*.js`, the base config is used, but `space` is overridden with `3`. The resulting config is:
335
326
 
336
327
  ```json
337
328
  {
338
- "esnext": false,
339
329
  "semicolon": false,
340
330
  "space": 3
341
331
  }
@@ -345,8 +335,7 @@ XO makes it easy to override configs for specific files. The `overrides` propert
345
335
 
346
336
  ```json
347
337
  {
348
- "esnext": true,
349
- "semicolon": false,
338
+ "semicolon": true,
350
339
  "space": 3
351
340
  }
352
341
  ```