@endo/compartment-mapper 1.6.3 → 2.1.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/package.json +24 -14
- package/src/archive-lite.d.ts +7 -7
- package/src/archive-lite.d.ts.map +1 -1
- package/src/archive-lite.js +81 -30
- package/src/archive.d.ts.map +1 -1
- package/src/archive.js +7 -0
- package/src/bundle-lite.d.ts +3 -3
- package/src/bundle-lite.d.ts.map +1 -1
- package/src/bundle-lite.js +19 -24
- package/src/bundle.d.ts +3 -3
- package/src/bundle.d.ts.map +1 -1
- package/src/bundle.js +19 -24
- package/src/capture-lite.d.ts +2 -2
- package/src/capture-lite.d.ts.map +1 -1
- package/src/capture-lite.js +243 -25
- package/src/compartment-map.d.ts +9 -2
- package/src/compartment-map.d.ts.map +1 -1
- package/src/compartment-map.js +738 -254
- package/src/digest.d.ts +22 -2
- package/src/digest.d.ts.map +1 -1
- package/src/digest.js +180 -57
- package/src/generic-graph.d.ts +7 -25
- package/src/generic-graph.d.ts.map +1 -1
- package/src/generic-graph.js +83 -108
- package/src/guards.d.ts +18 -0
- package/src/guards.d.ts.map +1 -0
- package/src/guards.js +109 -0
- package/src/hooks.md +124 -0
- package/src/import-archive-lite.d.ts.map +1 -1
- package/src/import-archive-lite.js +15 -11
- package/src/import-archive.d.ts +5 -19
- package/src/import-archive.d.ts.map +1 -1
- package/src/import-archive.js +7 -27
- package/src/import-hook.d.ts +4 -3
- package/src/import-hook.d.ts.map +1 -1
- package/src/import-hook.js +140 -70
- package/src/import-lite.d.ts +6 -6
- package/src/import-lite.d.ts.map +1 -1
- package/src/import-lite.js +8 -5
- package/src/import.d.ts +3 -3
- package/src/import.d.ts.map +1 -1
- package/src/import.js +16 -6
- package/src/infer-exports.d.ts +4 -2
- package/src/infer-exports.d.ts.map +1 -1
- package/src/infer-exports.js +172 -23
- package/src/link.d.ts +4 -3
- package/src/link.d.ts.map +1 -1
- package/src/link.js +122 -52
- package/src/node-modules.d.ts +4 -3
- package/src/node-modules.d.ts.map +1 -1
- package/src/node-modules.js +513 -151
- package/src/parse-cjs-shared-export-wrapper.d.ts.map +1 -1
- package/src/parse-cjs-shared-export-wrapper.js +3 -1
- package/src/pattern-replacement.d.ts +6 -0
- package/src/pattern-replacement.d.ts.map +1 -0
- package/src/pattern-replacement.js +198 -0
- package/src/policy-format.d.ts +22 -5
- package/src/policy-format.d.ts.map +1 -1
- package/src/policy-format.js +342 -108
- package/src/policy.d.ts +13 -28
- package/src/policy.d.ts.map +1 -1
- package/src/policy.js +161 -106
- package/src/types/canonical-name.d.ts +97 -0
- package/src/types/canonical-name.d.ts.map +1 -0
- package/src/types/canonical-name.ts +151 -0
- package/src/types/compartment-map-schema.d.ts +121 -35
- package/src/types/compartment-map-schema.d.ts.map +1 -1
- package/src/types/compartment-map-schema.ts +211 -37
- package/src/types/external.d.ts +240 -76
- package/src/types/external.d.ts.map +1 -1
- package/src/types/external.ts +305 -74
- package/src/types/generic-graph.d.ts +8 -2
- package/src/types/generic-graph.d.ts.map +1 -1
- package/src/types/generic-graph.ts +7 -2
- package/src/types/internal.d.ts +31 -50
- package/src/types/internal.d.ts.map +1 -1
- package/src/types/internal.ts +60 -58
- package/src/types/node-modules.d.ts +112 -14
- package/src/types/node-modules.d.ts.map +1 -1
- package/src/types/node-modules.ts +152 -13
- package/src/types/pattern-replacement.d.ts +62 -0
- package/src/types/pattern-replacement.d.ts.map +1 -0
- package/src/types/pattern-replacement.ts +70 -0
- package/src/types/policy-schema.d.ts +26 -11
- package/src/types/policy-schema.d.ts.map +1 -1
- package/src/types/policy-schema.ts +29 -16
- package/src/types/policy.d.ts +6 -2
- package/src/types/policy.d.ts.map +1 -1
- package/src/types/policy.ts +7 -2
- package/src/types/powers.d.ts +11 -9
- package/src/types/powers.d.ts.map +1 -1
- package/src/types/powers.ts +11 -10
- package/src/types/typescript.d.ts +28 -0
- package/src/types/typescript.d.ts.map +1 -1
- package/src/types/typescript.ts +37 -1
package/src/link.js
CHANGED
|
@@ -13,28 +13,39 @@
|
|
|
13
13
|
/**
|
|
14
14
|
* @import {ModuleMapHook} from 'ses'
|
|
15
15
|
* @import {
|
|
16
|
-
* CompartmentDescriptor,
|
|
17
|
-
* CompartmentMapDescriptor,
|
|
18
16
|
* ImportNowHookMaker,
|
|
19
17
|
* LinkOptions,
|
|
20
18
|
* LinkResult,
|
|
21
|
-
* ModuleDescriptor,
|
|
22
19
|
* ParseFn,
|
|
23
20
|
* AsyncParseFn,
|
|
24
21
|
* ParserForLanguage,
|
|
25
22
|
* ParserImplementation,
|
|
26
23
|
* ShouldDeferError,
|
|
24
|
+
* ScopeDescriptor,
|
|
25
|
+
* CompartmentModuleConfiguration,
|
|
26
|
+
* PackageCompartmentMapDescriptor,
|
|
27
|
+
* FileUrlString,
|
|
28
|
+
* PackageCompartmentDescriptor,
|
|
29
|
+
* FileCompartmentMapDescriptor,
|
|
30
|
+
* FileCompartmentDescriptor,
|
|
31
|
+
* FileModuleConfiguration,
|
|
27
32
|
* } from './types.js'
|
|
33
|
+
* @import {SubpathReplacer} from './types/pattern-replacement.js'
|
|
28
34
|
*/
|
|
29
35
|
|
|
30
36
|
import { makeMapParsers } from './map-parser.js';
|
|
31
37
|
import { resolve as resolveFallback } from './node-module-specifier.js';
|
|
32
38
|
import {
|
|
33
|
-
ATTENUATORS_COMPARTMENT,
|
|
34
39
|
attenuateGlobals,
|
|
35
|
-
|
|
40
|
+
enforcePolicyByModule,
|
|
36
41
|
makeDeferredAttenuatorsProvider,
|
|
37
42
|
} from './policy.js';
|
|
43
|
+
import { ATTENUATORS_COMPARTMENT } from './policy-format.js';
|
|
44
|
+
import {
|
|
45
|
+
isCompartmentModuleConfiguration,
|
|
46
|
+
isExitModuleConfiguration,
|
|
47
|
+
} from './guards.js';
|
|
48
|
+
import { makeMultiSubpathReplacer } from './pattern-replacement.js';
|
|
38
49
|
|
|
39
50
|
const { assign, create, entries, freeze } = Object;
|
|
40
51
|
const { hasOwnProperty } = Object.prototype;
|
|
@@ -47,17 +58,17 @@ const { allSettled } = Promise;
|
|
|
47
58
|
*/
|
|
48
59
|
const promiseAllSettled = allSettled.bind(Promise);
|
|
49
60
|
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
// q, as in quote, for strings in error messages.
|
|
53
|
-
const q = JSON.stringify;
|
|
61
|
+
const DefaultCompartment = Compartment;
|
|
54
62
|
|
|
55
63
|
/**
|
|
64
|
+
* TODO: can we just use `Object.hasOwn` instead?
|
|
56
65
|
* @param {Record<string, unknown>} object
|
|
57
66
|
* @param {string} key
|
|
58
67
|
* @returns {boolean}
|
|
59
68
|
*/
|
|
60
69
|
const has = (object, key) => apply(hasOwnProperty, object, [key]);
|
|
70
|
+
// q, as in quote, for strings in error messages.
|
|
71
|
+
const { quote: q } = assert;
|
|
61
72
|
|
|
62
73
|
/**
|
|
63
74
|
* For a full, absolute module specifier like "dependency",
|
|
@@ -89,11 +100,11 @@ const trimModuleSpecifierPrefix = (moduleSpecifier, prefix) => {
|
|
|
89
100
|
* Any module specifier with an absolute prefix should be captured by
|
|
90
101
|
* the `moduleMap` or `moduleMapHook`.
|
|
91
102
|
*
|
|
92
|
-
* @param {
|
|
103
|
+
* @param {FileCompartmentDescriptor|PackageCompartmentDescriptor} compartmentDescriptor
|
|
93
104
|
* @param {Record<string, Compartment>} compartments
|
|
94
|
-
* @param {
|
|
95
|
-
* @param {Record<string,
|
|
96
|
-
* @param {Record<string,
|
|
105
|
+
* @param {FileUrlString} compartmentName
|
|
106
|
+
* @param {Record<string, FileModuleConfiguration|CompartmentModuleConfiguration>} moduleDescriptors
|
|
107
|
+
* @param {Record<string, ScopeDescriptor<FileUrlString>>} scopeDescriptors
|
|
97
108
|
* @returns {ModuleMapHook | undefined}
|
|
98
109
|
*/
|
|
99
110
|
const makeModuleMapHook = (
|
|
@@ -103,9 +114,16 @@ const makeModuleMapHook = (
|
|
|
103
114
|
moduleDescriptors,
|
|
104
115
|
scopeDescriptors,
|
|
105
116
|
) => {
|
|
117
|
+
// Build pattern matcher once per compartment if patterns exist.
|
|
118
|
+
const { patterns } = /** @type {Partial<PackageCompartmentDescriptor>} */ (
|
|
119
|
+
compartmentDescriptor
|
|
120
|
+
);
|
|
121
|
+
/** @type {SubpathReplacer | null} */
|
|
122
|
+
const matchPattern =
|
|
123
|
+
patterns && patterns.length > 0 ? makeMultiSubpathReplacer(patterns) : null;
|
|
124
|
+
|
|
106
125
|
/**
|
|
107
|
-
* @
|
|
108
|
-
* @returns {string | object | undefined}
|
|
126
|
+
* @type {ModuleMapHook}
|
|
109
127
|
*/
|
|
110
128
|
const moduleMapHook = moduleSpecifier => {
|
|
111
129
|
compartmentDescriptor.retained = true;
|
|
@@ -114,39 +132,90 @@ const makeModuleMapHook = (
|
|
|
114
132
|
if (moduleDescriptor !== undefined) {
|
|
115
133
|
moduleDescriptor.retained = true;
|
|
116
134
|
|
|
135
|
+
if (isExitModuleConfiguration(moduleDescriptor)) {
|
|
136
|
+
return undefined;
|
|
137
|
+
}
|
|
117
138
|
// "foreignCompartmentName" refers to the compartment which
|
|
118
139
|
// may differ from the current compartment
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
140
|
+
if (isCompartmentModuleConfiguration(moduleDescriptor)) {
|
|
141
|
+
const {
|
|
142
|
+
compartment: foreignCompartmentName = compartmentName,
|
|
143
|
+
module: foreignModuleSpecifier,
|
|
144
|
+
} = moduleDescriptor;
|
|
145
|
+
if (foreignModuleSpecifier !== undefined) {
|
|
146
|
+
// archive goes through foreignModuleSpecifier for local modules too
|
|
147
|
+
if (!moduleSpecifier.startsWith('./')) {
|
|
148
|
+
// This code path seems to only be reached on subsequent imports of the same specifier in the same compartment.
|
|
149
|
+
// The check should be redundant and is only left here out of abundance of caution.
|
|
150
|
+
enforcePolicyByModule(moduleSpecifier, compartmentDescriptor, {
|
|
151
|
+
exit: false,
|
|
152
|
+
errorHint:
|
|
153
|
+
'This check should not be reachable. If you see this error, please file an issue.',
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const foreignCompartment = compartments[foreignCompartmentName];
|
|
158
|
+
if (foreignCompartment === undefined) {
|
|
159
|
+
throw Error(
|
|
160
|
+
`Cannot import from missing compartment ${q(
|
|
161
|
+
foreignCompartmentName,
|
|
162
|
+
)}}`,
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
// actual module descriptor
|
|
166
|
+
return {
|
|
167
|
+
compartment: foreignCompartment,
|
|
168
|
+
namespace: foreignModuleSpecifier,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
126
171
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Check patterns for wildcard matches (before scopes).
|
|
175
|
+
// Patterns may resolve within the same compartment (internal patterns)
|
|
176
|
+
// or to a foreign compartment (dependency export patterns).
|
|
177
|
+
if (matchPattern) {
|
|
178
|
+
const match = matchPattern(moduleSpecifier);
|
|
179
|
+
if (match !== null) {
|
|
180
|
+
const { result: resolvedPath, compartment: foreignCompartmentName } =
|
|
181
|
+
match;
|
|
182
|
+
|
|
183
|
+
// Null result means the specifier is explicitly excluded.
|
|
184
|
+
if (resolvedPath === null) {
|
|
185
|
+
throw Error(
|
|
186
|
+
`Cannot find module ${q(moduleSpecifier)} — excluded by null target pattern in ${q(compartmentName)}`,
|
|
187
|
+
);
|
|
137
188
|
}
|
|
189
|
+
const targetCompartmentName =
|
|
190
|
+
/** @type {FileUrlString} */
|
|
191
|
+
(foreignCompartmentName || compartmentName);
|
|
192
|
+
|
|
193
|
+
// Write back to moduleDescriptors for caching, archival, and
|
|
194
|
+
// policy enforcement. The write-back must precede the policy
|
|
195
|
+
// check because enforcePolicyByModule verifies the specifier
|
|
196
|
+
// exists in compartmentDescriptor.modules (the same object).
|
|
197
|
+
moduleDescriptors[moduleSpecifier] = {
|
|
198
|
+
retained: true,
|
|
199
|
+
compartment: targetCompartmentName,
|
|
200
|
+
module: resolvedPath,
|
|
201
|
+
__createdBy: 'link-pattern',
|
|
202
|
+
};
|
|
138
203
|
|
|
139
|
-
|
|
140
|
-
|
|
204
|
+
// Policy enforcement for pattern-matched modules
|
|
205
|
+
enforcePolicyByModule(moduleSpecifier, compartmentDescriptor, {
|
|
206
|
+
exit: false,
|
|
207
|
+
errorHint: `Pattern matched in compartment ${q(compartmentName)}: module specifier ${q(moduleSpecifier)} mapped to ${q(resolvedPath)}`,
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
const targetCompartment = compartments[targetCompartmentName];
|
|
211
|
+
if (targetCompartment === undefined) {
|
|
141
212
|
throw Error(
|
|
142
|
-
`Cannot import from missing compartment ${q(
|
|
143
|
-
foreignCompartmentName,
|
|
144
|
-
)}}`,
|
|
213
|
+
`Cannot import module specifier ${q(moduleSpecifier)} from missing compartment ${q(targetCompartmentName)}`,
|
|
145
214
|
);
|
|
146
215
|
}
|
|
147
216
|
return {
|
|
148
|
-
compartment:
|
|
149
|
-
namespace:
|
|
217
|
+
compartment: targetCompartment,
|
|
218
|
+
namespace: resolvedPath,
|
|
150
219
|
};
|
|
151
220
|
}
|
|
152
221
|
}
|
|
@@ -178,7 +247,7 @@ const makeModuleMapHook = (
|
|
|
178
247
|
);
|
|
179
248
|
}
|
|
180
249
|
|
|
181
|
-
|
|
250
|
+
enforcePolicyByModule(scopePrefix, compartmentDescriptor, {
|
|
182
251
|
exit: false,
|
|
183
252
|
errorHint: `Blocked in linking. ${q(
|
|
184
253
|
moduleSpecifier,
|
|
@@ -198,7 +267,9 @@ const makeModuleMapHook = (
|
|
|
198
267
|
retained: true,
|
|
199
268
|
compartment: foreignCompartmentName,
|
|
200
269
|
module: foreignModuleSpecifier,
|
|
270
|
+
__createdBy: 'link',
|
|
201
271
|
};
|
|
272
|
+
// actual module descriptor
|
|
202
273
|
return {
|
|
203
274
|
compartment: foreignCompartment,
|
|
204
275
|
namespace: foreignModuleSpecifier,
|
|
@@ -236,16 +307,10 @@ const impossibleImportNowHookMaker = () => {
|
|
|
236
307
|
* - Passes the given globals and external modules into the root compartment
|
|
237
308
|
* only.
|
|
238
309
|
*
|
|
239
|
-
* @param {
|
|
310
|
+
* @param {PackageCompartmentMapDescriptor|FileCompartmentMapDescriptor} compartmentMap
|
|
240
311
|
* @param {LinkOptions} options
|
|
241
312
|
* @returns {LinkResult} the root compartment of the compartment DAG
|
|
242
313
|
*/
|
|
243
|
-
|
|
244
|
-
/**
|
|
245
|
-
* @param {CompartmentMapDescriptor} compartmentMap
|
|
246
|
-
* @param {LinkOptions} options
|
|
247
|
-
* @returns {LinkResult}
|
|
248
|
-
*/
|
|
249
314
|
export const link = (
|
|
250
315
|
{ entry, compartments: compartmentDescriptors },
|
|
251
316
|
options,
|
|
@@ -262,7 +327,7 @@ export const link = (
|
|
|
262
327
|
__shimTransforms__ = [],
|
|
263
328
|
__native__ = false,
|
|
264
329
|
archiveOnly = false,
|
|
265
|
-
Compartment =
|
|
330
|
+
Compartment = DefaultCompartment,
|
|
266
331
|
} = options;
|
|
267
332
|
|
|
268
333
|
const { compartment: entryCompartmentName } = entry;
|
|
@@ -291,9 +356,14 @@ export const link = (
|
|
|
291
356
|
syncModuleTransforms,
|
|
292
357
|
});
|
|
293
358
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
359
|
+
const compartmentDescriptorEntries =
|
|
360
|
+
/** @type {[FileUrlString, PackageCompartmentDescriptor|FileCompartmentDescriptor][]} */ (
|
|
361
|
+
entries(compartmentDescriptors)
|
|
362
|
+
);
|
|
363
|
+
for (const [
|
|
364
|
+
compartmentName,
|
|
365
|
+
compartmentDescriptor,
|
|
366
|
+
] of compartmentDescriptorEntries) {
|
|
297
367
|
const {
|
|
298
368
|
location,
|
|
299
369
|
name,
|
|
@@ -418,7 +488,7 @@ export const link = (
|
|
|
418
488
|
};
|
|
419
489
|
|
|
420
490
|
/**
|
|
421
|
-
* @param {
|
|
491
|
+
* @param {PackageCompartmentMapDescriptor} compartmentMap
|
|
422
492
|
* @param {LinkOptions} options
|
|
423
493
|
* @deprecated Use {@link link}.
|
|
424
494
|
*/
|
package/src/node-modules.d.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
export function basename(location: string): string;
|
|
2
|
-
export function
|
|
3
|
-
export function mapNodeModules(readPowers: ReadFn | ReadPowers<FileUrlString> | MaybeReadPowers<FileUrlString>, moduleLocation: string, { tags, conditions, log, ...otherOptions }?: MapNodeModulesOptions): Promise<
|
|
2
|
+
export function compartmentMapForNodeModules_(readPowers: ReadFn | ReadPowers<FileUrlString> | MaybeReadPowers<FileUrlString>, entryPackageLocation: FileUrlString, conditionsOption: Set<string>, packageDescriptor: PackageDescriptor, entryModuleSpecifier: string, options?: CompartmentMapForNodeModulesOptions): Promise<PackageCompartmentMapDescriptor>;
|
|
3
|
+
export function mapNodeModules(readPowers: ReadFn | ReadPowers<FileUrlString> | MaybeReadPowers<FileUrlString>, moduleLocation: string, { tags, conditions, log, unknownCanonicalNameHook, packageDataHook, packageDependenciesHook, policy, ...otherOptions }?: MapNodeModulesOptions): Promise<PackageCompartmentMapDescriptor>;
|
|
4
|
+
export function compartmentMapForNodeModules(readPowers: ReadFn | ReadPowers<FileUrlString> | MaybeReadPowers<FileUrlString>, entryPackageLocation: FileUrlString, conditionsOption: Set<string>, packageDescriptor: PackageDescriptor, entryModuleSpecifier: string, options?: CompartmentMapForNodeModulesOptions): Promise<PackageCompartmentMapDescriptor>;
|
|
4
5
|
import type { ReadFn } from './types.js';
|
|
5
6
|
import type { FileUrlString } from './types.js';
|
|
6
7
|
import type { ReadPowers } from './types.js';
|
|
7
8
|
import type { MaybeReadPowers } from './types.js';
|
|
8
9
|
import type { PackageDescriptor } from './types.js';
|
|
9
10
|
import type { CompartmentMapForNodeModulesOptions } from './types.js';
|
|
10
|
-
import type {
|
|
11
|
+
import type { PackageCompartmentMapDescriptor } from './types.js';
|
|
11
12
|
import type { MapNodeModulesOptions } from './types.js';
|
|
12
13
|
//# sourceMappingURL=node-modules.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-modules.d.ts","sourceRoot":"","sources":["node-modules.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"node-modules.d.ts","sourceRoot":"","sources":["node-modules.js"],"names":[],"mappings":"AA4LO,mCAHI,MAAM,GACJ,MAAM,CAYlB;AA+kCM,0DARI,MAAM,GAAG,WAAW,aAAa,CAAC,GAAG,gBAAgB,aAAa,CAAC,wBACnE,aAAa,oBACb,GAAG,CAAC,MAAM,CAAC,qBACX,iBAAiB,wBACjB,MAAM,YACN,mCAAmC,GACjC,OAAO,CAAC,+BAA+B,CAAC,CA0HpD;AAaM,2CALI,MAAM,GAAG,WAAW,aAAa,CAAC,GAAG,gBAAgB,aAAa,CAAC,kBACnE,MAAM,2HACN,qBAAqB,GACnB,OAAO,CAAC,+BAA+B,CAAC,CA6CpD;AAhLM,yDARI,MAAM,GAAG,WAAW,aAAa,CAAC,GAAG,gBAAgB,aAAa,CAAC,wBACnE,aAAa,oBACb,GAAG,CAAC,MAAM,CAAC,qBACX,iBAAiB,wBACjB,MAAM,YACN,mCAAmC,GACjC,OAAO,CAAC,+BAA+B,CAAC,CA0HpD;4BAt1CS,YAAY;mCAAZ,YAAY;gCAAZ,YAAY;qCAAZ,YAAY;uCAAZ,YAAY;yDAAZ,YAAY;qDAAZ,YAAY;2CAAZ,YAAY"}
|