@voltro/testing 0.80.0 → 0.82.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/CHANGELOG.md +1610 -6
- package/THIRD-PARTY-NOTICES.md +1 -1
- package/dist/index.d.ts +151 -6
- package/dist/index.js +358 -186
- package/dist/platform.d.ts +14 -0
- package/dist/platform.js +46 -0
- package/package.json +13 -8
package/dist/index.js
CHANGED
|
@@ -1,64 +1,68 @@
|
|
|
1
1
|
import { AUTO_FILLED_COLUMNS as e, allRegisteredTables as t, changeDelete as n, changeInsert as r, changeSoftDelete as i, changeUpdate as a, clearRelationsRegistry as o, missingRequiredColumns as s, registerRelations as c } from "@voltro/database";
|
|
2
2
|
import { Cause as l, Effect as u, Either as d, Exit as f, Layer as p, Schema as m } from "effect";
|
|
3
|
-
import {
|
|
4
|
-
import { EventBus as
|
|
5
|
-
import { installEnvSnapshot as
|
|
6
|
-
import
|
|
7
|
-
import { describe as
|
|
8
|
-
import { collectPublicApiRoutes as
|
|
9
|
-
import { createLogger as
|
|
10
|
-
import {
|
|
3
|
+
import { ApiUnavailable as h, SubjectService as g, anonymousSubject as _, checkGuardsEffect as v, composeAuthStrategies as y, composeRpcInterceptors as b, eventRoute as x, systemSubject as S, tenantScopedSubject as ee } from "@voltro/protocol";
|
|
4
|
+
import { EventBus as te, InMemoryDataStore as ne, NO_ROW_FILTER as C, apiBindingTokenEnv as re, apiBindingUrlEnv as ie, appValidation as ae, applyRowFilterToDescriptor as oe, clearSystemStoreHandle as se, getFieldCipher as ce, getRowFilter as w, getSystemStoreHandle as le, makeAppAccess as ue, makeConnectionState as de, makeDataLoader as fe, makeEffectStoreLayer as T, makeEventPublisher as pe, makeFieldCipher as me, makeOutboxFacade as he, makeSchemaRegistry as ge, mintServiceToken as _e, publishEvent as ve, resolveRequestClientAddress as ye, resolveRowFilterScopeFor as be, resolveTransactionSubject as xe, resolveTrustedProxies as Se, runProvidedEffect as E, runWithDeadlockRetry as Ce, serviceCallerTokenEnv as we, setFieldCipher as Te, setSystemStoreHandle as D, wrapStoreWithMixinBehaviour as O } from "@voltro/runtime";
|
|
5
|
+
import { installEnvSnapshot as Ee } from "@voltro/env";
|
|
6
|
+
import k from "node:net";
|
|
7
|
+
import { describe as De } from "vitest";
|
|
8
|
+
import { collectPublicApiRoutes as Oe, dispatchSharedPath as ke, restRoutesToHttpRoutes as Ae } from "@voltro/protocol/rest";
|
|
9
|
+
import { createLogger as je } from "@voltro/logger";
|
|
10
|
+
import { randomBytes as Me } from "node:crypto";
|
|
11
|
+
import { CurrentWorkflowRunId as Ne, getWorkflowJournalCipher as Pe, inMemoryWorkflowEngineLayer as Fe, makeInMemoryRecorder as Ie, setWorkflowJournalCipher as Le } from "@voltro/workflow";
|
|
12
|
+
import { spawn as Re } from "node:child_process";
|
|
13
|
+
import { createRequire as ze } from "node:module";
|
|
14
|
+
import { dirname as Be, join as A } from "node:path";
|
|
11
15
|
//#region src/fixtureRow.ts
|
|
12
|
-
var
|
|
16
|
+
var Ve = new Set(e), j = 0, M = () => ++j, He = (e, t) => {
|
|
13
17
|
if (t.oneOf && t.oneOf.length > 0) return t.oneOf[0];
|
|
14
18
|
if (t.enumValues && t.enumValues.length > 0) return t.enumValues[0];
|
|
15
19
|
let n = t.unique === !0;
|
|
16
20
|
switch (t.type) {
|
|
17
21
|
case "text":
|
|
18
22
|
case "id":
|
|
19
|
-
case "enum": return n ? `${e}-${++
|
|
20
|
-
case "reference": return t.referenceStorage === "numeric" ? n ? ++
|
|
23
|
+
case "enum": return n ? `${e}-${++j}` : e;
|
|
24
|
+
case "reference": return t.referenceStorage === "numeric" ? n ? ++j : 0 : n ? `${e}-${++j}` : e;
|
|
21
25
|
case "integer":
|
|
22
|
-
case "real": return n ? ++
|
|
26
|
+
case "real": return n ? ++j : 0;
|
|
23
27
|
case "decimal":
|
|
24
|
-
case "bigint": return n ? String(++
|
|
28
|
+
case "bigint": return n ? String(++j) : "0";
|
|
25
29
|
case "boolean": return !1;
|
|
26
30
|
case "timestamp":
|
|
27
31
|
case "date": return /* @__PURE__ */ new Date(0);
|
|
28
32
|
default: throw Error(`fixtureRow: column '${e}' is a required '${t.type}' with no default, and fixtureRow can't synthesize a safe placeholder for that type. Pass it explicitly: fixtureRow(table, { ${e}: … }).`);
|
|
29
33
|
}
|
|
30
|
-
},
|
|
34
|
+
}, N = (e, t = {}) => {
|
|
31
35
|
let n = {};
|
|
32
|
-
for (let r of s(e, t))
|
|
36
|
+
for (let r of s(e, t)) Ve.has(r) || (n[r] = He(r, e.fields[r]));
|
|
33
37
|
return {
|
|
34
38
|
...n,
|
|
35
39
|
...t
|
|
36
40
|
};
|
|
37
|
-
},
|
|
38
|
-
if (typeof e != "string" || !
|
|
39
|
-
let n = e.slice(0, 10), r =
|
|
41
|
+
}, P = m.decodeUnknownEither(m.DateFromString), Ue = /^\d{4}-\d{2}-\d{2}$/, We = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/, Ge = (e, t) => {
|
|
42
|
+
if (typeof e != "string" || !We.test(e) && !(t === "date" && Ue.test(e))) return !1;
|
|
43
|
+
let n = e.slice(0, 10), r = P(n);
|
|
40
44
|
return d.isRight(r) && Number.isFinite(r.right.getTime()) && r.right.toISOString().slice(0, 10) === n;
|
|
41
|
-
},
|
|
45
|
+
}, Ke = (e, t) => {
|
|
42
46
|
let n = Object.entries(e.fields).filter(([, e]) => e.type === "timestamp" || e.type === "date");
|
|
43
47
|
return t.map((t, r) => {
|
|
44
48
|
let i = { ...t };
|
|
45
49
|
for (let [a, o] of n) {
|
|
46
50
|
let n = t[a];
|
|
47
51
|
if (n == null || n instanceof Date && Number.isFinite(n.getTime())) continue;
|
|
48
|
-
let s =
|
|
49
|
-
if (!
|
|
52
|
+
let s = P(n);
|
|
53
|
+
if (!Ge(n, o.type) || d.isLeft(s) || !Number.isFinite(s.right.getTime())) throw TypeError(`hydrateFixtureRows: table '${e.tableName}', row ${r}, column '${a}' requires a valid Date or ISO date-time with Z or an offset${o.type === "date" ? " (YYYY-MM-DD is also accepted as UTC midnight)" : ""}.`);
|
|
50
54
|
i[a] = s.right;
|
|
51
55
|
}
|
|
52
56
|
return i;
|
|
53
57
|
});
|
|
54
|
-
},
|
|
58
|
+
}, qe = (e) => {
|
|
55
59
|
let t = {};
|
|
56
|
-
for (let [n, r] of Object.entries(e)) t[n] = typeof r == "function" ? r(
|
|
60
|
+
for (let [n, r] of Object.entries(e)) t[n] = typeof r == "function" ? r(M()) : r;
|
|
57
61
|
return t;
|
|
58
|
-
},
|
|
62
|
+
}, Je = (e) => {
|
|
59
63
|
for (let [t, n] of Object.entries(e.fields)) if (n.type === "id") return t;
|
|
60
64
|
return "id";
|
|
61
|
-
},
|
|
65
|
+
}, Ye = async (e, t, n, r, i) => {
|
|
62
66
|
let a = {};
|
|
63
67
|
for (let o of s(t, n)) {
|
|
64
68
|
let n = t.fields[o];
|
|
@@ -66,29 +70,29 @@ var Oe = new Set(e), k = 0, A = () => ++k, ke = (e, t) => {
|
|
|
66
70
|
let s = n.references();
|
|
67
71
|
if (i.includes(s.tableName)) throw Error(`defineFactory: creating '${t.tableName}' requires '${s.tableName}' via '${o}', and that reference is cyclic (${[...i, s.tableName].join(" → ")}). Insert one side first and pass the id: create(store, { ${o}: existing.id }).`);
|
|
68
72
|
let c = r[o];
|
|
69
|
-
a[o] = (c === void 0 ? await
|
|
73
|
+
a[o] = (c === void 0 ? await F(e, s, {}, {}, [...i, s.tableName]) : await c.create(e, {}))[n.referenceColumn ?? Je(s)];
|
|
70
74
|
}
|
|
71
75
|
return a;
|
|
72
|
-
},
|
|
76
|
+
}, F = async (e, t, n, r, i) => {
|
|
73
77
|
let a = {
|
|
74
|
-
...await
|
|
78
|
+
...await Ye(e, t, n, r, i),
|
|
75
79
|
...n
|
|
76
80
|
};
|
|
77
|
-
return e.insert(t.tableName,
|
|
78
|
-
},
|
|
81
|
+
return e.insert(t.tableName, N(t, a));
|
|
82
|
+
}, Xe = (e, t) => typeof e == "function" ? e(t) : e ?? {}, Ze = (e, t = {}) => {
|
|
79
83
|
let n = t.traits ?? {}, r = t.associations ?? {}, i = (t) => {
|
|
80
84
|
let a = (e = {}) => ({
|
|
81
|
-
...
|
|
85
|
+
...qe(t),
|
|
82
86
|
...e
|
|
83
|
-
}), o = (t = {}) =>
|
|
87
|
+
}), o = (t = {}) => N(e, a(t));
|
|
84
88
|
return {
|
|
85
89
|
table: e,
|
|
86
90
|
build: o,
|
|
87
|
-
buildList: (e, t) => Array.from({ length: e }, (e, n) => o(
|
|
88
|
-
create: (t, n = {}) =>
|
|
91
|
+
buildList: (e, t) => Array.from({ length: e }, (e, n) => o(Xe(t, n))),
|
|
92
|
+
create: (t, n = {}) => F(t, e, a(n), r, [e.tableName]),
|
|
89
93
|
createList: async (t, n, i) => {
|
|
90
94
|
let o = [];
|
|
91
|
-
for (let s = 0; s < n; s++) o.push(await
|
|
95
|
+
for (let s = 0; s < n; s++) o.push(await F(t, e, a(Xe(i, s)), r, [e.tableName]));
|
|
92
96
|
return o;
|
|
93
97
|
},
|
|
94
98
|
with: (...r) => {
|
|
@@ -110,19 +114,19 @@ var Oe = new Set(e), k = 0, A = () => ++k, ke = (e, t) => {
|
|
|
110
114
|
};
|
|
111
115
|
};
|
|
112
116
|
return i(t.defaults ?? {});
|
|
113
|
-
},
|
|
117
|
+
}, I = Symbol.for("voltro/testing/mockClock.installed"), L = () => globalThis, Qe = (e, t) => new Proxy(e, {
|
|
114
118
|
construct: (e, n, r) => Reflect.construct(e, n.length === 0 ? [t()] : n, r),
|
|
115
119
|
apply: () => new e(t()).toString(),
|
|
116
120
|
get: (e, n, r) => n === "now" ? () => t() : Reflect.get(e, n, r)
|
|
117
|
-
}),
|
|
121
|
+
}), R = (e) => {
|
|
118
122
|
if (typeof e == "number") return e;
|
|
119
123
|
let t = e instanceof Date ? e.getTime() : Date.parse(e);
|
|
120
124
|
if (Number.isNaN(t)) throw Error(`mockClock: cannot read an instant from '${String(e)}'`);
|
|
121
125
|
return t;
|
|
122
|
-
},
|
|
126
|
+
}, z = class {
|
|
123
127
|
currentMs;
|
|
124
128
|
constructor(e = "2026-01-01T00:00:00Z") {
|
|
125
|
-
this.currentMs =
|
|
129
|
+
this.currentMs = R(e);
|
|
126
130
|
}
|
|
127
131
|
now() {
|
|
128
132
|
return this.currentMs;
|
|
@@ -131,47 +135,47 @@ var Oe = new Set(e), k = 0, A = () => ++k, ke = (e, t) => {
|
|
|
131
135
|
return new Date(this.currentMs);
|
|
132
136
|
}
|
|
133
137
|
advance(e) {
|
|
134
|
-
this.currentMs += typeof e == "number" ? e :
|
|
138
|
+
this.currentMs += typeof e == "number" ? e : nt(e);
|
|
135
139
|
}
|
|
136
140
|
set(e) {
|
|
137
|
-
this.currentMs =
|
|
141
|
+
this.currentMs = R(e);
|
|
138
142
|
}
|
|
139
143
|
get installed() {
|
|
140
|
-
return
|
|
144
|
+
return L()[I]?.clock === this;
|
|
141
145
|
}
|
|
142
146
|
install() {
|
|
143
|
-
let e =
|
|
147
|
+
let e = L(), t = e[I];
|
|
144
148
|
if (t !== void 0) throw Error("mockClock: global time is already faked" + (t.clock === this ? " by this same clock" : " by another MockClock") + ". Uninstall it before installing again — a nested install restores the outer fake on the way out, which leaves the realm frozen with nothing pointing at why. `withFrozenTime` always restores, including on a throw.");
|
|
145
149
|
let n = globalThis.Date;
|
|
146
|
-
return e[
|
|
150
|
+
return e[I] = {
|
|
147
151
|
realDate: n,
|
|
148
152
|
clock: this
|
|
149
|
-
}, globalThis.Date =
|
|
153
|
+
}, globalThis.Date = Qe(n, () => this.currentMs), () => {
|
|
150
154
|
this.uninstall();
|
|
151
155
|
};
|
|
152
156
|
}
|
|
153
157
|
uninstall() {
|
|
154
|
-
let e =
|
|
155
|
-
t !== void 0 && t.clock === this && (globalThis.Date = t.realDate, delete e[
|
|
158
|
+
let e = L(), t = e[I];
|
|
159
|
+
t !== void 0 && t.clock === this && (globalThis.Date = t.realDate, delete e[I]);
|
|
156
160
|
}
|
|
157
|
-
},
|
|
158
|
-
let n = e instanceof
|
|
161
|
+
}, $e = (e) => typeof e == "object" && !!e && typeof e.then == "function", et = (e, t) => {
|
|
162
|
+
let n = e instanceof z ? e : new z(e);
|
|
159
163
|
n.install();
|
|
160
164
|
let r = !1;
|
|
161
165
|
try {
|
|
162
166
|
let e = t(n);
|
|
163
|
-
return
|
|
167
|
+
return $e(e) ? (r = !0, e.then((e) => (n.uninstall(), e), (e) => {
|
|
164
168
|
throw n.uninstall(), e;
|
|
165
169
|
})) : e;
|
|
166
170
|
} finally {
|
|
167
171
|
r || n.uninstall();
|
|
168
172
|
}
|
|
169
|
-
},
|
|
170
|
-
let t = e instanceof
|
|
173
|
+
}, tt = (e) => u.acquireRelease(u.sync(() => {
|
|
174
|
+
let t = e instanceof z ? e : new z(e);
|
|
171
175
|
return t.install(), t;
|
|
172
176
|
}), (e) => u.sync(() => {
|
|
173
177
|
e.uninstall();
|
|
174
|
-
})),
|
|
178
|
+
})), nt = (e) => {
|
|
175
179
|
let t = /^\s*(\d+(?:\.\d+)?)\s*(ms|s|m|h|d)\s*$/.exec(e);
|
|
176
180
|
if (!t) throw Error(`mockClock: cannot parse duration '${e}'`);
|
|
177
181
|
let n = Number(t[1]), r = t[2];
|
|
@@ -183,16 +187,19 @@ var Oe = new Set(e), k = 0, A = () => ++k, ke = (e, t) => {
|
|
|
183
187
|
case "d": return n * 864e5;
|
|
184
188
|
default: throw Error(`mockClock: unknown unit '${r}'`);
|
|
185
189
|
}
|
|
186
|
-
},
|
|
190
|
+
}, B = class {
|
|
187
191
|
emitted = [];
|
|
188
192
|
async emit(e, t) {
|
|
189
|
-
let n = typeof e == "string" ? e : e.id ?? e.event ?? "(unnamed event)";
|
|
193
|
+
let n = typeof e == "string" ? e : e.name ?? e.id ?? e.event ?? "(unnamed event)";
|
|
190
194
|
return this.emitted.push({
|
|
191
195
|
event: n,
|
|
192
196
|
payload: t,
|
|
193
197
|
emittedAt: /* @__PURE__ */ new Date()
|
|
194
198
|
}), { delivered: 0 };
|
|
195
199
|
}
|
|
200
|
+
async listTargets(e, t) {
|
|
201
|
+
return [];
|
|
202
|
+
}
|
|
196
203
|
payloadsFor(e) {
|
|
197
204
|
return this.emitted.filter((t) => t.event === e).map((e) => e.payload);
|
|
198
205
|
}
|
|
@@ -202,14 +209,14 @@ var Oe = new Set(e), k = 0, A = () => ++k, ke = (e, t) => {
|
|
|
202
209
|
clear() {
|
|
203
210
|
this.emitted.length = 0;
|
|
204
211
|
}
|
|
205
|
-
},
|
|
206
|
-
let t = e.tenantId ?? null, n = new
|
|
212
|
+
}, V = (e = {}) => {
|
|
213
|
+
let t = e.tenantId ?? null, n = new te({
|
|
207
214
|
origin: e.origin ?? "test",
|
|
208
215
|
...e.ringSize === void 0 ? {} : { ringSize: e.ringSize }
|
|
209
216
|
});
|
|
210
217
|
return {
|
|
211
218
|
publish: async (e, r, i) => {
|
|
212
|
-
let a = await u.runPromise(u.either(
|
|
219
|
+
let a = await u.runPromise(u.either(ve({
|
|
213
220
|
bus: n,
|
|
214
221
|
tenantId: t
|
|
215
222
|
}, e, r, i)));
|
|
@@ -258,7 +265,7 @@ var Oe = new Set(e), k = 0, A = () => ++k, ke = (e, t) => {
|
|
|
258
265
|
},
|
|
259
266
|
skipSerials: (e, r, i, a) => {
|
|
260
267
|
let o = a?.tenantId ?? t, s = {
|
|
261
|
-
route:
|
|
268
|
+
route: x(o, e.name, r),
|
|
262
269
|
event: e.name,
|
|
263
270
|
origin: "test-gap",
|
|
264
271
|
n: i + 1,
|
|
@@ -272,7 +279,7 @@ var Oe = new Set(e), k = 0, A = () => ++k, ke = (e, t) => {
|
|
|
272
279
|
n.clear();
|
|
273
280
|
}
|
|
274
281
|
};
|
|
275
|
-
},
|
|
282
|
+
}, H = class {
|
|
276
283
|
queue;
|
|
277
284
|
calls = [];
|
|
278
285
|
constructor(e) {
|
|
@@ -287,38 +294,41 @@ var Oe = new Set(e), k = 0, A = () => ++k, ke = (e, t) => {
|
|
|
287
294
|
remaining() {
|
|
288
295
|
return this.queue.length;
|
|
289
296
|
}
|
|
290
|
-
},
|
|
291
|
-
let n =
|
|
297
|
+
}, rt = (e) => e, U = "00000000000000000000000000000000", W = /* @__PURE__ */ new WeakMap(), G = /* @__PURE__ */ new WeakMap(), it = (e, t) => {
|
|
298
|
+
let n = G.get(e);
|
|
292
299
|
if (n === void 0) throw Error("withRpcConnection requires a context created by makeTestContext");
|
|
293
300
|
return n(t);
|
|
294
|
-
},
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
301
|
+
}, K = /* @__PURE__ */ new WeakMap(), q = /* @__PURE__ */ new WeakMap(), J = /* @__PURE__ */ new WeakMap(), Y = (e) => J.get(e) ?? [], X = /* @__PURE__ */ new WeakMap(), Z = (e, t, n) => {
|
|
302
|
+
X.set(e, {
|
|
303
|
+
publicApi: t,
|
|
304
|
+
...n === void 0 ? {} : { remoteAddr: n }
|
|
305
|
+
});
|
|
306
|
+
}, at = (e) => X.get(e), ot = /* @__PURE__ */ new WeakMap(), st = (e, t) => {
|
|
307
|
+
let n = J.get(e) ?? [], r = t === "mutation" ? "interceptMutation" : t === "query" ? "interceptQuery" : "interceptAction", i = [];
|
|
298
308
|
for (let e of n) {
|
|
299
309
|
let t = e[r];
|
|
300
310
|
typeof t == "function" && i.push(t);
|
|
301
311
|
}
|
|
302
|
-
return
|
|
303
|
-
},
|
|
304
|
-
let t = (
|
|
312
|
+
return b(i);
|
|
313
|
+
}, ct = (e) => {
|
|
314
|
+
let t = (J.get(e) ?? []).map((e) => e.services).filter((e) => e !== void 0), n = ot.get(e) ?? [], r = [...t, ...n];
|
|
305
315
|
if (r.length !== 0) return p.mergeAll(...r);
|
|
306
|
-
},
|
|
307
|
-
let t =
|
|
316
|
+
}, lt = (e) => {
|
|
317
|
+
let t = K.get(e);
|
|
308
318
|
t !== void 0 && (t.length = 0);
|
|
309
|
-
},
|
|
310
|
-
let t =
|
|
319
|
+
}, Q = async (e) => {
|
|
320
|
+
let t = K.get(e);
|
|
311
321
|
if (t === void 0 || t.length === 0) return;
|
|
312
322
|
let n = [...t];
|
|
313
323
|
t.length = 0;
|
|
314
324
|
for (let e of n) await e();
|
|
315
|
-
},
|
|
316
|
-
let n =
|
|
325
|
+
}, ut = (e) => q.get(e) ?? [], dt = async (e, t) => {
|
|
326
|
+
let n = W.get(e);
|
|
317
327
|
return n === void 0 ? e.store.transactional(async (n) => t({
|
|
318
328
|
...e,
|
|
319
329
|
store: n
|
|
320
330
|
})) : n(t);
|
|
321
|
-
},
|
|
331
|
+
}, ft = (e) => {
|
|
322
332
|
let t = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map(), r = (n) => {
|
|
323
333
|
let r = t.get(n);
|
|
324
334
|
return r === void 0 ? !1 : r.expiresAt !== null && r.expiresAt <= e() ? (t.delete(n), !1) : !0;
|
|
@@ -357,7 +367,7 @@ var Oe = new Set(e), k = 0, A = () => ++k, ke = (e, t) => {
|
|
|
357
367
|
return i(e, o, n.ttlMs, n.tags), o;
|
|
358
368
|
}
|
|
359
369
|
};
|
|
360
|
-
},
|
|
370
|
+
}, pt = (e) => {
|
|
361
371
|
let t = /* @__PURE__ */ new Map(), n = (n) => {
|
|
362
372
|
let r = t.get(n);
|
|
363
373
|
return r === void 0 ? !1 : r.expiresAt !== null && r.expiresAt <= e() ? (t.delete(n), !1) : !0;
|
|
@@ -385,47 +395,49 @@ var Oe = new Set(e), k = 0, A = () => ++k, ke = (e, t) => {
|
|
|
385
395
|
t.clear();
|
|
386
396
|
}
|
|
387
397
|
};
|
|
388
|
-
},
|
|
389
|
-
let n =
|
|
398
|
+
}, mt = async (e, t) => {
|
|
399
|
+
let n = le();
|
|
390
400
|
D(e);
|
|
391
401
|
try {
|
|
392
402
|
return await t();
|
|
393
403
|
} finally {
|
|
394
|
-
n === void 0 ?
|
|
404
|
+
n === void 0 ? se() : D(n);
|
|
395
405
|
}
|
|
396
|
-
},
|
|
397
|
-
|
|
398
|
-
},
|
|
399
|
-
let r =
|
|
406
|
+
}, ht = /* @__PURE__ */ new Set(), gt = (e) => {
|
|
407
|
+
ht.has(e) || (ht.add(e), console.warn(e));
|
|
408
|
+
}, _t = (e, t, n) => {
|
|
409
|
+
let r = vt, i;
|
|
400
410
|
return () => {
|
|
401
411
|
let a = t ?? w();
|
|
402
|
-
return t !== void 0 && w() !== void 0 && t !== w() &&
|
|
412
|
+
return t !== void 0 && w() !== void 0 && t !== w() && gt("[voltro:testing] this test passes `rowFilter:` while a DIFFERENT filter is registered via `setRowFilter`. The option wins, so this test does not exercise your app's registration. Drop `rowFilter:` to run the real process-global one."), (i === void 0 || a !== r) && (r = a, i = mt(n, () => E(be(a, e, (e) => {
|
|
403
413
|
console.error("[voltro:testing] row filter failed to load — reads refused for this subject", e);
|
|
404
414
|
})))), i;
|
|
405
415
|
};
|
|
406
|
-
},
|
|
407
|
-
if (n === "query") return async (n) => e.query(
|
|
416
|
+
}, vt = Symbol("unresolved"), yt = (e, t) => new Proxy(e, { get: (e, n) => {
|
|
417
|
+
if (n === "query") return async (n) => e.query(oe(await t(), n));
|
|
408
418
|
let r = Reflect.get(e, n, e);
|
|
409
419
|
return typeof r == "function" ? r.bind(e) : r;
|
|
410
|
-
} }),
|
|
411
|
-
if (
|
|
420
|
+
} }), bt = (e = {}) => {
|
|
421
|
+
if (Ee({
|
|
412
422
|
...process.env,
|
|
413
423
|
...e.env ?? {}
|
|
414
|
-
}), e.fieldEncryptionKey !== void 0 &&
|
|
424
|
+
}), e.fieldEncryptionKey !== void 0 && Te(me(e.fieldEncryptionKey)), e.relations !== void 0) {
|
|
415
425
|
o();
|
|
416
426
|
for (let t of e.relations) c(t);
|
|
417
427
|
}
|
|
418
|
-
let n = e.tables ?? t(), r =
|
|
428
|
+
let n = e.tables ?? t(), r = ge(n), i = new ne(e.store ?? {});
|
|
429
|
+
for (let t of e.plugins ?? []) t.bindDataStore?.(i);
|
|
430
|
+
let a = {
|
|
419
431
|
dataStore: i,
|
|
420
432
|
schemaRegistry: r
|
|
421
433
|
};
|
|
422
434
|
D(a);
|
|
423
|
-
let s = new
|
|
435
|
+
let s = new z(e.clockStart), l = new B(), u = V(), d = new H(e.llmResponses ?? []), f = ft(() => s.now()), p = pt(() => s.now()), m = (t, n, o = i, c, h = !1) => {
|
|
424
436
|
let g = {
|
|
425
437
|
subject: t,
|
|
426
|
-
traceId:
|
|
438
|
+
traceId: U,
|
|
427
439
|
...n === void 0 ? {} : { connection: n }
|
|
428
|
-
}, _ = c?.queued ?? [], v = c?.nudges ?? [], y =
|
|
440
|
+
}, _ = c?.queued ?? [], v = c?.nudges ?? [], y = pe({
|
|
429
441
|
bus: u.bus,
|
|
430
442
|
tenantId: t.tenantId ?? null,
|
|
431
443
|
...o === i ? {} : { deferToCommit: (e) => {
|
|
@@ -433,9 +445,10 @@ var Oe = new Set(e), k = 0, A = () => ++k, ke = (e, t) => {
|
|
|
433
445
|
e();
|
|
434
446
|
});
|
|
435
447
|
} }
|
|
436
|
-
}), b =
|
|
448
|
+
}), b = fe({ store: o }), x = h ? async () => C : _t(t, e.rowFilter, a), S = {
|
|
449
|
+
apis: e.apis ?? Object.freeze({}),
|
|
437
450
|
transaction: async (e, r) => {
|
|
438
|
-
let a =
|
|
451
|
+
let a = xe(t, r?.tenantId, o !== i);
|
|
439
452
|
if (a !== t) return m(a, n, i, void 0, !0).transaction(e);
|
|
440
453
|
if (o !== i) return e(S);
|
|
441
454
|
let s, c = await o.transactional(async (r) => {
|
|
@@ -445,7 +458,7 @@ var Oe = new Set(e), k = 0, A = () => ++k, ke = (e, t) => {
|
|
|
445
458
|
}, h), a = await e(i);
|
|
446
459
|
return s = i, a;
|
|
447
460
|
});
|
|
448
|
-
return s !== void 0 && (await
|
|
461
|
+
return s !== void 0 && (await Q(s), v.push(...ut(s))), c;
|
|
449
462
|
},
|
|
450
463
|
clock: s,
|
|
451
464
|
webhooks: l,
|
|
@@ -454,29 +467,29 @@ var Oe = new Set(e), k = 0, A = () => ++k, ke = (e, t) => {
|
|
|
454
467
|
llm: d,
|
|
455
468
|
...e.ai === void 0 ? {} : { ai: e.ai },
|
|
456
469
|
request: g,
|
|
457
|
-
...n === void 0 ? {} : { connectionState:
|
|
470
|
+
...n === void 0 ? {} : { connectionState: de(n, o === i ? void 0 : (e) => {
|
|
458
471
|
_.push(e);
|
|
459
472
|
}) },
|
|
460
|
-
validation:
|
|
461
|
-
access:
|
|
473
|
+
validation: ae,
|
|
474
|
+
access: ue(t),
|
|
462
475
|
cache: f,
|
|
463
476
|
kv: p,
|
|
464
|
-
store: O(
|
|
477
|
+
store: O(yt(o, x), {
|
|
465
478
|
subject: t,
|
|
466
479
|
schemaRegistry: r,
|
|
467
480
|
rowFilter: C
|
|
468
481
|
}),
|
|
469
|
-
storeForTenant: (e) => O(
|
|
482
|
+
storeForTenant: (e) => O(yt(o, x), {
|
|
470
483
|
subject: ee(t, e),
|
|
471
484
|
schemaRegistry: r,
|
|
472
485
|
rowFilter: C
|
|
473
486
|
}),
|
|
474
|
-
outbox:
|
|
487
|
+
outbox: he({
|
|
475
488
|
store: o,
|
|
476
489
|
subject: t,
|
|
477
|
-
traceId:
|
|
490
|
+
traceId: U,
|
|
478
491
|
nudge: () => {
|
|
479
|
-
v.push(
|
|
492
|
+
v.push(U);
|
|
480
493
|
},
|
|
481
494
|
afterCommit: (e) => {
|
|
482
495
|
_.push(e);
|
|
@@ -507,37 +520,37 @@ var Oe = new Set(e), k = 0, A = () => ++k, ke = (e, t) => {
|
|
|
507
520
|
nudges: v
|
|
508
521
|
})
|
|
509
522
|
};
|
|
510
|
-
return
|
|
523
|
+
return K.set(S, _), G.set(S, (e) => m(t, e, o, {
|
|
511
524
|
queued: _,
|
|
512
525
|
nudges: v
|
|
513
|
-
})),
|
|
526
|
+
})), q.set(S, v), J.set(S, e.plugins ?? []), ot.set(S, e.layers ?? []), W.set(S, (e) => o.transactional((r) => e(m(t, n, r, {
|
|
514
527
|
queued: _,
|
|
515
528
|
nudges: v
|
|
516
529
|
})))), S;
|
|
517
530
|
};
|
|
518
|
-
return m(e.subject ??
|
|
519
|
-
},
|
|
520
|
-
let n =
|
|
521
|
-
return (n === void 0 ? e : u.provide(e, n)).pipe(u.provide(T(t.store)), u.provideService(
|
|
522
|
-
},
|
|
531
|
+
return m(e.subject ?? _(null), e.connection);
|
|
532
|
+
}, xt = (e, t) => {
|
|
533
|
+
let n = ct(t);
|
|
534
|
+
return (n === void 0 ? e : u.provide(e, n)).pipe(u.provide(T(t.store)), u.provideService(g, t.request.subject));
|
|
535
|
+
}, St = async (e, t, n, r) => {
|
|
523
536
|
let i = e.input, a = await m.decodeUnknownPromise(i)(n), o = e.kind, s = async (e) => {
|
|
524
537
|
let n = t(a, e);
|
|
525
|
-
return u.isEffect(n) ? E(
|
|
538
|
+
return u.isEffect(n) ? E(xt(n, e)) : n;
|
|
526
539
|
}, c = async () => {
|
|
527
540
|
let t = e.guards;
|
|
528
541
|
if (t !== void 0 && t.length > 0) {
|
|
529
|
-
let e = await u.runPromise(
|
|
542
|
+
let e = await u.runPromise(v(r.request.subject, t, a));
|
|
530
543
|
if (e !== null) throw e;
|
|
531
544
|
}
|
|
532
545
|
if (o !== "mutation") return s(r);
|
|
533
|
-
let n = await
|
|
534
|
-
return await
|
|
535
|
-
}, d = o === "mutation" || o === "query" || o === "action" ? o : void 0, p = d === void 0 ? void 0 :
|
|
546
|
+
let n = await Ce(async () => dt(r, async (e) => (lt(r), s(e))), { delay: () => Promise.resolve() });
|
|
547
|
+
return await Q(r), n;
|
|
548
|
+
}, d = o === "mutation" || o === "query" || o === "action" ? o : void 0, p = d === void 0 ? void 0 : st(r, d);
|
|
536
549
|
if (p === void 0 || d === void 0) return await c();
|
|
537
550
|
let h = u.tryPromise({
|
|
538
551
|
try: () => c(),
|
|
539
552
|
catch: (e) => e
|
|
540
|
-
}), g =
|
|
553
|
+
}), g = at(r), _ = p(h, {
|
|
541
554
|
tag: e.name ?? "",
|
|
542
555
|
kind: d,
|
|
543
556
|
input: a,
|
|
@@ -547,16 +560,17 @@ var Oe = new Set(e), k = 0, A = () => ++k, ke = (e, t) => {
|
|
|
547
560
|
...g === void 0 ? {} : {
|
|
548
561
|
surface: "rest",
|
|
549
562
|
publicApi: g.publicApi
|
|
550
|
-
}
|
|
551
|
-
|
|
563
|
+
},
|
|
564
|
+
...g?.remoteAddr === void 0 ? {} : { remoteAddr: g.remoteAddr }
|
|
565
|
+
}), y = await u.runPromiseExit(_);
|
|
552
566
|
if (f.isSuccess(y)) return y.value;
|
|
553
567
|
throw l.squash(y.cause);
|
|
554
|
-
},
|
|
555
|
-
let n = new
|
|
568
|
+
}, Ct = (e) => new Promise((t) => {
|
|
569
|
+
let n = new k.Socket(), r = (e) => {
|
|
556
570
|
clearTimeout(i), n.destroy(), t(e);
|
|
557
571
|
}, i = setTimeout(() => r(!1), e.timeoutMs ?? 750);
|
|
558
572
|
n.once("connect", () => r(!0)), n.once("error", () => r(!1)), n.connect(e.port, e.host);
|
|
559
|
-
}),
|
|
573
|
+
}), wt = async (e, t, n, r) => {
|
|
560
574
|
if (typeof t != "string" || typeof n != "function" || typeof r != "function") throw TypeError(`describeIfAvailable('${e}', ...): expected (label, dependency, probe, suite) — got dependency: ${typeof t}, probe: ${typeof n}, suite: ${typeof r}. Three arguments means the suite body is being used as the probe: it would run at file scope, unconditionally, and the skip would silently do nothing.`);
|
|
561
575
|
let i = !1;
|
|
562
576
|
try {
|
|
@@ -564,21 +578,21 @@ var Oe = new Set(e), k = 0, A = () => ++k, ke = (e, t) => {
|
|
|
564
578
|
} catch {
|
|
565
579
|
i = !1;
|
|
566
580
|
}
|
|
567
|
-
|
|
568
|
-
},
|
|
569
|
-
await
|
|
570
|
-
},
|
|
581
|
+
De.skipIf(!i)(i ? e : `${e} [SKIPPED: needs ${t}]`, r);
|
|
582
|
+
}, Tt = async (e, t, n) => {
|
|
583
|
+
await wt(e, `${t.name} at ${t.host}:${t.port}`, () => Ct(t), n);
|
|
584
|
+
}, Et = async (e, t) => {
|
|
571
585
|
try {
|
|
572
586
|
let n = await t();
|
|
573
587
|
n !== void 0 && n !== "" && console.log(`[engine] ${e}: ${n}`);
|
|
574
588
|
} catch {}
|
|
575
|
-
},
|
|
589
|
+
}, Dt = "test-tenant", $ = (e, t, n) => ({
|
|
576
590
|
type: e,
|
|
577
591
|
id: t,
|
|
578
592
|
tenantId: n.tenantId ?? "test-tenant",
|
|
579
593
|
scopes: n.scopes ?? [],
|
|
580
594
|
...n.metadata === void 0 ? {} : { metadata: n.metadata }
|
|
581
|
-
}),
|
|
595
|
+
}), Ot = (e, t = {}) => $("user", e, t), kt = (e, t = {}) => $("apiKey", e, t), At = (e, t = {}) => $("serviceAccount", e, t), jt = (e = null) => _(e), Mt = (e = "job:test", t) => t === void 0 ? S(e) : S(e, t), Nt = "127.0.0.1", Pt = (e) => {
|
|
582
596
|
let t = e.indexOf("?");
|
|
583
597
|
return t === -1 ? {
|
|
584
598
|
path: e,
|
|
@@ -587,105 +601,110 @@ var Oe = new Set(e), k = 0, A = () => ++k, ke = (e, t) => {
|
|
|
587
601
|
path: e.slice(0, t),
|
|
588
602
|
query: e.slice(t + 1)
|
|
589
603
|
};
|
|
590
|
-
},
|
|
604
|
+
}, Ft = (e, t) => {
|
|
591
605
|
let n = e.split("/").filter((e) => e.length > 0), r = t.split("/").filter((e) => e.length > 0);
|
|
592
606
|
return n.length === r.length && n.every((e, t) => e.startsWith(":") || e === r[t]);
|
|
593
|
-
},
|
|
607
|
+
}, It = (e) => {
|
|
594
608
|
let t = {};
|
|
595
609
|
for (let [n, r] of Object.entries(e)) t[n.toLowerCase()] = r;
|
|
596
610
|
return t;
|
|
597
|
-
},
|
|
598
|
-
let { ctx:
|
|
611
|
+
}, Lt = (e) => e === void 0 ? /* @__PURE__ */ new Uint8Array() : new TextEncoder().encode(JSON.stringify(e)), Rt = (e) => e === void 0 ? "" : typeof e == "string" ? e : new TextDecoder().decode(e), zt = (e) => {
|
|
612
|
+
let t = Se(e.security?.trustedProxies, process.env, e.security?.clientAddressHeader), { ctx: n } = e, r = Oe((e.publicApi ?? []).map((e) => ({
|
|
599
613
|
descriptor: e.descriptor,
|
|
600
|
-
invoke: (
|
|
614
|
+
invoke: (t, r) => n.withSubject(r.subject, (n) => (e.descriptor.publicApi !== void 0 && Z(n, e.descriptor.publicApi, r.remoteAddr), St(e.descriptor, e.handler, t, n)))
|
|
601
615
|
})), {
|
|
602
|
-
pluginErrors:
|
|
616
|
+
pluginErrors: Y(n).flatMap((e) => e.errorSchemas ?? []),
|
|
603
617
|
...e.publicApiProfile === void 0 ? {} : { profile: e.publicApiProfile }
|
|
604
|
-
}),
|
|
605
|
-
|
|
606
|
-
getStore: () =>
|
|
607
|
-
}),
|
|
608
|
-
let
|
|
609
|
-
store:
|
|
610
|
-
buildContext: () =>
|
|
611
|
-
resolveSubject:
|
|
618
|
+
}), i = [...e.restRoutes ?? [], ...r], a = y(e.strategies ?? [], {
|
|
619
|
+
anonymous: e.anonymous ?? { headerOrTenant: "acme" },
|
|
620
|
+
getStore: () => n.store
|
|
621
|
+
}), o = (r, s) => {
|
|
622
|
+
let c = {
|
|
623
|
+
store: n.store,
|
|
624
|
+
buildContext: () => n,
|
|
625
|
+
resolveSubject: r === void 0 ? async (e) => (await a({
|
|
612
626
|
headers: e,
|
|
613
627
|
clientId: -1
|
|
614
|
-
})).subject : () =>
|
|
628
|
+
})).subject : () => r,
|
|
615
629
|
...e.idempotency === void 0 ? {} : { idempotency: e.idempotency }
|
|
616
|
-
},
|
|
617
|
-
pattern:
|
|
630
|
+
}, l = Ae(i, c).map((e, t) => ({
|
|
631
|
+
pattern: i[t].path,
|
|
618
632
|
route: e
|
|
619
|
-
})),
|
|
620
|
-
let { path:
|
|
621
|
-
if (
|
|
633
|
+
})), u = async (e, r, a = {}) => {
|
|
634
|
+
let { path: o, query: c } = Pt(r), u = l.filter((e) => Ft(e.pattern, o)).map((e) => e.route);
|
|
635
|
+
if (u.length === 0) return {
|
|
622
636
|
status: 404,
|
|
623
637
|
headers: {},
|
|
624
638
|
text: "",
|
|
625
639
|
body: {
|
|
626
640
|
error: "No route mounted for this path",
|
|
627
|
-
mounted:
|
|
641
|
+
mounted: i.map((e) => e.path)
|
|
628
642
|
},
|
|
629
643
|
stream: !1
|
|
630
644
|
};
|
|
631
|
-
let
|
|
645
|
+
let d = {
|
|
646
|
+
...It(s),
|
|
647
|
+
...It(a.headers ?? {})
|
|
648
|
+
}, f = ye({
|
|
649
|
+
socketAddress: a.remoteAddr ?? Nt,
|
|
650
|
+
headers: d,
|
|
651
|
+
config: t
|
|
652
|
+
}), p = {
|
|
632
653
|
method: e.toUpperCase(),
|
|
633
|
-
path:
|
|
634
|
-
query:
|
|
635
|
-
headers:
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
}
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
d.contentType !== void 0 && (f["content-type"] = d.contentType);
|
|
644
|
-
let p = St(d.body), m = (d.contentType ?? "").includes("json");
|
|
654
|
+
path: o,
|
|
655
|
+
query: c,
|
|
656
|
+
headers: d,
|
|
657
|
+
rawBody: Lt(a.body),
|
|
658
|
+
store: n.store,
|
|
659
|
+
...f === void 0 ? {} : { remoteAddr: f }
|
|
660
|
+
}, m = await ke(u, p), h = {};
|
|
661
|
+
for (let [e, t] of Object.entries(m.headers ?? {})) h[e.toLowerCase()] = t;
|
|
662
|
+
m.contentType !== void 0 && (h["content-type"] = m.contentType);
|
|
663
|
+
let g = Rt(m.body), _ = (m.contentType ?? "").includes("json");
|
|
645
664
|
return {
|
|
646
|
-
status:
|
|
647
|
-
headers:
|
|
648
|
-
text:
|
|
649
|
-
body:
|
|
650
|
-
stream:
|
|
665
|
+
status: m.status,
|
|
666
|
+
headers: h,
|
|
667
|
+
text: g,
|
|
668
|
+
body: _ && g !== "" ? JSON.parse(g) : void 0,
|
|
669
|
+
stream: m.stream !== void 0
|
|
651
670
|
};
|
|
652
671
|
};
|
|
653
672
|
return {
|
|
654
|
-
actingAs: (e) =>
|
|
655
|
-
withHeaders: (e) =>
|
|
656
|
-
...
|
|
673
|
+
actingAs: (e) => o(e, s),
|
|
674
|
+
withHeaders: (e) => o(r, {
|
|
675
|
+
...s,
|
|
657
676
|
...e
|
|
658
677
|
}),
|
|
659
|
-
get: (e, t) =>
|
|
660
|
-
delete: (e, t) =>
|
|
661
|
-
post: (e, t, n) =>
|
|
678
|
+
get: (e, t) => u("GET", e, t ?? {}),
|
|
679
|
+
delete: (e, t) => u("DELETE", e, t ?? {}),
|
|
680
|
+
post: (e, t, n) => u("POST", e, {
|
|
662
681
|
...n ?? {},
|
|
663
682
|
body: t
|
|
664
683
|
}),
|
|
665
|
-
put: (e, t, n) =>
|
|
684
|
+
put: (e, t, n) => u("PUT", e, {
|
|
666
685
|
...n ?? {},
|
|
667
686
|
body: t
|
|
668
687
|
}),
|
|
669
|
-
patch: (e, t, n) =>
|
|
688
|
+
patch: (e, t, n) => u("PATCH", e, {
|
|
670
689
|
...n ?? {},
|
|
671
690
|
body: t
|
|
672
691
|
}),
|
|
673
|
-
request: (e, t, n) =>
|
|
674
|
-
paths:
|
|
692
|
+
request: (e, t, n) => u(e, t, n ?? {}),
|
|
693
|
+
paths: i.map((e) => e.path)
|
|
675
694
|
};
|
|
676
695
|
};
|
|
677
|
-
return
|
|
678
|
-
},
|
|
696
|
+
return o(void 0, {});
|
|
697
|
+
}, Bt = (e = {}) => {
|
|
679
698
|
let t = e.id ?? "test", n = e.store ?? new Proxy({}, { get: (e, t) => {
|
|
680
699
|
throw Error(`makeSubscribeContext: this subscriber reached ctx.store.${String(t)} and the test passed no store. Pass \`{ store: makeTestContext().store }\` so the subscriber and the code under test share one — an empty stand-in would let a read of the wrong table pass.`);
|
|
681
700
|
} });
|
|
682
701
|
return {
|
|
683
702
|
id: t,
|
|
684
|
-
log: e.log ??
|
|
703
|
+
log: e.log ?? je({ scope: `subscribe:${t}` }),
|
|
685
704
|
store: n,
|
|
686
705
|
...e.publish === void 0 ? {} : { publish: e.publish }
|
|
687
706
|
};
|
|
688
|
-
},
|
|
707
|
+
}, Vt = (e) => {
|
|
689
708
|
let t = /* @__PURE__ */ new Map();
|
|
690
709
|
for (let n of e) {
|
|
691
710
|
let e = t.get(n.stepName);
|
|
@@ -711,13 +730,18 @@ var Oe = new Set(e), k = 0, A = () => ++k, ke = (e, t) => {
|
|
|
711
730
|
});
|
|
712
731
|
}
|
|
713
732
|
return n.sort((e, t) => e._startedAt - t._startedAt), n.map(({ _startedAt: e, ...t }) => t);
|
|
714
|
-
},
|
|
733
|
+
}, Ht = () => {
|
|
734
|
+
if (Pe() !== void 0) return;
|
|
735
|
+
let e = me(Me(32).toString("hex"));
|
|
736
|
+
Le(() => ce() ?? e);
|
|
737
|
+
}, Ut = (e) => {
|
|
738
|
+
Ht();
|
|
715
739
|
let t = e.workflows ?? [], n = /* @__PURE__ */ new Map(), r = 0;
|
|
716
740
|
return {
|
|
717
741
|
start: async (i, a) => {
|
|
718
742
|
let o = t.find((e) => e.workflow.name === i);
|
|
719
743
|
if (o === void 0) throw Error(`makeWorkflowRunner: no workflow named '${i}' — pass it in makeWorkflowRunner({ ctx, workflows: [{ workflow, execute }] }).`);
|
|
720
|
-
let s = `wfrun_test_${++r}`, c =
|
|
744
|
+
let s = `wfrun_test_${++r}`, c = Ie(), l = o.workflow.toLayer(o.execute).pipe(p.provideMerge(Fe)), d = /* @__PURE__ */ new Date(), f = o.workflow.execute(a).pipe(u.locally(Ne, s), u.provide(c.layer), u.provide(l)), m = (e.ctx.store === void 0 ? f : u.provide(f, T(e.ctx.store))).pipe(u.either), h = await u.runPromise(m), g = Vt(c.readSteps()), _ = /* @__PURE__ */ new Date(), v;
|
|
721
745
|
if (h._tag === "Right") v = {
|
|
722
746
|
status: "succeeded",
|
|
723
747
|
output: h.right,
|
|
@@ -757,6 +781,154 @@ var Oe = new Set(e), k = 0, A = () => ++k, ke = (e, t) => {
|
|
|
757
781
|
},
|
|
758
782
|
inspect: async (e) => n.get(e) ?? null
|
|
759
783
|
};
|
|
760
|
-
},
|
|
784
|
+
}, Wt = (e, t, n = {}) => {
|
|
785
|
+
let r = n.name ?? "mock", i = [], a = /* @__PURE__ */ new Map(), o = (e, t) => `${e}\u0000${JSON.stringify(t)}`, s = async (n, a, o) => {
|
|
786
|
+
let s = e[n];
|
|
787
|
+
if (s === void 0) throw Error(`makeServiceApiMock: '${n}' is not a service procedure of this api`);
|
|
788
|
+
let c = s.input, l = m.encodeUnknownSync(c)(a), u = m.decodeUnknownSync(c)(l);
|
|
789
|
+
i.push({
|
|
790
|
+
tag: n,
|
|
791
|
+
input: u,
|
|
792
|
+
idempotencyKey: o?.idempotencyKey
|
|
793
|
+
});
|
|
794
|
+
let d = t[n];
|
|
795
|
+
if (d === void 0) throw new h({
|
|
796
|
+
api: r,
|
|
797
|
+
tag: n,
|
|
798
|
+
reason: "transport",
|
|
799
|
+
message: "no handler in makeServiceApiMock"
|
|
800
|
+
});
|
|
801
|
+
let f = await d(u), p = s.output;
|
|
802
|
+
return m.decodeUnknownSync(p)(m.encodeUnknownSync(p)(f));
|
|
803
|
+
}, c = (e) => {
|
|
804
|
+
let t = e.join("."), n = Object.assign((e, n) => s(t, e, n), {
|
|
805
|
+
effect: (e, n) => u.tryPromise({
|
|
806
|
+
try: () => s(t, e, n),
|
|
807
|
+
catch: (e) => e
|
|
808
|
+
}),
|
|
809
|
+
subscribe: (e, n) => {
|
|
810
|
+
let r = o(t, e), i = a.get(r) ?? /* @__PURE__ */ new Set();
|
|
811
|
+
return a.set(r, i), i.add(n.onValue), s(t, e).then(n.onValue, (e) => n.onError?.(e)), { unsubscribe: () => {
|
|
812
|
+
i.delete(n.onValue);
|
|
813
|
+
} };
|
|
814
|
+
}
|
|
815
|
+
});
|
|
816
|
+
return new Proxy(n, { get: (t, n) => {
|
|
817
|
+
if (typeof n == "string") {
|
|
818
|
+
if (n === "effect" || n === "subscribe") return t[n];
|
|
819
|
+
if (n !== "then") return c([...e, n]);
|
|
820
|
+
}
|
|
821
|
+
} });
|
|
822
|
+
};
|
|
823
|
+
return {
|
|
824
|
+
api: new Proxy({}, { get: (e, t) => typeof t == "string" && t !== "then" ? c([t]) : void 0 }),
|
|
825
|
+
calls: (e) => e === void 0 ? [...i] : i.filter((t) => t.tag === e),
|
|
826
|
+
emit: (t, n, r) => {
|
|
827
|
+
let i = e[t], s = i === void 0 ? r : m.decodeUnknownSync(i.output)(m.encodeUnknownSync(i.output)(r));
|
|
828
|
+
for (let e of a.get(o(t, n)) ?? []) e(s);
|
|
829
|
+
}
|
|
830
|
+
};
|
|
831
|
+
}, Gt = () => new Promise((e, t) => {
|
|
832
|
+
let n = k.createServer();
|
|
833
|
+
n.once("error", t), n.listen(0, "127.0.0.1", () => {
|
|
834
|
+
let t = n.address(), r = typeof t == "object" && t ? t.port : 0;
|
|
835
|
+
n.close(() => e(r));
|
|
836
|
+
});
|
|
837
|
+
}), Kt = async (e) => {
|
|
838
|
+
try {
|
|
839
|
+
return (await fetch(`http://127.0.0.1:${e}/internal/readiness`)).status === 200;
|
|
840
|
+
} catch {
|
|
841
|
+
return !1;
|
|
842
|
+
}
|
|
843
|
+
}, qt = (e) => A(Be(ze(A(e, "package.json")).resolve("@voltro/cli/package.json")), "bin", "voltro.mjs"), Jt = 1e4, Yt = (e) => new Promise((t) => {
|
|
844
|
+
if (e.exitCode !== null || e.signalCode !== null) return t();
|
|
845
|
+
let n = setTimeout(() => {
|
|
846
|
+
e.kill("SIGKILL");
|
|
847
|
+
}, Jt);
|
|
848
|
+
e.once("exit", () => {
|
|
849
|
+
clearTimeout(n), t();
|
|
850
|
+
}), e.kill("SIGTERM");
|
|
851
|
+
}), Xt = async (e) => {
|
|
852
|
+
let t = Object.keys(e.apps);
|
|
853
|
+
if (t.length === 0) throw Error("startTestApps: no apps given");
|
|
854
|
+
let n = e.mode ?? "dev", r = e.bootTimeoutMs ?? 3e5, i = e.cli ?? qt(e.apps[t[0]].root), a = /* @__PURE__ */ new Map();
|
|
855
|
+
for (let e of t) a.set(e, await Gt());
|
|
856
|
+
let o = /* @__PURE__ */ new Map(), s = new Map(t.map((e) => [e, {}]));
|
|
857
|
+
for (let n of e.edges ?? []) {
|
|
858
|
+
for (let e of [n.caller, n.callee]) if (!t.includes(e)) throw Error(`startTestApps: edge names '${e}', which is not among the apps (${t.join(", ")})`);
|
|
859
|
+
let e = _e();
|
|
860
|
+
o.set(`${n.caller}\u0000${n.callee}`, e), Object.assign(s.get(n.caller), {
|
|
861
|
+
[re(n.binding)]: e,
|
|
862
|
+
[ie(n.binding)]: `ws://127.0.0.1:${a.get(n.callee)}/ws`
|
|
863
|
+
}), Object.assign(s.get(n.callee), { [we(n.caller)]: e });
|
|
864
|
+
}
|
|
865
|
+
let c = [], l = /* @__PURE__ */ new Set(), u = (t) => {
|
|
866
|
+
if (!c.includes(t)) {
|
|
867
|
+
if (l.has(t)) throw Error(`startTestApps: the edges form a cycle through '${t}' — no app can boot first`);
|
|
868
|
+
l.add(t);
|
|
869
|
+
for (let n of e.edges ?? []) n.caller === t && u(n.callee);
|
|
870
|
+
l.delete(t), c.push(t);
|
|
871
|
+
}
|
|
872
|
+
};
|
|
873
|
+
for (let e of t) u(e);
|
|
874
|
+
let d = [], f = /* @__PURE__ */ new Map(), p = async () => {
|
|
875
|
+
await Promise.all(d.map(Yt));
|
|
876
|
+
};
|
|
877
|
+
for (let t of c) {
|
|
878
|
+
let o = e.apps[t], c = a.get(t), l = "", u = Re(process.execPath, [
|
|
879
|
+
i,
|
|
880
|
+
n,
|
|
881
|
+
...n === "serve" ? ["."] : []
|
|
882
|
+
], {
|
|
883
|
+
cwd: o.root,
|
|
884
|
+
env: {
|
|
885
|
+
...process.env,
|
|
886
|
+
...n === "serve" ? { VOLTRO_SESSION_SECRET: Me(32).toString("base64url") } : {},
|
|
887
|
+
...o.env,
|
|
888
|
+
...s.get(t),
|
|
889
|
+
PORT: String(c)
|
|
890
|
+
},
|
|
891
|
+
stdio: [
|
|
892
|
+
"ignore",
|
|
893
|
+
"pipe",
|
|
894
|
+
"pipe"
|
|
895
|
+
]
|
|
896
|
+
});
|
|
897
|
+
d.push(u), u.stdout?.on("data", (e) => {
|
|
898
|
+
l += e.toString();
|
|
899
|
+
}), u.stderr?.on("data", (e) => {
|
|
900
|
+
l += e.toString();
|
|
901
|
+
}), u.on("exit", (e, t) => {
|
|
902
|
+
l += `\n[exited] code=${String(e)} signal=${String(t)}`;
|
|
903
|
+
});
|
|
904
|
+
let m = {
|
|
905
|
+
name: t,
|
|
906
|
+
port: c,
|
|
907
|
+
url: `http://127.0.0.1:${c}`,
|
|
908
|
+
wsUrl: `ws://127.0.0.1:${c}/ws`,
|
|
909
|
+
log: () => l,
|
|
910
|
+
stop: () => Yt(u)
|
|
911
|
+
};
|
|
912
|
+
f.set(t, m);
|
|
913
|
+
let h = Date.now() + r;
|
|
914
|
+
for (; !await Kt(c);) {
|
|
915
|
+
if (u.exitCode !== null || u.signalCode !== null || Date.now() > h) {
|
|
916
|
+
await p();
|
|
917
|
+
let e = u.exitCode !== null || u.signalCode !== null ? "exited before it was ready" : `was not ready within ${r} ms`;
|
|
918
|
+
throw Error(`startTestApps: '${t}' ${e}\n${m.log().slice(-4e3)}`);
|
|
919
|
+
}
|
|
920
|
+
await new Promise((e) => setTimeout(e, 250));
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
return {
|
|
924
|
+
apps: Object.fromEntries(f),
|
|
925
|
+
token: (e, t) => {
|
|
926
|
+
let n = o.get(`${e}\u0000${t}`);
|
|
927
|
+
if (n === void 0) throw Error(`startTestApps: no edge ${e} → ${t}`);
|
|
928
|
+
return n;
|
|
929
|
+
},
|
|
930
|
+
stop: p
|
|
931
|
+
};
|
|
932
|
+
}, Zt = 1;
|
|
761
933
|
//#endregion
|
|
762
|
-
export {
|
|
934
|
+
export { z as MockClock, H as MockLLM, B as MockWebhooks, Zt as TESTING_PRESET_VERSION, Dt as TEST_TENANT_ID, jt as anonymous, kt as apiKey, n as changeDelete, r as changeInsert, i as changeSoftDelete, a as changeUpdate, Ze as defineFactory, wt as describeIfAvailable, Tt as describeIfReachable, N as fixtureRow, tt as frozenTime, Ke as hydrateFixtureRows, St as invoke, Ct as isTcpReachable, Wt as makeServiceApiMock, Bt as makeSubscribeContext, zt as makeTestApp, bt as makeTestContext, Ut as makeWorkflowRunner, Z as markRestInvocation, rt as mockStore, M as nextSequence, ut as outboxNudgesOf, Y as pluginsOf, Et as reportEngineVersion, lt as resetAfterCommit, at as restInvocationOf, st as rpcInterceptorFor, Q as runAfterCommit, dt as runInStoreTransaction, At as serviceAccount, ct as serviceLayerFor, Xt as startTestApps, Mt as system, V as testEventBus, Ot as user, et as withFrozenTime, it as withRpcConnection };
|