@endo/compartment-mapper 1.6.3 → 2.0.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 (81) hide show
  1. package/package.json +12 -16
  2. package/src/archive-lite.d.ts +7 -7
  3. package/src/archive-lite.d.ts.map +1 -1
  4. package/src/archive-lite.js +78 -27
  5. package/src/archive.d.ts.map +1 -1
  6. package/src/archive.js +7 -0
  7. package/src/bundle-lite.d.ts +3 -3
  8. package/src/bundle-lite.d.ts.map +1 -1
  9. package/src/bundle-lite.js +19 -24
  10. package/src/bundle.d.ts +3 -3
  11. package/src/bundle.d.ts.map +1 -1
  12. package/src/bundle.js +19 -24
  13. package/src/capture-lite.d.ts +2 -2
  14. package/src/capture-lite.d.ts.map +1 -1
  15. package/src/capture-lite.js +217 -25
  16. package/src/compartment-map.d.ts +9 -2
  17. package/src/compartment-map.d.ts.map +1 -1
  18. package/src/compartment-map.js +737 -254
  19. package/src/digest.d.ts +22 -2
  20. package/src/digest.d.ts.map +1 -1
  21. package/src/digest.js +179 -56
  22. package/src/generic-graph.d.ts.map +1 -1
  23. package/src/generic-graph.js +8 -3
  24. package/src/guards.d.ts +18 -0
  25. package/src/guards.d.ts.map +1 -0
  26. package/src/guards.js +109 -0
  27. package/src/hooks.md +124 -0
  28. package/src/import-archive-lite.d.ts.map +1 -1
  29. package/src/import-archive-lite.js +15 -11
  30. package/src/import-archive.d.ts +5 -19
  31. package/src/import-archive.d.ts.map +1 -1
  32. package/src/import-archive.js +7 -27
  33. package/src/import-hook.d.ts +4 -3
  34. package/src/import-hook.d.ts.map +1 -1
  35. package/src/import-hook.js +138 -69
  36. package/src/import-lite.d.ts +6 -6
  37. package/src/import-lite.d.ts.map +1 -1
  38. package/src/import-lite.js +8 -5
  39. package/src/import.d.ts +3 -3
  40. package/src/import.d.ts.map +1 -1
  41. package/src/import.js +16 -6
  42. package/src/infer-exports.d.ts.map +1 -1
  43. package/src/infer-exports.js +16 -6
  44. package/src/link.d.ts +4 -3
  45. package/src/link.d.ts.map +1 -1
  46. package/src/link.js +70 -58
  47. package/src/node-modules.d.ts +4 -3
  48. package/src/node-modules.d.ts.map +1 -1
  49. package/src/node-modules.js +482 -114
  50. package/src/parse-cjs-shared-export-wrapper.d.ts.map +1 -1
  51. package/src/parse-cjs-shared-export-wrapper.js +3 -1
  52. package/src/policy-format.d.ts +22 -5
  53. package/src/policy-format.d.ts.map +1 -1
  54. package/src/policy-format.js +342 -108
  55. package/src/policy.d.ts +13 -28
  56. package/src/policy.d.ts.map +1 -1
  57. package/src/policy.js +161 -106
  58. package/src/types/canonical-name.d.ts +97 -0
  59. package/src/types/canonical-name.d.ts.map +1 -0
  60. package/src/types/canonical-name.ts +151 -0
  61. package/src/types/compartment-map-schema.d.ts +114 -35
  62. package/src/types/compartment-map-schema.d.ts.map +1 -1
  63. package/src/types/compartment-map-schema.ts +202 -37
  64. package/src/types/external.d.ts +168 -28
  65. package/src/types/external.d.ts.map +1 -1
  66. package/src/types/external.ts +215 -26
  67. package/src/types/internal.d.ts +23 -42
  68. package/src/types/internal.d.ts.map +1 -1
  69. package/src/types/internal.ts +51 -50
  70. package/src/types/node-modules.d.ts +71 -10
  71. package/src/types/node-modules.d.ts.map +1 -1
  72. package/src/types/node-modules.ts +107 -9
  73. package/src/types/policy-schema.d.ts +26 -11
  74. package/src/types/policy-schema.d.ts.map +1 -1
  75. package/src/types/policy-schema.ts +29 -16
  76. package/src/types/policy.d.ts +6 -2
  77. package/src/types/policy.d.ts.map +1 -1
  78. package/src/types/policy.ts +7 -2
  79. package/src/types/typescript.d.ts +28 -0
  80. package/src/types/typescript.d.ts.map +1 -1
  81. package/src/types/typescript.ts +37 -1
@@ -29,14 +29,19 @@
29
29
  * ImportNowHookMaker,
30
30
  * MakeImportHookMakerOptions,
31
31
  * MakeImportNowHookMakerOptions,
32
- * ModuleDescriptor,
33
32
  * ParseResult,
34
33
  * ReadFn,
35
34
  * ReadPowers,
36
35
  * ReadNowPowers,
37
36
  * StrictlyRequiredFn,
37
+ * DeferErrorFn,
38
+ * ErrorModuleSource,
39
+ * FileUrlString,
38
40
  * CompartmentSources,
39
- * DeferErrorFn
41
+ * CompartmentModuleConfiguration,
42
+ * LogOptions,
43
+ * CanonicalName,
44
+ * LocalModuleSource
40
45
  * } from './types.js'
41
46
  */
42
47
 
@@ -44,14 +49,14 @@ import { asyncTrampoline, syncTrampoline } from '@endo/trampoline';
44
49
  import { resolve } from './node-module-specifier.js';
45
50
  import {
46
51
  attenuateModuleHook,
47
- ATTENUATORS_COMPARTMENT,
48
- enforceModulePolicy,
52
+ enforcePolicyByModule,
53
+ enforcePackagePolicyByCanonicalName,
49
54
  } from './policy.js';
55
+ import { ATTENUATORS_COMPARTMENT } from './policy-format.js';
50
56
  import { unpackReadPowers } from './powers.js';
51
57
 
52
58
  // q, as in quote, for quoting strings in error messages.
53
- const q = JSON.stringify;
54
-
59
+ const { quote: q } = assert;
55
60
  const { apply } = Reflect;
56
61
 
57
62
  /**
@@ -62,7 +67,7 @@ const { apply } = Reflect;
62
67
  */
63
68
  const freeze = Object.freeze;
64
69
 
65
- const { entries, keys, assign, create } = Object;
70
+ const { keys, assign, create } = Object;
66
71
 
67
72
  const { hasOwnProperty } = Object.prototype;
68
73
  /**
@@ -71,12 +76,15 @@ const { hasOwnProperty } = Object.prototype;
71
76
  */
72
77
  const has = (haystack, needle) => apply(hasOwnProperty, haystack, [needle]);
73
78
 
79
+ const noop = () => {};
80
+
74
81
  /**
75
82
  * @param {string} rel - a relative URL
76
- * @param {string} abs - a fully qualified URL
77
- * @returns {string}
83
+ * @param {FileUrlString} abs - a fully qualified URL
84
+ * @returns {FileUrlString}
78
85
  */
79
- const resolveLocation = (rel, abs) => new URL(rel, abs).toString();
86
+ const resolveLocation = (rel, abs) =>
87
+ /** @type {FileUrlString} */ (new URL(rel, abs).toString());
80
88
 
81
89
  // this is annoying
82
90
  function getImportsFromRecord(record) {
@@ -98,14 +106,14 @@ const nodejsConventionSearchSuffixes = [
98
106
 
99
107
  /**
100
108
  * Returns `true` if `absoluteModuleSpecifier` is within the path `compartmentLocation`.
101
- * @param {string} absoluteModudeSpecifier Absolute path to module specifier
109
+ * @param {string} absoluteModuleSpecifier Absolute path to module specifier
102
110
  * @param {string} compartmentLocation Absolute path to compartment location
103
111
  * @returns {boolean}
104
112
  */
105
113
  const isLocationWithinCompartment = (
106
- absoluteModudeSpecifier,
114
+ absoluteModuleSpecifier,
107
115
  compartmentLocation,
108
- ) => absoluteModudeSpecifier.startsWith(compartmentLocation);
116
+ ) => absoluteModuleSpecifier.startsWith(compartmentLocation);
109
117
 
110
118
  /**
111
119
  * Computes the relative path to a module from its compartment location (including a leading `./`)
@@ -159,30 +167,15 @@ const findRedirect = ({
159
167
  return undefined;
160
168
  }
161
169
 
162
- // this tests the compartment referred to by the absolute path
163
- // is a dependency of the compartment descriptor
164
- if (compartmentDescriptor.compartments.has(location)) {
165
- return {
166
- specifier: relativeSpecifier(moduleSpecifierLocation, location),
167
- compartment: compartments[location],
168
- };
169
- }
170
-
171
- // this tests if the compartment descriptor is a dependency of the
172
- // compartment referred to by the absolute path.
173
- // it may be in scope, but disallowed by policy.
174
- if (
175
- someCompartmentDescriptor.compartments.has(
176
- compartmentDescriptor.location,
177
- )
178
- ) {
179
- enforceModulePolicy(
180
- compartmentDescriptor.name,
170
+ if (compartmentDescriptor.policy) {
171
+ enforcePackagePolicyByCanonicalName(
181
172
  someCompartmentDescriptor,
173
+ compartmentDescriptor,
182
174
  {
183
- errorHint: `Blocked in import hook. ${q(absoluteModuleSpecifier)} is part of the compartment map and resolves to ${location}`,
175
+ errorHint: `Blocked in importNow hook by package policy. ${q(absoluteModuleSpecifier)} is part of the compartment map and resolves to ${location}`,
184
176
  },
185
177
  );
178
+
186
179
  return {
187
180
  specifier: relativeSpecifier(moduleSpecifierLocation, location),
188
181
  compartment: compartments[location],
@@ -264,6 +257,66 @@ const nominateCandidates = (moduleSpecifier, searchSuffixes) => {
264
257
  return candidates;
265
258
  };
266
259
 
260
+ /**
261
+ * Executes the moduleSource hook for a {@link LocalModuleSource}.
262
+ *
263
+ * Preprocesses the fields for the hook.
264
+ *
265
+ * @param {import('./types.js').ModuleSourceHook | undefined} moduleSourceHook Hook function
266
+ * @param {LocalModuleSource} moduleSource Original `LocalModuleSource` object
267
+ * @param {CanonicalName} canonicalName Canonical name of the compartment/package
268
+ * @param {LogOptions} options Options
269
+ * @returns {void}
270
+ */
271
+ const executeLocalModuleSourceHook = (
272
+ moduleSourceHook,
273
+ moduleSource,
274
+ canonicalName,
275
+ { log = noop } = {},
276
+ ) => {
277
+ if (!moduleSourceHook) {
278
+ return;
279
+ }
280
+
281
+ const {
282
+ sourceLocation: location,
283
+ parser: language,
284
+ bytes,
285
+ record,
286
+ sha512,
287
+ } = moduleSource;
288
+ /** @type {string[]|undefined} */
289
+ let imports;
290
+ /** @type {string[]|undefined} */
291
+ let exports;
292
+ /** @type {string[]|undefined} */
293
+ let reexports;
294
+
295
+ if ('imports' in record) {
296
+ ({ imports } = record);
297
+ }
298
+ if ('exports' in record) {
299
+ ({ exports } = record);
300
+ }
301
+ if ('reexports' in record) {
302
+ ({ reexports } = record);
303
+ }
304
+
305
+ moduleSourceHook({
306
+ moduleSource: {
307
+ location,
308
+ language,
309
+ bytes,
310
+ imports,
311
+ exports,
312
+ reexports,
313
+ sha512,
314
+ },
315
+ canonicalName,
316
+ log,
317
+ });
318
+ };
319
+
267
320
  /**
268
321
  * Returns a generator which applies {@link ChooseModuleDescriptorOperators} in
269
322
  * `operators` using the options in options to ultimately result in a
@@ -297,7 +350,9 @@ function* chooseModuleDescriptor(
297
350
  readPowers,
298
351
  archiveOnly,
299
352
  sourceMapHook,
353
+ moduleSourceHook,
300
354
  strictlyRequiredForCompartment,
355
+ log = noop,
301
356
  },
302
357
  { maybeRead, parse, shouldDeferError = () => false },
303
358
  ) {
@@ -394,6 +449,7 @@ function* chooseModuleDescriptor(
394
449
  retained: true,
395
450
  module: candidateSpecifier,
396
451
  compartment: packageLocation,
452
+ __createdBy: 'import-hook',
397
453
  };
398
454
  }
399
455
  /** @type {StaticModuleType} */
@@ -420,7 +476,9 @@ function* chooseModuleDescriptor(
420
476
  const packageRelativeLocation = moduleLocation.slice(
421
477
  packageLocation.length,
422
478
  );
423
- packageSources[candidateSpecifier] = {
479
+
480
+ /** @type {LocalModuleSource} */
481
+ const localModuleSource = {
424
482
  location: packageRelativeLocation,
425
483
  sourceLocation: moduleLocation,
426
484
  sourceDirname,
@@ -429,6 +487,16 @@ function* chooseModuleDescriptor(
429
487
  record: concreteRecord,
430
488
  sha512,
431
489
  };
490
+
491
+ packageSources[candidateSpecifier] = localModuleSource;
492
+
493
+ executeLocalModuleSourceHook(
494
+ moduleSourceHook,
495
+ localModuleSource,
496
+ compartmentDescriptor.label,
497
+ { log },
498
+ );
499
+
432
500
  if (!shouldDeferError(parser)) {
433
501
  for (const importSpecifier of getImportsFromRecord(record)) {
434
502
  strictlyRequiredForCompartment(packageLocation).add(
@@ -458,9 +526,7 @@ const makeDeferError = (
458
526
  packageSources,
459
527
  ) => {
460
528
  /**
461
- * @param {string} specifier
462
- * @param {Error} error - error to throw on execute
463
- * @returns {StaticModuleType}
529
+ * @type {DeferErrorFn}
464
530
  */
465
531
  const deferError = (specifier, error) => {
466
532
  // strictlyRequired is populated with imports declared by modules whose parser is not using heuristics to figure
@@ -482,9 +548,11 @@ const makeDeferError = (
482
548
  throw error;
483
549
  },
484
550
  });
485
- packageSources[specifier] = {
551
+ /** @type {ErrorModuleSource} */
552
+ const moduleSource = {
486
553
  deferredError: error.message,
487
554
  };
555
+ packageSources[specifier] = moduleSource;
488
556
 
489
557
  return record;
490
558
  };
@@ -493,7 +561,7 @@ const makeDeferError = (
493
561
 
494
562
  /**
495
563
  * @param {ReadFn|ReadPowers} readPowers
496
- * @param {string} baseLocation
564
+ * @param {FileUrlString} baseLocation
497
565
  * @param {MakeImportHookMakerOptions} options
498
566
  * @returns {ImportHookMaker}
499
567
  */
@@ -510,6 +578,8 @@ export const makeImportHookMaker = (
510
578
  entryCompartmentName,
511
579
  entryModuleSpecifier,
512
580
  importHook: exitModuleImportHook = undefined,
581
+ moduleSourceHook,
582
+ log = noop,
513
583
  },
514
584
  ) => {
515
585
  // Set of specifiers for modules (scoped to compartment) whose parser is not
@@ -581,12 +651,23 @@ export const makeImportHookMaker = (
581
651
  if (record) {
582
652
  // It'd be nice to check the policy before importing it, but we can only throw a policy error if the
583
653
  // hook returns something. Otherwise, we need to fall back to the 'cannot find' error below.
584
- enforceModulePolicy(moduleSpecifier, compartmentDescriptor, {
654
+ enforcePolicyByModule(moduleSpecifier, compartmentDescriptor, {
585
655
  exit: true,
586
656
  errorHint: `Blocked in loading. ${q(
587
657
  moduleSpecifier,
588
658
  )} was not in the compartment map and an attempt was made to load it as a builtin`,
589
659
  });
660
+
661
+ if (moduleSourceHook) {
662
+ moduleSourceHook({
663
+ moduleSource: {
664
+ exit: moduleSpecifier,
665
+ },
666
+ canonicalName: compartmentDescriptor.label,
667
+ log,
668
+ });
669
+ }
670
+
590
671
  if (archiveOnly) {
591
672
  // Return a place-holder.
592
673
  // Archived compartments are not executed.
@@ -630,7 +711,9 @@ export const makeImportHookMaker = (
630
711
  readPowers,
631
712
  archiveOnly,
632
713
  sourceMapHook,
714
+ moduleSourceHook,
633
715
  strictlyRequiredForCompartment,
716
+ log,
634
717
  },
635
718
  { maybeRead, parse, shouldDeferError },
636
719
  );
@@ -659,7 +742,7 @@ export const makeImportHookMaker = (
659
742
  * Synchronous import for dynamic requires.
660
743
  *
661
744
  * @param {ReadNowPowers} readPowers
662
- * @param {string} baseLocation
745
+ * @param {FileUrlString} baseLocation
663
746
  * @param {MakeImportNowHookMakerOptions} options
664
747
  * @returns {ImportNowHookMaker}
665
748
  */
@@ -674,13 +757,14 @@ export function makeImportNowHookMaker(
674
757
  archiveOnly = false,
675
758
  sourceMapHook = undefined,
676
759
  importNowHook: exitModuleImportNowHook = undefined,
760
+ moduleSourceHook,
761
+ log = noop,
677
762
  },
678
763
  ) {
679
764
  // Set of specifiers for modules (scoped to compartment) whose parser is not
680
765
  // using heuristics to determine imports.
681
766
  /** @type {Map<string, Set<string>>} compartment name ->* module specifier */
682
767
  const strictlyRequired = new Map();
683
-
684
768
  /**
685
769
  * @param {string} compartmentName
686
770
  */
@@ -704,10 +788,13 @@ export function makeImportNowHookMaker(
704
788
  compartments,
705
789
  shouldDeferError,
706
790
  }) => {
791
+ packageLocation = resolveLocation(packageLocation, baseLocation);
792
+ const packageSources = sources[packageLocation] || create(null);
793
+ sources[packageLocation] = packageSources;
707
794
  const deferError = makeDeferError(
708
795
  strictlyRequiredForCompartment,
709
796
  packageLocation,
710
- sources,
797
+ packageSources,
711
798
  );
712
799
 
713
800
  /**
@@ -729,9 +816,9 @@ export function makeImportNowHookMaker(
729
816
  if (exitRecord) {
730
817
  // It'd be nice to check the policy before importing it, but we can only throw a policy error if the
731
818
  // hook returns something. Otherwise, we need to fall back to the 'cannot find' error below.
732
- enforceModulePolicy(moduleSpecifier, compartmentDescriptor, {
819
+ enforcePolicyByModule(moduleSpecifier, compartmentDescriptor, {
733
820
  exit: true,
734
- errorHint: `Blocked in loading. ${q(
821
+ errorHint: `Blocked exit module in loading. ${q(
735
822
  moduleSpecifier,
736
823
  )} was not in the compartment map and an attempt was made to load it as a builtin`,
737
824
  });
@@ -759,37 +846,17 @@ export function makeImportNowHookMaker(
759
846
  };
760
847
  }
761
848
 
762
- const compartmentDescriptor = compartmentDescriptors[packageLocation] || {};
849
+ const compartmentDescriptor =
850
+ compartmentDescriptors[packageLocation] || create(null);
763
851
 
764
- packageLocation = resolveLocation(packageLocation, baseLocation);
765
- const packageSources = sources[packageLocation] || create(null);
766
- sources[packageLocation] = packageSources;
767
852
  const {
768
853
  modules:
769
- moduleDescriptors = /** @type {Record<string, ModuleDescriptor>} */ (
854
+ moduleDescriptors = /** @type {Record<string, CompartmentModuleConfiguration>} */ (
770
855
  create(null)
771
856
  ),
772
857
  } = compartmentDescriptor;
773
- compartmentDescriptor.modules = moduleDescriptors;
774
858
 
775
- let { policy } = compartmentDescriptor;
776
- policy = policy || create(null);
777
-
778
- // Associates modules with compartment descriptors based on policy
779
- // in cases where the association was not made when building the
780
- // compartment map but is indicated by the policy.
781
- if ('packages' in policy && typeof policy.packages === 'object') {
782
- for (const [packageName, packagePolicyItem] of entries(policy.packages)) {
783
- if (
784
- !(packageName in compartmentDescriptor.modules) &&
785
- packageName in compartmentDescriptor.scopes &&
786
- packagePolicyItem
787
- ) {
788
- compartmentDescriptor.modules[packageName] =
789
- compartmentDescriptor.scopes[packageName];
790
- }
791
- }
792
- }
859
+ compartmentDescriptor.modules = moduleDescriptors;
793
860
 
794
861
  const { maybeReadNow, isAbsolute } = readPowers;
795
862
 
@@ -850,7 +917,9 @@ export function makeImportNowHookMaker(
850
917
  readPowers,
851
918
  archiveOnly,
852
919
  sourceMapHook,
920
+ moduleSourceHook,
853
921
  strictlyRequiredForCompartment,
922
+ log,
854
923
  },
855
924
  {
856
925
  maybeRead: maybeReadNow,
@@ -1,22 +1,22 @@
1
1
  /**
2
2
  * @overload
3
3
  * @param {ReadNowPowers} readPowers
4
- * @param {CompartmentMapDescriptor} compartmentMap
4
+ * @param {PackageCompartmentMapDescriptor} compartmentMap
5
5
  * @param {SyncImportLocationOptions} [opts]
6
6
  * @returns {Promise<Application>}
7
7
  */
8
- export function loadFromMap(readPowers: ReadNowPowers, compartmentMap: CompartmentMapDescriptor, opts?: SyncImportLocationOptions | undefined): Promise<Application>;
8
+ export function loadFromMap(readPowers: ReadNowPowers, compartmentMap: PackageCompartmentMapDescriptor, opts?: SyncImportLocationOptions | undefined): Promise<Application>;
9
9
  /**
10
10
  * @overload
11
11
  * @param {ReadFn | ReadPowers} readPowers
12
- * @param {CompartmentMapDescriptor} compartmentMap
12
+ * @param {PackageCompartmentMapDescriptor} compartmentMap
13
13
  * @param {ImportLocationOptions} [opts]
14
14
  * @returns {Promise<Application>}
15
15
  */
16
- export function loadFromMap(readPowers: ReadFn | ReadPowers, compartmentMap: CompartmentMapDescriptor, opts?: ImportLocationOptions | undefined): Promise<Application>;
17
- export function importFromMap(readPowers: ReadFn | ReadPowers, compartmentMap: CompartmentMapDescriptor, options?: ImportLocationOptions): Promise<SomeObject>;
16
+ export function loadFromMap(readPowers: ReadFn | ReadPowers, compartmentMap: PackageCompartmentMapDescriptor, opts?: ImportLocationOptions | undefined): Promise<Application>;
17
+ export function importFromMap(readPowers: ReadFn | ReadPowers, compartmentMap: PackageCompartmentMapDescriptor, options?: ImportLocationOptions): Promise<SomeObject>;
18
18
  import type { ReadNowPowers } from './types.js';
19
- import type { CompartmentMapDescriptor } from './types.js';
19
+ import type { PackageCompartmentMapDescriptor } from './types.js';
20
20
  import type { SyncImportLocationOptions } from './types.js';
21
21
  import type { Application } from './types.js';
22
22
  import type { ReadFn } from './types.js';
@@ -1 +1 @@
1
- {"version":3,"file":"import-lite.d.ts","sourceRoot":"","sources":["import-lite.js"],"names":[],"mappings":";;;;;;;AAyEG,wCACQ,aAAa,kBACb,wBAAwB,iDAEtB,OAAO,CAAC,WAAW,CAAC,CAChC;;;;;;;;AAGE,wCACQ,MAAM,GAAG,UAAU,kBACnB,wBAAwB,6CAEtB,OAAO,CAAC,WAAW,CAAC,CAChC;AA4JM,0CANI,MAAM,GAAG,UAAU,kBACnB,wBAAwB,YACxB,qBAAqB,GACnB,OAAO,CAAC,UAAU,CAAC,CAU/B;mCAxNS,YAAY;8CAAZ,YAAY;+CAAZ,YAAY;iCAAZ,YAAY;4BAAZ,YAAY;gCAAZ,YAAY;2CAAZ,YAAY;gCAAZ,YAAY"}
1
+ {"version":3,"file":"import-lite.d.ts","sourceRoot":"","sources":["import-lite.js"],"names":[],"mappings":";;;;;;;AAyEG,wCACQ,aAAa,kBACb,+BAA+B,iDAE7B,OAAO,CAAC,WAAW,CAAC,CAChC;;;;;;;;AAGE,wCACQ,MAAM,GAAG,UAAU,kBACnB,+BAA+B,6CAE7B,OAAO,CAAC,WAAW,CAAC,CAChC;AA+JM,0CANI,MAAM,GAAG,UAAU,kBACnB,+BAA+B,YAC/B,qBAAqB,GACnB,OAAO,CAAC,UAAU,CAAC,CAU/B;mCA3NS,YAAY;qDAAZ,YAAY;+CAAZ,YAAY;iCAAZ,YAAY;4BAAZ,YAAY;gCAAZ,YAAY;2CAAZ,YAAY;gCAAZ,YAAY"}
@@ -21,7 +21,6 @@
21
21
 
22
22
  /**
23
23
  * @import {
24
- * CompartmentMapDescriptor,
25
24
  * SyncImportLocationOptions,
26
25
  * ImportNowHookMaker,
27
26
  * ReadNowPowers,
@@ -31,6 +30,7 @@
31
30
  * ReadFn,
32
31
  * ReadPowers,
33
32
  * SomeObject,
33
+ * PackageCompartmentMapDescriptor,
34
34
  * } from './types.js'
35
35
  */
36
36
 
@@ -73,7 +73,7 @@ const isSyncOptions = value => {
73
73
  /**
74
74
  * @overload
75
75
  * @param {ReadNowPowers} readPowers
76
- * @param {CompartmentMapDescriptor} compartmentMap
76
+ * @param {PackageCompartmentMapDescriptor} compartmentMap
77
77
  * @param {SyncImportLocationOptions} [opts]
78
78
  * @returns {Promise<Application>}
79
79
  */
@@ -81,14 +81,14 @@ const isSyncOptions = value => {
81
81
  /**
82
82
  * @overload
83
83
  * @param {ReadFn | ReadPowers} readPowers
84
- * @param {CompartmentMapDescriptor} compartmentMap
84
+ * @param {PackageCompartmentMapDescriptor} compartmentMap
85
85
  * @param {ImportLocationOptions} [opts]
86
86
  * @returns {Promise<Application>}
87
87
  */
88
88
 
89
89
  /**
90
90
  * @param {ReadFn|ReadPowers|ReadNowPowers} readPowers
91
- * @param {CompartmentMapDescriptor} compartmentMap
91
+ * @param {PackageCompartmentMapDescriptor} compartmentMap
92
92
  * @param {ImportLocationOptions} [options]
93
93
  * @returns {Promise<Application>}
94
94
  */
@@ -98,6 +98,7 @@ export const loadFromMap = async (readPowers, compartmentMap, options = {}) => {
98
98
  searchSuffixes = undefined,
99
99
  parserForLanguage: parserForLanguageOption = {},
100
100
  Compartment: LoadCompartmentOption = Compartment,
101
+ moduleSourceHook,
101
102
  } = options;
102
103
 
103
104
  const parserForLanguage = freeze(
@@ -172,6 +173,7 @@ export const loadFromMap = async (readPowers, compartmentMap, options = {}) => {
172
173
  entryCompartmentName,
173
174
  entryModuleSpecifier,
174
175
  importHook: compartmentExitModuleImportHook,
176
+ moduleSourceHook,
175
177
  },
176
178
  );
177
179
 
@@ -195,6 +197,7 @@ export const loadFromMap = async (readPowers, compartmentMap, options = {}) => {
195
197
  compartmentDescriptors: compartmentMap.compartments,
196
198
  searchSuffixes,
197
199
  importNowHook: exitModuleImportNowHook,
200
+ moduleSourceHook,
198
201
  },
199
202
  );
200
203
  ({ compartment, pendingJobsPromise } = link(compartmentMap, {
@@ -235,7 +238,7 @@ export const loadFromMap = async (readPowers, compartmentMap, options = {}) => {
235
238
 
236
239
  /**
237
240
  * @param {ReadFn | ReadPowers} readPowers
238
- * @param {CompartmentMapDescriptor} compartmentMap
241
+ * @param {PackageCompartmentMapDescriptor} compartmentMap
239
242
  * @param {ImportLocationOptions} [options]
240
243
  * @returns {Promise<SomeObject>} the object of the imported modules exported
241
244
  * names.
package/src/import.d.ts CHANGED
@@ -2,10 +2,10 @@
2
2
  * @overload
3
3
  * @param {ReadNowPowers} readPowers
4
4
  * @param {string} moduleLocation
5
- * @param {SyncArchiveOptions} options
5
+ * @param {SyncLoadLocationOptions} options
6
6
  * @returns {Promise<Application>}
7
7
  */
8
- export function loadLocation(readPowers: ReadNowPowers, moduleLocation: string, options: SyncArchiveOptions): Promise<Application>;
8
+ export function loadLocation(readPowers: ReadNowPowers, moduleLocation: string, options: SyncLoadLocationOptions): Promise<Application>;
9
9
  /**
10
10
  * @overload
11
11
  * @param {ReadFn | ReadPowers} readPowers
@@ -37,7 +37,7 @@ export function importLocation(readPowers: ReadNowPowers, moduleLocation: string
37
37
  */
38
38
  export function importLocation(readPowers: ReadPowers | ReadFn, moduleLocation: string, options?: ImportLocationOptions | undefined): Promise<SomeObject>;
39
39
  import type { ReadNowPowers } from './types.js';
40
- import type { SyncArchiveOptions } from './types.js';
40
+ import type { SyncLoadLocationOptions } from './types.js';
41
41
  import type { Application } from './types.js';
42
42
  import type { ReadFn } from './types.js';
43
43
  import type { ReadPowers } from './types.js';
@@ -1 +1 @@
1
- {"version":3,"file":"import.d.ts","sourceRoot":"","sources":["import.js"],"names":[],"mappings":";;;;;;;AAmDG,yCACQ,aAAa,kBACb,MAAM,WACN,kBAAkB,GAChB,OAAO,CAAC,WAAW,CAAC,CAChC;;;;;;;;AAGE,yCACQ,MAAM,GAAG,UAAU,kBACnB,MAAM,8CAEJ,OAAO,CAAC,WAAW,CAAC,CAChC;;;;;;;;;;;AAuDE,2CACQ,aAAa,kBACb,MAAM,WACN,yBAAyB,GACvB,OAAO,CAAC,UAAU,CAAC,CAE/B;;;;;;;;;;;AAKE,2CACQ,UAAU,GAAC,MAAM,kBACjB,MAAM,gDAEJ,OAAO,CAAC,UAAU,CAAC,CAE/B;mCA7GS,YAAY;wCAAZ,YAAY;iCAAZ,YAAY;4BAAZ,YAAY;gCAAZ,YAAY;yCAAZ,YAAY;+CAAZ,YAAY;gCAAZ,YAAY;2CAAZ,YAAY"}
1
+ {"version":3,"file":"import.d.ts","sourceRoot":"","sources":["import.js"],"names":[],"mappings":";;;;;;;AAkDG,yCACQ,aAAa,kBACb,MAAM,WACN,uBAAuB,GACrB,OAAO,CAAC,WAAW,CAAC,CAChC;;;;;;;;AAGE,yCACQ,MAAM,GAAG,UAAU,kBACnB,MAAM,8CAEJ,OAAO,CAAC,WAAW,CAAC,CAChC;;;;;;;;;;;AAkEE,2CACQ,aAAa,kBACb,MAAM,WACN,yBAAyB,GACvB,OAAO,CAAC,UAAU,CAAC,CAE/B;;;;;;;;;;;AAKE,2CACQ,UAAU,GAAC,MAAM,kBACjB,MAAM,gDAEJ,OAAO,CAAC,UAAU,CAAC,CAE/B;mCAxHS,YAAY;6CAAZ,YAAY;iCAAZ,YAAY;4BAAZ,YAAY;gCAAZ,YAAY;yCAAZ,YAAY;+CAAZ,YAAY;gCAAZ,YAAY;2CAAZ,YAAY"}
package/src/import.js CHANGED
@@ -18,26 +18,25 @@
18
18
  * Application,
19
19
  * SyncImportLocationOptions,
20
20
  * ImportLocationOptions,
21
- * SyncArchiveOptions,
22
21
  * LoadLocationOptions,
23
22
  * SomeObject,
24
23
  * ReadNowPowers,
25
- * ArchiveOptions,
26
24
  * ReadFn,
27
25
  * ReadPowers,
26
+ SyncLoadLocationOptions,
28
27
  * } from './types.js'
29
28
  */
30
29
 
30
+ import { loadFromMap } from './import-lite.js';
31
31
  import { defaultParserForLanguage } from './import-parsers.js';
32
32
  import { mapNodeModules } from './node-modules.js';
33
- import { loadFromMap } from './import-lite.js';
34
33
 
35
34
  const { assign, create, freeze } = Object;
36
35
 
37
36
  /**
38
37
  * Add the default parserForLanguage option.
39
- * @param {ArchiveOptions} [options]
40
- * @returns {ArchiveOptions}
38
+ * @param {LoadLocationOptions} [options]
39
+ * @returns {LoadLocationOptions}
41
40
  */
42
41
  const assignParserForLanguage = (options = {}) => {
43
42
  const { parserForLanguage: parserForLanguageOption, ...rest } = options;
@@ -52,7 +51,7 @@ const assignParserForLanguage = (options = {}) => {
52
51
  * @overload
53
52
  * @param {ReadNowPowers} readPowers
54
53
  * @param {string} moduleLocation
55
- * @param {SyncArchiveOptions} options
54
+ * @param {SyncLoadLocationOptions} options
56
55
  * @returns {Promise<Application>}
57
56
  */
58
57
 
@@ -82,6 +81,7 @@ export const loadLocation = async (
82
81
  commonDependencies,
83
82
  policy,
84
83
  parserForLanguage,
84
+ log,
85
85
  languages,
86
86
  languageForExtension,
87
87
  commonjsLanguageForExtension,
@@ -89,6 +89,10 @@ export const loadLocation = async (
89
89
  workspaceLanguageForExtension,
90
90
  workspaceCommonjsLanguageForExtension,
91
91
  workspaceModuleLanguageForExtension,
92
+ unknownCanonicalNameHook,
93
+ packageDataHook,
94
+ packageDependenciesHook,
95
+ moduleSourceHook,
92
96
  ...otherOptions
93
97
  } = assignParserForLanguage(options);
94
98
  // conditions are not present in SyncArchiveOptions
@@ -107,9 +111,15 @@ export const loadLocation = async (
107
111
  workspaceCommonjsLanguageForExtension,
108
112
  workspaceModuleLanguageForExtension,
109
113
  languages,
114
+ log,
115
+ unknownCanonicalNameHook,
116
+ packageDataHook,
117
+ packageDependenciesHook,
110
118
  });
111
119
  return loadFromMap(readPowers, compartmentMap, {
112
120
  parserForLanguage,
121
+ log,
122
+ moduleSourceHook,
113
123
  ...otherOptions,
114
124
  });
115
125
  };
@@ -1 +1 @@
1
- {"version":3,"file":"infer-exports.d.ts","sourceRoot":"","sources":["infer-exports.js"],"names":[],"mappings":"AA4HO,+DAPI,iBAAiB,cACjB,GAAG,CAAC,MAAM,CAAC,SAEX,oBAAoB,kCA2B9B;AAkBM,yCAPI,iBAAiB,cACjB,GAAG,CAAC,MAAM,CAAC,SAEX,oBAAoB,GAElB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAG8B;AAU1D,mDANI,iBAAiB,mBACjB,IAAI,CAAC,iBAAiB,CAAC,mBACvB,IAAI,CAAC,iBAAiB,CAAC,cACvB,GAAG,CAAC,MAAM,CAAC,SACX,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,QA6ChC;uCAhNyD,YAAY;0CAAZ,YAAY;0BAC/C,yBAAyB"}
1
+ {"version":3,"file":"infer-exports.d.ts","sourceRoot":"","sources":["infer-exports.js"],"names":[],"mappings":"AAsIO,+DAPI,iBAAiB,cACjB,GAAG,CAAC,MAAM,CAAC,SAEX,oBAAoB,kCA2B9B;AAkBM,yCAPI,iBAAiB,cACjB,GAAG,CAAC,MAAM,CAAC,SAEX,oBAAoB,GAElB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAG8B;AAU1D,mDANI,iBAAiB,mBACjB,IAAI,CAAC,iBAAiB,CAAC,mBACvB,IAAI,CAAC,iBAAiB,CAAC,cACvB,GAAG,CAAC,MAAM,CAAC,SACX,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,QA6ChC;uCA1NyD,YAAY;0CAAZ,YAAY;0BAC/C,yBAAyB"}
@@ -63,13 +63,15 @@ function* interpretBrowserField(name, browser, main = 'index.js') {
63
63
  * @param {object} exports - the `exports` field from a package.json.
64
64
  * @param {Set<string>} conditions - build conditions about the target environment
65
65
  * for selecting relevant exports, e.g., "browser" or "node".
66
+ * @param {LanguageForExtension} types - an object to populate
67
+ * with any recognized module's type, if implied by a tag.
66
68
  * @yields {[string, string]}
67
69
  * @returns {Generator<[string, string]>}
68
70
  */
69
- function* interpretExports(name, exports, conditions) {
71
+ function* interpretExports(name, exports, conditions, types) {
70
72
  if (isArray(exports)) {
71
73
  for (const section of exports) {
72
- const results = [...interpretExports(name, section, conditions)];
74
+ const results = [...interpretExports(name, section, conditions, types)];
73
75
  if (results.length > 0) {
74
76
  yield* results;
75
77
  break;
@@ -93,12 +95,20 @@ function* interpretExports(name, exports, conditions) {
93
95
  continue; // or no-op
94
96
  } else if (key.startsWith('./') || key === '.') {
95
97
  if (name === '.') {
96
- yield* interpretExports(key, value, conditions);
98
+ yield* interpretExports(key, value, conditions, types);
97
99
  } else {
98
- yield* interpretExports(join(name, key), value, conditions);
100
+ yield* interpretExports(join(name, key), value, conditions, types);
99
101
  }
100
102
  } else if (conditions.has(key)) {
101
- yield* interpretExports(name, value, conditions);
103
+ if (types && key === 'import' && typeof value === 'string') {
104
+ // In this one case, the key "import" has carried a hint that the
105
+ // referenced module is an ECMASCript module, and that hint may be
106
+ // necessary to override whatever type might be inferred from the module
107
+ // specifier extension.
108
+ const spec = relativize(value);
109
+ types[spec] = 'mjs';
110
+ }
111
+ yield* interpretExports(name, value, conditions, types);
102
112
  // Take only the first matching tag.
103
113
  break;
104
114
  }
@@ -141,7 +151,7 @@ export const inferExportsEntries = function* inferExportsEntries(
141
151
  yield ['.', relativize(main)];
142
152
  }
143
153
  if (exports !== undefined) {
144
- yield* interpretExports('.', exports, conditions);
154
+ yield* interpretExports('.', exports, conditions, types);
145
155
  }
146
156
  // TODO Otherwise, glob 'files' for all '.js', '.cjs', and '.mjs' entry
147
157
  // modules, taking care to exclude node_modules.