@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/README.md +14 -0
- package/import-archive-all-parsers.d.ts +2 -0
- package/import-archive-all-parsers.d.ts.map +1 -0
- package/import-archive-all-parsers.js +1 -0
- package/package.json +10 -5
- package/src/archive-lite.d.ts +2 -4
- package/src/archive-lite.d.ts.map +1 -1
- package/src/archive-lite.js +15 -191
- package/src/archive.d.ts.map +1 -1
- package/src/archive.js +8 -0
- package/src/bundle.d.ts.map +1 -1
- package/src/bundle.js +8 -2
- package/src/capture-lite.d.ts.map +1 -1
- package/src/capture-lite.js +9 -187
- package/src/digest.d.ts +5 -0
- package/src/digest.d.ts.map +1 -0
- package/src/digest.js +235 -0
- package/src/import-archive-all-parsers.d.ts +11 -0
- package/src/import-archive-all-parsers.d.ts.map +1 -0
- package/src/import-archive-all-parsers.js +29 -0
- package/src/import-archive-lite.d.ts.map +1 -1
- package/src/import-archive-lite.js +4 -0
- package/src/import-lite.d.ts.map +1 -1
- package/src/import-lite.js +3 -0
- package/src/import.d.ts.map +1 -1
- package/src/import.js +2 -0
- package/src/link.d.ts.map +1 -1
- package/src/link.js +2 -0
- package/src/map-parser.d.ts.map +1 -1
- package/src/map-parser.js +4 -1
- package/src/node-modules.d.ts +1 -1
- package/src/node-modules.d.ts.map +1 -1
- package/src/node-modules.js +37 -11
- package/src/types/external.d.ts +47 -4
- package/src/types/external.d.ts.map +1 -1
- package/src/types/external.ts +53 -4
- package/src/types/internal.d.ts +1 -0
- package/src/types/internal.d.ts.map +1 -1
- package/src/types/internal.ts +1 -0
package/README.md
CHANGED
|
@@ -328,6 +328,20 @@ These will be appended to each module from the archive, for debugging purposes.
|
|
|
328
328
|
The `@endo/bundle-source` and `@endo/import-bundle` tools integrate source maps
|
|
329
329
|
for an end-to-end debugging experience.
|
|
330
330
|
|
|
331
|
+
# XS (experimental)
|
|
332
|
+
|
|
333
|
+
The Compartment Mapper can use native XS `Compartment` and `ModuleSource` under
|
|
334
|
+
certain conditions:
|
|
335
|
+
|
|
336
|
+
1. The application must be an XS script that was compiled with the `xs`
|
|
337
|
+
package condition.
|
|
338
|
+
This causes `ses`, `@endo/module-source`, and `@endo/import-bundle` to
|
|
339
|
+
provide slightly different implementations that can fall through to native
|
|
340
|
+
behavior.
|
|
341
|
+
2. The application must opt-in with the `__native__: true` option on any
|
|
342
|
+
of the compartment mapper methods that import modules like `importLocation`
|
|
343
|
+
and `importArchive`.
|
|
344
|
+
|
|
331
345
|
# Design
|
|
332
346
|
|
|
333
347
|
Each of the workflows the compartment mapper executes a portion of one sequence
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"import-archive-all-parsers.d.ts","sourceRoot":"","sources":["import-archive-all-parsers.js"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { defaultParserForLanguage } from './src/import-archive-all-parsers.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@endo/compartment-mapper",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "The compartment mapper assembles Node applications in a sandbox",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"node",
|
|
@@ -32,7 +32,12 @@
|
|
|
32
32
|
"./capture-lite.js": "./capture-lite.js",
|
|
33
33
|
"./import-archive.js": "./import-archive.js",
|
|
34
34
|
"./import-archive-lite.js": "./import-archive-lite.js",
|
|
35
|
-
"./import-archive-parsers.js":
|
|
35
|
+
"./import-archive-parsers.js": {
|
|
36
|
+
"xs": "./import-archive-all-parsers.js",
|
|
37
|
+
"node": "./import-archive-all-parsers.js",
|
|
38
|
+
"default": "./import-archive-parsers.js"
|
|
39
|
+
},
|
|
40
|
+
"./import-archive-all-parsers.js": "./import-archive-all-parsers.js",
|
|
36
41
|
"./bundle.js": "./bundle.js",
|
|
37
42
|
"./node-powers.js": "./node-powers.js",
|
|
38
43
|
"./node-modules.js": "./node-modules.js",
|
|
@@ -52,10 +57,10 @@
|
|
|
52
57
|
},
|
|
53
58
|
"dependencies": {
|
|
54
59
|
"@endo/cjs-module-analyzer": "^1.0.9",
|
|
55
|
-
"@endo/module-source": "^1.
|
|
60
|
+
"@endo/module-source": "^1.2.0",
|
|
56
61
|
"@endo/trampoline": "^1.0.3",
|
|
57
62
|
"@endo/zip": "^1.0.9",
|
|
58
|
-
"ses": "^1.
|
|
63
|
+
"ses": "^1.11.0"
|
|
59
64
|
},
|
|
60
65
|
"devDependencies": {
|
|
61
66
|
"ava": "^6.1.3",
|
|
@@ -109,5 +114,5 @@
|
|
|
109
114
|
"typeCoverage": {
|
|
110
115
|
"atLeast": 86.14
|
|
111
116
|
},
|
|
112
|
-
"gitHead": "
|
|
117
|
+
"gitHead": "e0683e0bfdbfc84351af332c9e78813d7b67ef89"
|
|
113
118
|
}
|
package/src/archive-lite.d.ts
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
export function makeArchiveCompartmentMap(compartmentMap: CompartmentMapDescriptor, sources: Sources):
|
|
2
|
-
archiveCompartmentMap: CompartmentMapDescriptor;
|
|
3
|
-
archiveSources: Sources;
|
|
4
|
-
};
|
|
1
|
+
export function makeArchiveCompartmentMap(compartmentMap: CompartmentMapDescriptor, sources: Sources): ArchiveResult;
|
|
5
2
|
export function makeAndHashArchiveFromMap(powers: ReadFn | ReadPowers, compartmentMap: CompartmentMapDescriptor, options?: ArchiveLiteOptions | undefined): Promise<{
|
|
6
3
|
bytes: Uint8Array;
|
|
7
4
|
sha512?: string;
|
|
@@ -12,6 +9,7 @@ export function hashFromMap(powers: HashPowers, compartmentMap: CompartmentMapDe
|
|
|
12
9
|
export function writeArchiveFromMap(write: WriteFn, readPowers: ReadFn | ReadPowers, archiveLocation: string, compartmentMap: CompartmentMapDescriptor, options?: ArchiveLiteOptions | undefined): Promise<void>;
|
|
13
10
|
import type { CompartmentMapDescriptor } from './types.js';
|
|
14
11
|
import type { Sources } from './types.js';
|
|
12
|
+
import type { ArchiveResult } from './types.js';
|
|
15
13
|
import type { ReadFn } from './types.js';
|
|
16
14
|
import type { ReadPowers } from './types.js';
|
|
17
15
|
import type { ArchiveLiteOptions } from './types.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"archive-lite.d.ts","sourceRoot":"","sources":["archive-lite.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"archive-lite.d.ts","sourceRoot":"","sources":["archive-lite.js"],"names":[],"mappings":"AAmHO,0DAJI,wBAAwB,WACxB,OAAO,GACL,aAAa,CAiBzB;AAyGM,kDALI,MAAM,GAAG,UAAU,kBACnB,wBAAwB,6CAEtB,OAAO,CAAC;IAAC,KAAK,EAAE,UAAU,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAC,CAAC,CAmBzD;AAQM,2CALI,MAAM,GAAG,UAAU,kBACnB,wBAAwB,6CAEtB,OAAO,CAAC,UAAU,CAAC,CAS/B;AAQM,mCALI,MAAM,GAAG,UAAU,kBACnB,wBAAwB,6CAEtB,OAAO,CAAC,UAAU,CAAC,CAS/B;AAQM,oCALI,UAAU,kBACV,wBAAwB,6CAEtB,OAAO,CAAC,MAAM,CAAC,CAU3B;AASM,2CANI,OAAO,cACP,MAAM,GAAG,UAAU,mBACnB,MAAM,kBACN,wBAAwB,2DAgBlC;8CApRS,YAAY;6BAAZ,YAAY;mCAAZ,YAAY;4BAAZ,YAAY;gCAAZ,YAAY;wCAAZ,YAAY;gCAAZ,YAAY;6BAAZ,YAAY"}
|
package/src/archive-lite.js
CHANGED
|
@@ -33,12 +33,11 @@
|
|
|
33
33
|
/**
|
|
34
34
|
* @import {
|
|
35
35
|
* ArchiveLiteOptions,
|
|
36
|
+
* ArchiveResult,
|
|
36
37
|
* ArchiveWriter,
|
|
37
38
|
* CaptureSourceLocationHook,
|
|
38
|
-
* CompartmentDescriptor,
|
|
39
39
|
* CompartmentMapDescriptor,
|
|
40
40
|
* HashPowers,
|
|
41
|
-
* ModuleDescriptor,
|
|
42
41
|
* ReadFn,
|
|
43
42
|
* ReadPowers,
|
|
44
43
|
* Sources,
|
|
@@ -54,12 +53,8 @@ import {
|
|
|
54
53
|
makeImportHookMaker,
|
|
55
54
|
} from './import-hook.js';
|
|
56
55
|
import { unpackReadPowers } from './powers.js';
|
|
57
|
-
import {
|
|
58
|
-
assertCompartmentMap,
|
|
59
|
-
stringCompare,
|
|
60
|
-
pathCompare,
|
|
61
|
-
} from './compartment-map.js';
|
|
62
56
|
import { detectAttenuators } from './policy.js';
|
|
57
|
+
import { digestCompartmentMap } from './digest.js';
|
|
63
58
|
|
|
64
59
|
const textEncoder = new TextEncoder();
|
|
65
60
|
|
|
@@ -72,160 +67,7 @@ const { assign, create, freeze } = Object;
|
|
|
72
67
|
*/
|
|
73
68
|
const resolveLocation = (rel, abs) => new URL(rel, abs).toString();
|
|
74
69
|
|
|
75
|
-
const { keys
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* We attempt to produce compartment maps that are consistent regardless of
|
|
79
|
-
* whether the packages were originally laid out on disk for development or
|
|
80
|
-
* production, and other trivia like the fully qualified path of a specific
|
|
81
|
-
* installation.
|
|
82
|
-
*
|
|
83
|
-
* Naming compartments for the self-ascribed name and version of each Node.js
|
|
84
|
-
* package is insufficient because they are not guaranteed to be unique.
|
|
85
|
-
* Dependencies do not necessarilly come from the npm registry and may be
|
|
86
|
-
* for example derived from fully qualified URL's or Github org and project
|
|
87
|
-
* names.
|
|
88
|
-
* Package managers are also not required to fully deduplicate the hard
|
|
89
|
-
* copy of each package even when they are identical resources.
|
|
90
|
-
* Duplication is undesirable, but we elect to defer that problem to solutions
|
|
91
|
-
* in the package managers, as the alternative would be to consistently hash
|
|
92
|
-
* the original sources of the packages themselves, which may not even be
|
|
93
|
-
* available much less pristine for us.
|
|
94
|
-
*
|
|
95
|
-
* So, instead, we use the lexically least path of dependency names, delimited
|
|
96
|
-
* by hashes.
|
|
97
|
-
* The compartment maps generated by the ./node-modules.js tooling pre-compute
|
|
98
|
-
* these traces for our use here.
|
|
99
|
-
* We sort the compartments lexically on their self-ascribed name and version,
|
|
100
|
-
* and use the lexically least dependency name path as a tie-breaker.
|
|
101
|
-
* The dependency path is logical and orthogonal to the package manager's
|
|
102
|
-
* actual installation location, so should be orthogonal to the vagaries of the
|
|
103
|
-
* package manager's deduplication algorithm.
|
|
104
|
-
*
|
|
105
|
-
* @param {Record<string, CompartmentDescriptor>} compartments
|
|
106
|
-
* @returns {Record<string, string>} map from old to new compartment names.
|
|
107
|
-
*/
|
|
108
|
-
const renameCompartments = compartments => {
|
|
109
|
-
/** @type {Record<string, string>} */
|
|
110
|
-
const compartmentRenames = create(null);
|
|
111
|
-
let index = 0;
|
|
112
|
-
let prev = '';
|
|
113
|
-
|
|
114
|
-
// The sort below combines two comparators to avoid depending on sort
|
|
115
|
-
// stability, which became standard as recently as 2019.
|
|
116
|
-
// If that date seems quaint, please accept my regards from the distant past.
|
|
117
|
-
// We are very proud of you.
|
|
118
|
-
const compartmentsByPath = Object.entries(compartments)
|
|
119
|
-
.map(([name, compartment]) => ({
|
|
120
|
-
name,
|
|
121
|
-
path: compartment.path,
|
|
122
|
-
label: compartment.label,
|
|
123
|
-
}))
|
|
124
|
-
.sort((a, b) => {
|
|
125
|
-
if (a.label === b.label) {
|
|
126
|
-
assert(a.path !== undefined && b.path !== undefined);
|
|
127
|
-
return pathCompare(a.path, b.path);
|
|
128
|
-
}
|
|
129
|
-
return stringCompare(a.label, b.label);
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
for (const { name, label } of compartmentsByPath) {
|
|
133
|
-
if (label === prev) {
|
|
134
|
-
compartmentRenames[name] = `${label}-n${index}`;
|
|
135
|
-
index += 1;
|
|
136
|
-
} else {
|
|
137
|
-
compartmentRenames[name] = label;
|
|
138
|
-
prev = label;
|
|
139
|
-
index = 1;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
return compartmentRenames;
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* @param {Record<string, CompartmentDescriptor>} compartments
|
|
147
|
-
* @param {Sources} sources
|
|
148
|
-
* @param {Record<string, string>} compartmentRenames
|
|
149
|
-
*/
|
|
150
|
-
const translateCompartmentMap = (compartments, sources, compartmentRenames) => {
|
|
151
|
-
const result = create(null);
|
|
152
|
-
for (const compartmentName of keys(compartmentRenames)) {
|
|
153
|
-
const compartment = compartments[compartmentName];
|
|
154
|
-
const { name, label, retained: compartmentRetained, policy } = compartment;
|
|
155
|
-
if (compartmentRetained) {
|
|
156
|
-
// rename module compartments
|
|
157
|
-
/** @type {Record<string, ModuleDescriptor>} */
|
|
158
|
-
const modules = create(null);
|
|
159
|
-
const compartmentModules = compartment.modules;
|
|
160
|
-
if (compartment.modules) {
|
|
161
|
-
for (const name of keys(compartmentModules).sort()) {
|
|
162
|
-
const { retained: moduleRetained, ...retainedModule } =
|
|
163
|
-
compartmentModules[name];
|
|
164
|
-
if (moduleRetained) {
|
|
165
|
-
if (retainedModule.compartment !== undefined) {
|
|
166
|
-
modules[name] = {
|
|
167
|
-
...retainedModule,
|
|
168
|
-
compartment: compartmentRenames[retainedModule.compartment],
|
|
169
|
-
};
|
|
170
|
-
} else {
|
|
171
|
-
modules[name] = retainedModule;
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
// integrate sources into modules
|
|
178
|
-
const compartmentSources = sources[compartmentName];
|
|
179
|
-
if (compartmentSources) {
|
|
180
|
-
for (const name of keys(compartmentSources).sort()) {
|
|
181
|
-
const source = compartmentSources[name];
|
|
182
|
-
const { location, parser, exit, sha512, deferredError } = source;
|
|
183
|
-
if (location !== undefined) {
|
|
184
|
-
modules[name] = {
|
|
185
|
-
location,
|
|
186
|
-
parser,
|
|
187
|
-
sha512,
|
|
188
|
-
};
|
|
189
|
-
} else if (exit !== undefined) {
|
|
190
|
-
modules[name] = {
|
|
191
|
-
exit,
|
|
192
|
-
};
|
|
193
|
-
} else if (deferredError !== undefined) {
|
|
194
|
-
modules[name] = {
|
|
195
|
-
deferredError,
|
|
196
|
-
};
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
result[compartmentRenames[compartmentName]] = {
|
|
202
|
-
name,
|
|
203
|
-
label,
|
|
204
|
-
location: compartmentRenames[compartmentName],
|
|
205
|
-
modules,
|
|
206
|
-
policy,
|
|
207
|
-
// `scopes`, `types`, and `parsers` are not necessary since every
|
|
208
|
-
// loadable module is captured in `modules`.
|
|
209
|
-
};
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
return result;
|
|
214
|
-
};
|
|
215
|
-
|
|
216
|
-
/**
|
|
217
|
-
* @param {Sources} sources
|
|
218
|
-
* @param {Record<string, string>} compartmentRenames
|
|
219
|
-
* @returns {Sources}
|
|
220
|
-
*/
|
|
221
|
-
const renameSources = (sources, compartmentRenames) => {
|
|
222
|
-
return fromEntries(
|
|
223
|
-
entries(sources).map(([name, compartmentSources]) => [
|
|
224
|
-
compartmentRenames[name],
|
|
225
|
-
compartmentSources,
|
|
226
|
-
]),
|
|
227
|
-
);
|
|
228
|
-
};
|
|
70
|
+
const { keys } = Object;
|
|
229
71
|
|
|
230
72
|
/**
|
|
231
73
|
* @param {ArchiveWriter} archive
|
|
@@ -269,41 +111,23 @@ const captureSourceLocations = async (sources, captureSourceLocation) => {
|
|
|
269
111
|
/**
|
|
270
112
|
* @param {CompartmentMapDescriptor} compartmentMap
|
|
271
113
|
* @param {Sources} sources
|
|
272
|
-
* @returns {
|
|
114
|
+
* @returns {ArchiveResult}
|
|
273
115
|
*/
|
|
274
116
|
export const makeArchiveCompartmentMap = (compartmentMap, sources) => {
|
|
275
117
|
const {
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
118
|
+
compartmentMap: archiveCompartmentMap,
|
|
119
|
+
sources: archiveSources,
|
|
120
|
+
oldToNewCompartmentNames,
|
|
121
|
+
newToOldCompartmentNames,
|
|
122
|
+
compartmentRenames,
|
|
123
|
+
} = digestCompartmentMap(compartmentMap, sources);
|
|
124
|
+
return {
|
|
125
|
+
archiveCompartmentMap,
|
|
126
|
+
archiveSources,
|
|
127
|
+
oldToNewCompartmentNames,
|
|
128
|
+
newToOldCompartmentNames,
|
|
284
129
|
compartmentRenames,
|
|
285
|
-
);
|
|
286
|
-
const archiveEntryCompartmentName = compartmentRenames[entryCompartmentName];
|
|
287
|
-
const archiveSources = renameSources(sources, compartmentRenames);
|
|
288
|
-
|
|
289
|
-
const archiveCompartmentMap = {
|
|
290
|
-
// TODO migrate tags to conditions
|
|
291
|
-
// https://github.com/endojs/endo/issues/2388
|
|
292
|
-
tags: [],
|
|
293
|
-
entry: {
|
|
294
|
-
compartment: archiveEntryCompartmentName,
|
|
295
|
-
module: entryModuleSpecifier,
|
|
296
|
-
},
|
|
297
|
-
compartments: archiveCompartments,
|
|
298
130
|
};
|
|
299
|
-
|
|
300
|
-
// Cross-check:
|
|
301
|
-
// We assert that we have constructed a valid compartment map, not because it
|
|
302
|
-
// might not be, but to ensure that the assertCompartmentMap function can
|
|
303
|
-
// accept all valid compartment maps.
|
|
304
|
-
assertCompartmentMap(archiveCompartmentMap);
|
|
305
|
-
|
|
306
|
-
return { archiveCompartmentMap, archiveSources };
|
|
307
131
|
};
|
|
308
132
|
|
|
309
133
|
/**
|
package/src/archive.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["archive.js"],"names":[],"mappings":"AA2DO,2CALI,MAAM,GAAG,UAAU,kBACnB,MAAM,yCAEJ,OAAO,CAAC;IAAC,KAAK,EAAE,UAAU,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAC,CAAC,CAiBzD;AAQM,oCALI,MAAM,GAAG,UAAU,kBACnB,MAAM,yCAEJ,OAAO,CAAC,UAAU,CAAC,
|
|
1
|
+
{"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["archive.js"],"names":[],"mappings":"AA2DO,2CALI,MAAM,GAAG,UAAU,kBACnB,MAAM,yCAEJ,OAAO,CAAC;IAAC,KAAK,EAAE,UAAU,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAC,CAAC,CAiBzD;AAQM,oCALI,MAAM,GAAG,UAAU,kBACnB,MAAM,yCAEJ,OAAO,CAAC,UAAU,CAAC,CAwC/B;AAQM,oCALI,MAAM,GAAG,UAAU,kBACnB,MAAM,yCAEJ,OAAO,CAAC,UAAU,CAAC,CAyC/B;AAQM,qCALI,UAAU,kBACV,MAAM,yCAEJ,OAAO,CAAC,MAAM,CAAC,CAyC3B;AASM,oCANI,OAAO,cACP,MAAM,GAAG,UAAU,mBACnB,MAAM,kBACN,MAAM,uDAgDhB;4BApPS,YAAY;gCAAZ,YAAY;oCAAZ,YAAY;gCAAZ,YAAY;6BAAZ,YAAY"}
|
package/src/archive.js
CHANGED
|
@@ -85,6 +85,7 @@ export const makeArchive = async (powers, moduleLocation, options = {}) => {
|
|
|
85
85
|
dev,
|
|
86
86
|
tags,
|
|
87
87
|
conditions = tags,
|
|
88
|
+
strict = false,
|
|
88
89
|
commonDependencies,
|
|
89
90
|
policy,
|
|
90
91
|
languageForExtension,
|
|
@@ -99,6 +100,7 @@ export const makeArchive = async (powers, moduleLocation, options = {}) => {
|
|
|
99
100
|
} = assignParserForLanguage(options);
|
|
100
101
|
const compartmentMap = await mapNodeModules(powers, moduleLocation, {
|
|
101
102
|
dev,
|
|
103
|
+
strict,
|
|
102
104
|
conditions,
|
|
103
105
|
commonDependencies,
|
|
104
106
|
policy,
|
|
@@ -129,6 +131,7 @@ export const mapLocation = async (powers, moduleLocation, options = {}) => {
|
|
|
129
131
|
dev,
|
|
130
132
|
tags,
|
|
131
133
|
conditions = tags,
|
|
134
|
+
strict = false,
|
|
132
135
|
commonDependencies,
|
|
133
136
|
policy,
|
|
134
137
|
parserForLanguage,
|
|
@@ -144,6 +147,7 @@ export const mapLocation = async (powers, moduleLocation, options = {}) => {
|
|
|
144
147
|
|
|
145
148
|
const compartmentMap = await mapNodeModules(powers, moduleLocation, {
|
|
146
149
|
dev,
|
|
150
|
+
strict,
|
|
147
151
|
conditions,
|
|
148
152
|
commonDependencies,
|
|
149
153
|
policy,
|
|
@@ -174,6 +178,7 @@ export const hashLocation = async (powers, moduleLocation, options = {}) => {
|
|
|
174
178
|
dev,
|
|
175
179
|
tags,
|
|
176
180
|
conditions = tags,
|
|
181
|
+
strict = false,
|
|
177
182
|
commonDependencies,
|
|
178
183
|
policy,
|
|
179
184
|
parserForLanguage,
|
|
@@ -189,6 +194,7 @@ export const hashLocation = async (powers, moduleLocation, options = {}) => {
|
|
|
189
194
|
|
|
190
195
|
const compartmentMap = await mapNodeModules(powers, moduleLocation, {
|
|
191
196
|
dev,
|
|
197
|
+
strict,
|
|
192
198
|
conditions,
|
|
193
199
|
commonDependencies,
|
|
194
200
|
policy,
|
|
@@ -226,6 +232,7 @@ export const writeArchive = async (
|
|
|
226
232
|
dev,
|
|
227
233
|
tags,
|
|
228
234
|
conditions = tags,
|
|
235
|
+
strict = false,
|
|
229
236
|
commonDependencies,
|
|
230
237
|
policy,
|
|
231
238
|
parserForLanguage,
|
|
@@ -240,6 +247,7 @@ export const writeArchive = async (
|
|
|
240
247
|
} = assignParserForLanguage(options);
|
|
241
248
|
const compartmentMap = await mapNodeModules(readPowers, moduleLocation, {
|
|
242
249
|
dev,
|
|
250
|
+
strict,
|
|
243
251
|
conditions,
|
|
244
252
|
commonDependencies,
|
|
245
253
|
policy,
|
package/src/bundle.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bundle.d.ts","sourceRoot":"","sources":["bundle.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"bundle.d.ts","sourceRoot":"","sources":["bundle.js"],"names":[],"mappings":"AAsOO,uCALI,MAAM,GAAG,UAAU,GAAG,eAAe,kBACrC,MAAM,yCAEJ,OAAO,CAAC,MAAM,CAAC,CAgN3B;AASM,mCANI,OAAO,QACP,MAAM,kBACN,MAAM,kBACN,MAAM,uDAahB;;;;;;;;;;;gBAlba,MAAM,MAAM;;;;;;;cAOZ,MAAM,MAAM;;;;;;;oBAIZ,MAAM,MAAM;;;;;wBAIZ,MAAM,MAAM;;yBAKH,oBAAoB,SAA9B,OAAS;SAER,MAAM;qBACN,MAAM;qBACN,MAAM;YACN,MAAM;YACN,gBAAgB,GAAG,oBAAoB;qBACvC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;oBACtB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;WACtB,UAAU;WACV,MAAM;gBACN,UAAU;;0BAID,oBAAoB,SAA9B,OAAS,aAEX,YAAY,CAAC,oBAAoB,CAAC,KAChC,UAAU;2BAIA,oBAAoB,SAA9B,OAAS;aAER,MAAM;mBACN,aAAa,CAAC,oBAAoB,CAAC;;4BAlDvC,YAAY;gCAAZ,YAAY;qCAAZ,YAAY;oCAAZ,YAAY;6BAAZ,YAAY;sCAVZ,KAAK"}
|
package/src/bundle.js
CHANGED
|
@@ -117,8 +117,14 @@ const sortedModules = (
|
|
|
117
117
|
const source = compartmentSources[compartmentName][moduleSpecifier];
|
|
118
118
|
if (source !== undefined) {
|
|
119
119
|
const { record, parser, deferredError, bytes } = source;
|
|
120
|
-
assert(
|
|
121
|
-
|
|
120
|
+
assert(
|
|
121
|
+
bytes !== undefined,
|
|
122
|
+
`No bytes for ${moduleSpecifier} in ${compartmentName}`,
|
|
123
|
+
);
|
|
124
|
+
assert(
|
|
125
|
+
parser !== undefined,
|
|
126
|
+
`No parser for ${moduleSpecifier} in ${compartmentName}`,
|
|
127
|
+
);
|
|
122
128
|
if (deferredError) {
|
|
123
129
|
throw Error(
|
|
124
130
|
`Cannot bundle: encountered deferredError ${deferredError}`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capture-lite.d.ts","sourceRoot":"","sources":["capture-lite.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"capture-lite.d.ts","sourceRoot":"","sources":["capture-lite.js"],"names":[],"mappings":"AAoFO,uCALI,MAAM,GAAG,UAAU,kBACnB,wBAAwB,6CAEtB,OAAO,CAAC,aAAa,CAAC,CAmElC;4BA9GS,YAAY;gCAAZ,YAAY;8CAAZ,YAAY;wCAAZ,YAAY;mCAAZ,YAAY"}
|
package/src/capture-lite.js
CHANGED
|
@@ -33,20 +33,13 @@
|
|
|
33
33
|
* @import {
|
|
34
34
|
* CaptureLiteOptions,
|
|
35
35
|
* CaptureResult,
|
|
36
|
-
* CompartmentDescriptor,
|
|
37
36
|
* CompartmentMapDescriptor,
|
|
38
|
-
* ModuleDescriptor,
|
|
39
37
|
* ReadFn,
|
|
40
38
|
* ReadPowers,
|
|
41
39
|
* Sources,
|
|
42
40
|
* } from './types.js'
|
|
43
41
|
*/
|
|
44
42
|
|
|
45
|
-
import {
|
|
46
|
-
assertCompartmentMap,
|
|
47
|
-
pathCompare,
|
|
48
|
-
stringCompare,
|
|
49
|
-
} from './compartment-map.js';
|
|
50
43
|
import {
|
|
51
44
|
exitModuleImportHookMaker,
|
|
52
45
|
makeImportHookMaker,
|
|
@@ -55,161 +48,12 @@ import { link } from './link.js';
|
|
|
55
48
|
import { resolve } from './node-module-specifier.js';
|
|
56
49
|
import { detectAttenuators } from './policy.js';
|
|
57
50
|
import { unpackReadPowers } from './powers.js';
|
|
51
|
+
import { digestCompartmentMap } from './digest.js';
|
|
58
52
|
|
|
59
|
-
const { freeze, assign, create
|
|
53
|
+
const { freeze, assign, create } = Object;
|
|
60
54
|
|
|
61
55
|
const defaultCompartment = Compartment;
|
|
62
56
|
|
|
63
|
-
/**
|
|
64
|
-
* We attempt to produce compartment maps that are consistent regardless of
|
|
65
|
-
* whether the packages were originally laid out on disk for development or
|
|
66
|
-
* production, and other trivia like the fully qualified path of a specific
|
|
67
|
-
* installation.
|
|
68
|
-
*
|
|
69
|
-
* Naming compartments for the self-ascribed name and version of each Node.js
|
|
70
|
-
* package is insufficient because they are not guaranteed to be unique.
|
|
71
|
-
* Dependencies do not necessarilly come from the npm registry and may be
|
|
72
|
-
* for example derived from fully qualified URL's or Github org and project
|
|
73
|
-
* names.
|
|
74
|
-
* Package managers are also not required to fully deduplicate the hard
|
|
75
|
-
* copy of each package even when they are identical resources.
|
|
76
|
-
* Duplication is undesirable, but we elect to defer that problem to solutions
|
|
77
|
-
* in the package managers, as the alternative would be to consistently hash
|
|
78
|
-
* the original sources of the packages themselves, which may not even be
|
|
79
|
-
* available much less pristine for us.
|
|
80
|
-
*
|
|
81
|
-
* So, instead, we use the lexically least path of dependency names, delimited
|
|
82
|
-
* by hashes.
|
|
83
|
-
* The compartment maps generated by the ./node-modules.js tooling pre-compute
|
|
84
|
-
* these traces for our use here.
|
|
85
|
-
* We sort the compartments lexically on their self-ascribed name and version,
|
|
86
|
-
* and use the lexically least dependency name path as a tie-breaker.
|
|
87
|
-
* The dependency path is logical and orthogonal to the package manager's
|
|
88
|
-
* actual installation location, so should be orthogonal to the vagaries of the
|
|
89
|
-
* package manager's deduplication algorithm.
|
|
90
|
-
*
|
|
91
|
-
* @param {Record<string, CompartmentDescriptor>} compartments
|
|
92
|
-
* @returns {Record<string, string>} map from old to new compartment names.
|
|
93
|
-
*/
|
|
94
|
-
const renameCompartments = compartments => {
|
|
95
|
-
/** @type {Record<string, string>} */
|
|
96
|
-
const compartmentRenames = create(null);
|
|
97
|
-
let index = 0;
|
|
98
|
-
let prev = '';
|
|
99
|
-
|
|
100
|
-
// The sort below combines two comparators to avoid depending on sort
|
|
101
|
-
// stability, which became standard as recently as 2019.
|
|
102
|
-
// If that date seems quaint, please accept my regards from the distant past.
|
|
103
|
-
// We are very proud of you.
|
|
104
|
-
const compartmentsByPath = Object.entries(compartments)
|
|
105
|
-
.map(([name, compartment]) => ({
|
|
106
|
-
name,
|
|
107
|
-
path: compartment.path,
|
|
108
|
-
label: compartment.label,
|
|
109
|
-
}))
|
|
110
|
-
.sort((a, b) => {
|
|
111
|
-
if (a.label === b.label) {
|
|
112
|
-
assert(a.path !== undefined && b.path !== undefined);
|
|
113
|
-
return pathCompare(a.path, b.path);
|
|
114
|
-
}
|
|
115
|
-
return stringCompare(a.label, b.label);
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
for (const { name, label } of compartmentsByPath) {
|
|
119
|
-
if (label === prev) {
|
|
120
|
-
compartmentRenames[name] = `${label}-n${index}`;
|
|
121
|
-
index += 1;
|
|
122
|
-
} else {
|
|
123
|
-
compartmentRenames[name] = label;
|
|
124
|
-
prev = label;
|
|
125
|
-
index = 1;
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
return compartmentRenames;
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* @param {Record<string, CompartmentDescriptor>} compartments
|
|
133
|
-
* @param {Sources} sources
|
|
134
|
-
* @param {Record<string, string>} compartmentRenames
|
|
135
|
-
*/
|
|
136
|
-
const translateCompartmentMap = (compartments, sources, compartmentRenames) => {
|
|
137
|
-
const result = create(null);
|
|
138
|
-
for (const compartmentName of keys(compartmentRenames)) {
|
|
139
|
-
const compartment = compartments[compartmentName];
|
|
140
|
-
const { name, label, retained, policy } = compartment;
|
|
141
|
-
if (retained) {
|
|
142
|
-
// rename module compartments
|
|
143
|
-
/** @type {Record<string, ModuleDescriptor>} */
|
|
144
|
-
const modules = create(null);
|
|
145
|
-
const compartmentModules = compartment.modules;
|
|
146
|
-
if (compartment.modules) {
|
|
147
|
-
for (const name of keys(compartmentModules).sort()) {
|
|
148
|
-
const module = compartmentModules[name];
|
|
149
|
-
if (module.compartment !== undefined) {
|
|
150
|
-
modules[name] = {
|
|
151
|
-
...module,
|
|
152
|
-
compartment: compartmentRenames[module.compartment],
|
|
153
|
-
};
|
|
154
|
-
} else {
|
|
155
|
-
modules[name] = module;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
// integrate sources into modules
|
|
161
|
-
const compartmentSources = sources[compartmentName];
|
|
162
|
-
if (compartmentSources) {
|
|
163
|
-
for (const name of keys(compartmentSources).sort()) {
|
|
164
|
-
const source = compartmentSources[name];
|
|
165
|
-
const { location, parser, exit, sha512, deferredError } = source;
|
|
166
|
-
if (location !== undefined) {
|
|
167
|
-
modules[name] = {
|
|
168
|
-
location,
|
|
169
|
-
parser,
|
|
170
|
-
sha512,
|
|
171
|
-
};
|
|
172
|
-
} else if (exit !== undefined) {
|
|
173
|
-
modules[name] = {
|
|
174
|
-
exit,
|
|
175
|
-
};
|
|
176
|
-
} else if (deferredError !== undefined) {
|
|
177
|
-
modules[name] = {
|
|
178
|
-
deferredError,
|
|
179
|
-
};
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
result[compartmentRenames[compartmentName]] = {
|
|
185
|
-
name,
|
|
186
|
-
label,
|
|
187
|
-
location: compartmentRenames[compartmentName],
|
|
188
|
-
modules,
|
|
189
|
-
policy,
|
|
190
|
-
// `scopes`, `types`, and `parsers` are not necessary since every
|
|
191
|
-
// loadable module is captured in `modules`.
|
|
192
|
-
};
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
return result;
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* @param {Sources} sources
|
|
201
|
-
* @param {Record<string, string>} compartmentRenames
|
|
202
|
-
* @returns {Sources}
|
|
203
|
-
*/
|
|
204
|
-
const renameSources = (sources, compartmentRenames) => {
|
|
205
|
-
return fromEntries(
|
|
206
|
-
entries(sources).map(([name, compartmentSources]) => [
|
|
207
|
-
compartmentRenames[name],
|
|
208
|
-
compartmentSources,
|
|
209
|
-
]),
|
|
210
|
-
);
|
|
211
|
-
};
|
|
212
|
-
|
|
213
57
|
/**
|
|
214
58
|
* @param {CompartmentMapDescriptor} compartmentMap
|
|
215
59
|
* @param {Sources} sources
|
|
@@ -217,40 +61,18 @@ const renameSources = (sources, compartmentRenames) => {
|
|
|
217
61
|
*/
|
|
218
62
|
const captureCompartmentMap = (compartmentMap, sources) => {
|
|
219
63
|
const {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
const compartmentRenames = renameCompartments(compartments);
|
|
225
|
-
const captureCompartments = translateCompartmentMap(
|
|
226
|
-
compartments,
|
|
227
|
-
sources,
|
|
64
|
+
compartmentMap: captureCompartmentMap,
|
|
65
|
+
sources: captureSources,
|
|
66
|
+
newToOldCompartmentNames,
|
|
228
67
|
compartmentRenames,
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
const captureSources = renameSources(sources, compartmentRenames);
|
|
232
|
-
|
|
233
|
-
const captureCompartmentMap = {
|
|
234
|
-
// TODO graceful migration from tags to conditions
|
|
235
|
-
// https://github.com/endojs/endo/issues/2388
|
|
236
|
-
tags: [],
|
|
237
|
-
entry: {
|
|
238
|
-
compartment: captureEntryCompartmentName,
|
|
239
|
-
module: entryModuleSpecifier,
|
|
240
|
-
},
|
|
241
|
-
compartments: captureCompartments,
|
|
242
|
-
};
|
|
243
|
-
|
|
244
|
-
// Cross-check:
|
|
245
|
-
// We assert that we have constructed a valid compartment map, not because it
|
|
246
|
-
// might not be, but to ensure that the assertCompartmentMap function can
|
|
247
|
-
// accept all valid compartment maps.
|
|
248
|
-
assertCompartmentMap(captureCompartmentMap);
|
|
249
|
-
|
|
68
|
+
oldToNewCompartmentNames,
|
|
69
|
+
} = digestCompartmentMap(compartmentMap, sources);
|
|
250
70
|
return {
|
|
251
71
|
captureCompartmentMap,
|
|
252
72
|
captureSources,
|
|
253
73
|
compartmentRenames,
|
|
74
|
+
newToOldCompartmentNames,
|
|
75
|
+
oldToNewCompartmentNames,
|
|
254
76
|
};
|
|
255
77
|
};
|
|
256
78
|
|
package/src/digest.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export function digestCompartmentMap(compartmentMap: CompartmentMapDescriptor, sources: Sources): DigestResult;
|
|
2
|
+
import type { CompartmentMapDescriptor } from './types.js';
|
|
3
|
+
import type { Sources } from './types.js';
|
|
4
|
+
import type { DigestResult } from './types.js';
|
|
5
|
+
//# sourceMappingURL=digest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"digest.d.ts","sourceRoot":"","sources":["digest.js"],"names":[],"mappings":"AAwLO,qDAJI,wBAAwB,WACxB,OAAO,GACL,YAAY,CAoDxB;8CA3NS,YAAY;6BAAZ,YAAY;kCAAZ,YAAY"}
|