Skip to content

Commit 5cd0309

Browse files
committed
squashme poc
1 parent 6445f79 commit 5cd0309

File tree

10 files changed

+128
-14
lines changed

10 files changed

+128
-14
lines changed

packages/compartment-mapper/demo/policy/index.mjs

+11-9
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,6 @@ lockdown({
77
});
88

99
import fs from 'fs';
10-
import os from 'os';
11-
import assert from 'assert';
12-
import zlib from 'zlib';
13-
import path from 'path';
1410

1511
import { importLocation, makeArchive, parseArchive } from '../../index.js';
1612

@@ -98,13 +94,17 @@ const options = {
9894
console,
9995
process,
10096
},
97+
exitModuleImportHook: async specifier => {
98+
const module = await import(specifier);
99+
return module;
100+
},
101101
modules: {
102-
path: await addToCompartment('path', path),
103-
assert: await addToCompartment('assert', assert),
102+
// path: await addToCompartment('path', path),
103+
// assert: await addToCompartment('assert', assert),
104104
buffer: await addToCompartment('buffer', Object.create(null)), // imported but unused
105-
zlib: await addToCompartment('zlib', zlib),
106-
fs: await addToCompartment('fs', fs),
107-
os: await addToCompartment('os', os),
105+
// zlib: await addToCompartment('zlib', zlib),
106+
// fs: await addToCompartment('fs', fs),
107+
// os: await addToCompartment('os', os),
108108
},
109109
};
110110

@@ -124,6 +124,7 @@ console.log('\n\n________________________________________________ Archive\n');
124124
const archive = await makeArchive(readPower, entrypointPath, {
125125
modules: options.modules,
126126
policy: options.policy,
127+
exitModuleImportHook: options.exitModuleImportHook,
127128
});
128129
console.log('>----------makeArchive -> parseArchive');
129130
const application = await parseArchive(archive, '<unknown>', {
@@ -133,6 +134,7 @@ console.log('\n\n________________________________________________ Archive\n');
133134
const { namespace } = await application.import({
134135
globals: options.globals,
135136
modules: options.modules,
137+
exitModuleImportHook: options.exitModuleImportHook,
136138
});
137139
console.log('>----------import -> end');
138140
console.log(2, namespace.poem);

packages/compartment-mapper/src/archive.js

+2
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ const digestLocation = async (powers, moduleLocation, options) => {
259259
searchSuffixes = undefined,
260260
commonDependencies = undefined,
261261
policy = undefined,
262+
exitModuleImportHook = undefined,
262263
} = options || {};
263264
const { read, computeSha512 } = unpackReadPowers(powers);
264265
const {
@@ -299,6 +300,7 @@ const digestLocation = async (powers, moduleLocation, options) => {
299300
sources,
300301
compartments,
301302
exitModules,
303+
exitModuleImportHook, // should it get the archiveOnly hint somehow?
302304
computeSha512,
303305
searchSuffixes,
304306
);

packages/compartment-mapper/src/bundle.js

+1
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ export const makeBundle = async (read, moduleLocation, options) => {
207207
sources,
208208
compartments,
209209
undefined,
210+
undefined, // TODO: support exitModuleImportHook
210211
undefined,
211212
searchSuffixes,
212213
);

packages/compartment-mapper/src/import-archive.js

+32-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
/** @typedef {import('./types.js').ComputeSourceLocationHook} ComputeSourceLocationHook */
1515
/** @typedef {import('./types.js').LoadArchiveOptions} LoadArchiveOptions */
1616
/** @typedef {import('./types.js').ExecuteOptions} ExecuteOptions */
17+
/** @typedef {import('./types.js').ExitModuleImportHook} ExitModuleImportHook */
1718

1819
import { ZipReader } from '@endo/zip';
1920
import { link } from './link.js';
@@ -78,6 +79,7 @@ const postponeErrorToExecute = errorMessage => {
7879
* @param {string} archiveLocation
7980
* @param {HashFn} [computeSha512]
8081
* @param {ComputeSourceLocationHook} [computeSourceLocation]
82+
* @param {ExitModuleImportHook} [exitModuleImportHook]
8183
* @returns {ArchiveImportHookMaker}
8284
*/
8385
const makeArchiveImportHookMaker = (
@@ -86,6 +88,7 @@ const makeArchiveImportHookMaker = (
8688
archiveLocation,
8789
computeSha512 = undefined,
8890
computeSourceLocation = undefined,
91+
exitModuleImportHook = undefined,
8992
) => {
9093
// per-assembly:
9194
/** @type {ArchiveImportHookMaker} */
@@ -97,6 +100,23 @@ const makeArchiveImportHookMaker = (
97100
// per-module:
98101
const module = modules[moduleSpecifier];
99102
if (module === undefined) {
103+
if (exitModuleImportHook) {
104+
console.error('#################x');
105+
const ns = await exitModuleImportHook(moduleSpecifier);
106+
if (ns) {
107+
return {
108+
record: freeze({
109+
imports: [],
110+
exports: Object.keys(ns),
111+
execute: moduleExports => {
112+
moduleExports.default = ns;
113+
Object.assign(moduleExports, ns);
114+
},
115+
}),
116+
specifier: moduleSpecifier,
117+
};
118+
}
119+
}
100120
throw new Error(
101121
`Cannot find module ${q(moduleSpecifier)} in package ${q(
102122
packageLocation,
@@ -190,6 +210,7 @@ const makeFeauxModuleExportsNamespace = Compartment => {
190210
* @param {string} [options.expectedSha512]
191211
* @param {HashFn} [options.computeSha512]
192212
* @param {Record<string, unknown>} [options.modules]
213+
* @param {ExitModuleImportHook} [options.exitModuleImportHook]
193214
* @param {Compartment} [options.Compartment]
194215
* @param {ComputeSourceLocationHook} [options.computeSourceLocation]
195216
* @returns {Promise<Application>}
@@ -205,6 +226,7 @@ export const parseArchive = async (
205226
computeSourceLocation = undefined,
206227
Compartment = DefaultCompartment,
207228
modules = undefined,
229+
exitModuleImportHook = undefined,
208230
} = options;
209231

210232
const archive = new ZipReader(archiveBytes, { name: archiveLocation });
@@ -264,6 +286,7 @@ export const parseArchive = async (
264286
archiveLocation,
265287
computeSha512,
266288
computeSourceLocation,
289+
exitModuleImportHook,
267290
);
268291
// A weakness of the current Compartment design is that the `modules` map
269292
// must be given a module namespace object that passes a brand check.
@@ -291,14 +314,21 @@ export const parseArchive = async (
291314

292315
/** @type {ExecuteFn} */
293316
const execute = async options => {
294-
const { globals, modules, transforms, __shimTransforms__, Compartment } =
295-
options || {};
317+
const {
318+
globals,
319+
modules,
320+
transforms,
321+
__shimTransforms__,
322+
Compartment,
323+
exitModuleImportHook,
324+
} = options || {};
296325
const makeImportHook = makeArchiveImportHookMaker(
297326
get,
298327
compartments,
299328
archiveLocation,
300329
computeSha512,
301330
computeSourceLocation,
331+
exitModuleImportHook,
302332
);
303333
const { compartment, pendingJobsPromise } = link(compartmentMap, {
304334
makeImportHook,

packages/compartment-mapper/src/import-hook.js

+16
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ const nodejsConventionSearchSuffixes = [
6565
* @param {Sources} sources
6666
* @param {Record<string, CompartmentDescriptor>} compartmentDescriptors
6767
* @param {Record<string, any>} exitModules
68+
* @param {ImportHook=} exitModuleImportHook
6869
* @param {HashFn=} computeSha512
6970
* @param {Array<string>} searchSuffixes - Suffixes to search if the unmodified specifier is not found.
7071
* Pass [] to emulate Node.js’s strict behavior.
@@ -80,6 +81,7 @@ export const makeImportHookMaker = (
8081
sources = Object.create(null),
8182
compartmentDescriptors = Object.create(null),
8283
exitModules = Object.create(null),
84+
exitModuleImportHook = undefined,
8385
computeSha512 = undefined,
8486
searchSuffixes = nodejsConventionSearchSuffixes,
8587
) => {
@@ -156,6 +158,20 @@ export const makeImportHookMaker = (
156158
// Archived compartments are not executed.
157159
return freeze({ imports: [], exports: [], execute() {} });
158160
}
161+
if (exitModuleImportHook) {
162+
console.error('#################i');
163+
const ns = await exitModuleImportHook(moduleSpecifier);
164+
if (ns) {
165+
return freeze({
166+
imports: [],
167+
exports: Object.keys(ns),
168+
execute: moduleExports => {
169+
moduleExports.default = ns; // Why is typescript complaining about this?
170+
Object.assign(moduleExports, ns);
171+
},
172+
});
173+
}
174+
}
159175
return deferError(
160176
moduleSpecifier,
161177
new Error(

packages/compartment-mapper/src/import.js

+10-3
Original file line numberDiff line numberDiff line change
@@ -70,14 +70,21 @@ export const loadLocation = async (readPowers, moduleLocation, options) => {
7070

7171
/** @type {ExecuteFn} */
7272
const execute = async (options = {}) => {
73-
const { globals, modules, transforms, __shimTransforms__, Compartment } =
74-
options;
73+
const {
74+
globals,
75+
modules,
76+
transforms,
77+
__shimTransforms__,
78+
Compartment,
79+
exitModuleImportHook,
80+
} = options;
7581
const makeImportHook = makeImportHookMaker(
7682
readPowers,
7783
packageLocation,
7884
undefined,
7985
compartmentMap.compartments,
80-
undefined,
86+
modules,
87+
exitModuleImportHook,
8188
undefined,
8289
searchSuffixes,
8390
);

packages/compartment-mapper/src/types.js

+8
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,12 @@ export {};
225225
* @returns {string|undefined} sourceLocation
226226
*/
227227

228+
/**
229+
* @callback ExitModuleImportHook
230+
* @param {string} specifier
231+
* @returns {Promise<object>} module namespace
232+
*/
233+
228234
/**
229235
* @typedef {object} LoadArchiveOptions
230236
* @property {string} [expectedSha512]
@@ -239,6 +245,7 @@ export {};
239245
* @property {Array<Transform>} [transforms]
240246
* @property {Array<Transform>} [__shimTransforms__]
241247
* @property {Record<string, object>} [modules]
248+
* @property {ExitModuleImportHook} [exitModuleImportHook]
242249
* @property {Record<string, object>} [attenuations]
243250
* @property {Compartment} [Compartment]
244251
*/
@@ -310,6 +317,7 @@ export {};
310317
* @typedef {object} ArchiveOptions
311318
* @property {ModuleTransforms} [moduleTransforms]
312319
* @property {Record<string, any>} [modules]
320+
* @property {ExitModuleImportHook} [exitModuleImportHook]
313321
* @property {boolean} [dev]
314322
* @property {object} [policy]
315323
* @property {Set<string>} [tags]

packages/compartment-mapper/test/fixtures-policy/node_modules/app/importActualBuiltin.js

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)