@substrat-run/contract-tests 0.1.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/modules.d.ts +727 -0
- package/dist/modules.d.ts.map +1 -0
- package/dist/modules.js +383 -0
- package/dist/modules.js.map +1 -0
- package/dist/permission-suite.d.ts.map +1 -1
- package/dist/permission-suite.js +49 -33
- package/dist/permission-suite.js.map +1 -1
- package/dist/scope-host-suite.d.ts +12 -1
- package/dist/scope-host-suite.d.ts.map +1 -1
- package/dist/scope-host-suite.js +190 -200
- package/dist/scope-host-suite.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modules.d.ts","sourceRoot":"","sources":["../src/modules.ts"],"names":[],"mappings":"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"}
|
package/dist/modules.js
ADDED
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Executable contract-test artifacts as STATIC importable values (not inline
|
|
3
|
+
* `beforeAll` closures). The Cloudflare adapter bundles these into its ScopeDO
|
|
4
|
+
* at code time — a Durable Object cannot receive handler closures over RPC — so
|
|
5
|
+
* both the pure-SQLite suite (which registers them on the facade that also
|
|
6
|
+
* executes them) and the CF suite (whose DO executes them, facade only
|
|
7
|
+
* validates) draw from this one source. The assertions live in the suites; the
|
|
8
|
+
* artifacts live here.
|
|
9
|
+
*/
|
|
10
|
+
import { dataSubjectId, moduleManifest, } from '@substrat-run/contracts';
|
|
11
|
+
// -- manifests ---------------------------------------------------------------
|
|
12
|
+
export const testModManifest = moduleManifest.parse({
|
|
13
|
+
id: '@test/mod',
|
|
14
|
+
version: '1.0.0',
|
|
15
|
+
kernelContract: '^0.0.1',
|
|
16
|
+
permissions: [{ key: 'testmod:use', description: 'test permission' }],
|
|
17
|
+
events: { emits: [], consumes: [] },
|
|
18
|
+
migrations: { journalDir: './migrations', compatibleFrom: '1.0.0' },
|
|
19
|
+
attachmentTargets: [],
|
|
20
|
+
entityRelations: [{ entityType: 'item', parentType: 'box' }],
|
|
21
|
+
entitlementKey: 'testmod',
|
|
22
|
+
});
|
|
23
|
+
export const flowModManifest = moduleManifest.parse({
|
|
24
|
+
id: '@test/flow',
|
|
25
|
+
version: '1.0.0',
|
|
26
|
+
kernelContract: '^0.0.1',
|
|
27
|
+
permissions: [{ key: 'flow:use', description: 'flow permission' }],
|
|
28
|
+
events: {
|
|
29
|
+
emits: [
|
|
30
|
+
{ type: 'flow.step1', schemaVersion: 1 },
|
|
31
|
+
{ type: 'flow.step2', schemaVersion: 1 },
|
|
32
|
+
],
|
|
33
|
+
consumes: [
|
|
34
|
+
{ type: 'flow.step1', schemaVersion: 1 },
|
|
35
|
+
{ type: 'flow.step2', schemaVersion: 1 },
|
|
36
|
+
],
|
|
37
|
+
},
|
|
38
|
+
migrations: { journalDir: './migrations', compatibleFrom: '1.0.0' },
|
|
39
|
+
attachmentTargets: [],
|
|
40
|
+
entitlementKey: 'flow',
|
|
41
|
+
});
|
|
42
|
+
export const lateModManifest = moduleManifest.parse({
|
|
43
|
+
id: '@test/late',
|
|
44
|
+
version: '1.0.0',
|
|
45
|
+
kernelContract: '^0.0.1',
|
|
46
|
+
permissions: [{ key: 'late:use', description: 'late module permission' }],
|
|
47
|
+
events: { emits: [], consumes: [] },
|
|
48
|
+
migrations: { journalDir: './migrations', compatibleFrom: '1.0.0' },
|
|
49
|
+
attachmentTargets: [],
|
|
50
|
+
entitlementKey: 'late',
|
|
51
|
+
});
|
|
52
|
+
// Entitlement gate (§4.3): a module whose SKU flag the tenant does not hold does
|
|
53
|
+
// not load — its operations do not resolve. Isolated on its own tenant so
|
|
54
|
+
// granting/revoking here cannot disturb the other suites' fixtures.
|
|
55
|
+
export const billedModManifest = moduleManifest.parse({
|
|
56
|
+
id: '@test/billed',
|
|
57
|
+
version: '1.0.0',
|
|
58
|
+
kernelContract: '^0.0.1',
|
|
59
|
+
permissions: [{ key: 'billed:use', description: 'billed module permission' }],
|
|
60
|
+
events: { emits: [], consumes: [] },
|
|
61
|
+
migrations: { journalDir: './migrations', compatibleFrom: '1.0.0' },
|
|
62
|
+
attachmentTargets: [],
|
|
63
|
+
entitlementKey: 'billed',
|
|
64
|
+
});
|
|
65
|
+
// Manifest-declared operation guards (K-17). Two modules, on purpose: one
|
|
66
|
+
// GUARDED module whose manifest declares the gate, one GATE module that
|
|
67
|
+
// contributes the named predicate. The guarded module registers FIRST — the
|
|
68
|
+
// contract says predicates resolve at invoke, not at registration, because
|
|
69
|
+
// registration order is caller-controlled.
|
|
70
|
+
export const guardedModManifest = moduleManifest.parse({
|
|
71
|
+
id: '@test/guarded',
|
|
72
|
+
version: '1.0.0',
|
|
73
|
+
kernelContract: '^0.0.1',
|
|
74
|
+
permissions: [{ key: 'guarded:use', description: 'guarded permission' }],
|
|
75
|
+
events: { emits: [], consumes: [] },
|
|
76
|
+
migrations: { journalDir: './migrations', compatibleFrom: '1.0.0' },
|
|
77
|
+
attachmentTargets: [],
|
|
78
|
+
entitlementKey: 'guarded',
|
|
79
|
+
guards: [
|
|
80
|
+
{ before: 'guarded/act', predicate: 'gate/flag-set', config: { flag: 'go' } },
|
|
81
|
+
// A guard whose predicate NO module contributes: the operation must fail
|
|
82
|
+
// closed, never run unguarded.
|
|
83
|
+
{ before: 'guarded/orphan', predicate: 'gate/does-not-exist', config: {} },
|
|
84
|
+
],
|
|
85
|
+
});
|
|
86
|
+
// Operation withdrawal (K-17). Order-independence is the contract, so the suite
|
|
87
|
+
// withdraws one operation BEFORE its module registers and one AFTER.
|
|
88
|
+
export const withdrawEarlyManifest = moduleManifest.parse({
|
|
89
|
+
id: '@test/withdraw-early',
|
|
90
|
+
version: '1.0.0',
|
|
91
|
+
kernelContract: '^0.0.1',
|
|
92
|
+
permissions: [{ key: 'wearly:use', description: 'early withdrawer' }],
|
|
93
|
+
events: { emits: [], consumes: [] },
|
|
94
|
+
migrations: { journalDir: './migrations', compatibleFrom: '1.0.0' },
|
|
95
|
+
attachmentTargets: [],
|
|
96
|
+
entitlementKey: 'withdraw-early',
|
|
97
|
+
withdraws: ['victim/a'], // @test/victim has not registered yet
|
|
98
|
+
});
|
|
99
|
+
export const victimModManifest = moduleManifest.parse({
|
|
100
|
+
id: '@test/victim',
|
|
101
|
+
version: '1.0.0',
|
|
102
|
+
kernelContract: '^0.0.1',
|
|
103
|
+
permissions: [{ key: 'victim:use', description: 'victim permission' }],
|
|
104
|
+
events: { emits: [], consumes: [] },
|
|
105
|
+
migrations: { journalDir: './migrations', compatibleFrom: '1.0.0' },
|
|
106
|
+
attachmentTargets: [],
|
|
107
|
+
entitlementKey: 'victim',
|
|
108
|
+
});
|
|
109
|
+
export const withdrawLateManifest = moduleManifest.parse({
|
|
110
|
+
id: '@test/withdraw-late',
|
|
111
|
+
version: '1.0.0',
|
|
112
|
+
kernelContract: '^0.0.1',
|
|
113
|
+
permissions: [{ key: 'wlate:use', description: 'late withdrawer' }],
|
|
114
|
+
events: { emits: [], consumes: [] },
|
|
115
|
+
migrations: { journalDir: './migrations', compatibleFrom: '1.0.0' },
|
|
116
|
+
attachmentTargets: [],
|
|
117
|
+
entitlementKey: 'withdraw-late',
|
|
118
|
+
withdraws: ['victim/b'], // @test/victim already registered
|
|
119
|
+
});
|
|
120
|
+
export const gateModManifest = moduleManifest.parse({
|
|
121
|
+
id: '@test/gate',
|
|
122
|
+
version: '1.0.0',
|
|
123
|
+
kernelContract: '^0.0.1',
|
|
124
|
+
permissions: [{ key: 'gate:use', description: 'gate permission' }],
|
|
125
|
+
events: { emits: [], consumes: [] },
|
|
126
|
+
migrations: { journalDir: './migrations', compatibleFrom: '1.0.0' },
|
|
127
|
+
attachmentTargets: [],
|
|
128
|
+
entitlementKey: 'gate',
|
|
129
|
+
});
|
|
130
|
+
export const permModManifest = moduleManifest.parse({
|
|
131
|
+
id: '@perm/mod',
|
|
132
|
+
version: '1.0.0',
|
|
133
|
+
kernelContract: '^0.0.1',
|
|
134
|
+
permissions: [
|
|
135
|
+
{ key: 'perm:use', description: 'use the thing' },
|
|
136
|
+
{ key: 'perm:read', description: 'read the thing' },
|
|
137
|
+
],
|
|
138
|
+
events: { emits: [], consumes: [] },
|
|
139
|
+
migrations: { journalDir: './migrations', compatibleFrom: '1.0.0' },
|
|
140
|
+
attachmentTargets: [],
|
|
141
|
+
entityRelations: [{ entityType: 'item', parentType: 'box' }],
|
|
142
|
+
entitlementKey: 'perm',
|
|
143
|
+
});
|
|
144
|
+
// Shared across test/stash + test/read-stash. Module scope so the value survives
|
|
145
|
+
// between invokes on the same DO instance (and, on the pure adapter, across the
|
|
146
|
+
// suite process). Only these two operations touch it.
|
|
147
|
+
const stash = {};
|
|
148
|
+
export const contractTestBareOps = {
|
|
149
|
+
'test/init-counter': ((ctx) => {
|
|
150
|
+
ctx.sql.exec('CREATE TABLE IF NOT EXISTS counter (n INTEGER NOT NULL)');
|
|
151
|
+
ctx.sql.exec('DELETE FROM counter');
|
|
152
|
+
ctx.sql.exec('INSERT INTO counter (n) VALUES (0)');
|
|
153
|
+
}),
|
|
154
|
+
// Read → await → write. Under interleaving this loses updates; under strict
|
|
155
|
+
// serialization it cannot.
|
|
156
|
+
'test/slow-increment': (async (ctx) => {
|
|
157
|
+
const [row] = ctx.sql.query('SELECT n FROM counter');
|
|
158
|
+
await new Promise((r) => setTimeout(r, 5));
|
|
159
|
+
ctx.sql.exec('UPDATE counter SET n = ?', [row.n + 1]);
|
|
160
|
+
}),
|
|
161
|
+
'test/read-counter': ((ctx) => {
|
|
162
|
+
const [row] = ctx.sql.query('SELECT n FROM counter');
|
|
163
|
+
return row.n;
|
|
164
|
+
}),
|
|
165
|
+
'test/stash': ((_ctx, input) => {
|
|
166
|
+
stash.value = input;
|
|
167
|
+
}),
|
|
168
|
+
'test/read-stash': (() => stash.value),
|
|
169
|
+
'test/emit-event': ((ctx, input) => {
|
|
170
|
+
ctx.emit({
|
|
171
|
+
type: 'test.happened',
|
|
172
|
+
schemaVersion: 1,
|
|
173
|
+
entity: { entityType: 'test-thing', entityId: 'x1' },
|
|
174
|
+
piiClass: input?.subject ? 'pseudonymous' : 'none',
|
|
175
|
+
...(input?.subject ? { subjectId: dataSubjectId.parse(input.subject) } : {}),
|
|
176
|
+
payload: { hello: 'world' },
|
|
177
|
+
});
|
|
178
|
+
}),
|
|
179
|
+
'test/emit-unclassified-pii': ((ctx) => {
|
|
180
|
+
// piiClass 'direct' without subjectId — must be rejected at emit (§6.1)
|
|
181
|
+
ctx.emit({
|
|
182
|
+
type: 'test.bad',
|
|
183
|
+
schemaVersion: 1,
|
|
184
|
+
entity: { entityType: 'test-thing', entityId: 'x2' },
|
|
185
|
+
piiClass: 'direct',
|
|
186
|
+
payload: {},
|
|
187
|
+
});
|
|
188
|
+
}),
|
|
189
|
+
'test/read-outbox': ((ctx) => ctx.sql.query('SELECT * FROM _substrat_outbox ORDER BY id')),
|
|
190
|
+
'test/write-marker': ((ctx, input) => {
|
|
191
|
+
ctx.sql.exec('CREATE TABLE IF NOT EXISTS marker (v TEXT NOT NULL)');
|
|
192
|
+
ctx.sql.exec('INSERT INTO marker (v) VALUES (?)', [input.v]);
|
|
193
|
+
}),
|
|
194
|
+
'test/read-markers': ((ctx) => {
|
|
195
|
+
ctx.sql.exec('CREATE TABLE IF NOT EXISTS marker (v TEXT NOT NULL)');
|
|
196
|
+
return ctx.sql.query('SELECT v FROM marker').map((r) => r.v);
|
|
197
|
+
}),
|
|
198
|
+
'test/atomic-init': ((ctx) => {
|
|
199
|
+
ctx.sql.exec('CREATE TABLE IF NOT EXISTS atomic_t (n INTEGER NOT NULL)');
|
|
200
|
+
}),
|
|
201
|
+
'test/atomic-fail': ((ctx) => {
|
|
202
|
+
ctx.sql.exec('INSERT INTO atomic_t (n) VALUES (1)');
|
|
203
|
+
ctx.emit({
|
|
204
|
+
type: 'test.atomic',
|
|
205
|
+
schemaVersion: 1,
|
|
206
|
+
entity: { entityType: 'test-thing', entityId: 'x9' },
|
|
207
|
+
piiClass: 'none',
|
|
208
|
+
payload: {},
|
|
209
|
+
});
|
|
210
|
+
throw new Error('boom');
|
|
211
|
+
}),
|
|
212
|
+
'test/atomic-read': ((ctx) => ({
|
|
213
|
+
rows: ctx.sql.query('SELECT n FROM atomic_t').length,
|
|
214
|
+
events: ctx.sql.query('SELECT id FROM _substrat_outbox WHERE type = ?', ['test.atomic']).length,
|
|
215
|
+
})),
|
|
216
|
+
};
|
|
217
|
+
// -- module operation handlers -----------------------------------------------
|
|
218
|
+
const addItem = (ctx, input) => {
|
|
219
|
+
ctx.sql.exec('INSERT INTO testmod_items (id, box) VALUES (?, ?)', [input.id, input.box]);
|
|
220
|
+
ctx.link({ entityType: 'item', entityId: input.id }, { entityType: 'box', entityId: input.box });
|
|
221
|
+
};
|
|
222
|
+
const relinkItem = (ctx, input) => {
|
|
223
|
+
ctx.link({ entityType: 'item', entityId: input.id }, { entityType: 'box', entityId: input.box });
|
|
224
|
+
};
|
|
225
|
+
const linkUndeclared = (ctx) => {
|
|
226
|
+
ctx.link({ entityType: 'box', entityId: 'b1' }, { entityType: 'item', entityId: 'i1' });
|
|
227
|
+
};
|
|
228
|
+
const readJournal = (ctx) => ctx.sql.query('SELECT module_id, version FROM _substrat_migrations ORDER BY module_id');
|
|
229
|
+
const readTuples = (ctx) => ctx.sql.query('SELECT subject, relation, object FROM _substrat_tuples ORDER BY subject');
|
|
230
|
+
const linkOp = (ctx, input) => {
|
|
231
|
+
ctx.link(input.child, input.parent);
|
|
232
|
+
};
|
|
233
|
+
const probeOp = (ctx, input) => ctx.check(input.permission, input.entity);
|
|
234
|
+
const flowStep1Consumer = (ctx, event) => {
|
|
235
|
+
ctx.sql.exec('INSERT INTO flow_log (event_id, type) VALUES (?, ?)', [event.id, event.type]);
|
|
236
|
+
ctx.emit({
|
|
237
|
+
type: 'flow.step2',
|
|
238
|
+
schemaVersion: 1,
|
|
239
|
+
entity: event.entity,
|
|
240
|
+
piiClass: 'none',
|
|
241
|
+
payload: {},
|
|
242
|
+
});
|
|
243
|
+
};
|
|
244
|
+
const flowStep2Consumer = (ctx, event) => {
|
|
245
|
+
ctx.sql.exec('INSERT INTO flow_log (event_id, type) VALUES (?, ?)', [event.id, event.type]);
|
|
246
|
+
};
|
|
247
|
+
// -- module registrations ----------------------------------------------------
|
|
248
|
+
export const testMod = {
|
|
249
|
+
manifest: testModManifest,
|
|
250
|
+
migrations: [
|
|
251
|
+
{
|
|
252
|
+
version: '0001-init',
|
|
253
|
+
sql: 'CREATE TABLE testmod_items (id TEXT PRIMARY KEY, box TEXT NOT NULL)',
|
|
254
|
+
},
|
|
255
|
+
],
|
|
256
|
+
operations: {
|
|
257
|
+
'testmod/add': addItem,
|
|
258
|
+
'testmod/relink': relinkItem,
|
|
259
|
+
'testmod/link-undeclared': linkUndeclared,
|
|
260
|
+
'testmod/read-journal': readJournal,
|
|
261
|
+
'testmod/read-tuples': readTuples,
|
|
262
|
+
},
|
|
263
|
+
};
|
|
264
|
+
export const flowMod = {
|
|
265
|
+
manifest: flowModManifest,
|
|
266
|
+
migrations: [
|
|
267
|
+
{
|
|
268
|
+
version: '0001-init',
|
|
269
|
+
sql: 'CREATE TABLE flow_log (event_id TEXT PRIMARY KEY, type TEXT NOT NULL)',
|
|
270
|
+
},
|
|
271
|
+
],
|
|
272
|
+
operations: {
|
|
273
|
+
'flow/produce': ((ctx) => {
|
|
274
|
+
ctx.emit({
|
|
275
|
+
type: 'flow.step1',
|
|
276
|
+
schemaVersion: 1,
|
|
277
|
+
entity: { entityType: 'flow-thing', entityId: 'f1' },
|
|
278
|
+
piiClass: 'none',
|
|
279
|
+
payload: {},
|
|
280
|
+
});
|
|
281
|
+
}),
|
|
282
|
+
'flow/log': ((ctx) => ctx.sql.query('SELECT event_id, type FROM flow_log ORDER BY event_id')),
|
|
283
|
+
'flow/deliveries': ((ctx) => ctx.sql.query(`SELECT event_id, consumer_module, error FROM _substrat_deliveries
|
|
284
|
+
WHERE consumer_module = '@test/flow' ORDER BY event_id`)),
|
|
285
|
+
'flow/step2-actors': ((ctx) => ctx.sql.query(`SELECT actor FROM _substrat_outbox WHERE type = 'flow.step2'`)),
|
|
286
|
+
},
|
|
287
|
+
consumers: {
|
|
288
|
+
'flow.step1': flowStep1Consumer,
|
|
289
|
+
'flow.step2': flowStep2Consumer,
|
|
290
|
+
},
|
|
291
|
+
};
|
|
292
|
+
export const guardedMod = {
|
|
293
|
+
manifest: guardedModManifest,
|
|
294
|
+
migrations: [{ version: '0001-init', sql: 'CREATE TABLE guarded_t (v TEXT NOT NULL)' }],
|
|
295
|
+
operations: {
|
|
296
|
+
'guarded/act': ((ctx, input) => {
|
|
297
|
+
ctx.sql.exec('INSERT INTO guarded_t (v) VALUES (?)', [input?.flag ?? 'none']);
|
|
298
|
+
ctx.emit({
|
|
299
|
+
type: 'guarded.acted',
|
|
300
|
+
schemaVersion: 1,
|
|
301
|
+
entity: { entityType: 'guarded-thing', entityId: 'g1' },
|
|
302
|
+
piiClass: 'none',
|
|
303
|
+
payload: {},
|
|
304
|
+
});
|
|
305
|
+
}),
|
|
306
|
+
'guarded/orphan': (() => 'ran'),
|
|
307
|
+
'guarded/rows': ((ctx) => ctx.sql.query('SELECT v FROM guarded_t').map((r) => r.v)),
|
|
308
|
+
'guarded/events': ((ctx) => ctx.sql.query('SELECT id FROM _substrat_outbox WHERE type = ?', ['guarded.acted'])
|
|
309
|
+
.length),
|
|
310
|
+
},
|
|
311
|
+
};
|
|
312
|
+
export const gateMod = {
|
|
313
|
+
manifest: gateModManifest,
|
|
314
|
+
predicates: {
|
|
315
|
+
// The predicate sees ctx (its own transaction), the manifest config, and the
|
|
316
|
+
// operation input. It THROWS to block, returns to allow.
|
|
317
|
+
'gate/flag-set': (_ctx, config, input) => {
|
|
318
|
+
const want = config.flag;
|
|
319
|
+
const got = input?.flag;
|
|
320
|
+
if (got !== want)
|
|
321
|
+
throw new Error(`guard: expected flag '${String(want)}', got '${String(got)}'`);
|
|
322
|
+
},
|
|
323
|
+
},
|
|
324
|
+
};
|
|
325
|
+
export const withdrawEarlyMod = { manifest: withdrawEarlyManifest };
|
|
326
|
+
export const victimMod = {
|
|
327
|
+
manifest: victimModManifest,
|
|
328
|
+
operations: {
|
|
329
|
+
'victim/a': (() => 'a'),
|
|
330
|
+
'victim/b': (() => 'b'),
|
|
331
|
+
'victim/c': (() => 'c'),
|
|
332
|
+
},
|
|
333
|
+
};
|
|
334
|
+
export const withdrawLateMod = { manifest: withdrawLateManifest };
|
|
335
|
+
export const lateMod = {
|
|
336
|
+
manifest: lateModManifest,
|
|
337
|
+
migrations: [{ version: '0001-init', sql: 'CREATE TABLE late_t (id TEXT PRIMARY KEY)' }],
|
|
338
|
+
operations: {
|
|
339
|
+
'late/check': ((ctx) => ctx.sql.query(`SELECT name FROM sqlite_master WHERE name = 'late_t'`)
|
|
340
|
+
.length),
|
|
341
|
+
},
|
|
342
|
+
};
|
|
343
|
+
export const billedMod = {
|
|
344
|
+
manifest: billedModManifest,
|
|
345
|
+
operations: {
|
|
346
|
+
'billed/act': (() => 'ran'),
|
|
347
|
+
},
|
|
348
|
+
};
|
|
349
|
+
export const permMod = {
|
|
350
|
+
manifest: permModManifest,
|
|
351
|
+
operations: {
|
|
352
|
+
'perm/link': linkOp,
|
|
353
|
+
'perm/probe': probeOp,
|
|
354
|
+
},
|
|
355
|
+
};
|
|
356
|
+
/**
|
|
357
|
+
* The modules the scope-host suite's `beforeAll` registers, in the exact order
|
|
358
|
+
* the original inline registration used — order carries meaning: the early
|
|
359
|
+
* withdrawer precedes @test/victim, the late withdrawer follows it, and the
|
|
360
|
+
* guarded module precedes the gate that supplies its predicate.
|
|
361
|
+
*/
|
|
362
|
+
export const contractTestInitialModules = [
|
|
363
|
+
testMod,
|
|
364
|
+
flowMod,
|
|
365
|
+
guardedMod,
|
|
366
|
+
gateMod,
|
|
367
|
+
withdrawEarlyMod,
|
|
368
|
+
victimMod,
|
|
369
|
+
withdrawLateMod,
|
|
370
|
+
];
|
|
371
|
+
/**
|
|
372
|
+
* Every module a CF ScopeDO must carry to serve BOTH suites — the initial set
|
|
373
|
+
* plus the ones the suites register mid-test (`lateMod`, `billedMod`) and the
|
|
374
|
+
* permission suite's module. The DO closes over all of them at construction; the
|
|
375
|
+
* facade still gates/withdraws exactly as each suite drives it.
|
|
376
|
+
*/
|
|
377
|
+
export const contractTestModules = [
|
|
378
|
+
...contractTestInitialModules,
|
|
379
|
+
lateMod,
|
|
380
|
+
billedMod,
|
|
381
|
+
permMod,
|
|
382
|
+
];
|
|
383
|
+
//# sourceMappingURL=modules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modules.js","sourceRoot":"","sources":["../src/modules.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EACL,aAAa,EACb,cAAc,GAGf,MAAM,yBAAyB,CAAC;AAOjC,+EAA+E;AAE/E,MAAM,CAAC,MAAM,eAAe,GAAG,cAAc,CAAC,KAAK,CAAC;IAClD,EAAE,EAAE,WAAW;IACf,OAAO,EAAE,OAAO;IAChB,cAAc,EAAE,QAAQ;IACxB,WAAW,EAAE,CAAC,EAAE,GAAG,EAAE,aAAa,EAAE,WAAW,EAAE,iBAAiB,EAAE,CAAC;IACrE,MAAM,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;IACnC,UAAU,EAAE,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,EAAE,OAAO,EAAE;IACnE,iBAAiB,EAAE,EAAE;IACrB,eAAe,EAAE,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;IAC5D,cAAc,EAAE,SAAS;CAC1B,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,eAAe,GAAG,cAAc,CAAC,KAAK,CAAC;IAClD,EAAE,EAAE,YAAY;IAChB,OAAO,EAAE,OAAO;IAChB,cAAc,EAAE,QAAQ;IACxB,WAAW,EAAE,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,WAAW,EAAE,iBAAiB,EAAE,CAAC;IAClE,MAAM,EAAE;QACN,KAAK,EAAE;YACL,EAAE,IAAI,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC,EAAE;YACxC,EAAE,IAAI,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC,EAAE;SACzC;QACD,QAAQ,EAAE;YACR,EAAE,IAAI,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC,EAAE;YACxC,EAAE,IAAI,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC,EAAE;SACzC;KACF;IACD,UAAU,EAAE,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,EAAE,OAAO,EAAE;IACnE,iBAAiB,EAAE,EAAE;IACrB,cAAc,EAAE,MAAM;CACvB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,eAAe,GAAG,cAAc,CAAC,KAAK,CAAC;IAClD,EAAE,EAAE,YAAY;IAChB,OAAO,EAAE,OAAO;IAChB,cAAc,EAAE,QAAQ;IACxB,WAAW,EAAE,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,WAAW,EAAE,wBAAwB,EAAE,CAAC;IACzE,MAAM,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;IACnC,UAAU,EAAE,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,EAAE,OAAO,EAAE;IACnE,iBAAiB,EAAE,EAAE;IACrB,cAAc,EAAE,MAAM;CACvB,CAAC,CAAC;AAEH,iFAAiF;AACjF,0EAA0E;AAC1E,oEAAoE;AACpE,MAAM,CAAC,MAAM,iBAAiB,GAAG,cAAc,CAAC,KAAK,CAAC;IACpD,EAAE,EAAE,cAAc;IAClB,OAAO,EAAE,OAAO;IAChB,cAAc,EAAE,QAAQ;IACxB,WAAW,EAAE,CAAC,EAAE,GAAG,EAAE,YAAY,EAAE,WAAW,EAAE,0BAA0B,EAAE,CAAC;IAC7E,MAAM,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;IACnC,UAAU,EAAE,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,EAAE,OAAO,EAAE;IACnE,iBAAiB,EAAE,EAAE;IACrB,cAAc,EAAE,QAAQ;CACzB,CAAC,CAAC;AAEH,0EAA0E;AAC1E,wEAAwE;AACxE,4EAA4E;AAC5E,2EAA2E;AAC3E,2CAA2C;AAC3C,MAAM,CAAC,MAAM,kBAAkB,GAAG,cAAc,CAAC,KAAK,CAAC;IACrD,EAAE,EAAE,eAAe;IACnB,OAAO,EAAE,OAAO;IAChB,cAAc,EAAE,QAAQ;IACxB,WAAW,EAAE,CAAC,EAAE,GAAG,EAAE,aAAa,EAAE,WAAW,EAAE,oBAAoB,EAAE,CAAC;IACxE,MAAM,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;IACnC,UAAU,EAAE,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,EAAE,OAAO,EAAE;IACnE,iBAAiB,EAAE,EAAE;IACrB,cAAc,EAAE,SAAS;IACzB,MAAM,EAAE;QACN,EAAE,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;QAC7E,yEAAyE;QACzE,+BAA+B;QAC/B,EAAE,MAAM,EAAE,gBAAgB,EAAE,SAAS,EAAE,qBAAqB,EAAE,MAAM,EAAE,EAAE,EAAE;KAC3E;CACF,CAAC,CAAC;AAEH,gFAAgF;AAChF,qEAAqE;AACrE,MAAM,CAAC,MAAM,qBAAqB,GAAG,cAAc,CAAC,KAAK,CAAC;IACxD,EAAE,EAAE,sBAAsB;IAC1B,OAAO,EAAE,OAAO;IAChB,cAAc,EAAE,QAAQ;IACxB,WAAW,EAAE,CAAC,EAAE,GAAG,EAAE,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,CAAC;IACrE,MAAM,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;IACnC,UAAU,EAAE,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,EAAE,OAAO,EAAE;IACnE,iBAAiB,EAAE,EAAE;IACrB,cAAc,EAAE,gBAAgB;IAChC,SAAS,EAAE,CAAC,UAAU,CAAC,EAAE,sCAAsC;CAChE,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG,cAAc,CAAC,KAAK,CAAC;IACpD,EAAE,EAAE,cAAc;IAClB,OAAO,EAAE,OAAO;IAChB,cAAc,EAAE,QAAQ;IACxB,WAAW,EAAE,CAAC,EAAE,GAAG,EAAE,YAAY,EAAE,WAAW,EAAE,mBAAmB,EAAE,CAAC;IACtE,MAAM,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;IACnC,UAAU,EAAE,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,EAAE,OAAO,EAAE;IACnE,iBAAiB,EAAE,EAAE;IACrB,cAAc,EAAE,QAAQ;CACzB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,oBAAoB,GAAG,cAAc,CAAC,KAAK,CAAC;IACvD,EAAE,EAAE,qBAAqB;IACzB,OAAO,EAAE,OAAO;IAChB,cAAc,EAAE,QAAQ;IACxB,WAAW,EAAE,CAAC,EAAE,GAAG,EAAE,WAAW,EAAE,WAAW,EAAE,iBAAiB,EAAE,CAAC;IACnE,MAAM,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;IACnC,UAAU,EAAE,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,EAAE,OAAO,EAAE;IACnE,iBAAiB,EAAE,EAAE;IACrB,cAAc,EAAE,eAAe;IAC/B,SAAS,EAAE,CAAC,UAAU,CAAC,EAAE,kCAAkC;CAC5D,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,eAAe,GAAG,cAAc,CAAC,KAAK,CAAC;IAClD,EAAE,EAAE,YAAY;IAChB,OAAO,EAAE,OAAO;IAChB,cAAc,EAAE,QAAQ;IACxB,WAAW,EAAE,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,WAAW,EAAE,iBAAiB,EAAE,CAAC;IAClE,MAAM,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;IACnC,UAAU,EAAE,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,EAAE,OAAO,EAAE;IACnE,iBAAiB,EAAE,EAAE;IACrB,cAAc,EAAE,MAAM;CACvB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,eAAe,GAAG,cAAc,CAAC,KAAK,CAAC;IAClD,EAAE,EAAE,WAAW;IACf,OAAO,EAAE,OAAO;IAChB,cAAc,EAAE,QAAQ;IACxB,WAAW,EAAE;QACX,EAAE,GAAG,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE;QACjD,EAAE,GAAG,EAAE,WAAW,EAAE,WAAW,EAAE,gBAAgB,EAAE;KACpD;IACD,MAAM,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;IACnC,UAAU,EAAE,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,EAAE,OAAO,EAAE;IACnE,iBAAiB,EAAE,EAAE;IACrB,eAAe,EAAE,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;IAC5D,cAAc,EAAE,MAAM;CACvB,CAAC,CAAC;AAcH,iFAAiF;AACjF,gFAAgF;AAChF,sDAAsD;AACtD,MAAM,KAAK,GAAoC,EAAE,CAAC;AAElD,MAAM,CAAC,MAAM,mBAAmB,GAAqD;IACnF,mBAAmB,EAAE,CAAC,CAAC,GAAG,EAAE,EAAE;QAC5B,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,yDAAyD,CAAC,CAAC;QACxE,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;QACpC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;IACrD,CAAC,CAAqC;IACtC,4EAA4E;IAC5E,2BAA2B;IAC3B,qBAAqB,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACpC,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,KAAK,CAAgB,uBAAuB,CAAC,CAAC;QACpE,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC3C,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,0BAA0B,EAAE,CAAC,GAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACzD,CAAC,CAAqC;IACtC,mBAAmB,EAAE,CAAC,CAAC,GAAG,EAAE,EAAE;QAC5B,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,KAAK,CAAgB,uBAAuB,CAAC,CAAC;QACpE,OAAO,GAAI,CAAC,CAAC,CAAC;IAChB,CAAC,CAAqC;IACtC,YAAY,EAAE,CAAC,CAAC,IAAI,EAAE,KAA0B,EAAE,EAAE;QAClD,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC;IACtB,CAAC,CAAqC;IACtC,iBAAiB,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,KAAM,CAAqC;IAC3E,iBAAiB,EAAE,CAAC,CAAC,GAAG,EAAE,KAAuC,EAAE,EAAE;QACnE,GAAG,CAAC,IAAI,CAAC;YACP,IAAI,EAAE,eAAe;YACrB,aAAa,EAAE,CAAC;YAChB,MAAM,EAAE,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE;YACpD,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM;YAClD,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,aAAa,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5E,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE;SAC5B,CAAC,CAAC;IACL,CAAC,CAAqC;IACtC,4BAA4B,EAAE,CAAC,CAAC,GAAG,EAAE,EAAE;QACrC,wEAAwE;QACxE,GAAG,CAAC,IAAI,CAAC;YACP,IAAI,EAAE,UAAU;YAChB,aAAa,EAAE,CAAC;YAChB,MAAM,EAAE,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE;YACpD,QAAQ,EAAE,QAAQ;YAClB,OAAO,EAAE,EAAE;SACZ,CAAC,CAAC;IACL,CAAC,CAAqC;IACtC,kBAAkB,EAAE,CAAC,CAAC,GAAG,EAAE,EAAE,CAC3B,GAAG,CAAC,GAAG,CAAC,KAAK,CAAY,4CAA4C,CAAC,CAGvE;IACD,mBAAmB,EAAE,CAAC,CAAC,GAAG,EAAE,KAAoB,EAAE,EAAE;QAClD,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,qDAAqD,CAAC,CAAC;QACpE,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,mCAAmC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/D,CAAC,CAAqC;IACtC,mBAAmB,EAAE,CAAC,CAAC,GAAG,EAAE,EAAE;QAC5B,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,qDAAqD,CAAC,CAAC;QACpE,OAAO,GAAG,CAAC,GAAG,CAAC,KAAK,CAAgB,sBAAsB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9E,CAAC,CAAqC;IACtC,kBAAkB,EAAE,CAAC,CAAC,GAAG,EAAE,EAAE;QAC3B,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,0DAA0D,CAAC,CAAC;IAC3E,CAAC,CAAqC;IACtC,kBAAkB,EAAE,CAAC,CAAC,GAAG,EAAE,EAAE;QAC3B,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;QACpD,GAAG,CAAC,IAAI,CAAC;YACP,IAAI,EAAE,aAAa;YACnB,aAAa,EAAE,CAAC;YAChB,MAAM,EAAE,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE;YACpD,QAAQ,EAAE,MAAM;YAChB,OAAO,EAAE,EAAE;SACZ,CAAC,CAAC;QACH,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;IAC1B,CAAC,CAAqC;IACtC,kBAAkB,EAAE,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAC7B,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,KAAK,CAAgB,wBAAwB,CAAC,CAAC,MAAM;QACnE,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,gDAAgD,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM;KAChG,CAAC,CAAqC;CACxC,CAAC;AAEF,+EAA+E;AAE/E,MAAM,OAAO,GAAwD,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;IAClF,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,mDAAmD,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IACzF,GAAG,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;AACnG,CAAC,CAAC;AAEF,MAAM,UAAU,GAAwD,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;IACrF,GAAG,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;AACnG,CAAC,CAAC;AAEF,MAAM,cAAc,GAAsC,CAAC,GAAG,EAAE,EAAE;IAChE,GAAG,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;AAC1F,CAAC,CAAC;AAEF,MAAM,WAAW,GAA0E,CAAC,GAAG,EAAE,EAAE,CACjG,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,wEAAwE,CAAC,CAAC;AAE1F,MAAM,UAAU,GAGZ,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,yEAAyE,CAAC,CAAC;AAEtG,MAAM,MAAM,GAAoE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;IAC7F,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;AACtC,CAAC,CAAC;AAEF,MAAM,OAAO,GAAiF,CAC5F,GAAG,EACH,KAAK,EACL,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;AAE/C,MAAM,iBAAiB,GAAoB,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;IACxD,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,qDAAqD,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IAC5F,GAAG,CAAC,IAAI,CAAC;QACP,IAAI,EAAE,YAAY;QAClB,aAAa,EAAE,CAAC;QAChB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,QAAQ,EAAE,MAAM;QAChB,OAAO,EAAE,EAAE;KACZ,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAoB,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;IACxD,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,qDAAqD,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;AAC9F,CAAC,CAAC;AAEF,+EAA+E;AAE/E,MAAM,CAAC,MAAM,OAAO,GAAuB;IACzC,QAAQ,EAAE,eAAe;IACzB,UAAU,EAAE;QACV;YACE,OAAO,EAAE,WAAW;YACpB,GAAG,EAAE,qEAAqE;SAC3E;KACF;IACD,UAAU,EAAE;QACV,aAAa,EAAE,OAA2C;QAC1D,gBAAgB,EAAE,UAA8C;QAChE,yBAAyB,EAAE,cAAkD;QAC7E,sBAAsB,EAAE,WAA+C;QACvE,qBAAqB,EAAE,UAA8C;KACtE;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAuB;IACzC,QAAQ,EAAE,eAAe;IACzB,UAAU,EAAE;QACV;YACE,OAAO,EAAE,WAAW;YACpB,GAAG,EAAE,uEAAuE;SAC7E;KACF;IACD,UAAU,EAAE;QACV,cAAc,EAAE,CAAC,CAAC,GAAG,EAAE,EAAE;YACvB,GAAG,CAAC,IAAI,CAAC;gBACP,IAAI,EAAE,YAAY;gBAClB,aAAa,EAAE,CAAC;gBAChB,MAAM,EAAE,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE;gBACpD,QAAQ,EAAE,MAAM;gBAChB,OAAO,EAAE,EAAE;aACZ,CAAC,CAAC;QACL,CAAC,CAAqC;QACtC,UAAU,EAAE,CAAC,CAAC,GAAG,EAAE,EAAE,CACnB,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAGvE;QACD,iBAAiB,EAAE,CAAC,CAAC,GAAG,EAAE,EAAE,CAC1B,GAAG,CAAC,GAAG,CAAC,KAAK,CACX;gEACwD,CACzD,CAAqC;QACxC,mBAAmB,EAAE,CAAC,CAAC,GAAG,EAAE,EAAE,CAC5B,GAAG,CAAC,GAAG,CAAC,KAAK,CACX,8DAA8D,CAC/D,CAAqC;KACzC;IACD,SAAS,EAAE;QACT,YAAY,EAAE,iBAAiB;QAC/B,YAAY,EAAE,iBAAiB;KAChC;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAuB;IAC5C,QAAQ,EAAE,kBAAkB;IAC5B,UAAU,EAAE,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,EAAE,0CAA0C,EAAE,CAAC;IACvF,UAAU,EAAE;QACV,aAAa,EAAE,CAAC,CAAC,GAAG,EAAE,KAAwB,EAAE,EAAE;YAChD,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,sCAAsC,EAAE,CAAC,KAAK,EAAE,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC;YAC9E,GAAG,CAAC,IAAI,CAAC;gBACP,IAAI,EAAE,eAAe;gBACrB,aAAa,EAAE,CAAC;gBAChB,MAAM,EAAE,EAAE,UAAU,EAAE,eAAe,EAAE,QAAQ,EAAE,IAAI,EAAE;gBACvD,QAAQ,EAAE,MAAM;gBAChB,OAAO,EAAE,EAAE;aACZ,CAAC,CAAC;QACL,CAAC,CAAqC;QACtC,gBAAgB,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,CAAqC;QACnE,cAAc,EAAE,CAAC,CAAC,GAAG,EAAE,EAAE,CACvB,GAAG,CAAC,GAAG,CAAC,KAAK,CAAgB,yBAAyB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAGxE;QACD,gBAAgB,EAAE,CAAC,CAAC,GAAG,EAAE,EAAE,CACzB,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,gDAAgD,EAAE,CAAC,eAAe,CAAC,CAAC;aAC/E,MAAM,CAAqC;KACjD;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAuB;IACzC,QAAQ,EAAE,eAAe;IACzB,UAAU,EAAE;QACV,6EAA6E;QAC7E,yDAAyD;QACzD,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE;YACvC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;YACzB,MAAM,GAAG,GAAI,KAAuC,EAAE,IAAI,CAAC;YAC3D,IAAI,GAAG,KAAK,IAAI;gBACd,MAAM,IAAI,KAAK,CAAC,yBAAyB,MAAM,CAAC,IAAI,CAAC,WAAW,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpF,CAAC;KACF;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAuB,EAAE,QAAQ,EAAE,qBAAqB,EAAE,CAAC;AAExF,MAAM,CAAC,MAAM,SAAS,GAAuB;IAC3C,QAAQ,EAAE,iBAAiB;IAC3B,UAAU,EAAE;QACV,UAAU,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAqC;QAC3D,UAAU,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAqC;QAC3D,UAAU,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAqC;KAC5D;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAuB,EAAE,QAAQ,EAAE,oBAAoB,EAAE,CAAC;AAEtF,MAAM,CAAC,MAAM,OAAO,GAAuB;IACzC,QAAQ,EAAE,eAAe;IACzB,UAAU,EAAE,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,EAAE,2CAA2C,EAAE,CAAC;IACxF,UAAU,EAAE;QACV,YAAY,EAAE,CAAC,CAAC,GAAG,EAAE,EAAE,CACrB,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,sDAAsD,CAAC;aAClE,MAAM,CAAqC;KACjD;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAuB;IAC3C,QAAQ,EAAE,iBAAiB;IAC3B,UAAU,EAAE;QACV,YAAY,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,CAAqC;KAChE;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAuB;IACzC,QAAQ,EAAE,eAAe;IACzB,UAAU,EAAE;QACV,WAAW,EAAE,MAA0C;QACvD,YAAY,EAAE,OAA2C;KAC1D;CACF,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAyB;IAC9D,OAAO;IACP,OAAO;IACP,UAAU;IACV,OAAO;IACP,gBAAgB;IAChB,SAAS;IACT,eAAe;CAChB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAyB;IACvD,GAAG,0BAA0B;IAC7B,OAAO;IACP,SAAS;IACT,OAAO;CACR,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permission-suite.d.ts","sourceRoot":"","sources":["../src/permission-suite.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"permission-suite.d.ts","sourceRoot":"","sources":["../src/permission-suite.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAM9D;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,OAAO,CAAC,gBAAgB,CAAC,GAC3C,IAAI,CAgKN"}
|
package/dist/permission-suite.js
CHANGED
|
@@ -1,24 +1,7 @@
|
|
|
1
1
|
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
|
|
2
|
-
import {
|
|
2
|
+
import { permissionKey, platformActorId, principalId, scopeId, tenantId, } from '@substrat-run/contracts';
|
|
3
3
|
import { ulid } from '@substrat-run/kernel';
|
|
4
|
-
|
|
5
|
-
id: '@perm/mod',
|
|
6
|
-
version: '1.0.0',
|
|
7
|
-
kernelContract: '^0.0.1',
|
|
8
|
-
permissions: [
|
|
9
|
-
{ key: 'perm:use', description: 'use the thing' },
|
|
10
|
-
{ key: 'perm:read', description: 'read the thing' },
|
|
11
|
-
],
|
|
12
|
-
events: { emits: [], consumes: [] },
|
|
13
|
-
migrations: { journalDir: './migrations', compatibleFrom: '1.0.0' },
|
|
14
|
-
attachmentTargets: [],
|
|
15
|
-
entityRelations: [{ entityType: 'item', parentType: 'box' }],
|
|
16
|
-
entitlementKey: 'perm',
|
|
17
|
-
});
|
|
18
|
-
const linkOp = (ctx, input) => {
|
|
19
|
-
ctx.link(input.child, input.parent);
|
|
20
|
-
};
|
|
21
|
-
const probeOp = (ctx, input) => ctx.check(input.permission, input.entity);
|
|
4
|
+
import { permMod } from './modules.js';
|
|
22
5
|
const PERM_USE = permissionKey.parse('perm:use');
|
|
23
6
|
const PERM_READ = permissionKey.parse('perm:read');
|
|
24
7
|
/**
|
|
@@ -38,6 +21,7 @@ export function permissionContractSuite(adapterName, makeFixture) {
|
|
|
38
21
|
const carol = principalId.parse(ulid()); // entity-narrowed grant
|
|
39
22
|
const dave = principalId.parse(ulid()); // expired grant
|
|
40
23
|
const erin = principalId.parse(ulid()); // via org membership
|
|
24
|
+
const staff = platformActorId.parse(ulid()); // control-plane dev actor (§6)
|
|
41
25
|
const probe = async (who, scope, permission, entity) => {
|
|
42
26
|
const stub = await host.getScope(who, t1, scope);
|
|
43
27
|
return stub.invoke('perm/probe', {
|
|
@@ -48,20 +32,19 @@ export function permissionContractSuite(adapterName, makeFixture) {
|
|
|
48
32
|
beforeAll(async () => {
|
|
49
33
|
fixture = await makeFixture();
|
|
50
34
|
host = fixture.host;
|
|
51
|
-
host.registerModule(
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
});
|
|
55
|
-
await host.provisionScope({ tenantId: t1, scopeId:
|
|
56
|
-
await host.
|
|
57
|
-
host.admin.defineRole(t1, {
|
|
35
|
+
host.registerModule(permMod);
|
|
36
|
+
await host.admin.createTenant(staff, { id: t1, slug: 'perm-tenant', name: 'Perm Tenant' });
|
|
37
|
+
await host.admin.grantEntitlement(staff, t1, 'perm'); // default-deny (§4.3): perm/* needs it
|
|
38
|
+
await host.provisionScope(staff, { tenantId: t1, scopeId: s1 });
|
|
39
|
+
await host.provisionScope(staff, { tenantId: t1, scopeId: s2 });
|
|
40
|
+
await host.admin.defineRole(staff, t1, {
|
|
58
41
|
key: 'admin',
|
|
59
42
|
permissions: [PERM_USE, PERM_READ],
|
|
60
43
|
source: 'vertical',
|
|
61
44
|
});
|
|
62
|
-
host.admin.defineRole(t1, { key: 'tech', permissions: [PERM_READ], source: 'vertical' });
|
|
63
|
-
host.admin.assignRole({ principalId: alice, roleKey: 'admin', node: { tenantId: t1, scopeId: null } });
|
|
64
|
-
host.admin.assignRole({ principalId: bob, roleKey: 'tech', node: { tenantId: t1, scopeId: s1 } });
|
|
45
|
+
await host.admin.defineRole(staff, t1, { key: 'tech', permissions: [PERM_READ], source: 'vertical' });
|
|
46
|
+
await host.admin.assignRole(staff, { principalId: alice, roleKey: 'admin', node: { tenantId: t1, scopeId: null } });
|
|
47
|
+
await host.admin.assignRole(staff, { principalId: bob, roleKey: 'tech', node: { tenantId: t1, scopeId: s1 } });
|
|
65
48
|
// Entity graph in s1: item i1 → box b1, item i2 → box b2.
|
|
66
49
|
const stub = await host.getScope(alice, t1, s1);
|
|
67
50
|
await stub.invoke('perm/link', {
|
|
@@ -72,22 +55,22 @@ export function permissionContractSuite(adapterName, makeFixture) {
|
|
|
72
55
|
child: { entityType: 'item', entityId: 'i2' },
|
|
73
56
|
parent: { entityType: 'box', entityId: 'b2' },
|
|
74
57
|
});
|
|
75
|
-
host.admin.grant({
|
|
58
|
+
await host.admin.grant(staff, {
|
|
76
59
|
principalId: carol,
|
|
77
60
|
permission: PERM_READ,
|
|
78
61
|
node: { tenantId: t1, scopeId: s1 },
|
|
79
62
|
entity: { entityType: 'box', entityId: 'b1' },
|
|
80
63
|
grantedBy: alice,
|
|
81
64
|
});
|
|
82
|
-
host.admin.grant({
|
|
65
|
+
await host.admin.grant(staff, {
|
|
83
66
|
principalId: dave,
|
|
84
67
|
permission: PERM_READ,
|
|
85
68
|
node: { tenantId: t1, scopeId: s1 },
|
|
86
69
|
expiresAt: (await import('@substrat-run/contracts')).instant.parse('2000-01-01T00:00:00Z'),
|
|
87
70
|
grantedBy: alice,
|
|
88
71
|
});
|
|
89
|
-
host.admin.grantToOrg('acme', PERM_READ, { tenantId: t1, scopeId: s1 });
|
|
90
|
-
host.admin.addMember(t1, erin, 'acme');
|
|
72
|
+
await host.admin.grantToOrg(staff, 'acme', PERM_READ, { tenantId: t1, scopeId: s1 });
|
|
73
|
+
await host.admin.addMember(staff, t1, erin, 'acme');
|
|
91
74
|
});
|
|
92
75
|
afterAll(async () => {
|
|
93
76
|
await fixture.cleanup();
|
|
@@ -124,6 +107,39 @@ export function permissionContractSuite(adapterName, makeFixture) {
|
|
|
124
107
|
expect(d.allowed).toBe(true);
|
|
125
108
|
expect(JSON.stringify(d.proof)).toContain('org:acme');
|
|
126
109
|
});
|
|
110
|
+
// -- control-plane audit trail (control-plane.md §4.4) --------------------
|
|
111
|
+
it('records every admin mutation with actor and target, append-only (K-20)', async () => {
|
|
112
|
+
const log = await host.admin.auditLog({ tenantId: t1 });
|
|
113
|
+
// The six seed mutations each left a row; nothing is ever removed.
|
|
114
|
+
expect(log.length).toBeGreaterThanOrEqual(6);
|
|
115
|
+
// Every row is stamped platform-side: our staff actor, this tenant, a timestamp.
|
|
116
|
+
for (const row of log) {
|
|
117
|
+
expect(row.actor).toBe(staff);
|
|
118
|
+
expect(row.tenantId).toBe(t1);
|
|
119
|
+
expect(typeof row.at).toBe('string');
|
|
120
|
+
}
|
|
121
|
+
const actions = log.map((r) => r.action);
|
|
122
|
+
expect(actions).toEqual(expect.arrayContaining(['defineRole', 'assignRole', 'grant', 'grantToOrg', 'addMember']));
|
|
123
|
+
// defineRole captures the applied role in `after` — the raw material for
|
|
124
|
+
// the §4.5 permission diff.
|
|
125
|
+
const defined = log.find((r) => r.action === 'defineRole');
|
|
126
|
+
expect(defined?.after).toMatchObject({ permissions: expect.any(Array) });
|
|
127
|
+
});
|
|
128
|
+
it('captures before/after when a role is redefined — the permission-diff seed', async () => {
|
|
129
|
+
await host.admin.defineRole(staff, t1, { key: 'tech', permissions: [PERM_USE], source: 'vertical' });
|
|
130
|
+
const redefines = (await host.admin.auditLog({ tenantId: t1 }))
|
|
131
|
+
.filter((r) => r.action === 'defineRole' &&
|
|
132
|
+
r.after?.key === 'tech' &&
|
|
133
|
+
r.before !== null);
|
|
134
|
+
expect(redefines.length).toBeGreaterThanOrEqual(1);
|
|
135
|
+
const last = redefines[redefines.length - 1];
|
|
136
|
+
expect(last.before.permissions).toEqual([PERM_READ]);
|
|
137
|
+
expect(last.after.permissions).toEqual([PERM_USE]);
|
|
138
|
+
});
|
|
139
|
+
it('scopes the audit read by tenant', async () => {
|
|
140
|
+
const otherTenant = tenantId.parse(ulid());
|
|
141
|
+
expect(await host.admin.auditLog({ tenantId: otherTenant })).toEqual([]);
|
|
142
|
+
});
|
|
127
143
|
});
|
|
128
144
|
}
|
|
129
145
|
//# sourceMappingURL=permission-suite.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permission-suite.js","sourceRoot":"","sources":["../src/permission-suite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AACnE,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"permission-suite.js","sourceRoot":"","sources":["../src/permission-suite.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,11 +3,22 @@ export interface ScopeHostFixture {
|
|
|
3
3
|
host: ScopeHost;
|
|
4
4
|
cleanup(): Promise<void>;
|
|
5
5
|
}
|
|
6
|
+
/** Adapter capability flags — everything an adapter cannot honor identically. */
|
|
7
|
+
export interface ScopeHostSuiteOptions {
|
|
8
|
+
/**
|
|
9
|
+
* Whether the adapter supports registering a module AFTER a scope was first
|
|
10
|
+
* accessed (runtime registration). The pure adapter does; the Cloudflare
|
|
11
|
+
* adapter closes its ScopeDO over a code-time module set, so it does not. When
|
|
12
|
+
* `false`, the single late-registration test is skipped — every other test is
|
|
13
|
+
* shared unchanged (D-14).
|
|
14
|
+
*/
|
|
15
|
+
supportsRuntimeRegistration?: boolean;
|
|
16
|
+
}
|
|
6
17
|
/**
|
|
7
18
|
* The scope-host contract suite (design doc §11). Every adapter — pure SQLite,
|
|
8
19
|
* Cloudflare, and any future one — must pass this unchanged (D-14). If an
|
|
9
20
|
* adapter needs the suite modified, the contract changed and that is a
|
|
10
21
|
* decision, not a patch.
|
|
11
22
|
*/
|
|
12
|
-
export declare function scopeHostContractSuite(adapterName: string, makeFixture: () => Promise<ScopeHostFixture
|
|
23
|
+
export declare function scopeHostContractSuite(adapterName: string, makeFixture: () => Promise<ScopeHostFixture>, opts?: ScopeHostSuiteOptions): void;
|
|
13
24
|
//# sourceMappingURL=scope-host-suite.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scope-host-suite.d.ts","sourceRoot":"","sources":["../src/scope-host-suite.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"scope-host-suite.d.ts","sourceRoot":"","sources":["../src/scope-host-suite.ts"],"names":[],"mappings":"AASA,OAAO,EAA+B,KAAK,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAWnF,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAYD,iFAAiF;AACjF,MAAM,WAAW,qBAAqB;IACpC;;;;;;OAMG;IACH,2BAA2B,CAAC,EAAE,OAAO,CAAC;CACvC;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,OAAO,CAAC,gBAAgB,CAAC,EAC5C,IAAI,GAAE,qBAA0B,GAC/B,IAAI,CAgaN"}
|