@endo/compartment-mapper 1.6.2 → 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 (94) 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 +84 -0
  23. package/src/generic-graph.d.ts.map +1 -0
  24. package/src/generic-graph.js +356 -0
  25. package/src/guards.d.ts +18 -0
  26. package/src/guards.d.ts.map +1 -0
  27. package/src/guards.js +109 -0
  28. package/src/hooks.md +124 -0
  29. package/src/import-archive-lite.d.ts.map +1 -1
  30. package/src/import-archive-lite.js +15 -11
  31. package/src/import-archive.d.ts +5 -19
  32. package/src/import-archive.d.ts.map +1 -1
  33. package/src/import-archive.js +7 -27
  34. package/src/import-hook.d.ts +4 -3
  35. package/src/import-hook.d.ts.map +1 -1
  36. package/src/import-hook.js +156 -71
  37. package/src/import-lite.d.ts +6 -6
  38. package/src/import-lite.d.ts.map +1 -1
  39. package/src/import-lite.js +8 -5
  40. package/src/import.d.ts +3 -3
  41. package/src/import.d.ts.map +1 -1
  42. package/src/import.js +16 -6
  43. package/src/infer-exports.d.ts.map +1 -1
  44. package/src/infer-exports.js +16 -6
  45. package/src/json.d.ts +1 -1
  46. package/src/json.d.ts.map +1 -1
  47. package/src/json.js +10 -3
  48. package/src/link.d.ts +4 -3
  49. package/src/link.d.ts.map +1 -1
  50. package/src/link.js +70 -58
  51. package/src/node-modules.d.ts +5 -3
  52. package/src/node-modules.d.ts.map +1 -1
  53. package/src/node-modules.js +648 -245
  54. package/src/node-powers.d.ts +6 -5
  55. package/src/node-powers.d.ts.map +1 -1
  56. package/src/node-powers.js +11 -8
  57. package/src/parse-cjs-shared-export-wrapper.d.ts.map +1 -1
  58. package/src/parse-cjs-shared-export-wrapper.js +3 -1
  59. package/src/policy-format.d.ts +22 -5
  60. package/src/policy-format.d.ts.map +1 -1
  61. package/src/policy-format.js +342 -108
  62. package/src/policy.d.ts +13 -28
  63. package/src/policy.d.ts.map +1 -1
  64. package/src/policy.js +161 -106
  65. package/src/types/canonical-name.d.ts +97 -0
  66. package/src/types/canonical-name.d.ts.map +1 -0
  67. package/src/types/canonical-name.ts +151 -0
  68. package/src/types/compartment-map-schema.d.ts +114 -35
  69. package/src/types/compartment-map-schema.d.ts.map +1 -1
  70. package/src/types/compartment-map-schema.ts +202 -37
  71. package/src/types/external.d.ts +173 -29
  72. package/src/types/external.d.ts.map +1 -1
  73. package/src/types/external.ts +221 -27
  74. package/src/types/generic-graph.d.ts +17 -0
  75. package/src/types/generic-graph.d.ts.map +1 -0
  76. package/src/types/generic-graph.ts +17 -0
  77. package/src/types/internal.d.ts +24 -42
  78. package/src/types/internal.d.ts.map +1 -1
  79. package/src/types/internal.ts +52 -50
  80. package/src/types/node-modules.d.ts +101 -17
  81. package/src/types/node-modules.d.ts.map +1 -1
  82. package/src/types/node-modules.ts +142 -17
  83. package/src/types/policy-schema.d.ts +26 -11
  84. package/src/types/policy-schema.d.ts.map +1 -1
  85. package/src/types/policy-schema.ts +29 -16
  86. package/src/types/policy.d.ts +6 -2
  87. package/src/types/policy.d.ts.map +1 -1
  88. package/src/types/policy.ts +7 -2
  89. package/src/types/powers.d.ts +38 -11
  90. package/src/types/powers.d.ts.map +1 -1
  91. package/src/types/powers.ts +50 -17
  92. package/src/types/typescript.d.ts +28 -0
  93. package/src/types/typescript.d.ts.map +1 -1
  94. package/src/types/typescript.ts +37 -1
@@ -0,0 +1,356 @@
1
+ /**
2
+ * Provides {@link GenericGraph} and {@link makeShortestPath}.
3
+ *
4
+ * Portions adapted from
5
+ * [graph data structure](https://github.com/datavis-tech/graph-data-structure),
6
+ * which is Copyright (c) 2016 Curran Kelleher and licensed under the MIT
7
+ * License.
8
+ *
9
+ * @module
10
+ */
11
+
12
+ /**
13
+ * @import {TraversalContext} from './types/generic-graph.js';
14
+ */
15
+
16
+ const { quote: q } = assert;
17
+
18
+ /**
19
+ * Remove the node with the minimum weight from the priority queue.
20
+ *
21
+ * Performs linear search.
22
+ * @template [T=string]
23
+ * @param {TraversalContext<T>} tracks
24
+ * @returns {T|undefined}
25
+ */
26
+ const extractMin = ({ distances, queue }) => {
27
+ let min = Infinity;
28
+
29
+ /** @type {T|undefined} */
30
+ let minNode;
31
+
32
+ queue.forEach(node => {
33
+ const nodeWeight = distances.get(node) ?? Infinity;
34
+
35
+ if (nodeWeight < min) {
36
+ min = nodeWeight;
37
+ minNode = node;
38
+ }
39
+ });
40
+
41
+ if (minNode === undefined) {
42
+ queue.clear();
43
+ return undefined;
44
+ }
45
+
46
+ queue.delete(minNode);
47
+ return minNode;
48
+ };
49
+
50
+ /**
51
+ * Update context with the new distance to the target node if the distance
52
+ * through the source node is shorter than the current distance.
53
+ *
54
+ * @template [T=string]
55
+ * @param {GenericGraph<T>} graph
56
+ * @param {TraversalContext<NoInfer<T>>} context
57
+ * @param {NoInfer<T>} source
58
+ * @param {NoInfer<T>} target
59
+ */
60
+ const relax = (graph, { distances, predecessors }, source, target) => {
61
+ const number = graph.getEdgeWeight(source, target);
62
+
63
+ const distanceSource = distances.get(source);
64
+ const distanceTarget = distances.get(target);
65
+
66
+ assert(
67
+ distanceSource !== undefined,
68
+ `Missing distance for source ${q(source)}`,
69
+ );
70
+ assert(
71
+ distanceTarget !== undefined,
72
+ `Missing distance for target ${q(target)} target`,
73
+ );
74
+
75
+ if (distanceTarget > distanceSource + number) {
76
+ distances.set(target, distanceSource + number);
77
+ predecessors.set(target, source);
78
+ }
79
+ };
80
+
81
+ /**
82
+ * Assembles the shortest path by traversing the
83
+ * predecessor subgraph from destination to source.
84
+ *
85
+ * @template [T=string]
86
+ * @param {TraversalContext<NoInfer<T>>} context Traversal context object
87
+ * @param {NoInfer<T>} source Source node
88
+ * @param {NoInfer<T>} target Destination node
89
+ * @returns {[T, T, ...T[]]} Nodes from `source` to `target` inclusive
90
+ * @throws If no path is found
91
+ * @throws If the path has less than two nodes
92
+ */
93
+ const getPath = ({ predecessors }, source, target) => {
94
+ /** @type {T[]} */
95
+ const nodeList = [];
96
+
97
+ assert(
98
+ source !== target,
99
+ `Source ${q(source)} cannot be the same as target ${q(target)}`,
100
+ );
101
+
102
+ let node = target;
103
+
104
+ while (predecessors.has(node)) {
105
+ const currentNode = /** @type {T} */ (predecessors.get(node));
106
+ nodeList.push(node);
107
+ node = currentNode;
108
+ }
109
+
110
+ assert.equal(node, source, `No path found from ${q(source)} to ${q(target)}`);
111
+
112
+ nodeList.push(node);
113
+
114
+ assert(
115
+ nodeList.length >= 2,
116
+ `The path from ${source} to ${target} should have at least two nodes`,
117
+ );
118
+
119
+ return /** @type {[T, T, ...T[]]} */ (nodeList.reverse());
120
+ };
121
+
122
+ /**
123
+ * @template [T=string] The type of nodes in the graph
124
+ *
125
+ * A generic graph implementation with edge weights.
126
+ *
127
+ * Edge weights are assumed to be non-negative numbers (including `Infinity`)
128
+ */
129
+ export class GenericGraph {
130
+ /**
131
+ * @type {Set<T>}
132
+ */
133
+ #nodes;
134
+
135
+ /**
136
+ * @type {Map<T, Set<T>>}
137
+ */
138
+ #edges;
139
+
140
+ /**
141
+ * @type {Map<T, Map<T, number>>}
142
+ */
143
+ #edgeWeights;
144
+
145
+ /**
146
+ * Initializes internal data structures.
147
+ */
148
+ constructor() {
149
+ this.#edgeWeights = new Map();
150
+ this.#edges = new Map();
151
+ this.#nodes = new Set();
152
+ }
153
+
154
+ /**
155
+ * Returns a shallow copy of the `Set` of nodes in the graph.
156
+ */
157
+ get nodes() {
158
+ return new Set(this.#nodes);
159
+ }
160
+
161
+ /**
162
+ * Adds a node to the graph.
163
+ * If node was already added, this function does nothing.
164
+ * If node was not already added, this function sets up an empty adjacency list.
165
+ * @param {T} node Node to add
166
+ * @returns {this} This graph instance
167
+ */
168
+ addNode(node) {
169
+ if (!this.#nodes.has(node)) {
170
+ this.#nodes.add(node);
171
+ }
172
+ if (!this.#edges.has(node)) {
173
+ this.#edges.set(node, new Set());
174
+ }
175
+ return this;
176
+ }
177
+
178
+ /**
179
+ * Removes a node from the graph.
180
+ * Also removes incoming and outgoing edges.
181
+ * @param {T} node
182
+ * @returns {this}
183
+ */
184
+ removeNode(node) {
185
+ this.#edges.delete(node);
186
+ this.#nodes.delete(node);
187
+ for (const adjacentNodes of this.#edges.values()) {
188
+ adjacentNodes.delete(node);
189
+ }
190
+ return this;
191
+ }
192
+
193
+ /**
194
+ * Gets the adjacent nodes set for the given node.
195
+ * @param {T} node
196
+ * @returns {Set<T>|undefined}
197
+ */
198
+ adjacent(node) {
199
+ return this.#edges.get(node);
200
+ }
201
+
202
+ /**
203
+ * Sets the weight of the given edge between `source` and `target`.
204
+ *
205
+ * @param {T} source Source node
206
+ * @param {T} target Target node
207
+ * @param {number} weight New edge weight
208
+ * @returns {this}
209
+ */
210
+ setEdgeWeight(source, target, weight) {
211
+ if (!this.#edgeWeights.has(source)) {
212
+ this.#edgeWeights.set(source, new Map());
213
+ }
214
+ const weights = /** @type {Map<T, number>} */ (
215
+ this.#edgeWeights.get(source)
216
+ );
217
+ weights.set(target, weight);
218
+ return this;
219
+ }
220
+
221
+ /**
222
+ * Gets the weight of the given edge between `source` and `target`.
223
+ *
224
+ * @param {T} source Source node
225
+ * @param {T} target Target node
226
+ * @returns {number} Edge weight from source to target
227
+ */
228
+ getEdgeWeight(source, target) {
229
+ const weight = this.#edgeWeights.get(source)?.get(target);
230
+ if (weight === undefined) {
231
+ throw new ReferenceError(
232
+ `Edge weight from ${q(source)} to ${q(target)} is not set`,
233
+ );
234
+ }
235
+ return weight;
236
+ }
237
+
238
+ /**
239
+ * Adds an edge from the `source` node to `target` node.
240
+ *
241
+ * This method will create the `source` and `target` node(s) if they do not
242
+ * already exist.
243
+ *
244
+ * If {@link T `T`} is an object, the comparison is by-reference.
245
+ *
246
+ * @param {T} source Source node
247
+ * @param {T} target Target node
248
+ * @param {number} weight Edge weight from source to target
249
+ * @returns {this} This graph instance
250
+ */
251
+ addEdge(source, target, weight) {
252
+ this.addNode(source);
253
+ this.addNode(target);
254
+ const adjacentNodes = this.adjacent(source);
255
+ assert(adjacentNodes, `Source ${q(source)} should have adjacent nodes`);
256
+
257
+ adjacentNodes.add(target);
258
+ this.setEdgeWeight(source, target, weight);
259
+ return this;
260
+ }
261
+
262
+ /**
263
+ * Removes the edge from the `source` node to `target` node.
264
+ * Does not remove the nodes themselves.
265
+ * Does nothing if the edge does not exist.
266
+ * @param {T} source
267
+ * @param {T} target
268
+ * @returns {this}
269
+ */
270
+ removeEdge(source, target) {
271
+ this.#edges.get(source)?.delete(target);
272
+ return this;
273
+ }
274
+
275
+ /**
276
+ * Returns true if there is an edge from the `source` node to `target` node.
277
+ * @param {T} source
278
+ * @param {T} target
279
+ * @returns {boolean}
280
+ */
281
+ hasEdge(source, target) {
282
+ return this.#edges.get(source)?.has(target) ?? false;
283
+ }
284
+ }
285
+
286
+ /**
287
+ * Dijkstra's algorithm for shortest paths in a graph.
288
+ * @template [T=string] The type of nodes in the graph
289
+ * @param {GenericGraph<T>} graph
290
+ * @param {T} source
291
+ * @param {T} target
292
+ * @returns {TraversalContext<T>}
293
+ */
294
+ const dijkstra = (graph, source, target) => {
295
+ const { nodes } = graph;
296
+ /** @type {TraversalContext<T>} */
297
+ const context = {
298
+ distances: new Map(),
299
+ predecessors: new Map(),
300
+ queue: new Set(),
301
+ };
302
+ const { queue, distances } = context;
303
+
304
+ for (const node of nodes) {
305
+ distances.set(node, Infinity);
306
+ }
307
+
308
+ assert(
309
+ distances.get(source) === Infinity,
310
+ `Source ${q(source)} is not in the graph`,
311
+ );
312
+ assert(
313
+ distances.get(target) === Infinity,
314
+ `Target ${q(target)} is not in the graph`,
315
+ );
316
+
317
+ distances.set(source, 0);
318
+
319
+ for (const node of nodes) {
320
+ queue.add(node);
321
+ }
322
+
323
+ while (queue.size !== 0) {
324
+ const node = extractMin(context);
325
+ if (node === undefined) {
326
+ return context;
327
+ }
328
+ const adjacent = graph.adjacent(node);
329
+ if (adjacent) {
330
+ for (const edge of adjacent) {
331
+ relax(graph, context, node, edge);
332
+ }
333
+ }
334
+ }
335
+ return context;
336
+ };
337
+
338
+ /**
339
+ * Returns a function which uses Dijkstra's shortest path algorithm to compute
340
+ * the shortest path from `source` to `destination` in the given `graph`.
341
+ *
342
+ * @template [T=string]
343
+ * @param {GenericGraph<T>} graph Graph to use
344
+ */
345
+ export const makeShortestPath = graph => {
346
+ /**
347
+ * @param {NoInfer<T>} source Source node
348
+ * @param {NoInfer<T>} target Target node
349
+ * @returns {[T, T, ...T[]]} Nodes from `source` to `target` inclusive (minimum of two nodes)
350
+ */
351
+ const shortestPath = (source, target) => {
352
+ const context = dijkstra(graph, source, target);
353
+ return getPath(context, source, target);
354
+ };
355
+ return shortestPath;
356
+ };
@@ -0,0 +1,18 @@
1
+ export function isErrorModuleConfiguration(value: ModuleConfiguration): value is ErrorModuleConfiguration;
2
+ export function isFileModuleConfiguration(value: ModuleConfiguration): value is FileModuleConfiguration;
3
+ export function isExitModuleConfiguration(value: ModuleConfiguration): value is ExitModuleConfiguration;
4
+ export function isCompartmentModuleConfiguration(value: ModuleConfiguration): value is CompartmentModuleConfiguration;
5
+ export function isErrorModuleSource(value: ModuleSource): value is ErrorModuleSource;
6
+ export function isExitModuleSource(value: ModuleSource): value is ExitModuleSource;
7
+ export function isLocalModuleSource(value: ModuleSource): value is LocalModuleSource;
8
+ export function isNonNullableObject(value: unknown): value is object;
9
+ import type { ModuleConfiguration } from './types.js';
10
+ import type { ErrorModuleConfiguration } from './types.js';
11
+ import type { FileModuleConfiguration } from './types.js';
12
+ import type { ExitModuleConfiguration } from './types.js';
13
+ import type { CompartmentModuleConfiguration } from './types.js';
14
+ import type { ModuleSource } from './types.js';
15
+ import type { ErrorModuleSource } from './types.js';
16
+ import type { ExitModuleSource } from './types.js';
17
+ import type { LocalModuleSource } from './types.js';
18
+ //# sourceMappingURL=guards.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guards.d.ts","sourceRoot":"","sources":["guards.js"],"names":[],"mappings":"AA2BO,kDAHI,mBAAmB,GACjB,KAAK,IAAI,wBAAwB,CAIU;AAQjD,iDAHI,mBAAmB,GACjB,KAAK,IAAI,uBAAuB,CAKT;AAO7B,iDAHI,mBAAmB,GACjB,KAAK,IAAI,uBAAuB,CAKT;AAO7B,wDAHI,mBAAmB,GACjB,KAAK,IAAI,8BAA8B,CAOhB;AAO7B,2CAHI,YAAY,GACV,KAAK,IAAI,iBAAiB,CAIiB;AAQjD,0CAHI,YAAY,GACV,KAAK,IAAI,gBAAgB,CAKT;AAQtB,2CAHI,YAAY,GACV,KAAK,IAAI,iBAAiB,CAWV;AAQtB,2CAHI,OAAO,GACL,KAAK,IAAI,MAAM,CAGiB;yCAzFnC,YAAY;8CAAZ,YAAY;6CAAZ,YAAY;6CAAZ,YAAY;oDAAZ,YAAY;kCAAZ,YAAY;uCAAZ,YAAY;sCAAZ,YAAY;uCAAZ,YAAY"}
package/src/guards.js ADDED
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Common type guards.
3
+ *
4
+ * @module
5
+ */
6
+
7
+ const { hasOwn } = Object;
8
+
9
+ /**
10
+ * @import {
11
+ * ModuleConfiguration,
12
+ * FileModuleConfiguration,
13
+ * ErrorModuleConfiguration,
14
+ * ModuleSource,
15
+ * ExitModuleSource,
16
+ * ErrorModuleSource,
17
+ * LocalModuleSource,
18
+ * ExitModuleConfiguration,
19
+ * CompartmentModuleConfiguration
20
+ * } from './types.js';
21
+ */
22
+
23
+ /**
24
+ * Type guard for an {@link ErrorModuleConfiguration}.
25
+ * @param {ModuleConfiguration} value
26
+ * @returns {value is ErrorModuleConfiguration}
27
+ */
28
+ export const isErrorModuleConfiguration = value =>
29
+ hasOwn(value, 'deferredError') &&
30
+ /** @type {any} */ (value).deferredError !== undefined;
31
+
32
+ /**
33
+ * Type guard for a {@link FileModuleConfiguration}.
34
+ *
35
+ * @param {ModuleConfiguration} value
36
+ * @returns {value is FileModuleConfiguration}
37
+ */
38
+ export const isFileModuleConfiguration = value =>
39
+ hasOwn(value, 'parser') &&
40
+ /** @type {any} */ (value).parser !== undefined &&
41
+ !isErrorModuleConfiguration(value);
42
+
43
+ /**
44
+ * Type guard for an {@link ExitModuleConfiguration}.
45
+ * @param {ModuleConfiguration} value
46
+ * @returns {value is ExitModuleConfiguration}
47
+ */
48
+ export const isExitModuleConfiguration = value =>
49
+ hasOwn(value, 'exit') &&
50
+ /** @type {any} */ (value).exit !== undefined &&
51
+ !isErrorModuleConfiguration(value);
52
+
53
+ /**
54
+ * Type guard for an {@link CompartmentModuleConfiguration}.
55
+ * @param {ModuleConfiguration} value
56
+ * @returns {value is CompartmentModuleConfiguration}
57
+ */
58
+ export const isCompartmentModuleConfiguration = value =>
59
+ hasOwn(value, 'compartment') &&
60
+ /** @type {any} */ (value).compartment !== undefined &&
61
+ hasOwn(value, 'module') &&
62
+ /** @type {any} */ (value).module !== undefined &&
63
+ !isErrorModuleConfiguration(value);
64
+ /**
65
+ * Type guard for an {@link ErrorModuleSource}.
66
+ *
67
+ * @param {ModuleSource} value
68
+ * @returns {value is ErrorModuleSource}
69
+ */
70
+ export const isErrorModuleSource = value =>
71
+ hasOwn(value, 'deferredError') &&
72
+ /** @type {any} */ (value).deferredError !== undefined;
73
+
74
+ /**
75
+ * Type guard for an {@link ExitModuleSource}.
76
+ *
77
+ * @param {ModuleSource} value
78
+ * @returns {value is ExitModuleSource}
79
+ */
80
+ export const isExitModuleSource = value =>
81
+ hasOwn(value, 'exit') &&
82
+ /** @type {any} */ (value).exit !== undefined &&
83
+ !isErrorModuleSource(value);
84
+
85
+ /**
86
+ * Type guard for an {@link LocalModuleSource}.
87
+ *
88
+ * @param {ModuleSource} value
89
+ * @returns {value is LocalModuleSource}
90
+ */
91
+ export const isLocalModuleSource = value =>
92
+ hasOwn(value, 'bytes') &&
93
+ /** @type {any} */ (value).bytes !== undefined &&
94
+ hasOwn(value, 'parser') &&
95
+ /** @type {any} */ (value).parser !== undefined &&
96
+ hasOwn(value, 'sourceDirname') &&
97
+ /** @type {any} */ (value).sourceDirname !== undefined &&
98
+ hasOwn(value, 'location') &&
99
+ /** @type {any} */ (value).location !== undefined &&
100
+ !isErrorModuleSource(value);
101
+
102
+ /**
103
+ * Type guard for a non-nullable object
104
+ *
105
+ * @param {unknown} value
106
+ * @returns {value is object}
107
+ */
108
+ export const isNonNullableObject = value =>
109
+ typeof value === 'object' && value !== null;
package/src/hooks.md ADDED
@@ -0,0 +1,124 @@
1
+ # Review of compartment-mapper hooks
2
+
3
+
4
+
5
+ | Hook Name | Description |
6
+ |-------------------------- | --- |
7
+ | `packageDataHook` | Receives all found package descriptors data before graph translation. |
8
+ | `packageDependenciesHook` | Allows dynamic mutation of dependencies during node_modules graph translation. |
9
+ | `unknownCanonicalNameHook`| Called when the policy references unknown canonical names, can suggest typos/similar names. |
10
+ | `moduleSourceHook` | Invoked when a module source is created. |
11
+ | `packageConnectionsHook` | Surfaces connections during digest. (ignored in archiving) |
12
+
13
+
14
+
15
+ [Type declarations for the hooks](./types/external.ts)
16
+
17
+ ```mermaid
18
+ graph TB
19
+
20
+ exports((public exports))
21
+ exports -.- compartmentMapForNodeModules
22
+ exports -.- mapNodeModules
23
+ exports -.- loadLocation
24
+ exports -.- importLocation
25
+ exports -.- captureFromMap
26
+ exports -.- importFromMap
27
+ exports -.- loadFromMap
28
+ exports -.- digestCompartmentMap
29
+ exports -.- makeFunctor
30
+ exports -.- makeScript
31
+
32
+
33
+ subgraph "import-hook.js"
34
+ moduleSourceHook{{moduleSourceHook}} -.- note5["for all module sources read"]
35
+ makeDeferError --> moduleSourceHook
36
+ makeImportHookMaker --> makeDeferError
37
+ makeImportNowHookMaker --> makeDeferError
38
+ makeImportNowHookMaker -- via importNowHook --> chooseModuleDescriptor --> executeLocalModuleSourceHook--> moduleSourceHook
39
+ makeImportHookMaker --via importHook exitModule logic--> moduleSourceHook
40
+ makeImportHookMaker --via importHook call--> chooseModuleDescriptor
41
+ end
42
+
43
+ subgraph "node-modules.js"
44
+ compartmentMapForNodeModules --> packageDataHook{{packageDataHook}} -.- note0["called once"]
45
+ compartmentMapForNodeModules --> unknownCanonicalNameHook{{unknownCanonicalNameHook}} -.- note1["for all issues from policy;<br>after defaultUnknownCanonicalNameHandler"]
46
+ compartmentMapForNodeModules --> translateGraph --> packageDependenciesHook{{packageDependenciesHook}} -.-note3["for all locatons in graph<br>after defaultPackageDependenciesFilter"]
47
+ mapNodeModules --> compartmentMapForNodeModules
48
+
49
+ end
50
+
51
+ subgraph "digest.js"
52
+ digestCompartmentMap --> translateCompartmentMap --> packageConnectionsHook{{packageConnectionsHook}} -.- note4["for all retained compartments"]
53
+ end
54
+
55
+ subgraph "bundle.js"
56
+ makeFunctor -- options:can include hooks ----------> mapNodeModules
57
+ makeScript -- options:can include hooks ----------> mapNodeModules
58
+ end
59
+
60
+
61
+ subgraph "import-lite.js"
62
+ importFromMap --> loadFromMap ---> makeImportHookMaker
63
+ loadFromMap ----> makeImportNowHookMaker
64
+ end
65
+
66
+
67
+ subgraph "capture-lite.js"
68
+ captureFromMap -----> makeImportHookMaker
69
+ captureFromMap --> captureCompartmentMap --> digestCompartmentMap
70
+ end
71
+
72
+
73
+ subgraph "import.js"
74
+ loadLocation ----------> mapNodeModules
75
+ importLocation --> loadLocation
76
+ loadLocation --> loadFromMap
77
+ end
78
+
79
+
80
+ %% STYLING
81
+ classDef note fill:#999, stroke:#ccb
82
+ class note0,note1,note2,note3,note4,note5 note
83
+
84
+ ```
85
+
86
+
87
+
88
+ <details>
89
+ <summary>Bundle and Archive bits of the diagram that don't use hooks</summary>
90
+
91
+ These are calling the functions accepting hooks but don't pass them
92
+
93
+ > [TODO]
94
+ > copy-paste this to the main diagram whenever the connections are made.
95
+
96
+ ```mermaid
97
+
98
+ graph TB
99
+
100
+ subgraph "bundle.js"
101
+ makeFunctor -- options:transparently ----------> mapNodeModules
102
+ makeScript -- options:transparently ----------> mapNodeModules
103
+ makeFunctorFromMap -- no moduleSourceHook ----x makeImportHookMaker
104
+ end
105
+
106
+ subgraph "bundle-lite.js"
107
+ makeFunctorFromMap2 --no moduleSourceHook -----x makeImportHookMaker
108
+ end
109
+
110
+ subgraph "archive-lite.js"
111
+ digestFromMap -- no moduleSourceHook -----x makeImportHookMaker
112
+ makeArchiveCompartmentMap --no packageConnectionsHook----x digestCompartmentMap
113
+ end
114
+
115
+ subgraph "archive.js"
116
+ archive(("multiple <br> methods")) --no hooks passed-----------x mapNodeModules
117
+ end
118
+
119
+ ```
120
+
121
+ </details>
122
+
123
+
124
+
@@ -1 +1 @@
1
- {"version":3,"file":"import-archive-lite.d.ts","sourceRoot":"","sources":["import-archive-lite.js"],"names":[],"mappings":"AAsPO,2CALI,UAAU,oBACV,MAAM,YACN,mBAAmB,GACjB,OAAO,CAAC,WAAW,CAAC,CAiKhC;AAQM,wCALI,MAAM,GAAG,UAAU,mBACnB,MAAM,YACN,kBAAkB,GAChB,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"}
1
+ {"version":3,"file":"import-archive-lite.d.ts","sourceRoot":"","sources":["import-archive-lite.js"],"names":[],"mappings":"AA0PO,2CALI,UAAU,oBACV,MAAM,YACN,mBAAmB,GACjB,OAAO,CAAC,WAAW,CAAC,CAiKhC;AAQM,wCALI,MAAM,GAAG,UAAU,mBACnB,MAAM,YACN,kBAAkB,GAChB,OAAO,CAAC,WAAW,CAAC,CAwBhC;AAQM,0CALI,MAAM,GAAG,UAAU,mBACnB,MAAM,WACN,kBAAkB,GAChB,OAAO,CAAC,UAAU,CAAC,CAK/B;yCA5ZS,YAAY;iCAAZ,YAAY;4BAAZ,YAAY;gCAAZ,YAAY;wCAAZ,YAAY;gCAAZ,YAAY"}
@@ -23,7 +23,7 @@
23
23
  * } from 'ses';
24
24
  * @import {
25
25
  * Application,
26
- * CompartmentDescriptor,
26
+ * FileCompartmentDescriptor,
27
27
  * ComputeSourceLocationHook,
28
28
  * ComputeSourceMapLocationHook,
29
29
  * ExecuteFn,
@@ -44,9 +44,13 @@ import { link } from './link.js';
44
44
  import { parseLocatedJson } from './json.js';
45
45
  import { unpackReadPowers } from './powers.js';
46
46
  import { join } from './node-module-specifier.js';
47
- import { assertCompartmentMap } from './compartment-map.js';
47
+ import { assertFileCompartmentMap } from './compartment-map.js';
48
48
  import { exitModuleImportHookMaker } from './import-hook.js';
49
- import { attenuateModuleHook, enforceModulePolicy } from './policy.js';
49
+ import { attenuateModuleHook, enforcePolicyByModule } from './policy.js';
50
+ import {
51
+ isErrorModuleConfiguration,
52
+ isFileModuleConfiguration,
53
+ } from './guards.js';
50
54
 
51
55
  const { Fail, quote: q } = assert;
52
56
 
@@ -77,7 +81,7 @@ const postponeErrorToExecute = errorMessage => {
77
81
 
78
82
  /**
79
83
  * @param {(path: string) => Uint8Array} get
80
- * @param {Record<string, CompartmentDescriptor>} compartments
84
+ * @param {Record<string, FileCompartmentDescriptor>} compartments
81
85
  * @param {string} archiveLocation
82
86
  * @param {ParserForLanguage} parserForLanguage
83
87
  * @param {HashFn} [computeSha512]
@@ -118,7 +122,7 @@ const makeArchiveImportHookMaker = (
118
122
  // At this point in archive importing, if a module is not found and
119
123
  // exitModuleImportHook exists, the only possibility is that the
120
124
  // module is a "builtin" module and the policy needs to be enforced.
121
- enforceModulePolicy(moduleSpecifier, compartmentDescriptor, {
125
+ enforcePolicyByModule(moduleSpecifier, compartmentDescriptor, {
122
126
  exit: true,
123
127
  errorHint: `Blocked in loading. ${q(
124
128
  moduleSpecifier,
@@ -161,22 +165,22 @@ const makeArchiveImportHookMaker = (
161
165
  )} in archive ${q(archiveLocation)}`,
162
166
  );
163
167
  }
164
- if (module.deferredError !== undefined) {
168
+ if (isErrorModuleConfiguration(module)) {
165
169
  return postponeErrorToExecute(module.deferredError);
166
170
  }
167
- if (module.parser === undefined) {
171
+ if (!isFileModuleConfiguration(module)) {
168
172
  throw Error(
169
173
  `Cannot parse module ${q(moduleSpecifier)} in package ${q(
170
174
  packageLocation,
171
- )} in archive ${q(archiveLocation)}`,
175
+ )} in archive ${q(archiveLocation)}; missing parser`,
172
176
  );
173
177
  }
174
178
  const parser = parserForLanguage[module.parser];
175
179
  if (parser === undefined) {
176
180
  throw Error(
177
- `Cannot parse ${q(module.parser)} module ${q(
181
+ `Cannot parse module ${q(
178
182
  moduleSpecifier,
179
- )} in package ${q(packageLocation)} in archive ${q(archiveLocation)}`,
183
+ )} in package ${q(packageLocation)} in archive ${q(archiveLocation)}; unknown parser (${q(module.parser)})`,
180
184
  );
181
185
  }
182
186
  const { parse } = parser;
@@ -306,7 +310,7 @@ export const parseArchive = async (
306
310
  compartmentMapText,
307
311
  'compartment-map.json',
308
312
  );
309
- assertCompartmentMap(compartmentMap, archiveLocation);
313
+ assertFileCompartmentMap(compartmentMap, archiveLocation);
310
314
 
311
315
  const {
312
316
  compartments,