@putout/plugin-nodejs 19.1.0 → 19.2.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 +40 -2
- package/lib/apply-privately-required-file/change-require/index.js +11 -0
- package/lib/apply-privately-required-file/get-require/index.js +28 -0
- package/lib/apply-privately-required-file/index.js +83 -0
- package/lib/apply-privately-required-file/private-imports.js +81 -0
- package/lib/index.js +2 -0
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -33,12 +33,16 @@ npm i putout @putout/plugin-nodejs -D
|
|
|
33
33
|
- ✅ [group-require-by-id](#group-require-by-id);
|
|
34
34
|
- ✅ [remove-process-exit](#remove-process-exit);
|
|
35
35
|
- ✅ [remove-useless-promisify](#remove-useless-promisify);
|
|
36
|
-
- ✅ [rename-file-cjs-to-js](#rename-file-cjs-to-js);
|
|
37
|
-
- ✅ [rename-file-mjs-to-js](#rename-file-mjs-to-js);
|
|
38
36
|
- ✅ [remove-useless-strict-mode](#remove-useless-strict-mode);
|
|
39
37
|
- ✅ [remove-illegal-strict-mode](#remove-useless-strict-mode);
|
|
38
|
+
|
|
39
|
+
## File rules
|
|
40
|
+
|
|
41
|
+
- ✅ [apply-privately-imported-file](#apply-privately-imported-file);
|
|
40
42
|
- ✅ [cjs-file](#cjs-file);
|
|
41
43
|
- ✅ [mjs-file](#mjs-file);
|
|
44
|
+
- ✅ [rename-file-cjs-to-js](#rename-file-cjs-to-js);
|
|
45
|
+
- ✅ [rename-file-mjs-to-js](#rename-file-mjs-to-js);
|
|
42
46
|
|
|
43
47
|
## Config
|
|
44
48
|
|
|
@@ -587,6 +591,40 @@ export const readSize = promisify(async (dir, options, callback) => {});
|
|
|
587
591
|
export const readSize = async (dir, options, callback) => {};
|
|
588
592
|
```
|
|
589
593
|
|
|
594
|
+
#### apply-privately-required-to-file
|
|
595
|
+
|
|
596
|
+
> Entries in the imports field must be strings starting with `#`.
|
|
597
|
+
> Package imports permit mapping to external packages.
|
|
598
|
+
> This field defines subpath imports for the current package.
|
|
599
|
+
>
|
|
600
|
+
> (c) [nodejs.org](https://nodejs.org/api/packages.html#imports)
|
|
601
|
+
|
|
602
|
+
Let's consider file structure:
|
|
603
|
+
|
|
604
|
+
```
|
|
605
|
+
/
|
|
606
|
+
|-- package.json {"imports": {"#is: {"default": "./lib/tokenize/is.js"}}}
|
|
607
|
+
|-- lib/
|
|
608
|
+
| `-- tokenize/
|
|
609
|
+
| `-- is.js "export const isPrev = () => {}"
|
|
610
|
+
| `-- expressions/
|
|
611
|
+
`-- spread-element.js "const {isPrev} = require('../is.js')"
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
In this case `spread-element.js` can be fixed:
|
|
615
|
+
|
|
616
|
+
#### ❌ Example of incorrect code
|
|
617
|
+
|
|
618
|
+
```js
|
|
619
|
+
const {isPrev} = require('../is.js');
|
|
620
|
+
```
|
|
621
|
+
|
|
622
|
+
#### ✅ Example of correct code
|
|
623
|
+
|
|
624
|
+
```js
|
|
625
|
+
const {isPrev} = require('#is');
|
|
626
|
+
```
|
|
627
|
+
|
|
590
628
|
## License
|
|
591
629
|
|
|
592
630
|
MIT
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import {types} from 'putout';
|
|
2
|
+
|
|
3
|
+
const {isStringLiteral} = types;
|
|
4
|
+
|
|
5
|
+
export const report = (path) => {
|
|
6
|
+
const [arg] = path.node.arguments;
|
|
7
|
+
return arg.value;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export const fix = () => {};
|
|
11
|
+
|
|
12
|
+
export const include = () => [
|
|
13
|
+
'require(__a)',
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
export const filter = (path) => {
|
|
17
|
+
const [arg] = path.node.arguments;
|
|
18
|
+
|
|
19
|
+
if (!isStringLiteral(arg))
|
|
20
|
+
return false;
|
|
21
|
+
|
|
22
|
+
const {value} = arg;
|
|
23
|
+
|
|
24
|
+
if (!value.startsWith('.'))
|
|
25
|
+
return false;
|
|
26
|
+
|
|
27
|
+
return /\.[mc]?js/.test(value);
|
|
28
|
+
};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import {join, dirname} from 'node:path';
|
|
2
|
+
import {
|
|
3
|
+
parse,
|
|
4
|
+
print,
|
|
5
|
+
transform,
|
|
6
|
+
operator,
|
|
7
|
+
} from 'putout';
|
|
8
|
+
import * as getImports from './get-require/index.js';
|
|
9
|
+
import * as changeImports from './change-require/index.js';
|
|
10
|
+
import {createGetPrivateImports} from './private-imports.js';
|
|
11
|
+
|
|
12
|
+
const {
|
|
13
|
+
getFilename,
|
|
14
|
+
readFileContent,
|
|
15
|
+
writeFileContent,
|
|
16
|
+
} = operator;
|
|
17
|
+
|
|
18
|
+
const getMessage = (a) => a.message;
|
|
19
|
+
|
|
20
|
+
export const report = (file, {from, to}) => `Apply privately required source: '${from}' -> '${to}'`;
|
|
21
|
+
export const fix = (file, {content, ast, from, to}) => {
|
|
22
|
+
transform(ast, content, {
|
|
23
|
+
rules: {
|
|
24
|
+
'change-require': ['on', {
|
|
25
|
+
from,
|
|
26
|
+
to,
|
|
27
|
+
}],
|
|
28
|
+
},
|
|
29
|
+
plugins: [
|
|
30
|
+
['change-require', 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
|
+
'*.cjs',
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
const getPrivateImports = createGetPrivateImports();
|
|
46
|
+
|
|
47
|
+
for (const file of trackFile(rootPath, mask)) {
|
|
48
|
+
const content = readFileContent(file);
|
|
49
|
+
|
|
50
|
+
if (!content.includes('require'))
|
|
51
|
+
continue;
|
|
52
|
+
|
|
53
|
+
const privateImports = getPrivateImports(file);
|
|
54
|
+
|
|
55
|
+
if (!privateImports.size)
|
|
56
|
+
continue;
|
|
57
|
+
|
|
58
|
+
const ast = parse(content);
|
|
59
|
+
|
|
60
|
+
const places = transform(ast, content, {
|
|
61
|
+
plugins: [
|
|
62
|
+
['get-require', getImports],
|
|
63
|
+
],
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const imports = places.map(getMessage);
|
|
67
|
+
|
|
68
|
+
const filename = getFilename(file);
|
|
69
|
+
const dir = dirname(filename);
|
|
70
|
+
|
|
71
|
+
for (const from of imports) {
|
|
72
|
+
const to = join(dir, from);
|
|
73
|
+
|
|
74
|
+
if (privateImports.has(to))
|
|
75
|
+
push(file, {
|
|
76
|
+
from,
|
|
77
|
+
to: privateImports.get(to),
|
|
78
|
+
content,
|
|
79
|
+
ast,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import {dirname, resolve} from 'node:path';
|
|
2
|
+
import {tryCatch} from 'try-catch';
|
|
3
|
+
import {operator} from 'putout';
|
|
4
|
+
|
|
5
|
+
const {
|
|
6
|
+
getFilename,
|
|
7
|
+
readFileContent,
|
|
8
|
+
findFileUp,
|
|
9
|
+
} = operator;
|
|
10
|
+
|
|
11
|
+
const {entries} = Object;
|
|
12
|
+
const {parse: parseJson} = JSON;
|
|
13
|
+
const isString = (a) => typeof a === 'string';
|
|
14
|
+
|
|
15
|
+
function insert(a, b, {importsEntries, aliasBased}) {
|
|
16
|
+
if (aliasBased) {
|
|
17
|
+
importsEntries.set(b, a);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
importsEntries.set(a, b);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const createGetPrivateImports = (importsCache = new Map(), emptyMap = new Map()) => (file, options = {}) => {
|
|
25
|
+
const filename = getFilename(file);
|
|
26
|
+
const dir = dirname(filename);
|
|
27
|
+
const {aliasBased = false} = options;
|
|
28
|
+
|
|
29
|
+
if (importsCache.has(dir))
|
|
30
|
+
return importsCache.get(dir);
|
|
31
|
+
|
|
32
|
+
const [packageDirectory, packagePath] = findFileUp(file, 'package.json');
|
|
33
|
+
|
|
34
|
+
if (!packagePath) {
|
|
35
|
+
importsCache.set(dir, emptyMap);
|
|
36
|
+
return emptyMap;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const packageContent = readFileContent(packagePath);
|
|
40
|
+
const [error, packageJson] = tryCatch(parseJson, packageContent);
|
|
41
|
+
|
|
42
|
+
if (error) {
|
|
43
|
+
importsCache.set(dir, emptyMap);
|
|
44
|
+
|
|
45
|
+
return emptyMap;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const {imports = {}} = packageJson;
|
|
49
|
+
const importsEntries = new Map();
|
|
50
|
+
|
|
51
|
+
for (const [alias, property] of entries(imports)) {
|
|
52
|
+
const filePath = parseProperty(property);
|
|
53
|
+
|
|
54
|
+
if (!filePath)
|
|
55
|
+
continue;
|
|
56
|
+
|
|
57
|
+
const resolvedPath = resolve(packageDirectory, filePath);
|
|
58
|
+
|
|
59
|
+
insert(resolvedPath, alias, {
|
|
60
|
+
importsEntries,
|
|
61
|
+
aliasBased,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
importsCache.set(dir, importsEntries);
|
|
66
|
+
|
|
67
|
+
return importsEntries;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
function parseProperty(property) {
|
|
71
|
+
if (isString(property))
|
|
72
|
+
return property;
|
|
73
|
+
|
|
74
|
+
const {
|
|
75
|
+
default: filePath,
|
|
76
|
+
node,
|
|
77
|
+
browser,
|
|
78
|
+
} = property;
|
|
79
|
+
|
|
80
|
+
return filePath || node || browser;
|
|
81
|
+
}
|
package/lib/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as applyPrivatelyRequiredFiles from './apply-privately-required-file/index.js';
|
|
1
2
|
import * as convertBufferToBufferAlloc from './convert-buffer-to-buffer-alloc/index.js';
|
|
2
3
|
import * as convertFsPromises from './convert-fs-promises/index.js';
|
|
3
4
|
import * as convertPromisifyToFsPromises from './convert-promisify-to-fs-promises/index.js';
|
|
@@ -32,6 +33,7 @@ export const rules = {
|
|
|
32
33
|
'add-node-prefix': addNodePrefix,
|
|
33
34
|
'convert-exports-to-module-exports': convertExportsToModuleExports,
|
|
34
35
|
|
|
36
|
+
'apply-privately-required-files': ['off', applyPrivatelyRequiredFiles],
|
|
35
37
|
'convert-esm-to-commonjs': ['off', convertEsmToCommonjs],
|
|
36
38
|
'convert-commonjs-to-esm/exports': ['off', convertCommonjsToEsm.rules.exports],
|
|
37
39
|
'convert-commonjs-to-esm/common': ['off', convertCommonjsToEsm.rules.commons],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@putout/plugin-nodejs",
|
|
3
|
-
"version": "19.1
|
|
3
|
+
"version": "19.2.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"author": "coderaiser <mnemonic.enemy@gmail.com> (https://github.com/coderaiser)",
|
|
6
6
|
"description": "🐊Putout plugin adds ability to transform code to new API of Node.js",
|
|
@@ -30,7 +30,8 @@
|
|
|
30
30
|
"report": "madrun report"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"just-camel-case": "^6.2.0"
|
|
33
|
+
"just-camel-case": "^6.2.0",
|
|
34
|
+
"try-catch": "^4.0.7"
|
|
34
35
|
},
|
|
35
36
|
"keywords": [
|
|
36
37
|
"putout",
|
|
@@ -39,7 +40,7 @@
|
|
|
39
40
|
"nodejs"
|
|
40
41
|
],
|
|
41
42
|
"devDependencies": {
|
|
42
|
-
"@putout/eslint-flat": "^
|
|
43
|
+
"@putout/eslint-flat": "^4.0.0",
|
|
43
44
|
"@putout/plugin-declare": "*",
|
|
44
45
|
"@putout/plugin-declare-before-reference": "*",
|
|
45
46
|
"@putout/plugin-esm": "*",
|
|
@@ -50,7 +51,7 @@
|
|
|
50
51
|
"c8": "^10.0.0",
|
|
51
52
|
"eslint": "^10.0.0-alpha.0",
|
|
52
53
|
"eslint-plugin-n": "^17.0.0",
|
|
53
|
-
"eslint-plugin-putout": "^
|
|
54
|
+
"eslint-plugin-putout": "^30.0.0",
|
|
54
55
|
"madrun": "^12.0.0",
|
|
55
56
|
"montag": "^1.2.1",
|
|
56
57
|
"nodemon": "^3.0.1"
|