@endo/compartment-mapper 1.6.3 → 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.
- package/package.json +12 -16
- package/src/archive-lite.d.ts +7 -7
- package/src/archive-lite.d.ts.map +1 -1
- package/src/archive-lite.js +78 -27
- package/src/archive.d.ts.map +1 -1
- package/src/archive.js +7 -0
- package/src/bundle-lite.d.ts +3 -3
- package/src/bundle-lite.d.ts.map +1 -1
- package/src/bundle-lite.js +19 -24
- package/src/bundle.d.ts +3 -3
- package/src/bundle.d.ts.map +1 -1
- package/src/bundle.js +19 -24
- package/src/capture-lite.d.ts +2 -2
- package/src/capture-lite.d.ts.map +1 -1
- package/src/capture-lite.js +217 -25
- package/src/compartment-map.d.ts +9 -2
- package/src/compartment-map.d.ts.map +1 -1
- package/src/compartment-map.js +737 -254
- package/src/digest.d.ts +22 -2
- package/src/digest.d.ts.map +1 -1
- package/src/digest.js +179 -56
- package/src/generic-graph.d.ts.map +1 -1
- package/src/generic-graph.js +8 -3
- package/src/guards.d.ts +18 -0
- package/src/guards.d.ts.map +1 -0
- package/src/guards.js +109 -0
- package/src/hooks.md +124 -0
- package/src/import-archive-lite.d.ts.map +1 -1
- package/src/import-archive-lite.js +15 -11
- package/src/import-archive.d.ts +5 -19
- package/src/import-archive.d.ts.map +1 -1
- package/src/import-archive.js +7 -27
- package/src/import-hook.d.ts +4 -3
- package/src/import-hook.d.ts.map +1 -1
- package/src/import-hook.js +138 -69
- package/src/import-lite.d.ts +6 -6
- package/src/import-lite.d.ts.map +1 -1
- package/src/import-lite.js +8 -5
- package/src/import.d.ts +3 -3
- package/src/import.d.ts.map +1 -1
- package/src/import.js +16 -6
- package/src/infer-exports.d.ts.map +1 -1
- package/src/infer-exports.js +16 -6
- package/src/link.d.ts +4 -3
- package/src/link.d.ts.map +1 -1
- package/src/link.js +70 -58
- package/src/node-modules.d.ts +4 -3
- package/src/node-modules.d.ts.map +1 -1
- package/src/node-modules.js +482 -114
- package/src/parse-cjs-shared-export-wrapper.d.ts.map +1 -1
- package/src/parse-cjs-shared-export-wrapper.js +3 -1
- package/src/policy-format.d.ts +22 -5
- package/src/policy-format.d.ts.map +1 -1
- package/src/policy-format.js +342 -108
- package/src/policy.d.ts +13 -28
- package/src/policy.d.ts.map +1 -1
- package/src/policy.js +161 -106
- package/src/types/canonical-name.d.ts +97 -0
- package/src/types/canonical-name.d.ts.map +1 -0
- package/src/types/canonical-name.ts +151 -0
- package/src/types/compartment-map-schema.d.ts +114 -35
- package/src/types/compartment-map-schema.d.ts.map +1 -1
- package/src/types/compartment-map-schema.ts +202 -37
- package/src/types/external.d.ts +168 -28
- package/src/types/external.d.ts.map +1 -1
- package/src/types/external.ts +215 -26
- package/src/types/internal.d.ts +23 -42
- package/src/types/internal.d.ts.map +1 -1
- package/src/types/internal.ts +51 -50
- package/src/types/node-modules.d.ts +71 -10
- package/src/types/node-modules.d.ts.map +1 -1
- package/src/types/node-modules.ts +107 -9
- package/src/types/policy-schema.d.ts +26 -11
- package/src/types/policy-schema.d.ts.map +1 -1
- package/src/types/policy-schema.ts +29 -16
- package/src/types/policy.d.ts +6 -2
- package/src/types/policy.d.ts.map +1 -1
- package/src/types/policy.ts +7 -2
- package/src/types/typescript.d.ts +28 -0
- package/src/types/typescript.d.ts.map +1 -1
- package/src/types/typescript.ts +37 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse-cjs-shared-export-wrapper.d.ts","sourceRoot":"","sources":["parse-cjs-shared-export-wrapper.js"],"names":[],"mappings":"AA0CO,2CAPI,UAAU,GAAG,MAAM,GAAG,SAAS,YAC/B,MAAM,GACJ;IACR,QAAQ,EAAC,MAAM,GAAC,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,GAAC,IAAI,CAAA;CACrB,CAgCH;AAmBM,uGAZJ;IAAmB,uBAAuB,EAAlC,MAAM;IACU,WAAW,EAA3B,WAAW;IACgB,eAAe,EAA1C,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IACX,QAAQ,EAAnB,MAAM;IAC8B,UAAU,EAA9C,MAAM,GAAG,UAAU,GAAG,SAAS;CACvC,GAAU;IACR,MAAM,EAAE;QAAE,OAAO,EAAE,GAAG,CAAA;KAAE,CAAC;IACzB,aAAa,EAAE,GAAG,CAAC;IACnB,YAAY,WAAW;IACvB,OAAO,WAAW;CACnB,
|
|
1
|
+
{"version":3,"file":"parse-cjs-shared-export-wrapper.d.ts","sourceRoot":"","sources":["parse-cjs-shared-export-wrapper.js"],"names":[],"mappings":"AA0CO,2CAPI,UAAU,GAAG,MAAM,GAAG,SAAS,YAC/B,MAAM,GACJ;IACR,QAAQ,EAAC,MAAM,GAAC,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,GAAC,IAAI,CAAA;CACrB,CAgCH;AAmBM,uGAZJ;IAAmB,uBAAuB,EAAlC,MAAM;IACU,WAAW,EAA3B,WAAW;IACgB,eAAe,EAA1C,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IACX,QAAQ,EAAnB,MAAM;IAC8B,UAAU,EAA9C,MAAM,GAAG,UAAU,GAAG,SAAS;CACvC,GAAU;IACR,MAAM,EAAE;QAAE,OAAO,EAAE,GAAG,CAAA;KAAE,CAAC;IACzB,aAAa,EAAE,GAAG,CAAC;IACnB,YAAY,WAAW;IACvB,OAAO,WAAW;CACnB,CAiJH;gCAlOqC,YAAY;4BAAZ,YAAY"}
|
|
@@ -219,7 +219,9 @@ export const wrap = ({
|
|
|
219
219
|
}
|
|
220
220
|
} else {
|
|
221
221
|
for (const prop of redefined) {
|
|
222
|
-
|
|
222
|
+
if (prop !== 'default') {
|
|
223
|
+
moduleEnvironmentRecord[prop] = moduleEnvironmentRecord.default[prop];
|
|
224
|
+
}
|
|
223
225
|
}
|
|
224
226
|
}
|
|
225
227
|
};
|
package/src/policy-format.d.ts
CHANGED
|
@@ -1,10 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Const string to identify the internal attenuators compartment
|
|
3
|
+
*/
|
|
4
|
+
export const ATTENUATORS_COMPARTMENT: "<ATTENUATORS>";
|
|
5
|
+
export const ENTRY_COMPARTMENT: "$root$";
|
|
6
|
+
export function generateCanonicalName({ isEntry, name, path }: PackageNamingKit): string;
|
|
1
7
|
export const WILDCARD_POLICY_VALUE: "any";
|
|
2
|
-
export function policyLookupHelper(packagePolicy:
|
|
3
|
-
export function isAllowingEverything(policyValue: unknown): policyValue is
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
8
|
+
export function policyLookupHelper(packagePolicy: PackagePolicy, field: PolicyEnforcementField, canonicalName: string): boolean | AttenuationDefinition;
|
|
9
|
+
export function isAllowingEverything(policyValue: unknown): policyValue is WildcardPolicy;
|
|
10
|
+
/**
|
|
11
|
+
* Type guard for `AttenuationDefinition`
|
|
12
|
+
*/
|
|
13
|
+
export const isAttenuationDefinition: (value: unknown) => value is FullAttenuationDefinition | ImplicitAttenuationDefinition;
|
|
14
|
+
export function getAttenuatorFromDefinition(attenuationDefinition: AttenuationDefinition): UnifiedAttenuationDefinition;
|
|
15
|
+
export function assertPackagePolicy(allegedPackagePolicy: unknown, keypath: string, url?: string): asserts allegedPackagePolicy is SomePackagePolicy | undefined;
|
|
7
16
|
export function assertPolicy(allegedPolicy: unknown): asserts allegedPolicy is (SomePolicy | undefined);
|
|
17
|
+
import type { PackageNamingKit } from './types.js';
|
|
18
|
+
import type { PackagePolicy } from './types.js';
|
|
19
|
+
import type { PolicyEnforcementField } from './types.js';
|
|
20
|
+
import type { AttenuationDefinition } from './types.js';
|
|
21
|
+
import type { WildcardPolicy } from './types.js';
|
|
22
|
+
import type { FullAttenuationDefinition } from './types.js';
|
|
23
|
+
import type { ImplicitAttenuationDefinition } from './types.js';
|
|
24
|
+
import type { UnifiedAttenuationDefinition } from './types.js';
|
|
8
25
|
import type { SomePackagePolicy } from './types.js';
|
|
9
26
|
import type { SomePolicy } from './types.js';
|
|
10
27
|
//# sourceMappingURL=policy-format.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"policy-format.d.ts","sourceRoot":"","sources":["policy-format.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"policy-format.d.ts","sourceRoot":"","sources":["policy-format.js"],"names":[],"mappings":"AA8BA;;GAEG;AACH,sCAAuC,eAAe,CAAC;AAEvD,gCAAiC,QAAQ,CAAC;AAmBnC,+DAJI,gBAAgB,GACd,MAAM,CAWlB;AAED,oCAAqC,KAAK,CAAC;AAqEpC,kDALI,aAAa,SACb,sBAAsB,iBACtB,MAAM,GACJ,OAAO,GAAG,qBAAqB,CA2B3C;AAQM,kDAHI,OAAO,GACL,WAAW,IAAI,cAAc,CAGH;AA6EvC;;GAEG;AACH,6HAGG;AAQI,mEAHI,qBAAqB,GACnB,4BAA4B,CAwBxC;AAqGM,0DALI,OAAO,WACP,MAAM,QACN,MAAM,GACJ,QAAQ,oBAAoB,IAAI,iBAAiB,GAAC,SAAS,CA0DvE;AAUM,4CAHI,OAAO,GACL,QAAQ,aAAa,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC,CAiC7D;sCAvcQ,YAAY;mCAAZ,YAAY;4CAAZ,YAAY;2CAAZ,YAAY;oCAAZ,YAAY;+CAAZ,YAAY;mDAAZ,YAAY;kDAAZ,YAAY;uCAAZ,YAAY;gCAAZ,YAAY"}
|
package/src/policy-format.js
CHANGED
|
@@ -5,51 +5,156 @@
|
|
|
5
5
|
* @module
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
/**
|
|
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
|
-
|
|
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 {
|
|
27
|
-
* @
|
|
28
|
-
|
|
29
|
-
|
|
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
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
) {
|
|
143
|
+
|
|
144
|
+
const policyDefinition = packagePolicy[field];
|
|
145
|
+
|
|
146
|
+
if (!policyDefinition) {
|
|
40
147
|
return false;
|
|
41
148
|
}
|
|
42
149
|
|
|
43
|
-
if (
|
|
150
|
+
if (policyDefinition === WILDCARD_POLICY_VALUE) {
|
|
44
151
|
return true;
|
|
45
152
|
}
|
|
46
153
|
|
|
47
|
-
|
|
48
|
-
|
|
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
|
|
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
|
|
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
|
|
69
|
-
*/
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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 {
|
|
82
|
-
* @returns {
|
|
256
|
+
* @param {AttenuationDefinition} attenuationDefinition
|
|
257
|
+
* @returns {UnifiedAttenuationDefinition}
|
|
83
258
|
*/
|
|
84
259
|
export const getAttenuatorFromDefinition = attenuationDefinition => {
|
|
85
|
-
if (
|
|
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
|
-
}
|
|
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
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
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
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
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
|
|
315
|
+
* @returns {item is PolicyItem|undefined}
|
|
131
316
|
*/
|
|
132
317
|
const isPolicyItem = item =>
|
|
133
|
-
item
|
|
318
|
+
isUndefined(item) ||
|
|
134
319
|
item === WILDCARD_POLICY_VALUE ||
|
|
135
|
-
|
|
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}
|
|
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,
|
|
148
|
-
if (allegedPackagePolicy
|
|
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
|
-
|
|
154
|
-
|
|
155
|
-
|
|
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:
|
|
164
|
-
//
|
|
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
|
-
} =
|
|
402
|
+
} = allegedPackagePolicy;
|
|
168
403
|
|
|
169
404
|
assert(
|
|
170
|
-
|
|
171
|
-
`${
|
|
405
|
+
isEmptyObject(extra),
|
|
406
|
+
`${keypath} must not have extra properties, got ${q(keys(extra))}${inUrl}`,
|
|
172
407
|
);
|
|
173
408
|
|
|
174
409
|
assert(
|
|
175
|
-
noGlobalFreeze
|
|
176
|
-
`${
|
|
410
|
+
isNoGlobalFreeze(noGlobalFreeze),
|
|
411
|
+
`${keypath}.noGlobalFreeze must be a boolean, got ${q({
|
|
177
412
|
noGlobalFreeze,
|
|
178
413
|
})}${inUrl}`,
|
|
179
414
|
);
|
|
180
415
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
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
|
|
449
|
+
if (isUndefined(allegedPolicy)) {
|
|
217
450
|
return;
|
|
218
451
|
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
allegedPolicy
|
|
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
|
-
|
|
460
|
+
isEmptyObject(extra),
|
|
228
461
|
`policy must not have extra properties, got ${q(keys(extra))}`,
|
|
229
462
|
);
|
|
230
463
|
|
|
231
464
|
assert(
|
|
232
|
-
|
|
465
|
+
isPlainObject(resources),
|
|
233
466
|
`policy.resources must be an object, got ${q(resources)}`,
|
|
234
467
|
);
|
|
468
|
+
|
|
235
469
|
assert(
|
|
236
|
-
|
|
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`);
|