eslint-plugin-putout 10.1.0 → 10.5.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/README.md +4 -2
- package/lib/evaluate/README.md +35 -0
- package/lib/evaluate/index.js +44 -0
- package/lib/index.js +4 -0
- package/lib/no-unresolved/README.md +30 -0
- package/lib/no-unresolved/index.js +75 -0
- package/lib/single-property-destructuring/README.md +2 -2
- package/lib/ts.js +1 -0
- package/lib/wrap.js +5 -1
- package/package.json +10 -4
package/README.md
CHANGED
|
@@ -70,6 +70,8 @@ Then configure the rules you want to use under the rules section.
|
|
|
70
70
|
- [Remove newline after default import](/packages/eslint-plugin-putout/lib/remove-newline-after-default-import)
|
|
71
71
|
- [Objects braces inside array](/packages/eslint-plugin-putout/lib/objects-braces-inside-array)
|
|
72
72
|
- [Object init](/packages/eslint-plugin-putout/lib/object-init)
|
|
73
|
+
- [No unresolved](/packages/eslint-plugin-putout/lib/no-unresolved)
|
|
74
|
+
- [Evaluate](/packages/eslint-plugin-putout/lib/evaluate)
|
|
73
75
|
|
|
74
76
|
### Safe mode
|
|
75
77
|
|
|
@@ -95,5 +97,5 @@ List of disabled `putout` rules:
|
|
|
95
97
|
- [remove-skip](https://github.com/coderaiser/putout/tree/v20.0.0/packages/remove-skip);
|
|
96
98
|
- [remove-only](https://github.com/coderaiser/putout/tree/v20.0.0/packages/remove-only);
|
|
97
99
|
- [remove-console](https://github.com/coderaiser/putout/tree/v20.0.0/packages/remove-console);
|
|
98
|
-
- [
|
|
99
|
-
- [
|
|
100
|
+
- [remove-debugger](https://github.com/coderaiser/putout/tree/v20.0.0/packages/remove-debugger);
|
|
101
|
+
- [convert-for-to-for-of](https://github.com/coderaiser/putout/tree/v20.0.0/packages/convert-for-to-for-of);
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# evaluate expression (evaluate)
|
|
2
|
+
|
|
3
|
+
Evaluate expression started with `__putout_evaluate: `.
|
|
4
|
+
Provided code is processed with [`@putout/plugin-declare-undefined-variables`](https://github.com/coderaiser/putout/tree/master/packages/plugin-declare-undefined-variables). So next code:
|
|
5
|
+
|
|
6
|
+
```js
|
|
7
|
+
import {join} from 'path';
|
|
8
|
+
__putout_evaluate: join("hello", " ", "world");
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Converted to:
|
|
12
|
+
|
|
13
|
+
```js
|
|
14
|
+
const fn = (__filename, __dirname, require) => {
|
|
15
|
+
const {join} = require('path');
|
|
16
|
+
return join("hello", " ", "world");
|
|
17
|
+
};
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Rule Details
|
|
21
|
+
|
|
22
|
+
This rule aims to evaluate expressions `source` of `ImportDeclaration`:
|
|
23
|
+
|
|
24
|
+
Examples of **incorrect** code locaed in `hello.spec.js` for this rule:
|
|
25
|
+
|
|
26
|
+
```js
|
|
27
|
+
import {readFile} from '__putout_evaluate: `./` + basename(__filename).replace(`.spec.js`, `.js`)';
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Examples of **correct** code for this rule:
|
|
32
|
+
|
|
33
|
+
```js
|
|
34
|
+
import {readFile} from './hello.js';
|
|
35
|
+
```
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const {dirname} = require('path');
|
|
4
|
+
const putout = require('putout');
|
|
5
|
+
|
|
6
|
+
module.exports.category = 'evaluate';
|
|
7
|
+
module.exports.report = () => 'Evaluate expression';
|
|
8
|
+
module.exports.include = () => ['ImportDeclaration'];
|
|
9
|
+
|
|
10
|
+
module.exports.filter = ({node}) => {
|
|
11
|
+
const {value} = node.source;
|
|
12
|
+
|
|
13
|
+
if (!/^__putout_evaluate:/.test(value))
|
|
14
|
+
return false;
|
|
15
|
+
|
|
16
|
+
return true;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
module.exports.fix = ({text, node, filename}) => {
|
|
20
|
+
const {value} = node.source;
|
|
21
|
+
|
|
22
|
+
const result = evaluate({
|
|
23
|
+
value,
|
|
24
|
+
filename,
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
return text.replace(value, result);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
function evaluate({value, filename}) {
|
|
31
|
+
value = value.replace(/__putout_evaluate:\s?/, 'return ');
|
|
32
|
+
const {code} = putout(value, {
|
|
33
|
+
rules: {
|
|
34
|
+
'convert-esm-to-commonjs': 'on',
|
|
35
|
+
},
|
|
36
|
+
plugins: [
|
|
37
|
+
'declare-undefined-variables',
|
|
38
|
+
'convert-esm-to-commonjs',
|
|
39
|
+
],
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
const fn = Function('__filename', '__dirname', 'require', code);
|
|
43
|
+
return fn(filename, dirname(__filename), require);
|
|
44
|
+
}
|
package/lib/index.js
CHANGED
|
@@ -28,6 +28,8 @@ module.exports.rules = {
|
|
|
28
28
|
...getWrapRule('remove-newline-after-default-import'),
|
|
29
29
|
...getWrapRule('objects-braces-inside-array'),
|
|
30
30
|
...getWrapRule('object-init'),
|
|
31
|
+
...getWrapRule('no-unresolved'),
|
|
32
|
+
...getWrapRule('evaluate'),
|
|
31
33
|
...getRule('putout'),
|
|
32
34
|
};
|
|
33
35
|
|
|
@@ -53,6 +55,8 @@ const recommended = {
|
|
|
53
55
|
'putout/remove-newline-after-default-import': 'error',
|
|
54
56
|
'putout/objects-braces-inside-array': 'error',
|
|
55
57
|
'putout/object-init': 'error',
|
|
58
|
+
'putout/no-unresolved': 'error',
|
|
59
|
+
'putout/evaluate': 'error',
|
|
56
60
|
'putout/putout': 'error',
|
|
57
61
|
|
|
58
62
|
'node/no-unsupported-features/es-syntax': 'off',
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# check if path can be resolved and fix if cannot (no-unresolved)
|
|
2
|
+
|
|
3
|
+
Similar to [`no-unresolved`](https://github.com/import-js/eslint-plugin-import/blob/HEAD/docs/rules/no-unresolved.md) from
|
|
4
|
+
[`eslint-plugin-putout`](https://github.com/import-js/eslint-plugin-import). But supports only `ESM` and have `autofix`.
|
|
5
|
+
|
|
6
|
+
## Rule Details
|
|
7
|
+
|
|
8
|
+
This rule aims to fix `unresolved import`:
|
|
9
|
+
|
|
10
|
+
Examples of **incorrect** code for this rule:
|
|
11
|
+
|
|
12
|
+
```js
|
|
13
|
+
import x from './y';
|
|
14
|
+
import dir from './dir';
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
[File extension is mandatory](https://nodejs.org/api/esm.html#esm_mandatory_file_extensions) and will produce an error from `node.js`:
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/Users/coderaiser/putout/y' imported from /Users/coderaiser/putout/x.mjs
|
|
21
|
+
Did you mean to import ../y.js?
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Examples of **correct** code for this rule:
|
|
25
|
+
|
|
26
|
+
```js
|
|
27
|
+
import x from './y.js';
|
|
28
|
+
import dir from './dir/index.js';
|
|
29
|
+
```
|
|
30
|
+
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const tryCatch = require('try-catch');
|
|
4
|
+
|
|
5
|
+
const {accessSync} = require('fs');
|
|
6
|
+
|
|
7
|
+
const {
|
|
8
|
+
extname,
|
|
9
|
+
dirname,
|
|
10
|
+
join,
|
|
11
|
+
} = require('path');
|
|
12
|
+
|
|
13
|
+
const cwd = process.cwd();
|
|
14
|
+
|
|
15
|
+
const RELATIVE = '\\.\\.?\\/?';
|
|
16
|
+
const isRelativeStart = (a) => RegExp(`^${RELATIVE}`).test(a);
|
|
17
|
+
const isRelativeEnd = (a) => RegExp(`${RELATIVE}$`).test(a);
|
|
18
|
+
const getDir = (a) => a === '<input>' ? cwd : dirname(a);
|
|
19
|
+
|
|
20
|
+
module.exports.category = 'errors';
|
|
21
|
+
module.exports.report = () => 'Always add an extension to relative imports';
|
|
22
|
+
module.exports.include = () => ['ImportDeclaration'];
|
|
23
|
+
|
|
24
|
+
module.exports.fix = ({node, text, filename}) => {
|
|
25
|
+
const {source} = node;
|
|
26
|
+
const {value} = source;
|
|
27
|
+
|
|
28
|
+
const dir = getDir(filename);
|
|
29
|
+
|
|
30
|
+
const resolved = resolveSource({
|
|
31
|
+
dir,
|
|
32
|
+
value,
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
return text.replace(value, resolved);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
module.exports.filter = ({node}) => {
|
|
39
|
+
const {source} = node;
|
|
40
|
+
const {value} = source;
|
|
41
|
+
|
|
42
|
+
if (!isRelativeStart(value))
|
|
43
|
+
return false;
|
|
44
|
+
|
|
45
|
+
return !extname(value);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
function resolveSource({dir, value}) {
|
|
49
|
+
if (isRelativeEnd(value)) {
|
|
50
|
+
const name = join(dir, value, 'package.json');
|
|
51
|
+
const [error, info] = tryCatch(require, name);
|
|
52
|
+
|
|
53
|
+
if (error)
|
|
54
|
+
return value;
|
|
55
|
+
|
|
56
|
+
return join(value, info.main);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
for (const ext of ['js', 'mjs', 'cjs']) {
|
|
60
|
+
const name = join(dir, `${value}.${ext}`);
|
|
61
|
+
const [error] = tryCatch(accessSync, name);
|
|
62
|
+
|
|
63
|
+
if (!error)
|
|
64
|
+
return `${value}.${ext}`;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const name = join(dir, value, `index.js`);
|
|
68
|
+
const [error] = tryCatch(accessSync, name);
|
|
69
|
+
|
|
70
|
+
if (!error)
|
|
71
|
+
return join(value, 'index.js');
|
|
72
|
+
|
|
73
|
+
return `${value}.js`;
|
|
74
|
+
}
|
|
75
|
+
|
|
@@ -15,12 +15,12 @@ const {
|
|
|
15
15
|
|
|
16
16
|
import {
|
|
17
17
|
password,
|
|
18
|
-
} from './user';
|
|
18
|
+
} from './user.js';
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
Examples of **correct** code for this rule:
|
|
22
22
|
|
|
23
23
|
```js
|
|
24
24
|
const {username} = user;
|
|
25
|
-
import {password} from './user';
|
|
25
|
+
import {password} from './user.js';
|
|
26
26
|
```
|
package/lib/ts.js
CHANGED
package/lib/wrap.js
CHANGED
|
@@ -4,6 +4,7 @@ const prepare = (plugin, context, options) => (node) => {
|
|
|
4
4
|
const {filter, report} = plugin;
|
|
5
5
|
|
|
6
6
|
const source = context.getSourceCode();
|
|
7
|
+
const filename = context.getFilename();
|
|
7
8
|
const getText = source.getText.bind(source);
|
|
8
9
|
|
|
9
10
|
const text = getText(node);
|
|
@@ -13,12 +14,14 @@ const prepare = (plugin, context, options) => (node) => {
|
|
|
13
14
|
node,
|
|
14
15
|
options,
|
|
15
16
|
getText,
|
|
17
|
+
filename,
|
|
16
18
|
});
|
|
17
19
|
|
|
18
20
|
if (!result)
|
|
19
21
|
return;
|
|
20
22
|
|
|
21
23
|
const fix = prepareFix(plugin.fix, {
|
|
24
|
+
filename,
|
|
22
25
|
node,
|
|
23
26
|
text,
|
|
24
27
|
getText,
|
|
@@ -31,11 +34,12 @@ const prepare = (plugin, context, options) => (node) => {
|
|
|
31
34
|
});
|
|
32
35
|
};
|
|
33
36
|
|
|
34
|
-
const prepareFix = (fix, {node, text, getText}) => (fixer) => {
|
|
37
|
+
const prepareFix = (fix, {node, text, getText, filename}) => (fixer) => {
|
|
35
38
|
const fixed = fix({
|
|
36
39
|
node,
|
|
37
40
|
text,
|
|
38
41
|
getText,
|
|
42
|
+
filename,
|
|
39
43
|
});
|
|
40
44
|
|
|
41
45
|
return [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-putout",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.5.0",
|
|
4
4
|
"description": "eslint plugin for putout",
|
|
5
5
|
"release": false,
|
|
6
6
|
"tag": false,
|
|
@@ -20,9 +20,11 @@
|
|
|
20
20
|
"scripts": {
|
|
21
21
|
"wisdom": "madrun wisdom",
|
|
22
22
|
"test": "madrun test",
|
|
23
|
+
"test:all": "madrun test:all",
|
|
23
24
|
"watch:test": "madrun watch:test",
|
|
24
25
|
"lint": "madrun lint",
|
|
25
|
-
"lint:
|
|
26
|
+
"lint:all": "madrun lint:all",
|
|
27
|
+
"lint:ide": "madrun lint:ide",
|
|
26
28
|
"fresh:lint": "madrun fresh:lint",
|
|
27
29
|
"lint:fresh": "madrun lint:fresh",
|
|
28
30
|
"fix:lint": "madrun fix:lint",
|
|
@@ -38,7 +40,8 @@
|
|
|
38
40
|
"@putout/eslint-config": "^6.0.0",
|
|
39
41
|
"align-spaces": "^1.0.0",
|
|
40
42
|
"eslint-plugin-node": "^11.0.0",
|
|
41
|
-
"estree-to-babel": "^4.0.1"
|
|
43
|
+
"estree-to-babel": "^4.0.1",
|
|
44
|
+
"try-catch": "^3.0.0"
|
|
42
45
|
},
|
|
43
46
|
"devDependencies": {
|
|
44
47
|
"c8": "^7.5.0",
|
|
@@ -46,7 +49,10 @@
|
|
|
46
49
|
"eslint-plugin-eslint-plugin": "^3.2.0",
|
|
47
50
|
"madrun": "^8.0.1",
|
|
48
51
|
"mocha": "^9.0.1",
|
|
49
|
-
"montag": "^1.0.0"
|
|
52
|
+
"montag": "^1.0.0",
|
|
53
|
+
"simport": "^1.2.0",
|
|
54
|
+
"supertape": "^6.6.0",
|
|
55
|
+
"try-to-catch": "^3.0.0"
|
|
50
56
|
},
|
|
51
57
|
"engines": {
|
|
52
58
|
"node": ">=14"
|