@endo/compartment-mapper 1.4.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/README.md +292 -111
  2. package/bundle.d.ts +1 -1
  3. package/bundle.js +4 -1
  4. package/functor-lite.d.ts +3 -0
  5. package/functor-lite.d.ts.map +1 -0
  6. package/functor-lite.js +4 -0
  7. package/functor.d.ts +3 -0
  8. package/functor.d.ts.map +1 -0
  9. package/functor.js +4 -0
  10. package/import-archive-all-parsers.d.ts +2 -0
  11. package/import-archive-all-parsers.d.ts.map +1 -0
  12. package/import-archive-all-parsers.js +1 -0
  13. package/index.d.ts +1 -1
  14. package/index.js +4 -1
  15. package/package.json +14 -5
  16. package/script-lite.d.ts +3 -0
  17. package/script-lite.d.ts.map +1 -0
  18. package/script-lite.js +4 -0
  19. package/script.d.ts +3 -0
  20. package/script.d.ts.map +1 -0
  21. package/script.js +4 -0
  22. package/src/archive-lite.d.ts +2 -4
  23. package/src/archive-lite.d.ts.map +1 -1
  24. package/src/archive-lite.js +16 -192
  25. package/src/archive.d.ts.map +1 -1
  26. package/src/archive.js +8 -0
  27. package/src/bundle-cjs.d.ts +1 -1
  28. package/src/bundle-cjs.d.ts.map +1 -1
  29. package/src/bundle-cjs.js +57 -28
  30. package/src/bundle-json.d.ts.map +1 -1
  31. package/src/bundle-json.js +2 -3
  32. package/src/bundle-lite.d.ts +91 -0
  33. package/src/bundle-lite.d.ts.map +1 -0
  34. package/src/bundle-lite.js +668 -0
  35. package/src/bundle-mjs.d.ts +2 -2
  36. package/src/bundle-mjs.d.ts.map +1 -1
  37. package/src/bundle-mjs.js +36 -19
  38. package/src/bundle.d.ts +48 -10
  39. package/src/bundle.d.ts.map +1 -1
  40. package/src/bundle.js +399 -127
  41. package/src/capture-lite.d.ts.map +1 -1
  42. package/src/capture-lite.js +10 -188
  43. package/src/digest.d.ts +5 -0
  44. package/src/digest.d.ts.map +1 -0
  45. package/src/digest.js +235 -0
  46. package/src/import-archive-all-parsers.d.ts +11 -0
  47. package/src/import-archive-all-parsers.d.ts.map +1 -0
  48. package/src/import-archive-all-parsers.js +29 -0
  49. package/src/import-archive-lite.d.ts.map +1 -1
  50. package/src/import-archive-lite.js +4 -0
  51. package/src/import-hook.d.ts +3 -16
  52. package/src/import-hook.d.ts.map +1 -1
  53. package/src/import-hook.js +11 -18
  54. package/src/import-lite.d.ts.map +1 -1
  55. package/src/import-lite.js +7 -2
  56. package/src/import.d.ts.map +1 -1
  57. package/src/import.js +2 -0
  58. package/src/link.d.ts.map +1 -1
  59. package/src/link.js +2 -0
  60. package/src/map-parser.d.ts.map +1 -1
  61. package/src/map-parser.js +4 -1
  62. package/src/node-modules.d.ts +4 -47
  63. package/src/node-modules.d.ts.map +1 -1
  64. package/src/node-modules.js +157 -131
  65. package/src/parse-archive-cjs.d.ts.map +1 -1
  66. package/src/parse-archive-cjs.js +8 -3
  67. package/src/parse-cjs-shared-export-wrapper.d.ts.map +1 -1
  68. package/src/parse-cjs-shared-export-wrapper.js +2 -10
  69. package/src/parse-cjs.js +1 -1
  70. package/src/parse-mjs.js +2 -2
  71. package/src/policy.d.ts.map +1 -1
  72. package/src/policy.js +4 -7
  73. package/src/search.d.ts +6 -12
  74. package/src/search.d.ts.map +1 -1
  75. package/src/search.js +29 -12
  76. package/src/types/compartment-map-schema.d.ts +5 -0
  77. package/src/types/compartment-map-schema.d.ts.map +1 -1
  78. package/src/types/compartment-map-schema.ts +5 -0
  79. package/src/types/external.d.ts +159 -12
  80. package/src/types/external.d.ts.map +1 -1
  81. package/src/types/external.ts +180 -12
  82. package/src/types/internal.d.ts +86 -13
  83. package/src/types/internal.d.ts.map +1 -1
  84. package/src/types/internal.ts +107 -13
  85. package/src/types/node-modules.d.ts +79 -0
  86. package/src/types/node-modules.d.ts.map +1 -0
  87. package/src/types/node-modules.ts +89 -0
  88. package/src/types/node-powers.d.ts +4 -4
  89. package/src/types/node-powers.d.ts.map +1 -1
  90. package/src/types/node-powers.ts +4 -4
  91. package/src/types/powers.d.ts +2 -2
  92. package/src/types/powers.d.ts.map +1 -1
  93. package/src/types/powers.ts +2 -2
@@ -17,57 +17,27 @@
17
17
  * CompartmentDescriptor,
18
18
  * CompartmentMapDescriptor,
19
19
  * CompartmentMapForNodeModulesOptions,
20
- * Language,
21
20
  * LanguageForExtension,
22
21
  * MapNodeModulesOptions,
23
22
  * MaybeReadFn,
24
23
  * MaybeReadPowers,
25
- * ModuleDescriptor,
24
+ * PackageDescriptor,
25
+ * ReadDescriptorFn,
26
26
  * ReadFn,
27
27
  * ReadPowers,
28
- * ScopeDescriptor,
29
28
  * SomePackagePolicy,
30
29
  * SomePolicy,
31
30
  * } from './types.js'
32
- */
33
-
34
- /**
35
- * The graph is an intermediate object model that the functions of this module
36
- * build by exploring the `node_modules` tree dropped by tools like npm and
37
- * consumed by tools like Node.js.
38
- * This gets translated finally into a compartment map.
39
- *
40
- * @typedef {Record<string, Node>} Graph
41
- */
42
-
43
- /**
44
- * @typedef {object} Node
45
- * @property {string} label
46
- * @property {string} name
47
- * @property {Array<string>} path
48
- * @property {Array<string>} logicalPath
49
- * @property {boolean} explicitExports
50
- * @property {Record<string, string>} internalAliases
51
- * @property {Record<string, string>} externalAliases
52
- * @property {Record<string, string>} dependencyLocations - from module name to
53
- * location in storage.
54
- * @property {LanguageForExtension} parsers - the parser for
55
- * modules based on their extension.
56
- * @property {Record<string, Language>} types - the parser for specific
57
- * modules.
58
- */
59
-
60
- /**
61
- * @typedef {object} LanguageOptions
62
- * @property {LanguageForExtension} commonjsLanguageForExtension
63
- * @property {LanguageForExtension} moduleLanguageForExtension
64
- * @property {LanguageForExtension} workspaceCommonjsLanguageForExtension
65
- * @property {LanguageForExtension} workspaceModuleLanguageForExtension
66
- * @property {Set<string>} languages
67
- */
68
-
69
- /**
70
- * @typedef {Record<string, {spec: string, alias: string}>} CommonDependencyDescriptors
31
+ * @import {
32
+ * Graph,
33
+ * Node,
34
+ * LanguageOptions,
35
+ * CommonDependencyDescriptors,
36
+ * GatherDependencyOptions,
37
+ * GraphPackageOptions,
38
+ * GraphPackagesOptions,
39
+ * PackageDetails,
40
+ * } from './types/node-modules.js'
71
41
  */
72
42
 
73
43
  import { pathCompare } from './compartment-map.js';
@@ -90,6 +60,11 @@ const decoder = new TextDecoder();
90
60
  // q, as in quote, for enquoting strings in error messages.
91
61
  const q = JSON.stringify;
92
62
 
63
+ /**
64
+ * Default logger that does nothing.
65
+ */
66
+ const noop = () => {};
67
+
93
68
  /**
94
69
  * @param {string} rel - a relative URL
95
70
  * @param {string} abs - a fully qualified URL
@@ -99,12 +74,16 @@ const resolveLocation = (rel, abs) => {
99
74
  return new URL(rel, abs).toString();
100
75
  };
101
76
 
77
+ // Exported for testing:
102
78
  /**
103
79
  * @param {string} location
104
80
  * @returns {string}
105
81
  */
106
- const basename = location => {
107
- const { pathname } = new URL(location);
82
+ export const basename = location => {
83
+ let { pathname } = new URL(location);
84
+ if (pathname.endsWith('/')) {
85
+ pathname = pathname.slice(0, -1);
86
+ }
108
87
  const index = pathname.lastIndexOf('/');
109
88
  if (index < 0) {
110
89
  return pathname;
@@ -145,27 +124,19 @@ const readDescriptorWithMemo = async (memo, maybeRead, packageLocation) => {
145
124
  };
146
125
 
147
126
  /**
148
- * @callback ReadDescriptorFn
149
- * @param {string} packageLocation
150
- * @returns {Promise<object>}
151
- */
152
-
153
- /**
154
- * findPackage behaves as Node.js to find third-party modules by searching
127
+ * `findPackage` behaves as Node.js to find third-party modules by searching
155
128
  * parent to ancestor directories for a `node_modules` directory that contains
156
129
  * the name.
130
+ *
157
131
  * Node.js does not actually require these to be packages, but in practice,
158
- * these are the locations that pakcage managers drop a package so Node.js can
132
+ * these are the locations that package managers drop a package so Node.js can
159
133
  * find it efficiently.
160
134
  *
161
135
  * @param {ReadDescriptorFn} readDescriptor
162
136
  * @param {CanonicalFn} canonical
163
137
  * @param {string} directory
164
138
  * @param {string} name
165
- * @returns {Promise<{
166
- * packageLocation: string,
167
- * packageDescriptor: object,
168
- * } | undefined>}
139
+ * @returns {Promise<PackageDetails|undefined>}
169
140
  */
170
141
  const findPackage = async (readDescriptor, canonical, directory, name) => {
171
142
  await null;
@@ -198,6 +169,7 @@ const findPackage = async (readDescriptor, canonical, directory, name) => {
198
169
  }
199
170
  };
200
171
 
172
+ /** @satisfies {LanguageForExtension} */
201
173
  const defaultLanguageForExtension = /** @type {const} */ ({
202
174
  mjs: 'mjs',
203
175
  cjs: 'cjs',
@@ -205,15 +177,19 @@ const defaultLanguageForExtension = /** @type {const} */ ({
205
177
  text: 'text',
206
178
  bytes: 'bytes',
207
179
  });
180
+
181
+ /** @satisfies {LanguageForExtension} */
208
182
  const defaultCommonjsLanguageForExtension = /** @type {const} */ ({
209
183
  js: 'cjs',
210
184
  });
185
+
186
+ /** @satisfies {LanguageForExtension} */
211
187
  const defaultModuleLanguageForExtension = /** @type {const} */ ({
212
188
  js: 'mjs',
213
189
  });
214
190
 
215
191
  /**
216
- * @param {object} descriptor
192
+ * @param {PackageDescriptor} descriptor
217
193
  * @param {string} location
218
194
  * @param {LanguageOptions} languageOptions
219
195
  * @returns {Record<string, string>}
@@ -278,7 +254,7 @@ const inferParsers = (descriptor, location, languageOptions) => {
278
254
  };
279
255
 
280
256
  /**
281
- * graphPackage and gatherDependency are mutually recursive functions that
257
+ * `graphPackage` and {@link gatherDependency} are mutually recursive functions that
282
258
  * gather the metadata for a package and its transitive dependencies.
283
259
  * The keys of the graph are the locations of the package descriptors.
284
260
  * The metadata include a label (which is informative and not necessarily
@@ -289,15 +265,12 @@ const inferParsers = (descriptor, location, languageOptions) => {
289
265
  * @param {ReadDescriptorFn} readDescriptor
290
266
  * @param {CanonicalFn} canonical
291
267
  * @param {Graph} graph
292
- * @param {object} packageDetails
293
- * @param {string} packageDetails.packageLocation
294
- * @param {object} packageDetails.packageDescriptor
268
+ * @param {PackageDetails} packageDetails
295
269
  * @param {Set<string>} conditions
296
270
  * @param {boolean | undefined} dev
297
- * @param {CommonDependencyDescriptors} commonDependencyDescriptors
298
271
  * @param {LanguageOptions} languageOptions
299
- * @param {Map<string, Array<string>>} preferredPackageLogicalPathMap
300
- * @param {Array<string>} logicalPath
272
+ * @param {boolean} strict
273
+ * @param {GraphPackageOptions} options
301
274
  * @returns {Promise<undefined>}
302
275
  */
303
276
  const graphPackage = async (
@@ -308,10 +281,14 @@ const graphPackage = async (
308
281
  { packageLocation, packageDescriptor },
309
282
  conditions,
310
283
  dev,
311
- commonDependencyDescriptors,
312
284
  languageOptions,
313
- preferredPackageLogicalPathMap = new Map(),
314
- logicalPath = [],
285
+ strict,
286
+ {
287
+ commonDependencyDescriptors = {},
288
+ preferredPackageLogicalPathMap = new Map(),
289
+ logicalPath = [],
290
+ log = noop,
291
+ } = {},
315
292
  ) => {
316
293
  if (graph[packageLocation] !== undefined) {
317
294
  // Returning the promise here would create a causal cycle and stall recursion.
@@ -319,20 +296,19 @@ const graphPackage = async (
319
296
  }
320
297
 
321
298
  if (packageDescriptor.name !== name) {
322
- console.warn(
323
- `Package named ${q(
324
- name,
325
- )} does not match location ${packageLocation} got (${q(
326
- packageDescriptor.name,
327
- )})`,
328
- );
299
+ log('Package name does not match location', {
300
+ name,
301
+ packageDescriptorName: packageDescriptor.name,
302
+ packageLocation,
303
+ });
329
304
  }
330
305
 
331
- const result = {};
332
- graph[packageLocation] = /** @type {Node} */ (result);
306
+ const result = /** @type {Node} */ ({});
307
+ graph[packageLocation] = result;
333
308
 
334
- /** @type {Record<string, string>} */
309
+ /** @type {Node['dependencyLocations']} */
335
310
  const dependencyLocations = {};
311
+ /** @type {ReturnType<typeof gatherDependency>[]} */
336
312
  const children = [];
337
313
  const optionals = new Set();
338
314
  const {
@@ -344,14 +320,18 @@ const graphPackage = async (
344
320
  devDependencies = {},
345
321
  } = packageDescriptor;
346
322
  const allDependencies = {};
347
- assign(allDependencies, commonDependencyDescriptors);
348
- for (const [name, { spec }] of Object.entries(commonDependencyDescriptors)) {
349
- allDependencies[name] = spec;
323
+ for (const [name, descriptor] of Object.entries(
324
+ commonDependencyDescriptors,
325
+ )) {
326
+ if (Object(descriptor) === descriptor) {
327
+ const { spec } = descriptor;
328
+ allDependencies[name] = spec;
329
+ }
350
330
  }
351
331
  assign(allDependencies, dependencies);
352
332
  assign(allDependencies, peerDependencies);
353
- for (const [name, { optional }] of Object.entries(peerDependenciesMeta)) {
354
- if (optional) {
333
+ for (const [name, meta] of Object.entries(peerDependenciesMeta)) {
334
+ if (Object(meta) === meta && meta.optional) {
355
335
  optionals.add(name);
356
336
  }
357
337
  }
@@ -360,7 +340,7 @@ const graphPackage = async (
360
340
  for (const name of Object.keys(optionalDependencies)) {
361
341
  optionals.add(name);
362
342
  }
363
- if (dev !== undefined && dev !== null ? dev : conditions.has('development')) {
343
+ if (dev) {
364
344
  assign(allDependencies, devDependencies);
365
345
  }
366
346
 
@@ -380,17 +360,25 @@ const graphPackage = async (
380
360
  conditions,
381
361
  preferredPackageLogicalPathMap,
382
362
  languageOptions,
383
- childLogicalPath,
384
- optional,
385
- commonDependencyDescriptors,
363
+ strict,
364
+ {
365
+ childLogicalPath,
366
+ optional,
367
+ commonDependencyDescriptors,
368
+ log,
369
+ },
386
370
  ),
387
371
  );
388
372
  }
389
373
 
390
374
  const { version = '', exports: exportsDescriptor } = packageDescriptor;
391
- /** @type {Record<string, Language>} */
375
+ /** @type {Node['types']} */
392
376
  const types = {};
393
377
 
378
+ /**
379
+ * @param {string} path
380
+ * @returns {Promise<PackageDescriptor>}
381
+ */
394
382
  const readDescriptorUpwards = async path => {
395
383
  const location = resolveLocation(path, packageLocation);
396
384
  // readDescriptor coming from above is memoized, so this is not awfully slow
@@ -398,9 +386,9 @@ const graphPackage = async (
398
386
  return data;
399
387
  };
400
388
 
401
- /** @type {Record<string, string>} */
389
+ /** @type {Node['externalAliases']} */
402
390
  const externalAliases = {};
403
- /** @type {Record<string, string>} */
391
+ /** @type {Node['internalAliases']} */
404
392
  const internalAliases = {};
405
393
 
406
394
  inferExportsAndAliases(
@@ -417,10 +405,13 @@ const graphPackage = async (
417
405
  languageOptions,
418
406
  );
419
407
 
408
+ const sourceDirname = basename(packageLocation);
409
+
420
410
  Object.assign(result, {
421
411
  name,
422
412
  path: logicalPath,
423
413
  label: `${name}${version ? `-v${version}` : ''}`,
414
+ sourceDirname,
424
415
  explicitExports: exportsDescriptor !== undefined,
425
416
  externalAliases,
426
417
  internalAliases,
@@ -472,6 +463,8 @@ const graphPackage = async (
472
463
  };
473
464
 
474
465
  /**
466
+ * Adds information for the dependency of the package at `packageLocation` to the `graph` object.
467
+ *
475
468
  * @param {ReadDescriptorFn} readDescriptor
476
469
  * @param {CanonicalFn} canonical
477
470
  * @param {Graph} graph - the partially build graph.
@@ -481,9 +474,9 @@ const graphPackage = async (
481
474
  * @param {Set<string>} conditions
482
475
  * @param {Map<string, Array<string>>} preferredPackageLogicalPathMap
483
476
  * @param {LanguageOptions} languageOptions
484
- * @param {Array<string>} [childLogicalPath]
485
- * @param {boolean} [optional] - whether the dependency is optional
486
- * @param {object} [commonDependencyDescriptors] - dependencies to be added to all packages
477
+ * @param {boolean} strict - If `true`, a missing dependency will throw an exception
478
+ * @param {GatherDependencyOptions} options
479
+ * @returns {Promise<void>}
487
480
  */
488
481
  const gatherDependency = async (
489
482
  readDescriptor,
@@ -495,9 +488,13 @@ const gatherDependency = async (
495
488
  conditions,
496
489
  preferredPackageLogicalPathMap,
497
490
  languageOptions,
498
- childLogicalPath = [],
499
- optional = false,
500
- commonDependencyDescriptors = undefined,
491
+ strict,
492
+ {
493
+ childLogicalPath = [],
494
+ optional = false,
495
+ commonDependencyDescriptors = {},
496
+ log = noop,
497
+ } = {},
501
498
  ) => {
502
499
  const dependency = await findPackage(
503
500
  readDescriptor,
@@ -507,7 +504,7 @@ const gatherDependency = async (
507
504
  );
508
505
  if (dependency === undefined) {
509
506
  // allow the dependency to be missing if optional
510
- if (optional) {
507
+ if (optional || !strict) {
511
508
  return;
512
509
  }
513
510
  throw Error(`Cannot find dependency ${name} for ${packageLocation}`);
@@ -530,32 +527,35 @@ const gatherDependency = async (
530
527
  dependency,
531
528
  conditions,
532
529
  false,
533
- commonDependencyDescriptors,
534
530
  languageOptions,
535
- preferredPackageLogicalPathMap,
536
- childLogicalPath,
531
+ strict,
532
+ {
533
+ commonDependencyDescriptors,
534
+ preferredPackageLogicalPathMap,
535
+ logicalPath: childLogicalPath,
536
+ log,
537
+ },
537
538
  );
538
539
  };
539
540
 
540
541
  /**
541
- * graphPackages returns a graph whose keys are nominally URLs, one per
542
- * package, with values that are label: (an informative Compartment name, built
543
- * as ${name}@${version}), dependencies: (a list of URLs), and exports: (an
544
- * object whose keys are the thing being imported, and the values are the names
545
- * of the matching module, relative to the containing package's root, that is,
546
- * the URL that was used as the key of graph).
547
- * The URLs in dependencies will all exist as other keys of graph.
542
+ * Resolves with a {@link Graph} representing the packages for which
543
+ * {@link CompartmentDescriptor CompartmentDescriptors} will be created.
548
544
  *
549
545
  * @param {MaybeReadFn} maybeRead
550
546
  * @param {CanonicalFn} canonical
551
547
  * @param {string} packageLocation - location of the main package.
552
548
  * @param {Set<string>} conditions
553
- * @param {object} mainPackageDescriptor - the parsed contents of the main
554
- * package.json, which was already read when searching for the package.json.
555
- * @param {boolean|undefined} dev - whether to use devDependencies from this package (and
556
- * only this package).
557
- * @param {Record<string,string>} commonDependencies - dependencies to be added to all packages
549
+ * @param {PackageDescriptor} mainPackageDescriptor - the parsed contents of the
550
+ * main `package.json`, which was already read when searching for the
551
+ * `package.json`.
552
+ * @param {boolean|undefined} dev - whether to use devDependencies from this
553
+ * package (and only this package).
554
+ * @param {Record<string,string>} commonDependencies - dependencies to be added
555
+ * to all packages
558
556
  * @param {LanguageOptions} languageOptions
557
+ * @param {boolean} strict
558
+ * @param {GraphPackagesOptions} options
559
559
  */
560
560
  const graphPackages = async (
561
561
  maybeRead,
@@ -566,11 +566,13 @@ const graphPackages = async (
566
566
  dev,
567
567
  commonDependencies,
568
568
  languageOptions,
569
+ strict,
570
+ { log = noop } = {},
569
571
  ) => {
570
572
  const memo = create(null);
571
573
  /**
572
574
  * @param {string} packageLocation
573
- * @returns {Promise<object>}
575
+ * @returns {Promise<PackageDescriptor>}
574
576
  */
575
577
  const readDescriptor = packageLocation =>
576
578
  readDescriptorWithMemo(memo, maybeRead, packageLocation);
@@ -621,15 +623,19 @@ const graphPackages = async (
621
623
  },
622
624
  conditions,
623
625
  dev,
624
- commonDependencyDescriptors,
625
626
  languageOptions,
627
+ strict,
628
+ {
629
+ commonDependencyDescriptors,
630
+ log,
631
+ },
626
632
  );
627
633
  return graph;
628
634
  };
629
635
 
630
636
  /**
631
- * translateGraph converts the graph returned by graph packages (above) into a
632
- * compartment map.
637
+ * `translateGraph` converts the graph returned by graph packages (above) into a
638
+ * {@link CompartmentMapDescriptor compartment map}.
633
639
  *
634
640
  * @param {string} entryPackageLocation
635
641
  * @param {string} entryModuleSpecifier
@@ -646,7 +652,7 @@ const translateGraph = (
646
652
  conditions,
647
653
  policy,
648
654
  ) => {
649
- /** @type {Record<string, CompartmentDescriptor>} */
655
+ /** @type {CompartmentMapDescriptor['compartments']} */
650
656
  const compartments = Object.create(null);
651
657
 
652
658
  // For each package, build a map of all the external modules the package can
@@ -663,14 +669,15 @@ const translateGraph = (
663
669
  name,
664
670
  path,
665
671
  label,
672
+ sourceDirname,
666
673
  dependencyLocations,
667
674
  internalAliases,
668
675
  parsers,
669
676
  types,
670
677
  } = graph[dependeeLocation];
671
- /** @type {Record<string, ModuleDescriptor>} */
678
+ /** @type {CompartmentDescriptor['modules']} */
672
679
  const moduleDescriptors = Object.create(null);
673
- /** @type {Record<string, ScopeDescriptor>} */
680
+ /** @type {CompartmentDescriptor['scopes']} */
674
681
  const scopes = Object.create(null);
675
682
 
676
683
  /**
@@ -757,6 +764,7 @@ const translateGraph = (
757
764
  name,
758
765
  path,
759
766
  location: dependeeLocation,
767
+ sourceDirname,
760
768
  modules: moduleDescriptors,
761
769
  scopes,
762
770
  parsers,
@@ -849,33 +857,49 @@ const makeLanguageOptions = ({
849
857
  /**
850
858
  * @param {ReadFn | ReadPowers | MaybeReadPowers} readPowers
851
859
  * @param {string} packageLocation
852
- * @param {Set<string>} conditions
853
- * @param {object} packageDescriptor
860
+ * @param {Set<string>} conditionsOption
861
+ * @param {PackageDescriptor} packageDescriptor
854
862
  * @param {string} moduleSpecifier
855
863
  * @param {CompartmentMapForNodeModulesOptions} [options]
856
864
  * @returns {Promise<CompartmentMapDescriptor>}
865
+ * @deprecated Use {@link mapNodeModules} instead.
857
866
  */
858
867
  export const compartmentMapForNodeModules = async (
859
868
  readPowers,
860
869
  packageLocation,
861
- conditions,
870
+ conditionsOption,
862
871
  packageDescriptor,
863
872
  moduleSpecifier,
864
873
  options = {},
865
874
  ) => {
866
- const { dev = undefined, commonDependencies = {}, policy } = options;
875
+ const {
876
+ dev = false,
877
+ commonDependencies = {},
878
+ policy,
879
+ strict = false,
880
+ log = noop,
881
+ } = options;
867
882
  const { maybeRead, canonical } = unpackReadPowers(readPowers);
868
883
  const languageOptions = makeLanguageOptions(options);
869
884
 
885
+ const conditions = new Set(conditionsOption || []);
886
+
887
+ // dev is only set for the entry package, and implied by the development
888
+ // condition.
889
+ // The dev option is deprecated in favor of using conditions, since that
890
+ // covers more intentional behaviors of the development mode.
891
+
870
892
  const graph = await graphPackages(
871
893
  maybeRead,
872
894
  canonical,
873
895
  packageLocation,
874
896
  conditions,
875
897
  packageDescriptor,
876
- dev,
898
+ dev || (conditions && conditions.has('development')),
877
899
  commonDependencies,
878
900
  languageOptions,
901
+ strict,
902
+ { log },
879
903
  );
880
904
 
881
905
  if (policy) {
@@ -906,6 +930,11 @@ export const compartmentMapForNodeModules = async (
906
930
  };
907
931
 
908
932
  /**
933
+ * Creates a {@link CompartmentMapDescriptor} from the module at
934
+ * `moduleLocation`, considering dependencies found in `node_modules`.
935
+ *
936
+ * Locates the {@link PackageDescriptor} for the module at `moduleLocation`
937
+ *
909
938
  * @param {ReadFn | ReadPowers | MaybeReadPowers} readPowers
910
939
  * @param {string} moduleLocation
911
940
  * @param {MapNodeModulesOptions} [options]
@@ -914,20 +943,17 @@ export const compartmentMapForNodeModules = async (
914
943
  export const mapNodeModules = async (
915
944
  readPowers,
916
945
  moduleLocation,
917
- options = {},
946
+ { tags = new Set(), conditions = tags, log = noop, ...otherOptions } = {},
918
947
  ) => {
919
- const { tags = new Set(), conditions = tags, ...otherOptions } = options;
920
-
921
948
  const {
922
949
  packageLocation,
923
950
  packageDescriptorText,
924
951
  packageDescriptorLocation,
925
952
  moduleSpecifier,
926
- } = await search(readPowers, moduleLocation);
953
+ } = await search(readPowers, moduleLocation, { log });
927
954
 
928
- const packageDescriptor = parseLocatedJson(
929
- packageDescriptorText,
930
- packageDescriptorLocation,
955
+ const packageDescriptor = /** @type {PackageDescriptor} */ (
956
+ parseLocatedJson(packageDescriptorText, packageDescriptorLocation)
931
957
  );
932
958
 
933
959
  return compartmentMapForNodeModules(
@@ -936,6 +962,6 @@ export const mapNodeModules = async (
936
962
  conditions,
937
963
  packageDescriptor,
938
964
  moduleSpecifier,
939
- otherOptions,
965
+ { log, ...otherOptions },
940
966
  );
941
967
  };
@@ -1 +1 @@
1
- {"version":3,"file":"parse-archive-cjs.d.ts","sourceRoot":"","sources":["parse-archive-cjs.js"],"names":[],"mappings":"AAkBA,sBAAsB;AACtB,8BADW,OAAO,CA6ChB;wBAES,OAAO,YAAY,EAAE,oBAAoB;;6BA5DzB,YAAY"}
1
+ {"version":3,"file":"parse-archive-cjs.d.ts","sourceRoot":"","sources":["parse-archive-cjs.js"],"names":[],"mappings":"AAkBA,sBAAsB;AACtB,8BADW,OAAO,CAkDhB;wBAES,OAAO,YAAY,EAAE,oBAAoB;;6BAjEzB,YAAY"}
@@ -22,9 +22,12 @@ export const parseArchiveCjs = (
22
22
  _specifier,
23
23
  location,
24
24
  _packageLocation,
25
+ options = {},
25
26
  ) => {
26
27
  const source = textDecoder.decode(bytes);
27
28
 
29
+ const { archiveOnly = false } = options;
30
+
28
31
  const {
29
32
  requires: imports,
30
33
  exports,
@@ -35,18 +38,20 @@ export const parseArchiveCjs = (
35
38
  exports.push('default');
36
39
  }
37
40
 
38
- const cjsWrappedSource = `(function (require, exports, module, __filename, __dirname) { ${source} //*/\n})\n`;
41
+ let cjsFunctor = `(function (require, exports, module, __filename, __dirname) { 'use strict'; ${source} //*/\n})\n`;
39
42
 
40
43
  const pre = textEncoder.encode(
41
44
  JSON.stringify({
42
45
  imports,
43
46
  exports,
44
47
  reexports,
45
- source: cjsWrappedSource,
48
+ source: cjsFunctor,
46
49
  }),
47
50
  );
48
51
 
49
- const cjsFunctor = `${cjsWrappedSource}//# sourceURL=${location}\n`;
52
+ if (!archiveOnly) {
53
+ cjsFunctor = `${cjsFunctor}//# sourceURL=${location}\n`;
54
+ }
50
55
 
51
56
  return {
52
57
  parser: 'pre-cjs-json',
@@ -1 +1 @@
1
- {"version":3,"file":"parse-cjs-shared-export-wrapper.d.ts","sourceRoot":"","sources":["parse-cjs-shared-export-wrapper.js"],"names":[],"mappings":"AAwCO,2CAPI,UAAU,GAAG,MAAM,GAAG,SAAS,YAC/B,MAAM,GACJ;IACR,QAAQ,EAAC,MAAM,GAAC,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,GAAC,IAAI,CAAA;CACrB,CAgCH;AAmBM,uGAZJ;IAAmB,uBAAuB,EAAlC,MAAM;IACU,WAAW,EAA3B,WAAW;IACgB,eAAe,EAA1C,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IACX,QAAQ,EAAnB,MAAM;IAC8B,UAAU,EAA9C,MAAM,GAAG,UAAU,GAAG,SAAS;CACvC,GAAU;IACR,MAAM,EAAE;QAAE,OAAO,EAAE,GAAG,CAAA;KAAE,CAAC;IACzB,aAAa,EAAE,GAAG,CAAC;IACnB,YAAY,WAAW;IACvB,OAAO,WAAW;CACnB,CAmIH;gCApNqC,YAAY;4BAAZ,YAAY"}
1
+ {"version":3,"file":"parse-cjs-shared-export-wrapper.d.ts","sourceRoot":"","sources":["parse-cjs-shared-export-wrapper.js"],"names":[],"mappings":"AAwCO,2CAPI,UAAU,GAAG,MAAM,GAAG,SAAS,YAC/B,MAAM,GACJ;IACR,QAAQ,EAAC,MAAM,GAAC,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,GAAC,IAAI,CAAA;CACrB,CAgCH;AAmBM,uGAZJ;IAAmB,uBAAuB,EAAlC,MAAM;IACU,WAAW,EAA3B,WAAW;IACgB,eAAe,EAA1C,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IACX,QAAQ,EAAnB,MAAM;IAC8B,UAAU,EAA9C,MAAM,GAAG,UAAU,GAAG,SAAS;CACvC,GAAU;IACR,MAAM,EAAE;QAAE,OAAO,EAAE,GAAG,CAAA;KAAE,CAAC;IACzB,aAAa,EAAE,GAAG,CAAC;IACnB,YAAY,WAAW;IACvB,OAAO,WAAW;CACnB,CA2HH;gCA5MqC,YAAY;4BAAZ,YAAY"}
@@ -135,16 +135,7 @@ export const wrap = ({
135
135
  },
136
136
  });
137
137
 
138
- let finalExports = originalExports;
139
-
140
- const module = freeze({
141
- get exports() {
142
- return finalExports;
143
- },
144
- set exports(value) {
145
- finalExports = value;
146
- },
147
- });
138
+ const module = { exports: originalExports };
148
139
 
149
140
  /** @param {string} importSpecifier */
150
141
  const require = importSpecifier => {
@@ -192,6 +183,7 @@ export const wrap = ({
192
183
  freeze(require);
193
184
 
194
185
  const afterExecute = () => {
186
+ const finalExports = module.exports; // in case it's a getter, only call it once
195
187
  const exportsHaveBeenOverwritten = finalExports !== originalExports;
196
188
  // Promotes keys from redefined module.export to top level namespace for import *
197
189
  // Note: We could do it less consistently but closer to how node does it if we iterated over exports detected by
package/src/parse-cjs.js CHANGED
@@ -41,7 +41,7 @@ export const parseCjs = (
41
41
  */
42
42
  const execute = (moduleEnvironmentRecord, compartment, resolvedImports) => {
43
43
  const functor = compartment.evaluate(
44
- `(function (require, exports, module, __filename, __dirname) { ${source} //*/\n})\n//# sourceURL=${location}`,
44
+ `(function (require, exports, module, __filename, __dirname) { 'use strict'; ${source} })\n`,
45
45
  );
46
46
 
47
47
  const { require, moduleExports, module, afterExecute } = wrap({
package/src/parse-mjs.js CHANGED
@@ -14,10 +14,10 @@ export const parseMjs = (
14
14
  _packageLocation,
15
15
  options = {},
16
16
  ) => {
17
- const { sourceMap, sourceMapHook } = options;
17
+ const { sourceMap, sourceMapHook, archiveOnly = false } = options;
18
18
  const source = textDecoder.decode(bytes);
19
19
  const record = new ModuleSource(source, {
20
- sourceUrl,
20
+ sourceUrl: archiveOnly ? undefined : sourceUrl,
21
21
  sourceMap,
22
22
  sourceMapUrl: sourceUrl,
23
23
  sourceMapHook,