@endo/compartment-mapper 1.4.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/digest.js ADDED
@@ -0,0 +1,235 @@
1
+ /* eslint-disable no-shadow */
2
+ /**
3
+ * Provides {@link digestCompartmentMap} which creates a digest of a compartment
4
+ * map suitable for archival or further inspection.
5
+ *
6
+ * @module
7
+ */
8
+
9
+ /**
10
+ * @import {
11
+ * CompartmentDescriptor,
12
+ * CompartmentMapDescriptor,
13
+ * DigestResult,
14
+ * ModuleDescriptor,
15
+ * Sources,
16
+ * } from './types.js'
17
+ */
18
+
19
+ import {
20
+ assertCompartmentMap,
21
+ pathCompare,
22
+ stringCompare,
23
+ } from './compartment-map.js';
24
+
25
+ const { create, fromEntries, entries, keys } = Object;
26
+
27
+ /**
28
+ * We attempt to produce compartment maps that are consistent regardless of
29
+ * whether the packages were originally laid out on disk for development or
30
+ * production, and other trivia like the fully qualified path of a specific
31
+ * installation.
32
+ *
33
+ * Naming compartments for the self-ascribed name and version of each Node.js
34
+ * package is insufficient because they are not guaranteed to be unique.
35
+ * Dependencies do not necessarilly come from the npm registry and may be
36
+ * for example derived from fully qualified URL's or Github org and project
37
+ * names.
38
+ * Package managers are also not required to fully deduplicate the hard
39
+ * copy of each package even when they are identical resources.
40
+ * Duplication is undesirable, but we elect to defer that problem to solutions
41
+ * in the package managers, as the alternative would be to consistently hash
42
+ * the original sources of the packages themselves, which may not even be
43
+ * available much less pristine for us.
44
+ *
45
+ * So, instead, we use the lexically least path of dependency names, delimited
46
+ * by hashes.
47
+ * The compartment maps generated by the ./node-modules.js tooling pre-compute
48
+ * these traces for our use here.
49
+ * We sort the compartments lexically on their self-ascribed name and version,
50
+ * and use the lexically least dependency name path as a tie-breaker.
51
+ * The dependency path is logical and orthogonal to the package manager's
52
+ * actual installation location, so should be orthogonal to the vagaries of the
53
+ * package manager's deduplication algorithm.
54
+ *
55
+ * @param {Record<string, CompartmentDescriptor>} compartments
56
+ * @returns {Record<string, string>} map from old to new compartment names.
57
+ */
58
+ const renameCompartments = compartments => {
59
+ /** @type {Record<string, string>} */
60
+ const compartmentRenames = create(null);
61
+ let index = 0;
62
+ let prev = '';
63
+
64
+ // The sort below combines two comparators to avoid depending on sort
65
+ // stability, which became standard as recently as 2019.
66
+ // If that date seems quaint, please accept my regards from the distant past.
67
+ // We are very proud of you.
68
+ const compartmentsByPath = Object.entries(compartments)
69
+ .map(([name, compartment]) => ({
70
+ name,
71
+ path: compartment.path,
72
+ label: compartment.label,
73
+ }))
74
+ .sort((a, b) => {
75
+ if (a.label === b.label) {
76
+ assert(a.path !== undefined && b.path !== undefined);
77
+ return pathCompare(a.path, b.path);
78
+ }
79
+ return stringCompare(a.label, b.label);
80
+ });
81
+
82
+ for (const { name, label } of compartmentsByPath) {
83
+ if (label === prev) {
84
+ compartmentRenames[name] = `${label}-n${index}`;
85
+ index += 1;
86
+ } else {
87
+ compartmentRenames[name] = label;
88
+ prev = label;
89
+ index = 1;
90
+ }
91
+ }
92
+ return compartmentRenames;
93
+ };
94
+
95
+ /**
96
+ * @param {Record<string, CompartmentDescriptor>} compartments
97
+ * @param {Sources} sources
98
+ * @param {Record<string, string>} compartmentRenames
99
+ */
100
+ const translateCompartmentMap = (compartments, sources, compartmentRenames) => {
101
+ const result = create(null);
102
+ for (const compartmentName of keys(compartmentRenames)) {
103
+ const compartment = compartments[compartmentName];
104
+ const { name, label, retained: compartmentRetained, policy } = compartment;
105
+ if (compartmentRetained) {
106
+ // rename module compartments
107
+ /** @type {Record<string, ModuleDescriptor>} */
108
+ const modules = create(null);
109
+ const compartmentModules = compartment.modules;
110
+ if (compartment.modules) {
111
+ for (const name of keys(compartmentModules).sort()) {
112
+ const { retained: moduleRetained, ...retainedModule } =
113
+ compartmentModules[name];
114
+ if (moduleRetained) {
115
+ if (retainedModule.compartment !== undefined) {
116
+ modules[name] = {
117
+ ...retainedModule,
118
+ compartment: compartmentRenames[retainedModule.compartment],
119
+ };
120
+ } else {
121
+ modules[name] = retainedModule;
122
+ }
123
+ }
124
+ }
125
+ }
126
+
127
+ // integrate sources into modules
128
+ const compartmentSources = sources[compartmentName];
129
+ if (compartmentSources) {
130
+ for (const name of keys(compartmentSources).sort()) {
131
+ const source = compartmentSources[name];
132
+ const { location, parser, exit, sha512, deferredError } = source;
133
+ if (location !== undefined) {
134
+ modules[name] = {
135
+ location,
136
+ parser,
137
+ sha512,
138
+ };
139
+ } else if (exit !== undefined) {
140
+ modules[name] = {
141
+ exit,
142
+ };
143
+ } else if (deferredError !== undefined) {
144
+ modules[name] = {
145
+ deferredError,
146
+ };
147
+ }
148
+ }
149
+ }
150
+
151
+ result[compartmentRenames[compartmentName]] = {
152
+ name,
153
+ label,
154
+ location: compartmentRenames[compartmentName],
155
+ modules,
156
+ policy,
157
+ // `scopes`, `types`, and `parsers` are not necessary since every
158
+ // loadable module is captured in `modules`.
159
+ };
160
+ }
161
+ }
162
+
163
+ return result;
164
+ };
165
+
166
+ /**
167
+ * @param {Sources} sources
168
+ * @param {Record<string, string>} compartmentRenames
169
+ * @returns {Sources}
170
+ */
171
+ const renameSources = (sources, compartmentRenames) => {
172
+ return fromEntries(
173
+ entries(sources).map(([name, compartmentSources]) => [
174
+ compartmentRenames[name],
175
+ compartmentSources,
176
+ ]),
177
+ );
178
+ };
179
+
180
+ /**
181
+ * @param {CompartmentMapDescriptor} compartmentMap
182
+ * @param {Sources} sources
183
+ * @returns {DigestResult}
184
+ */
185
+ export const digestCompartmentMap = (compartmentMap, sources) => {
186
+ const {
187
+ compartments,
188
+ entry: { compartment: entryCompartmentName, module: entryModuleSpecifier },
189
+ } = compartmentMap;
190
+
191
+ const oldToNewCompartmentNames = renameCompartments(compartments);
192
+ const digestCompartments = translateCompartmentMap(
193
+ compartments,
194
+ sources,
195
+ oldToNewCompartmentNames,
196
+ );
197
+ const digestEntryCompartmentName =
198
+ oldToNewCompartmentNames[entryCompartmentName];
199
+ const digestSources = renameSources(sources, oldToNewCompartmentNames);
200
+
201
+ const digestCompartmentMap = {
202
+ // TODO graceful migration from tags to conditions
203
+ // https://github.com/endojs/endo/issues/2388
204
+ tags: [],
205
+ entry: {
206
+ compartment: digestEntryCompartmentName,
207
+ module: entryModuleSpecifier,
208
+ },
209
+ compartments: digestCompartments,
210
+ };
211
+
212
+ // Cross-check:
213
+ // We assert that we have constructed a valid compartment map, not because it
214
+ // might not be, but to ensure that the assertCompartmentMap function can
215
+ // accept all valid compartment maps.
216
+ assertCompartmentMap(digestCompartmentMap);
217
+
218
+ const newToOldCompartmentNames = fromEntries(
219
+ entries(oldToNewCompartmentNames).map(([oldName, newName]) => [
220
+ newName,
221
+ oldName,
222
+ ]),
223
+ );
224
+
225
+ /** @type {DigestResult} */
226
+ const digestResult = {
227
+ compartmentMap: digestCompartmentMap,
228
+ sources: digestSources,
229
+ oldToNewCompartmentNames,
230
+ newToOldCompartmentNames,
231
+ compartmentRenames: newToOldCompartmentNames,
232
+ };
233
+
234
+ return digestResult;
235
+ };
@@ -0,0 +1,11 @@
1
+ /** @satisfies {Readonly<ParserForLanguage>} */
2
+ export const defaultParserForLanguage: Readonly<{
3
+ readonly 'pre-cjs-json': import("./types.js").ParserImplementation;
4
+ readonly 'pre-mjs-json': import("./types.js").ParserImplementation;
5
+ readonly cjs: import("./types.js").ParserImplementation;
6
+ readonly mjs: import("./types.js").ParserImplementation;
7
+ readonly json: import("./types.js").ParserImplementation;
8
+ readonly text: import("./types.js").ParserImplementation;
9
+ readonly bytes: import("./types.js").ParserImplementation;
10
+ }>;
11
+ //# sourceMappingURL=import-archive-all-parsers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"import-archive-all-parsers.d.ts","sourceRoot":"","sources":["import-archive-all-parsers.js"],"names":[],"mappings":"AAiBA,+CAA+C;AAC/C;;;;;;;;GAUE"}
@@ -0,0 +1,29 @@
1
+ /* Provides a set of default language behaviors (parsers) suitable for
2
+ * evaluating archives (zip files with a `compartment-map.json` and a file for
3
+ * each module) with pre-compiled _or_ original ESM and CommonJS.
4
+ *
5
+ * This module does not entrain a dependency on Babel on XS, but does on other
6
+ * platforms like Node.js.
7
+ */
8
+ /** @import {ParserForLanguage} from './types.js' */
9
+
10
+ import parserPreCjs from './parse-pre-cjs.js';
11
+ import parserJson from './parse-json.js';
12
+ import parserText from './parse-text.js';
13
+ import parserBytes from './parse-bytes.js';
14
+ import parserPreMjs from './parse-pre-mjs.js';
15
+ import parserMjs from './parse-mjs.js';
16
+ import parserCjs from './parse-cjs.js';
17
+
18
+ /** @satisfies {Readonly<ParserForLanguage>} */
19
+ export const defaultParserForLanguage = Object.freeze(
20
+ /** @type {const} */ ({
21
+ 'pre-cjs-json': parserPreCjs,
22
+ 'pre-mjs-json': parserPreMjs,
23
+ cjs: parserCjs,
24
+ mjs: parserMjs,
25
+ json: parserJson,
26
+ text: parserText,
27
+ bytes: parserBytes,
28
+ }),
29
+ );
@@ -1 +1 @@
1
- {"version":3,"file":"import-archive-lite.d.ts","sourceRoot":"","sources":["import-archive-lite.js"],"names":[],"mappings":"AAoPO,2CALI,UAAU,oFAGR,OAAO,CAAC,WAAW,CAAC,CA6JhC;AAQM,wCALI,MAAM,GAAG,UAAU,mBACnB,MAAM,8CAEJ,OAAO,CAAC,WAAW,CAAC,CAwBhC;AAQM,0CALI,MAAM,GAAG,UAAU,mBACnB,MAAM,WACN,kBAAkB,GAChB,OAAO,CAAC,UAAU,CAAC,CAK/B;yCApZS,YAAY;iCAAZ,YAAY;4BAAZ,YAAY;gCAAZ,YAAY;wCAAZ,YAAY;gCAAZ,YAAY"}
1
+ {"version":3,"file":"import-archive-lite.d.ts","sourceRoot":"","sources":["import-archive-lite.js"],"names":[],"mappings":"AAoPO,2CALI,UAAU,oFAGR,OAAO,CAAC,WAAW,CAAC,CAiKhC;AAQM,wCALI,MAAM,GAAG,UAAU,mBACnB,MAAM,8CAEJ,OAAO,CAAC,WAAW,CAAC,CAwBhC;AAQM,0CALI,MAAM,GAAG,UAAU,mBACnB,MAAM,WACN,kBAAkB,GAChB,OAAO,CAAC,UAAU,CAAC,CAK/B;yCAxZS,YAAY;iCAAZ,YAAY;4BAAZ,YAAY;gCAAZ,YAAY;wCAAZ,YAAY;gCAAZ,YAAY"}
@@ -257,6 +257,7 @@ export const parseArchive = async (
257
257
  modules = undefined,
258
258
  importHook: exitModuleImportHook = undefined,
259
259
  parserForLanguage: parserForLanguageOption = {},
260
+ __native__ = false,
260
261
  } = options;
261
262
 
262
263
  const parserForLanguage = freeze(
@@ -343,6 +344,7 @@ export const parseArchive = async (
343
344
  }),
344
345
  ),
345
346
  Compartment: CompartmentParseOption,
347
+ __native__,
346
348
  });
347
349
 
348
350
  await pendingJobsPromise;
@@ -362,6 +364,7 @@ export const parseArchive = async (
362
364
  transforms,
363
365
  __shimTransforms__,
364
366
  Compartment: CompartmentOption = CompartmentParseOption,
367
+ __native__,
365
368
  importHook: exitModuleImportHook,
366
369
  } = options || {};
367
370
 
@@ -388,6 +391,7 @@ export const parseArchive = async (
388
391
  transforms,
389
392
  __shimTransforms__,
390
393
  Compartment: CompartmentOption,
394
+ __native__,
391
395
  });
392
396
 
393
397
  await pendingJobsPromise;
@@ -1 +1 @@
1
- {"version":3,"file":"import-lite.d.ts","sourceRoot":"","sources":["import-lite.js"],"names":[],"mappings":";;;;;;;AAuEG,wCACQ,aAAa,kBACb,wBAAwB,iDAEtB,OAAO,CAAC,WAAW,CAAC,CAChC;;;;;;;;AAGE,wCACQ,MAAM,GAAG,UAAU,kBACnB,wBAAwB,6CAEtB,OAAO,CAAC,WAAW,CAAC,CAChC;AAuJM,0CANI,MAAM,GAAG,UAAU,kBACnB,wBAAwB,gDAEtB,OAAO,CAAC,UAAU,CAAC,CAU/B;mCAnNS,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":";;;;;;;AAuEG,wCACQ,aAAa,kBACb,wBAAwB,iDAEtB,OAAO,CAAC,WAAW,CAAC,CAChC;;;;;;;;AAGE,wCACQ,MAAM,GAAG,UAAU,kBACnB,wBAAwB,6CAEtB,OAAO,CAAC,WAAW,CAAC,CAChC;AA0JM,0CANI,MAAM,GAAG,UAAU,kBACnB,wBAAwB,gDAEtB,OAAO,CAAC,UAAU,CAAC,CAU/B;mCAtNS,YAAY;8CAAZ,YAAY;+CAAZ,YAAY;iCAAZ,YAAY;4BAAZ,YAAY;gCAAZ,YAAY;2CAAZ,YAAY;gCAAZ,YAAY"}
@@ -152,6 +152,7 @@ export const loadFromMap = async (readPowers, compartmentMap, options = {}) => {
152
152
  transforms,
153
153
  __shimTransforms__,
154
154
  Compartment: CompartmentOption = LoadCompartmentOption,
155
+ __native__,
155
156
  importHook: exitModuleImportHook,
156
157
  } = options;
157
158
  const compartmentExitModuleImportHook = exitModuleImportHookMaker({
@@ -201,6 +202,7 @@ export const loadFromMap = async (readPowers, compartmentMap, options = {}) => {
201
202
  syncModuleTransforms,
202
203
  __shimTransforms__,
203
204
  Compartment: CompartmentOption,
205
+ __native__,
204
206
  }));
205
207
  } else {
206
208
  // sync module transforms are allowed, because they are "compatible"
@@ -215,6 +217,7 @@ export const loadFromMap = async (readPowers, compartmentMap, options = {}) => {
215
217
  syncModuleTransforms,
216
218
  __shimTransforms__,
217
219
  Compartment: CompartmentOption,
220
+ __native__,
218
221
  }));
219
222
  }
220
223
 
@@ -1 +1 @@
1
- {"version":3,"file":"import.d.ts","sourceRoot":"","sources":["import.js"],"names":[],"mappings":";;;;;;;AAiDG,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;;;;;;;;;;;AAqDE,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;mCA3GS,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":";;;;;;;AAiDG,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"}
package/src/import.js CHANGED
@@ -76,6 +76,7 @@ export const loadLocation = async (
76
76
  const {
77
77
  dev,
78
78
  tags,
79
+ strict,
79
80
  commonDependencies,
80
81
  policy,
81
82
  parserForLanguage,
@@ -93,6 +94,7 @@ export const loadLocation = async (
93
94
  'conditions' in options ? options.conditions || tags : tags;
94
95
  const compartmentMap = await mapNodeModules(readPowers, moduleLocation, {
95
96
  dev,
97
+ strict,
96
98
  conditions,
97
99
  commonDependencies,
98
100
  policy,
package/src/link.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"link.d.ts","sourceRoot":"","sources":["link.js"],"names":[],"mappings":"AAsPO,sEAJI,wBAAwB,WACxB,WAAW,GACT,UAAU,CAwKtB;AAOM,yCAJI,wBAAwB,WACxB,WAAW,eAIqB;8CA5YjC,YAAY;iCAAZ,YAAY;gCAAZ,YAAY"}
1
+ {"version":3,"file":"link.d.ts","sourceRoot":"","sources":["link.js"],"names":[],"mappings":"AAsPO,sEAJI,wBAAwB,WACxB,WAAW,GACT,UAAU,CA0KtB;AAOM,yCAJI,wBAAwB,WACxB,WAAW,eAIqB;8CA9YjC,YAAY;iCAAZ,YAAY;gCAAZ,YAAY"}
package/src/link.js CHANGED
@@ -258,6 +258,7 @@ export const link = (
258
258
  moduleTransforms,
259
259
  syncModuleTransforms,
260
260
  __shimTransforms__ = [],
261
+ __native__ = false,
261
262
  archiveOnly = false,
262
263
  Compartment = defaultCompartment,
263
264
  } = options;
@@ -362,6 +363,7 @@ export const link = (
362
363
  transforms,
363
364
  __shimTransforms__,
364
365
  __options__: true,
366
+ __native__,
365
367
  });
366
368
 
367
369
  if (!archiveOnly) {
@@ -1 +1 @@
1
- {"version":3,"file":"map-parser.d.ts","sourceRoot":"","sources":["map-parser.js"],"names":[],"mappings":"AA0SO,+FAHI,qBAAqB,GACnB,YAAY,CA+CxB;2CApUS,YAAY;kCAAZ,YAAY"}
1
+ {"version":3,"file":"map-parser.d.ts","sourceRoot":"","sources":["map-parser.js"],"names":[],"mappings":"AA6SO,+FAHI,qBAAqB,GACnB,YAAY,CA+CxB;2CAvUS,YAAY;kCAAZ,YAAY"}
package/src/map-parser.js CHANGED
@@ -18,6 +18,9 @@
18
18
  * SyncModuleTransform,
19
19
  * SyncModuleTransforms
20
20
  * } from './types.js';
21
+ * @import {
22
+ * EReturn
23
+ * } from '@endo/eventual-send';
21
24
  */
22
25
 
23
26
  import { syncTrampoline, asyncTrampoline } from '@endo/trampoline';
@@ -82,7 +85,7 @@ const makeExtensionParser = (
82
85
  * @param {string} location
83
86
  * @param {string} packageLocation
84
87
  * @param {*} options
85
- * @returns {Generator<ReturnType<ModuleTransform>|ReturnType<SyncModuleTransform>, ParseResult, Awaited<ReturnType<ModuleTransform>|ReturnType<SyncModuleTransform>>>}
88
+ * @returns {Generator<ReturnType<ModuleTransform>|ReturnType<SyncModuleTransform>, ParseResult, EReturn<ModuleTransform|SyncModuleTransform>>}
86
89
  */
87
90
  function* getParserGenerator(
88
91
  bytes,
@@ -1,4 +1,4 @@
1
- export function compartmentMapForNodeModules(readPowers: ReadFn | ReadPowers | MaybeReadPowers, packageLocation: string, conditions: Set<string>, packageDescriptor: object, moduleSpecifier: string, options?: CompartmentMapForNodeModulesOptions | undefined): Promise<CompartmentMapDescriptor>;
1
+ export function compartmentMapForNodeModules(readPowers: ReadFn | ReadPowers | MaybeReadPowers, packageLocation: string, conditionsOption: Set<string>, packageDescriptor: object, moduleSpecifier: string, options?: CompartmentMapForNodeModulesOptions | undefined): Promise<CompartmentMapDescriptor>;
2
2
  export function mapNodeModules(readPowers: ReadFn | ReadPowers | MaybeReadPowers, moduleLocation: string, options?: MapNodeModulesOptions | undefined): Promise<CompartmentMapDescriptor>;
3
3
  /**
4
4
  * The graph is an intermediate object model that the functions of this module
@@ -1 +1 @@
1
- {"version":3,"file":"node-modules.d.ts","sourceRoot":"","sources":["node-modules.js"],"names":[],"mappings":"AAy1BO,yDARI,MAAM,GAAG,UAAU,GAAG,eAAe,mBACrC,MAAM,cACN,GAAG,CAAC,MAAM,CAAC,qBACX,MAAM,mBACN,MAAM,8DAEJ,OAAO,CAAC,wBAAwB,CAAC,CAkD7C;AAQM,2CALI,MAAM,GAAG,UAAU,GAAG,eAAe,kBACrC,MAAM,gDAEJ,OAAO,CAAC,wBAAwB,CAAC,CA6B7C;;;;;;;oBAr4BY,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC;;WAKnB,MAAM;UACN,MAAM;UACN,KAAK,CAAC,MAAM,CAAC;iBACb,KAAK,CAAC,MAAM,CAAC;qBACb,OAAO;qBACP,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;qBACtB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;;;;;yBACtB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;;;;;aAEtB,oBAAoB;;;;;WAEpB,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC;;;kCAMxB,oBAAoB;gCACpB,oBAAoB;2CACpB,oBAAoB;yCACpB,oBAAoB;eACpB,GAAG,CAAC,MAAM,CAAC;;0CAIZ,MAAM,CAAC,MAAM,EAAE;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAC,CAAC;iDA+E/C,MAAM,KACJ,OAAO,CAAC,MAAM,CAAC;4BAvHlB,YAAY;gCAAZ,YAAY;qCAAZ,YAAY;yDAAZ,YAAY;8CAAZ,YAAY;2CAAZ,YAAY;0CAAZ,YAAY;8BAAZ,YAAY"}
1
+ {"version":3,"file":"node-modules.d.ts","sourceRoot":"","sources":["node-modules.js"],"names":[],"mappings":"AAs2BO,yDARI,MAAM,GAAG,UAAU,GAAG,eAAe,mBACrC,MAAM,oBACN,GAAG,CAAC,MAAM,CAAC,qBACX,MAAM,mBACN,MAAM,8DAEJ,OAAO,CAAC,wBAAwB,CAAC,CA+D7C;AAQM,2CALI,MAAM,GAAG,UAAU,GAAG,eAAe,kBACrC,MAAM,gDAEJ,OAAO,CAAC,wBAAwB,CAAC,CA6B7C;;;;;;;oBA/5BY,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC;;WAKnB,MAAM;UACN,MAAM;UACN,KAAK,CAAC,MAAM,CAAC;iBACb,KAAK,CAAC,MAAM,CAAC;qBACb,OAAO;qBACP,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;qBACtB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;;;;;yBACtB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;;;;;aAEtB,oBAAoB;;;;;WAEpB,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC;;;kCAMxB,oBAAoB;gCACpB,oBAAoB;2CACpB,oBAAoB;yCACpB,oBAAoB;eACpB,GAAG,CAAC,MAAM,CAAC;;0CAIZ,MAAM,CAAC,MAAM,EAAE;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAC,CAAC;iDA+E/C,MAAM,KACJ,OAAO,CAAC,MAAM,CAAC;4BAvHlB,YAAY;gCAAZ,YAAY;qCAAZ,YAAY;yDAAZ,YAAY;8CAAZ,YAAY;2CAAZ,YAAY;0CAAZ,YAAY;8BAAZ,YAAY"}
@@ -296,6 +296,7 @@ const inferParsers = (descriptor, location, languageOptions) => {
296
296
  * @param {boolean | undefined} dev
297
297
  * @param {CommonDependencyDescriptors} commonDependencyDescriptors
298
298
  * @param {LanguageOptions} languageOptions
299
+ * @param {boolean} strict
299
300
  * @param {Map<string, Array<string>>} preferredPackageLogicalPathMap
300
301
  * @param {Array<string>} logicalPath
301
302
  * @returns {Promise<undefined>}
@@ -310,6 +311,7 @@ const graphPackage = async (
310
311
  dev,
311
312
  commonDependencyDescriptors,
312
313
  languageOptions,
314
+ strict,
313
315
  preferredPackageLogicalPathMap = new Map(),
314
316
  logicalPath = [],
315
317
  ) => {
@@ -344,14 +346,18 @@ const graphPackage = async (
344
346
  devDependencies = {},
345
347
  } = packageDescriptor;
346
348
  const allDependencies = {};
347
- assign(allDependencies, commonDependencyDescriptors);
348
- for (const [name, { spec }] of Object.entries(commonDependencyDescriptors)) {
349
- allDependencies[name] = spec;
349
+ for (const [name, descriptor] of Object.entries(
350
+ commonDependencyDescriptors,
351
+ )) {
352
+ if (Object(descriptor) === descriptor) {
353
+ const { spec } = descriptor;
354
+ allDependencies[name] = spec;
355
+ }
350
356
  }
351
357
  assign(allDependencies, dependencies);
352
358
  assign(allDependencies, peerDependencies);
353
- for (const [name, { optional }] of Object.entries(peerDependenciesMeta)) {
354
- if (optional) {
359
+ for (const [name, meta] of Object.entries(peerDependenciesMeta)) {
360
+ if (Object(meta) === meta && meta.optional) {
355
361
  optionals.add(name);
356
362
  }
357
363
  }
@@ -360,7 +366,7 @@ const graphPackage = async (
360
366
  for (const name of Object.keys(optionalDependencies)) {
361
367
  optionals.add(name);
362
368
  }
363
- if (dev !== undefined && dev !== null ? dev : conditions.has('development')) {
369
+ if (dev) {
364
370
  assign(allDependencies, devDependencies);
365
371
  }
366
372
 
@@ -380,6 +386,7 @@ const graphPackage = async (
380
386
  conditions,
381
387
  preferredPackageLogicalPathMap,
382
388
  languageOptions,
389
+ strict,
383
390
  childLogicalPath,
384
391
  optional,
385
392
  commonDependencyDescriptors,
@@ -481,6 +488,7 @@ const graphPackage = async (
481
488
  * @param {Set<string>} conditions
482
489
  * @param {Map<string, Array<string>>} preferredPackageLogicalPathMap
483
490
  * @param {LanguageOptions} languageOptions
491
+ * @param {boolean} strict
484
492
  * @param {Array<string>} [childLogicalPath]
485
493
  * @param {boolean} [optional] - whether the dependency is optional
486
494
  * @param {object} [commonDependencyDescriptors] - dependencies to be added to all packages
@@ -495,6 +503,7 @@ const gatherDependency = async (
495
503
  conditions,
496
504
  preferredPackageLogicalPathMap,
497
505
  languageOptions,
506
+ strict,
498
507
  childLogicalPath = [],
499
508
  optional = false,
500
509
  commonDependencyDescriptors = undefined,
@@ -507,7 +516,7 @@ const gatherDependency = async (
507
516
  );
508
517
  if (dependency === undefined) {
509
518
  // allow the dependency to be missing if optional
510
- if (optional) {
519
+ if (optional || !strict) {
511
520
  return;
512
521
  }
513
522
  throw Error(`Cannot find dependency ${name} for ${packageLocation}`);
@@ -532,6 +541,7 @@ const gatherDependency = async (
532
541
  false,
533
542
  commonDependencyDescriptors,
534
543
  languageOptions,
544
+ strict,
535
545
  preferredPackageLogicalPathMap,
536
546
  childLogicalPath,
537
547
  );
@@ -556,6 +566,7 @@ const gatherDependency = async (
556
566
  * only this package).
557
567
  * @param {Record<string,string>} commonDependencies - dependencies to be added to all packages
558
568
  * @param {LanguageOptions} languageOptions
569
+ * @param {boolean} strict
559
570
  */
560
571
  const graphPackages = async (
561
572
  maybeRead,
@@ -566,6 +577,7 @@ const graphPackages = async (
566
577
  dev,
567
578
  commonDependencies,
568
579
  languageOptions,
580
+ strict,
569
581
  ) => {
570
582
  const memo = create(null);
571
583
  /**
@@ -623,6 +635,7 @@ const graphPackages = async (
623
635
  dev,
624
636
  commonDependencyDescriptors,
625
637
  languageOptions,
638
+ strict,
626
639
  );
627
640
  return graph;
628
641
  };
@@ -849,7 +862,7 @@ const makeLanguageOptions = ({
849
862
  /**
850
863
  * @param {ReadFn | ReadPowers | MaybeReadPowers} readPowers
851
864
  * @param {string} packageLocation
852
- * @param {Set<string>} conditions
865
+ * @param {Set<string>} conditionsOption
853
866
  * @param {object} packageDescriptor
854
867
  * @param {string} moduleSpecifier
855
868
  * @param {CompartmentMapForNodeModulesOptions} [options]
@@ -858,24 +871,37 @@ const makeLanguageOptions = ({
858
871
  export const compartmentMapForNodeModules = async (
859
872
  readPowers,
860
873
  packageLocation,
861
- conditions,
874
+ conditionsOption,
862
875
  packageDescriptor,
863
876
  moduleSpecifier,
864
877
  options = {},
865
878
  ) => {
866
- const { dev = undefined, commonDependencies = {}, policy } = options;
879
+ const {
880
+ dev = false,
881
+ commonDependencies = {},
882
+ policy,
883
+ strict = false,
884
+ } = options;
867
885
  const { maybeRead, canonical } = unpackReadPowers(readPowers);
868
886
  const languageOptions = makeLanguageOptions(options);
869
887
 
888
+ const conditions = new Set(conditionsOption || []);
889
+
890
+ // dev is only set for the entry package, and implied by the development
891
+ // condition.
892
+ // The dev option is deprecated in favor of using conditions, since that
893
+ // covers more intentional behaviors of the development mode.
894
+
870
895
  const graph = await graphPackages(
871
896
  maybeRead,
872
897
  canonical,
873
898
  packageLocation,
874
899
  conditions,
875
900
  packageDescriptor,
876
- dev,
901
+ dev || (conditions && conditions.has('development')),
877
902
  commonDependencies,
878
903
  languageOptions,
904
+ strict,
879
905
  );
880
906
 
881
907
  if (policy) {
@@ -15,12 +15,14 @@ export type ExecuteOptions = Partial<{
15
15
  __shimTransforms__: Array<Transform>;
16
16
  attenuations: Record<string, object>;
17
17
  Compartment: typeof Compartment;
18
+ __native__: boolean;
18
19
  }> & ModulesOption & ExitModuleImportHookOption;
19
20
  export type ParseArchiveOptions = Partial<{
20
21
  expectedSha512: string;
21
22
  computeSha512: HashFn;
22
23
  computeSourceLocation: ComputeSourceLocationHook;
23
24
  computeSourceMapLocation: ComputeSourceMapLocationHook;
25
+ __native__: boolean;
24
26
  }> & ModulesOption & CompartmentOption & ParserForLanguageOption & ExitModuleImportHookOption;
25
27
  export type LoadArchiveOptions = ParseArchiveOptions;
26
28
  export type MapNodeModulesOptions = MapNodeModulesOptionsOmitPolicy & PolicyOption;
@@ -43,6 +45,13 @@ type MapNodeModulesOptionsOmitPolicy = Partial<{
43
45
  * of having the `"development"` condition.
44
46
  */
45
47
  dev: boolean;
48
+ /**
49
+ * Indicates that the node_modules tree should fail to map if it does not
50
+ * strictly reach every expected package.
51
+ * By default, unreachable packages are simply omitted from the map,
52
+ * which defers some errors to when modules load.
53
+ */
54
+ strict: boolean;
46
55
  /** Dependencies to make reachable from any package */
47
56
  commonDependencies: Record<string, string>;
48
57
  /** Maps extensions to languages for all packages, like `txt` to `text` */
@@ -139,12 +148,46 @@ type ImportingOptions = ModulesOption & SyncOrAsyncImportingOptions & ExitModule
139
148
  type SyncImportingOptions = ModulesOption & SyncOrAsyncImportingOptions & ExitModuleImportNowHookOption;
140
149
  type LinkingOptions = ParserForLanguageOption & CompartmentOption & SyncModuleTransformsOption & ModuleTransformsOption;
141
150
  /**
142
- * The result of `captureFromMap`.
151
+ * Result of `digestCompartmentMap()`
143
152
  */
144
- export type CaptureResult = {
145
- captureCompartmentMap: CompartmentMapDescriptor;
146
- captureSources: Sources;
153
+ export interface DigestResult {
154
+ /**
155
+ * Normalized `CompartmentMapDescriptor`
156
+ */
157
+ compartmentMap: CompartmentMapDescriptor;
158
+ /**
159
+ * Sources found in the `CompartmentMapDescriptor`
160
+ */
161
+ sources: Sources;
162
+ /**
163
+ * A record of renamed {@link CompartmentDescriptor CompartmentDescriptors}
164
+ * from _new_ to _original_ name
165
+ */
166
+ newToOldCompartmentNames: Record<string, string>;
167
+ /**
168
+ * A record of renamed {@link CompartmentDescriptor CompartmentDescriptors}
169
+ * from _original_ to _new_ name
170
+ */
171
+ oldToNewCompartmentNames: Record<string, string>;
172
+ /**
173
+ * Alias for `newToOldCompartmentNames`
174
+ * @deprecated Use {@link newToOldCompartmentNames} instead.
175
+ */
147
176
  compartmentRenames: Record<string, string>;
177
+ }
178
+ /**
179
+ * The result of `captureFromMap`.
180
+ */
181
+ export type CaptureResult = Omit<DigestResult, 'compartmentMap' | 'sources'> & {
182
+ captureCompartmentMap: DigestResult['compartmentMap'];
183
+ captureSources: DigestResult['sources'];
184
+ };
185
+ /**
186
+ * The result of `makeArchiveCompartmentMap`
187
+ */
188
+ export type ArchiveResult = Omit<DigestResult, 'compartmentMap' | 'sources'> & {
189
+ archiveCompartmentMap: DigestResult['compartmentMap'];
190
+ archiveSources: DigestResult['sources'];
148
191
  };
149
192
  /**
150
193
  * The compartment mapper can capture the Sources for all loaded modules