@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.
Files changed (95) hide show
  1. package/package.json +24 -14
  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 +81 -30
  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 +243 -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 +738 -254
  19. package/src/digest.d.ts +22 -2
  20. package/src/digest.d.ts.map +1 -1
  21. package/src/digest.js +180 -57
  22. package/src/generic-graph.d.ts +7 -25
  23. package/src/generic-graph.d.ts.map +1 -1
  24. package/src/generic-graph.js +83 -108
  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 +140 -70
  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 +4 -2
  44. package/src/infer-exports.d.ts.map +1 -1
  45. package/src/infer-exports.js +172 -23
  46. package/src/link.d.ts +4 -3
  47. package/src/link.d.ts.map +1 -1
  48. package/src/link.js +122 -52
  49. package/src/node-modules.d.ts +4 -3
  50. package/src/node-modules.d.ts.map +1 -1
  51. package/src/node-modules.js +513 -151
  52. package/src/parse-cjs-shared-export-wrapper.d.ts.map +1 -1
  53. package/src/parse-cjs-shared-export-wrapper.js +3 -1
  54. package/src/pattern-replacement.d.ts +6 -0
  55. package/src/pattern-replacement.d.ts.map +1 -0
  56. package/src/pattern-replacement.js +198 -0
  57. package/src/policy-format.d.ts +22 -5
  58. package/src/policy-format.d.ts.map +1 -1
  59. package/src/policy-format.js +342 -108
  60. package/src/policy.d.ts +13 -28
  61. package/src/policy.d.ts.map +1 -1
  62. package/src/policy.js +161 -106
  63. package/src/types/canonical-name.d.ts +97 -0
  64. package/src/types/canonical-name.d.ts.map +1 -0
  65. package/src/types/canonical-name.ts +151 -0
  66. package/src/types/compartment-map-schema.d.ts +121 -35
  67. package/src/types/compartment-map-schema.d.ts.map +1 -1
  68. package/src/types/compartment-map-schema.ts +211 -37
  69. package/src/types/external.d.ts +240 -76
  70. package/src/types/external.d.ts.map +1 -1
  71. package/src/types/external.ts +305 -74
  72. package/src/types/generic-graph.d.ts +8 -2
  73. package/src/types/generic-graph.d.ts.map +1 -1
  74. package/src/types/generic-graph.ts +7 -2
  75. package/src/types/internal.d.ts +31 -50
  76. package/src/types/internal.d.ts.map +1 -1
  77. package/src/types/internal.ts +60 -58
  78. package/src/types/node-modules.d.ts +112 -14
  79. package/src/types/node-modules.d.ts.map +1 -1
  80. package/src/types/node-modules.ts +152 -13
  81. package/src/types/pattern-replacement.d.ts +62 -0
  82. package/src/types/pattern-replacement.d.ts.map +1 -0
  83. package/src/types/pattern-replacement.ts +70 -0
  84. package/src/types/policy-schema.d.ts +26 -11
  85. package/src/types/policy-schema.d.ts.map +1 -1
  86. package/src/types/policy-schema.ts +29 -16
  87. package/src/types/policy.d.ts +6 -2
  88. package/src/types/policy.d.ts.map +1 -1
  89. package/src/types/policy.ts +7 -2
  90. package/src/types/powers.d.ts +11 -9
  91. package/src/types/powers.d.ts.map +1 -1
  92. package/src/types/powers.ts +11 -10
  93. package/src/types/typescript.d.ts +28 -0
  94. package/src/types/typescript.d.ts.map +1 -1
  95. package/src/types/typescript.ts +37 -1
@@ -5,51 +5,156 @@
5
5
  * @module
6
6
  */
7
7
 
8
- /** @import {SomePackagePolicy, SomePolicy} from './types.js' */
8
+ /**
9
+ * @import {SomePackagePolicy,
10
+ * PackagePolicy,
11
+ * AttenuationDefinition,
12
+ * PolicyEnforcementField,
13
+ * UnifiedAttenuationDefinition,
14
+ * PolicyItem,
15
+ * TypeGuard,
16
+ * GuardedType,
17
+ * SomeTypeGuard,
18
+ * ImplicitAttenuationDefinition,
19
+ * FullAttenuationDefinition,
20
+ * UnionToIntersection,
21
+ * PackageNamingKit,
22
+ * WildcardPolicy,
23
+ * SomePolicy
24
+ *} from './types.js'
25
+ */
9
26
 
10
- const { entries, keys } = Object;
27
+ const { entries, keys, hasOwn } = Object;
11
28
  const { isArray } = Array;
12
29
  const q = JSON.stringify;
13
30
 
31
+ /**
32
+ * Const string to identify the internal attenuators compartment
33
+ */
34
+ export const ATTENUATORS_COMPARTMENT = '<ATTENUATORS>';
35
+
36
+ export const ENTRY_COMPARTMENT = '$root$';
37
+
38
+ /**
39
+ * @satisfies {keyof FullAttenuationDefinition}
40
+ */
14
41
  const ATTENUATOR_KEY = 'attenuate';
42
+
43
+ /**
44
+ * @satisfies {keyof FullAttenuationDefinition}
45
+ */
15
46
  const ATTENUATOR_PARAMS_KEY = 'params';
47
+
48
+ /**
49
+ * Generates a string identifying a package for policy lookup purposes.
50
+ *
51
+ * @param {PackageNamingKit} namingKit
52
+ * @returns {string}
53
+ */
54
+
55
+ export const generateCanonicalName = ({ isEntry = false, name, path }) => {
56
+ if (isEntry) {
57
+ return ENTRY_COMPARTMENT;
58
+ }
59
+ if (name === ATTENUATORS_COMPARTMENT) {
60
+ return ATTENUATORS_COMPARTMENT;
61
+ }
62
+ return path.join('>');
63
+ };
64
+
16
65
  export const WILDCARD_POLICY_VALUE = 'any';
17
66
 
18
- const POLICY_FIELDS_LOOKUP = /** @type {const} */ ([
67
+ /**
68
+ * @satisfies {PolicyEnforcementField[]}
69
+ */
70
+ const POLICY_ENFORCEMENT_FIELDS = /** @type {const} */ ([
19
71
  'builtins',
20
72
  'globals',
21
73
  'packages',
22
74
  ]);
23
75
 
24
76
  /**
77
+ * Type guard for `undefined`
78
+ *
79
+ * @param {unknown} item
80
+ * @returns {item is undefined}
81
+ */
82
+ const isUndefined = item => item === undefined;
83
+
84
+ /**
85
+ * Type guard for a function or constructor
25
86
  *
26
- * @param {import('./types.js').PackagePolicy} packagePolicy
27
- * @param {'builtins'|'globals'|'packages'} field
28
- * @param {string} itemName
29
- * @returns {boolean | import('./types.js').AttenuationDefinition}
87
+ * @param {unknown} item
88
+ * @returns {item is ((...args: any[]) => any) | (new (...args: any[]) => any)}
89
+ */
90
+ const isFunction = item => typeof item === 'function';
91
+
92
+ /**
93
+ * Type guard for a plain object
94
+ *
95
+ * @param {unknown} item
96
+ * @returns {item is Record<PropertyKey, unknown>}
97
+ */
98
+ const isPlainObject = item =>
99
+ Object(item) === item && !isArray(item) && !isFunction(item);
100
+
101
+ /**
102
+ * Asserts that `item` is a plain object
103
+ *
104
+ * @param {unknown} item
105
+ * @param {string} [message]
106
+ * @returns {asserts item is Record<string, any>}
30
107
  */
31
- export const policyLookupHelper = (packagePolicy, field, itemName) => {
32
- if (!POLICY_FIELDS_LOOKUP.includes(field)) {
33
- throw Error(`Invalid field ${q(field)}`);
108
+ const assertPlainObject = (item, message) => {
109
+ assert(
110
+ isPlainObject(item),
111
+ message ?? `Expected a plain object, got ${q(item)}`,
112
+ );
113
+ };
114
+
115
+ /**
116
+ * Checks if the result of `keys(item).length` is `0`.
117
+ *
118
+ * Not a "real" type guard; probably needs to be used with a type assertion.
119
+ *
120
+ * @param {object} item
121
+ * @returns {item is object}
122
+ */
123
+ const isEmpty = item => keys(item).length === 0;
124
+
125
+ /**
126
+ * Helps find a value in `field` of {@link PackagePolicy} `packagePolicy`
127
+ * matching `itemNameOrPath`.
128
+ *
129
+ * @param {PackagePolicy} packagePolicy Package policy
130
+ * @param {PolicyEnforcementField} field Package policy field to look up
131
+ * @param {string} canonicalName A canonical name
132
+ * @returns {boolean | AttenuationDefinition}
133
+ */
134
+ export const policyLookupHelper = (packagePolicy, field, canonicalName) => {
135
+ assert(
136
+ POLICY_ENFORCEMENT_FIELDS.includes(field),
137
+ `Unknown or unsupported policy field ${q(field)}`,
138
+ );
139
+
140
+ if (!isPlainObject(packagePolicy)) {
141
+ return false;
34
142
  }
35
- if (
36
- typeof packagePolicy !== 'object' ||
37
- packagePolicy === null ||
38
- !packagePolicy[field]
39
- ) {
143
+
144
+ const policyDefinition = packagePolicy[field];
145
+
146
+ if (!policyDefinition) {
40
147
  return false;
41
148
  }
42
149
 
43
- if (packagePolicy[field] === WILDCARD_POLICY_VALUE) {
150
+ if (policyDefinition === WILDCARD_POLICY_VALUE) {
44
151
  return true;
45
152
  }
46
153
 
47
- const value = /** @type {import('./types.js').AttenuationDefinition} */ (
48
- packagePolicy[field]
49
- );
50
- if (itemName in value) {
51
- return value[itemName];
154
+ if (hasOwn(policyDefinition, canonicalName)) {
155
+ return policyDefinition[canonicalName];
52
156
  }
157
+
53
158
  return false;
54
159
  };
55
160
 
@@ -57,61 +162,140 @@ export const policyLookupHelper = (packagePolicy, field, itemName) => {
57
162
  * Type guard; checks if the policy value is set to the wildcard value to allow everything
58
163
  *
59
164
  * @param {unknown} policyValue
60
- * @returns {policyValue is import('./types.js').WildcardPolicy}
165
+ * @returns {policyValue is WildcardPolicy}
61
166
  */
62
167
  export const isAllowingEverything = policyValue =>
63
168
  policyValue === WILDCARD_POLICY_VALUE;
64
169
 
65
170
  /**
66
- * Type guard for `AttenuationDefinition`
171
+ * Type guard for a {@link ImplicitAttenuationDefinition}
172
+ */
173
+ const isImplicitAttenuationDefinition =
174
+ /** @type {TypeGuard<unknown, ImplicitAttenuationDefinition>} */ (isArray);
175
+
176
+ /**
177
+ * Combine multiple type guards with a logical "OR" operation.
178
+ *
179
+ * @template {SomeTypeGuard} T Any type guard function
180
+ * @overload
181
+ * @param {T[]} guards Array of type guard functions
182
+ * @returns {[T] extends [TypeGuard<infer U, any>] ? (value: U) => value is GuardedType<T> : never} Type guard that returns a union of the types checked by the guards
183
+ */
184
+
185
+ /**
186
+ * Combine two type guards with a logical "OR" operation.
187
+ *
188
+ * Note the overload here is due to TS' inflexibility w/r/t using conditional return types.
189
+ * @template {SomeTypeGuard} T
190
+ * @param {T[]} guards
191
+ */
192
+ const or =
193
+ guards =>
194
+ /** @param {any} item */
195
+ item =>
196
+ guards.some(guard => guard(item));
197
+
198
+ /**
199
+ * Combine multiple type guards with a logical "AND" operation.
200
+ *
201
+ * @template {SomeTypeGuard} T Any type guard function
202
+ * @overload
203
+ * @param {T[]} guards Array of type guard functions
204
+ * @returns {[T] extends [TypeGuard<infer U, any>] ? (value: U) => value is Extract<UnionToIntersection<GuardedType<T>>, U> : never} Type guard that returns an intesection of the types checked by the guards
205
+ */
206
+
207
+ /**
208
+ * @template {SomeTypeGuard} T
209
+ * @param {T[]} guards
210
+ */
211
+ const and = guards => /** @param {any} item */ item =>
212
+ guards.every(guard => guard(item));
213
+
214
+ /**
215
+ * @template {SomeTypeGuard} T
216
+ * @overload
217
+ * @param {T} guard
218
+ * @returns {[T] extends [TypeGuard<infer U, any>] ? (value: U) => value is GuardedType<T> & never : never}
219
+ */
220
+
221
+ /**
222
+ * @template {SomeTypeGuard} T
223
+ * @param {T} guard
224
+ */
225
+ const not = guard => /** @param {any} item */ item => !guard(item);
226
+ /**
227
+ * Type guard for a string
228
+ *
229
+ * @param {unknown} item
230
+ * @returns {item is string}
231
+ */
232
+ const isString = item => typeof item === 'string';
233
+
234
+ /**
235
+ * Type guard for a {@link FullAttenuationDefinition}
67
236
  * @param {unknown} allegedDefinition
68
- * @returns {allegedDefinition is import('./types.js').AttenuationDefinition}
69
- */
70
- export const isAttenuationDefinition = allegedDefinition => {
71
- return Boolean(
72
- (allegedDefinition &&
73
- typeof allegedDefinition === 'object' &&
74
- typeof allegedDefinition[ATTENUATOR_KEY] === 'string') || // object with attenuator name
75
- isArray(allegedDefinition), // params for default attenuator
76
- );
77
- };
237
+ * @returns {allegedDefinition is FullAttenuationDefinition}
238
+ */
239
+ const isFullAttenuationDefinition = allegedDefinition =>
240
+ isPlainObject(allegedDefinition) &&
241
+ isString(allegedDefinition[ATTENUATOR_KEY]) &&
242
+ (isUndefined(allegedDefinition[ATTENUATOR_PARAMS_KEY]) ||
243
+ isArray(allegedDefinition[ATTENUATOR_PARAMS_KEY]));
244
+
245
+ /**
246
+ * Type guard for `AttenuationDefinition`
247
+ */
248
+ export const isAttenuationDefinition = or([
249
+ isImplicitAttenuationDefinition,
250
+ isFullAttenuationDefinition,
251
+ ]);
78
252
 
79
253
  /**
254
+ * Converts a {@link ImplicitAttenuationDefinition} or {@link FullAttenuationDefinition} to a {@link UnifiedAttenuationDefinition}
80
255
  *
81
- * @param {import('./types.js').AttenuationDefinition} attenuationDefinition
82
- * @returns {import('./types.js').UnifiedAttenuationDefinition}
256
+ * @param {AttenuationDefinition} attenuationDefinition
257
+ * @returns {UnifiedAttenuationDefinition}
83
258
  */
84
259
  export const getAttenuatorFromDefinition = attenuationDefinition => {
85
- if (!isAttenuationDefinition(attenuationDefinition)) {
86
- throw Error(
87
- `Invalid attenuation ${q(
88
- attenuationDefinition,
89
- )}, must be an array of params for default attenuator or an object with an attenuator key`,
90
- );
91
- }
92
- if (isArray(attenuationDefinition)) {
260
+ if (isImplicitAttenuationDefinition(attenuationDefinition)) {
93
261
  return {
94
262
  displayName: '<default attenuator>',
95
263
  specifier: null,
96
264
  params: attenuationDefinition,
97
265
  };
98
- } else {
266
+ }
267
+
268
+ if (isFullAttenuationDefinition(attenuationDefinition)) {
99
269
  return {
100
270
  displayName: attenuationDefinition[ATTENUATOR_KEY],
101
271
  specifier: attenuationDefinition[ATTENUATOR_KEY],
102
272
  params: attenuationDefinition[ATTENUATOR_PARAMS_KEY],
103
273
  };
104
274
  }
105
- };
106
275
 
107
- // TODO: should be a type guard
108
- const isRecordOf = (item, predicate) => {
109
- if (typeof item !== 'object' || item === null || isArray(item)) {
110
- return false;
111
- }
112
- return entries(item).every(([key, value]) => predicate(value, key));
276
+ throw TypeError(
277
+ `Invalid attenuation ${q(
278
+ attenuationDefinition,
279
+ )}, must be an array of params for default attenuator or an object with an attenuator key`,
280
+ );
113
281
  };
114
282
 
283
+ /**
284
+ * Type guard for a `Record` of items with enumerable keys of type `string` and
285
+ * values of a type defined by a type guard.
286
+ *
287
+ * @template {SomeTypeGuard} T Some type guard function
288
+ * @param {T} guard Type guard function
289
+ */
290
+ const isRecordOf =
291
+ guard =>
292
+ /**
293
+ * @param {unknown} item
294
+ * @returns {item is Record<string, GuardedType<T>>}
295
+ */ item =>
296
+ isPlainObject(item) &&
297
+ entries(item).every(([key, value]) => isString(key) && guard(value));
298
+
115
299
  /**
116
300
  * Type guard for `boolean`
117
301
  * @param {unknown} item
@@ -119,20 +303,71 @@ const isRecordOf = (item, predicate) => {
119
303
  */
120
304
  const isBoolean = item => typeof item === 'boolean';
121
305
 
122
- // TODO: should be a type guard
123
- const predicateOr =
124
- (...predicates) =>
125
- item =>
126
- predicates.some(p => p(item));
306
+ /**
307
+ * Type guard for a `Record<string, boolean>`
308
+ */
309
+ const isRecordOfBoolean = isRecordOf(isBoolean);
127
310
 
128
311
  /**
312
+ * Type guard for {@link PolicyItem}
313
+ *
129
314
  * @param {unknown} item
130
- * @returns {item is import('./types.js').PolicyItem}
315
+ * @returns {item is PolicyItem|undefined}
131
316
  */
132
317
  const isPolicyItem = item =>
133
- item === undefined ||
318
+ isUndefined(item) ||
134
319
  item === WILDCARD_POLICY_VALUE ||
135
- isRecordOf(item, isBoolean);
320
+ isRecordOfBoolean(item);
321
+
322
+ /**
323
+ * Type guard for {@link PackagePolicy.globals}
324
+ */
325
+ const isGlobals = or([isPolicyItem, isAttenuationDefinition]);
326
+
327
+ /**
328
+ * Type guard for {@link PackagePolicy.noGlobalFreeze}
329
+ */
330
+ const isNoGlobalFreeze = or([isUndefined, isBoolean]);
331
+
332
+ /**
333
+ * Type guard for {@link PackagePolicy.builtins}
334
+ */
335
+ const isBuiltins = or([
336
+ isPolicyItem,
337
+ isRecordOf(or([isBoolean, isAttenuationDefinition])),
338
+ ]);
339
+
340
+ /**
341
+ * Type guard for an empty object
342
+ *
343
+ * TODO: Shouldn't need type assertions here
344
+ */
345
+ const isEmptyObject =
346
+ /** @type {TypeGuard<unknown, Record<PropertyKey, never>>} */ (
347
+ and([
348
+ isPlainObject,
349
+ /**
350
+ * @type {TypeGuard<any, Record<PropertyKey, never>>}
351
+ */
352
+ value => isEmpty(value),
353
+ ])
354
+ );
355
+
356
+ /**
357
+ * Type guard for an empty string
358
+ */
359
+ const isEmptyString = and([
360
+ isString,
361
+ /** @type {TypeGuard<unknown, {length: 0}>} */ (isEmpty),
362
+ ]);
363
+
364
+ /**
365
+ * Type guard for {@link PackagePolicy.defaultAttenuator}
366
+ */
367
+ const isDefaultAttenuator = or([
368
+ isUndefined,
369
+ and([isString, not(isEmptyString)]),
370
+ ]);
136
371
 
137
372
  /**
138
373
  * This asserts (i.e., throws) that `allegedPackagePolicy` is a valid `PackagePolicy`.
@@ -140,68 +375,66 @@ const isPolicyItem = item =>
140
375
  * Mild-mannered during the day, but fights crime at night as a type guard.
141
376
  *
142
377
  * @param {unknown} allegedPackagePolicy - Alleged `PackagePolicy` to test
143
- * @param {string} path - Path in the `Policy` object; used for error messages only
378
+ * @param {string} keypath - Keypath in the `Policy` object; used for error messages only
144
379
  * @param {string} [url] - URL of the policy file; used for error messages only
145
380
  * @returns {asserts allegedPackagePolicy is SomePackagePolicy|undefined}
146
381
  */
147
- export const assertPackagePolicy = (allegedPackagePolicy, path, url) => {
148
- if (allegedPackagePolicy === undefined) {
382
+ export const assertPackagePolicy = (allegedPackagePolicy, keypath, url) => {
383
+ if (isUndefined(allegedPackagePolicy)) {
149
384
  return;
150
385
  }
386
+
151
387
  const inUrl = url ? ` in ${q(url)}` : '';
152
388
 
153
- const packagePolicy = Object(allegedPackagePolicy);
154
- assert(
155
- allegedPackagePolicy === packagePolicy && !isArray(allegedPackagePolicy),
156
- `${path} must be an object, got ${q(allegedPackagePolicy)}${inUrl}`,
389
+ assertPlainObject(
390
+ allegedPackagePolicy,
391
+ `${keypath} must be an object, got ${q(allegedPackagePolicy)}${inUrl}`,
157
392
  );
393
+
158
394
  const {
159
395
  packages,
160
396
  builtins,
161
397
  globals,
162
398
  noGlobalFreeze,
163
- defaultAttenuator: _ignore, // a carve out for the default attenuator in compartment map
164
- // eslint-disable-next-line no-unused-vars
165
- options, // any extra options
399
+ defaultAttenuator: _defaultAttenuator, // a carve out for the default attenuator in compartment map
400
+ options: _options, // any extra options
166
401
  ...extra
167
- } = /** @type {SomePackagePolicy} */ (packagePolicy);
402
+ } = allegedPackagePolicy;
168
403
 
169
404
  assert(
170
- keys(extra).length === 0,
171
- `${path} must not have extra properties, got ${q(keys(extra))}${inUrl}`,
405
+ isEmptyObject(extra),
406
+ `${keypath} must not have extra properties, got ${q(keys(extra))}${inUrl}`,
172
407
  );
173
408
 
174
409
  assert(
175
- noGlobalFreeze === undefined || typeof noGlobalFreeze === 'boolean',
176
- `${path}.noGlobalFreeze must be a boolean, got ${q({
410
+ isNoGlobalFreeze(noGlobalFreeze),
411
+ `${keypath}.noGlobalFreeze must be a boolean, got ${q({
177
412
  noGlobalFreeze,
178
413
  })}${inUrl}`,
179
414
  );
180
415
 
181
- isPolicyItem(packages) ||
182
- assert.fail(
183
- `${path}.packages must be a record of booleans, got ${q({
184
- packages,
185
- })}${inUrl}`,
186
- );
187
-
188
- isPolicyItem(globals) ||
189
- isAttenuationDefinition(globals) ||
190
- assert.fail(
191
- `${path}.globals must be a record of booleans or a single attenuation, got ${q(
192
- {
193
- globals,
194
- },
195
- )}${inUrl}`,
196
- );
197
-
198
- isPolicyItem(builtins) ||
199
- isRecordOf(builtins, predicateOr(isBoolean, isAttenuationDefinition)) ||
200
- assert.fail(
201
- `${path}.builtins must be a record of booleans or attenuations, got ${q({
202
- builtins,
203
- })}${inUrl}`,
204
- );
416
+ assert(
417
+ isPolicyItem(packages),
418
+ `${keypath}.packages must be a record of booleans, got ${q({
419
+ packages,
420
+ })}${inUrl}`,
421
+ );
422
+
423
+ assert(
424
+ isGlobals(globals),
425
+ `${keypath}.globals must be a record of booleans or a single attenuation, got ${q(
426
+ {
427
+ globals,
428
+ },
429
+ )}${inUrl}`,
430
+ );
431
+
432
+ assert(
433
+ isBuiltins(builtins),
434
+ `${keypath}.builtins must be a record of booleans or attenuations, got ${q({
435
+ builtins,
436
+ })}${inUrl}`,
437
+ );
205
438
  };
206
439
 
207
440
  /**
@@ -213,28 +446,29 @@ export const assertPackagePolicy = (allegedPackagePolicy, path, url) => {
213
446
  * @returns {asserts allegedPolicy is (SomePolicy | undefined)}
214
447
  */
215
448
  export const assertPolicy = allegedPolicy => {
216
- if (allegedPolicy === undefined) {
449
+ if (isUndefined(allegedPolicy)) {
217
450
  return;
218
451
  }
219
- const policy = Object(allegedPolicy);
220
- assert(
221
- allegedPolicy === policy && !Array.isArray(policy),
222
- `policy must be an object, got ${allegedPolicy}`,
452
+
453
+ assertPlainObject(
454
+ allegedPolicy,
455
+ `policy must be an object, got ${q(allegedPolicy)}`,
223
456
  );
457
+ const { resources, entry, defaultAttenuator, ...extra } = allegedPolicy;
224
458
 
225
- const { resources, entry, defaultAttenuator, ...extra } = policy;
226
459
  assert(
227
- keys(extra).length === 0,
460
+ isEmptyObject(extra),
228
461
  `policy must not have extra properties, got ${q(keys(extra))}`,
229
462
  );
230
463
 
231
464
  assert(
232
- typeof resources === 'object' && resources !== null && !isArray(resources),
465
+ isPlainObject(resources),
233
466
  `policy.resources must be an object, got ${q(resources)}`,
234
467
  );
468
+
235
469
  assert(
236
- !defaultAttenuator || typeof defaultAttenuator === 'string',
237
- `policy.defaultAttenuator must be a string, got ${q(defaultAttenuator)}`,
470
+ isDefaultAttenuator(defaultAttenuator),
471
+ `policy.defaultAttenuator must be a nonempty string, got ${q(defaultAttenuator)}`,
238
472
  );
239
473
 
240
474
  assertPackagePolicy(entry, `policy.entry`);
package/src/policy.d.ts CHANGED
@@ -1,33 +1,15 @@
1
- /**
2
- * Const string to identify the internal attenuators compartment
3
- */
4
- export const ATTENUATORS_COMPARTMENT: "<ATTENUATORS>";
5
1
  export function detectAttenuators(policy?: Policy): Array<string>;
6
- export function dependencyAllowedByPolicy(namingKit: PackageNamingKit, packagePolicy: PackagePolicy): boolean;
7
- /**
8
- * Returns the policy applicable to the canonicalName of the package
9
- *
10
- * @overload
11
- * @param {PackageNamingKit} namingKit - a key in the policy resources spec is derived from these
12
- * @param {SomePolicy} policy - user supplied policy
13
- * @returns {SomePackagePolicy} packagePolicy if policy was specified
14
- */
15
- export function getPolicyForPackage(namingKit: PackageNamingKit, policy: SomePolicy): SomePackagePolicy;
16
- /**
17
- * Returns `undefined`
18
- *
19
- * @overload
20
- * @param {PackageNamingKit} namingKit - a key in the policy resources spec is derived from these
21
- * @param {SomePolicy} [policy] - user supplied policy
22
- * @returns {SomePackagePolicy|undefined} packagePolicy if policy was specified
23
- */
24
- export function getPolicyForPackage(namingKit: PackageNamingKit, policy?: SomePolicy | undefined): SomePackagePolicy | undefined;
2
+ export function dependencyAllowedByPolicy(canonicalName: CanonicalName, packagePolicy: PackagePolicy): boolean;
3
+ export function makePackagePolicy(label: CanonicalName | typeof ATTENUATORS_COMPARTMENT | typeof ENTRY_COMPARTMENT, { policy }?: {
4
+ policy?: SomePolicy | undefined;
5
+ }): SomePackagePolicy | undefined;
25
6
  export function makeDeferredAttenuatorsProvider(compartments: Record<string, Compartment>, compartmentDescriptors: Record<string, CompartmentDescriptor>): DeferredAttenuatorsProvider;
26
- export function attenuateGlobals(globalThis: object, globals: object, packagePolicy: PackagePolicy, attenuators: DeferredAttenuatorsProvider, pendingJobs: Array<Promise<any>>, name?: string): void;
27
- export function enforceModulePolicy(specifier: string, compartmentDescriptor: CompartmentDescriptor, { exit, errorHint }?: EnforceModulePolicyOptions): void;
28
- export function attenuateModuleHook(specifier: string, originalModuleRecord: import("ses").ThirdPartyStaticModuleInterface, policy: PackagePolicy, attenuators: DeferredAttenuatorsProvider): Promise<import("ses").ThirdPartyStaticModuleInterface>;
7
+ export function attenuateGlobals(globalThis: object, globals: object, packagePolicy: PackagePolicy | undefined, attenuators: DeferredAttenuatorsProvider, pendingJobs: Array<Promise<any>>, name?: string): void;
8
+ export function enforcePolicyByModule(specifier: string, compartmentDescriptor: CompartmentDescriptor, { exit, errorHint }?: EnforceModulePolicyOptions): void;
9
+ export function enforcePackagePolicyByCanonicalName(compartmentDescriptor: CompartmentDescriptor, referrerCompartmentDescriptor: CompartmentDescriptor, { errorHint }?: EnforceModulePolicyOptions): void;
10
+ export function attenuateModuleHook(specifier: string, originalModuleRecord: ThirdPartyStaticModuleInterface, policy: PackagePolicy | undefined, attenuators: DeferredAttenuatorsProvider): Promise<ThirdPartyStaticModuleInterface>;
29
11
  /**
30
- * Options for {@link enforceModulePolicy}
12
+ * Options for {@link enforcePolicyByModule}
31
13
  */
32
14
  export type EnforceModulePolicyOptions = {
33
15
  /**
@@ -40,10 +22,13 @@ export type EnforceModulePolicyOptions = {
40
22
  errorHint?: string | undefined;
41
23
  };
42
24
  import type { Policy } from './types.js';
43
- import type { PackageNamingKit } from './types.js';
25
+ import type { CanonicalName } from './types.js';
44
26
  import type { PackagePolicy } from './types.js';
27
+ import { ATTENUATORS_COMPARTMENT } from './policy-format.js';
28
+ import { ENTRY_COMPARTMENT } from './policy-format.js';
45
29
  import type { SomePolicy } from './types.js';
46
30
  import type { SomePackagePolicy } from './types.js';
47
31
  import type { CompartmentDescriptor } from './types.js';
48
32
  import type { DeferredAttenuatorsProvider } from './types.js';
33
+ import type { ThirdPartyStaticModuleInterface } from 'ses';
49
34
  //# sourceMappingURL=policy.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["policy.js"],"names":[],"mappings":"AAkCA;;GAEG;AACH,sCAAuC,eAAe,CAAC;AAyDhD,2CAHI,MAAM,GACJ,KAAK,CAAC,MAAM,CAAC,CAezB;AA0BM,qDAJI,gBAAgB,iBAChB,aAAa,GACX,OAAO,CASnB;;;;;;;;;AAKE,+CACQ,gBAAgB,UAChB,UAAU,GACR,iBAAiB,CAC7B;;;;;;;;;AAKE,+CACQ,gBAAgB,oCAEd,iBAAiB,GAAC,SAAS,CACvC;AA+EM,8DAJI,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,0BAC3B,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,GACnC,2BAA2B,CA0CvC;AAoDM,6CARI,MAAM,WACN,MAAM,iBACN,aAAa,eACb,2BAA2B,eAC3B,KAAK,cAAS,SACd,MAAM,GACJ,IAAI,CAgDhB;AA2BM,+CAJI,MAAM,yBACN,qBAAqB,wBACrB,0BAA0B,QAgCpC;AAgDM,+CANI,MAAM,wBACN,OAAO,KAAK,EAAE,+BAA+B,UAC7C,aAAa,eACb,2BAA2B,GACzB,OAAO,CAAC,OAAO,KAAK,EAAE,+BAA+B,CAAC,CAyBlE;;;;;;;;;;;;;;4BApeS,YAAY;sCAAZ,YAAY;mCAAZ,YAAY;gCAAZ,YAAY;uCAAZ,YAAY;2CAAZ,YAAY;iDAAZ,YAAY"}
1
+ {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["policy.js"],"names":[],"mappings":"AAqGO,2CAHI,MAAM,GACJ,KAAK,CAAC,MAAM,CAAC,CAezB;AAUM,yDAJI,aAAa,iBACb,aAAa,GACX,OAAO,CAInB;AAaM,yCAPI,aAAa,GAAG,OAAO,uBAAuB,GAAG,OAAO,iBAAiB,eAEjF;IAA6B,MAAM;CACnC,GAAU,iBAAiB,GAAC,SAAS,CA8BvC;AAsDM,8DAJI,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,0BAC3B,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,GACnC,2BAA2B,CA+CvC;AAoDM,6CARI,MAAM,WACN,MAAM,iBACN,aAAa,GAAC,SAAS,eACvB,2BAA2B,eAC3B,KAAK,cAAS,SACd,MAAM,GACJ,IAAI,CAgDhB;AAuDM,iDAJI,MAAM,yBACN,qBAAqB,wBACrB,0BAA0B,QAiCpC;AASM,2EAJI,qBAAqB,iCACrB,qBAAqB,kBACrB,0BAA0B,QA2BpC;AAkDM,+CANI,MAAM,wBACN,+BAA+B,UAC/B,aAAa,GAAC,SAAS,eACvB,2BAA2B,GACzB,OAAO,CAAC,+BAA+B,CAAC,CA4BpD;;;;;;;;;;;;;;4BA1hBS,YAAY;mCAAZ,YAAY;mCAAZ,YAAY;wCAYf,oBAAoB;kCAApB,oBAAoB;gCAZjB,YAAY;uCAAZ,YAAY;2CAAZ,YAAY;iDAAZ,YAAY;qDAC4B,KAAK"}