@putout/plugin-esm 4.0.0 → 4.1.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/README.md
CHANGED
|
@@ -27,6 +27,7 @@ npm i putout @putout/plugin-esm -D
|
|
|
27
27
|
- ✅ [remove-empty-import](#remove-empty-import);
|
|
28
28
|
- ✅ [remove-empty-export](#remove-empty-export);
|
|
29
29
|
- ✅ [sort-imports-by-specifiers](#sort-imports-by-specifiers);
|
|
30
|
+
- ✅ [resolve-imported-file](#resolve-imported-file);
|
|
30
31
|
|
|
31
32
|
## Config
|
|
32
33
|
|
|
@@ -43,7 +44,8 @@ npm i putout @putout/plugin-esm -D
|
|
|
43
44
|
"esm/remove-empty-import": ["on", {
|
|
44
45
|
"ignore": []
|
|
45
46
|
}],
|
|
46
|
-
"esm/sort-imports-by-specifiers": "on"
|
|
47
|
+
"esm/sort-imports-by-specifiers": "on",
|
|
48
|
+
"esm/resolve-imported-file": "on"
|
|
47
49
|
}
|
|
48
50
|
}
|
|
49
51
|
```
|
|
@@ -73,7 +75,6 @@ import addAction from './add-action/index.js';
|
|
|
73
75
|
export const rules = {};
|
|
74
76
|
```
|
|
75
77
|
|
|
76
|
-
|
|
77
78
|
### apply-export-from
|
|
78
79
|
|
|
79
80
|
> The `export` declaration is used to export values from a JavaScript module.
|
|
@@ -305,6 +306,37 @@ import('foo.json', {
|
|
|
305
306
|
});
|
|
306
307
|
```
|
|
307
308
|
|
|
309
|
+
### resolve-imported-file
|
|
310
|
+
|
|
311
|
+
Check out in 🐊**Putout Editor**:
|
|
312
|
+
|
|
313
|
+
- ✅ [`resolve-imported-file`](https://putout.cloudcmd.io/#/gist/241489cb2781dd37ec96baf0115cde4e/83c2f2e9f490850b7fda432f8d25ae6a64ed07e3);
|
|
314
|
+
- ✅ [`get-imports`](https://putout.cloudcmd.io/#/gist/ee10100fed86e4db926885dd54298668/7538bca7a9ae006d976f41261c0ed4c0e1902ace);
|
|
315
|
+
- ✅ [`change-imports`](https://putout.cloudcmd.io/#/gist/23a6dc6741b772c03fbed95feda2b451/1fbecac6fc40282bcda0593aa666a8c213ef85b7);
|
|
316
|
+
|
|
317
|
+
Let's consider file structure:
|
|
318
|
+
|
|
319
|
+
```
|
|
320
|
+
/
|
|
321
|
+
|-- lib/
|
|
322
|
+
| `-- index.js
|
|
323
|
+
| `-- a.js
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
In this case `index.js` can be fixed:
|
|
327
|
+
|
|
328
|
+
#### ❌ Example of incorrect code
|
|
329
|
+
|
|
330
|
+
```js
|
|
331
|
+
import a from './a';
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
#### ✅ Example of correct code
|
|
335
|
+
|
|
336
|
+
```js
|
|
337
|
+
import a from './a.js';
|
|
338
|
+
```
|
|
339
|
+
|
|
308
340
|
## License
|
|
309
341
|
|
|
310
342
|
MIT
|
package/lib/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as resolveImportedFile from './resolve-imported-file/index.js';
|
|
1
2
|
import * as addIndexToImport from './add-index-to-import/index.js';
|
|
2
3
|
import * as declareImportsFirst from './declare-imports-first/index.js';
|
|
3
4
|
import * as groupImportsBySource from './group-imports-by-source/index.js';
|
|
@@ -10,7 +11,7 @@ import * as convertAssertToWith from './convert-assert-to-with/index.js';
|
|
|
10
11
|
import * as applyExportFrom from './apply-export-from/index.js';
|
|
11
12
|
|
|
12
13
|
export const rules = {
|
|
13
|
-
'add-index-to-import': addIndexToImport,
|
|
14
|
+
'add-index-to-import': ['off', addIndexToImport],
|
|
14
15
|
'apply-export-from': applyExportFrom,
|
|
15
16
|
'convert-assert-to-with': convertAssertToWith,
|
|
16
17
|
'declare-imports-first': declareImportsFirst,
|
|
@@ -20,4 +21,5 @@ export const rules = {
|
|
|
20
21
|
'remove-empty-import': removeEmptyImport,
|
|
21
22
|
'remove-empty-export': removeEmptyExport,
|
|
22
23
|
'sort-imports-by-specifiers': sortImportsBySpecifiers,
|
|
24
|
+
'resolve-imported-file': ['off', resolveImportedFile],
|
|
23
25
|
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const report = (path) => path.node.source.value;
|
|
2
|
+
|
|
3
|
+
export const fix = () => {};
|
|
4
|
+
|
|
5
|
+
export const include = () => [
|
|
6
|
+
'ImportDeclaration',
|
|
7
|
+
];
|
|
8
|
+
|
|
9
|
+
export const filter = (path) => {
|
|
10
|
+
const {value} = path.node.source;
|
|
11
|
+
|
|
12
|
+
if (!value.startsWith('.'))
|
|
13
|
+
return false;
|
|
14
|
+
|
|
15
|
+
return !/\.[m|c]?js/.test(value);
|
|
16
|
+
};
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import {join, dirname} from 'node:path';
|
|
2
|
+
import {
|
|
3
|
+
parse,
|
|
4
|
+
print,
|
|
5
|
+
transform,
|
|
6
|
+
operator,
|
|
7
|
+
} from 'putout';
|
|
8
|
+
import * as getImportsSource from './get-imports-source/index.js';
|
|
9
|
+
import * as changeImports from './change-imports/index.js';
|
|
10
|
+
|
|
11
|
+
const {
|
|
12
|
+
findFile,
|
|
13
|
+
getFilename,
|
|
14
|
+
readFileContent,
|
|
15
|
+
writeFileContent,
|
|
16
|
+
} = operator;
|
|
17
|
+
|
|
18
|
+
const getMessage = (a) => a.message;
|
|
19
|
+
|
|
20
|
+
export const report = (file, {from, to}) => `Resolve import source: '${from}' -> '${to}'`;
|
|
21
|
+
export const fix = (file, {content, ast, from, to}) => {
|
|
22
|
+
transform(ast, content, {
|
|
23
|
+
rules: {
|
|
24
|
+
'change-imports': ['on', {
|
|
25
|
+
from,
|
|
26
|
+
to,
|
|
27
|
+
}],
|
|
28
|
+
},
|
|
29
|
+
plugins: [
|
|
30
|
+
['change-imports', changeImports],
|
|
31
|
+
],
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const newContent = print(ast);
|
|
35
|
+
|
|
36
|
+
writeFileContent(file, newContent);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const scan = (rootPath, {push, trackFile}) => {
|
|
40
|
+
const mask = [
|
|
41
|
+
'*.js',
|
|
42
|
+
'*.mjs',
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
for (const file of trackFile(rootPath, mask)) {
|
|
46
|
+
const content = readFileContent(file);
|
|
47
|
+
|
|
48
|
+
if (!content.includes('import'))
|
|
49
|
+
continue;
|
|
50
|
+
|
|
51
|
+
const ast = parse(content);
|
|
52
|
+
|
|
53
|
+
const places = transform(ast, content, {
|
|
54
|
+
plugins: [
|
|
55
|
+
['get-imports-source', getImportsSource],
|
|
56
|
+
],
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const imports = places.map(getMessage);
|
|
60
|
+
const filename = getFilename(file);
|
|
61
|
+
const dir = dirname(filename);
|
|
62
|
+
const importsTuples = buildImports(dir, imports);
|
|
63
|
+
const resolvedTuples = buildResolved(rootPath, importsTuples);
|
|
64
|
+
|
|
65
|
+
for (const [from, to] of resolvedTuples) {
|
|
66
|
+
push(file, {
|
|
67
|
+
from,
|
|
68
|
+
to,
|
|
69
|
+
content,
|
|
70
|
+
ast,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
function buildImports(dir, imports) {
|
|
77
|
+
const list = [];
|
|
78
|
+
|
|
79
|
+
for (const current of imports) {
|
|
80
|
+
const full = join(dir, current);
|
|
81
|
+
list.push([current, full]);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return list;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function buildResolved(rootPath, importsTuples) {
|
|
88
|
+
const result = [];
|
|
89
|
+
|
|
90
|
+
for (const [relative, current] of importsTuples) {
|
|
91
|
+
const withIndex = join(current, 'index.js');
|
|
92
|
+
const withJs = `${current}.js`;
|
|
93
|
+
|
|
94
|
+
if (findFile(rootPath, withIndex).length) {
|
|
95
|
+
result.push([relative, `${relative}/index.js`]);
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (relative === '..') {
|
|
100
|
+
const withPackage = join(current, 'package.json');
|
|
101
|
+
const [packageJson] = findFile(rootPath, withPackage);
|
|
102
|
+
|
|
103
|
+
if (!packageJson)
|
|
104
|
+
continue;
|
|
105
|
+
|
|
106
|
+
const json = readFileContent(packageJson);
|
|
107
|
+
const {main} = JSON.parse(json);
|
|
108
|
+
|
|
109
|
+
result.push([relative, join(relative, main)]);
|
|
110
|
+
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (findFile(rootPath, withJs).length) {
|
|
115
|
+
result.push([relative, `${relative}.js`]);
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return result;
|
|
121
|
+
}
|
package/package.json
CHANGED