@voltro/testing 0.79.1 → 0.81.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 +169 -0
- package/dist/index.d.ts +138 -3
- package/dist/index.js +342 -180
- package/package.json +8 -8
package/dist/index.js
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
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 { CurrentWorkflowRunId as
|
|
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, getRowFilter as w, getSystemStoreHandle as ce, makeAppAccess as le, makeConnectionState as ue, makeDataLoader as de, makeEffectStoreLayer as fe, 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 T, runWithDeadlockRetry as Ce, serviceCallerTokenEnv as we, setFieldCipher as Te, setSystemStoreHandle as E, wrapStoreWithMixinBehaviour as D } from "@voltro/runtime";
|
|
5
|
+
import { installEnvSnapshot as Ee } from "@voltro/env";
|
|
6
|
+
import O 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 { CurrentWorkflowRunId as Me, inMemoryWorkflowEngineLayer as Ne, makeInMemoryRecorder as Pe } from "@voltro/workflow";
|
|
11
|
+
import { spawn as Fe } from "node:child_process";
|
|
12
|
+
import { randomBytes as Ie } from "node:crypto";
|
|
13
|
+
import { createRequire as Le } from "node:module";
|
|
14
|
+
import { dirname as Re, join as ze } from "node:path";
|
|
11
15
|
//#region src/fixtureRow.ts
|
|
12
|
-
var
|
|
16
|
+
var Be = new Set(e), k = 0, Ve = () => ++k, 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;
|
|
@@ -27,38 +31,38 @@ var Oe = new Set(e), k = 0, A = () => ++k, ke = (e, t) => {
|
|
|
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
|
+
}, A = (e, t = {}) => {
|
|
31
35
|
let n = {};
|
|
32
|
-
for (let r of s(e, t))
|
|
36
|
+
for (let r of s(e, t)) Be.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
|
+
}, j = 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 = j(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 = j(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(Ve()) : 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 M(e, s, {}, {}, [...i, s.tableName]) : await c.create(e, {}))[n.referenceColumn ?? Je(s)];
|
|
70
74
|
}
|
|
71
75
|
return a;
|
|
72
|
-
},
|
|
76
|
+
}, M = 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, A(t, a));
|
|
82
|
+
}, N = (e, t) => typeof e == "function" ? e(t) : e ?? {}, Xe = (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 = {}) => A(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(N(t, n))),
|
|
92
|
+
create: (t, n = {}) => M(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 M(t, e, a(N(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
|
+
}, P = Symbol.for("voltro/testing/mockClock.installed"), F = () => globalThis, Ze = (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
|
+
}), Qe = (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
|
+
}, I = class {
|
|
123
127
|
currentMs;
|
|
124
128
|
constructor(e = "2026-01-01T00:00:00Z") {
|
|
125
|
-
this.currentMs =
|
|
129
|
+
this.currentMs = Qe(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 = Qe(e);
|
|
138
142
|
}
|
|
139
143
|
get installed() {
|
|
140
|
-
return
|
|
144
|
+
return F()[P]?.clock === this;
|
|
141
145
|
}
|
|
142
146
|
install() {
|
|
143
|
-
let e =
|
|
147
|
+
let e = F(), t = e[P];
|
|
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[P] = {
|
|
147
151
|
realDate: n,
|
|
148
152
|
clock: this
|
|
149
|
-
}, globalThis.Date =
|
|
153
|
+
}, globalThis.Date = Ze(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 = F(), t = e[P];
|
|
159
|
+
t !== void 0 && t.clock === this && (globalThis.Date = t.realDate, delete e[P]);
|
|
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 I ? e : new I(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 I ? e : new I(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,7 +187,7 @@ 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
|
+
}, L = class {
|
|
187
191
|
emitted = [];
|
|
188
192
|
async emit(e, t) {
|
|
189
193
|
let n = typeof e == "string" ? e : e.id ?? e.event ?? "(unnamed event)";
|
|
@@ -202,14 +206,14 @@ var Oe = new Set(e), k = 0, A = () => ++k, ke = (e, t) => {
|
|
|
202
206
|
clear() {
|
|
203
207
|
this.emitted.length = 0;
|
|
204
208
|
}
|
|
205
|
-
},
|
|
206
|
-
let t = e.tenantId ?? null, n = new
|
|
209
|
+
}, R = (e = {}) => {
|
|
210
|
+
let t = e.tenantId ?? null, n = new te({
|
|
207
211
|
origin: e.origin ?? "test",
|
|
208
212
|
...e.ringSize === void 0 ? {} : { ringSize: e.ringSize }
|
|
209
213
|
});
|
|
210
214
|
return {
|
|
211
215
|
publish: async (e, r, i) => {
|
|
212
|
-
let a = await u.runPromise(u.either(
|
|
216
|
+
let a = await u.runPromise(u.either(ve({
|
|
213
217
|
bus: n,
|
|
214
218
|
tenantId: t
|
|
215
219
|
}, e, r, i)));
|
|
@@ -258,7 +262,7 @@ var Oe = new Set(e), k = 0, A = () => ++k, ke = (e, t) => {
|
|
|
258
262
|
},
|
|
259
263
|
skipSerials: (e, r, i, a) => {
|
|
260
264
|
let o = a?.tenantId ?? t, s = {
|
|
261
|
-
route:
|
|
265
|
+
route: x(o, e.name, r),
|
|
262
266
|
event: e.name,
|
|
263
267
|
origin: "test-gap",
|
|
264
268
|
n: i + 1,
|
|
@@ -272,7 +276,7 @@ var Oe = new Set(e), k = 0, A = () => ++k, ke = (e, t) => {
|
|
|
272
276
|
n.clear();
|
|
273
277
|
}
|
|
274
278
|
};
|
|
275
|
-
},
|
|
279
|
+
}, z = class {
|
|
276
280
|
queue;
|
|
277
281
|
calls = [];
|
|
278
282
|
constructor(e) {
|
|
@@ -287,38 +291,41 @@ var Oe = new Set(e), k = 0, A = () => ++k, ke = (e, t) => {
|
|
|
287
291
|
remaining() {
|
|
288
292
|
return this.queue.length;
|
|
289
293
|
}
|
|
290
|
-
},
|
|
291
|
-
let n =
|
|
294
|
+
}, rt = (e) => e, B = "00000000000000000000000000000000", V = /* @__PURE__ */ new WeakMap(), H = /* @__PURE__ */ new WeakMap(), it = (e, t) => {
|
|
295
|
+
let n = H.get(e);
|
|
292
296
|
if (n === void 0) throw Error("withRpcConnection requires a context created by makeTestContext");
|
|
293
297
|
return n(t);
|
|
294
|
-
},
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
+
}, U = /* @__PURE__ */ new WeakMap(), W = /* @__PURE__ */ new WeakMap(), G = /* @__PURE__ */ new WeakMap(), K = (e) => G.get(e) ?? [], q = /* @__PURE__ */ new WeakMap(), J = (e, t, n) => {
|
|
299
|
+
q.set(e, {
|
|
300
|
+
publicApi: t,
|
|
301
|
+
...n === void 0 ? {} : { remoteAddr: n }
|
|
302
|
+
});
|
|
303
|
+
}, Y = (e) => q.get(e), X = /* @__PURE__ */ new WeakMap(), at = (e, t) => {
|
|
304
|
+
let n = G.get(e) ?? [], r = t === "mutation" ? "interceptMutation" : t === "query" ? "interceptQuery" : "interceptAction", i = [];
|
|
298
305
|
for (let e of n) {
|
|
299
306
|
let t = e[r];
|
|
300
307
|
typeof t == "function" && i.push(t);
|
|
301
308
|
}
|
|
302
|
-
return
|
|
303
|
-
},
|
|
304
|
-
let t = (
|
|
309
|
+
return b(i);
|
|
310
|
+
}, ot = (e) => {
|
|
311
|
+
let t = (G.get(e) ?? []).map((e) => e.services).filter((e) => e !== void 0), n = X.get(e) ?? [], r = [...t, ...n];
|
|
305
312
|
if (r.length !== 0) return p.mergeAll(...r);
|
|
306
|
-
},
|
|
307
|
-
let t =
|
|
313
|
+
}, st = (e) => {
|
|
314
|
+
let t = U.get(e);
|
|
308
315
|
t !== void 0 && (t.length = 0);
|
|
309
316
|
}, Z = async (e) => {
|
|
310
|
-
let t =
|
|
317
|
+
let t = U.get(e);
|
|
311
318
|
if (t === void 0 || t.length === 0) return;
|
|
312
319
|
let n = [...t];
|
|
313
320
|
t.length = 0;
|
|
314
321
|
for (let e of n) await e();
|
|
315
|
-
},
|
|
316
|
-
let n =
|
|
322
|
+
}, ct = (e) => W.get(e) ?? [], lt = async (e, t) => {
|
|
323
|
+
let n = V.get(e);
|
|
317
324
|
return n === void 0 ? e.store.transactional(async (n) => t({
|
|
318
325
|
...e,
|
|
319
326
|
store: n
|
|
320
327
|
})) : n(t);
|
|
321
|
-
},
|
|
328
|
+
}, ut = (e) => {
|
|
322
329
|
let t = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map(), r = (n) => {
|
|
323
330
|
let r = t.get(n);
|
|
324
331
|
return r === void 0 ? !1 : r.expiresAt !== null && r.expiresAt <= e() ? (t.delete(n), !1) : !0;
|
|
@@ -357,7 +364,7 @@ var Oe = new Set(e), k = 0, A = () => ++k, ke = (e, t) => {
|
|
|
357
364
|
return i(e, o, n.ttlMs, n.tags), o;
|
|
358
365
|
}
|
|
359
366
|
};
|
|
360
|
-
},
|
|
367
|
+
}, dt = (e) => {
|
|
361
368
|
let t = /* @__PURE__ */ new Map(), n = (n) => {
|
|
362
369
|
let r = t.get(n);
|
|
363
370
|
return r === void 0 ? !1 : r.expiresAt !== null && r.expiresAt <= e() ? (t.delete(n), !1) : !0;
|
|
@@ -385,47 +392,47 @@ var Oe = new Set(e), k = 0, A = () => ++k, ke = (e, t) => {
|
|
|
385
392
|
t.clear();
|
|
386
393
|
}
|
|
387
394
|
};
|
|
388
|
-
},
|
|
389
|
-
let n =
|
|
390
|
-
|
|
395
|
+
}, ft = async (e, t) => {
|
|
396
|
+
let n = ce();
|
|
397
|
+
E(e);
|
|
391
398
|
try {
|
|
392
399
|
return await t();
|
|
393
400
|
} finally {
|
|
394
|
-
n === void 0 ?
|
|
401
|
+
n === void 0 ? se() : E(n);
|
|
395
402
|
}
|
|
396
|
-
},
|
|
397
|
-
|
|
398
|
-
},
|
|
399
|
-
let r =
|
|
403
|
+
}, pt = /* @__PURE__ */ new Set(), mt = (e) => {
|
|
404
|
+
pt.has(e) || (pt.add(e), console.warn(e));
|
|
405
|
+
}, ht = (e, t, n) => {
|
|
406
|
+
let r = gt, i;
|
|
400
407
|
return () => {
|
|
401
408
|
let a = t ?? w();
|
|
402
|
-
return t !== void 0 && w() !== void 0 && t !== w() &&
|
|
409
|
+
return t !== void 0 && w() !== void 0 && t !== w() && mt("[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 = ft(n, () => T(be(a, e, (e) => {
|
|
403
410
|
console.error("[voltro:testing] row filter failed to load — reads refused for this subject", e);
|
|
404
411
|
})))), i;
|
|
405
412
|
};
|
|
406
|
-
},
|
|
407
|
-
if (n === "query") return async (n) => e.query(
|
|
413
|
+
}, gt = Symbol("unresolved"), Q = (e, t) => new Proxy(e, { get: (e, n) => {
|
|
414
|
+
if (n === "query") return async (n) => e.query(oe(await t(), n));
|
|
408
415
|
let r = Reflect.get(e, n, e);
|
|
409
416
|
return typeof r == "function" ? r.bind(e) : r;
|
|
410
|
-
} }),
|
|
411
|
-
if (
|
|
417
|
+
} }), _t = (e = {}) => {
|
|
418
|
+
if (Ee({
|
|
412
419
|
...process.env,
|
|
413
420
|
...e.env ?? {}
|
|
414
|
-
}), e.fieldEncryptionKey !== void 0 &&
|
|
421
|
+
}), e.fieldEncryptionKey !== void 0 && Te(me(e.fieldEncryptionKey)), e.relations !== void 0) {
|
|
415
422
|
o();
|
|
416
423
|
for (let t of e.relations) c(t);
|
|
417
424
|
}
|
|
418
|
-
let n = e.tables ?? t(), r =
|
|
425
|
+
let n = e.tables ?? t(), r = ge(n), i = new ne(e.store ?? {}), a = {
|
|
419
426
|
dataStore: i,
|
|
420
427
|
schemaRegistry: r
|
|
421
428
|
};
|
|
422
|
-
|
|
423
|
-
let s = new
|
|
429
|
+
E(a);
|
|
430
|
+
let s = new I(e.clockStart), l = new L(), u = R(), d = new z(e.llmResponses ?? []), f = ut(() => s.now()), p = dt(() => s.now()), m = (t, n, o = i, c, h = !1) => {
|
|
424
431
|
let g = {
|
|
425
432
|
subject: t,
|
|
426
|
-
traceId:
|
|
433
|
+
traceId: B,
|
|
427
434
|
...n === void 0 ? {} : { connection: n }
|
|
428
|
-
}, _ = c?.queued ?? [], v = c?.nudges ?? [], y =
|
|
435
|
+
}, _ = c?.queued ?? [], v = c?.nudges ?? [], y = pe({
|
|
429
436
|
bus: u.bus,
|
|
430
437
|
tenantId: t.tenantId ?? null,
|
|
431
438
|
...o === i ? {} : { deferToCommit: (e) => {
|
|
@@ -433,9 +440,10 @@ var Oe = new Set(e), k = 0, A = () => ++k, ke = (e, t) => {
|
|
|
433
440
|
e();
|
|
434
441
|
});
|
|
435
442
|
} }
|
|
436
|
-
}), b =
|
|
443
|
+
}), b = de({ store: o }), x = h ? async () => C : ht(t, e.rowFilter, a), S = {
|
|
444
|
+
apis: e.apis ?? Object.freeze({}),
|
|
437
445
|
transaction: async (e, r) => {
|
|
438
|
-
let a =
|
|
446
|
+
let a = xe(t, r?.tenantId, o !== i);
|
|
439
447
|
if (a !== t) return m(a, n, i, void 0, !0).transaction(e);
|
|
440
448
|
if (o !== i) return e(S);
|
|
441
449
|
let s, c = await o.transactional(async (r) => {
|
|
@@ -445,7 +453,7 @@ var Oe = new Set(e), k = 0, A = () => ++k, ke = (e, t) => {
|
|
|
445
453
|
}, h), a = await e(i);
|
|
446
454
|
return s = i, a;
|
|
447
455
|
});
|
|
448
|
-
return s !== void 0 && (await Z(s), v.push(...
|
|
456
|
+
return s !== void 0 && (await Z(s), v.push(...ct(s))), c;
|
|
449
457
|
},
|
|
450
458
|
clock: s,
|
|
451
459
|
webhooks: l,
|
|
@@ -454,29 +462,29 @@ var Oe = new Set(e), k = 0, A = () => ++k, ke = (e, t) => {
|
|
|
454
462
|
llm: d,
|
|
455
463
|
...e.ai === void 0 ? {} : { ai: e.ai },
|
|
456
464
|
request: g,
|
|
457
|
-
...n === void 0 ? {} : { connectionState:
|
|
465
|
+
...n === void 0 ? {} : { connectionState: ue(n, o === i ? void 0 : (e) => {
|
|
458
466
|
_.push(e);
|
|
459
467
|
}) },
|
|
460
|
-
validation:
|
|
461
|
-
access:
|
|
468
|
+
validation: ae,
|
|
469
|
+
access: le(t),
|
|
462
470
|
cache: f,
|
|
463
471
|
kv: p,
|
|
464
|
-
store:
|
|
472
|
+
store: D(Q(o, x), {
|
|
465
473
|
subject: t,
|
|
466
474
|
schemaRegistry: r,
|
|
467
475
|
rowFilter: C
|
|
468
476
|
}),
|
|
469
|
-
storeForTenant: (e) =>
|
|
477
|
+
storeForTenant: (e) => D(Q(o, x), {
|
|
470
478
|
subject: ee(t, e),
|
|
471
479
|
schemaRegistry: r,
|
|
472
480
|
rowFilter: C
|
|
473
481
|
}),
|
|
474
|
-
outbox:
|
|
482
|
+
outbox: he({
|
|
475
483
|
store: o,
|
|
476
484
|
subject: t,
|
|
477
|
-
traceId:
|
|
485
|
+
traceId: B,
|
|
478
486
|
nudge: () => {
|
|
479
|
-
v.push(
|
|
487
|
+
v.push(B);
|
|
480
488
|
},
|
|
481
489
|
afterCommit: (e) => {
|
|
482
490
|
_.push(e);
|
|
@@ -507,37 +515,37 @@ var Oe = new Set(e), k = 0, A = () => ++k, ke = (e, t) => {
|
|
|
507
515
|
nudges: v
|
|
508
516
|
})
|
|
509
517
|
};
|
|
510
|
-
return
|
|
518
|
+
return U.set(S, _), H.set(S, (e) => m(t, e, o, {
|
|
511
519
|
queued: _,
|
|
512
520
|
nudges: v
|
|
513
|
-
})),
|
|
521
|
+
})), W.set(S, v), G.set(S, e.plugins ?? []), X.set(S, e.layers ?? []), V.set(S, (e) => o.transactional((r) => e(m(t, n, r, {
|
|
514
522
|
queued: _,
|
|
515
523
|
nudges: v
|
|
516
524
|
})))), S;
|
|
517
525
|
};
|
|
518
|
-
return m(e.subject ??
|
|
519
|
-
},
|
|
520
|
-
let n =
|
|
521
|
-
return (n === void 0 ? e : u.provide(e, n)).pipe(u.provide(
|
|
522
|
-
},
|
|
526
|
+
return m(e.subject ?? _(null), e.connection);
|
|
527
|
+
}, vt = (e, t) => {
|
|
528
|
+
let n = ot(t);
|
|
529
|
+
return (n === void 0 ? e : u.provide(e, n)).pipe(u.provide(fe(t.store)), u.provideService(g, t.request.subject));
|
|
530
|
+
}, yt = async (e, t, n, r) => {
|
|
523
531
|
let i = e.input, a = await m.decodeUnknownPromise(i)(n), o = e.kind, s = async (e) => {
|
|
524
532
|
let n = t(a, e);
|
|
525
|
-
return u.isEffect(n) ?
|
|
533
|
+
return u.isEffect(n) ? T(vt(n, e)) : n;
|
|
526
534
|
}, c = async () => {
|
|
527
535
|
let t = e.guards;
|
|
528
536
|
if (t !== void 0 && t.length > 0) {
|
|
529
|
-
let e = await u.runPromise(
|
|
537
|
+
let e = await u.runPromise(v(r.request.subject, t, a));
|
|
530
538
|
if (e !== null) throw e;
|
|
531
539
|
}
|
|
532
540
|
if (o !== "mutation") return s(r);
|
|
533
|
-
let n = await
|
|
541
|
+
let n = await Ce(async () => lt(r, async (e) => (st(r), s(e))), { delay: () => Promise.resolve() });
|
|
534
542
|
return await Z(r), n;
|
|
535
|
-
}, d = o === "mutation" || o === "query" || o === "action" ? o : void 0, p = d === void 0 ? void 0 :
|
|
543
|
+
}, d = o === "mutation" || o === "query" || o === "action" ? o : void 0, p = d === void 0 ? void 0 : at(r, d);
|
|
536
544
|
if (p === void 0 || d === void 0) return await c();
|
|
537
545
|
let h = u.tryPromise({
|
|
538
546
|
try: () => c(),
|
|
539
547
|
catch: (e) => e
|
|
540
|
-
}), g =
|
|
548
|
+
}), g = Y(r), _ = p(h, {
|
|
541
549
|
tag: e.name ?? "",
|
|
542
550
|
kind: d,
|
|
543
551
|
input: a,
|
|
@@ -547,16 +555,17 @@ var Oe = new Set(e), k = 0, A = () => ++k, ke = (e, t) => {
|
|
|
547
555
|
...g === void 0 ? {} : {
|
|
548
556
|
surface: "rest",
|
|
549
557
|
publicApi: g.publicApi
|
|
550
|
-
}
|
|
551
|
-
|
|
558
|
+
},
|
|
559
|
+
...g?.remoteAddr === void 0 ? {} : { remoteAddr: g.remoteAddr }
|
|
560
|
+
}), y = await u.runPromiseExit(_);
|
|
552
561
|
if (f.isSuccess(y)) return y.value;
|
|
553
562
|
throw l.squash(y.cause);
|
|
554
|
-
},
|
|
555
|
-
let n = new
|
|
563
|
+
}, bt = (e) => new Promise((t) => {
|
|
564
|
+
let n = new O.Socket(), r = (e) => {
|
|
556
565
|
clearTimeout(i), n.destroy(), t(e);
|
|
557
566
|
}, i = setTimeout(() => r(!1), e.timeoutMs ?? 750);
|
|
558
567
|
n.once("connect", () => r(!0)), n.once("error", () => r(!1)), n.connect(e.port, e.host);
|
|
559
|
-
}),
|
|
568
|
+
}), xt = async (e, t, n, r) => {
|
|
560
569
|
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
570
|
let i = !1;
|
|
562
571
|
try {
|
|
@@ -564,21 +573,21 @@ var Oe = new Set(e), k = 0, A = () => ++k, ke = (e, t) => {
|
|
|
564
573
|
} catch {
|
|
565
574
|
i = !1;
|
|
566
575
|
}
|
|
567
|
-
|
|
568
|
-
},
|
|
569
|
-
await
|
|
570
|
-
},
|
|
576
|
+
De.skipIf(!i)(i ? e : `${e} [SKIPPED: needs ${t}]`, r);
|
|
577
|
+
}, St = async (e, t, n) => {
|
|
578
|
+
await xt(e, `${t.name} at ${t.host}:${t.port}`, () => bt(t), n);
|
|
579
|
+
}, Ct = async (e, t) => {
|
|
571
580
|
try {
|
|
572
581
|
let n = await t();
|
|
573
582
|
n !== void 0 && n !== "" && console.log(`[engine] ${e}: ${n}`);
|
|
574
583
|
} catch {}
|
|
575
|
-
},
|
|
584
|
+
}, wt = "test-tenant", $ = (e, t, n) => ({
|
|
576
585
|
type: e,
|
|
577
586
|
id: t,
|
|
578
587
|
tenantId: n.tenantId ?? "test-tenant",
|
|
579
588
|
scopes: n.scopes ?? [],
|
|
580
589
|
...n.metadata === void 0 ? {} : { metadata: n.metadata }
|
|
581
|
-
}),
|
|
590
|
+
}), Tt = (e, t = {}) => $("user", e, t), Et = (e, t = {}) => $("apiKey", e, t), Dt = (e, t = {}) => $("serviceAccount", e, t), Ot = (e = null) => _(e), kt = (e = "job:test", t) => t === void 0 ? S(e) : S(e, t), At = "127.0.0.1", jt = (e) => {
|
|
582
591
|
let t = e.indexOf("?");
|
|
583
592
|
return t === -1 ? {
|
|
584
593
|
path: e,
|
|
@@ -587,105 +596,110 @@ var Oe = new Set(e), k = 0, A = () => ++k, ke = (e, t) => {
|
|
|
587
596
|
path: e.slice(0, t),
|
|
588
597
|
query: e.slice(t + 1)
|
|
589
598
|
};
|
|
590
|
-
},
|
|
599
|
+
}, Mt = (e, t) => {
|
|
591
600
|
let n = e.split("/").filter((e) => e.length > 0), r = t.split("/").filter((e) => e.length > 0);
|
|
592
601
|
return n.length === r.length && n.every((e, t) => e.startsWith(":") || e === r[t]);
|
|
593
|
-
},
|
|
602
|
+
}, Nt = (e) => {
|
|
594
603
|
let t = {};
|
|
595
604
|
for (let [n, r] of Object.entries(e)) t[n.toLowerCase()] = r;
|
|
596
605
|
return t;
|
|
597
|
-
},
|
|
598
|
-
let { ctx:
|
|
606
|
+
}, Pt = (e) => e === void 0 ? /* @__PURE__ */ new Uint8Array() : new TextEncoder().encode(JSON.stringify(e)), Ft = (e) => e === void 0 ? "" : typeof e == "string" ? e : new TextDecoder().decode(e), It = (e) => {
|
|
607
|
+
let t = Se(e.security?.trustedProxies, process.env, e.security?.clientAddressHeader), { ctx: n } = e, r = Oe((e.publicApi ?? []).map((e) => ({
|
|
599
608
|
descriptor: e.descriptor,
|
|
600
|
-
invoke: (
|
|
609
|
+
invoke: (t, r) => n.withSubject(r.subject, (n) => (e.descriptor.publicApi !== void 0 && J(n, e.descriptor.publicApi, r.remoteAddr), yt(e.descriptor, e.handler, t, n)))
|
|
601
610
|
})), {
|
|
602
|
-
pluginErrors:
|
|
611
|
+
pluginErrors: K(n).flatMap((e) => e.errorSchemas ?? []),
|
|
603
612
|
...e.publicApiProfile === void 0 ? {} : { profile: e.publicApiProfile }
|
|
604
|
-
}),
|
|
613
|
+
}), i = [...e.restRoutes ?? [], ...r], a = y(e.strategies ?? [], {
|
|
605
614
|
...e.anonymousTenantRequired === void 0 ? {} : { anonymousTenantRequired: e.anonymousTenantRequired },
|
|
606
|
-
getStore: () =>
|
|
607
|
-
}),
|
|
608
|
-
let
|
|
609
|
-
store:
|
|
610
|
-
buildContext: () =>
|
|
611
|
-
resolveSubject:
|
|
615
|
+
getStore: () => n.store
|
|
616
|
+
}), o = (r, s) => {
|
|
617
|
+
let c = {
|
|
618
|
+
store: n.store,
|
|
619
|
+
buildContext: () => n,
|
|
620
|
+
resolveSubject: r === void 0 ? async (e) => (await a({
|
|
612
621
|
headers: e,
|
|
613
622
|
clientId: -1
|
|
614
|
-
})).subject : () =>
|
|
623
|
+
})).subject : () => r,
|
|
615
624
|
...e.idempotency === void 0 ? {} : { idempotency: e.idempotency }
|
|
616
|
-
},
|
|
617
|
-
pattern:
|
|
625
|
+
}, l = Ae(i, c).map((e, t) => ({
|
|
626
|
+
pattern: i[t].path,
|
|
618
627
|
route: e
|
|
619
|
-
})),
|
|
620
|
-
let { path:
|
|
621
|
-
if (
|
|
628
|
+
})), u = async (e, r, a = {}) => {
|
|
629
|
+
let { path: o, query: c } = jt(r), u = l.filter((e) => Mt(e.pattern, o)).map((e) => e.route);
|
|
630
|
+
if (u.length === 0) return {
|
|
622
631
|
status: 404,
|
|
623
632
|
headers: {},
|
|
624
633
|
text: "",
|
|
625
634
|
body: {
|
|
626
635
|
error: "No route mounted for this path",
|
|
627
|
-
mounted:
|
|
636
|
+
mounted: i.map((e) => e.path)
|
|
628
637
|
},
|
|
629
638
|
stream: !1
|
|
630
639
|
};
|
|
631
|
-
let
|
|
640
|
+
let d = {
|
|
641
|
+
...Nt(s),
|
|
642
|
+
...Nt(a.headers ?? {})
|
|
643
|
+
}, f = ye({
|
|
644
|
+
socketAddress: a.remoteAddr ?? At,
|
|
645
|
+
headers: d,
|
|
646
|
+
config: t
|
|
647
|
+
}), p = {
|
|
632
648
|
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");
|
|
649
|
+
path: o,
|
|
650
|
+
query: c,
|
|
651
|
+
headers: d,
|
|
652
|
+
rawBody: Pt(a.body),
|
|
653
|
+
store: n.store,
|
|
654
|
+
...f === void 0 ? {} : { remoteAddr: f }
|
|
655
|
+
}, m = await ke(u, p), h = {};
|
|
656
|
+
for (let [e, t] of Object.entries(m.headers ?? {})) h[e.toLowerCase()] = t;
|
|
657
|
+
m.contentType !== void 0 && (h["content-type"] = m.contentType);
|
|
658
|
+
let g = Ft(m.body), _ = (m.contentType ?? "").includes("json");
|
|
645
659
|
return {
|
|
646
|
-
status:
|
|
647
|
-
headers:
|
|
648
|
-
text:
|
|
649
|
-
body:
|
|
650
|
-
stream:
|
|
660
|
+
status: m.status,
|
|
661
|
+
headers: h,
|
|
662
|
+
text: g,
|
|
663
|
+
body: _ && g !== "" ? JSON.parse(g) : void 0,
|
|
664
|
+
stream: m.stream !== void 0
|
|
651
665
|
};
|
|
652
666
|
};
|
|
653
667
|
return {
|
|
654
|
-
actingAs: (e) =>
|
|
655
|
-
withHeaders: (e) =>
|
|
656
|
-
...
|
|
668
|
+
actingAs: (e) => o(e, s),
|
|
669
|
+
withHeaders: (e) => o(r, {
|
|
670
|
+
...s,
|
|
657
671
|
...e
|
|
658
672
|
}),
|
|
659
|
-
get: (e, t) =>
|
|
660
|
-
delete: (e, t) =>
|
|
661
|
-
post: (e, t, n) =>
|
|
673
|
+
get: (e, t) => u("GET", e, t ?? {}),
|
|
674
|
+
delete: (e, t) => u("DELETE", e, t ?? {}),
|
|
675
|
+
post: (e, t, n) => u("POST", e, {
|
|
662
676
|
...n ?? {},
|
|
663
677
|
body: t
|
|
664
678
|
}),
|
|
665
|
-
put: (e, t, n) =>
|
|
679
|
+
put: (e, t, n) => u("PUT", e, {
|
|
666
680
|
...n ?? {},
|
|
667
681
|
body: t
|
|
668
682
|
}),
|
|
669
|
-
patch: (e, t, n) =>
|
|
683
|
+
patch: (e, t, n) => u("PATCH", e, {
|
|
670
684
|
...n ?? {},
|
|
671
685
|
body: t
|
|
672
686
|
}),
|
|
673
|
-
request: (e, t, n) =>
|
|
674
|
-
paths:
|
|
687
|
+
request: (e, t, n) => u(e, t, n ?? {}),
|
|
688
|
+
paths: i.map((e) => e.path)
|
|
675
689
|
};
|
|
676
690
|
};
|
|
677
|
-
return
|
|
678
|
-
},
|
|
691
|
+
return o(void 0, {});
|
|
692
|
+
}, Lt = (e = {}) => {
|
|
679
693
|
let t = e.id ?? "test", n = e.store ?? new Proxy({}, { get: (e, t) => {
|
|
680
694
|
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
695
|
} });
|
|
682
696
|
return {
|
|
683
697
|
id: t,
|
|
684
|
-
log: e.log ??
|
|
698
|
+
log: e.log ?? je({ scope: `subscribe:${t}` }),
|
|
685
699
|
store: n,
|
|
686
700
|
...e.publish === void 0 ? {} : { publish: e.publish }
|
|
687
701
|
};
|
|
688
|
-
},
|
|
702
|
+
}, Rt = (e) => {
|
|
689
703
|
let t = /* @__PURE__ */ new Map();
|
|
690
704
|
for (let n of e) {
|
|
691
705
|
let e = t.get(n.stepName);
|
|
@@ -711,13 +725,13 @@ var Oe = new Set(e), k = 0, A = () => ++k, ke = (e, t) => {
|
|
|
711
725
|
});
|
|
712
726
|
}
|
|
713
727
|
return n.sort((e, t) => e._startedAt - t._startedAt), n.map(({ _startedAt: e, ...t }) => t);
|
|
714
|
-
},
|
|
728
|
+
}, zt = (e) => {
|
|
715
729
|
let t = e.workflows ?? [], n = /* @__PURE__ */ new Map(), r = 0;
|
|
716
730
|
return {
|
|
717
731
|
start: async (i, a) => {
|
|
718
732
|
let o = t.find((e) => e.workflow.name === i);
|
|
719
733
|
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 =
|
|
734
|
+
let s = `wfrun_test_${++r}`, c = Pe(), l = o.workflow.toLayer(o.execute).pipe(p.provideMerge(Ne)), d = /* @__PURE__ */ new Date(), f = o.workflow.execute(a).pipe(u.locally(Me, s), u.provide(c.layer), u.provide(l)), m = (e.ctx.store === void 0 ? f : u.provide(f, fe(e.ctx.store))).pipe(u.either), h = await u.runPromise(m), g = Rt(c.readSteps()), _ = /* @__PURE__ */ new Date(), v;
|
|
721
735
|
if (h._tag === "Right") v = {
|
|
722
736
|
status: "succeeded",
|
|
723
737
|
output: h.right,
|
|
@@ -757,6 +771,154 @@ var Oe = new Set(e), k = 0, A = () => ++k, ke = (e, t) => {
|
|
|
757
771
|
},
|
|
758
772
|
inspect: async (e) => n.get(e) ?? null
|
|
759
773
|
};
|
|
760
|
-
},
|
|
774
|
+
}, Bt = (e, t, n = {}) => {
|
|
775
|
+
let r = n.name ?? "mock", i = [], a = /* @__PURE__ */ new Map(), o = (e, t) => `${e}\u0000${JSON.stringify(t)}`, s = async (n, a, o) => {
|
|
776
|
+
let s = e[n];
|
|
777
|
+
if (s === void 0) throw Error(`makeServiceApiMock: '${n}' is not a service procedure of this api`);
|
|
778
|
+
let c = s.input, l = m.encodeUnknownSync(c)(a), u = m.decodeUnknownSync(c)(l);
|
|
779
|
+
i.push({
|
|
780
|
+
tag: n,
|
|
781
|
+
input: u,
|
|
782
|
+
idempotencyKey: o?.idempotencyKey
|
|
783
|
+
});
|
|
784
|
+
let d = t[n];
|
|
785
|
+
if (d === void 0) throw new h({
|
|
786
|
+
api: r,
|
|
787
|
+
tag: n,
|
|
788
|
+
reason: "transport",
|
|
789
|
+
message: "no handler in makeServiceApiMock"
|
|
790
|
+
});
|
|
791
|
+
let f = await d(u), p = s.output;
|
|
792
|
+
return m.decodeUnknownSync(p)(m.encodeUnknownSync(p)(f));
|
|
793
|
+
}, c = (e) => {
|
|
794
|
+
let t = e.join("."), n = Object.assign((e, n) => s(t, e, n), {
|
|
795
|
+
effect: (e, n) => u.tryPromise({
|
|
796
|
+
try: () => s(t, e, n),
|
|
797
|
+
catch: (e) => e
|
|
798
|
+
}),
|
|
799
|
+
subscribe: (e, n) => {
|
|
800
|
+
let r = o(t, e), i = a.get(r) ?? /* @__PURE__ */ new Set();
|
|
801
|
+
return a.set(r, i), i.add(n.onValue), s(t, e).then(n.onValue, (e) => n.onError?.(e)), { unsubscribe: () => {
|
|
802
|
+
i.delete(n.onValue);
|
|
803
|
+
} };
|
|
804
|
+
}
|
|
805
|
+
});
|
|
806
|
+
return new Proxy(n, { get: (t, n) => {
|
|
807
|
+
if (typeof n == "string") {
|
|
808
|
+
if (n === "effect" || n === "subscribe") return t[n];
|
|
809
|
+
if (n !== "then") return c([...e, n]);
|
|
810
|
+
}
|
|
811
|
+
} });
|
|
812
|
+
};
|
|
813
|
+
return {
|
|
814
|
+
api: new Proxy({}, { get: (e, t) => typeof t == "string" && t !== "then" ? c([t]) : void 0 }),
|
|
815
|
+
calls: (e) => e === void 0 ? [...i] : i.filter((t) => t.tag === e),
|
|
816
|
+
emit: (t, n, r) => {
|
|
817
|
+
let i = e[t], s = i === void 0 ? r : m.decodeUnknownSync(i.output)(m.encodeUnknownSync(i.output)(r));
|
|
818
|
+
for (let e of a.get(o(t, n)) ?? []) e(s);
|
|
819
|
+
}
|
|
820
|
+
};
|
|
821
|
+
}, Vt = () => new Promise((e, t) => {
|
|
822
|
+
let n = O.createServer();
|
|
823
|
+
n.once("error", t), n.listen(0, "127.0.0.1", () => {
|
|
824
|
+
let t = n.address(), r = typeof t == "object" && t ? t.port : 0;
|
|
825
|
+
n.close(() => e(r));
|
|
826
|
+
});
|
|
827
|
+
}), Ht = async (e) => {
|
|
828
|
+
try {
|
|
829
|
+
return (await fetch(`http://127.0.0.1:${e}/internal/readiness`)).status === 200;
|
|
830
|
+
} catch {
|
|
831
|
+
return !1;
|
|
832
|
+
}
|
|
833
|
+
}, Ut = (e) => ze(Re(Le(ze(e, "package.json")).resolve("@voltro/cli/package.json")), "bin", "voltro.mjs"), Wt = 1e4, Gt = (e) => new Promise((t) => {
|
|
834
|
+
if (e.exitCode !== null || e.signalCode !== null) return t();
|
|
835
|
+
let n = setTimeout(() => {
|
|
836
|
+
e.kill("SIGKILL");
|
|
837
|
+
}, Wt);
|
|
838
|
+
e.once("exit", () => {
|
|
839
|
+
clearTimeout(n), t();
|
|
840
|
+
}), e.kill("SIGTERM");
|
|
841
|
+
}), Kt = async (e) => {
|
|
842
|
+
let t = Object.keys(e.apps);
|
|
843
|
+
if (t.length === 0) throw Error("startTestApps: no apps given");
|
|
844
|
+
let n = e.mode ?? "dev", r = e.bootTimeoutMs ?? 3e5, i = e.cli ?? Ut(e.apps[t[0]].root), a = /* @__PURE__ */ new Map();
|
|
845
|
+
for (let e of t) a.set(e, await Vt());
|
|
846
|
+
let o = /* @__PURE__ */ new Map(), s = new Map(t.map((e) => [e, {}]));
|
|
847
|
+
for (let n of e.edges ?? []) {
|
|
848
|
+
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(", ")})`);
|
|
849
|
+
let e = _e();
|
|
850
|
+
o.set(`${n.caller}\u0000${n.callee}`, e), Object.assign(s.get(n.caller), {
|
|
851
|
+
[re(n.binding)]: e,
|
|
852
|
+
[ie(n.binding)]: `ws://127.0.0.1:${a.get(n.callee)}/ws`
|
|
853
|
+
}), Object.assign(s.get(n.callee), { [we(n.caller)]: e });
|
|
854
|
+
}
|
|
855
|
+
let c = [], l = /* @__PURE__ */ new Set(), u = (t) => {
|
|
856
|
+
if (!c.includes(t)) {
|
|
857
|
+
if (l.has(t)) throw Error(`startTestApps: the edges form a cycle through '${t}' — no app can boot first`);
|
|
858
|
+
l.add(t);
|
|
859
|
+
for (let n of e.edges ?? []) n.caller === t && u(n.callee);
|
|
860
|
+
l.delete(t), c.push(t);
|
|
861
|
+
}
|
|
862
|
+
};
|
|
863
|
+
for (let e of t) u(e);
|
|
864
|
+
let d = [], f = /* @__PURE__ */ new Map(), p = async () => {
|
|
865
|
+
await Promise.all(d.map(Gt));
|
|
866
|
+
};
|
|
867
|
+
for (let t of c) {
|
|
868
|
+
let o = e.apps[t], c = a.get(t), l = "", u = Fe(process.execPath, [
|
|
869
|
+
i,
|
|
870
|
+
n,
|
|
871
|
+
...n === "serve" ? ["."] : []
|
|
872
|
+
], {
|
|
873
|
+
cwd: o.root,
|
|
874
|
+
env: {
|
|
875
|
+
...process.env,
|
|
876
|
+
...n === "serve" ? { VOLTRO_SESSION_SECRET: Ie(32).toString("base64url") } : {},
|
|
877
|
+
...o.env,
|
|
878
|
+
...s.get(t),
|
|
879
|
+
PORT: String(c)
|
|
880
|
+
},
|
|
881
|
+
stdio: [
|
|
882
|
+
"ignore",
|
|
883
|
+
"pipe",
|
|
884
|
+
"pipe"
|
|
885
|
+
]
|
|
886
|
+
});
|
|
887
|
+
d.push(u), u.stdout?.on("data", (e) => {
|
|
888
|
+
l += e.toString();
|
|
889
|
+
}), u.stderr?.on("data", (e) => {
|
|
890
|
+
l += e.toString();
|
|
891
|
+
}), u.on("exit", (e, t) => {
|
|
892
|
+
l += `\n[exited] code=${String(e)} signal=${String(t)}`;
|
|
893
|
+
});
|
|
894
|
+
let m = {
|
|
895
|
+
name: t,
|
|
896
|
+
port: c,
|
|
897
|
+
url: `http://127.0.0.1:${c}`,
|
|
898
|
+
wsUrl: `ws://127.0.0.1:${c}/ws`,
|
|
899
|
+
log: () => l,
|
|
900
|
+
stop: () => Gt(u)
|
|
901
|
+
};
|
|
902
|
+
f.set(t, m);
|
|
903
|
+
let h = Date.now() + r;
|
|
904
|
+
for (; !await Ht(c);) {
|
|
905
|
+
if (u.exitCode !== null || u.signalCode !== null || Date.now() > h) {
|
|
906
|
+
await p();
|
|
907
|
+
let e = u.exitCode !== null || u.signalCode !== null ? "exited before it was ready" : `was not ready within ${r} ms`;
|
|
908
|
+
throw Error(`startTestApps: '${t}' ${e}\n${m.log().slice(-4e3)}`);
|
|
909
|
+
}
|
|
910
|
+
await new Promise((e) => setTimeout(e, 250));
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
return {
|
|
914
|
+
apps: Object.fromEntries(f),
|
|
915
|
+
token: (e, t) => {
|
|
916
|
+
let n = o.get(`${e}\u0000${t}`);
|
|
917
|
+
if (n === void 0) throw Error(`startTestApps: no edge ${e} → ${t}`);
|
|
918
|
+
return n;
|
|
919
|
+
},
|
|
920
|
+
stop: p
|
|
921
|
+
};
|
|
922
|
+
}, qt = 1;
|
|
761
923
|
//#endregion
|
|
762
|
-
export {
|
|
924
|
+
export { I as MockClock, z as MockLLM, L as MockWebhooks, qt as TESTING_PRESET_VERSION, wt as TEST_TENANT_ID, Ot as anonymous, Et as apiKey, n as changeDelete, r as changeInsert, i as changeSoftDelete, a as changeUpdate, Xe as defineFactory, xt as describeIfAvailable, St as describeIfReachable, A as fixtureRow, tt as frozenTime, Ke as hydrateFixtureRows, yt as invoke, bt as isTcpReachable, Bt as makeServiceApiMock, Lt as makeSubscribeContext, It as makeTestApp, _t as makeTestContext, zt as makeWorkflowRunner, J as markRestInvocation, rt as mockStore, Ve as nextSequence, ct as outboxNudgesOf, K as pluginsOf, Ct as reportEngineVersion, st as resetAfterCommit, Y as restInvocationOf, at as rpcInterceptorFor, Z as runAfterCommit, lt as runInStoreTransaction, Dt as serviceAccount, ot as serviceLayerFor, Kt as startTestApps, kt as system, R as testEventBus, Tt as user, et as withFrozenTime, it as withRpcConnection };
|