@ms-cloudpack/esm-stub-utilities 0.7.22 → 0.8.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/lib/generateESMStubFromCJS.d.ts +9 -0
- package/lib/generateESMStubFromCJS.d.ts.map +1 -0
- package/lib/{createESMStub.js → generateESMStubFromCJS.js} +16 -22
- package/lib/generateESMStubFromCJS.js.map +1 -0
- package/lib/{createJSONStub.d.ts → generateESMStubFromJSON.d.ts} +4 -2
- package/lib/generateESMStubFromJSON.d.ts.map +1 -0
- package/lib/{createJSONStub.js → generateESMStubFromJSON.js} +5 -12
- package/lib/generateESMStubFromJSON.js.map +1 -0
- package/lib/getExportInfo.d.ts +6 -0
- package/lib/getExportInfo.d.ts.map +1 -0
- package/lib/getExportInfo.js +16 -0
- package/lib/getExportInfo.js.map +1 -0
- package/lib/getStubPath.d.ts +10 -0
- package/lib/getStubPath.d.ts.map +1 -0
- package/lib/getStubPath.js +24 -0
- package/lib/getStubPath.js.map +1 -0
- package/lib/index.d.ts +4 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/{runInSandbox.d.ts → processStubsInWorker.d.ts} +6 -9
- package/lib/processStubsInWorker.d.ts.map +1 -0
- package/lib/processStubsInWorker.js +93 -0
- package/lib/processStubsInWorker.js.map +1 -0
- package/lib/tsdoc-metadata.json +1 -1
- package/lib/types/ESMStub.d.ts +7 -0
- package/lib/types/ESMStub.d.ts.map +1 -0
- package/lib/types/ESMStub.js +2 -0
- package/lib/types/ESMStub.js.map +1 -0
- package/lib/types/ProcessStubsFunction.d.ts +4 -0
- package/lib/types/ProcessStubsFunction.d.ts.map +1 -0
- package/lib/types/ProcessStubsFunction.js +2 -0
- package/lib/types/ProcessStubsFunction.js.map +1 -0
- package/lib/types/StubError.d.ts +4 -0
- package/lib/types/StubError.d.ts.map +1 -1
- package/lib/types/StubError.js.map +1 -1
- package/lib/types/WriteESMStubsInput.d.ts +7 -0
- package/lib/types/WriteESMStubsInput.d.ts.map +1 -0
- package/lib/types/WriteESMStubsInput.js +2 -0
- package/lib/types/WriteESMStubsInput.js.map +1 -0
- package/lib/types/WriteESMStubsOutput.d.ts +6 -0
- package/lib/types/WriteESMStubsOutput.d.ts.map +1 -0
- package/lib/types/WriteESMStubsOutput.js +2 -0
- package/lib/types/WriteESMStubsOutput.js.map +1 -0
- package/lib/worker/workerEntry.d.ts +2 -0
- package/lib/worker/workerEntry.d.ts.map +1 -0
- package/lib/worker/workerEntry.js +46 -0
- package/lib/worker/workerEntry.js.map +1 -0
- package/lib/writeESMStubs.d.ts +10 -0
- package/lib/writeESMStubs.d.ts.map +1 -0
- package/lib/writeESMStubs.js +9 -0
- package/lib/writeESMStubs.js.map +1 -0
- package/lib/writeESMStubsInternal.d.ts +8 -0
- package/lib/writeESMStubsInternal.d.ts.map +1 -0
- package/lib/writeESMStubsInternal.js +50 -0
- package/lib/writeESMStubsInternal.js.map +1 -0
- package/package.json +3 -2
- package/lib/createESMStub.d.ts +0 -14
- package/lib/createESMStub.d.ts.map +0 -1
- package/lib/createESMStub.js.map +0 -1
- package/lib/createJSONStub.d.ts.map +0 -1
- package/lib/createJSONStub.js.map +0 -1
- package/lib/runInSandbox.d.ts.map +0 -1
- package/lib/runInSandbox.js +0 -168
- package/lib/runInSandbox.js.map +0 -1
- package/lib/worker/worker.d.ts +0 -2
- package/lib/worker/worker.d.ts.map +0 -1
- package/lib/worker/worker.js +0 -85
- package/lib/worker/worker.js.map +0 -1
- package/lib/writeESMStub.d.ts +0 -9
- package/lib/writeESMStub.d.ts.map +0 -1
- package/lib/writeESMStub.js +0 -34
- package/lib/writeESMStub.js.map +0 -1
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Given entry/stub paths and cjs export info, generates the esm stub content.
|
|
3
|
+
* The stubPath is required to generate the proper import statement.
|
|
4
|
+
*/
|
|
5
|
+
export declare function generateESMStubFromCJS(options: {
|
|
6
|
+
filePath: string;
|
|
7
|
+
stubPath: string;
|
|
8
|
+
}): string;
|
|
9
|
+
//# sourceMappingURL=generateESMStubFromCJS.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generateESMStubFromCJS.d.ts","sourceRoot":"","sources":["../src/generateESMStubFromCJS.ts"],"names":[],"mappings":"AASA;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAqD9F"}
|
|
@@ -1,34 +1,28 @@
|
|
|
1
|
-
import os from 'os';
|
|
2
1
|
import path from 'path';
|
|
2
|
+
import os from 'os';
|
|
3
3
|
import { slash } from '@ms-cloudpack/path-string-parsing';
|
|
4
|
-
import { runInSandbox } from './runInSandbox.js';
|
|
5
|
-
import { createJSONStub } from './createJSONStub.js';
|
|
6
4
|
import { isValidIdentifierName } from './isValidIdentifierName.js';
|
|
5
|
+
import { createRequire } from 'module';
|
|
6
|
+
import { getExportInfo } from './getExportInfo.js';
|
|
7
|
+
const require = createRequire(import.meta.url);
|
|
7
8
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* Should only throw an error on bad input or other cases that likely indicate either a bug
|
|
11
|
-
* or bad configuration (as opposed to a problem with the file being stubbed).
|
|
9
|
+
* Given entry/stub paths and cjs export info, generates the esm stub content.
|
|
10
|
+
* The stubPath is required to generate the proper import statement.
|
|
12
11
|
*/
|
|
13
|
-
export
|
|
14
|
-
const {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
// Run the entry point file in a sandbox to determine the exports
|
|
19
|
-
const exportInfo = await runInSandbox(entryPath);
|
|
20
|
-
if ('error' in exportInfo) {
|
|
21
|
-
return exportInfo.error;
|
|
22
|
-
}
|
|
12
|
+
export function generateESMStubFromCJS(options) {
|
|
13
|
+
const { filePath, stubPath } = options;
|
|
14
|
+
// Assume CJS.
|
|
15
|
+
const exportInfo = getExportInfo(require(filePath));
|
|
16
|
+
const { type: exportType } = exportInfo;
|
|
23
17
|
let relativePath;
|
|
24
|
-
|
|
18
|
+
// We need to compute a relative path from the stub to the entry to construct the proper import in the stub.
|
|
19
|
+
if (os.platform() === 'win32' && path.parse(filePath).root !== path.parse(stubPath).root) {
|
|
25
20
|
// Different drive letters. These can't be relative to each other.
|
|
26
|
-
relativePath =
|
|
21
|
+
relativePath = filePath;
|
|
27
22
|
}
|
|
28
23
|
else {
|
|
29
|
-
relativePath = './' + slash(path.relative(path.dirname(stubPath),
|
|
24
|
+
relativePath = './' + slash(path.relative(path.dirname(stubPath), filePath));
|
|
30
25
|
}
|
|
31
|
-
const exportType = exportInfo.type;
|
|
32
26
|
if (exportType === 'none') {
|
|
33
27
|
// No exports. Just import the module.
|
|
34
28
|
return `import "${relativePath}";`;
|
|
@@ -58,4 +52,4 @@ export async function createESMStub(params) {
|
|
|
58
52
|
}
|
|
59
53
|
return stub.join('\n');
|
|
60
54
|
}
|
|
61
|
-
//# sourceMappingURL=
|
|
55
|
+
//# sourceMappingURL=generateESMStubFromCJS.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generateESMStubFromCJS.js","sourceRoot":"","sources":["../src/generateESMStubFromCJS.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,KAAK,EAAE,MAAM,mCAAmC,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAE/C;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,OAA+C;IACpF,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAEvC,cAAc;IACd,MAAM,UAAU,GAAG,aAAa,CAAC,OAAO,CAAC,QAAQ,CAAY,CAAC,CAAC;IAE/D,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,UAAU,CAAC;IACxC,IAAI,YAAoB,CAAC;IAEzB,4GAA4G;IAC5G,IAAI,EAAE,CAAC,QAAQ,EAAE,KAAK,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;QACzF,kEAAkE;QAClE,YAAY,GAAG,QAAQ,CAAC;IAC1B,CAAC;SAAM,CAAC;QACN,YAAY,GAAG,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC/E,CAAC;IAED,IAAI,UAAU,KAAK,MAAM,EAAE,CAAC;QAC1B,sCAAsC;QACtC,OAAO,WAAW,YAAY,IAAI,CAAC;IACrC,CAAC;IAED,IAAI,UAAU,KAAK,OAAO,EAAE,CAAC;QAC3B,wDAAwD;QACxD,sFAAsF;QACtF,6FAA6F;QAC7F,iDAAiD;QACjD,OAAO,6BAA6B,YAAY,kCAAkC,CAAC;IACrF,CAAC;IAED,mGAAmG;IACnG,MAAM,YAAY,GAAG,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAC;IACnF,MAAM,gBAAgB,GAAG,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAC7D,MAAM,IAAI,GAAG,CAAC,6BAA6B,YAAY,IAAI,CAAC,CAAC;IAE7D,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;QACxB,IAAI,CAAC,IAAI,CAAC,WAAW,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IACpE,CAAC;IAED,IAAI,gBAAgB,EAAE,CAAC;QACrB,IAAI,CAAC,IAAI,CACP,kFAAkF,EAClF,+BAA+B,CAChC,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,IAAI,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IAC5C,CAAC;IAED,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;QACxB,IAAI,CAAC,IAAI,CAAC,YAAY,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrD,CAAC;IAED,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACzB,CAAC","sourcesContent":["import path from 'path';\nimport os from 'os';\nimport { slash } from '@ms-cloudpack/path-string-parsing';\nimport { isValidIdentifierName } from './isValidIdentifierName.js';\nimport { createRequire } from 'module';\nimport { getExportInfo } from './getExportInfo.js';\n\nconst require = createRequire(import.meta.url);\n\n/**\n * Given entry/stub paths and cjs export info, generates the esm stub content.\n * The stubPath is required to generate the proper import statement.\n */\nexport function generateESMStubFromCJS(options: { filePath: string; stubPath: string }): string {\n const { filePath, stubPath } = options;\n\n // Assume CJS.\n const exportInfo = getExportInfo(require(filePath) as unknown);\n\n const { type: exportType } = exportInfo;\n let relativePath: string;\n\n // We need to compute a relative path from the stub to the entry to construct the proper import in the stub.\n if (os.platform() === 'win32' && path.parse(filePath).root !== path.parse(stubPath).root) {\n // Different drive letters. These can't be relative to each other.\n relativePath = filePath;\n } else {\n relativePath = './' + slash(path.relative(path.dirname(stubPath), filePath));\n }\n\n if (exportType === 'none') {\n // No exports. Just import the module.\n return `import \"${relativePath}\";`;\n }\n\n if (exportType === 'other') {\n // Some kind of value. Import then re-export as default.\n // (Note that even for values such as numbers which we could in theory rewrite inline,\n // we don't know how the value is calculated at runtime or what other side effects the module\n // might have, so we should preserve the import.)\n return `import moduleExport from \"${relativePath}\";\\nexport default moduleExport;`;\n }\n\n // Object or function. Export both named properties (if any, and filtering keywords) and a default.\n const namedExports = exportInfo.keys.filter((name) => isValidIdentifierName(name));\n const hasDefaultExport = exportInfo.keys.includes('default');\n const stub = [`import moduleExport from \"${relativePath}\";`];\n\n if (namedExports.length) {\n stub.push(`const { ${namedExports.join(', ')} } = moduleExport;`);\n }\n\n if (hasDefaultExport) {\n stub.push(\n `const defaultExport = (moduleExport?.default?.default) ?? moduleExport?.default;`,\n `export default defaultExport;`,\n );\n } else {\n stub.push(`export default moduleExport;`);\n }\n\n if (namedExports.length) {\n stub.push(`export { ${namedExports.join(', ')} }`);\n }\n\n return stub.join('\\n');\n}\n"]}
|
|
@@ -3,5 +3,7 @@
|
|
|
3
3
|
* it in the sandbox.
|
|
4
4
|
* @param entryPath - The full path to the JSON entry file.
|
|
5
5
|
*/
|
|
6
|
-
export declare function
|
|
7
|
-
|
|
6
|
+
export declare function generateESMStubFromJSON(options: {
|
|
7
|
+
filePath: string;
|
|
8
|
+
}): Promise<string>;
|
|
9
|
+
//# sourceMappingURL=generateESMStubFromJSON.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generateESMStubFromJSON.d.ts","sourceRoot":"","sources":["../src/generateESMStubFromJSON.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,wBAAsB,uBAAuB,CAAC,OAAO,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAoB5F"}
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import path from 'path';
|
|
3
1
|
import { readJson } from '@ms-cloudpack/json-utilities';
|
|
4
2
|
import { isValidIdentifierName } from './isValidIdentifierName.js';
|
|
5
3
|
/**
|
|
@@ -7,16 +5,11 @@ import { isValidIdentifierName } from './isValidIdentifierName.js';
|
|
|
7
5
|
* it in the sandbox.
|
|
8
6
|
* @param entryPath - The full path to the JSON entry file.
|
|
9
7
|
*/
|
|
10
|
-
export async function
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
if (!fs.existsSync(entryPath)) {
|
|
15
|
-
throw new Error('File does not exist: ' + entryPath);
|
|
16
|
-
}
|
|
17
|
-
const jsonData = await readJson(entryPath);
|
|
8
|
+
export async function generateESMStubFromJSON(options) {
|
|
9
|
+
const { filePath } = options;
|
|
10
|
+
const jsonData = await readJson(filePath);
|
|
18
11
|
if (!jsonData) {
|
|
19
|
-
throw new Error('File is not valid JSON: ' +
|
|
12
|
+
throw new Error('File is not valid JSON: ' + filePath);
|
|
20
13
|
}
|
|
21
14
|
const result = [`const data = ${JSON.stringify(jsonData, null, 2)};`, 'export default data;'];
|
|
22
15
|
if (jsonData && typeof jsonData === 'object' && !Array.isArray(jsonData)) {
|
|
@@ -27,4 +20,4 @@ export async function createJSONStub(entryPath) {
|
|
|
27
20
|
}
|
|
28
21
|
return result.join('\n');
|
|
29
22
|
}
|
|
30
|
-
//# sourceMappingURL=
|
|
23
|
+
//# sourceMappingURL=generateESMStubFromJSON.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generateESMStubFromJSON.js","sourceRoot":"","sources":["../src/generateESMStubFromJSON.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAEnE;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,OAA6B;IACzE,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAC7B,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAE1C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,0BAA0B,GAAG,QAAQ,CAAC,CAAC;IACzD,CAAC;IAED,MAAM,MAAM,GAAG,CAAC,gBAAgB,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,EAAE,sBAAsB,CAAC,CAAC;IAE9F,IAAI,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzE,iEAAiE;QACjE,MAAM,CAAC,IAAI,CACT,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;aACrB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC;aAC7C,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,gBAAgB,IAAI,WAAW,IAAI,GAAG,CAAC,CACzD,CAAC;IACJ,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC3B,CAAC","sourcesContent":["import { readJson } from '@ms-cloudpack/json-utilities';\nimport { isValidIdentifierName } from './isValidIdentifierName.js';\n\n/**\n * Generates an ESM stub of a JSON file. This just inlines the file contents rather than running\n * it in the sandbox.\n * @param entryPath - The full path to the JSON entry file.\n */\nexport async function generateESMStubFromJSON(options: { filePath: string }): Promise<string> {\n const { filePath } = options;\n const jsonData = await readJson(filePath);\n\n if (!jsonData) {\n throw new Error('File is not valid JSON: ' + filePath);\n }\n\n const result = [`const data = ${JSON.stringify(jsonData, null, 2)};`, 'export default data;'];\n\n if (jsonData && typeof jsonData === 'object' && !Array.isArray(jsonData)) {\n // Export individual properties if they're valid identifier names\n result.push(\n ...Object.keys(jsonData)\n .filter((name) => isValidIdentifierName(name))\n .map((prop) => `export const ${prop} = data.${prop};`),\n );\n }\n\n return result.join('\\n');\n}\n"]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { StubExportInfo } from './types/StubExportInfo.js';
|
|
2
|
+
/**
|
|
3
|
+
* Get information about a CJS module's exports, for purposes of creating a stub.
|
|
4
|
+
*/
|
|
5
|
+
export declare function getExportInfo(moduleExport: unknown): StubExportInfo;
|
|
6
|
+
//# sourceMappingURL=getExportInfo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getExportInfo.d.ts","sourceRoot":"","sources":["../src/getExportInfo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAEhE;;GAEG;AACH,wBAAgB,aAAa,CAAC,YAAY,EAAE,OAAO,GAAG,cAAc,CAcnE"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get information about a CJS module's exports, for purposes of creating a stub.
|
|
3
|
+
*/
|
|
4
|
+
export function getExportInfo(moduleExport) {
|
|
5
|
+
if (moduleExport === undefined) {
|
|
6
|
+
return { type: 'none' };
|
|
7
|
+
}
|
|
8
|
+
if (typeof moduleExport === 'function') {
|
|
9
|
+
return { type: 'function', keys: Object.keys(moduleExport) };
|
|
10
|
+
}
|
|
11
|
+
if (moduleExport && typeof moduleExport === 'object' && !Array.isArray(moduleExport)) {
|
|
12
|
+
return { type: 'object', keys: Object.keys(moduleExport) };
|
|
13
|
+
}
|
|
14
|
+
return { type: 'other' };
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=getExportInfo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getExportInfo.js","sourceRoot":"","sources":["../src/getExportInfo.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,YAAqB;IACjD,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC1B,CAAC;IAED,IAAI,OAAO,YAAY,KAAK,UAAU,EAAE,CAAC;QACvC,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;IAC/D,CAAC;IAED,IAAI,YAAY,IAAI,OAAO,YAAY,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;QACrF,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;IAC7D,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAC3B,CAAC","sourcesContent":["import type { StubExportInfo } from './types/StubExportInfo.js';\n\n/**\n * Get information about a CJS module's exports, for purposes of creating a stub.\n */\nexport function getExportInfo(moduleExport: unknown): StubExportInfo {\n if (moduleExport === undefined) {\n return { type: 'none' };\n }\n\n if (typeof moduleExport === 'function') {\n return { type: 'function', keys: Object.keys(moduleExport) };\n }\n\n if (moduleExport && typeof moduleExport === 'object' && !Array.isArray(moduleExport)) {\n return { type: 'object', keys: Object.keys(moduleExport) };\n }\n\n return { type: 'other' };\n}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const supportedCJSExtensions: string[];
|
|
2
|
+
/**
|
|
3
|
+
* Given an (absolute) inputPath and (relative) entryPath, returns an absolute stub path
|
|
4
|
+
* if a stub should indeed be generated for the entry. Otherwise returns undefined.
|
|
5
|
+
*/
|
|
6
|
+
export declare function getStubPath(options: {
|
|
7
|
+
inputPath: string;
|
|
8
|
+
entryPath: string;
|
|
9
|
+
}): Promise<string | undefined>;
|
|
10
|
+
//# sourceMappingURL=getStubPath.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getStubPath.d.ts","sourceRoot":"","sources":["../src/getStubPath.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,sBAAsB,UAAkB,CAAC;AAEtD;;;GAGG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAkBhH"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { mkdir } from 'fs/promises';
|
|
3
|
+
import { detectModuleType } from '@ms-cloudpack/package-utilities';
|
|
4
|
+
import { slash } from '@ms-cloudpack/path-string-parsing';
|
|
5
|
+
export const supportedCJSExtensions = ['.js', '.cjs'];
|
|
6
|
+
/**
|
|
7
|
+
* Given an (absolute) inputPath and (relative) entryPath, returns an absolute stub path
|
|
8
|
+
* if a stub should indeed be generated for the entry. Otherwise returns undefined.
|
|
9
|
+
*/
|
|
10
|
+
export async function getStubPath(options) {
|
|
11
|
+
const { inputPath, entryPath } = options;
|
|
12
|
+
const ext = path.extname(entryPath).toLowerCase();
|
|
13
|
+
const isCJSEntry = supportedCJSExtensions.includes(ext) && (await detectModuleType(path.resolve(inputPath, entryPath))) === 'cjs';
|
|
14
|
+
const isJSONEntry = ext === '.json';
|
|
15
|
+
if (isCJSEntry || isJSONEntry) {
|
|
16
|
+
const stubFilename = path.basename(entryPath, supportedCJSExtensions.includes(ext) ? ext : undefined) + '-stub.mjs';
|
|
17
|
+
const stubRelativePath = path.dirname(entryPath);
|
|
18
|
+
const stubFolderPath = path.resolve(inputPath, './node_modules/.cache/cloudpack-stubs/', stubRelativePath);
|
|
19
|
+
await mkdir(stubFolderPath, { recursive: true });
|
|
20
|
+
return slash(path.join(stubFolderPath, stubFilename));
|
|
21
|
+
}
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=getStubPath.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getStubPath.js","sourceRoot":"","sources":["../src/getStubPath.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,KAAK,EAAE,MAAM,mCAAmC,CAAC;AAE1D,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;AAEtD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAiD;IACjF,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IACzC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC;IAClD,MAAM,UAAU,GACd,sBAAsB,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC;IACjH,MAAM,WAAW,GAAG,GAAG,KAAK,OAAO,CAAC;IAEpC,IAAI,UAAU,IAAI,WAAW,EAAE,CAAC;QAC9B,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,sBAAsB,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,WAAW,CAAC;QACpH,MAAM,gBAAgB,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACjD,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,wCAAwC,EAAE,gBAAgB,CAAC,CAAC;QAE3G,MAAM,KAAK,CAAC,cAAc,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAEjD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC,CAAC;IACxD,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC","sourcesContent":["import path from 'path';\nimport { mkdir } from 'fs/promises';\nimport { detectModuleType } from '@ms-cloudpack/package-utilities';\nimport { slash } from '@ms-cloudpack/path-string-parsing';\n\nexport const supportedCJSExtensions = ['.js', '.cjs'];\n\n/**\n * Given an (absolute) inputPath and (relative) entryPath, returns an absolute stub path\n * if a stub should indeed be generated for the entry. Otherwise returns undefined.\n */\nexport async function getStubPath(options: { inputPath: string; entryPath: string }): Promise<string | undefined> {\n const { inputPath, entryPath } = options;\n const ext = path.extname(entryPath).toLowerCase();\n const isCJSEntry =\n supportedCJSExtensions.includes(ext) && (await detectModuleType(path.resolve(inputPath, entryPath))) === 'cjs';\n const isJSONEntry = ext === '.json';\n\n if (isCJSEntry || isJSONEntry) {\n const stubFilename = path.basename(entryPath, supportedCJSExtensions.includes(ext) ? ext : undefined) + '-stub.mjs';\n const stubRelativePath = path.dirname(entryPath);\n const stubFolderPath = path.resolve(inputPath, './node_modules/.cache/cloudpack-stubs/', stubRelativePath);\n\n await mkdir(stubFolderPath, { recursive: true });\n\n return slash(path.join(stubFolderPath, stubFilename));\n }\n\n return undefined;\n}\n"]}
|
package/lib/index.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { writeESMStubs } from './writeESMStubs.js';
|
|
2
|
+
export type { ESMStub } from './types/ESMStub.js';
|
|
2
3
|
export type { StubError } from './types/StubError.js';
|
|
4
|
+
export type { WriteESMStubsInput } from './types/WriteESMStubsInput.js';
|
|
5
|
+
export type { WriteESMStubsOutput } from './types/WriteESMStubsOutput.js';
|
|
3
6
|
//# sourceMappingURL=index.d.ts.map
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,YAAY,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACxE,YAAY,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC"}
|
package/lib/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { writeESMStubs } from './writeESMStubs.js';
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC","sourcesContent":["export { writeESMStubs } from './writeESMStubs.js';\nexport type { ESMStub } from './types/ESMStub.js';\nexport type { StubError } from './types/StubError.js';\nexport type { WriteESMStubsInput } from './types/WriteESMStubsInput.js';\nexport type { WriteESMStubsOutput } from './types/WriteESMStubsOutput.js';\n"]}
|
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { StubError } from './types/StubError.js';
|
|
3
|
-
/** Stop the worker for testing */
|
|
4
|
-
export declare function _stopWorker(): Promise<void>;
|
|
1
|
+
import type { ProcessStubsFunction } from './types/ProcessStubsFunction.js';
|
|
5
2
|
/**
|
|
6
|
-
* Run a CommonJS file within a sandboxed environment.
|
|
3
|
+
* Initializes a worker, where Run a CommonJS file within a sandboxed environment.
|
|
7
4
|
* @param entryPath - Path to a CommonJS file to run in a sandbox (does not work with ESM files)
|
|
8
5
|
* @returns Info about the file's exports, or error info if there was an issue.
|
|
9
6
|
* Should only throw an error on bad input or other cases that likely indicate either a bug
|
|
10
7
|
* or bad configuration (as opposed to a problem with the file being stubbed).
|
|
11
8
|
*/
|
|
12
|
-
export declare
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
//# sourceMappingURL=
|
|
9
|
+
export declare const processStubsInWorker: ProcessStubsFunction;
|
|
10
|
+
/** Stop the worker for testing */
|
|
11
|
+
export declare function _stopWorker(): Promise<void>;
|
|
12
|
+
//# sourceMappingURL=processStubsInWorker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"processStubsInWorker.d.ts","sourceRoot":"","sources":["../src/processStubsInWorker.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAU5E;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,EAAE,oBAyFlC,CAAC;AAEF,kCAAkC;AAClC,wBAAsB,WAAW,kBAGhC"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { fileURLToPath } from 'url';
|
|
3
|
+
import { Worker } from 'worker_threads';
|
|
4
|
+
const currentPath = path.dirname(fileURLToPath(import.meta.url));
|
|
5
|
+
const workerPath = path.join(currentPath, './worker/workerEntry.js');
|
|
6
|
+
let _counter = 0;
|
|
7
|
+
// TODO do we need a pool?
|
|
8
|
+
let worker;
|
|
9
|
+
/**
|
|
10
|
+
* Initializes a worker, where Run a CommonJS file within a sandboxed environment.
|
|
11
|
+
* @param entryPath - Path to a CommonJS file to run in a sandbox (does not work with ESM files)
|
|
12
|
+
* @returns Info about the file's exports, or error info if there was an issue.
|
|
13
|
+
* Should only throw an error on bad input or other cases that likely indicate either a bug
|
|
14
|
+
* or bad configuration (as opposed to a problem with the file being stubbed).
|
|
15
|
+
*/
|
|
16
|
+
export const processStubsInWorker = async (options) => {
|
|
17
|
+
const id = _counter++;
|
|
18
|
+
// Initialize worker.
|
|
19
|
+
if (!worker) {
|
|
20
|
+
try {
|
|
21
|
+
worker = new Worker(workerPath, { stdout: true, stderr: true, execArgv: [] });
|
|
22
|
+
worker.stdout?.on('data', (data) => {
|
|
23
|
+
console.debug(`[sandbox stdout] ${data}`);
|
|
24
|
+
});
|
|
25
|
+
worker.stderr?.on('data', (data) => {
|
|
26
|
+
console.debug(`[sandbox stderr] ${data}`);
|
|
27
|
+
});
|
|
28
|
+
worker.on('exit', () => {
|
|
29
|
+
worker = undefined;
|
|
30
|
+
});
|
|
31
|
+
// don't hold the process open if only the worker is left
|
|
32
|
+
worker.unref();
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
throw new Error(`Error initializing worker: ${err?.stack || err}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return new Promise((resolve, reject) => {
|
|
39
|
+
// just for type checking
|
|
40
|
+
if (!worker)
|
|
41
|
+
return;
|
|
42
|
+
worker.on('message', onMessage);
|
|
43
|
+
worker.on('messageerror', onMessageError);
|
|
44
|
+
worker.on('error', onError);
|
|
45
|
+
worker.on('exit', onExit);
|
|
46
|
+
// Send a message requesting the file to be run.
|
|
47
|
+
worker.postMessage({ id, ...options });
|
|
48
|
+
/** Normally, both success and error results should be sent back as messages. */
|
|
49
|
+
function onMessage(message) {
|
|
50
|
+
if (message.id !== id) {
|
|
51
|
+
return; // result about a different file
|
|
52
|
+
}
|
|
53
|
+
handlersOff();
|
|
54
|
+
if (message) {
|
|
55
|
+
resolve(message);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
reject(new Error(`Unexpected sandbox worker message while running ${JSON.stringify(options, null, 2)}`));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/** 'messageerror' event: deserializing a message failed. */
|
|
62
|
+
function onMessageError(err) {
|
|
63
|
+
handlersOff();
|
|
64
|
+
reject(new Error(`Error with sandbox worker message serialization while running ${JSON.stringify(options, null, 2)}: ${err.stack || err}\n`));
|
|
65
|
+
}
|
|
66
|
+
/** 'error' event: unhandled exception in the worker, which shouldn't happen. */
|
|
67
|
+
function onError(err) {
|
|
68
|
+
handlersOff();
|
|
69
|
+
reject(new Error(`Uncaught error in sandbox worker while running ${JSON.stringify(options, null, 2)}: ${err.stack || err}\n`));
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Make sure the promise rejects if the worker exits unexpectedly. (This handler is unlikely
|
|
73
|
+
* to be used because the worker should throw an error if a file calls process.exit().)
|
|
74
|
+
*/
|
|
75
|
+
function onExit() {
|
|
76
|
+
worker = undefined;
|
|
77
|
+
reject(new Error(`Sandbox worker exited unexpectedly while running ${JSON.stringify(options, null, 2)}`));
|
|
78
|
+
}
|
|
79
|
+
/** Remove all event handlers to avoid interference with future sandbox runs. */
|
|
80
|
+
function handlersOff() {
|
|
81
|
+
worker?.off('message', onMessage);
|
|
82
|
+
worker?.off('messageerror', onMessageError);
|
|
83
|
+
worker?.off('error', onError);
|
|
84
|
+
worker?.off('exit', onExit);
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
};
|
|
88
|
+
/** Stop the worker for testing */
|
|
89
|
+
export async function _stopWorker() {
|
|
90
|
+
await worker?.terminate();
|
|
91
|
+
worker = undefined;
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=processStubsInWorker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"processStubsInWorker.js","sourceRoot":"","sources":["../src/processStubsInWorker.ts"],"names":[],"mappings":"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","sourcesContent":["import path from 'path';\nimport { fileURLToPath } from 'url';\nimport { Worker } from 'worker_threads';\nimport type { ProcessStubsFunction } from './types/ProcessStubsFunction.js';\nimport type { WriteESMStubsOutput } from './types/WriteESMStubsOutput.js';\n\nconst currentPath = path.dirname(fileURLToPath(import.meta.url));\nconst workerPath = path.join(currentPath, './worker/workerEntry.js');\nlet _counter = 0;\n\n// TODO do we need a pool?\nlet worker: Worker | undefined;\n\n/**\n * Initializes a worker, where Run a CommonJS file within a sandboxed environment.\n * @param entryPath - Path to a CommonJS file to run in a sandbox (does not work with ESM files)\n * @returns Info about the file's exports, or error info if there was an issue.\n * Should only throw an error on bad input or other cases that likely indicate either a bug\n * or bad configuration (as opposed to a problem with the file being stubbed).\n */\nexport const processStubsInWorker: ProcessStubsFunction = async (options) => {\n const id = _counter++;\n\n // Initialize worker.\n if (!worker) {\n try {\n worker = new Worker(workerPath, { stdout: true, stderr: true, execArgv: [] });\n worker.stdout?.on('data', (data) => {\n console.debug(`[sandbox stdout] ${data}`);\n });\n worker.stderr?.on('data', (data) => {\n console.debug(`[sandbox stderr] ${data}`);\n });\n worker.on('exit', () => {\n worker = undefined;\n });\n // don't hold the process open if only the worker is left\n worker.unref();\n } catch (err) {\n throw new Error(`Error initializing worker: ${(err as Error)?.stack || err}`);\n }\n }\n\n return new Promise((resolve, reject) => {\n // just for type checking\n if (!worker) return;\n\n worker.on('message', onMessage);\n worker.on('messageerror', onMessageError);\n worker.on('error', onError);\n worker.on('exit', onExit);\n\n // Send a message requesting the file to be run.\n worker.postMessage({ id, ...options });\n\n /** Normally, both success and error results should be sent back as messages. */\n function onMessage(message: WriteESMStubsOutput & { id: number }) {\n if (message.id !== id) {\n return; // result about a different file\n }\n\n handlersOff();\n\n if (message) {\n resolve(message);\n } else {\n reject(new Error(`Unexpected sandbox worker message while running ${JSON.stringify(options, null, 2)}`));\n }\n }\n\n /** 'messageerror' event: deserializing a message failed. */\n function onMessageError(err: Error) {\n handlersOff();\n reject(\n new Error(\n `Error with sandbox worker message serialization while running ${JSON.stringify(options, null, 2)}: ${\n err.stack || err\n }\\n`,\n ),\n );\n }\n\n /** 'error' event: unhandled exception in the worker, which shouldn't happen. */\n function onError(err: Error) {\n handlersOff();\n reject(\n new Error(\n `Uncaught error in sandbox worker while running ${JSON.stringify(options, null, 2)}: ${err.stack || err}\\n`,\n ),\n );\n }\n\n /**\n * Make sure the promise rejects if the worker exits unexpectedly. (This handler is unlikely\n * to be used because the worker should throw an error if a file calls process.exit().)\n */\n function onExit() {\n worker = undefined;\n reject(new Error(`Sandbox worker exited unexpectedly while running ${JSON.stringify(options, null, 2)}`));\n }\n\n /** Remove all event handlers to avoid interference with future sandbox runs. */\n function handlersOff() {\n worker?.off('message', onMessage);\n worker?.off('messageerror', onMessageError);\n worker?.off('error', onError);\n worker?.off('exit', onExit);\n }\n });\n};\n\n/** Stop the worker for testing */\nexport async function _stopWorker() {\n await worker?.terminate();\n worker = undefined;\n}\n"]}
|
package/lib/tsdoc-metadata.json
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ESMStub.d.ts","sourceRoot":"","sources":["../../src/types/ESMStub.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,MAAM,MAAM,OAAO,GAAG;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ESMStub.js","sourceRoot":"","sources":["../../src/types/ESMStub.ts"],"names":[],"mappings":"","sourcesContent":["import type { StubError } from './StubError.js';\n\nexport type ESMStub = {\n entryPath: string;\n stubPath?: string;\n error?: StubError;\n};\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { WriteESMStubsInput } from './WriteESMStubsInput.js';
|
|
2
|
+
import type { WriteESMStubsOutput } from './WriteESMStubsOutput.js';
|
|
3
|
+
export type ProcessStubsFunction = (options: WriteESMStubsInput) => Promise<WriteESMStubsOutput>;
|
|
4
|
+
//# sourceMappingURL=ProcessStubsFunction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProcessStubsFunction.d.ts","sourceRoot":"","sources":["../../src/types/ProcessStubsFunction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAEpE,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,EAAE,kBAAkB,KAAK,OAAO,CAAC,mBAAmB,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProcessStubsFunction.js","sourceRoot":"","sources":["../../src/types/ProcessStubsFunction.ts"],"names":[],"mappings":"","sourcesContent":["import type { WriteESMStubsInput } from './WriteESMStubsInput.js';\nimport type { WriteESMStubsOutput } from './WriteESMStubsOutput.js';\n\nexport type ProcessStubsFunction = (options: WriteESMStubsInput) => Promise<WriteESMStubsOutput>;\n"]}
|
package/lib/types/StubError.d.ts
CHANGED
|
@@ -17,6 +17,10 @@ export interface StubError {
|
|
|
17
17
|
* file location in the final BundleMessage error.
|
|
18
18
|
*/
|
|
19
19
|
message: string;
|
|
20
|
+
/**
|
|
21
|
+
* Original stack string.
|
|
22
|
+
*/
|
|
23
|
+
stack?: string;
|
|
20
24
|
/**
|
|
21
25
|
* Stack from the location of the error down to the file attempting to be stubbed,
|
|
22
26
|
* omitting frames from Node built-ins. Each line follows the standard stack trace format
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StubError.d.ts","sourceRoot":"","sources":["../../src/types/StubError.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB;;;;;;;OAOG;IACH,IAAI,EAAE,kBAAkB,GAAG,aAAa,GAAG,cAAc,GAAG,gBAAgB,GAAG,aAAa,CAAC;IAE7F;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB"}
|
|
1
|
+
{"version":3,"file":"StubError.d.ts","sourceRoot":"","sources":["../../src/types/StubError.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB;;;;;;;OAOG;IACH,IAAI,EAAE,kBAAkB,GAAG,aAAa,GAAG,cAAc,GAAG,gBAAgB,GAAG,aAAa,CAAC;IAE7F;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StubError.js","sourceRoot":"","sources":["../../src/types/StubError.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Error that occurred while attempting to create an ESM stub from a CJS or JSON file.\n */\nexport interface StubError {\n /**\n * Type of error:\n * - `module-not-found`: Some file attempted to load a module that wasn't found.\n * - `require-esm`: Some file attempted to load an ESM module using `require()`.\n * - `entry-is-esm`: The entry file being stubbed is already ESM.\n * - `invalid-syntax`: Some loaded file has invalid syntax.\n * - `other-error`: Anything else.\n */\n type: 'module-not-found' | 'require-esm' | 'entry-is-esm' | 'invalid-syntax' | 'other-error';\n\n /**\n * Error message. This will *not* include the path to the file that was being stubbed,\n * since it's assumed the caller already has this context, and it should be reported as the\n * file location in the final BundleMessage error.\n */\n message: string;\n\n /**\n * Stack from the location of the error down to the file attempting to be stubbed,\n * omitting frames from Node built-ins. Each line follows the standard stack trace format\n * `at <function> (<file>:<line>:<column>)` (but with whitespace trimmed).\n */\n partialStack?: string[];\n}\n"]}
|
|
1
|
+
{"version":3,"file":"StubError.js","sourceRoot":"","sources":["../../src/types/StubError.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Error that occurred while attempting to create an ESM stub from a CJS or JSON file.\n */\nexport interface StubError {\n /**\n * Type of error:\n * - `module-not-found`: Some file attempted to load a module that wasn't found.\n * - `require-esm`: Some file attempted to load an ESM module using `require()`.\n * - `entry-is-esm`: The entry file being stubbed is already ESM.\n * - `invalid-syntax`: Some loaded file has invalid syntax.\n * - `other-error`: Anything else.\n */\n type: 'module-not-found' | 'require-esm' | 'entry-is-esm' | 'invalid-syntax' | 'other-error';\n\n /**\n * Error message. This will *not* include the path to the file that was being stubbed,\n * since it's assumed the caller already has this context, and it should be reported as the\n * file location in the final BundleMessage error.\n */\n message: string;\n\n /**\n * Original stack string.\n */\n stack?: string;\n\n /**\n * Stack from the location of the error down to the file attempting to be stubbed,\n * omitting frames from Node built-ins. Each line follows the standard stack trace format\n * `at <function> (<file>:<line>:<column>)` (but with whitespace trimmed).\n */\n partialStack?: string[];\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WriteESMStubsInput.d.ts","sourceRoot":"","sources":["../../src/types/WriteESMStubsInput.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAAG;IAC/B,wCAAwC;IACxC,SAAS,EAAE,MAAM,CAAC;IAElB,sCAAsC;IACtC,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WriteESMStubsInput.js","sourceRoot":"","sources":["../../src/types/WriteESMStubsInput.ts"],"names":[],"mappings":"","sourcesContent":["export type WriteESMStubsInput = {\n /** The absolute path to the package. */\n inputPath: string;\n\n /** An array of entry source paths. */\n entryPaths: string[];\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WriteESMStubsOutput.d.ts","sourceRoot":"","sources":["../../src/types/WriteESMStubsOutput.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,KAAK,EAAE,OAAO,EAAE,CAAC;CAClB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WriteESMStubsOutput.js","sourceRoot":"","sources":["../../src/types/WriteESMStubsOutput.ts"],"names":[],"mappings":"","sourcesContent":["import type { ESMStub } from './ESMStub.js';\n\nexport type WriteESMStubsOutput = {\n error?: Error;\n stubs: ESMStub[];\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workerEntry.d.ts","sourceRoot":"","sources":["../../src/worker/workerEntry.js"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// These files use JS because they're loaded directly into a worker (see runInSandbox.ts),
|
|
2
|
+
// which must work both during tests (where the files are loaded from "src") and at runtime.
|
|
3
|
+
// They can still be type checked like TS, and the transpilation step doesn't do anything that
|
|
4
|
+
// should change the desired runtime behavior.
|
|
5
|
+
import { isMainThread, parentPort } from 'worker_threads';
|
|
6
|
+
import { initBrowserEnvironment } from './initBrowserEnvironment.js';
|
|
7
|
+
import { cleanUpGlobals, getGlobalProperties } from './globals.js';
|
|
8
|
+
import { writeESMStubsInternal } from '../writeESMStubsInternal.js';
|
|
9
|
+
if (isMainThread || !parentPort) {
|
|
10
|
+
throw new Error('This file should only be loaded in a worker thread');
|
|
11
|
+
}
|
|
12
|
+
await initBrowserEnvironment();
|
|
13
|
+
// TODO should the globals be marked as readonly if possible?
|
|
14
|
+
const initialGlobalProperties = getGlobalProperties();
|
|
15
|
+
/**
|
|
16
|
+
* @param {import('../types/WriteESMStubsOutput.js').WriteESMStubsOutput & { id: number }} message
|
|
17
|
+
*/
|
|
18
|
+
function emitMessage(message) {
|
|
19
|
+
parentPort?.postMessage(message);
|
|
20
|
+
}
|
|
21
|
+
parentPort.on('message', (/** @type {import('../types/WriteESMStubsInput.js').WriteESMStubsInput & { id: number }} */ options) => {
|
|
22
|
+
const { id } = options;
|
|
23
|
+
function onExit() {
|
|
24
|
+
// In this case, throw an error rather than sending a message to avoid handling it twice.
|
|
25
|
+
// Don't include the filename since that's potentially ambiguous (and redundant with info
|
|
26
|
+
// included by the runInSandbox error handler).
|
|
27
|
+
throw new Error('process.exit() was unexpectedly called');
|
|
28
|
+
}
|
|
29
|
+
process.on('exit', onExit);
|
|
30
|
+
writeESMStubsInternal(options)
|
|
31
|
+
.then((stubs) => {
|
|
32
|
+
emitMessage({ id, stubs });
|
|
33
|
+
})
|
|
34
|
+
.catch((/** @type {Error} */ error) => {
|
|
35
|
+
emitMessage({
|
|
36
|
+
id,
|
|
37
|
+
stubs: [],
|
|
38
|
+
error,
|
|
39
|
+
});
|
|
40
|
+
})
|
|
41
|
+
.finally(() => {
|
|
42
|
+
cleanUpGlobals(initialGlobalProperties);
|
|
43
|
+
process.off('exit', onExit);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
//# sourceMappingURL=workerEntry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workerEntry.js","sourceRoot":"","sources":["../../src/worker/workerEntry.js"],"names":[],"mappings":"AAAA,0FAA0F;AAC1F,4FAA4F;AAC5F,8FAA8F;AAC9F,8CAA8C;AAE9C,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnE,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAEpE,IAAI,YAAY,IAAI,CAAC,UAAU,EAAE,CAAC;IAChC,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;AACxE,CAAC;AAED,MAAM,sBAAsB,EAAE,CAAC;AAE/B,6DAA6D;AAC7D,MAAM,uBAAuB,GAAG,mBAAmB,EAAE,CAAC;AAEtD;;GAEG;AACH,SAAS,WAAW,CAAC,OAAO;IAC1B,UAAU,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;AACnC,CAAC;AAED,UAAU,CAAC,EAAE,CACX,SAAS,EACT,CAAC,2FAA2F,CAAC,OAAO,EAAE,EAAE;IACtG,MAAM,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC;IAEvB,SAAS,MAAM;QACb,yFAAyF;QACzF,yFAAyF;QACzF,+CAA+C;QAC/C,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;IAC5D,CAAC;IAED,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE3B,qBAAqB,CAAC,OAAO,CAAC;SAC3B,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;QACd,WAAW,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7B,CAAC,CAAC;SACD,KAAK,CAAC,CAAC,oBAAoB,CAAC,KAAK,EAAE,EAAE;QACpC,WAAW,CAAC;YACV,EAAE;YACF,KAAK,EAAE,EAAE;YACT,KAAK;SACN,CAAC,CAAC;IACL,CAAC,CAAC;SACD,OAAO,CAAC,GAAG,EAAE;QACZ,cAAc,CAAC,uBAAuB,CAAC,CAAC;QACxC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;AACP,CAAC,CACF,CAAC","sourcesContent":["// These files use JS because they're loaded directly into a worker (see runInSandbox.ts),\n// which must work both during tests (where the files are loaded from \"src\") and at runtime.\n// They can still be type checked like TS, and the transpilation step doesn't do anything that\n// should change the desired runtime behavior.\n\nimport { isMainThread, parentPort } from 'worker_threads';\nimport { initBrowserEnvironment } from './initBrowserEnvironment.js';\nimport { cleanUpGlobals, getGlobalProperties } from './globals.js';\nimport { writeESMStubsInternal } from '../writeESMStubsInternal.js';\n\nif (isMainThread || !parentPort) {\n throw new Error('This file should only be loaded in a worker thread');\n}\n\nawait initBrowserEnvironment();\n\n// TODO should the globals be marked as readonly if possible?\nconst initialGlobalProperties = getGlobalProperties();\n\n/**\n * @param {import('../types/WriteESMStubsOutput.js').WriteESMStubsOutput & { id: number }} message\n */\nfunction emitMessage(message) {\n parentPort?.postMessage(message);\n}\n\nparentPort.on(\n 'message',\n (/** @type {import('../types/WriteESMStubsInput.js').WriteESMStubsInput & { id: number }} */ options) => {\n const { id } = options;\n\n function onExit() {\n // In this case, throw an error rather than sending a message to avoid handling it twice.\n // Don't include the filename since that's potentially ambiguous (and redundant with info\n // included by the runInSandbox error handler).\n throw new Error('process.exit() was unexpectedly called');\n }\n\n process.on('exit', onExit);\n\n writeESMStubsInternal(options)\n .then((stubs) => {\n emitMessage({ id, stubs });\n })\n .catch((/** @type {Error} */ error) => {\n emitMessage({\n id,\n stubs: [],\n error,\n });\n })\n .finally(() => {\n cleanUpGlobals(initialGlobalProperties);\n process.off('exit', onExit);\n });\n },\n);\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { WriteESMStubsOutput } from './types/WriteESMStubsOutput.js';
|
|
2
|
+
/**
|
|
3
|
+
* Generates ESM stubs for CommonJS and JSON modules.
|
|
4
|
+
* @returns An object result containing the stubs or error that occured.
|
|
5
|
+
*/
|
|
6
|
+
export declare function writeESMStubs(options: {
|
|
7
|
+
inputPath: string;
|
|
8
|
+
entryPaths: string[];
|
|
9
|
+
}): Promise<WriteESMStubsOutput>;
|
|
10
|
+
//# sourceMappingURL=writeESMStubs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writeESMStubs.d.ts","sourceRoot":"","sources":["../src/writeESMStubs.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAE1E;;;GAGG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAE/B"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { processStubsInWorker } from './processStubsInWorker.js';
|
|
2
|
+
/**
|
|
3
|
+
* Generates ESM stubs for CommonJS and JSON modules.
|
|
4
|
+
* @returns An object result containing the stubs or error that occured.
|
|
5
|
+
*/
|
|
6
|
+
export async function writeESMStubs(options) {
|
|
7
|
+
return processStubsInWorker(options);
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=writeESMStubs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writeESMStubs.js","sourceRoot":"","sources":["../src/writeESMStubs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAGjE;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAGnC;IACC,OAAO,oBAAoB,CAAC,OAAO,CAAC,CAAC;AACvC,CAAC","sourcesContent":["import { processStubsInWorker } from './processStubsInWorker.js';\nimport type { WriteESMStubsOutput } from './types/WriteESMStubsOutput.js';\n\n/**\n * Generates ESM stubs for CommonJS and JSON modules.\n * @returns An object result containing the stubs or error that occured.\n */\nexport async function writeESMStubs(options: {\n inputPath: string;\n entryPaths: string[];\n}): Promise<WriteESMStubsOutput> {\n return processStubsInWorker(options);\n}\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { WriteESMStubsInput } from './types/WriteESMStubsInput.js';
|
|
2
|
+
import type { ESMStub } from './types/ESMStub.js';
|
|
3
|
+
/**
|
|
4
|
+
* Generates a set of ESM stubs for given entries and writes it to disk. If
|
|
5
|
+
* any files doesn't need a stub, then entry will have an undefined stubPath.
|
|
6
|
+
*/
|
|
7
|
+
export declare function writeESMStubsInternal(options: WriteESMStubsInput): Promise<ESMStub[]>;
|
|
8
|
+
//# sourceMappingURL=writeESMStubsInternal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writeESMStubsInternal.d.ts","sourceRoot":"","sources":["../src/writeESMStubsInternal.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACxE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAGlD;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CA6C3F"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { generateESMStubFromCJS } from './generateESMStubFromCJS.js';
|
|
2
|
+
import { generateESMStubFromJSON } from './generateESMStubFromJSON.js';
|
|
3
|
+
import { getStubPath } from './getStubPath.js';
|
|
4
|
+
import { writeFile } from 'fs/promises';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import { slash } from '@ms-cloudpack/path-string-parsing';
|
|
7
|
+
/**
|
|
8
|
+
* Generates a set of ESM stubs for given entries and writes it to disk. If
|
|
9
|
+
* any files doesn't need a stub, then entry will have an undefined stubPath.
|
|
10
|
+
*/
|
|
11
|
+
export async function writeESMStubsInternal(options) {
|
|
12
|
+
const { inputPath, entryPaths } = options;
|
|
13
|
+
return await Promise.all(entryPaths.map(async (entryPath) => {
|
|
14
|
+
const filePath = slash(path.join(inputPath, entryPath));
|
|
15
|
+
let stubContent = '';
|
|
16
|
+
let stubPath;
|
|
17
|
+
try {
|
|
18
|
+
stubPath = await getStubPath({ inputPath, entryPath });
|
|
19
|
+
if (!stubPath) {
|
|
20
|
+
return { entryPath };
|
|
21
|
+
}
|
|
22
|
+
// Process .json stubs
|
|
23
|
+
if (path.extname(entryPath).toLowerCase() === '.json') {
|
|
24
|
+
stubContent = await generateESMStubFromJSON({ filePath });
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
stubContent = generateESMStubFromCJS({
|
|
28
|
+
filePath,
|
|
29
|
+
stubPath,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
catch (e) {
|
|
34
|
+
const err = e;
|
|
35
|
+
return {
|
|
36
|
+
entryPath,
|
|
37
|
+
error: {
|
|
38
|
+
type: 'other-error',
|
|
39
|
+
message: String(err),
|
|
40
|
+
stack: err.stack,
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
// Attempt to write it to disk.
|
|
45
|
+
await writeFile(stubPath, stubContent, 'utf-8');
|
|
46
|
+
// Success, return the stub.
|
|
47
|
+
return { entryPath, stubPath: slash('./' + path.relative(inputPath, stubPath)) };
|
|
48
|
+
}));
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=writeESMStubsInternal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writeESMStubsInternal.js","sourceRoot":"","sources":["../src/writeESMStubsInternal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,IAAI,MAAM,MAAM,CAAC;AAGxB,OAAO,EAAE,KAAK,EAAE,MAAM,mCAAmC,CAAC;AAE1D;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,OAA2B;IACrE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;IAE1C,OAAO,MAAM,OAAO,CAAC,GAAG,CACtB,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE;QACjC,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC;QACxD,IAAI,WAAW,GAAW,EAAE,CAAC;QAC7B,IAAI,QAA4B,CAAC;QAEjC,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,WAAW,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC;YAEvD,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,OAAO,EAAE,SAAS,EAAE,CAAC;YACvB,CAAC;YAED,sBAAsB;YACtB,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,KAAK,OAAO,EAAE,CAAC;gBACtD,WAAW,GAAG,MAAM,uBAAuB,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;YAC5D,CAAC;iBAAM,CAAC;gBACN,WAAW,GAAG,sBAAsB,CAAC;oBACnC,QAAQ;oBACR,QAAQ;iBACT,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,GAAG,GAAG,CAAuD,CAAC;YAEpE,OAAO;gBACL,SAAS;gBACT,KAAK,EAAE;oBACL,IAAI,EAAE,aAAa;oBACnB,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC;oBACpB,KAAK,EAAE,GAAG,CAAC,KAAK;iBACjB;aACF,CAAC;QACJ,CAAC;QAED,+BAA+B;QAC/B,MAAM,SAAS,CAAC,QAAQ,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;QAEhD,4BAA4B;QAC5B,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,EAAa,CAAC;IAC9F,CAAC,CAAC,CACH,CAAC;AACJ,CAAC","sourcesContent":["import { generateESMStubFromCJS } from './generateESMStubFromCJS.js';\nimport { generateESMStubFromJSON } from './generateESMStubFromJSON.js';\nimport { getStubPath } from './getStubPath.js';\nimport { writeFile } from 'fs/promises';\nimport path from 'path';\nimport type { WriteESMStubsInput } from './types/WriteESMStubsInput.js';\nimport type { ESMStub } from './types/ESMStub.js';\nimport { slash } from '@ms-cloudpack/path-string-parsing';\n\n/**\n * Generates a set of ESM stubs for given entries and writes it to disk. If\n * any files doesn't need a stub, then entry will have an undefined stubPath.\n */\nexport async function writeESMStubsInternal(options: WriteESMStubsInput): Promise<ESMStub[]> {\n const { inputPath, entryPaths } = options;\n\n return await Promise.all<ESMStub>(\n entryPaths.map(async (entryPath) => {\n const filePath = slash(path.join(inputPath, entryPath));\n let stubContent: string = '';\n let stubPath: string | undefined;\n\n try {\n stubPath = await getStubPath({ inputPath, entryPath });\n\n if (!stubPath) {\n return { entryPath };\n }\n\n // Process .json stubs\n if (path.extname(entryPath).toLowerCase() === '.json') {\n stubContent = await generateESMStubFromJSON({ filePath });\n } else {\n stubContent = generateESMStubFromCJS({\n filePath,\n stubPath,\n });\n }\n } catch (e) {\n const err = e as Error & { code?: string; requireStack?: string[] };\n\n return {\n entryPath,\n error: {\n type: 'other-error',\n message: String(err),\n stack: err.stack,\n },\n };\n }\n\n // Attempt to write it to disk.\n await writeFile(stubPath, stubContent, 'utf-8');\n\n // Success, return the stub.\n return { entryPath, stubPath: slash('./' + path.relative(inputPath, stubPath)) } as ESMStub;\n }),\n );\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ms-cloudpack/esm-stub-utilities",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Generates ESM stubs for CommonJS entry files.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -15,8 +15,9 @@
|
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"@ms-cloudpack/json-utilities": "^0.1.3",
|
|
18
|
-
"@ms-cloudpack/path-utilities": "^2.4.
|
|
18
|
+
"@ms-cloudpack/path-utilities": "^2.4.3",
|
|
19
19
|
"@ms-cloudpack/path-string-parsing": "^1.1.3",
|
|
20
|
+
"@ms-cloudpack/package-utilities": "^5.7.10",
|
|
20
21
|
"atob": "^2.1.2",
|
|
21
22
|
"btoa": "^1.2.1",
|
|
22
23
|
"jsdom-global": "^3.0.2",
|
package/lib/createESMStub.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import type { StubError } from './types/StubError.js';
|
|
2
|
-
/**
|
|
3
|
-
* Generates an ESM stub for a CommonJS module.
|
|
4
|
-
* @returns The stub file contents, or an error object if the module could not be stubbed.
|
|
5
|
-
* Should only throw an error on bad input or other cases that likely indicate either a bug
|
|
6
|
-
* or bad configuration (as opposed to a problem with the file being stubbed).
|
|
7
|
-
*/
|
|
8
|
-
export declare function createESMStub(params: {
|
|
9
|
-
/** The full path to the CommonJS entry file. */
|
|
10
|
-
entryPath: string;
|
|
11
|
-
/** The path where the stub file will live. This is important for determining relative import paths. */
|
|
12
|
-
stubPath: string;
|
|
13
|
-
}): Promise<string | StubError>;
|
|
14
|
-
//# sourceMappingURL=createESMStub.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createESMStub.d.ts","sourceRoot":"","sources":["../src/createESMStub.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEtD;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE;IAC1C,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,uGAAuG;IACvG,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CA4D9B"}
|
package/lib/createESMStub.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createESMStub.js","sourceRoot":"","sources":["../src/createESMStub.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,KAAK,EAAE,MAAM,mCAAmC,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAGnE;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,MAKnC;IACC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC;IAEvC,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,KAAK,OAAO,EAAE,CAAC;QACtD,OAAO,cAAc,CAAC,SAAS,CAAC,CAAC;IACnC,CAAC;IAED,iEAAiE;IACjE,MAAM,UAAU,GAAG,MAAM,YAAY,CAAC,SAAS,CAAC,CAAC;IACjD,IAAI,OAAO,IAAI,UAAU,EAAE,CAAC;QAC1B,OAAO,UAAU,CAAC,KAAK,CAAC;IAC1B,CAAC;IAED,IAAI,YAAoB,CAAC;IACzB,IAAI,EAAE,CAAC,QAAQ,EAAE,KAAK,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;QAC1F,kEAAkE;QAClE,YAAY,GAAG,SAAS,CAAC;IAC3B,CAAC;SAAM,CAAC;QACN,YAAY,GAAG,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;IAChF,CAAC;IAED,MAAM,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC;IAEnC,IAAI,UAAU,KAAK,MAAM,EAAE,CAAC;QAC1B,sCAAsC;QACtC,OAAO,WAAW,YAAY,IAAI,CAAC;IACrC,CAAC;IAED,IAAI,UAAU,KAAK,OAAO,EAAE,CAAC;QAC3B,wDAAwD;QACxD,sFAAsF;QACtF,6FAA6F;QAC7F,iDAAiD;QACjD,OAAO,6BAA6B,YAAY,kCAAkC,CAAC;IACrF,CAAC;IAED,mGAAmG;IACnG,MAAM,YAAY,GAAG,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAC;IACnF,MAAM,gBAAgB,GAAG,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAE7D,MAAM,IAAI,GAAG,CAAC,6BAA6B,YAAY,IAAI,CAAC,CAAC;IAE7D,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;QACxB,IAAI,CAAC,IAAI,CAAC,WAAW,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IACpE,CAAC;IAED,IAAI,gBAAgB,EAAE,CAAC;QACrB,IAAI,CAAC,IAAI,CACP,kFAAkF,EAClF,+BAA+B,CAChC,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,IAAI,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IAC5C,CAAC;IAED,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;QACxB,IAAI,CAAC,IAAI,CAAC,YAAY,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrD,CAAC;IAED,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACzB,CAAC","sourcesContent":["import os from 'os';\nimport path from 'path';\nimport { slash } from '@ms-cloudpack/path-string-parsing';\nimport { runInSandbox } from './runInSandbox.js';\nimport { createJSONStub } from './createJSONStub.js';\nimport { isValidIdentifierName } from './isValidIdentifierName.js';\nimport type { StubError } from './types/StubError.js';\n\n/**\n * Generates an ESM stub for a CommonJS module.\n * @returns The stub file contents, or an error object if the module could not be stubbed.\n * Should only throw an error on bad input or other cases that likely indicate either a bug\n * or bad configuration (as opposed to a problem with the file being stubbed).\n */\nexport async function createESMStub(params: {\n /** The full path to the CommonJS entry file. */\n entryPath: string;\n /** The path where the stub file will live. This is important for determining relative import paths. */\n stubPath: string;\n}): Promise<string | StubError> {\n const { entryPath, stubPath } = params;\n\n if (path.extname(entryPath).toLowerCase() === '.json') {\n return createJSONStub(entryPath);\n }\n\n // Run the entry point file in a sandbox to determine the exports\n const exportInfo = await runInSandbox(entryPath);\n if ('error' in exportInfo) {\n return exportInfo.error;\n }\n\n let relativePath: string;\n if (os.platform() === 'win32' && path.parse(entryPath).root !== path.parse(stubPath).root) {\n // Different drive letters. These can't be relative to each other.\n relativePath = entryPath;\n } else {\n relativePath = './' + slash(path.relative(path.dirname(stubPath), entryPath));\n }\n\n const exportType = exportInfo.type;\n\n if (exportType === 'none') {\n // No exports. Just import the module.\n return `import \"${relativePath}\";`;\n }\n\n if (exportType === 'other') {\n // Some kind of value. Import then re-export as default.\n // (Note that even for values such as numbers which we could in theory rewrite inline,\n // we don't know how the value is calculated at runtime or what other side effects the module\n // might have, so we should preserve the import.)\n return `import moduleExport from \"${relativePath}\";\\nexport default moduleExport;`;\n }\n\n // Object or function. Export both named properties (if any, and filtering keywords) and a default.\n const namedExports = exportInfo.keys.filter((name) => isValidIdentifierName(name));\n const hasDefaultExport = exportInfo.keys.includes('default');\n\n const stub = [`import moduleExport from \"${relativePath}\";`];\n\n if (namedExports.length) {\n stub.push(`const { ${namedExports.join(', ')} } = moduleExport;`);\n }\n\n if (hasDefaultExport) {\n stub.push(\n `const defaultExport = (moduleExport?.default?.default) ?? moduleExport?.default;`,\n `export default defaultExport;`,\n );\n } else {\n stub.push(`export default moduleExport;`);\n }\n\n if (namedExports.length) {\n stub.push(`export { ${namedExports.join(', ')} }`);\n }\n\n return stub.join('\\n');\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createJSONStub.d.ts","sourceRoot":"","sources":["../src/createJSONStub.ts"],"names":[],"mappings":"AAKA;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA0BvE"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createJSONStub.js","sourceRoot":"","sources":["../src/createJSONStub.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAEnE;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,SAAiB;IACpD,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,KAAK,OAAO,EAAE,CAAC;QACtD,MAAM,IAAI,KAAK,CAAC,mBAAmB,GAAG,SAAS,CAAC,CAAC;IACnD,CAAC;IAED,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,uBAAuB,GAAG,SAAS,CAAC,CAAC;IACvD,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,SAAS,CAAC,CAAC;IAC3C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,0BAA0B,GAAG,SAAS,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,MAAM,GAAG,CAAC,gBAAgB,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,EAAE,sBAAsB,CAAC,CAAC;IAE9F,IAAI,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzE,iEAAiE;QACjE,MAAM,CAAC,IAAI,CACT,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;aACrB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC;aAC7C,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,gBAAgB,IAAI,WAAW,IAAI,GAAG,CAAC,CACzD,CAAC;IACJ,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC3B,CAAC","sourcesContent":["import fs from 'fs';\nimport path from 'path';\nimport { readJson } from '@ms-cloudpack/json-utilities';\nimport { isValidIdentifierName } from './isValidIdentifierName.js';\n\n/**\n * Generates an ESM stub of a JSON file. This just inlines the file contents rather than running\n * it in the sandbox.\n * @param entryPath - The full path to the JSON entry file.\n */\nexport async function createJSONStub(entryPath: string): Promise<string> {\n if (path.extname(entryPath).toLowerCase() !== '.json') {\n throw new Error('Not a JSON file: ' + entryPath);\n }\n\n if (!fs.existsSync(entryPath)) {\n throw new Error('File does not exist: ' + entryPath);\n }\n\n const jsonData = await readJson(entryPath);\n if (!jsonData) {\n throw new Error('File is not valid JSON: ' + entryPath);\n }\n\n const result = [`const data = ${JSON.stringify(jsonData, null, 2)};`, 'export default data;'];\n\n if (jsonData && typeof jsonData === 'object' && !Array.isArray(jsonData)) {\n // Export individual properties if they're valid identifier names\n result.push(\n ...Object.keys(jsonData)\n .filter((name) => isValidIdentifierName(name))\n .map((prop) => `export const ${prop} = data.${prop};`),\n );\n }\n\n return result.join('\\n');\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"runInSandbox.d.ts","sourceRoot":"","sources":["../src/runInSandbox.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAEhE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AActD,kCAAkC;AAClC,wBAAsB,WAAW,kBAGhC;AAsED;;;;;;GAMG;AAEH,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG;IAAE,KAAK,EAAE,SAAS,CAAA;CAAE,CAAC,CAsFpG"}
|
package/lib/runInSandbox.js
DELETED
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import { fileURLToPath } from 'url';
|
|
4
|
-
import { Worker } from 'worker_threads';
|
|
5
|
-
import { slash } from '@ms-cloudpack/path-string-parsing';
|
|
6
|
-
/** Some known error codes that can occur when running a file in a sandbox. */
|
|
7
|
-
const errorCodes = {
|
|
8
|
-
requireESM: 'ERR_REQUIRE_ESM',
|
|
9
|
-
moduleNotFound: 'MODULE_NOT_FOUND',
|
|
10
|
-
};
|
|
11
|
-
const dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
12
|
-
const workerPath = path.join(dirname, 'worker/worker.js');
|
|
13
|
-
// TODO do we need a pool?
|
|
14
|
-
let worker;
|
|
15
|
-
/** Stop the worker for testing */
|
|
16
|
-
export async function _stopWorker() {
|
|
17
|
-
await worker?.terminate();
|
|
18
|
-
worker = undefined;
|
|
19
|
-
}
|
|
20
|
-
function processError(error) {
|
|
21
|
-
const { message, code, name: errorName } = error;
|
|
22
|
-
let newMessage;
|
|
23
|
-
let type;
|
|
24
|
-
if (code === errorCodes.moduleNotFound) {
|
|
25
|
-
// Remove the require stack from MODULE_NOT_FOUND errors (we'll handle it separately).
|
|
26
|
-
// Error: Cannot find module 'foo'
|
|
27
|
-
// Require stack:
|
|
28
|
-
// - [...]/index.js
|
|
29
|
-
// - [.]/worker.js
|
|
30
|
-
newMessage = message.split('\n')[0];
|
|
31
|
-
type = 'module-not-found';
|
|
32
|
-
}
|
|
33
|
-
else if (code === errorCodes.requireESM) {
|
|
34
|
-
// Remove the instruction to change to a dynamic import, since it's less likely to be applicable here.
|
|
35
|
-
// Error [ERR_REQUIRE_ESM]: require() of ES Module [...]/esm.mjs not supported.
|
|
36
|
-
// Instead change the require of [...]/esm.mjs to a dynamic import() which is available in all CommonJS modules.
|
|
37
|
-
newMessage = message.split('\n')[0];
|
|
38
|
-
type = 'require-esm';
|
|
39
|
-
}
|
|
40
|
-
else if (errorName === 'SyntaxError') {
|
|
41
|
-
newMessage = message;
|
|
42
|
-
type = 'invalid-syntax';
|
|
43
|
-
}
|
|
44
|
-
else {
|
|
45
|
-
newMessage = message;
|
|
46
|
-
type = 'other-error';
|
|
47
|
-
}
|
|
48
|
-
let stack;
|
|
49
|
-
if (error.stack) {
|
|
50
|
-
// Get stack frame lines from the original error stack
|
|
51
|
-
stack = error.stack
|
|
52
|
-
.split('\n')
|
|
53
|
-
.filter((line) => /^\s+at /.test(line))
|
|
54
|
-
.map((line) => line.trim());
|
|
55
|
-
// Remove the worker frame and anything after it
|
|
56
|
-
const workerIndex = stack.findIndex((line) => slash(line).includes('esm-stub-utilities') && line.includes('worker.js'));
|
|
57
|
-
if (workerIndex !== -1) {
|
|
58
|
-
stack = stack.slice(0, workerIndex);
|
|
59
|
-
}
|
|
60
|
-
if (!stack.length) {
|
|
61
|
-
stack = undefined;
|
|
62
|
-
if (code === errorCodes.requireESM) {
|
|
63
|
-
// This error code + no stack outside the worker strongly implies that the file itself
|
|
64
|
-
// If we ended up with no stack besides the worker, this strongly implies that the file
|
|
65
|
-
// itself is an ESM file, not a CommonJS file.
|
|
66
|
-
newMessage =
|
|
67
|
-
"It appears you're trying to create a stub of an ES module, which is not supported. " +
|
|
68
|
-
'You may need to add a cloudpack override to bundle this package with ori.';
|
|
69
|
-
type = 'entry-is-esm';
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
// Remove node internals from the stack
|
|
74
|
-
const partialStack = stack?.filter((line) => !line.includes('(node:'));
|
|
75
|
-
return {
|
|
76
|
-
message: newMessage,
|
|
77
|
-
type,
|
|
78
|
-
partialStack: partialStack?.length ? partialStack : undefined,
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Run a CommonJS file within a sandboxed environment.
|
|
83
|
-
* @param entryPath - Path to a CommonJS file to run in a sandbox (does not work with ESM files)
|
|
84
|
-
* @returns Info about the file's exports, or error info if there was an issue.
|
|
85
|
-
* Should only throw an error on bad input or other cases that likely indicate either a bug
|
|
86
|
-
* or bad configuration (as opposed to a problem with the file being stubbed).
|
|
87
|
-
*/
|
|
88
|
-
// TODO add mechanism to force one-off worker
|
|
89
|
-
export async function runInSandbox(entryPath) {
|
|
90
|
-
if (!path.isAbsolute(entryPath)) {
|
|
91
|
-
throw new Error('Entry path must be absolute. Received: ' + entryPath);
|
|
92
|
-
}
|
|
93
|
-
if (!fs.existsSync(entryPath)) {
|
|
94
|
-
throw new Error('Entry path does not exist: ' + entryPath);
|
|
95
|
-
}
|
|
96
|
-
if (!worker) {
|
|
97
|
-
try {
|
|
98
|
-
worker = new Worker(workerPath, { stdout: true, stderr: true, execArgv: [] });
|
|
99
|
-
worker.stdout?.on('data', (data) => {
|
|
100
|
-
console.debug(`[sandbox stdout] ${data}`);
|
|
101
|
-
});
|
|
102
|
-
worker.stderr?.on('data', (data) => {
|
|
103
|
-
console.debug(`[sandbox stderr] ${data}`);
|
|
104
|
-
});
|
|
105
|
-
worker.on('exit', () => {
|
|
106
|
-
worker = undefined;
|
|
107
|
-
});
|
|
108
|
-
// don't hold the process open if only the worker is left
|
|
109
|
-
worker.unref();
|
|
110
|
-
}
|
|
111
|
-
catch (err) {
|
|
112
|
-
throw new Error(`Error initializing sandbox worker: ${err?.stack || err}`);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
return new Promise((resolve, reject) => {
|
|
116
|
-
// just for type checking
|
|
117
|
-
if (!worker)
|
|
118
|
-
return;
|
|
119
|
-
worker.on('message', onMessage);
|
|
120
|
-
worker.on('messageerror', onMessageError);
|
|
121
|
-
worker.on('error', onError);
|
|
122
|
-
worker.on('exit', onExit);
|
|
123
|
-
// Send a message requesting the file to be run.
|
|
124
|
-
worker.postMessage(entryPath);
|
|
125
|
-
/** Normally, both success and error results should be sent back as messages. */
|
|
126
|
-
function onMessage(message) {
|
|
127
|
-
if (message.entryPath !== entryPath) {
|
|
128
|
-
return; // message about a different file
|
|
129
|
-
}
|
|
130
|
-
handlersOff();
|
|
131
|
-
if (message.exportInfo) {
|
|
132
|
-
resolve(message.exportInfo);
|
|
133
|
-
}
|
|
134
|
-
else if (message.error) {
|
|
135
|
-
resolve({ error: processError(message.error) });
|
|
136
|
-
}
|
|
137
|
-
else {
|
|
138
|
-
// this indicates a bug in cloudpack
|
|
139
|
-
reject(new Error(`Unexpected sandbox worker message while running ${entryPath}: ${JSON.stringify(message)}`));
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
/** 'messageerror' event: deserializing a message failed. */
|
|
143
|
-
function onMessageError(err) {
|
|
144
|
-
handlersOff();
|
|
145
|
-
reject(new Error(`Error with sandbox worker message serialization while running ${entryPath}: ${err.stack || err}\n`));
|
|
146
|
-
}
|
|
147
|
-
/** 'error' event: unhandled exception in the worker, which shouldn't happen. */
|
|
148
|
-
function onError(err) {
|
|
149
|
-
handlersOff();
|
|
150
|
-
reject(new Error(`Uncaught error in sandbox worker while running ${entryPath}: ${err.stack || err}\n`));
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* Make sure the promise rejects if the worker exits unexpectedly. (This handler is unlikely
|
|
154
|
-
* to be used because the worker should throw an error if a file calls process.exit().)
|
|
155
|
-
*/
|
|
156
|
-
function onExit() {
|
|
157
|
-
reject(new Error(`Sandbox worker exited unexpectedly while running ${entryPath}`));
|
|
158
|
-
}
|
|
159
|
-
/** Remove all event handlers to avoid interference with future sandbox runs. */
|
|
160
|
-
function handlersOff() {
|
|
161
|
-
worker?.off('message', onMessage);
|
|
162
|
-
worker?.off('messageerror', onMessageError);
|
|
163
|
-
worker?.off('error', onError);
|
|
164
|
-
worker?.off('exit', onExit);
|
|
165
|
-
}
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
//# sourceMappingURL=runInSandbox.js.map
|
package/lib/runInSandbox.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"runInSandbox.js","sourceRoot":"","sources":["../src/runInSandbox.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'fs';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\nimport { Worker } from 'worker_threads';\nimport type { SandboxWorkerResponse } from './types/SandboxWorkerResponse.js';\nimport type { StubExportInfo } from './types/StubExportInfo.js';\nimport { slash } from '@ms-cloudpack/path-string-parsing';\nimport type { StubError } from './types/StubError.js';\n\n/** Some known error codes that can occur when running a file in a sandbox. */\nconst errorCodes = {\n requireESM: 'ERR_REQUIRE_ESM',\n moduleNotFound: 'MODULE_NOT_FOUND',\n};\n\nconst dirname = path.dirname(fileURLToPath(import.meta.url));\nconst workerPath = path.join(dirname, 'worker/worker.js');\n\n// TODO do we need a pool?\nlet worker: Worker | undefined;\n\n/** Stop the worker for testing */\nexport async function _stopWorker() {\n await worker?.terminate();\n worker = undefined;\n}\n\nfunction processError(error: NonNullable<SandboxWorkerResponse['error']>): StubError {\n const { message, code, name: errorName } = error;\n\n let newMessage: string;\n let type: StubError['type'];\n\n if (code === errorCodes.moduleNotFound) {\n // Remove the require stack from MODULE_NOT_FOUND errors (we'll handle it separately).\n // Error: Cannot find module 'foo'\n // Require stack:\n // - [...]/index.js\n // - [.]/worker.js\n newMessage = message.split('\\n')[0];\n type = 'module-not-found';\n } else if (code === errorCodes.requireESM) {\n // Remove the instruction to change to a dynamic import, since it's less likely to be applicable here.\n // Error [ERR_REQUIRE_ESM]: require() of ES Module [...]/esm.mjs not supported.\n // Instead change the require of [...]/esm.mjs to a dynamic import() which is available in all CommonJS modules.\n newMessage = message.split('\\n')[0];\n type = 'require-esm';\n } else if (errorName === 'SyntaxError') {\n newMessage = message;\n type = 'invalid-syntax';\n } else {\n newMessage = message;\n type = 'other-error';\n }\n\n let stack: string[] | undefined;\n if (error.stack) {\n // Get stack frame lines from the original error stack\n stack = error.stack\n .split('\\n')\n .filter((line) => /^\\s+at /.test(line))\n .map((line) => line.trim());\n\n // Remove the worker frame and anything after it\n const workerIndex = stack.findIndex(\n (line) => slash(line).includes('esm-stub-utilities') && line.includes('worker.js'),\n );\n if (workerIndex !== -1) {\n stack = stack.slice(0, workerIndex);\n }\n\n if (!stack.length) {\n stack = undefined;\n if (code === errorCodes.requireESM) {\n // This error code + no stack outside the worker strongly implies that the file itself\n // If we ended up with no stack besides the worker, this strongly implies that the file\n // itself is an ESM file, not a CommonJS file.\n newMessage =\n \"It appears you're trying to create a stub of an ES module, which is not supported. \" +\n 'You may need to add a cloudpack override to bundle this package with ori.';\n type = 'entry-is-esm';\n }\n }\n }\n\n // Remove node internals from the stack\n const partialStack = stack?.filter((line) => !line.includes('(node:'));\n\n return {\n message: newMessage,\n type,\n partialStack: partialStack?.length ? partialStack : undefined,\n };\n}\n\n/**\n * Run a CommonJS file within a sandboxed environment.\n * @param entryPath - Path to a CommonJS file to run in a sandbox (does not work with ESM files)\n * @returns Info about the file's exports, or error info if there was an issue.\n * Should only throw an error on bad input or other cases that likely indicate either a bug\n * or bad configuration (as opposed to a problem with the file being stubbed).\n */\n// TODO add mechanism to force one-off worker\nexport async function runInSandbox(entryPath: string): Promise<StubExportInfo | { error: StubError }> {\n if (!path.isAbsolute(entryPath)) {\n throw new Error('Entry path must be absolute. Received: ' + entryPath);\n }\n if (!fs.existsSync(entryPath)) {\n throw new Error('Entry path does not exist: ' + entryPath);\n }\n\n if (!worker) {\n try {\n worker = new Worker(workerPath, { stdout: true, stderr: true, execArgv: [] });\n worker.stdout?.on('data', (data) => {\n console.debug(`[sandbox stdout] ${data}`);\n });\n worker.stderr?.on('data', (data) => {\n console.debug(`[sandbox stderr] ${data}`);\n });\n worker.on('exit', () => {\n worker = undefined;\n });\n // don't hold the process open if only the worker is left\n worker.unref();\n } catch (err) {\n throw new Error(`Error initializing sandbox worker: ${(err as Error)?.stack || err}`);\n }\n }\n\n return new Promise((resolve, reject) => {\n // just for type checking\n if (!worker) return;\n\n worker.on('message', onMessage);\n worker.on('messageerror', onMessageError);\n worker.on('error', onError);\n worker.on('exit', onExit);\n\n // Send a message requesting the file to be run.\n worker.postMessage(entryPath);\n\n /** Normally, both success and error results should be sent back as messages. */\n function onMessage(message: SandboxWorkerResponse) {\n if (message.entryPath !== entryPath) {\n return; // message about a different file\n }\n\n handlersOff();\n if (message.exportInfo) {\n resolve(message.exportInfo);\n } else if (message.error) {\n resolve({ error: processError(message.error) });\n } else {\n // this indicates a bug in cloudpack\n reject(new Error(`Unexpected sandbox worker message while running ${entryPath}: ${JSON.stringify(message)}`));\n }\n }\n\n /** 'messageerror' event: deserializing a message failed. */\n function onMessageError(err: Error) {\n handlersOff();\n reject(\n new Error(`Error with sandbox worker message serialization while running ${entryPath}: ${err.stack || err}\\n`),\n );\n }\n\n /** 'error' event: unhandled exception in the worker, which shouldn't happen. */\n function onError(err: Error) {\n handlersOff();\n reject(new Error(`Uncaught error in sandbox worker while running ${entryPath}: ${err.stack || err}\\n`));\n }\n\n /**\n * Make sure the promise rejects if the worker exits unexpectedly. (This handler is unlikely\n * to be used because the worker should throw an error if a file calls process.exit().)\n */\n function onExit() {\n reject(new Error(`Sandbox worker exited unexpectedly while running ${entryPath}`));\n }\n\n /** Remove all event handlers to avoid interference with future sandbox runs. */\n function handlersOff() {\n worker?.off('message', onMessage);\n worker?.off('messageerror', onMessageError);\n worker?.off('error', onError);\n worker?.off('exit', onExit);\n }\n });\n}\n"]}
|
package/lib/worker/worker.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/worker/worker.js"],"names":[],"mappings":""}
|
package/lib/worker/worker.js
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
// These files use JS because they're loaded directly into a worker (see runInSandbox.ts),
|
|
2
|
-
// which must work both during tests (where the files are loaded from "src") and at runtime.
|
|
3
|
-
// They can still be type checked like TS, and the transpilation step doesn't do anything that
|
|
4
|
-
// should change the desired runtime behavior.
|
|
5
|
-
import { createRequire } from 'module';
|
|
6
|
-
import { isMainThread, parentPort } from 'worker_threads';
|
|
7
|
-
import { initBrowserEnvironment } from './initBrowserEnvironment.js';
|
|
8
|
-
import { cleanUpGlobals, getGlobalProperties } from './globals.js';
|
|
9
|
-
if (isMainThread || !parentPort) {
|
|
10
|
-
throw new Error('This file should only be loaded in a worker thread');
|
|
11
|
-
}
|
|
12
|
-
const require = createRequire(import.meta.url);
|
|
13
|
-
await initBrowserEnvironment();
|
|
14
|
-
// TODO should the globals be marked as readonly if possible?
|
|
15
|
-
const initialGlobalProperties = getGlobalProperties();
|
|
16
|
-
/**
|
|
17
|
-
* Type helper for sending messages to the parent.
|
|
18
|
-
* @param {import('../types/SandboxWorkerResponse.js').SandboxWorkerResponse} message
|
|
19
|
-
*/
|
|
20
|
-
function emitMessage(message) {
|
|
21
|
-
parentPort?.postMessage(message);
|
|
22
|
-
}
|
|
23
|
-
parentPort.on('message', (/** @type {string} */ entryPath) => {
|
|
24
|
-
if (typeof entryPath !== 'string') {
|
|
25
|
-
emitMessage({
|
|
26
|
-
error: { message: `Expected message to be a string; received: ${JSON.stringify(entryPath)}` },
|
|
27
|
-
entryPath: '',
|
|
28
|
-
});
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
function onExit() {
|
|
32
|
-
// In this case, throw an error rather than sending a message to avoid handling it twice.
|
|
33
|
-
// Don't include the filename since that's potentially ambiguous (and redundant with info
|
|
34
|
-
// included by the runInSandbox error handler).
|
|
35
|
-
throw new Error('process.exit() was unexpectedly called');
|
|
36
|
-
}
|
|
37
|
-
process.on('exit', onExit);
|
|
38
|
-
try {
|
|
39
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
40
|
-
const moduleExports = require(entryPath);
|
|
41
|
-
emitMessage({
|
|
42
|
-
entryPath,
|
|
43
|
-
exportInfo: getExportInfo(moduleExports),
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
catch (e) {
|
|
47
|
-
// Some errors running a module have a string `code` property.
|
|
48
|
-
// MODULE_NOT_FOUND errors have a `requireStack` property with a list of paths
|
|
49
|
-
// (right now we're using the call stack instead, but we could reconsider depending on
|
|
50
|
-
// which one seems more useful in practice).
|
|
51
|
-
const err = /** @type {Error & { code?: string; requireStack?: string[] }} */ (e);
|
|
52
|
-
emitMessage({
|
|
53
|
-
entryPath,
|
|
54
|
-
// Spreading doesn't work with errors, so copy manually
|
|
55
|
-
error: {
|
|
56
|
-
message: String(err), // handle non-Errors, and include the error name if present
|
|
57
|
-
name: err.name,
|
|
58
|
-
code: err.code,
|
|
59
|
-
stack: err.stack,
|
|
60
|
-
},
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
finally {
|
|
64
|
-
cleanUpGlobals(initialGlobalProperties);
|
|
65
|
-
process.off('exit', onExit);
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
|
-
/**
|
|
69
|
-
* Get information about a CJS module's exports, for purposes of creating a stub.
|
|
70
|
-
* @param {unknown} moduleExport The module's exports.
|
|
71
|
-
* @returns {import('../types/StubExportInfo.js').StubExportInfo}
|
|
72
|
-
*/
|
|
73
|
-
function getExportInfo(moduleExport) {
|
|
74
|
-
if (moduleExport === undefined) {
|
|
75
|
-
return { type: 'none' };
|
|
76
|
-
}
|
|
77
|
-
if (typeof moduleExport === 'function') {
|
|
78
|
-
return { type: 'function', keys: Object.keys(moduleExport) };
|
|
79
|
-
}
|
|
80
|
-
if (moduleExport && typeof moduleExport === 'object' && !Array.isArray(moduleExport)) {
|
|
81
|
-
return { type: 'object', keys: Object.keys(moduleExport) };
|
|
82
|
-
}
|
|
83
|
-
return { type: 'other' };
|
|
84
|
-
}
|
|
85
|
-
//# sourceMappingURL=worker.js.map
|
package/lib/worker/worker.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"worker.js","sourceRoot":"","sources":["../../src/worker/worker.js"],"names":[],"mappings":"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","sourcesContent":["// These files use JS because they're loaded directly into a worker (see runInSandbox.ts),\n// which must work both during tests (where the files are loaded from \"src\") and at runtime.\n// They can still be type checked like TS, and the transpilation step doesn't do anything that\n// should change the desired runtime behavior.\n\nimport { createRequire } from 'module';\nimport { isMainThread, parentPort } from 'worker_threads';\nimport { initBrowserEnvironment } from './initBrowserEnvironment.js';\nimport { cleanUpGlobals, getGlobalProperties } from './globals.js';\n\nif (isMainThread || !parentPort) {\n throw new Error('This file should only be loaded in a worker thread');\n}\n\nconst require = createRequire(import.meta.url);\n\nawait initBrowserEnvironment();\n// TODO should the globals be marked as readonly if possible?\nconst initialGlobalProperties = getGlobalProperties();\n\n/**\n * Type helper for sending messages to the parent.\n * @param {import('../types/SandboxWorkerResponse.js').SandboxWorkerResponse} message\n */\nfunction emitMessage(message) {\n parentPort?.postMessage(message);\n}\n\nparentPort.on('message', (/** @type {string} */ entryPath) => {\n if (typeof entryPath !== 'string') {\n emitMessage({\n error: { message: `Expected message to be a string; received: ${JSON.stringify(entryPath)}` },\n entryPath: '',\n });\n return;\n }\n\n function onExit() {\n // In this case, throw an error rather than sending a message to avoid handling it twice.\n // Don't include the filename since that's potentially ambiguous (and redundant with info\n // included by the runInSandbox error handler).\n throw new Error('process.exit() was unexpectedly called');\n }\n process.on('exit', onExit);\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const moduleExports = require(entryPath);\n emitMessage({\n entryPath,\n exportInfo: getExportInfo(moduleExports),\n });\n } catch (e) {\n // Some errors running a module have a string `code` property.\n // MODULE_NOT_FOUND errors have a `requireStack` property with a list of paths\n // (right now we're using the call stack instead, but we could reconsider depending on\n // which one seems more useful in practice).\n const err = /** @type {Error & { code?: string; requireStack?: string[] }} */ (e);\n emitMessage({\n entryPath,\n // Spreading doesn't work with errors, so copy manually\n error: {\n message: String(err), // handle non-Errors, and include the error name if present\n name: err.name,\n code: err.code,\n stack: err.stack,\n },\n });\n } finally {\n cleanUpGlobals(initialGlobalProperties);\n process.off('exit', onExit);\n }\n});\n\n/**\n * Get information about a CJS module's exports, for purposes of creating a stub.\n * @param {unknown} moduleExport The module's exports.\n * @returns {import('../types/StubExportInfo.js').StubExportInfo}\n */\nfunction getExportInfo(moduleExport) {\n if (moduleExport === undefined) {\n return { type: 'none' };\n }\n\n if (typeof moduleExport === 'function') {\n return { type: 'function', keys: Object.keys(moduleExport) };\n }\n\n if (moduleExport && typeof moduleExport === 'object' && !Array.isArray(moduleExport)) {\n return { type: 'object', keys: Object.keys(moduleExport) };\n }\n\n return { type: 'other' };\n}\n"]}
|
package/lib/writeESMStub.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { StubError } from './index.js';
|
|
2
|
-
/**
|
|
3
|
-
* Generates an ESM stub for CommonJS modules.
|
|
4
|
-
* @returns Path to the stub, or error info if there was an issue.
|
|
5
|
-
* Should only throw an error on bad input or other cases that likely indicate either a bug
|
|
6
|
-
* or bad configuration (as opposed to a problem with the file being stubbed).
|
|
7
|
-
*/
|
|
8
|
-
export declare function writeESMStub(entryPath: string): Promise<string | StubError>;
|
|
9
|
-
//# sourceMappingURL=writeESMStub.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"writeESMStub.d.ts","sourceRoot":"","sources":["../src/writeESMStub.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAyBjF"}
|
package/lib/writeESMStub.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import fsPromises from 'fs/promises';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import { createESMStub } from './createESMStub.js';
|
|
4
|
-
import { findPackageRoot } from '@ms-cloudpack/path-utilities';
|
|
5
|
-
import { slash } from '@ms-cloudpack/path-string-parsing';
|
|
6
|
-
/**
|
|
7
|
-
* Generates an ESM stub for CommonJS modules.
|
|
8
|
-
* @returns Path to the stub, or error info if there was an issue.
|
|
9
|
-
* Should only throw an error on bad input or other cases that likely indicate either a bug
|
|
10
|
-
* or bad configuration (as opposed to a problem with the file being stubbed).
|
|
11
|
-
*/
|
|
12
|
-
export async function writeESMStub(entryPath) {
|
|
13
|
-
// Ensure forward slashes
|
|
14
|
-
entryPath = slash(entryPath);
|
|
15
|
-
// Figure out where to put the stub
|
|
16
|
-
const packageRoot = findPackageRoot(entryPath);
|
|
17
|
-
if (!packageRoot) {
|
|
18
|
-
throw new Error(`Unable to find package root for ${entryPath}`);
|
|
19
|
-
}
|
|
20
|
-
const stubFilename = path.basename(entryPath, path.extname(entryPath)) + '-stub.mjs';
|
|
21
|
-
const stubFolderPath = path.join(packageRoot, 'node_modules/.cache/cloudpack-stubs/');
|
|
22
|
-
const stubPath = path.join(stubFolderPath, stubFilename);
|
|
23
|
-
// Create parent directories for the stub
|
|
24
|
-
await fsPromises.mkdir(stubFolderPath, { recursive: true });
|
|
25
|
-
// Generate and write the stub
|
|
26
|
-
const esmStubResult = await createESMStub({ entryPath, stubPath });
|
|
27
|
-
if (typeof esmStubResult === 'string') {
|
|
28
|
-
await fsPromises.writeFile(stubPath, esmStubResult);
|
|
29
|
-
return stubPath;
|
|
30
|
-
}
|
|
31
|
-
// There was an error, so return that instead
|
|
32
|
-
return esmStubResult;
|
|
33
|
-
}
|
|
34
|
-
//# sourceMappingURL=writeESMStub.js.map
|
package/lib/writeESMStub.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"writeESMStub.js","sourceRoot":"","sources":["../src/writeESMStub.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,aAAa,CAAC;AACrC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,KAAK,EAAE,MAAM,mCAAmC,CAAC;AAG1D;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,SAAiB;IAClD,yBAAyB;IACzB,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;IAE7B,mCAAmC;IACnC,MAAM,WAAW,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;IAC/C,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,mCAAmC,SAAS,EAAE,CAAC,CAAC;IAClE,CAAC;IACD,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,GAAG,WAAW,CAAC;IACrF,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,sCAAsC,CAAC,CAAC;IACtF,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;IAEzD,yCAAyC;IACzC,MAAM,UAAU,CAAC,KAAK,CAAC,cAAc,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE5D,8BAA8B;IAC9B,MAAM,aAAa,GAAG,MAAM,aAAa,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;IACnE,IAAI,OAAO,aAAa,KAAK,QAAQ,EAAE,CAAC;QACtC,MAAM,UAAU,CAAC,SAAS,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;QACpD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,6CAA6C;IAC7C,OAAO,aAAa,CAAC;AACvB,CAAC","sourcesContent":["import fsPromises from 'fs/promises';\nimport path from 'path';\nimport { createESMStub } from './createESMStub.js';\nimport { findPackageRoot } from '@ms-cloudpack/path-utilities';\nimport { slash } from '@ms-cloudpack/path-string-parsing';\nimport type { StubError } from './index.js';\n\n/**\n * Generates an ESM stub for CommonJS modules.\n * @returns Path to the stub, or error info if there was an issue.\n * Should only throw an error on bad input or other cases that likely indicate either a bug\n * or bad configuration (as opposed to a problem with the file being stubbed).\n */\nexport async function writeESMStub(entryPath: string): Promise<string | StubError> {\n // Ensure forward slashes\n entryPath = slash(entryPath);\n\n // Figure out where to put the stub\n const packageRoot = findPackageRoot(entryPath);\n if (!packageRoot) {\n throw new Error(`Unable to find package root for ${entryPath}`);\n }\n const stubFilename = path.basename(entryPath, path.extname(entryPath)) + '-stub.mjs';\n const stubFolderPath = path.join(packageRoot, 'node_modules/.cache/cloudpack-stubs/');\n const stubPath = path.join(stubFolderPath, stubFilename);\n\n // Create parent directories for the stub\n await fsPromises.mkdir(stubFolderPath, { recursive: true });\n\n // Generate and write the stub\n const esmStubResult = await createESMStub({ entryPath, stubPath });\n if (typeof esmStubResult === 'string') {\n await fsPromises.writeFile(stubPath, esmStubResult);\n return stubPath;\n }\n\n // There was an error, so return that instead\n return esmStubResult;\n}\n"]}
|