@ms-cloudpack/esm-stub-utilities 0.6.25 → 0.7.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.
Files changed (51) hide show
  1. package/lib/__fixtures__/loadStubWorker.d.ts +3 -0
  2. package/lib/__fixtures__/loadStubWorker.d.ts.map +1 -0
  3. package/lib/__fixtures__/loadStubWorker.js +122 -0
  4. package/lib/__fixtures__/loadStubWorker.js.map +1 -0
  5. package/lib/__fixtures__/tryImportStub.d.ts +44 -0
  6. package/lib/__fixtures__/tryImportStub.d.ts.map +1 -0
  7. package/lib/__fixtures__/tryImportStub.js +79 -0
  8. package/lib/__fixtures__/tryImportStub.js.map +1 -0
  9. package/lib/createESMStub.d.ts +11 -5
  10. package/lib/createESMStub.d.ts.map +1 -1
  11. package/lib/createESMStub.js +42 -52
  12. package/lib/createESMStub.js.map +1 -1
  13. package/lib/index.d.ts +1 -1
  14. package/lib/index.d.ts.map +1 -1
  15. package/lib/index.js +0 -1
  16. package/lib/index.js.map +1 -1
  17. package/lib/runInSandbox.d.ts +10 -7
  18. package/lib/runInSandbox.d.ts.map +1 -1
  19. package/lib/runInSandbox.js +139 -183
  20. package/lib/runInSandbox.js.map +1 -1
  21. package/lib/types/SandboxWorkerResponse.d.ts +21 -0
  22. package/lib/types/SandboxWorkerResponse.d.ts.map +1 -0
  23. package/lib/types/SandboxWorkerResponse.js +2 -0
  24. package/lib/types/SandboxWorkerResponse.js.map +1 -0
  25. package/lib/types/StubError.d.ts +27 -0
  26. package/lib/types/StubError.d.ts.map +1 -0
  27. package/lib/types/StubError.js +2 -0
  28. package/lib/types/StubError.js.map +1 -0
  29. package/lib/types/StubExportInfo.d.ts +18 -0
  30. package/lib/types/StubExportInfo.d.ts.map +1 -0
  31. package/lib/types/StubExportInfo.js +2 -0
  32. package/lib/types/StubExportInfo.js.map +1 -0
  33. package/lib/worker/globals.d.ts +8 -0
  34. package/lib/worker/globals.d.ts.map +1 -0
  35. package/lib/worker/globals.js +22 -0
  36. package/lib/worker/globals.js.map +1 -0
  37. package/lib/worker/initBrowserEnvironment.d.ts +5 -0
  38. package/lib/worker/initBrowserEnvironment.d.ts.map +1 -0
  39. package/lib/worker/initBrowserEnvironment.js +67 -0
  40. package/lib/worker/initBrowserEnvironment.js.map +1 -0
  41. package/lib/worker/worker.d.ts +2 -0
  42. package/lib/worker/worker.d.ts.map +1 -0
  43. package/lib/worker/worker.js +85 -0
  44. package/lib/worker/worker.js.map +1 -0
  45. package/lib/writeESMStub.d.ts +5 -1
  46. package/lib/writeESMStub.d.ts.map +1 -1
  47. package/lib/writeESMStub.js +21 -17
  48. package/lib/writeESMStub.js.map +1 -1
  49. package/package.json +6 -6
  50. package/browserEnvironment/index.cjs +0 -81
  51. package/browserEnvironment/typings.d.ts +0 -5
@@ -0,0 +1,67 @@
1
+ // See worker.js for why this is a JS file.
2
+ import btoa from 'btoa';
3
+ import atob from 'atob';
4
+ import { performance } from 'perf_hooks';
5
+ import util from 'util';
6
+ /**
7
+ * Initialize a fake browser environment.
8
+ */
9
+ export async function initBrowserEnvironment() {
10
+ // These must be set up before JSDOM
11
+ !global.performance && (global.performance = /** @type {*} */ (performance));
12
+ !global.TextEncoder && (global.TextEncoder = util.TextEncoder);
13
+ !global.TextDecoder && (global.TextDecoder = /** @type {*} */ (util.TextDecoder));
14
+ (await import('jsdom-global')).default();
15
+ await import('regenerator-runtime');
16
+ // Ensure assigning to and reading from `window.foo` globals works as expected by copying all the
17
+ // properties from the jsdom `window` to node's `global`, then assigning `global` to `window`.
18
+ Object.entries(Object.getOwnPropertyDescriptors(window)).forEach(([k, desc]) => {
19
+ // Skip storage to avoid errors "localStorage is not available for opaque origins"
20
+ // (these errors could in theory be resolved by passing a URL to jsdom-global setup, but that
21
+ // triggers some weird issues with whatwg-url using TextDecoder in a way that works in other
22
+ // environments but throws in the sandbox)
23
+ if (!(k in global) && !['localStorage', 'sessionStorage'].includes(k)) {
24
+ Object.defineProperty(global, k, desc);
25
+ }
26
+ });
27
+ /** @type {*} */ (global).window = global;
28
+ /** @type {*} */ (global).self = global;
29
+ /** @type {*} */ (document).window = global;
30
+ window.requestAnimationFrame = window.setTimeout;
31
+ window.cancelAnimationFrame = window.clearTimeout;
32
+ global.btoa = btoa;
33
+ global.atob = atob;
34
+ // Simulate WebSocket existence. (Needed for isomorphic-ws)
35
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
36
+ global.WebSocket = window.WebSocket = /** @type {*} */ (class WebSocket {
37
+ });
38
+ // Fake MessageChannel so scheduler won't hang the process by opening a channel.
39
+ global.MessageChannel = window.MessageChannel = class MessageChannel {
40
+ constructor() {
41
+ this.port1 = ({});
42
+ this.port2 = ({});
43
+ }
44
+ };
45
+ // eslint-disable-next-line etc/no-deprecated
46
+ const createElement = window.document.createElement.bind(window.document);
47
+ // Mock out canvas.
48
+ // eslint-disable-next-line etc/no-deprecated
49
+ global.document.createElement =
50
+ /** @type {*} */ (window).createElement =
51
+ /** @type {*} */ (global).createElement =
52
+ (/** @type {string} */ tagName, /** @type {ElementCreationOptions} */ options) => {
53
+ if (tagName === 'canvas') {
54
+ return /** @type {*} */ ({
55
+ getContext: () => ({
56
+ fillRect: () => { },
57
+ }),
58
+ measureText: () => ({}),
59
+ });
60
+ }
61
+ return createElement.apply(window.document, [tagName, options]);
62
+ };
63
+ window.fetch = /** @type {*} */ (async () => { });
64
+ // prevent 'debug' package from accessing process.stderr
65
+ process.env.DEBUG_COLORS = '0';
66
+ }
67
+ //# sourceMappingURL=initBrowserEnvironment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"initBrowserEnvironment.js","sourceRoot":"","sources":["../../src/worker/initBrowserEnvironment.js"],"names":[],"mappings":"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","sourcesContent":["// See worker.js for why this is a JS file.\n\nimport btoa from 'btoa';\nimport atob from 'atob';\nimport { performance } from 'perf_hooks';\nimport util from 'util';\n\n/**\n * Initialize a fake browser environment.\n */\nexport async function initBrowserEnvironment() {\n // These must be set up before JSDOM\n !global.performance && (global.performance = /** @type {*} */ (performance));\n !global.TextEncoder && (global.TextEncoder = util.TextEncoder);\n !global.TextDecoder && (global.TextDecoder = /** @type {*} */ (util.TextDecoder));\n\n (await import('jsdom-global')).default();\n\n await import('regenerator-runtime');\n\n // Ensure assigning to and reading from `window.foo` globals works as expected by copying all the\n // properties from the jsdom `window` to node's `global`, then assigning `global` to `window`.\n Object.entries(Object.getOwnPropertyDescriptors(window)).forEach(([k, desc]) => {\n // Skip storage to avoid errors \"localStorage is not available for opaque origins\"\n // (these errors could in theory be resolved by passing a URL to jsdom-global setup, but that\n // triggers some weird issues with whatwg-url using TextDecoder in a way that works in other\n // environments but throws in the sandbox)\n if (!(k in global) && !['localStorage', 'sessionStorage'].includes(k)) {\n Object.defineProperty(global, k, desc);\n }\n });\n /** @type {*} */ (global).window = global;\n /** @type {*} */ (global).self = global;\n /** @type {*} */ (document).window = global;\n\n window.requestAnimationFrame = window.setTimeout;\n window.cancelAnimationFrame = window.clearTimeout;\n global.btoa = btoa;\n global.atob = atob;\n\n // Simulate WebSocket existence. (Needed for isomorphic-ws)\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n global.WebSocket = window.WebSocket = /** @type {*} */ (class WebSocket {});\n\n // Fake MessageChannel so scheduler won't hang the process by opening a channel.\n global.MessageChannel = window.MessageChannel = class MessageChannel {\n port1 = /** @type {*} */ ({});\n port2 = /** @type {*} */ ({});\n };\n\n // eslint-disable-next-line etc/no-deprecated\n const createElement = window.document.createElement.bind(window.document);\n\n // Mock out canvas.\n // eslint-disable-next-line etc/no-deprecated\n global.document.createElement =\n /** @type {*} */ (window).createElement =\n /** @type {*} */ (global).createElement =\n (/** @type {string} */ tagName, /** @type {ElementCreationOptions} */ options) => {\n if (tagName === 'canvas') {\n return /** @type {*} */ ({\n getContext: () => ({\n fillRect: () => {},\n }),\n measureText: () => ({}),\n });\n }\n\n return createElement.apply(window.document, [tagName, options]);\n };\n\n window.fetch = /** @type {*} */ (async () => {});\n\n // prevent 'debug' package from accessing process.stderr\n process.env.DEBUG_COLORS = '0';\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/worker/worker.js"],"names":[],"mappings":""}
@@ -0,0 +1,85 @@
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),
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
@@ -0,0 +1 @@
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"]}
@@ -1,5 +1,9 @@
1
+ import type { StubError } from './index.js';
1
2
  /**
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).
3
7
  */
4
- export declare function writeESMStub(entryPath: string, stubPath?: string): Promise<string>;
8
+ export declare function writeESMStub(entryPath: string): Promise<string | StubError>;
5
9
  //# sourceMappingURL=writeESMStub.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"writeESMStub.d.ts","sourceRoot":"","sources":["../src/writeESMStub.ts"],"names":[],"mappings":"AAMA;;GAEG;AACH,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA0BxF"}
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"}
@@ -5,26 +5,30 @@ import { findPackageRoot } from '@ms-cloudpack/path-utilities';
5
5
  import { slash } from '@ms-cloudpack/path-string-parsing';
6
6
  /**
7
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).
8
11
  */
9
- export async function writeESMStub(entryPath, stubPath) {
12
+ export async function writeESMStub(entryPath) {
10
13
  // Ensure forward slashes
11
14
  entryPath = slash(entryPath);
12
- // Ensure stub path is provided.
13
- if (!stubPath) {
14
- const rootPath = findPackageRoot(entryPath);
15
- if (!rootPath) {
16
- throw new Error(`Unable to find package root for ${entryPath}`);
17
- }
18
- const extension = path.extname(entryPath);
19
- const stubFilename = path.basename(entryPath, extension) + '-stub.js';
20
- const stubFolderPath = path.join(rootPath, 'node_modules/.cache/cloudpack-stubs/');
21
- await fsPromises.mkdir(stubFolderPath, { recursive: true });
22
- stubPath = path.join(stubFolderPath, stubFilename);
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}`);
23
19
  }
24
- // If we have a package export, we can generate an ESM stub.
25
- const esmStub = await createESMStub(entryPath, stubPath);
26
- // Write the stub to disk.
27
- await fsPromises.writeFile(stubPath, esmStub);
28
- return stubPath;
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;
29
33
  }
30
34
  //# sourceMappingURL=writeESMStub.js.map
@@ -1 +1 @@
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;AAE1D;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,SAAiB,EAAE,QAAiB;IACrE,yBAAyB;IACzB,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;IAE7B,gCAAgC;IAChC,IAAI,CAAC,QAAQ,EAAE;QACb,MAAM,QAAQ,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;QAC5C,IAAI,CAAC,QAAQ,EAAE;YACb,MAAM,IAAI,KAAK,CAAC,mCAAmC,SAAS,EAAE,CAAC,CAAC;SACjE;QACD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAC1C,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC,GAAG,UAAU,CAAC;QACtE,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,sCAAsC,CAAC,CAAC;QAEnF,MAAM,UAAU,CAAC,KAAK,CAAC,cAAc,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE5D,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;KACpD;IAED,4DAA4D;IAC5D,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAEzD,0BAA0B;IAC1B,MAAM,UAAU,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAE9C,OAAO,QAAQ,CAAC;AAClB,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';\n\n/**\n * Generates an ESM stub for CommonJS modules.\n */\nexport async function writeESMStub(entryPath: string, stubPath?: string): Promise<string> {\n // Ensure forward slashes\n entryPath = slash(entryPath);\n\n // Ensure stub path is provided.\n if (!stubPath) {\n const rootPath = findPackageRoot(entryPath);\n if (!rootPath) {\n throw new Error(`Unable to find package root for ${entryPath}`);\n }\n const extension = path.extname(entryPath);\n const stubFilename = path.basename(entryPath, extension) + '-stub.js';\n const stubFolderPath = path.join(rootPath, 'node_modules/.cache/cloudpack-stubs/');\n\n await fsPromises.mkdir(stubFolderPath, { recursive: true });\n\n stubPath = path.join(stubFolderPath, stubFilename);\n }\n\n // If we have a package export, we can generate an ESM stub.\n const esmStub = await createESMStub(entryPath, stubPath);\n\n // Write the stub to disk.\n await fsPromises.writeFile(stubPath, esmStub);\n\n return stubPath;\n}\n"]}
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;QAChB,MAAM,IAAI,KAAK,CAAC,mCAAmC,SAAS,EAAE,CAAC,CAAC;KACjE;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;QACrC,MAAM,UAAU,CAAC,SAAS,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;QACpD,OAAO,QAAQ,CAAC;KACjB;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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ms-cloudpack/esm-stub-utilities",
3
- "version": "0.6.25",
3
+ "version": "0.7.0",
4
4
  "description": "Generates ESM stubs for CommonJS entry files.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -14,14 +14,13 @@
14
14
  },
15
15
  "dependencies": {
16
16
  "@ms-cloudpack/json-utilities": "^0.0.7",
17
- "@ms-cloudpack/path-utilities": "^2.3.3",
17
+ "@ms-cloudpack/path-utilities": "^2.3.4",
18
18
  "@ms-cloudpack/path-string-parsing": "^1.1.0",
19
19
  "atob": "^2.1.2",
20
20
  "btoa": "^1.2.1",
21
21
  "jsdom-global": "^3.0.2",
22
22
  "jsdom": "^22.0.0",
23
- "regenerator-runtime": "^0.13.9",
24
- "vm2": "^3.9.13"
23
+ "regenerator-runtime": "^0.14.0"
25
24
  },
26
25
  "devDependencies": {
27
26
  "@ms-cloudpack/bundler-types": "*",
@@ -31,7 +30,9 @@
31
30
  "@types/atob": "^2.1.2",
32
31
  "@types/btoa": "^1.2.3",
33
32
  "@types/jsdom": "^21.1.1",
34
- "@types/regenerator-runtime": "^0.13.1"
33
+ "@types/regenerator-runtime": "^0.13.1",
34
+ "lodash": "^4.17.21",
35
+ "pretty-format": "^29.7.0"
35
36
  },
36
37
  "scripts": {
37
38
  "api": "cloudpack-scripts api",
@@ -44,7 +45,6 @@
44
45
  "test": "cloudpack-scripts test"
45
46
  },
46
47
  "files": [
47
- "browserEnvironment",
48
48
  "lib/**/!(*.test.*)"
49
49
  ]
50
50
  }
@@ -1,81 +0,0 @@
1
- // @ts-check
2
- /* eslint-disable @typescript-eslint/triple-slash-reference */
3
- /* eslint-disable @typescript-eslint/no-unsafe-assignment */
4
- /* eslint-disable etc/no-deprecated */
5
-
6
- // This file uses JS because it's loaded directly into the CJS sandbox environment (see runInSandbox.ts).
7
- // It's located in a separate file because we don't want to run it through the typescript compiler
8
- // to avoid adding "use strict" or having issues with different versions of the file being used by
9
- // jest vs. actual runtime usage (jest would use the version from "src").
10
-
11
- /// <reference path="./typings.d.ts" />
12
-
13
- const btoa = require('btoa');
14
- const atob = require('atob');
15
- const { performance } = require('perf_hooks');
16
- const util = require('util');
17
-
18
- // These must be set up before JSDOM
19
- !global.performance && (global.performance = /** @type {*} */ (performance));
20
- !global.TextEncoder && (global.TextEncoder = util.TextEncoder);
21
- !global.TextDecoder && (global.TextDecoder = /** @type {*} */ (util.TextDecoder));
22
-
23
- require('jsdom-global')();
24
-
25
- require('regenerator-runtime');
26
-
27
- // Ensure assigning to and reading from `window.foo` globals works as expected by copying all the
28
- // properties from the jsdom `window` to node's `global`, then assigning `global` to `window`.
29
- Object.entries(Object.getOwnPropertyDescriptors(window)).forEach(([k, desc]) => {
30
- // Skip storage to avoid errors "localStorage is not available for opaque origins"
31
- // (these errors could in theory be resolved by passing a URL to jsdom-global setup, but that
32
- // triggers some weird issues with whatwg-url using TextDecoder in a way that works in other
33
- // environments but throws in the sandbox)
34
- if (!(k in global) && !['localStorage', 'sessionStorage'].includes(k)) {
35
- Object.defineProperty(global, k, desc);
36
- }
37
- });
38
- /** @type {*} */ (global).window = global;
39
- /** @type {*} */ (global).self = global;
40
- /** @type {*} */ (document).window = global;
41
-
42
- window.requestAnimationFrame = window.setTimeout;
43
- window.cancelAnimationFrame = window.clearTimeout;
44
- global.btoa = btoa;
45
- global.atob = atob;
46
-
47
- // Simulate WebSocket existence. (Needed for isomorphic-ws)
48
- global.WebSocket = window.WebSocket = /** @type {*} */ (class WebSocket {});
49
-
50
- // Fake MessageChannel so scheduler won't hang the process by opening a channel.
51
- global.MessageChannel = window.MessageChannel = class MessageChannel {
52
- port1 = /** @type {*} */ ({});
53
- port2 = /** @type {*} */ ({});
54
- };
55
-
56
- const createElement = window.document.createElement.bind(window.document);
57
-
58
- // Mock out canvas.
59
- global.document.createElement =
60
- /** @type {*} */ (window).createElement =
61
- /** @type {*} */ (global).createElement =
62
- (/** @type {string} */ tagName, /** @type {ElementCreationOptions} */ options) => {
63
- if (tagName === 'canvas') {
64
- return /** @type {*} */ ({
65
- getContext: () => ({
66
- fillRect: () => {
67
- /* no-op */
68
- },
69
- }),
70
- measureText: () => ({}),
71
- });
72
- }
73
-
74
- return createElement.apply(window.document, [tagName, options]);
75
- };
76
-
77
- window.fetch = /** @type {*} */ (
78
- async () => {
79
- /* no-op */
80
- }
81
- );
@@ -1,5 +0,0 @@
1
- declare module 'jsdom-global' {
2
- import type jsdom from 'jsdom';
3
- function setup(html?: string, options?: jsdom.ConstructorOptions): () => void;
4
- export = setup;
5
- }