@substrat-run/contract-tests 0.142.0 → 0.144.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/dist/attachment-refusal-suite.d.ts +3 -0
- package/dist/attachment-refusal-suite.d.ts.map +1 -0
- package/dist/attachment-refusal-suite.js +128 -0
- package/dist/attachment-refusal-suite.js.map +1 -0
- package/dist/bind-module.d.ts +199 -0
- package/dist/bind-module.d.ts.map +1 -0
- package/dist/bind-module.js +104 -0
- package/dist/bind-module.js.map +1 -0
- package/dist/binding-invite-suite.d.ts +12 -0
- package/dist/binding-invite-suite.d.ts.map +1 -0
- package/dist/binding-invite-suite.js +507 -0
- package/dist/binding-invite-suite.js.map +1 -0
- package/dist/caused-by-module.d.ts.map +1 -1
- package/dist/caused-by-module.js +3 -2
- package/dist/caused-by-module.js.map +1 -1
- package/dist/derived-module.d.ts +690 -0
- package/dist/derived-module.d.ts.map +1 -0
- package/dist/derived-module.js +320 -0
- package/dist/derived-module.js.map +1 -0
- package/dist/derived-suite.d.ts +3 -0
- package/dist/derived-suite.d.ts.map +1 -0
- package/dist/derived-suite.js +481 -0
- package/dist/derived-suite.js.map +1 -0
- package/dist/entity-state-module.d.ts.map +1 -1
- package/dist/entity-state-module.js +12 -6
- package/dist/entity-state-module.js.map +1 -1
- package/dist/entity-trash-module.d.ts.map +1 -1
- package/dist/entity-trash-module.js +4 -4
- package/dist/entity-trash-module.js.map +1 -1
- package/dist/entity-trash-suite.d.ts.map +1 -1
- package/dist/entity-trash-suite.js +17 -8
- package/dist/entity-trash-suite.js.map +1 -1
- package/dist/erasure-module.d.ts.map +1 -1
- package/dist/erasure-module.js +3 -2
- package/dist/erasure-module.js.map +1 -1
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/input-parse-suite.d.ts.map +1 -1
- package/dist/input-parse-suite.js +33 -2
- package/dist/input-parse-suite.js.map +1 -1
- package/dist/membership-module.d.ts.map +1 -1
- package/dist/membership-module.js +3 -2
- package/dist/membership-module.js.map +1 -1
- package/dist/migration-comments.d.ts.map +1 -1
- package/dist/migration-comments.js +3 -2
- package/dist/migration-comments.js.map +1 -1
- package/dist/modules.d.ts.map +1 -1
- package/dist/modules.js +78 -68
- package/dist/modules.js.map +1 -1
- package/dist/permission-suite.d.ts.map +1 -1
- package/dist/permission-suite.js +28 -0
- package/dist/permission-suite.js.map +1 -1
- package/dist/scope-host-suite.d.ts.map +1 -1
- package/dist/scope-host-suite.js +151 -31
- package/dist/scope-host-suite.js.map +1 -1
- package/dist/shape-backfill-ties.d.ts +29 -0
- package/dist/shape-backfill-ties.d.ts.map +1 -0
- package/dist/shape-backfill-ties.js +113 -0
- package/dist/shape-backfill-ties.js.map +1 -0
- package/dist/shape-reconcile-plan.d.ts +37 -0
- package/dist/shape-reconcile-plan.d.ts.map +1 -0
- package/dist/shape-reconcile-plan.js +143 -0
- package/dist/shape-reconcile-plan.js.map +1 -0
- package/dist/test-operations.d.ts +25 -0
- package/dist/test-operations.d.ts.map +1 -0
- package/dist/test-operations.js +22 -0
- package/dist/test-operations.js.map +1 -0
- package/dist/vertical-events-suite.d.ts.map +1 -1
- package/dist/vertical-events-suite.js +72 -7
- package/dist/vertical-events-suite.js.map +1 -1
- package/package.json +3 -3
package/dist/modules.js
CHANGED
|
@@ -11,9 +11,12 @@ import { dataSubjectId, moduleManifest, operationInputsOf, operationConcurrencyO
|
|
|
11
11
|
import { membershipFixtureMod } from './membership-module.js';
|
|
12
12
|
import { rebuildMod, stateMod } from './entity-state-module.js';
|
|
13
13
|
import { trashMod } from './entity-trash-module.js';
|
|
14
|
+
import { derivedMod } from './derived-module.js';
|
|
14
15
|
import { erasureMod, erasureOtherMod } from './erasure-module.js';
|
|
16
|
+
import { bindMod } from './bind-module.js';
|
|
15
17
|
import { commentedDdlMod } from './migration-comments.js';
|
|
16
18
|
import { assertAllowed, readAttachmentText, readHistory, readTimeline, readScopeTimeline, readScopeHistory, ulid, } from '@substrat-run/kernel';
|
|
19
|
+
import { testOperations } from './test-operations.js';
|
|
17
20
|
/**
|
|
18
21
|
* #1744: the machine `test/move` walks, in the form `model.json` emits — what the suite
|
|
19
22
|
* hands `lifecycleFlow`. #1745: also the one `test/refuse` asserts against, where
|
|
@@ -129,7 +132,7 @@ export const freshnessModManifest = moduleManifest.parse({
|
|
|
129
132
|
export const freshnessMod = {
|
|
130
133
|
manifest: freshnessModManifest,
|
|
131
134
|
migrations: [],
|
|
132
|
-
|
|
135
|
+
...testOperations({}),
|
|
133
136
|
};
|
|
134
137
|
/**
|
|
135
138
|
* #1577: the module a resumable RUN acts through.
|
|
@@ -163,7 +166,7 @@ export const jobsMod = {
|
|
|
163
166
|
migrations: [
|
|
164
167
|
{ version: '0001-init', sql: 'CREATE TABLE job_items (item TEXT NOT NULL)' },
|
|
165
168
|
],
|
|
166
|
-
|
|
169
|
+
...testOperations({
|
|
167
170
|
// Deliberately NOT idempotent and NOT unique-keyed: a repeated step shows up as
|
|
168
171
|
// a DUPLICATE ROW rather than being silently absorbed, which is the only way the
|
|
169
172
|
// resume assertion can fail loudly when the memo stops working.
|
|
@@ -174,7 +177,7 @@ export const jobsMod = {
|
|
|
174
177
|
'jobs/items': ((ctx) => ctx.sql
|
|
175
178
|
.query('SELECT item FROM job_items ORDER BY rowid')
|
|
176
179
|
.map((r) => r.item)),
|
|
177
|
-
},
|
|
180
|
+
}),
|
|
178
181
|
};
|
|
179
182
|
export const flowModManifest = moduleManifest.parse({
|
|
180
183
|
id: '@test/flow',
|
|
@@ -1075,7 +1078,7 @@ export const testMod = {
|
|
|
1075
1078
|
`,
|
|
1076
1079
|
},
|
|
1077
1080
|
],
|
|
1078
|
-
|
|
1081
|
+
...testOperations({
|
|
1079
1082
|
'testmod/add': addItem,
|
|
1080
1083
|
'testmod/link-again': linkItemAgain,
|
|
1081
1084
|
'testmod/link-undeclared': linkUndeclared,
|
|
@@ -1104,14 +1107,14 @@ export const testMod = {
|
|
|
1104
1107
|
'testmod/project-journal': projectJournal,
|
|
1105
1108
|
'testmod/read-items': readItems,
|
|
1106
1109
|
'testmod/read-notes': readNotes,
|
|
1107
|
-
},
|
|
1110
|
+
}),
|
|
1108
1111
|
};
|
|
1109
1112
|
export const atomicMod = {
|
|
1110
1113
|
manifest: atomicModManifest,
|
|
1111
1114
|
migrations: [
|
|
1112
1115
|
{ version: '0001-init', sql: 'CREATE TABLE atomic_rows (id TEXT PRIMARY KEY, tag TEXT NOT NULL)' },
|
|
1113
1116
|
],
|
|
1114
|
-
|
|
1117
|
+
...testOperations({
|
|
1115
1118
|
'atomic/rollback': atomicRollback,
|
|
1116
1119
|
'atomic/success': atomicSuccess,
|
|
1117
1120
|
'atomic/stacked': atomicStacked,
|
|
@@ -1123,14 +1126,14 @@ export const atomicMod = {
|
|
|
1123
1126
|
'atomic/read-outbox': atomicReadOutbox,
|
|
1124
1127
|
'atomic/read-tuples': atomicReadTuples,
|
|
1125
1128
|
'atomic/read-intents': atomicReadIntents,
|
|
1126
|
-
},
|
|
1129
|
+
}),
|
|
1127
1130
|
};
|
|
1128
1131
|
export const scheduleMod = {
|
|
1129
1132
|
manifest: scheduleModManifest,
|
|
1130
1133
|
migrations: [
|
|
1131
1134
|
{ version: '0001-init', sql: 'CREATE TABLE sched_ticks (n INTEGER NOT NULL)' },
|
|
1132
1135
|
],
|
|
1133
|
-
|
|
1136
|
+
...testOperations({
|
|
1134
1137
|
// The scheduled operation: check the granted permission, then emit + record a
|
|
1135
1138
|
// tick. Under a system caller its emitted event's actor must be { system: … }.
|
|
1136
1139
|
'sched/tick': (async (ctx) => {
|
|
@@ -1177,7 +1180,7 @@ export const scheduleMod = {
|
|
|
1177
1180
|
// on `sched/schedule-state` — proving a FAILED run carries the identical id, not
|
|
1178
1181
|
// just a fired one.
|
|
1179
1182
|
'sched/read-denials': readDenialsOp,
|
|
1180
|
-
},
|
|
1183
|
+
}),
|
|
1181
1184
|
};
|
|
1182
1185
|
/**
|
|
1183
1186
|
* #1525: the failure twin of `scheduleMod` itself — a SEPARATE module so registering
|
|
@@ -1207,11 +1210,11 @@ export const deniedScheduleModManifest = moduleManifest.parse({
|
|
|
1207
1210
|
});
|
|
1208
1211
|
export const deniedScheduleMod = {
|
|
1209
1212
|
manifest: deniedScheduleModManifest,
|
|
1210
|
-
|
|
1213
|
+
...testOperations({
|
|
1211
1214
|
'sched-denied/tick': (async (ctx) => {
|
|
1212
1215
|
assertAllowed(await ctx.check('sched-denied:admin'));
|
|
1213
1216
|
}),
|
|
1214
|
-
},
|
|
1217
|
+
}),
|
|
1215
1218
|
};
|
|
1216
1219
|
// -- #1654: a composed engine's own schedule, on a tenant holding only the vertical's key --
|
|
1217
1220
|
/**
|
|
@@ -1246,7 +1249,7 @@ export function countComposedSweeps(ctx) {
|
|
|
1246
1249
|
export const composedEngineMod = {
|
|
1247
1250
|
manifest: composedEngineModManifest,
|
|
1248
1251
|
migrations: [{ version: '0001-init', sql: 'CREATE TABLE composed_engine_sweeps (n INTEGER NOT NULL)' }],
|
|
1249
|
-
|
|
1252
|
+
...testOperations({
|
|
1250
1253
|
'composed-engine/sweep': (async (ctx) => {
|
|
1251
1254
|
assertAllowed(await ctx.check('composed-engine:sweep'));
|
|
1252
1255
|
ctx.sql.exec('INSERT INTO composed_engine_sweeps (n) VALUES (1)');
|
|
@@ -1262,7 +1265,7 @@ export const composedEngineMod = {
|
|
|
1262
1265
|
assertAllowed(await ctx.check('composed-engine:sweep'));
|
|
1263
1266
|
ctx.sql.exec('INSERT INTO composed_engine_sweeps (n) VALUES (1)');
|
|
1264
1267
|
}),
|
|
1265
|
-
},
|
|
1268
|
+
}),
|
|
1266
1269
|
};
|
|
1267
1270
|
/**
|
|
1268
1271
|
* #1654's VERTICAL: holds the key a standard install grants (`composer`), and reads the
|
|
@@ -1282,9 +1285,9 @@ export const composerModManifest = moduleManifest.parse({
|
|
|
1282
1285
|
});
|
|
1283
1286
|
export const composerMod = {
|
|
1284
1287
|
manifest: composerModManifest,
|
|
1285
|
-
|
|
1288
|
+
...testOperations({
|
|
1286
1289
|
'composer/sweeps': ((ctx) => countComposedSweeps(ctx)),
|
|
1287
|
-
},
|
|
1290
|
+
}),
|
|
1288
1291
|
};
|
|
1289
1292
|
export const flowMod = {
|
|
1290
1293
|
manifest: flowModManifest,
|
|
@@ -1294,7 +1297,7 @@ export const flowMod = {
|
|
|
1294
1297
|
sql: 'CREATE TABLE flow_log (event_id TEXT PRIMARY KEY, type TEXT NOT NULL)',
|
|
1295
1298
|
},
|
|
1296
1299
|
],
|
|
1297
|
-
|
|
1300
|
+
...testOperations({
|
|
1298
1301
|
'flow/produce': ((ctx) => {
|
|
1299
1302
|
ctx.emit({
|
|
1300
1303
|
type: 'flow.step1',
|
|
@@ -1317,7 +1320,7 @@ export const flowMod = {
|
|
|
1317
1320
|
WHERE type IN ('flow.step1', 'flow.step2') ORDER BY id`)),
|
|
1318
1321
|
'flow/causes': ((ctx) => ctx.sql.query(`SELECT id, type, operation, caused_by FROM _substrat_outbox
|
|
1319
1322
|
WHERE type IN ('flow.step1', 'flow.step2') ORDER BY id`)),
|
|
1320
|
-
},
|
|
1323
|
+
}),
|
|
1321
1324
|
consumers: {
|
|
1322
1325
|
'flow.step1': flowStep1Consumer,
|
|
1323
1326
|
'flow.step2': flowStep2Consumer,
|
|
@@ -1326,7 +1329,7 @@ export const flowMod = {
|
|
|
1326
1329
|
export const guardedMod = {
|
|
1327
1330
|
manifest: guardedModManifest,
|
|
1328
1331
|
migrations: [{ version: '0001-init', sql: 'CREATE TABLE guarded_t (v TEXT NOT NULL)' }],
|
|
1329
|
-
|
|
1332
|
+
...testOperations({
|
|
1330
1333
|
'guarded/act': ((ctx, input) => {
|
|
1331
1334
|
ctx.sql.exec('INSERT INTO guarded_t (v) VALUES (?)', [input?.flag ?? 'none']);
|
|
1332
1335
|
ctx.emit({
|
|
@@ -1344,7 +1347,7 @@ export const guardedMod = {
|
|
|
1344
1347
|
'guarded/rows': ((ctx) => ctx.sql.query('SELECT v FROM guarded_t').map((r) => r.v)),
|
|
1345
1348
|
'guarded/events': ((ctx) => ctx.sql.query('SELECT id FROM _substrat_outbox WHERE type = ?', ['guarded.acted'])
|
|
1346
1349
|
.length),
|
|
1347
|
-
},
|
|
1350
|
+
}),
|
|
1348
1351
|
};
|
|
1349
1352
|
export const gateMod = {
|
|
1350
1353
|
manifest: gateModManifest,
|
|
@@ -1374,31 +1377,31 @@ export const gateMod = {
|
|
|
1374
1377
|
export const withdrawEarlyMod = { manifest: withdrawEarlyManifest };
|
|
1375
1378
|
export const victimMod = {
|
|
1376
1379
|
manifest: victimModManifest,
|
|
1377
|
-
|
|
1380
|
+
...testOperations({
|
|
1378
1381
|
'victim/a': (() => 'a'),
|
|
1379
1382
|
'victim/b': (() => 'b'),
|
|
1380
1383
|
'victim/c': (() => 'c'),
|
|
1381
|
-
},
|
|
1384
|
+
}),
|
|
1382
1385
|
};
|
|
1383
1386
|
export const withdrawLateMod = { manifest: withdrawLateManifest };
|
|
1384
1387
|
export const lateMod = {
|
|
1385
1388
|
manifest: lateModManifest,
|
|
1386
1389
|
migrations: [{ version: '0001-init', sql: 'CREATE TABLE late_t (id TEXT PRIMARY KEY)' }],
|
|
1387
|
-
|
|
1390
|
+
...testOperations({
|
|
1388
1391
|
'late/check': ((ctx) => ctx.sql.query(`SELECT name FROM sqlite_master WHERE name = 'late_t'`)
|
|
1389
1392
|
.length),
|
|
1390
|
-
},
|
|
1393
|
+
}),
|
|
1391
1394
|
};
|
|
1392
1395
|
export const billedMod = {
|
|
1393
1396
|
manifest: billedModManifest,
|
|
1394
|
-
|
|
1397
|
+
...testOperations({
|
|
1395
1398
|
'billed/act': (() => 'ran'),
|
|
1396
1399
|
// #304: read the request-time entitlement view. Gated on 'billed' like every op in this
|
|
1397
1400
|
// module, so the tenant holds 'billed' when it runs; the KEY read is the operation input,
|
|
1398
1401
|
// letting a test read a held key, an absent key (→ null), or an expired one (→ null).
|
|
1399
1402
|
'billed/read-entitlement': (async (ctx, key) => ctx.entitlement(key)),
|
|
1400
1403
|
'billed/list-entitlements': (async (ctx) => ctx.entitlements()),
|
|
1401
|
-
},
|
|
1404
|
+
}),
|
|
1402
1405
|
};
|
|
1403
1406
|
export const impersonationEchoMod = {
|
|
1404
1407
|
manifest: impersonationEchoManifest,
|
|
@@ -1408,9 +1411,9 @@ export const impersonationEchoMod = {
|
|
|
1408
1411
|
sql: 'CREATE TABLE imp_echo (event_id TEXT PRIMARY KEY, impersonation TEXT)',
|
|
1409
1412
|
},
|
|
1410
1413
|
],
|
|
1411
|
-
|
|
1414
|
+
...testOperations({
|
|
1412
1415
|
'imp-echo/seen': ((ctx) => ctx.sql.query('SELECT event_id, impersonation FROM imp_echo ORDER BY event_id')),
|
|
1413
|
-
},
|
|
1416
|
+
}),
|
|
1414
1417
|
consumers: {
|
|
1415
1418
|
// The stamp as the CONSUMER received it, JSON-encoded so an absent one and a
|
|
1416
1419
|
// null one stay distinguishable in the assertion.
|
|
@@ -1424,7 +1427,7 @@ export const impersonationEchoMod = {
|
|
|
1424
1427
|
};
|
|
1425
1428
|
export const permMod = {
|
|
1426
1429
|
manifest: permModManifest,
|
|
1427
|
-
|
|
1430
|
+
...testOperations({
|
|
1428
1431
|
'perm/link': linkOp,
|
|
1429
1432
|
'perm/relink': relinkOp,
|
|
1430
1433
|
'perm/probe': probeOp,
|
|
@@ -1499,7 +1502,7 @@ export const permMod = {
|
|
|
1499
1502
|
await ctx.revoke(principalId.parse(i.principal), permissionKey.parse(i.permission), i.entity);
|
|
1500
1503
|
return { revoked: true };
|
|
1501
1504
|
}),
|
|
1502
|
-
},
|
|
1505
|
+
}),
|
|
1503
1506
|
consumers: {
|
|
1504
1507
|
'perm.check-requested': checkRequestedConsumer,
|
|
1505
1508
|
},
|
|
@@ -1541,7 +1544,7 @@ export const connectorMod = {
|
|
|
1541
1544
|
sql: 'CREATE TABLE connector_requests (id TEXT PRIMARY KEY, principal TEXT NOT NULL)',
|
|
1542
1545
|
},
|
|
1543
1546
|
],
|
|
1544
|
-
|
|
1547
|
+
...testOperations({
|
|
1545
1548
|
'connector/request-member': ((ctx, input) => {
|
|
1546
1549
|
ctx.sql.exec('INSERT INTO connector_requests (id, principal) VALUES (?, ?)', [
|
|
1547
1550
|
input.principal,
|
|
@@ -1602,7 +1605,7 @@ export const connectorMod = {
|
|
|
1602
1605
|
});
|
|
1603
1606
|
}),
|
|
1604
1607
|
'connector/requests': ((ctx) => ctx.sql.query('SELECT id FROM connector_requests')),
|
|
1605
|
-
},
|
|
1608
|
+
}),
|
|
1606
1609
|
};
|
|
1607
1610
|
/**
|
|
1608
1611
|
* The modules the scope-host suite's `beforeAll` registers, in the exact order
|
|
@@ -1670,7 +1673,6 @@ export const listDeclaredOps = {
|
|
|
1670
1673
|
};
|
|
1671
1674
|
export const listMod = {
|
|
1672
1675
|
manifest: listModManifest,
|
|
1673
|
-
operationInputs: operationInputsOf(listDeclaredOps),
|
|
1674
1676
|
migrations: [
|
|
1675
1677
|
{
|
|
1676
1678
|
version: '0001-init',
|
|
@@ -1680,7 +1682,7 @@ export const listMod = {
|
|
|
1680
1682
|
},
|
|
1681
1683
|
{ version: '0002-hold', sql: 'ALTER TABLE list_orders ADD COLUMN hold TEXT;' },
|
|
1682
1684
|
],
|
|
1683
|
-
|
|
1685
|
+
...testOperations({
|
|
1684
1686
|
'list/add': (async (ctx, input) => {
|
|
1685
1687
|
const i = input;
|
|
1686
1688
|
ctx.sql.exec('INSERT INTO list_orders (id, number, status, kind, hold) VALUES (?, ?, ?, ?, ?)', [
|
|
@@ -1748,7 +1750,7 @@ export const listMod = {
|
|
|
1748
1750
|
]);
|
|
1749
1751
|
return ctx.page('listorder', { limit: 50 });
|
|
1750
1752
|
}),
|
|
1751
|
-
},
|
|
1753
|
+
}, { inputs: operationInputsOf(listDeclaredOps) }),
|
|
1752
1754
|
};
|
|
1753
1755
|
export const searchModManifest = moduleManifest.parse({
|
|
1754
1756
|
id: '@test/search',
|
|
@@ -1775,7 +1777,7 @@ export const searchMod = {
|
|
|
1775
1777
|
CREATE TABLE search_notes (id TEXT PRIMARY KEY, body TEXT NOT NULL);`,
|
|
1776
1778
|
},
|
|
1777
1779
|
],
|
|
1778
|
-
|
|
1780
|
+
...testOperations({
|
|
1779
1781
|
'search/add': (async (ctx, input) => {
|
|
1780
1782
|
const i = input;
|
|
1781
1783
|
ctx.sql.exec('INSERT INTO search_customers (id, number, name) VALUES (?, ?, ?)', [
|
|
@@ -1816,7 +1818,7 @@ export const searchMod = {
|
|
|
1816
1818
|
]);
|
|
1817
1819
|
return ctx.search('searchcustomer', i.term);
|
|
1818
1820
|
}),
|
|
1819
|
-
},
|
|
1821
|
+
}),
|
|
1820
1822
|
};
|
|
1821
1823
|
// -- #893: the declared input the HOST parses ---------------------------------
|
|
1822
1824
|
export const parseModManifest = moduleManifest.parse({
|
|
@@ -1873,12 +1875,11 @@ const parseDeclaration = {
|
|
|
1873
1875
|
};
|
|
1874
1876
|
export const parseMod = {
|
|
1875
1877
|
manifest: parseModManifest,
|
|
1876
|
-
|
|
1878
|
+
...testOperations({
|
|
1877
1879
|
'parse/echo': echo,
|
|
1878
1880
|
'parse/paged': echo,
|
|
1879
1881
|
'parse/bare': echo,
|
|
1880
|
-
},
|
|
1881
|
-
operationInputs: operationInputsOf(parseDeclaration),
|
|
1882
|
+
}, { inputs: operationInputsOf(parseDeclaration) }),
|
|
1882
1883
|
};
|
|
1883
1884
|
// -- #129: the precondition the HOST compares ---------------------------------
|
|
1884
1885
|
export const concurrencyModManifest = moduleManifest.parse({
|
|
@@ -1980,16 +1981,17 @@ const concurrencyDeclaration = {
|
|
|
1980
1981
|
};
|
|
1981
1982
|
export const concurrencyMod = {
|
|
1982
1983
|
manifest: concurrencyModManifest,
|
|
1983
|
-
|
|
1984
|
+
...testOperations({
|
|
1984
1985
|
'conc/update': concUpdate,
|
|
1985
1986
|
'conc/read': concRead,
|
|
1986
1987
|
'conc/silent': concSilent,
|
|
1987
1988
|
'conc/keyless': concRead,
|
|
1988
1989
|
'conc/forbidden': concForbidden,
|
|
1989
1990
|
'conc/unguarded': concUnguarded,
|
|
1990
|
-
},
|
|
1991
|
-
|
|
1992
|
-
|
|
1991
|
+
}, {
|
|
1992
|
+
inputs: operationInputsOf(concurrencyDeclaration),
|
|
1993
|
+
concurrency: operationConcurrencyOf(concurrencyDeclaration),
|
|
1994
|
+
}),
|
|
1993
1995
|
};
|
|
1994
1996
|
// -- #116: request idempotency ------------------------------------------------
|
|
1995
1997
|
export const idempotencyModManifest = moduleManifest.parse({
|
|
@@ -2080,17 +2082,18 @@ const idempotencyDeclaration = {
|
|
|
2080
2082
|
};
|
|
2081
2083
|
export const idempotencyMod = {
|
|
2082
2084
|
manifest: idempotencyModManifest,
|
|
2083
|
-
|
|
2085
|
+
...testOperations({
|
|
2084
2086
|
'idem/create': idemCreate,
|
|
2085
2087
|
'idem/create-guarded': idemCreate,
|
|
2086
2088
|
'idem/runs': idemRuns,
|
|
2087
2089
|
'idem/fails': idemFails,
|
|
2088
2090
|
'idem/big': idemBig,
|
|
2089
2091
|
'idem/secret': idemSecret,
|
|
2090
|
-
},
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2092
|
+
}, {
|
|
2093
|
+
inputs: operationInputsOf(idempotencyDeclaration),
|
|
2094
|
+
concurrency: operationConcurrencyOf(idempotencyDeclaration),
|
|
2095
|
+
idempotencyOptOuts: operationIdempotencyOptOutsOf(idempotencyDeclaration),
|
|
2096
|
+
}),
|
|
2094
2097
|
};
|
|
2095
2098
|
// -- capabilities (#1672) ------------------------------------------------------
|
|
2096
2099
|
/**
|
|
@@ -2146,7 +2149,7 @@ export const capMod = {
|
|
|
2146
2149
|
migrations: [
|
|
2147
2150
|
{ version: '0001-init', sql: 'CREATE TABLE cap_notes (id TEXT PRIMARY KEY, body TEXT NOT NULL)' },
|
|
2148
2151
|
],
|
|
2149
|
-
|
|
2152
|
+
...testOperations({
|
|
2150
2153
|
'cap/link': linkOp,
|
|
2151
2154
|
'cap/share': ((ctx, input) => ctx.capabilities.mint(input)),
|
|
2152
2155
|
// The link a vertical would hand back — the secret spliced into a URL fragment, so the
|
|
@@ -2269,7 +2272,7 @@ export const capMod = {
|
|
|
2269
2272
|
}
|
|
2270
2273
|
return out;
|
|
2271
2274
|
}),
|
|
2272
|
-
},
|
|
2275
|
+
}),
|
|
2273
2276
|
consumers: {
|
|
2274
2277
|
// Records what the mint answered rather than letting the delivery fail, so the test
|
|
2275
2278
|
// reads an outcome instead of inferring one from a dead letter.
|
|
@@ -2329,7 +2332,7 @@ export const peerMod = {
|
|
|
2329
2332
|
migrations: [
|
|
2330
2333
|
{ version: '0001-init', sql: 'CREATE TABLE peer_notes (id TEXT PRIMARY KEY, body TEXT NOT NULL)' },
|
|
2331
2334
|
],
|
|
2332
|
-
|
|
2335
|
+
...testOperations({
|
|
2333
2336
|
'peer/note': (async (ctx, input) => {
|
|
2334
2337
|
assertAllowed(await ctx.check(PEER_WRITE));
|
|
2335
2338
|
const { id, body } = input;
|
|
@@ -2366,7 +2369,7 @@ export const peerMod = {
|
|
|
2366
2369
|
'peer/outbox': ((ctx) => ctx.sql.query("SELECT actor, authorization, operation, entity_id FROM _substrat_outbox WHERE type = 'peer.noted' ORDER BY id")),
|
|
2367
2370
|
'peer/denials': readDenialsOp,
|
|
2368
2371
|
'peer/tuples': ((ctx) => ctx.sql.query("SELECT subject, relation, object, revoked_at FROM _substrat_tuples WHERE substr(subject, 1, 9) = 'vertical:' ORDER BY subject, relation")),
|
|
2369
|
-
},
|
|
2372
|
+
}),
|
|
2370
2373
|
};
|
|
2371
2374
|
// -- #1746: what an invocation emitted ----------------------------------------
|
|
2372
2375
|
export const emittedModManifest = moduleManifest.parse({
|
|
@@ -2404,7 +2407,7 @@ const touchAll = (ctx, ids) => {
|
|
|
2404
2407
|
*/
|
|
2405
2408
|
export const emittedMod = {
|
|
2406
2409
|
manifest: emittedModManifest,
|
|
2407
|
-
|
|
2410
|
+
...testOperations({
|
|
2408
2411
|
'emitted/touch': ((ctx, input) => {
|
|
2409
2412
|
touchAll(ctx, input.ids);
|
|
2410
2413
|
return { touched: input.ids.length };
|
|
@@ -2428,7 +2431,7 @@ export const emittedMod = {
|
|
|
2428
2431
|
}
|
|
2429
2432
|
return { ok: true };
|
|
2430
2433
|
}),
|
|
2431
|
-
},
|
|
2434
|
+
}),
|
|
2432
2435
|
consumers: {
|
|
2433
2436
|
'emitted.touched': ((ctx, event) => {
|
|
2434
2437
|
ctx.emit({
|
|
@@ -2462,7 +2465,7 @@ export const loggedModManifest = moduleManifest.parse({
|
|
|
2462
2465
|
*/
|
|
2463
2466
|
export const loggedMod = {
|
|
2464
2467
|
manifest: loggedModManifest,
|
|
2465
|
-
|
|
2468
|
+
...testOperations({
|
|
2466
2469
|
'logged/act': ((ctx, input) => {
|
|
2467
2470
|
// `tenantId` and `operation` in the fields are the caller's own values: they stay
|
|
2468
2471
|
// fields and never replace what the host stamps.
|
|
@@ -2480,7 +2483,7 @@ export const loggedMod = {
|
|
|
2480
2483
|
ctx.log.error('could not reach {ticketId}', { ticketId: input.ticketId });
|
|
2481
2484
|
throw new Error('logged/fail: refused after logging');
|
|
2482
2485
|
}),
|
|
2483
|
-
},
|
|
2486
|
+
}),
|
|
2484
2487
|
consumers: {
|
|
2485
2488
|
'logged.acted': ((ctx, event) => {
|
|
2486
2489
|
ctx.log.warn('saw {type}', { type: event.type });
|
|
@@ -2517,7 +2520,7 @@ export const ASYNC_LOG_SECRET_ENTITY = 'alice@example.com';
|
|
|
2517
2520
|
*/
|
|
2518
2521
|
export const asyncLogMod = {
|
|
2519
2522
|
manifest: asyncLogModManifest,
|
|
2520
|
-
|
|
2523
|
+
...testOperations({
|
|
2521
2524
|
'asynclog/act': ((ctx, input) => {
|
|
2522
2525
|
for (const tag of input.tags) {
|
|
2523
2526
|
ctx.emit({
|
|
@@ -2548,7 +2551,7 @@ export const asyncLogMod = {
|
|
|
2548
2551
|
ctx.log.info('ticking, about to refuse');
|
|
2549
2552
|
throw substratError('conflict', `tick refused: ${ASYNC_LOG_SECRET_TEXT}`);
|
|
2550
2553
|
}),
|
|
2551
|
-
},
|
|
2554
|
+
}),
|
|
2552
2555
|
consumers: {
|
|
2553
2556
|
'asynclog.acted': ((ctx, event) => {
|
|
2554
2557
|
const { tag, fail } = event.payload;
|
|
@@ -2594,6 +2597,9 @@ export const contractTestModules = [
|
|
|
2594
2597
|
// its tables or invokes a `state/*` operation.
|
|
2595
2598
|
stateMod,
|
|
2596
2599
|
trashMod,
|
|
2600
|
+
// #1773: the derived-handler suite's module. Inert for every other suite — nothing else reads
|
|
2601
|
+
// its tables or invokes a `derived/*` operation.
|
|
2602
|
+
derivedMod,
|
|
2597
2603
|
// #2068: the subject-erasure suite's modules. Every scope in the kit carries them, so every
|
|
2598
2604
|
// `shredSubject` in every suite runs their declared erasure and their hook — which reaches
|
|
2599
2605
|
// only `er_*` tables nothing else writes, and misbehaves only for a subject the erasure suite
|
|
@@ -2601,6 +2607,10 @@ export const contractTestModules = [
|
|
|
2601
2607
|
// module half is harmless where it holds nothing.
|
|
2602
2608
|
erasureMod,
|
|
2603
2609
|
erasureOtherMod,
|
|
2610
|
+
// #1686: the binding-invite suite's record type. Every scope carries it, so every erasure in
|
|
2611
|
+
// every suite also runs its capture and release — over no recorded binding unless the binding
|
|
2612
|
+
// suite reconciled one onto that scope, and a hook that touches only `bind_*` tables.
|
|
2613
|
+
bindMod,
|
|
2604
2614
|
// #2068 r5: a module whose migrations comment their DDL and then drop the last column. Every
|
|
2605
2615
|
// scope in the kit migrates it, so a regression fails loudly everywhere.
|
|
2606
2616
|
commentedDdlMod,
|
|
@@ -2764,7 +2774,7 @@ const liveReshelveOp = async (ctx, input) => {
|
|
|
2764
2774
|
export const liveMod = {
|
|
2765
2775
|
manifest: liveModManifest,
|
|
2766
2776
|
migrations: [],
|
|
2767
|
-
|
|
2777
|
+
...testOperations({
|
|
2768
2778
|
'live/touch': liveTouchOp,
|
|
2769
2779
|
'live/touch-ledger': liveTouchLedgerOp,
|
|
2770
2780
|
'live/unshare': liveUnshareOp,
|
|
@@ -2773,7 +2783,7 @@ export const liveMod = {
|
|
|
2773
2783
|
'live/touch-each': liveTouchEachOp,
|
|
2774
2784
|
'live/shelve': liveShelveOp,
|
|
2775
2785
|
'live/reshelve': liveReshelveOp,
|
|
2776
|
-
},
|
|
2786
|
+
}),
|
|
2777
2787
|
};
|
|
2778
2788
|
export const brokenModManifest = moduleManifest.parse({
|
|
2779
2789
|
id: '@test/broken',
|
|
@@ -2801,9 +2811,9 @@ export const brokenMod = {
|
|
|
2801
2811
|
{ version: '0001-ok', sql: 'CREATE TABLE broken_ok (id TEXT PRIMARY KEY)' },
|
|
2802
2812
|
{ version: '0002-broken', sql: 'CREATE TABLE broken_t (' },
|
|
2803
2813
|
],
|
|
2804
|
-
|
|
2814
|
+
...testOperations({
|
|
2805
2815
|
'broken/act': (() => 'ran'),
|
|
2806
|
-
},
|
|
2816
|
+
}),
|
|
2807
2817
|
};
|
|
2808
2818
|
/**
|
|
2809
2819
|
* #1898: a module whose migration declares a foreign key to a spine table, and its twin whose
|
|
@@ -2832,7 +2842,7 @@ export const spineParentMod = {
|
|
|
2832
2842
|
sql: 'CREATE TABLE lists (id TEXT PRIMARY KEY);\nCREATE TABLE notes (t TEXT REFERENCES/**/"_Substrat_Tuples"(subject));',
|
|
2833
2843
|
},
|
|
2834
2844
|
],
|
|
2835
|
-
|
|
2845
|
+
...testOperations({}),
|
|
2836
2846
|
};
|
|
2837
2847
|
/**
|
|
2838
2848
|
* #2066: migrations that reach for the migration journal — one drops its digest fence, one writes
|
|
@@ -2845,14 +2855,14 @@ export const journalFenceDropMod = {
|
|
|
2845
2855
|
migrations: [
|
|
2846
2856
|
{ version: '0001-init', sql: 'CREATE TABLE jt (id TEXT PRIMARY KEY);\nDROP TRIGGER "_Substrat_Migrations_Digest_Required";' },
|
|
2847
2857
|
],
|
|
2848
|
-
|
|
2858
|
+
...testOperations({}),
|
|
2849
2859
|
};
|
|
2850
2860
|
export const journalWriteMod = {
|
|
2851
2861
|
manifest: foreignKeyModManifest('@test/journal-write'),
|
|
2852
2862
|
migrations: [
|
|
2853
2863
|
{ version: '0001-init', sql: "CREATE TABLE jt (id TEXT PRIMARY KEY);\nDELETE FROM main._substrat_migrations WHERE module_id = 'x';" },
|
|
2854
2864
|
],
|
|
2855
|
-
|
|
2865
|
+
...testOperations({}),
|
|
2856
2866
|
};
|
|
2857
2867
|
/**
|
|
2858
2868
|
* #2066 r3: authored migrations that reach for the rest of the spine — one shadows
|
|
@@ -2864,18 +2874,18 @@ export const spineShadowMod = {
|
|
|
2864
2874
|
migrations: [
|
|
2865
2875
|
{ version: '0001-init', sql: 'CREATE TABLE jt (id TEXT PRIMARY KEY);\nCREATE TEMP TABLE "_Substrat_Tuples" (subject TEXT);' },
|
|
2866
2876
|
],
|
|
2867
|
-
|
|
2877
|
+
...testOperations({}),
|
|
2868
2878
|
};
|
|
2869
2879
|
export const spineDropMod = {
|
|
2870
2880
|
manifest: foreignKeyModManifest('@test/spine-drop'),
|
|
2871
2881
|
migrations: [{ version: '0001-init', sql: 'CREATE TABLE jt (id TEXT PRIMARY KEY);\nDROP TABLE main._substrat_outbox;' }],
|
|
2872
|
-
|
|
2882
|
+
...testOperations({}),
|
|
2873
2883
|
};
|
|
2874
2884
|
export const ownParentMod = {
|
|
2875
2885
|
manifest: foreignKeyModManifest('@test/own-parent'),
|
|
2876
2886
|
migrations: [
|
|
2877
2887
|
{ version: '0001-init', sql: 'CREATE TABLE lists (id TEXT PRIMARY KEY);\nCREATE TABLE notes (t TEXT REFERENCES lists(id));' },
|
|
2878
2888
|
],
|
|
2879
|
-
|
|
2889
|
+
...testOperations({}),
|
|
2880
2890
|
};
|
|
2881
2891
|
//# sourceMappingURL=modules.js.map
|