@jsenv/plugin-commonjs 2.5.1 → 2.6.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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsenv/plugin-commonjs",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -28,16 +28,15 @@
|
|
|
28
28
|
"@jsenv/log": "3.4.0",
|
|
29
29
|
"@jsenv/url-meta": "8.1.0",
|
|
30
30
|
"@jsenv/urls": "2.2.1",
|
|
31
|
-
"@rollup/plugin-commonjs": "25.0.
|
|
31
|
+
"@rollup/plugin-commonjs": "25.0.4",
|
|
32
32
|
"@rollup/plugin-json": "6.0.0",
|
|
33
|
-
"@rollup/plugin-node-resolve": "15.1
|
|
33
|
+
"@rollup/plugin-node-resolve": "15.2.1",
|
|
34
34
|
"@rollup/plugin-replace": "5.0.2",
|
|
35
35
|
"cjs-module-lexer": "1.2.3",
|
|
36
36
|
"is-valid-identifier": "2.0.2",
|
|
37
|
-
"resolve": "1.22.
|
|
38
|
-
"rollup": "3.
|
|
37
|
+
"resolve": "1.22.4",
|
|
38
|
+
"rollup": "3.29.1",
|
|
39
39
|
"rollup-plugin-node-globals": "1.4.0",
|
|
40
|
-
"rollup-plugin-polyfill-node": "0.12.0"
|
|
41
|
-
"vm2": "3.9.19"
|
|
40
|
+
"rollup-plugin-polyfill-node": "0.12.0"
|
|
42
41
|
}
|
|
43
42
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { readFileSync } from "node:fs";
|
|
4
4
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
5
5
|
import path from "node:path";
|
|
6
|
-
import {
|
|
6
|
+
import { Worker } from "node:worker_threads";
|
|
7
7
|
import resolve from "resolve";
|
|
8
8
|
import isValidIdentifier from "is-valid-identifier";
|
|
9
9
|
import { init, parse } from "cjs-module-lexer";
|
|
@@ -27,23 +27,29 @@ export const rollupPluginCommonJsNamedExports = ({ logger }) => {
|
|
|
27
27
|
name: "scan_cjs_named_exports",
|
|
28
28
|
async buildStart({ input }) {
|
|
29
29
|
await init();
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
detectStaticExports({
|
|
34
|
-
detectExportsUsingSandboxedRuntime({
|
|
30
|
+
await Promise.all(
|
|
31
|
+
Object.keys(input).map(async (key) => {
|
|
32
|
+
const inputFilePath = input[key];
|
|
33
|
+
let namedCjs = detectStaticExports({
|
|
35
34
|
logger,
|
|
36
35
|
filePath: inputFilePath,
|
|
37
36
|
});
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
37
|
+
if (!namedCjs) {
|
|
38
|
+
namedCjs = await detectExportsUsingSandboxedRuntime({
|
|
39
|
+
logger,
|
|
40
|
+
filePath: inputFilePath,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
scanResults[inputFilePath] = {
|
|
44
|
+
all: true,
|
|
45
|
+
default: true,
|
|
46
|
+
namespace: true,
|
|
47
|
+
named: [],
|
|
48
|
+
namedCjs,
|
|
49
|
+
};
|
|
50
|
+
input[key] = importWrapper.wrap(inputFilePath);
|
|
51
|
+
}),
|
|
52
|
+
);
|
|
47
53
|
},
|
|
48
54
|
resolveId(specifier) {
|
|
49
55
|
if (importWrapper.isWrapped(specifier)) {
|
|
@@ -126,20 +132,36 @@ const detectStaticExports = ({ logger, filePath, visited = new Set() }) => {
|
|
|
126
132
|
/*
|
|
127
133
|
* Attempt #2b - Sandboxed runtime analysis: More powerful, but slower.
|
|
128
134
|
* This will only work on UMD and very simple CJS files (require not supported).
|
|
129
|
-
*
|
|
135
|
+
* run safely sandbox untrusted code (no access no Node.js primitives, just JS).
|
|
130
136
|
* If nothing was detected, return undefined.
|
|
131
137
|
*/
|
|
132
|
-
const detectExportsUsingSandboxedRuntime = ({
|
|
138
|
+
export const detectExportsUsingSandboxedRuntime = async ({
|
|
139
|
+
logger,
|
|
140
|
+
filePath,
|
|
141
|
+
}) => {
|
|
133
142
|
try {
|
|
134
|
-
const
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
143
|
+
const workerThread = new Worker(
|
|
144
|
+
new URL("./worker_runtime.mjs", import.meta.url),
|
|
145
|
+
);
|
|
146
|
+
workerThread.postMessage({
|
|
147
|
+
filePath,
|
|
148
|
+
});
|
|
149
|
+
const promise = new Promise((resolve, reject) => {
|
|
150
|
+
workerThread.on("error", reject);
|
|
151
|
+
workerThread.on("message", (message) => {
|
|
152
|
+
resolve(message);
|
|
153
|
+
workerThread.terminate();
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
const result = await promise;
|
|
157
|
+
if (result.errorMessage) {
|
|
158
|
+
throw new Error(result.errorMessage);
|
|
159
|
+
}
|
|
160
|
+
const exportNames = result.exportNames;
|
|
139
161
|
logger.debug(
|
|
140
|
-
`detectExportsUsingSandboxedRuntime success ${filePath}: ${
|
|
162
|
+
`detectExportsUsingSandboxedRuntime success ${filePath}: ${exportNames}`,
|
|
141
163
|
);
|
|
142
|
-
return
|
|
164
|
+
return exportNames.filter((identifier) => isValidIdentifier(identifier));
|
|
143
165
|
} catch (err) {
|
|
144
166
|
logger.debug(
|
|
145
167
|
`detectExportsUsingSandboxedRuntime error ${filePath}: ${err.message}`,
|
|
@@ -151,13 +173,6 @@ const detectExportsUsingSandboxedRuntime = ({ logger, filePath }) => {
|
|
|
151
173
|
const isValidNamedExport = (name) =>
|
|
152
174
|
name !== "default" && name !== "__esModule" && isValidIdentifier(name);
|
|
153
175
|
|
|
154
|
-
const wrapCodeToRunInVm = (code) => {
|
|
155
|
-
return `const exports = {};
|
|
156
|
-
const module = { exports };
|
|
157
|
-
${code};;
|
|
158
|
-
module.exports;`;
|
|
159
|
-
};
|
|
160
|
-
|
|
161
176
|
const generateCodeForExports = ({
|
|
162
177
|
uniqueNamedExports,
|
|
163
178
|
scanResult,
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { parentPort } from "node:worker_threads";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import vm from "node:vm";
|
|
4
|
+
|
|
5
|
+
parentPort.once("message", ({ filePath }) => {
|
|
6
|
+
const fileContents = readFileSync(filePath, "utf8");
|
|
7
|
+
const codeToRun = wrapCodeToRunInVm(fileContents);
|
|
8
|
+
const script = new vm.Script(codeToRun);
|
|
9
|
+
try {
|
|
10
|
+
const returnValue = script.runInNewContext(
|
|
11
|
+
{},
|
|
12
|
+
{
|
|
13
|
+
contextCodeGeneration: {
|
|
14
|
+
wasm: false,
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
);
|
|
18
|
+
const exportNames = Object.keys(returnValue);
|
|
19
|
+
parentPort.postMessage({
|
|
20
|
+
exportNames,
|
|
21
|
+
});
|
|
22
|
+
} catch (e) {
|
|
23
|
+
parentPort.postMessage({
|
|
24
|
+
errorMessage: e.message,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const wrapCodeToRunInVm = (code) => {
|
|
30
|
+
return `const exports = {};
|
|
31
|
+
const module = { exports };
|
|
32
|
+
${code};;
|
|
33
|
+
module.exports;`;
|
|
34
|
+
};
|