@ms-cloudpack/esm-stub-utilities 0.10.2 → 0.10.3

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 (43) hide show
  1. package/lib/getStubPath.d.ts +2 -0
  2. package/lib/getStubPath.d.ts.map +1 -1
  3. package/lib/getStubPath.js +3 -2
  4. package/lib/getStubPath.js.map +1 -1
  5. package/lib/index.d.ts +2 -0
  6. package/lib/index.d.ts.map +1 -1
  7. package/lib/index.js +1 -0
  8. package/lib/index.js.map +1 -1
  9. package/lib/processError.d.ts +12 -1
  10. package/lib/processError.d.ts.map +1 -1
  11. package/lib/processError.js +69 -33
  12. package/lib/processError.js.map +1 -1
  13. package/lib/types/VerifyStubOptions.d.ts +17 -0
  14. package/lib/types/VerifyStubOptions.d.ts.map +1 -0
  15. package/lib/types/VerifyStubOptions.js +2 -0
  16. package/lib/types/VerifyStubOptions.js.map +1 -0
  17. package/lib/types/WriteESMStubsOptions.d.ts +2 -0
  18. package/lib/types/WriteESMStubsOptions.d.ts.map +1 -1
  19. package/lib/types/WriteESMStubsOptions.js.map +1 -1
  20. package/lib/verifyStub/loadStubWorker.d.ts +14 -0
  21. package/lib/verifyStub/loadStubWorker.d.ts.map +1 -0
  22. package/lib/{__fixtures__ → verifyStub}/loadStubWorker.js +51 -34
  23. package/lib/verifyStub/loadStubWorker.js.map +1 -0
  24. package/lib/verifyStub/verifyStub.d.ts +19 -0
  25. package/lib/verifyStub/verifyStub.d.ts.map +1 -0
  26. package/lib/verifyStub/verifyStub.js +116 -0
  27. package/lib/verifyStub/verifyStub.js.map +1 -0
  28. package/lib/worker/globals.d.ts.map +1 -1
  29. package/lib/worker/globals.js +4 -1
  30. package/lib/worker/globals.js.map +1 -1
  31. package/lib/worker/initBrowserEnvironment.d.ts.map +1 -1
  32. package/lib/worker/initBrowserEnvironment.js +4 -1
  33. package/lib/worker/initBrowserEnvironment.js.map +1 -1
  34. package/lib/writeESMStubs.js +3 -3
  35. package/lib/writeESMStubs.js.map +1 -1
  36. package/package.json +4 -6
  37. package/lib/__fixtures__/loadStubWorker.d.ts +0 -3
  38. package/lib/__fixtures__/loadStubWorker.d.ts.map +0 -1
  39. package/lib/__fixtures__/loadStubWorker.js.map +0 -1
  40. package/lib/__fixtures__/tryImportStub.d.ts +0 -44
  41. package/lib/__fixtures__/tryImportStub.d.ts.map +0 -1
  42. package/lib/__fixtures__/tryImportStub.js +0 -79
  43. package/lib/__fixtures__/tryImportStub.js.map +0 -1
@@ -6,5 +6,7 @@ export declare const supportedCJSExtensions: string[];
6
6
  export declare function getStubPath(options: {
7
7
  inputPath: string;
8
8
  entryPath: string;
9
+ /** Assume the entry is CJS (for testing only) */
10
+ forceCJS?: boolean;
9
11
  }): Promise<string | undefined>;
10
12
  //# sourceMappingURL=getStubPath.d.ts.map
@@ -1 +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"}
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;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAoB9B"}
@@ -8,9 +8,10 @@ export const supportedCJSExtensions = ['.js', '.cjs'];
8
8
  * if a stub should indeed be generated for the entry. Otherwise returns undefined.
9
9
  */
10
10
  export async function getStubPath(options) {
11
- const { inputPath, entryPath } = options;
11
+ const { inputPath, entryPath, forceCJS } = options;
12
12
  const ext = path.extname(entryPath).toLowerCase();
13
- const isCJSEntry = supportedCJSExtensions.includes(ext) && (await detectModuleType(path.resolve(inputPath, entryPath))) === 'cjs';
13
+ const isCJSEntry = forceCJS ||
14
+ (supportedCJSExtensions.includes(ext) && (await detectModuleType(path.resolve(inputPath, entryPath))) === 'cjs');
14
15
  const isJSONEntry = ext === '.json';
15
16
  if (isCJSEntry || isJSONEntry) {
16
17
  const stubFilename = path.basename(entryPath, supportedCJSExtensions.includes(ext) ? ext : undefined) + '-stub.mjs';
@@ -1 +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"]}
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,OAKjC;IACC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAEnD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC;IAClD,MAAM,UAAU,GACd,QAAQ;QACR,CAAC,sBAAsB,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC;IACnH,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: {\n inputPath: string;\n entryPath: string;\n /** Assume the entry is CJS (for testing only) */\n forceCJS?: boolean;\n}): Promise<string | undefined> {\n const { inputPath, entryPath, forceCJS } = options;\n\n const ext = path.extname(entryPath).toLowerCase();\n const isCJSEntry =\n forceCJS ||\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,4 +1,6 @@
1
1
  export { writeESMStubs } from './writeESMStubs.js';
2
2
  export type { WriteESMStubsOptions } from './types/WriteESMStubsOptions.js';
3
3
  export type { WriteESMStubsResult } from './types/WriteESMStubsResult.js';
4
+ export { _verifyStub } from './verifyStub/verifyStub.js';
5
+ export type { _VerifyStubOptions } from './types/VerifyStubOptions.js';
4
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
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,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAC5E,YAAY,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC"}
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,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAC5E,YAAY,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,YAAY,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC"}
package/lib/index.js CHANGED
@@ -1,2 +1,3 @@
1
1
  export { writeESMStubs } from './writeESMStubs.js';
2
+ export { _verifyStub } from './verifyStub/verifyStub.js';
2
3
  //# 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,aAAa,EAAE,MAAM,oBAAoB,CAAC","sourcesContent":["export { writeESMStubs } from './writeESMStubs.js';\nexport type { WriteESMStubsOptions } from './types/WriteESMStubsOptions.js';\nexport type { WriteESMStubsResult } from './types/WriteESMStubsResult.js';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGnD,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC","sourcesContent":["export { writeESMStubs } from './writeESMStubs.js';\nexport type { WriteESMStubsOptions } from './types/WriteESMStubsOptions.js';\nexport type { WriteESMStubsResult } from './types/WriteESMStubsResult.js';\nexport { _verifyStub } from './verifyStub/verifyStub.js';\nexport type { _VerifyStubOptions } from './types/VerifyStubOptions.js';\n"]}
@@ -1,6 +1,17 @@
1
1
  import type { BundleMessage } from '@ms-cloudpack/bundler-types';
2
+ export type ErrorLike = {
3
+ name?: string;
4
+ message: string;
5
+ stack?: string;
6
+ code?: string;
7
+ requireStack?: string[];
8
+ };
2
9
  /**
3
10
  * Get info from an error which may be useful for debugging.
4
11
  */
5
- export declare function processError(entryKey: string, entryFullPath: string, errorParam: unknown): BundleMessage;
12
+ export declare function processError(params: {
13
+ entryKey: string;
14
+ entryFullPath: string;
15
+ error: unknown;
16
+ }): BundleMessage;
6
17
  //# sourceMappingURL=processError.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"processError.d.ts","sourceRoot":"","sources":["../src/processError.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AASjE;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,GAAG,aAAa,CA4ExG"}
1
+ {"version":3,"file":"processError.d.ts","sourceRoot":"","sources":["../src/processError.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAGjE,MAAM,MAAM,SAAS,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAYnH;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAAG,aAAa,CA2G/G"}
@@ -4,12 +4,18 @@ const errorCodes = {
4
4
  requireESM: 'ERR_REQUIRE_ESM',
5
5
  moduleNotFound: 'MODULE_NOT_FOUND',
6
6
  };
7
+ const esmPackageName = 'esm-stub-utilities';
8
+ const workerPackageName = 'worker-pool';
9
+ const workerEntryName = 'workerEntry.js';
7
10
  /**
8
11
  * Get info from an error which may be useful for debugging.
9
12
  */
10
- export function processError(entryKey, entryFullPath, errorParam) {
13
+ export function processError(params) {
14
+ const { entryKey, entryFullPath, error: errorParam } = params;
11
15
  const error = errorParam.message ? errorParam : { message: String(errorParam) };
12
- const { message: originalMessage, code, stack: originalStack, requireStack, } = error;
16
+ const { message: originalMessage, name, code, stack: originalStack, requireStack } = error;
17
+ let lineNumber = 1;
18
+ let columnNumber = 0;
13
19
  let message = originalMessage;
14
20
  if (code === errorCodes.requireESM) {
15
21
  // Remove the instruction to change to a dynamic import, since it's less likely to be applicable here.
@@ -26,50 +32,80 @@ export function processError(entryKey, entryFullPath, errorParam) {
26
32
  // - [...]/generateESMStubFromCJS.js
27
33
  message = message.split('\n')[0];
28
34
  // remove the generateESMStubFromCJS require line (not interesting)
29
- const filteredStack = requireStack.filter((line) => !line.includes('generateESMStubFromCJS'));
35
+ const filteredStack = requireStack.filter((line) => !line.includes(esmPackageName) && !line.includes(workerPackageName));
30
36
  if (filteredStack.length > 1) {
31
37
  // Only include the stack if it goes beyond the original file
32
- message += `. Require stack:\n${filteredStack.map((line) => ` ${line}`).join('\n')}`;
38
+ message += `.\nRequire stack:\n${filteredStack.map((line) => ` - ${line}`).join('\n')}`;
33
39
  }
34
40
  }
41
+ else if (name === 'SyntaxError' && originalStack) {
42
+ // SyntaxErrors will have a `stack` like this:
43
+ // /path/to/file.js:1
44
+ // oh no
45
+ // ^^
46
+ // SyntaxError: Unexpected identifier
47
+ // at ....
48
+ // Use the first part as the message, but remove the stack trace (will be added back later if needed).
49
+ message = originalStack.split(/\n\s+at /)[0];
50
+ // If the error is in the entry point file, get the line and possibly column number.
51
+ // (There won't be a stack line for the file with the syntax error, so the normal logic to get
52
+ // the line and column later won't work.)
53
+ const lineNumberMatch = message.match(/^(.*?):(\d+)\n/);
54
+ if (lineNumberMatch && slash(lineNumberMatch[1]).includes(slash(entryFullPath))) {
55
+ lineNumber = Number(lineNumberMatch[2]);
56
+ // Get the column if the stack includes ^^ indicating the error location
57
+ // (not all of them will have this, e.g. "unexpected end of input" errors won't)
58
+ const columnNumberMatch = message.match(/^\s*\^/m);
59
+ if (columnNumberMatch) {
60
+ columnNumber = columnNumberMatch[0].length - 1;
61
+ }
62
+ }
63
+ // This happens if a file is inferred from context or extension to be CJS but is actually ESM.
64
+ if (/Unexpected token '(import|export)'/.test(message)) {
65
+ message = `File appears to be an ES module that was loaded with require:\n${message}`;
66
+ }
67
+ }
68
+ else if (name !== 'Error') {
69
+ message = `${name}: ${message}`;
70
+ }
35
71
  let stack;
36
72
  if (originalStack) {
37
- // Get stack frame lines from the original error stack
38
- stack = originalStack.split('\n').filter((line) => /^\s+at /.test(line));
73
+ // Get stack frame lines from the original error stack, and remove parts that are less likely
74
+ // to be useful (node internals, and jest internals for errors while running tests).
75
+ stack = originalStack
76
+ .split('\n')
77
+ .filter((line) => /^\s+at /.test(line) && !/\(node:|jest-runtime|jest-resolve/.test(line));
39
78
  // The user probably only cares about the error location in the original code,
40
- // so make it easier to see that.
41
- let utilsIndex = stack.findIndex((line) => line.includes('workerEntry.js'));
42
- if (utilsIndex !== -1) {
43
- stack = stack.slice(utilsIndex + 1);
79
+ // so make it easier to see that by removing all the esm-stub-utilities frames.
80
+ const workerEntryIndex = stack.findIndex((line) => line.includes(workerEntryName));
81
+ if (workerEntryIndex !== -1) {
82
+ // Special case: if the error came from the file calling process.exit(), the most recent stack
83
+ // frame will be from workerEntry.js, and the real frames will be after that.
84
+ stack = stack.slice(workerEntryIndex + 1);
44
85
  }
45
- else {
46
- // Remove the generateESMStubFromCJS frame and anything after it
47
- utilsIndex = stack.findIndex((line) => /generateESMStubFromCJS\.[jt]s\b/.test(line));
48
- if (utilsIndex !== -1) {
49
- stack = stack.slice(0, utilsIndex);
50
- }
51
- }
52
- if (!stack.length) {
53
- stack = undefined;
54
- if (code === errorCodes.requireESM) {
55
- // If we ended up with no stack besides the worker, this strongly implies that the file
56
- // itself is an ESM file, not a CommonJS file. We tried to check for this with detectModuleType,
57
- // but maybe it can fail sometimes.
58
- message =
59
- "It appears you're trying to create a stub of an ES module, which is not supported. " +
60
- 'You may need to add a cloudpack override to bundle this package with ori.';
61
- }
86
+ // Find the first esm-stub-utilities line and remove that and everything after.
87
+ const utilsIndex = stack.findIndex((line) => line.includes(esmPackageName));
88
+ if (utilsIndex !== -1) {
89
+ stack = stack.slice(0, utilsIndex);
62
90
  }
63
91
  }
64
- // Remove node internals from the stack, and jest stuff for errors while running tests
65
- const partialStack = stack?.filter((line) => !line.includes('(node:') && !line.includes('jest-runtime') && !line.includes('jest-resolve'));
66
- if (partialStack && partialStack.length > 1 && code !== errorCodes.moduleNotFound) {
92
+ // See if we can find the line and column in the entry file from the stack trace
93
+ const locationMatch = stack?.find((line) => slash(line).includes(slash(entryFullPath)))?.match(/:(\d+):(\d+)\)$/);
94
+ if (locationMatch) {
95
+ lineNumber = Number(locationMatch[1]);
96
+ columnNumber = Number(locationMatch[2]);
97
+ }
98
+ // Include the stack if present, provided it's not just the entry file,
99
+ // and this isn't a module not found error which already includes a require stack.
100
+ // (If the only interesting stack line is the entry file, this is redundant with the returned
101
+ // `location` object.)
102
+ if (stack?.length && (stack.length > 1 || !locationMatch) && code !== errorCodes.moduleNotFound) {
67
103
  // Add the stack to the message
68
- message += `\n\nPartial error stack (node internals omitted):\n${partialStack.join('\n')}`;
104
+ message += `\n\nPartial stack (node internals omitted):\n${stack.join('\n')}`;
69
105
  }
70
106
  return {
71
- text: `Error creating stub for entry "./${entryKey}": ${message}`,
72
- location: { file: slash(entryFullPath), line: 1, column: 0 },
107
+ text: `Error creating stub for entry "./${entryKey}":\n${message}`,
108
+ location: { file: slash(entryFullPath), line: lineNumber, column: columnNumber },
73
109
  };
74
110
  }
75
111
  //# sourceMappingURL=processError.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"processError.js","sourceRoot":"","sources":["../src/processError.ts"],"names":[],"mappings":"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","sourcesContent":["import type { BundleMessage } from '@ms-cloudpack/bundler-types';\nimport { slash } from '@ms-cloudpack/path-string-parsing';\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\n/**\n * Get info from an error which may be useful for debugging.\n */\nexport function processError(entryKey: string, entryFullPath: string, errorParam: unknown): BundleMessage {\n const error = (errorParam as Error).message ? (errorParam as Error) : { message: String(errorParam) };\n\n const {\n message: originalMessage,\n code,\n stack: originalStack,\n requireStack,\n } = error as Error & { code?: string; requireStack?: string[] };\n\n let message = originalMessage;\n 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 message = message.split('\\n')[0];\n } else if (code === errorCodes.moduleNotFound && requireStack) {\n // Module not found errors have a require stack included in the error message, as well as a\n // requireStack property. Remove the stack from the message and rebuild it with filtering.\n // Error: Cannot find module 'foo'\n // Require stack:\n // - [...]/index.js\n // - [...]/generateESMStubFromCJS.js\n message = message.split('\\n')[0];\n // remove the generateESMStubFromCJS require line (not interesting)\n const filteredStack = requireStack.filter((line) => !line.includes('generateESMStubFromCJS'));\n if (filteredStack.length > 1) {\n // Only include the stack if it goes beyond the original file\n message += `. Require stack:\\n${filteredStack.map((line) => ` ${line}`).join('\\n')}`;\n }\n }\n\n let stack: string[] | undefined;\n if (originalStack) {\n // Get stack frame lines from the original error stack\n stack = originalStack.split('\\n').filter((line) => /^\\s+at /.test(line));\n\n // The user probably only cares about the error location in the original code,\n // so make it easier to see that.\n let utilsIndex = stack.findIndex((line) => line.includes('workerEntry.js'));\n if (utilsIndex !== -1) {\n stack = stack.slice(utilsIndex + 1);\n } else {\n // Remove the generateESMStubFromCJS frame and anything after it\n utilsIndex = stack.findIndex((line) => /generateESMStubFromCJS\\.[jt]s\\b/.test(line));\n if (utilsIndex !== -1) {\n stack = stack.slice(0, utilsIndex);\n }\n }\n\n if (!stack.length) {\n stack = undefined;\n if (code === errorCodes.requireESM) {\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. We tried to check for this with detectModuleType,\n // but maybe it can fail sometimes.\n message =\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 }\n }\n }\n\n // Remove node internals from the stack, and jest stuff for errors while running tests\n const partialStack = stack?.filter(\n (line) => !line.includes('(node:') && !line.includes('jest-runtime') && !line.includes('jest-resolve'),\n );\n if (partialStack && partialStack.length > 1 && code !== errorCodes.moduleNotFound) {\n // Add the stack to the message\n message += `\\n\\nPartial error stack (node internals omitted):\\n${partialStack.join('\\n')}`;\n }\n\n return {\n text: `Error creating stub for entry \"./${entryKey}\": ${message}`,\n location: { file: slash(entryFullPath), line: 1, column: 0 },\n };\n}\n"]}
1
+ {"version":3,"file":"processError.js","sourceRoot":"","sources":["../src/processError.ts"],"names":[],"mappings":"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","sourcesContent":["import type { BundleMessage } from '@ms-cloudpack/bundler-types';\nimport { slash } from '@ms-cloudpack/path-string-parsing';\n\nexport type ErrorLike = { name?: string; message: string; stack?: string; code?: string; requireStack?: string[] };\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 esmPackageName = 'esm-stub-utilities';\nconst workerPackageName = 'worker-pool';\nconst workerEntryName = 'workerEntry.js';\n\n/**\n * Get info from an error which may be useful for debugging.\n */\nexport function processError(params: { entryKey: string; entryFullPath: string; error: unknown }): BundleMessage {\n const { entryKey, entryFullPath, error: errorParam } = params;\n const error = (errorParam as Error).message ? (errorParam as ErrorLike) : { message: String(errorParam) };\n\n const { message: originalMessage, name, code, stack: originalStack, requireStack } = error;\n\n let lineNumber = 1;\n let columnNumber = 0;\n let message = originalMessage;\n\n 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 message = message.split('\\n')[0];\n } else if (code === errorCodes.moduleNotFound && requireStack) {\n // Module not found errors have a require stack included in the error message, as well as a\n // requireStack property. Remove the stack from the message and rebuild it with filtering.\n // Error: Cannot find module 'foo'\n // Require stack:\n // - [...]/index.js\n // - [...]/generateESMStubFromCJS.js\n message = message.split('\\n')[0];\n // remove the generateESMStubFromCJS require line (not interesting)\n const filteredStack = requireStack.filter(\n (line) => !line.includes(esmPackageName) && !line.includes(workerPackageName),\n );\n if (filteredStack.length > 1) {\n // Only include the stack if it goes beyond the original file\n message += `.\\nRequire stack:\\n${filteredStack.map((line) => ` - ${line}`).join('\\n')}`;\n }\n } else if (name === 'SyntaxError' && originalStack) {\n // SyntaxErrors will have a `stack` like this:\n // /path/to/file.js:1\n // oh no\n // ^^\n // SyntaxError: Unexpected identifier\n // at ....\n // Use the first part as the message, but remove the stack trace (will be added back later if needed).\n message = originalStack.split(/\\n\\s+at /)[0];\n\n // If the error is in the entry point file, get the line and possibly column number.\n // (There won't be a stack line for the file with the syntax error, so the normal logic to get\n // the line and column later won't work.)\n const lineNumberMatch = message.match(/^(.*?):(\\d+)\\n/);\n if (lineNumberMatch && slash(lineNumberMatch[1]).includes(slash(entryFullPath))) {\n lineNumber = Number(lineNumberMatch[2]);\n\n // Get the column if the stack includes ^^ indicating the error location\n // (not all of them will have this, e.g. \"unexpected end of input\" errors won't)\n const columnNumberMatch = message.match(/^\\s*\\^/m);\n if (columnNumberMatch) {\n columnNumber = columnNumberMatch[0].length - 1;\n }\n }\n\n // This happens if a file is inferred from context or extension to be CJS but is actually ESM.\n if (/Unexpected token '(import|export)'/.test(message)) {\n message = `File appears to be an ES module that was loaded with require:\\n${message}`;\n }\n } else if (name !== 'Error') {\n message = `${name}: ${message}`;\n }\n\n let stack: string[] | undefined;\n if (originalStack) {\n // Get stack frame lines from the original error stack, and remove parts that are less likely\n // to be useful (node internals, and jest internals for errors while running tests).\n stack = originalStack\n .split('\\n')\n .filter((line) => /^\\s+at /.test(line) && !/\\(node:|jest-runtime|jest-resolve/.test(line));\n\n // The user probably only cares about the error location in the original code,\n // so make it easier to see that by removing all the esm-stub-utilities frames.\n const workerEntryIndex = stack.findIndex((line) => line.includes(workerEntryName));\n if (workerEntryIndex !== -1) {\n // Special case: if the error came from the file calling process.exit(), the most recent stack\n // frame will be from workerEntry.js, and the real frames will be after that.\n stack = stack.slice(workerEntryIndex + 1);\n }\n // Find the first esm-stub-utilities line and remove that and everything after.\n const utilsIndex = stack.findIndex((line) => line.includes(esmPackageName));\n if (utilsIndex !== -1) {\n stack = stack.slice(0, utilsIndex);\n }\n }\n\n // See if we can find the line and column in the entry file from the stack trace\n const locationMatch = stack?.find((line) => slash(line).includes(slash(entryFullPath)))?.match(/:(\\d+):(\\d+)\\)$/);\n if (locationMatch) {\n lineNumber = Number(locationMatch[1]);\n columnNumber = Number(locationMatch[2]);\n }\n\n // Include the stack if present, provided it's not just the entry file,\n // and this isn't a module not found error which already includes a require stack.\n // (If the only interesting stack line is the entry file, this is redundant with the returned\n // `location` object.)\n if (stack?.length && (stack.length > 1 || !locationMatch) && code !== errorCodes.moduleNotFound) {\n // Add the stack to the message\n message += `\\n\\nPartial stack (node internals omitted):\\n${stack.join('\\n')}`;\n }\n\n return {\n text: `Error creating stub for entry \"./${entryKey}\":\\n${message}`,\n location: { file: slash(entryFullPath), line: lineNumber, column: columnNumber },\n };\n}\n"]}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * FOR TESTING ONLY: Options for `_verifyStub`.
3
+ * @internal
4
+ */
5
+ export type _VerifyStubOptions = {
6
+ /** Text of the stub file. */
7
+ stub: string;
8
+ /** Path where the stub file should be written. */
9
+ stubPath: string;
10
+ /**
11
+ * Test function body which receives a parameter `moduleExports`.
12
+ * The result is not returned, but this can be used to verify that an expected API is available
13
+ * (code calling it doesn't throw) even if it doesn't show up in the named exports.
14
+ */
15
+ testCode?: string;
16
+ };
17
+ //# sourceMappingURL=VerifyStubOptions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VerifyStubOptions.d.ts","sourceRoot":"","sources":["../../src/types/VerifyStubOptions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAC;IAEb,kDAAkD;IAClD,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=VerifyStubOptions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VerifyStubOptions.js","sourceRoot":"","sources":["../../src/types/VerifyStubOptions.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * FOR TESTING ONLY: Options for `_verifyStub`.\n * @internal\n */\nexport type _VerifyStubOptions = {\n /** Text of the stub file. */\n stub: string;\n\n /** Path where the stub file should be written. */\n stubPath: string;\n\n /**\n * Test function body which receives a parameter `moduleExports`.\n * The result is not returned, but this can be used to verify that an expected API is available\n * (code calling it doesn't throw) even if it doesn't show up in the named exports.\n */\n testCode?: string;\n};\n"]}
@@ -3,5 +3,7 @@ export type WriteESMStubsOptions = {
3
3
  inputPath: string;
4
4
  /** An array of entry source paths. */
5
5
  entries: Record<string, string>;
6
+ /** Assume entries are CJS (for testing). */
7
+ forceCJS?: boolean;
6
8
  };
7
9
  //# sourceMappingURL=WriteESMStubsOptions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"WriteESMStubsOptions.d.ts","sourceRoot":"","sources":["../../src/types/WriteESMStubsOptions.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,oBAAoB,GAAG;IACjC,wCAAwC;IACxC,SAAS,EAAE,MAAM,CAAC;IAElB,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC,CAAC"}
1
+ {"version":3,"file":"WriteESMStubsOptions.d.ts","sourceRoot":"","sources":["../../src/types/WriteESMStubsOptions.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,oBAAoB,GAAG;IACjC,wCAAwC;IACxC,SAAS,EAAE,MAAM,CAAC;IAElB,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEhC,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"WriteESMStubsOptions.js","sourceRoot":"","sources":["../../src/types/WriteESMStubsOptions.ts"],"names":[],"mappings":"","sourcesContent":["export type WriteESMStubsOptions = {\n /** The absolute path to the package. */\n inputPath: string;\n\n /** An array of entry source paths. */\n entries: Record<string, string>;\n};\n"]}
1
+ {"version":3,"file":"WriteESMStubsOptions.js","sourceRoot":"","sources":["../../src/types/WriteESMStubsOptions.ts"],"names":[],"mappings":"","sourcesContent":["export type WriteESMStubsOptions = {\n /** The absolute path to the package. */\n inputPath: string;\n\n /** An array of entry source paths. */\n entries: Record<string, string>;\n\n /** Assume entries are CJS (for testing). */\n forceCJS?: boolean;\n};\n"]}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Request to `loadStubWorker.js`
3
+ */
4
+ export type LoadStubWorkerRequest = Pick<import('../types/VerifyStubOptions.js')._VerifyStubOptions, 'stubPath' | 'testCode'>;
5
+ /**
6
+ * Response from `loadStubWorker.js`.
7
+ * `value` is the IPC-friendly result of importing the module.
8
+ */
9
+ export type LoadStubWorkerResponse = {
10
+ value: unknown;
11
+ } | {
12
+ error: string;
13
+ };
14
+ //# sourceMappingURL=loadStubWorker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loadStubWorker.d.ts","sourceRoot":"","sources":["../../src/verifyStub/loadStubWorker.js"],"names":[],"mappings":";;;oCAca,KAAK,OAAO,+BAA+B,EAAE,kBAAkB,EAAE,UAAU,GAAG,UAAU,CAAC;;;;;qCAGzF;IAAE,KAAK,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE"}
@@ -1,14 +1,22 @@
1
+ //
2
+ //
3
+ // This worker is used in tests to verify that generated stub files can be imported,
4
+ // and that the results of importing are as expected.
5
+ //
6
+ // See verifyStub.ts for more about why this is needed.
7
+ //
8
+ //
1
9
  /* eslint-disable @typescript-eslint/no-unsafe-member-access */
2
10
  /* eslint-disable @typescript-eslint/no-unsafe-return */
3
11
  /* eslint-disable @typescript-eslint/no-unsafe-argument */
4
- // This file is used in tests to verify that a stub file can be imported in a Node environment
5
- // without interference from Jest's wrappers and transpilation.
6
12
  /**
7
- * @typedef {import('./tryImportStub.js').StubImportRequest} StubImportRequest
8
- * @typedef {import('./tryImportStub.js').StubImportResponse} StubImportResponse
13
+ * @typedef {Pick<import('../types/VerifyStubOptions.js')._VerifyStubOptions, 'stubPath' | 'testCode'>}
14
+ * LoadStubWorkerRequest Request to `loadStubWorker.js`
15
+ *
16
+ * @typedef {{ value: unknown } | { error: string }} LoadStubWorkerResponse Response from `loadStubWorker.js`.
17
+ * `value` is the IPC-friendly result of importing the module.
9
18
  */
10
19
  /** */
11
- import { format } from 'pretty-format';
12
20
  import v8 from 'v8';
13
21
  import { isMainThread, parentPort } from 'worker_threads';
14
22
  import { initBrowserEnvironment } from '../worker/initBrowserEnvironment.js';
@@ -21,16 +29,15 @@ await initBrowserEnvironment();
21
29
  const initialGlobalProperties = getGlobalProperties();
22
30
  /**
23
31
  * Type helper for sending messages to the parent.
24
- * @param {StubImportResponse} message
32
+ * @param {LoadStubWorkerResponse} message
25
33
  */
26
34
  function emitMessage(message) {
27
35
  parentPort?.postMessage(message);
28
36
  }
29
- parentPort.on('message', (/** @type {StubImportRequest} */ request) => {
37
+ parentPort.on('message', (/** @type {LoadStubWorkerRequest} */ request) => {
30
38
  if (typeof request.stubPath !== 'string') {
31
39
  emitMessage({
32
- type: 'error',
33
- message: `Unexpected request format: ${JSON.stringify(request)}`,
40
+ error: `Unexpected request format: ${JSON.stringify(request)}`,
34
41
  });
35
42
  }
36
43
  else {
@@ -39,13 +46,12 @@ parentPort.on('message', (/** @type {StubImportRequest} */ request) => {
39
46
  void tryImportStub(request);
40
47
  }
41
48
  });
42
- /** @param {StubImportRequest} request */
49
+ /** @param {LoadStubWorkerRequest} request */
43
50
  async function tryImportStub(request) {
44
51
  const { stubPath, testCode } = request;
45
52
  let moduleExports;
46
53
  let step = 'Import';
47
54
  try {
48
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
49
55
  moduleExports = await import(stubPath);
50
56
  step = 'Running test code';
51
57
  if (testCode) {
@@ -55,8 +61,7 @@ async function tryImportStub(request) {
55
61
  }
56
62
  catch (err) {
57
63
  emitMessage({
58
- type: 'error',
59
- message: `${step} failed: ${ /** @type {Error} */(err).stack || String(err)}`,
64
+ error: `${step} failed: ${ /** @type {Error} */(err).stack || String(err)}`,
60
65
  });
61
66
  return;
62
67
  }
@@ -64,24 +69,20 @@ async function tryImportStub(request) {
64
69
  cleanUpGlobals(initialGlobalProperties);
65
70
  }
66
71
  try {
67
- emitMessage({
68
- type: 'result',
69
- value: toSerializable(moduleExports),
70
- });
72
+ emitMessage({ value: serialize(moduleExports) });
71
73
  }
72
74
  catch (err) {
73
75
  emitMessage({
74
- type: 'error',
75
- message: `Error formatting or serializing exports: ${ /** @type {Error} */(err).stack || String(err)}`,
76
+ error: `Error formatting or serializing exports: ${ /** @type {Error} */(err).stack || String(err)}`,
76
77
  });
77
78
  }
78
79
  }
79
80
  /**
80
- * Convert a value into an IPC-serializable form.
81
+ * Convert a value into an IPC-serializable form, so it can be passed back to the test and verified.
81
82
  * @param {*} value
82
83
  * @returns {*}
83
84
  */
84
- function toSerializable(value, depth = 1, encountered = new WeakSet()) {
85
+ function serialize(value, depth = 1, encountered = new WeakSet()) {
85
86
  if (depth > 3) {
86
87
  return '...';
87
88
  }
@@ -91,15 +92,38 @@ function toSerializable(value, depth = 1, encountered = new WeakSet()) {
91
92
  return '[Circular]';
92
93
  }
93
94
  encountered.add(value);
95
+ // Convert non-serializable types
96
+ if (value instanceof Set) {
97
+ return `Set ${JSON.stringify([...value])}`;
98
+ }
99
+ if (value instanceof Map) {
100
+ return `Map ${JSON.stringify(Object.fromEntries(value))}`;
101
+ }
102
+ if (value instanceof Error) {
103
+ return `[${value.name}: ${value.message}]`;
104
+ }
105
+ if (value instanceof RegExp) {
106
+ return value.toString();
107
+ }
94
108
  if (Array.isArray(value)) {
95
- return value.map((v) => toSerializable(v, depth + 1, encountered));
109
+ return value.map((v) => serialize(v, depth + 1, encountered));
96
110
  }
97
111
  if (Object.keys(value).length || value.constructor?.name === 'Object') {
98
- return Object.fromEntries(Object.entries(value).map(([k, v]) => [k, toSerializable(v, depth + 1, encountered)]));
112
+ return Object.fromEntries(Object.entries(value).map(([k, v]) => [k, serialize(v, depth + 1, encountered)]));
113
+ }
114
+ if (value.constructor) {
115
+ return `[${value.constructor.name}]`;
99
116
  }
100
- // Always format other objects (even if they're serializable) to avoid comparison issues
101
- // in expect(...).toEqual() (like "TypeError: Method Map.prototype.entries called on incompatible receiver #<Map>")
102
- return formatValue(value);
117
+ if (value[Symbol.toStringTag] == 'Module') {
118
+ return '[empty module]';
119
+ }
120
+ }
121
+ if (typeof value === 'function') {
122
+ const properties = JSON.stringify({ ...value });
123
+ return `[Function ${value.name || '<anonymous>'}${properties === '{}' ? '' : ` ${properties}`}]`;
124
+ }
125
+ if (typeof value === 'symbol') {
126
+ return value.toString();
103
127
  }
104
128
  try {
105
129
  // try to serialize the same way postMessage does, per
@@ -109,14 +133,7 @@ function toSerializable(value, depth = 1, encountered = new WeakSet()) {
109
133
  }
110
134
  catch {
111
135
  // not serializable, so format the value instead
112
- return formatValue(value);
136
+ return JSON.stringify(value);
113
137
  }
114
138
  }
115
- /**
116
- * Pretty-format a value, removing newlines.
117
- * (`pretty-format` has a `min` option, but it removes additional detail which isn't desired.)
118
- */
119
- function formatValue(/** @type {*} */ value) {
120
- return format(value, {}).replace(/\n/g, '').replace(/\s+/g, ' ');
121
- }
122
139
  //# sourceMappingURL=loadStubWorker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loadStubWorker.js","sourceRoot":"","sources":["../../src/verifyStub/loadStubWorker.js"],"names":[],"mappings":"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","sourcesContent":["//\n//\n// This worker is used in tests to verify that generated stub files can be imported,\n// and that the results of importing are as expected.\n//\n// See verifyStub.ts for more about why this is needed.\n//\n//\n\n/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/no-unsafe-return */\n/* eslint-disable @typescript-eslint/no-unsafe-argument */\n\n/**\n * @typedef {Pick<import('../types/VerifyStubOptions.js')._VerifyStubOptions, 'stubPath' | 'testCode'>}\n * LoadStubWorkerRequest Request to `loadStubWorker.js`\n *\n * @typedef {{ value: unknown } | { error: string }} LoadStubWorkerResponse Response from `loadStubWorker.js`.\n * `value` is the IPC-friendly result of importing the module.\n */\n/** */\nimport v8 from 'v8';\nimport { isMainThread, parentPort } from 'worker_threads';\nimport { initBrowserEnvironment } from '../worker/initBrowserEnvironment.js';\nimport { cleanUpGlobals, getGlobalProperties } from '../worker/globals.js';\n\nif (isMainThread || !parentPort) {\n throw new Error('This file should only be loaded in a worker thread');\n}\n\n// These modules may expect a browser environment\nawait initBrowserEnvironment();\nconst initialGlobalProperties = getGlobalProperties();\n\n/**\n * Type helper for sending messages to the parent.\n * @param {LoadStubWorkerResponse} message\n */\nfunction emitMessage(message) {\n parentPort?.postMessage(message);\n}\n\nparentPort.on('message', (/** @type {LoadStubWorkerRequest} */ request) => {\n if (typeof request.stubPath !== 'string') {\n emitMessage({\n error: `Unexpected request format: ${JSON.stringify(request)}`,\n });\n } else {\n // Import the stub and send a reponse\n // (`void` ignores the promise result since callbacks can't be async)\n void tryImportStub(request);\n }\n});\n\n/** @param {LoadStubWorkerRequest} request */\nasync function tryImportStub(request) {\n const { stubPath, testCode } = request;\n let moduleExports;\n let step = 'Import';\n try {\n moduleExports = await import(stubPath);\n step = 'Running test code';\n if (testCode) {\n // eslint-disable-next-line @typescript-eslint/no-implied-eval\n new Function('moduleExports', testCode)(moduleExports);\n }\n } catch (err) {\n emitMessage({\n error: `${step} failed: ${/** @type {Error} */ (err).stack || String(err)}`,\n });\n return;\n } finally {\n cleanUpGlobals(initialGlobalProperties);\n }\n\n try {\n emitMessage({ value: serialize(moduleExports) });\n } catch (err) {\n emitMessage({\n error: `Error formatting or serializing exports: ${/** @type {Error} */ (err).stack || String(err)}`,\n });\n }\n}\n\n/**\n * Convert a value into an IPC-serializable form, so it can be passed back to the test and verified.\n * @param {*} value\n * @returns {*}\n */\nfunction serialize(value, depth = 1, encountered = new WeakSet()) {\n if (depth > 3) {\n return '...';\n }\n\n if (value && typeof value === 'object') {\n // track encountered objects to avoid entering circular references\n if (encountered.has(value)) {\n return '[Circular]';\n }\n encountered.add(value);\n\n // Convert non-serializable types\n if (value instanceof Set) {\n return `Set ${JSON.stringify([...value])}`;\n }\n if (value instanceof Map) {\n return `Map ${JSON.stringify(Object.fromEntries(value))}`;\n }\n if (value instanceof Error) {\n return `[${value.name}: ${value.message}]`;\n }\n if (value instanceof RegExp) {\n return value.toString();\n }\n if (Array.isArray(value)) {\n return value.map((v) => serialize(v, depth + 1, encountered));\n }\n if (Object.keys(value).length || value.constructor?.name === 'Object') {\n return Object.fromEntries(Object.entries(value).map(([k, v]) => [k, serialize(v, depth + 1, encountered)]));\n }\n if (value.constructor) {\n return `[${value.constructor.name}]`;\n }\n if (value[Symbol.toStringTag] == 'Module') {\n return '[empty module]';\n }\n }\n\n if (typeof value === 'function') {\n const properties = JSON.stringify({ ...value });\n return `[Function ${value.name || '<anonymous>'}${properties === '{}' ? '' : ` ${properties}`}]`;\n }\n\n if (typeof value === 'symbol') {\n return value.toString();\n }\n\n try {\n // try to serialize the same way postMessage does, per\n // https://nodejs.org/api/worker_threads.html#portpostmessagevalue-transferlist\n v8.serialize(value);\n return value;\n } catch {\n // not serializable, so format the value instead\n return JSON.stringify(value);\n }\n}\n"]}
@@ -0,0 +1,19 @@
1
+ import type { _VerifyStubOptions } from '../types/VerifyStubOptions.js';
2
+ /**
3
+ * FOR TESTING ONLY:
4
+ * Write a stub file (fixing paths for Windows) and try importing it in a worker,
5
+ * to verify that it's valid and returns the expected exports.
6
+ * @internal
7
+ */
8
+ export declare function _verifyStub(options: _VerifyStubOptions): Promise<{
9
+ /**
10
+ * The result of importing the stub in the worker (if successful), in IPC-friendly format.
11
+ * Any non-IPC-friendly values (such as functions) will be pretty-printed as strings.
12
+ */
13
+ value?: unknown;
14
+ /** Error if unsuccessful. */
15
+ error?: unknown;
16
+ /** Dispose the worker. Unless/until this is called, the same worker will be reused. */
17
+ dispose: () => Promise<void>;
18
+ }>;
19
+ //# sourceMappingURL=verifyStub.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verifyStub.d.ts","sourceRoot":"","sources":["../../src/verifyStub/verifyStub.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAQxE;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC;IACtE;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,6BAA6B;IAC7B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,uFAAuF;IACvF,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B,CAAC,CA0BD"}
@@ -0,0 +1,116 @@
1
+ //
2
+ //
3
+ // The utilities in this folder are used to verify that a generated stub file can be imported,
4
+ // and that the results of importing are as expected.
5
+ //
6
+ // Why must the stub file be loaded in a worker?
7
+ // - Ensure that the module is imported in a "vanilla" way, without interference from
8
+ // Jest's transpilation, custom module resolution, or environment.
9
+ // - Allow the module to run in a simulated browser environment if needed.
10
+ //
11
+ //
12
+ import fs from 'fs/promises';
13
+ import os from 'os';
14
+ import path from 'path';
15
+ import { fileURLToPath, pathToFileURL } from 'url';
16
+ import { Worker } from 'worker_threads';
17
+ const dirname = path.dirname(fileURLToPath(import.meta.url));
18
+ const loadStubWorkerPath = path.join(dirname, 'loadStubWorker.js');
19
+ let worker;
20
+ /**
21
+ * FOR TESTING ONLY:
22
+ * Write a stub file (fixing paths for Windows) and try importing it in a worker,
23
+ * to verify that it's valid and returns the expected exports.
24
+ * @internal
25
+ */
26
+ export async function _verifyStub(options) {
27
+ // Write the stub content to disk (fixing paths if needed)
28
+ await writeStubFile(options);
29
+ // Try to import the stub in a worker
30
+ worker = ensureWorker();
31
+ const stubImportRequest = {
32
+ stubPath: getStubImportPath(options.stubPath),
33
+ testCode: options.testCode,
34
+ };
35
+ return new Promise((resolve) => {
36
+ const onMessage = (response) => {
37
+ worker?.off('error', onError);
38
+ resolve({ ...response, dispose: disposeWorker });
39
+ };
40
+ // unhandled exception (not expected)
41
+ const onError = (err) => {
42
+ worker?.off('message', onMessage);
43
+ resolve({ error: err, dispose: disposeWorker });
44
+ };
45
+ worker?.once('message', onMessage);
46
+ worker?.once('error', onError);
47
+ worker?.postMessage(stubImportRequest);
48
+ });
49
+ }
50
+ async function writeStubFile(options) {
51
+ // Fix the stub content on Windows...
52
+ let stub = options.stub;
53
+ if (os.platform() === 'win32') {
54
+ // Node only supports Windows absolute paths as file:// URLs.
55
+ // Unfortunately, the bundlers don't like this syntax, so we don't put it in the stub by default.
56
+ // Convert any absolute paths here so that the worker is able to natively import the stub.
57
+ stub = stub.replace(/(?:from|import) "([^"]*?)";/g, (match, importPath) => {
58
+ if (path.isAbsolute(importPath)) {
59
+ return match.replace(importPath, pathToFileURL(importPath).href);
60
+ }
61
+ return match;
62
+ });
63
+ }
64
+ // Write the stub file
65
+ await fs.writeFile(options.stubPath, stub);
66
+ }
67
+ /** Get a stub import path that works for the current platform. */
68
+ function getStubImportPath(stubPath) {
69
+ if (os.platform() === 'win32' && path.isAbsolute(stubPath)) {
70
+ // Convert the path to a file:// URL so the import works on Windows
71
+ return pathToFileURL(stubPath).href;
72
+ }
73
+ return stubPath;
74
+ }
75
+ /**
76
+ * Initialize the worker used by `verifyStub`. For testing only.
77
+ *
78
+ * (The worker is reused between tests for now because it's expensive to set up and tear down;
79
+ * this can be changed later for certain tests if needed.)
80
+ */
81
+ function ensureWorker() {
82
+ if (worker)
83
+ return worker;
84
+ worker = new Worker(loadStubWorkerPath);
85
+ // An 'error' event from a worker means an unhandled exception and it's about to exit.
86
+ // Don't throw an error in this fallback handler in case the error occurred during a call
87
+ // to `verifyStub` (which has its own error handler that can fail the calling test),
88
+ // but save the error to be included in the 'exit' handler's error message.
89
+ let lastError;
90
+ worker.on('error', (err) => {
91
+ lastError = err;
92
+ });
93
+ worker.on('exit', (code) => {
94
+ throw new Error(lastError
95
+ ? `Worker exited due to an uncaught exception: ${lastError.stack}`
96
+ : `Worker exited unexpectedly with code ${code || 0}`);
97
+ });
98
+ return worker;
99
+ }
100
+ /**
101
+ * Stop the worker used by `verifyStub`.
102
+ */
103
+ async function disposeWorker() {
104
+ if (worker) {
105
+ // Remove all listeners so that the exit handler set up during initialization doesn't throw
106
+ worker.removeAllListeners();
107
+ try {
108
+ await worker.terminate();
109
+ }
110
+ catch {
111
+ // ignore
112
+ }
113
+ worker = undefined;
114
+ }
115
+ }
116
+ //# sourceMappingURL=verifyStub.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verifyStub.js","sourceRoot":"","sources":["../../src/verifyStub/verifyStub.ts"],"names":[],"mappings":"AAAA,EAAE;AACF,EAAE;AACF,8FAA8F;AAC9F,qDAAqD;AACrD,EAAE;AACF,gDAAgD;AAChD,qFAAqF;AACrF,oEAAoE;AACpE,0EAA0E;AAC1E,EAAE;AACF,EAAE;AAEF,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAIxC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC7D,MAAM,kBAAkB,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC;AAEnE,IAAI,MAA0B,CAAC;AAE/B;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAA2B;IAW3D,0DAA0D;IAC1D,MAAM,aAAa,CAAC,OAAO,CAAC,CAAC;IAE7B,qCAAqC;IACrC,MAAM,GAAG,YAAY,EAAE,CAAC;IACxB,MAAM,iBAAiB,GAA0B;QAC/C,QAAQ,EAAE,iBAAiB,CAAC,OAAO,CAAC,QAAQ,CAAC;QAC7C,QAAQ,EAAE,OAAO,CAAC,QAAQ;KAC3B,CAAC;IAEF,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,SAAS,GAAG,CAAC,QAAgC,EAAE,EAAE;YACrD,MAAM,EAAE,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC9B,OAAO,CAAC,EAAE,GAAG,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC,CAAC;QACnD,CAAC,CAAC;QACF,qCAAqC;QACrC,MAAM,OAAO,GAAG,CAAC,GAAU,EAAE,EAAE;YAC7B,MAAM,EAAE,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;YAClC,OAAO,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC,CAAC;QAClD,CAAC,CAAC;QACF,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QACnC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAE/B,MAAM,EAAE,WAAW,CAAC,iBAAiB,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,OAA2B;IACtD,qCAAqC;IACrC,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IACxB,IAAI,EAAE,CAAC,QAAQ,EAAE,KAAK,OAAO,EAAE,CAAC;QAC9B,6DAA6D;QAC7D,iGAAiG;QACjG,0FAA0F;QAC1F,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,8BAA8B,EAAE,CAAC,KAAK,EAAE,UAAkB,EAAE,EAAE;YAChF,IAAI,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;gBAChC,OAAO,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC;YACnE,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC,CAAC,CAAC;IACL,CAAC;IAED,sBAAsB;IACtB,MAAM,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AAC7C,CAAC;AAED,kEAAkE;AAClE,SAAS,iBAAiB,CAAC,QAAgB;IACzC,IAAI,EAAE,CAAC,QAAQ,EAAE,KAAK,OAAO,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3D,mEAAmE;QACnE,OAAO,aAAa,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC;IACtC,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;GAKG;AACH,SAAS,YAAY;IACnB,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAE1B,MAAM,GAAG,IAAI,MAAM,CAAC,kBAAkB,CAAC,CAAC;IAExC,sFAAsF;IACtF,yFAAyF;IACzF,oFAAoF;IACpF,2EAA2E;IAC3E,IAAI,SAA4B,CAAC;IACjC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;QACzB,SAAS,GAAG,GAAG,CAAC;IAClB,CAAC,CAAC,CAAC;IACH,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;QACzB,MAAM,IAAI,KAAK,CACb,SAAS;YACP,CAAC,CAAC,+CAA+C,SAAS,CAAC,KAAK,EAAE;YAClE,CAAC,CAAC,wCAAwC,IAAI,IAAI,CAAC,EAAE,CACxD,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,aAAa;IAC1B,IAAI,MAAM,EAAE,CAAC;QACX,2FAA2F;QAC3F,MAAM,CAAC,kBAAkB,EAAE,CAAC;QAC5B,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,SAAS,EAAE,CAAC;QAC3B,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QACD,MAAM,GAAG,SAAS,CAAC;IACrB,CAAC;AACH,CAAC","sourcesContent":["//\n//\n// The utilities in this folder are used to verify that a generated stub file can be imported,\n// and that the results of importing are as expected.\n//\n// Why must the stub file be loaded in a worker?\n// - Ensure that the module is imported in a \"vanilla\" way, without interference from\n// Jest's transpilation, custom module resolution, or environment.\n// - Allow the module to run in a simulated browser environment if needed.\n//\n//\n\nimport fs from 'fs/promises';\nimport os from 'os';\nimport path from 'path';\nimport { fileURLToPath, pathToFileURL } from 'url';\nimport { Worker } from 'worker_threads';\nimport type { _VerifyStubOptions } from '../types/VerifyStubOptions.js';\nimport type { LoadStubWorkerRequest, LoadStubWorkerResponse } from './loadStubWorker.js';\n\nconst dirname = path.dirname(fileURLToPath(import.meta.url));\nconst loadStubWorkerPath = path.join(dirname, 'loadStubWorker.js');\n\nlet worker: Worker | undefined;\n\n/**\n * FOR TESTING ONLY:\n * Write a stub file (fixing paths for Windows) and try importing it in a worker,\n * to verify that it's valid and returns the expected exports.\n * @internal\n */\nexport async function _verifyStub(options: _VerifyStubOptions): Promise<{\n /**\n * The result of importing the stub in the worker (if successful), in IPC-friendly format.\n * Any non-IPC-friendly values (such as functions) will be pretty-printed as strings.\n */\n value?: unknown;\n /** Error if unsuccessful. */\n error?: unknown;\n /** Dispose the worker. Unless/until this is called, the same worker will be reused. */\n dispose: () => Promise<void>;\n}> {\n // Write the stub content to disk (fixing paths if needed)\n await writeStubFile(options);\n\n // Try to import the stub in a worker\n worker = ensureWorker();\n const stubImportRequest: LoadStubWorkerRequest = {\n stubPath: getStubImportPath(options.stubPath),\n testCode: options.testCode,\n };\n\n return new Promise((resolve) => {\n const onMessage = (response: LoadStubWorkerResponse) => {\n worker?.off('error', onError);\n resolve({ ...response, dispose: disposeWorker });\n };\n // unhandled exception (not expected)\n const onError = (err: Error) => {\n worker?.off('message', onMessage);\n resolve({ error: err, dispose: disposeWorker });\n };\n worker?.once('message', onMessage);\n worker?.once('error', onError);\n\n worker?.postMessage(stubImportRequest);\n });\n}\n\nasync function writeStubFile(options: _VerifyStubOptions) {\n // Fix the stub content on Windows...\n let stub = options.stub;\n if (os.platform() === 'win32') {\n // Node only supports Windows absolute paths as file:// URLs.\n // Unfortunately, the bundlers don't like this syntax, so we don't put it in the stub by default.\n // Convert any absolute paths here so that the worker is able to natively import the stub.\n stub = stub.replace(/(?:from|import) \"([^\"]*?)\";/g, (match, importPath: string) => {\n if (path.isAbsolute(importPath)) {\n return match.replace(importPath, pathToFileURL(importPath).href);\n }\n return match;\n });\n }\n\n // Write the stub file\n await fs.writeFile(options.stubPath, stub);\n}\n\n/** Get a stub import path that works for the current platform. */\nfunction getStubImportPath(stubPath: string): string {\n if (os.platform() === 'win32' && path.isAbsolute(stubPath)) {\n // Convert the path to a file:// URL so the import works on Windows\n return pathToFileURL(stubPath).href;\n }\n return stubPath;\n}\n\n/**\n * Initialize the worker used by `verifyStub`. For testing only.\n *\n * (The worker is reused between tests for now because it's expensive to set up and tear down;\n * this can be changed later for certain tests if needed.)\n */\nfunction ensureWorker(): Worker {\n if (worker) return worker;\n\n worker = new Worker(loadStubWorkerPath);\n\n // An 'error' event from a worker means an unhandled exception and it's about to exit.\n // Don't throw an error in this fallback handler in case the error occurred during a call\n // to `verifyStub` (which has its own error handler that can fail the calling test),\n // but save the error to be included in the 'exit' handler's error message.\n let lastError: Error | undefined;\n worker.on('error', (err) => {\n lastError = err;\n });\n worker.on('exit', (code) => {\n throw new Error(\n lastError\n ? `Worker exited due to an uncaught exception: ${lastError.stack}`\n : `Worker exited unexpectedly with code ${code || 0}`,\n );\n });\n\n return worker;\n}\n\n/**\n * Stop the worker used by `verifyStub`.\n */\nasync function disposeWorker() {\n if (worker) {\n // Remove all listeners so that the exit handler set up during initialization doesn't throw\n worker.removeAllListeners();\n try {\n await worker.terminate();\n } catch {\n // ignore\n }\n worker = undefined;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"globals.d.ts","sourceRoot":"","sources":["../../src/worker/globals.js"],"names":[],"mappings":"AAEA,gEAAgE;AAChE,gDAEC;AAED;;;GAGG;AACH,wDAFW,MAAM,EAAE,QAYlB"}
1
+ {"version":3,"file":"globals.d.ts","sourceRoot":"","sources":["../../src/worker/globals.js"],"names":[],"mappings":"AAKA,gEAAgE;AAChE,gDAEC;AAED;;;GAGG;AACH,wDAFW,MAAM,EAAE,QAYlB"}
@@ -1,4 +1,7 @@
1
- // This file is JS because it's also used in a test worker (see testWorker/verifyStub.ts).
1
+ //
2
+ // This file is JS because it's also used in a test worker within this package.
3
+ // See verifyStub/loadStubWorker.js for more details.
4
+ //
2
5
  /** Get all property descriptor names from the global object. */
3
6
  export function getGlobalProperties() {
4
7
  return Object.keys(Object.getOwnPropertyDescriptors(global));
@@ -1 +1 @@
1
- {"version":3,"file":"globals.js","sourceRoot":"","sources":["../../src/worker/globals.js"],"names":[],"mappings":"AAAA,0FAA0F;AAE1F,gEAAgE;AAChE,MAAM,UAAU,mBAAmB;IACjC,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,yBAAyB,CAAC,MAAM,CAAC,CAAC,CAAC;AAC/D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,uBAAuB;IACpD,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,yBAAyB,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE;QAC7E,IAAI,CAAC,uBAAuB,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YAC9D,IAAI,CAAC;gBACH,OAAO,EAAC,gBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACxC,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["// This file is JS because it's also used in a test worker (see testWorker/verifyStub.ts).\n\n/** Get all property descriptor names from the global object. */\nexport function getGlobalProperties() {\n return Object.keys(Object.getOwnPropertyDescriptors(global));\n}\n\n/**\n * Delete any new properties from the global object.\n * @param {string[]} initialGlobalProperties\n */\nexport function cleanUpGlobals(initialGlobalProperties) {\n Object.entries(Object.getOwnPropertyDescriptors(global)).forEach(([k, desc]) => {\n if (!initialGlobalProperties.includes(k) && desc.configurable) {\n try {\n delete (/** @type {*} */ (global)[k]);\n } catch {\n // ignore\n }\n }\n });\n}\n"]}
1
+ {"version":3,"file":"globals.js","sourceRoot":"","sources":["../../src/worker/globals.js"],"names":[],"mappings":"AAAA,EAAE;AACF,+EAA+E;AAC/E,qDAAqD;AACrD,EAAE;AAEF,gEAAgE;AAChE,MAAM,UAAU,mBAAmB;IACjC,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,yBAAyB,CAAC,MAAM,CAAC,CAAC,CAAC;AAC/D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,uBAAuB;IACpD,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,yBAAyB,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE;QAC7E,IAAI,CAAC,uBAAuB,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YAC9D,IAAI,CAAC;gBACH,OAAO,EAAC,gBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACxC,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["//\n// This file is JS because it's also used in a test worker within this package.\n// See verifyStub/loadStubWorker.js for more details.\n//\n\n/** Get all property descriptor names from the global object. */\nexport function getGlobalProperties() {\n return Object.keys(Object.getOwnPropertyDescriptors(global));\n}\n\n/**\n * Delete any new properties from the global object.\n * @param {string[]} initialGlobalProperties\n */\nexport function cleanUpGlobals(initialGlobalProperties) {\n Object.entries(Object.getOwnPropertyDescriptors(global)).forEach(([k, desc]) => {\n if (!initialGlobalProperties.includes(k) && desc.configurable) {\n try {\n delete (/** @type {*} */ (global)[k]);\n } catch {\n // ignore\n }\n }\n });\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"initBrowserEnvironment.d.ts","sourceRoot":"","sources":["../../src/worker/initBrowserEnvironment.js"],"names":[],"mappings":"AAKA;;GAEG;AACH,wDAuEC"}
1
+ {"version":3,"file":"initBrowserEnvironment.d.ts","sourceRoot":"","sources":["../../src/worker/initBrowserEnvironment.js"],"names":[],"mappings":"AAQA;;GAEG;AACH,wDAuEC"}
@@ -1,4 +1,7 @@
1
- // This file is JS because it's used in a worker (see workerEntry.js).
1
+ //
2
+ // This file is JS because it's also used in a test worker within this package.
3
+ // See verifyStub/loadStubWorker.js for more details.
4
+ //
2
5
  import { performance } from 'perf_hooks';
3
6
  import util from 'util';
4
7
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"initBrowserEnvironment.js","sourceRoot":"","sources":["../../src/worker/initBrowserEnvironment.js"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB;IAC1C,oCAAoC;IACpC,MAAM,CAAC,WAAW,KAAK,gBAAgB,CAAC,CAAC,WAAW,CAAC,CAAC;IACtD,MAAM,CAAC,WAAW,KAAK,IAAI,CAAC,WAAW,CAAC;IACxC,MAAM,CAAC,WAAW,KAAK,gBAAgB,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAE3D,CAAC,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;IAEzC,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAC;IAEpC,iGAAiG;IACjG,8FAA8F;IAC9F,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,yBAAyB,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE;QAC7E,kFAAkF;QAClF,6FAA6F;QAC7F,4FAA4F;QAC5F,0CAA0C;QAC1C,IAAI,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;YACtE,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;QACzC,CAAC;IACH,CAAC,CAAC,CAAC;IACH,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,MAAM,CAAC;IAC1C,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,GAAG,MAAM,CAAC;IACxC,gBAAgB,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,GAAG,MAAM,CAAC;IAE5C,MAAM,CAAC,qBAAqB,GAAG,MAAM,CAAC,UAAU,CAAC;IACjD,MAAM,CAAC,oBAAoB,GAAG,MAAM,CAAC,YAAY,CAAC;IAClD,MAAM,CAAC,IAAI,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACrE,MAAM,CAAC,IAAI,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAErE,2DAA2D;IAC3D,mEAAmE;IACnE,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,GAAG,gBAAgB,CAAC,CAAC,MAAM,SAAS;KAAG,CAAC,CAAC;IAE5E,gFAAgF;IAChF,MAAM,CAAC,cAAc,GAAG,MAAM,CAAC,cAAc,GAAG,MAAM,cAAc;QAApB;YAC9C,UAAK,GAAoB,CAAC,EAAE,CAAC,CAAC;YAC9B,UAAK,GAAoB,CAAC,EAAE,CAAC,CAAC;QAChC,CAAC;KAAA,CAAC;IAEF,kCAAkC;IAClC,MAAM,CAAC,gBAAgB,GAAG,MAAM,CAAC,gBAAgB,GAAG,QAAQ,CAAC,gBAAgB,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;IACzF,MAAM,CAAC,mBAAmB,GAAG,MAAM,CAAC,mBAAmB,GAAG,QAAQ,CAAC,mBAAmB,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;IAClG,MAAM,CAAC,aAAa,GAAG,MAAM,CAAC,aAAa,GAAG,QAAQ,CAAC,aAAa,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC;IAEnF,mBAAmB;IACnB,6CAA6C;IAC7C,MAAM,aAAa,GAAG,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC1E,MAAM,iBAAiB,GAAG,CAAC,qBAAqB,CAAC,OAAO,EAAE,qCAAqC,CAAC,OAAO,EAAE,EAAE;QACzG,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;YACzB,OAAO,gBAAgB,CAAC,CAAC;gBACvB,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,CAAC;gBAC1C,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC;aACxB,CAAC,CAAC;QACL,CAAC;QAED,OAAO,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;IAClE,CAAC,CAAC;IACF,6CAA6C;IAC7C,MAAM,CAAC,QAAQ,CAAC,aAAa;QAC3B,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa;YACvC,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa;gBACrC,iBAAiB,CAAC;IAEtB,MAAM,CAAC,KAAK,GAAG,gBAAgB,CAAC,CAAC,KAAK,IAAI,EAAE,GAAE,CAAC,CAAC,CAAC;IAEjD,wDAAwD;IACxD,OAAO,CAAC,GAAG,CAAC,YAAY,GAAG,GAAG,CAAC;IAE/B,mFAAmF;IACnF,gBAAgB,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC;AAC5C,CAAC","sourcesContent":["// This file is JS because it's used in a worker (see workerEntry.js).\n\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 ??= /** @type {*} */ (performance);\n global.TextEncoder ??= util.TextEncoder;\n 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 = (str) => Buffer.from(str, 'binary').toString('base64');\n global.atob = (str) => Buffer.from(str, 'base64').toString('binary');\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 // Prevent adding event listeners.\n global.addEventListener = window.addEventListener = document.addEventListener = () => {};\n global.removeEventListener = window.removeEventListener = document.removeEventListener = () => {};\n global.dispatchEvent = window.dispatchEvent = document.dispatchEvent = () => false;\n\n // Mock out canvas.\n // eslint-disable-next-line etc/no-deprecated\n const createElement = window.document.createElement.bind(window.document);\n const createElementMock = (/** @type {string} */ tagName, /** @type {ElementCreationOptions} */ options) => {\n if (tagName === 'canvas') {\n return /** @type {*} */ ({\n getContext: () => ({ fillRect: () => {} }),\n measureText: () => ({}),\n });\n }\n\n return createElement.apply(window.document, [tagName, options]);\n };\n // eslint-disable-next-line etc/no-deprecated\n global.document.createElement =\n /** @type {*} */ (window).createElement =\n /** @type {*} */ (global).createElement =\n createElementMock;\n\n window.fetch = /** @type {*} */ (async () => {});\n\n // prevent 'debug' package from accessing process.stderr\n process.env.DEBUG_COLORS = '0';\n\n // Some packages like readable-stream@2.3.7 read process.browser to avoid node code\n /** @type {*} */ (process).browser = true;\n}\n"]}
1
+ {"version":3,"file":"initBrowserEnvironment.js","sourceRoot":"","sources":["../../src/worker/initBrowserEnvironment.js"],"names":[],"mappings":"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","sourcesContent":["//\n// This file is JS because it's also used in a test worker within this package.\n// See verifyStub/loadStubWorker.js for more details.\n//\n\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 ??= /** @type {*} */ (performance);\n global.TextEncoder ??= util.TextEncoder;\n 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 = (str) => Buffer.from(str, 'binary').toString('base64');\n global.atob = (str) => Buffer.from(str, 'base64').toString('binary');\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 // Prevent adding event listeners.\n global.addEventListener = window.addEventListener = document.addEventListener = () => {};\n global.removeEventListener = window.removeEventListener = document.removeEventListener = () => {};\n global.dispatchEvent = window.dispatchEvent = document.dispatchEvent = () => false;\n\n // Mock out canvas.\n // eslint-disable-next-line etc/no-deprecated\n const createElement = window.document.createElement.bind(window.document);\n const createElementMock = (/** @type {string} */ tagName, /** @type {ElementCreationOptions} */ options) => {\n if (tagName === 'canvas') {\n return /** @type {*} */ ({\n getContext: () => ({ fillRect: () => {} }),\n measureText: () => ({}),\n });\n }\n\n return createElement.apply(window.document, [tagName, options]);\n };\n // eslint-disable-next-line etc/no-deprecated\n global.document.createElement =\n /** @type {*} */ (window).createElement =\n /** @type {*} */ (global).createElement =\n createElementMock;\n\n window.fetch = /** @type {*} */ (async () => {});\n\n // prevent 'debug' package from accessing process.stderr\n process.env.DEBUG_COLORS = '0';\n\n // Some packages like readable-stream@2.3.7 read process.browser to avoid node code\n /** @type {*} */ (process).browser = true;\n}\n"]}
@@ -10,7 +10,7 @@ import { processError } from './processError.js';
10
10
  * If any files doesn't need a stub, the returned entry will use the original path.
11
11
  */
12
12
  export async function writeESMStubs(options) {
13
- const { inputPath, entries } = options;
13
+ const { inputPath, entries, forceCJS } = options;
14
14
  const result = {
15
15
  newEntries: {},
16
16
  errors: [],
@@ -19,7 +19,7 @@ export async function writeESMStubs(options) {
19
19
  const filePath = slash(path.join(inputPath, entryPath));
20
20
  const safeEntryKey = stripLeadingRelativePath(entryKey);
21
21
  try {
22
- const stubPath = await getStubPath({ inputPath, entryPath });
22
+ const stubPath = await getStubPath({ inputPath, entryPath, forceCJS });
23
23
  if (!stubPath) {
24
24
  // Stub not needed
25
25
  result.newEntries[safeEntryKey] = path.join(inputPath, entryPath);
@@ -39,7 +39,7 @@ export async function writeESMStubs(options) {
39
39
  catch (e) {
40
40
  const entryFullPath = path.join(inputPath, entryPath);
41
41
  result.newEntries[safeEntryKey] = entryFullPath;
42
- result.errors.push(processError(safeEntryKey, entryFullPath, e));
42
+ result.errors.push(processError({ entryKey: safeEntryKey, entryFullPath, error: e }));
43
43
  }
44
44
  }
45
45
  return result;
@@ -1 +1 @@
1
- {"version":3,"file":"writeESMStubs.js","sourceRoot":"","sources":["../src/writeESMStubs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,mCAAmC,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,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,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAIjD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAA6B;IAC/D,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IACvC,MAAM,MAAM,GAAwB;QAClC,UAAU,EAAE,EAAE;QACd,MAAM,EAAE,EAAE;KACX,CAAC;IAEF,KAAK,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5D,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC;QACxD,MAAM,YAAY,GAAG,wBAAwB,CAAC,QAAQ,CAAC,CAAC;QAExD,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC;YAC7D,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,kBAAkB;gBAClB,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;gBAClE,SAAS;YACX,CAAC;YAED,IAAI,WAAW,GAAW,EAAE,CAAC;YAC7B,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,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;YAC/D,CAAC;YAED,+BAA+B;YAC/B,MAAM,SAAS,CAAC,QAAQ,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;YAEhD,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC,GAAG,QAAQ,CAAC;QAC7C,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;YACtD,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC,GAAG,aAAa,CAAC;YAChD,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,CAAC;QACnE,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,wBAAwB,CAAC,YAAoB;IACpD,OAAO,YAAY,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AAC3C,CAAC","sourcesContent":["import { slash } from '@ms-cloudpack/path-string-parsing';\nimport { writeFile } from 'fs/promises';\nimport path from 'path';\nimport { generateESMStubFromCJS } from './generateESMStubFromCJS.js';\nimport { generateESMStubFromJSON } from './generateESMStubFromJSON.js';\nimport { getStubPath } from './getStubPath.js';\nimport { processError } from './processError.js';\nimport type { WriteESMStubsOptions } from './types/WriteESMStubsOptions.js';\nimport type { WriteESMStubsResult } from './types/WriteESMStubsResult.js';\n\n/**\n * Generates a set of ESM stubs for given entries and writes it to disk.\n * If any files doesn't need a stub, the returned entry will use the original path.\n */\nexport async function writeESMStubs(options: WriteESMStubsOptions): Promise<WriteESMStubsResult> {\n const { inputPath, entries } = options;\n const result: WriteESMStubsResult = {\n newEntries: {},\n errors: [],\n };\n\n for (const [entryKey, entryPath] of Object.entries(entries)) {\n const filePath = slash(path.join(inputPath, entryPath));\n const safeEntryKey = stripLeadingRelativePath(entryKey);\n\n try {\n const stubPath = await getStubPath({ inputPath, entryPath });\n if (!stubPath) {\n // Stub not needed\n result.newEntries[safeEntryKey] = path.join(inputPath, entryPath);\n continue;\n }\n\n let stubContent: string = '';\n if (path.extname(entryPath).toLowerCase() === '.json') {\n stubContent = await generateESMStubFromJSON({ filePath });\n } else {\n stubContent = generateESMStubFromCJS({ filePath, stubPath });\n }\n\n // Attempt to write it to disk.\n await writeFile(stubPath, stubContent, 'utf-8');\n\n result.newEntries[safeEntryKey] = stubPath;\n } catch (e) {\n const entryFullPath = path.join(inputPath, entryPath);\n result.newEntries[safeEntryKey] = entryFullPath;\n result.errors.push(processError(safeEntryKey, entryFullPath, e));\n }\n }\n\n return result;\n}\n\nfunction stripLeadingRelativePath(relativePath: string) {\n return relativePath.replace(/^\\.\\//, '');\n}\n"]}
1
+ {"version":3,"file":"writeESMStubs.js","sourceRoot":"","sources":["../src/writeESMStubs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,mCAAmC,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,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,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAIjD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAA6B;IAC/D,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IACjD,MAAM,MAAM,GAAwB;QAClC,UAAU,EAAE,EAAE;QACd,MAAM,EAAE,EAAE;KACX,CAAC;IAEF,KAAK,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5D,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC;QACxD,MAAM,YAAY,GAAG,wBAAwB,CAAC,QAAQ,CAAC,CAAC;QAExD,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;YACvE,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,kBAAkB;gBAClB,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;gBAClE,SAAS;YACX,CAAC;YAED,IAAI,WAAW,GAAW,EAAE,CAAC;YAC7B,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,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;YAC/D,CAAC;YAED,+BAA+B;YAC/B,MAAM,SAAS,CAAC,QAAQ,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;YAEhD,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC,GAAG,QAAQ,CAAC;QAC7C,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;YACtD,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC,GAAG,aAAa,CAAC;YAChD,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QACxF,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,wBAAwB,CAAC,YAAoB;IACpD,OAAO,YAAY,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AAC3C,CAAC","sourcesContent":["import { slash } from '@ms-cloudpack/path-string-parsing';\nimport { writeFile } from 'fs/promises';\nimport path from 'path';\nimport { generateESMStubFromCJS } from './generateESMStubFromCJS.js';\nimport { generateESMStubFromJSON } from './generateESMStubFromJSON.js';\nimport { getStubPath } from './getStubPath.js';\nimport { processError } from './processError.js';\nimport type { WriteESMStubsOptions } from './types/WriteESMStubsOptions.js';\nimport type { WriteESMStubsResult } from './types/WriteESMStubsResult.js';\n\n/**\n * Generates a set of ESM stubs for given entries and writes it to disk.\n * If any files doesn't need a stub, the returned entry will use the original path.\n */\nexport async function writeESMStubs(options: WriteESMStubsOptions): Promise<WriteESMStubsResult> {\n const { inputPath, entries, forceCJS } = options;\n const result: WriteESMStubsResult = {\n newEntries: {},\n errors: [],\n };\n\n for (const [entryKey, entryPath] of Object.entries(entries)) {\n const filePath = slash(path.join(inputPath, entryPath));\n const safeEntryKey = stripLeadingRelativePath(entryKey);\n\n try {\n const stubPath = await getStubPath({ inputPath, entryPath, forceCJS });\n if (!stubPath) {\n // Stub not needed\n result.newEntries[safeEntryKey] = path.join(inputPath, entryPath);\n continue;\n }\n\n let stubContent: string = '';\n if (path.extname(entryPath).toLowerCase() === '.json') {\n stubContent = await generateESMStubFromJSON({ filePath });\n } else {\n stubContent = generateESMStubFromCJS({ filePath, stubPath });\n }\n\n // Attempt to write it to disk.\n await writeFile(stubPath, stubContent, 'utf-8');\n\n result.newEntries[safeEntryKey] = stubPath;\n } catch (e) {\n const entryFullPath = path.join(inputPath, entryPath);\n result.newEntries[safeEntryKey] = entryFullPath;\n result.errors.push(processError({ entryKey: safeEntryKey, entryFullPath, error: e }));\n }\n }\n\n return result;\n}\n\nfunction stripLeadingRelativePath(relativePath: string) {\n return relativePath.replace(/^\\.\\//, '');\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ms-cloudpack/esm-stub-utilities",
3
- "version": "0.10.2",
3
+ "version": "0.10.3",
4
4
  "description": "Generates ESM stubs for CommonJS entry files.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -19,10 +19,10 @@
19
19
  }
20
20
  },
21
21
  "dependencies": {
22
- "@ms-cloudpack/bundler-types": "^0.24.2",
22
+ "@ms-cloudpack/bundler-types": "^0.24.3",
23
23
  "@ms-cloudpack/json-utilities": "^0.1.4",
24
24
  "@ms-cloudpack/path-string-parsing": "^1.1.3",
25
- "@ms-cloudpack/package-utilities": "^5.10.2",
25
+ "@ms-cloudpack/package-utilities": "^5.10.3",
26
26
  "@ms-cloudpack/worker-pool": "^0.1.1",
27
27
  "jsdom-global": "^3.0.2",
28
28
  "jsdom": "^22.0.0",
@@ -33,9 +33,7 @@
33
33
  "@ms-cloudpack/scripts": "*",
34
34
  "@ms-cloudpack/test-utilities": "*",
35
35
  "@types/jsdom": "^21.1.1",
36
- "@types/regenerator-runtime": "^0.13.1",
37
- "lodash": "^4.17.21",
38
- "pretty-format": "^30.0.0-alpha.1"
36
+ "@types/regenerator-runtime": "^0.13.1"
39
37
  },
40
38
  "scripts": {
41
39
  "api": "cloudpack-scripts api",
@@ -1,3 +0,0 @@
1
- export type StubImportRequest = import('./tryImportStub.js').StubImportRequest;
2
- export type StubImportResponse = import('./tryImportStub.js').StubImportResponse;
3
- //# sourceMappingURL=loadStubWorker.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"loadStubWorker.d.ts","sourceRoot":"","sources":["../../src/__fixtures__/loadStubWorker.js"],"names":[],"mappings":"gCAQa,OAAO,oBAAoB,EAAE,iBAAiB;iCAC9C,OAAO,oBAAoB,EAAE,kBAAkB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"loadStubWorker.js","sourceRoot":"","sources":["../../src/__fixtures__/loadStubWorker.js"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/no-unsafe-return */\n/* eslint-disable @typescript-eslint/no-unsafe-argument */\n\n// This file is used in tests to verify that a stub file can be imported in a Node environment\n// without interference from Jest's wrappers and transpilation.\n\n/**\n * @typedef {import('./tryImportStub.js').StubImportRequest} StubImportRequest\n * @typedef {import('./tryImportStub.js').StubImportResponse} StubImportResponse\n */\n/** */\nimport { format } from 'pretty-format';\nimport v8 from 'v8';\nimport { isMainThread, parentPort } from 'worker_threads';\nimport { initBrowserEnvironment } from '../worker/initBrowserEnvironment.js';\nimport { cleanUpGlobals, getGlobalProperties } from '../worker/globals.js';\n\nif (isMainThread || !parentPort) {\n throw new Error('This file should only be loaded in a worker thread');\n}\n\n// These modules may expect a browser environment\nawait initBrowserEnvironment();\nconst initialGlobalProperties = getGlobalProperties();\n\n/**\n * Type helper for sending messages to the parent.\n * @param {StubImportResponse} message\n */\nfunction emitMessage(message) {\n parentPort?.postMessage(message);\n}\n\nparentPort.on('message', (/** @type {StubImportRequest} */ request) => {\n if (typeof request.stubPath !== 'string') {\n emitMessage({\n type: 'error',\n message: `Unexpected request format: ${JSON.stringify(request)}`,\n });\n } else {\n // Import the stub and send a reponse\n // (`void` ignores the promise result since callbacks can't be async)\n void tryImportStub(request);\n }\n});\n\n/** @param {StubImportRequest} request */\nasync function tryImportStub(request) {\n const { stubPath, testCode } = request;\n let moduleExports;\n let step = 'Import';\n try {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n moduleExports = await import(stubPath);\n step = 'Running test code';\n if (testCode) {\n // eslint-disable-next-line @typescript-eslint/no-implied-eval\n new Function('moduleExports', testCode)(moduleExports);\n }\n } catch (err) {\n emitMessage({\n type: 'error',\n message: `${step} failed: ${/** @type {Error} */ (err).stack || String(err)}`,\n });\n return;\n } finally {\n cleanUpGlobals(initialGlobalProperties);\n }\n\n try {\n emitMessage({\n type: 'result',\n value: toSerializable(moduleExports),\n });\n } catch (err) {\n emitMessage({\n type: 'error',\n message: `Error formatting or serializing exports: ${/** @type {Error} */ (err).stack || String(err)}`,\n });\n }\n}\n\n/**\n * Convert a value into an IPC-serializable form.\n * @param {*} value\n * @returns {*}\n */\nfunction toSerializable(value, depth = 1, encountered = new WeakSet()) {\n if (depth > 3) {\n return '...';\n }\n\n if (value && typeof value === 'object') {\n // track encountered objects to avoid entering circular references\n if (encountered.has(value)) {\n return '[Circular]';\n }\n encountered.add(value);\n\n if (Array.isArray(value)) {\n return value.map((v) => toSerializable(v, depth + 1, encountered));\n }\n\n if (Object.keys(value).length || value.constructor?.name === 'Object') {\n return Object.fromEntries(Object.entries(value).map(([k, v]) => [k, toSerializable(v, depth + 1, encountered)]));\n }\n\n // Always format other objects (even if they're serializable) to avoid comparison issues\n // in expect(...).toEqual() (like \"TypeError: Method Map.prototype.entries called on incompatible receiver #<Map>\")\n return formatValue(value);\n }\n\n try {\n // try to serialize the same way postMessage does, per\n // https://nodejs.org/api/worker_threads.html#portpostmessagevalue-transferlist\n v8.serialize(value);\n return value;\n } catch {\n // not serializable, so format the value instead\n return formatValue(value);\n }\n}\n\n/**\n * Pretty-format a value, removing newlines.\n * (`pretty-format` has a `min` option, but it removes additional detail which isn't desired.)\n */\nfunction formatValue(/** @type {*} */ value) {\n return format(value, {}).replace(/\\n/g, '').replace(/\\s+/g, ' ');\n}\n"]}
@@ -1,44 +0,0 @@
1
- export type StubImportRequest = {
2
- stubPath: string;
3
- /**
4
- * Test function body which receives a parameter `moduleExports`.
5
- * The result is not returned, but this can be used to verify that an expected API is available
6
- * (code calling it doesn't throw) even if it doesn't show up in the named exports.
7
- */
8
- testCode?: string;
9
- };
10
- type StubImportResult = {
11
- type: 'result';
12
- /**
13
- * IPC-friendly result of importing the module.
14
- * Any non-IPC-friendly values (such as functions) will be pretty-printed as strings.
15
- */
16
- value: unknown;
17
- };
18
- export type StubImportResponse = StubImportResult | {
19
- type: 'error';
20
- message: string;
21
- };
22
- /**
23
- * Initialize a worker used for importing stubs.
24
- * (The worker is reused between tests for now because it's expensive to set up and tear down;
25
- * this can be changed later for certain tests if needed.)
26
- */
27
- export declare function ensureStubWorker(): void;
28
- /**
29
- * Import the stub in a worker and return the result.
30
- * Note that non-IPC-friendly values (such as functions) will be pretty-printed as strings.
31
- *
32
- * Why use a worker?
33
- * - Ensure that the module is imported in a "vanilla" way, without interference from Jest
34
- * transpilation or custom module resolution
35
- * - Allow the module to run in a simulated browser environment if needed
36
- * - Avoid potential pollution of the current process's globals
37
- *
38
- * (The worker is reused between tests for now because it's expensive to set up and tear down;
39
- * this can be changed later for certain tests if needed.)
40
- */
41
- export declare function tryImportStub(params: StubImportRequest): Promise<unknown>;
42
- export declare function cleanUpStubWorker(): Promise<void>;
43
- export {};
44
- //# sourceMappingURL=tryImportStub.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"tryImportStub.d.ts","sourceRoot":"","sources":["../../src/__fixtures__/tryImportStub.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,IAAI,EAAE,QAAQ,CAAC;IACf;;;OAGG;IACH,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AACF,MAAM,MAAM,kBAAkB,GAAG,gBAAgB,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAOvF;;;;GAIG;AACH,wBAAgB,gBAAgB,SAoB/B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC,CAuB/E;AAED,wBAAsB,iBAAiB,kBAWtC"}
@@ -1,79 +0,0 @@
1
- import path from 'path';
2
- import { fileURLToPath } from 'url';
3
- import { Worker } from 'worker_threads';
4
- const dirname = path.dirname(fileURLToPath(import.meta.url));
5
- const testWorkerPath = path.join(dirname, 'loadStubWorker.js');
6
- let worker;
7
- /**
8
- * Initialize a worker used for importing stubs.
9
- * (The worker is reused between tests for now because it's expensive to set up and tear down;
10
- * this can be changed later for certain tests if needed.)
11
- */
12
- export function ensureStubWorker() {
13
- if (worker)
14
- return;
15
- worker = new Worker(testWorkerPath);
16
- // An 'error' event from a worker means an unhandled exception and it's about to exit.
17
- // Don't throw an error in this fallback handler in case the error occurred during a call
18
- // to `tryImportStub` (which has its own error handler that can fail the calling test),
19
- // but save the error to be included in the 'exit' handler's error message.
20
- let lastError;
21
- worker.on('error', (err) => {
22
- lastError = err;
23
- });
24
- worker.on('exit', (code) => {
25
- throw new Error(lastError
26
- ? `Worker exited due to an uncaught exception: ${lastError.stack}`
27
- : `Worker exited unexpectedly with code ${code || 0}`);
28
- });
29
- }
30
- /**
31
- * Import the stub in a worker and return the result.
32
- * Note that non-IPC-friendly values (such as functions) will be pretty-printed as strings.
33
- *
34
- * Why use a worker?
35
- * - Ensure that the module is imported in a "vanilla" way, without interference from Jest
36
- * transpilation or custom module resolution
37
- * - Allow the module to run in a simulated browser environment if needed
38
- * - Avoid potential pollution of the current process's globals
39
- *
40
- * (The worker is reused between tests for now because it's expensive to set up and tear down;
41
- * this can be changed later for certain tests if needed.)
42
- */
43
- export async function tryImportStub(params) {
44
- ensureStubWorker();
45
- return new Promise((resolve, reject) => {
46
- const onMessage = (response) => {
47
- worker?.off('error', onError);
48
- if (response.type === 'error') {
49
- // error importing the module
50
- reject(response.message);
51
- }
52
- else {
53
- resolve(response.value);
54
- }
55
- };
56
- // unhandled exception (not expected)
57
- const onError = (err) => {
58
- worker?.off('message', onMessage);
59
- reject(err);
60
- };
61
- worker?.once('message', onMessage);
62
- worker?.once('error', onError);
63
- worker?.postMessage(params);
64
- });
65
- }
66
- export async function cleanUpStubWorker() {
67
- if (worker) {
68
- // Remove all listeners so that the exit handler set up during initialization doesn't throw
69
- worker.removeAllListeners();
70
- try {
71
- await worker.terminate();
72
- }
73
- catch {
74
- // ignore
75
- }
76
- worker = undefined;
77
- }
78
- }
79
- //# sourceMappingURL=tryImportStub.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"tryImportStub.js","sourceRoot":"","sources":["../../src/__fixtures__/tryImportStub.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAwBxC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC7D,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC;AAE/D,IAAI,MAA0B,CAAC;AAE/B;;;;GAIG;AACH,MAAM,UAAU,gBAAgB;IAC9B,IAAI,MAAM;QAAE,OAAO;IAEnB,MAAM,GAAG,IAAI,MAAM,CAAC,cAAc,CAAC,CAAC;IAEpC,sFAAsF;IACtF,yFAAyF;IACzF,uFAAuF;IACvF,2EAA2E;IAC3E,IAAI,SAA4B,CAAC;IACjC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;QACzB,SAAS,GAAG,GAAG,CAAC;IAClB,CAAC,CAAC,CAAC;IACH,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;QACzB,MAAM,IAAI,KAAK,CACb,SAAS;YACP,CAAC,CAAC,+CAA+C,SAAS,CAAC,KAAK,EAAE;YAClE,CAAC,CAAC,wCAAwC,IAAI,IAAI,CAAC,EAAE,CACxD,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,MAAyB;IAC3D,gBAAgB,EAAE,CAAC;IAEnB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,SAAS,GAAG,CAAC,QAA4B,EAAE,EAAE;YACjD,MAAM,EAAE,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC9B,IAAI,QAAQ,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBAC9B,6BAA6B;gBAC7B,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAC3B,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YAC1B,CAAC;QACH,CAAC,CAAC;QACF,qCAAqC;QACrC,MAAM,OAAO,GAAG,CAAC,GAAU,EAAE,EAAE;YAC7B,MAAM,EAAE,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;YAClC,MAAM,CAAC,GAAG,CAAC,CAAC;QACd,CAAC,CAAC;QACF,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QACnC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAE/B,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,IAAI,MAAM,EAAE,CAAC;QACX,2FAA2F;QAC3F,MAAM,CAAC,kBAAkB,EAAE,CAAC;QAC5B,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,SAAS,EAAE,CAAC;QAC3B,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QACD,MAAM,GAAG,SAAS,CAAC;IACrB,CAAC;AACH,CAAC","sourcesContent":["import path from 'path';\nimport { fileURLToPath } from 'url';\nimport { Worker } from 'worker_threads';\n\n// this type is used by loadStubWorker.js\n// (it's test-specific, so no reason to put it in the types folder)\nexport type StubImportRequest = {\n stubPath: string;\n /**\n * Test function body which receives a parameter `moduleExports`.\n * The result is not returned, but this can be used to verify that an expected API is available\n * (code calling it doesn't throw) even if it doesn't show up in the named exports.\n */\n testCode?: string;\n};\n\ntype StubImportResult = {\n type: 'result';\n /**\n * IPC-friendly result of importing the module.\n * Any non-IPC-friendly values (such as functions) will be pretty-printed as strings.\n */\n value: unknown;\n};\nexport type StubImportResponse = StubImportResult | { type: 'error'; message: string };\n\nconst dirname = path.dirname(fileURLToPath(import.meta.url));\nconst testWorkerPath = path.join(dirname, 'loadStubWorker.js');\n\nlet worker: Worker | undefined;\n\n/**\n * Initialize a worker used for importing stubs.\n * (The worker is reused between tests for now because it's expensive to set up and tear down;\n * this can be changed later for certain tests if needed.)\n */\nexport function ensureStubWorker() {\n if (worker) return;\n\n worker = new Worker(testWorkerPath);\n\n // An 'error' event from a worker means an unhandled exception and it's about to exit.\n // Don't throw an error in this fallback handler in case the error occurred during a call\n // to `tryImportStub` (which has its own error handler that can fail the calling test),\n // but save the error to be included in the 'exit' handler's error message.\n let lastError: Error | undefined;\n worker.on('error', (err) => {\n lastError = err;\n });\n worker.on('exit', (code) => {\n throw new Error(\n lastError\n ? `Worker exited due to an uncaught exception: ${lastError.stack}`\n : `Worker exited unexpectedly with code ${code || 0}`,\n );\n });\n}\n\n/**\n * Import the stub in a worker and return the result.\n * Note that non-IPC-friendly values (such as functions) will be pretty-printed as strings.\n *\n * Why use a worker?\n * - Ensure that the module is imported in a \"vanilla\" way, without interference from Jest\n * transpilation or custom module resolution\n * - Allow the module to run in a simulated browser environment if needed\n * - Avoid potential pollution of the current process's globals\n *\n * (The worker is reused between tests for now because it's expensive to set up and tear down;\n * this can be changed later for certain tests if needed.)\n */\nexport async function tryImportStub(params: StubImportRequest): Promise<unknown> {\n ensureStubWorker();\n\n return new Promise((resolve, reject) => {\n const onMessage = (response: StubImportResponse) => {\n worker?.off('error', onError);\n if (response.type === 'error') {\n // error importing the module\n reject(response.message);\n } else {\n resolve(response.value);\n }\n };\n // unhandled exception (not expected)\n const onError = (err: Error) => {\n worker?.off('message', onMessage);\n reject(err);\n };\n worker?.once('message', onMessage);\n worker?.once('error', onError);\n\n worker?.postMessage(params);\n });\n}\n\nexport async function cleanUpStubWorker() {\n if (worker) {\n // Remove all listeners so that the exit handler set up during initialization doesn't throw\n worker.removeAllListeners();\n try {\n await worker.terminate();\n } catch {\n // ignore\n }\n worker = undefined;\n }\n}\n"]}