@voltro/cli 0.20.2 → 0.21.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.
Files changed (64) hide show
  1. package/CHANGELOG.md +149 -0
  2. package/THIRD-PARTY-NOTICES.md +61 -61
  3. package/dist/{apiBuild-qZBEu59d.js → apiBuild-BHOtsQkp.js} +93 -80
  4. package/dist/apiBuild-K7M6Rt0U.js +2 -0
  5. package/dist/bin.js +41 -20
  6. package/dist/{commands-kYbfVoPO.js → commands-BZoimvvS.js} +2752 -2633
  7. package/dist/{dbCommand-BPp9R0Wc.js → dbCommand-CDBbZ-Ac.js} +27 -13
  8. package/dist/dbCommand-oADAj6ez.js +2 -0
  9. package/dist/dev-CZQ73Yoh.js +3 -0
  10. package/dist/{dev-OHLsAq4K.js → dev-DKb92NYX.js} +1537 -1527
  11. package/dist/index.js +1 -1
  12. package/dist/{inspectMetrics-DvPNXmGA.js → inspectMetrics-DMjWBQif.js} +576 -567
  13. package/dist/serveCommand-qHJCs0cX.js +1162 -0
  14. package/dist/serveEntry.js +2 -2
  15. package/dist/{start-CXQ7WL1W.js → start-B1x6Z60h.js} +389 -389
  16. package/dist/startEntry.js +2 -2
  17. package/package.json +27 -27
  18. package/templates/AGENTS.md +1 -1
  19. package/templates/agent-docs/_index.md +1 -1
  20. package/templates/agent-docs/cli.md +63 -0
  21. package/templates/agent-docs/database/migrations.md +33 -11
  22. package/templates/agent-docs/database/schema.md +7 -0
  23. package/templates/agent-docs/database/seedsdialects.md +3 -3
  24. package/templates/agent-docs/whats-new.md +136 -9
  25. package/templates/apps/api-ai/package.json +12 -12
  26. package/templates/apps/api-auth/package.json +13 -13
  27. package/templates/apps/api-backend/package.json +12 -12
  28. package/templates/apps/api-backend-deactivation/package.json +12 -12
  29. package/templates/apps/api-backend-mail/package.json +11 -11
  30. package/templates/apps/api-backend-mariadb/package.json +14 -14
  31. package/templates/apps/api-backend-storage/package.json +11 -11
  32. package/templates/apps/api-data-advanced/package.json +13 -13
  33. package/templates/apps/api-durable/package.json +13 -13
  34. package/templates/apps/api-feature-flags/package.json +14 -14
  35. package/templates/apps/api-governance/package.json +13 -13
  36. package/templates/apps/api-kv/package.json +13 -13
  37. package/templates/apps/api-moderation/package.json +13 -13
  38. package/templates/apps/api-observability/package.json +13 -13
  39. package/templates/apps/api-ratelimit/package.json +13 -13
  40. package/templates/apps/api-rbac/package.json +13 -13
  41. package/templates/apps/api-rest/package.json +12 -12
  42. package/templates/apps/api-saas/package.json +16 -16
  43. package/templates/apps/api-search/package.json +13 -13
  44. package/templates/apps/api-versioning/package.json +13 -13
  45. package/templates/apps/api-webhooks/package.json +14 -14
  46. package/templates/apps/changelog/package.json +8 -8
  47. package/templates/apps/edge-functions/package.json +5 -5
  48. package/templates/apps/frontend-admin/package.json +10 -10
  49. package/templates/apps/frontend-app/package.json +10 -10
  50. package/templates/apps/frontend-blank/package.json +9 -9
  51. package/templates/apps/frontend-contact/package.json +11 -11
  52. package/templates/apps/frontend-dashboard/package.json +9 -9
  53. package/templates/apps/frontend-docs/package.json +9 -9
  54. package/templates/apps/frontend-i18n/package.json +8 -8
  55. package/templates/apps/frontend-landing/package.json +9 -9
  56. package/templates/apps/frontend-spa/package.json +9 -9
  57. package/templates/apps/frontend-ssr/package.json +9 -9
  58. package/templates/apps/frontend-ssr-api/package.json +10 -10
  59. package/templates/apps/frontend-static-blog/package.json +8 -8
  60. package/dist/apiBuild-C9aHz4Yh.js +0 -2
  61. package/dist/dbCommand-DtUe-0dM.js +0 -2
  62. package/dist/dev-2AvdzDg2.js +0 -3
  63. package/dist/serveCommand-BKqTKWTX.js +0 -1136
  64. /package/templates/patches/{@effect__cluster@0.59.0.patch → @effect__cluster@0.60.0.patch} +0 -0
@@ -0,0 +1,1162 @@
1
+ import { at as e, t } from "./inspectMetrics-DMjWBQif.js";
2
+ import { s as n } from "./seedRunner-D6eu-u5U.js";
3
+ import { r, t as i } from "./appModuleLoader-C9r9mxZt.js";
4
+ import { f as a, m as o, n as s, p as c, u as l } from "./frameworkTableAssembly-sg41s14F.js";
5
+ import { l as u } from "./fileConventions-CBNPZVOV.js";
6
+ import { p as d } from "./inspect-Dwx0_tUj.js";
7
+ import { $ as ee, A as f, B as p, C as te, D as m, E as ne, F as re, G as ie, H as ae, I as h, K as oe, L as g, M as _, N as se, O as v, P as y, R as ce, S as le, T as ue, V as de, W as fe, _ as b, at as pe, b as me, c as he, et as ge, h as x, i as _e, it as S, j as ve, k as ye, lt as C, m as be, nt as w, o as T, ot as xe, q as Se, r as Ce, rt as we, st as Te, t as Ee, tt as De, u as Oe, ut as ke, v as Ae, w as je, x as E, y as Me, z as D } from "./dev-DKb92NYX.js";
8
+ import { l as O, r as Ne } from "./apiBuild-BHOtsQkp.js";
9
+ import { t as Pe } from "./bootTiming-BdyP9nYw.js";
10
+ import { n as Fe } from "./cliArgs-qdZSElM3.js";
11
+ import { join as Ie } from "node:path";
12
+ import { pathToFileURL as Le } from "node:url";
13
+ import { Cause as Re, Effect as k, Layer as A, ManagedRuntime as ze } from "effect";
14
+ import { createLogger as j } from "@voltro/logger";
15
+ import { existsSync as Be } from "node:fs";
16
+ import { AggregateRegistry as M, Dispatcher as Ve, apiKeyManagementRoutes as N, applySoftDeleteScope as He, applyTenantScope as Ue, attachAnalyticsMirror as We, awaitServerListening as Ge, bindMutation as P, bindStream as Ke, bindSubscription as F, buildTracingLayer as qe, cancelWakeup as Je, compileCron as Ye, dataStoreApiKeyStore as Xe, dataStoreIdempotencyStore as Ze, formatServerOnlyLeaks as Qe, frameworkApiKeyStrategy as $e, installPolicyGuardResolver as et, loadResourceTuples as tt, makeActionRunner as I, makeAdvisoryLockCoordinator as nt, makeApiKeyService as rt, makeApiKeyUsageBuffer as it, makeApiKeyUsageFlusher as at, makeAsyncKv as ot, makeCoordinatedScheduler as st, makeEffectStoreLayer as L, makeLazyWorkflowFacade as ct, makeMutationRunner as lt, makeOneShotQueryRunner as ut, makeQueryDescriptorProducer as dt, makeQueryReauthorizer as ft, makeQuerySubscriber as pt, makeSchemaRegistry as mt, makeWorkflowFacade as ht, makeWorkflowFacadeWithCallerContext as gt, makeWorkflowLayers as _t, noopKv as R, recordSubscriptionDelivery as vt, registerWakeup as yt, resolveSecretsBackend as bt, runProvidedEffect as z, setSecretsBackend as xt, setSystemStoreHandle as St, setTupleSource as Ct, singleCoordinator as wt, startRpcServer as Tt, startScheduler as Et, workflowToRpc as B, wrapStoreWithBootCodec as Dt } from "@voltro/runtime";
17
+ import { RpcGroup as Ot } from "@effect/rpc";
18
+ import { SqlClient as kt } from "@effect/sql";
19
+ import { and as At, ensureTableRegistered as jt, eq as V, or as Mt } from "@voltro/database";
20
+ import { appStorageProvider as H, fromNodeReadable as Nt, getObjectStream as Pt, putObjectStream as U, toNodeReadable as W } from "@voltro/plugin-storage";
21
+ import { AuthMiddleware as Ft, ConnectionInfoMiddleware as G, actionToRpc as K, anonymousSubject as It, mutationToRpc as Lt, queryToRpc as q, streamToRpc as Rt, workflowCancelDescriptor as zt, workflowDomainEventsQueryDescriptor as Bt, workflowEventDeliveriesQueryDescriptor as J, workflowResumeDescriptor as Vt, workflowRunEventsQueryDescriptor as Y, workflowRunQueryDescriptor as X, workflowRunStepsQueryDescriptor as Z, workflowRunsQueryDescriptor as Ht, workflowSignalDescriptor as Ut, workflowUpdateDescriptor as Wt } from "@voltro/protocol";
22
+ import { assertProductionSessionSecret as Gt } from "@voltro/protocol/session";
23
+ import { createHash as Kt, timingSafeEqual as qt } from "node:crypto";
24
+ import { declaredSnapshot as Jt, describeOutcome as Yt, runPlannedMigrations as Xt } from "@voltro/database/sql";
25
+ import { getAuthSessionStrategy as Zt } from "@voltro/plugin-auth";
26
+ import { collectPublicApiRoutes as Qt, restRoutesToHttpRoutes as $t } from "@voltro/protocol/rest";
27
+ import { buildDeliverWebhookExecute as en, buildWebhooksService as tn, defaultIncomingPath as nn, deliverWebhookWorkflow as rn, mountIncomingWebhook as an } from "@voltro/plugin-webhooks";
28
+ import { packBundle as on, runExport as sn, runImport as cn, storageBlobSink as ln, storageRefsBlobSource as un, unpackBundle as dn, unpackBundleToDir as fn } from "@voltro/data-transfer";
29
+ //#region src/bootRefusal.ts
30
+ var pn = "VoltroBootRefusal", mn = (e) => {
31
+ let t = Error(e);
32
+ return t.name = pn, t;
33
+ }, hn = "/_voltro/admin/import", gn = "/_voltro/admin/export", Q = (e, t) => ({
34
+ status: e,
35
+ contentType: "application/json; charset=utf-8",
36
+ body: JSON.stringify(t)
37
+ }), _n = (e) => {
38
+ let t = e.authorization ?? e.Authorization, n = t ? /^Bearer\s+(.+)$/i.exec(t) : null;
39
+ return n ? n[1] : null;
40
+ }, vn = (e, t) => qt(Kt("sha256").update(e).digest(), Kt("sha256").update(t).digest()), yn = (e, t) => {
41
+ if (e.method.toUpperCase() !== "POST") return Q(405, { error: "method not allowed" });
42
+ if (!t || t.length < 16) return Q(503, { error: "data transfer misconfigured (no/weak secret)" });
43
+ let n = _n(e.headers);
44
+ return !n || !vn(n, t) ? Q(401, { error: "unauthorized" }) : null;
45
+ }, bn = j({ scope: "voltro:admin-import" }), xn = "VBUNDLE2", Sn = async function* (e) {
46
+ yield e;
47
+ }, Cn = (e) => async (t) => {
48
+ let n = yn(t, e.secret);
49
+ if (n) return n;
50
+ let r = t.headers["x-import-mode"], i = t.headers["x-import-on-conflict"], a = t.headers["x-import-atomic"] === "1" || t.headers["x-import-atomic"] === "true", o = t.headers["x-import-force"] === "1" || t.headers["x-import-force"] === "true", s = t.rawBody.byteLength >= 8 && Buffer.from(t.rawBody.subarray(0, 8)).toString("latin1") === xn, c, l;
51
+ if (s) c = Sn(t.rawBody), l = "upload";
52
+ else {
53
+ let n;
54
+ try {
55
+ n = JSON.parse(Buffer.from(t.rawBody).toString("utf8") || "{}");
56
+ } catch {
57
+ return Q(400, { error: "body must be a packed bundle archive or { bundleKey } JSON" });
58
+ }
59
+ if (typeof n.bundleKey != "string" || !n.bundleKey) return Q(400, { error: "body.bundleKey (string) is required for the storage transport" });
60
+ if (!e.openArchive) return Q(501, { error: "storage transport not configured on this instance" });
61
+ c = e.openArchive(n.bundleKey), l = "storage";
62
+ }
63
+ let u = await import("node:os"), d = await import("node:fs/promises"), ee = await import("node:path"), f = await d.mkdtemp(ee.join(u.tmpdir(), "voltro-admin-import-"));
64
+ try {
65
+ e.assetSink ? await dn(c, {
66
+ dir: f,
67
+ blobs: e.assetSink
68
+ }) : await fn(c, f);
69
+ let t = await k.runPromiseExit(cn({
70
+ store: e.store,
71
+ bundleDir: f,
72
+ ...r ? { mode: r } : {},
73
+ ...i ? { onConflict: i } : {},
74
+ ...a ? { atomic: a } : {},
75
+ ...e.snapshot ? { targetSnapshot: e.snapshot } : {},
76
+ force: o,
77
+ onWarn: (e) => bn.warn("admin.import", { message: e }),
78
+ ...e.assetSink ? { assetsAlreadyRestored: !0 } : {}
79
+ }));
80
+ if (t._tag === "Failure") {
81
+ let e = t.cause._tag === "Fail" ? t.cause.error : void 0;
82
+ if (e && e._tag === "SchemaDriftError") {
83
+ let t = e;
84
+ return bn.warn("admin.import refused (schema drift)", {
85
+ transport: l,
86
+ bundle: t.bundleFingerprint.slice(0, 16),
87
+ target: t.targetFingerprint.slice(0, 16)
88
+ }), Q(409, {
89
+ error: "schema drift",
90
+ bundleFingerprint: t.bundleFingerprint,
91
+ targetFingerprint: t.targetFingerprint,
92
+ diff: t.diff,
93
+ hint: "re-export against the current schema, or resend with x-import-force: 1"
94
+ });
95
+ }
96
+ throw Error(String(e?.message ?? e ?? "import failed"));
97
+ }
98
+ let n = t.value, s = n.tables.reduce((e, t) => e + t.rowCount, 0);
99
+ return bn.info("admin.import", {
100
+ transport: l,
101
+ tables: n.tables.length,
102
+ rows: s,
103
+ mode: r ?? "upsert",
104
+ atomic: a
105
+ }), Q(200, {
106
+ tables: n.tables.length,
107
+ rows: s,
108
+ transport: l
109
+ });
110
+ } catch (e) {
111
+ return bn.warn("admin.import failed", {
112
+ transport: l,
113
+ error: e?.message ?? String(e)
114
+ }), Q(500, {
115
+ error: "import failed",
116
+ message: e?.message ?? String(e)
117
+ });
118
+ } finally {
119
+ await d.rm(f, {
120
+ recursive: !0,
121
+ force: !0
122
+ });
123
+ }
124
+ }, wn = j({ scope: "voltro:admin-export" }), Tn = async (e) => {
125
+ let t = [];
126
+ for await (let n of e) t.push(Buffer.from(n));
127
+ return new Uint8Array(Buffer.concat(t));
128
+ }, En = (e) => typeof e.tenant == "string" && e.tenant ? {
129
+ kind: "tenant",
130
+ tenantId: e.tenant
131
+ } : Array.isArray(e.tables) && e.tables.length ? {
132
+ kind: "tables",
133
+ tables: e.tables.filter((e) => typeof e == "string")
134
+ } : { kind: "all" }, Dn = (e) => async (t) => {
135
+ let n = yn(t, e.secret);
136
+ if (n) return n;
137
+ let r;
138
+ try {
139
+ r = JSON.parse(Buffer.from(t.rawBody).toString("utf8") || "{}");
140
+ } catch {
141
+ return Q(400, { error: "body must be JSON: { profile?, tenant?, tables?, consistency?, compression?, bundleKey? }" });
142
+ }
143
+ let i = {};
144
+ if (typeof r.profile == "string" && r.profile) {
145
+ if (!e.loadProfile) return Q(501, { error: "server-side profiles not configured on this instance" });
146
+ try {
147
+ i = await e.loadProfile(r.profile);
148
+ } catch (e) {
149
+ return Q(400, {
150
+ error: `profile '${r.profile}' could not be loaded`,
151
+ message: e?.message ?? String(e)
152
+ });
153
+ }
154
+ }
155
+ let a = r.consistency === "snapshot" ? "snapshot" : i.consistency ?? "live", o = (typeof r.compression == "string" ? r.compression : void 0) ?? i.compression, s = i.scope ?? En(r), c = typeof r.bundleKey == "string" && r.bundleKey.length > 0, l = r.assets === !0 && e.assetSource ? { blobs: e.assetSource } : {}, u = await import("node:os"), d = await import("node:fs/promises"), ee = await import("node:path"), f = await d.mkdtemp(ee.join(u.tmpdir(), "voltro-admin-export-"));
156
+ try {
157
+ let t = await k.runPromise(sn({
158
+ store: e.store,
159
+ snapshot: e.snapshot,
160
+ dialect: e.dialect,
161
+ outDir: f,
162
+ ...i.subset ? { subset: i.subset } : {
163
+ scope: s,
164
+ ...e.tenantTables && e.tenantTables.length > 0 ? { tenantTables: e.tenantTables } : {}
165
+ },
166
+ consistency: a,
167
+ ...o ? { compression: o } : {},
168
+ ...i.masking ? { masking: i.masking } : {}
169
+ })), n = t.tables.reduce((e, t) => e + t.rowCount, 0), u = t.masking?.transformed.length ?? 0;
170
+ if (c) {
171
+ if (!e.putArchive) return Q(501, { error: "storage transport not configured on this instance" });
172
+ let i = r.bundleKey;
173
+ return await e.putArchive(i, () => on({
174
+ dir: f,
175
+ ...l
176
+ })), wn.info("admin.export", {
177
+ transport: "storage",
178
+ tables: t.tables.length,
179
+ rows: n,
180
+ masked: u,
181
+ bundleKey: i
182
+ }), Q(200, {
183
+ bundleKey: i,
184
+ tables: t.tables.length,
185
+ rows: n,
186
+ masked: u,
187
+ transport: "storage"
188
+ });
189
+ }
190
+ let d = await Tn(on({
191
+ dir: f,
192
+ ...l
193
+ }));
194
+ return wn.info("admin.export", {
195
+ transport: "download",
196
+ tables: t.tables.length,
197
+ rows: n,
198
+ masked: u,
199
+ bytes: d.byteLength
200
+ }), {
201
+ status: 200,
202
+ contentType: "application/octet-stream",
203
+ body: d,
204
+ headers: {
205
+ "x-export-tables": String(t.tables.length),
206
+ "x-export-rows": String(n),
207
+ "x-export-masked": String(u)
208
+ }
209
+ };
210
+ } catch (e) {
211
+ return wn.warn("admin.export failed", { error: e?.message ?? String(e) }), Q(500, {
212
+ error: "export failed",
213
+ message: e?.message ?? String(e)
214
+ });
215
+ } finally {
216
+ await d.rm(f, {
217
+ recursive: !0,
218
+ force: !0
219
+ });
220
+ }
221
+ }, On = async (e) => {
222
+ let { resolve: t } = await import("node:path"), { existsSync: n } = await import("node:fs"), r = [
223
+ e,
224
+ `${e}.profile.ts`,
225
+ `data-profiles/${e}.ts`,
226
+ `data-profiles/${e}.profile.ts`
227
+ ].map((e) => t(process.cwd(), e)), i = r.find((e) => n(e));
228
+ if (!i) throw Error(`data profile '${e}' not found (looked for: ${r.join(", ")})`);
229
+ let a = await import(i), o = a.default ?? a.profile;
230
+ if (!o) throw Error(`data profile '${i}' has no default export`);
231
+ return o;
232
+ }, kn = (e, t, n = {}) => (async function* () {
233
+ let r = await W((await k.runPromise(Pt(e, t).pipe(k.timeout(n.openTimeout ?? "30 seconds")))).stream), i = n.stallMs ?? 12e4, a, o = () => {
234
+ a && clearTimeout(a), a = setTimeout(() => r.destroy(/* @__PURE__ */ Error(`storage read stalled for ${i}ms reading '${t}'`)), i);
235
+ };
236
+ try {
237
+ o();
238
+ for await (let e of r) o(), yield e instanceof Uint8Array ? e : new Uint8Array(e);
239
+ } finally {
240
+ a && clearTimeout(a), r.destroy();
241
+ }
242
+ })(), An = {
243
+ get: async () => void 0,
244
+ set: async () => {},
245
+ setWithTags: async () => {},
246
+ remove: async () => !1,
247
+ has: async () => !1,
248
+ clear: async () => {},
249
+ invalidateTag: async () => 0,
250
+ wrap: async (e, t, n) => n()
251
+ }, jn = async (e) => {
252
+ St({
253
+ dataStore: e.store,
254
+ schemaRegistry: e.schemaRegistry
255
+ });
256
+ let t = new Ve({
257
+ store: e.store,
258
+ ...e.snapshotCache ? { cache: e.snapshotCache } : {},
259
+ recordDelivery: (e) => vt({
260
+ label: e.label,
261
+ kind: e.kind,
262
+ durationMs: e.durationMs,
263
+ rowCount: e.rowCount
264
+ })
265
+ }), n = e.cache ?? An, r = e.kv ?? R, i, a, o, s = /* @__PURE__ */ new Map(), c = () => `wfctx_${globalThis.crypto?.randomUUID?.() ?? `${Date.now().toString(36)}${Math.random().toString(36).slice(2)}`}`, l = async (t, n, r) => {
266
+ let i = {
267
+ ...r,
268
+ source: r.source ?? `workflow:${t}`
269
+ };
270
+ s.set(n, i);
271
+ try {
272
+ let r = await e.store.query({
273
+ table: "_voltro_workflow_start_contexts",
274
+ order: [],
275
+ predicate: V("executionId", n),
276
+ projection: ["id"],
277
+ skip: void 0,
278
+ take: 1
279
+ }), a = {
280
+ workflowName: t,
281
+ executionId: n,
282
+ subject: i.subject ?? null,
283
+ traceId: i.traceId ?? null,
284
+ source: i.source ?? null,
285
+ parentExecutionId: i.parentExecutionId ?? null,
286
+ parentClosePolicy: i.parentClosePolicy ?? null,
287
+ createdAt: /* @__PURE__ */ new Date()
288
+ };
289
+ r[0] === void 0 ? await e.store.insert("_voltro_workflow_start_contexts", {
290
+ id: c(),
291
+ ...a
292
+ }) : await e.store.update("_voltro_workflow_start_contexts", r[0].id, a);
293
+ } catch (e) {
294
+ process.stderr.write(`[workflow] failed to persist start context for ${t}/${n}: ${e?.message ?? String(e)}\n`);
295
+ }
296
+ }, u = async (t, n) => {
297
+ let r = s.get(n);
298
+ if (r !== void 0) return r;
299
+ try {
300
+ let t = (await e.store.query({
301
+ table: "_voltro_workflow_start_contexts",
302
+ order: [],
303
+ predicate: V("executionId", n),
304
+ projection: void 0,
305
+ skip: void 0,
306
+ take: 1
307
+ }))[0];
308
+ if (t === void 0) return;
309
+ let r = {
310
+ ...t.subject === null ? {} : { subject: t.subject },
311
+ ...t.traceId === null ? {} : { traceId: t.traceId },
312
+ ...t.source === null ? {} : { source: t.source },
313
+ ...t.parentExecutionId === null ? {} : { parentExecutionId: t.parentExecutionId },
314
+ ...t.parentClosePolicy === null ? {} : { parentClosePolicy: t.parentClosePolicy }
315
+ };
316
+ return s.set(n, r), r;
317
+ } catch (e) {
318
+ process.stderr.write(`[workflow] failed to load start context for ${n}: ${e?.message ?? String(e)}\n`);
319
+ return;
320
+ }
321
+ }, d = (e.discovered.workflows?.length ?? 0) > 0 ? ct(() => i) : void 0, f = (e.discovered.workflows?.length ?? 0) > 0 || (e.discovered.eventTriggers?.length ?? 0) > 0, te = f || (e.discovered.workflowWorkers?.length ?? 0) > 0 || e.scheduleCoordination === "cluster", re = e.tenantIsolation === "namespace", ie = (e.log ?? j({ scope: "voltro:serve" })).child("webhooks"), ae, h = e.discovered.webhooks;
322
+ if (h && h.outgoing.length > 0 && e.workflowEngineLayer !== void 0) {
323
+ let t = e.workflowEngineLayer, i = S({
324
+ store: e.store,
325
+ schemaRegistry: e.schemaRegistry,
326
+ cache: n,
327
+ kv: r
328
+ }), a = h.outgoing.map((e) => e.descriptor);
329
+ ae = tn(i, async (e) => {
330
+ let n = rn.execute(e).pipe(k.provide(rn.toLayer(en(i, { events: a })).pipe(A.provideMerge(t))));
331
+ k.runPromise(n).catch((t) => {
332
+ ie.error("deliverWebhook workflow crashed", {
333
+ deliveryId: e.deliveryId,
334
+ targetId: e.targetId
335
+ }, t);
336
+ });
337
+ }, { events: a });
338
+ }
339
+ let oe = /* @__PURE__ */ new Map();
340
+ if (h) for (let e of h.incoming) {
341
+ let t = e.descriptor.path ?? nn(e.descriptor.id), n = `VOLTRO_WEBHOOK_SECRET_${e.descriptor.id.toUpperCase().replace(/[^A-Z0-9]/g, "_")}`, r = an(e.descriptor, {
342
+ resolveSecret: async () => process.env[n] ?? null,
343
+ resolveWorkflows: () => d === void 0 ? void 0 : gt(d, {
344
+ traceId: `incoming:${e.descriptor.id}`,
345
+ source: `incoming:${e.descriptor.id}`
346
+ }),
347
+ log: (e) => {
348
+ let t = {
349
+ webhookId: e.webhookId,
350
+ status: e.status,
351
+ signatureOk: String(e.signatureOk),
352
+ idempotency: e.idempotency,
353
+ durationMs: e.durationMs
354
+ };
355
+ e.status >= 500 ? ie.error("incoming delivery failed", t) : e.status >= 400 ? ie.warn("incoming delivery rejected", t) : ie.info("incoming delivery handled", t);
356
+ }
357
+ });
358
+ oe.set(t, { handle: r });
359
+ }
360
+ et(), Ct((t) => tt(e.store, t.subjectId, t.resourceType, t.resourceId));
361
+ let se = (e.discovered.outboxHandlers?.length ?? 0) > 0 ? p({
362
+ handlers: e.discovered.outboxHandlers ?? [],
363
+ store: e.store,
364
+ log: (e.log ?? j({ scope: "voltro:serve" })).child("outbox")
365
+ }) : void 0, v = ce({
366
+ definitions: (e.discovered.connections ?? []).map((e) => e.definition),
367
+ store: e.store,
368
+ publicUrl: g(e.port ?? 4e3),
369
+ log: (e.log ?? j({ scope: "voltro:serve" })).child("connections")
370
+ }), y = we({
371
+ store: e.store,
372
+ schemaRegistry: e.schemaRegistry,
373
+ cache: n,
374
+ kv: r,
375
+ ...ae === void 0 ? {} : { webhooksService: ae },
376
+ ...d === void 0 ? {} : { workflowsProxy: d },
377
+ eventTriggers: e.discovered.eventTriggers ?? [],
378
+ namespaceIsolationOn: re,
379
+ ...se === void 0 ? {} : { outbox: { nudge: se.nudge } },
380
+ ...v.active ? { connections: { registry: v.registry } } : {}
381
+ }), ue = A.succeed(M, m), fe = (t, n) => {
382
+ let r = t.pipe(k.provide(L(n)));
383
+ return z((e.baseLayer ? r.pipe(k.provide(e.baseLayer)) : r).pipe(k.provide(ue)));
384
+ }, pe = lt({
385
+ store: e.store,
386
+ buildContext: (e, t, n) => y(e, t, n),
387
+ runEffect: fe,
388
+ undoCapture: le()
389
+ }), me = E(), he = I({
390
+ buildContext: (e) => y(e),
391
+ runEffect: fe
392
+ }), ge = {
393
+ buildContext: (e) => y(e),
394
+ finalize: (t, n) => He(Ue(t, e.tenantScopedTables, n.subject.tenantId), e.softDeleteScopedTables),
395
+ provideEffect: (e, t) => e.pipe(k.provide(L(t)))
396
+ }, x = dt(ge), _e = ut({
397
+ ...ge,
398
+ queryRows: (t) => e.store.query(t)
399
+ }), ye = pt({
400
+ ...ge,
401
+ subscribeDescriptor: (e, n, r) => t.subscribe(e, n, r),
402
+ subscribeComputed: (e, n, r) => t.subscribeComputed(e, n, r)
403
+ }), C = {};
404
+ for (let n of [
405
+ ...e.discovered.queries,
406
+ ...me.queries,
407
+ ...v.queries
408
+ ]) C[n.descriptor.name] = (e) => F(x(n, e), t, `subscription.${n.descriptor.name}`, void 0, void 0, ft(n, e));
409
+ for (let t of [
410
+ ...e.discovered.mutations,
411
+ ...me.mutations,
412
+ ...v.mutations
413
+ ]) C[t.descriptor.name] = (e) => P(async (e, n) => pe(t, e, n), e, `mutation.${t.descriptor.name}`);
414
+ for (let t of [...e.discovered.actions, ...v.actions]) C[t.descriptor.name] = (e) => P(async (e, n) => he(t, e, n), e, `action.${t.descriptor.name}`);
415
+ let be = () => `public-${Math.random().toString(36).slice(2, 10)}`, T = [
416
+ ...e.discovered.queries.filter((e) => e.descriptor.publicApi !== void 0).map((e) => ({
417
+ descriptor: e.descriptor,
418
+ invoke: (t, n) => _e(e, t, {
419
+ subject: n.subject,
420
+ traceId: be()
421
+ }),
422
+ subscribe: (t, n, r) => ye(e, t, {
423
+ subject: n.subject,
424
+ traceId: be()
425
+ }, r)
426
+ })),
427
+ ...e.discovered.mutations.filter((e) => e.descriptor.publicApi !== void 0).map((e) => ({
428
+ descriptor: e.descriptor,
429
+ invoke: (t, n) => pe(e, t, {
430
+ subject: n.subject,
431
+ traceId: be()
432
+ })
433
+ })),
434
+ ...e.discovered.actions.filter((e) => e.descriptor.publicApi !== void 0).map((e) => ({
435
+ descriptor: e.descriptor,
436
+ invoke: (t, n) => he(e, t, {
437
+ subject: n.subject,
438
+ traceId: be()
439
+ })
440
+ }))
441
+ ], xe = T.length > 0 ? $t(Qt(T), {
442
+ store: e.store,
443
+ resolveSubject: (t) => e.resolveSubject(t, -1)
444
+ }) : [], Se = e.dataTransferSecret ?? process.env.VOLTRO_DATA_TRANSFER_SECRET, Ce = Se && Se.length >= 16 ? [{
445
+ method: "POST",
446
+ path: hn,
447
+ handle: Cn({
448
+ secret: Se,
449
+ store: e.store,
450
+ ...e.dataTransferSnapshot ? { snapshot: e.dataTransferSnapshot } : {},
451
+ assetSink: ln(H()),
452
+ openArchive: (e) => kn(H(), e)
453
+ })
454
+ }, {
455
+ method: "POST",
456
+ path: gn,
457
+ handle: Dn({
458
+ secret: Se,
459
+ store: e.store,
460
+ snapshot: e.dataTransferSnapshot ?? { tables: [] },
461
+ dialect: e.dataTransferDialect ?? "memory",
462
+ tenantTables: [...e.tenantScopedTables],
463
+ loadProfile: On,
464
+ assetSource: un(H(), e.store),
465
+ putArchive: async (e, t) => {
466
+ let { Readable: n } = await import("node:stream"), r = H(), i = Nt("storage", () => n.from(t()));
467
+ await k.runPromise(U(r, e, i, { contentType: "application/octet-stream" }));
468
+ }
469
+ })
470
+ }] : [], Te = [
471
+ ...e.httpRoutes ?? [],
472
+ ...xe,
473
+ ...Ce,
474
+ ...v.httpRoutes
475
+ ];
476
+ for (let t of e.discovered.streams ?? []) C[t.descriptor.name] = (n) => Ke((r) => {
477
+ let i = y(r), a = t.executor(n, i);
478
+ if (k.isEffect(a)) {
479
+ let t = a.pipe(k.provide(L(i.store)));
480
+ return (e.baseLayer ? t.pipe(k.provide(e.baseLayer)) : t).pipe(k.provide(ue));
481
+ }
482
+ return typeof a == "object" && a && typeof a.then == "function" ? k.promise(() => a) : a;
483
+ }, `stream.${t.descriptor.name}`);
484
+ for (let t of e.discovered.workflows ?? []) C[t.definition.name] = (e) => P(async (e, n) => {
485
+ let r = n;
486
+ return gt(d, {
487
+ subject: r.subject,
488
+ traceId: r.traceId,
489
+ source: "workflow-rpc"
490
+ }).start(t.definition.name, e);
491
+ }, e, `workflow.${t.definition.name}`);
492
+ f && (C[X.name] = (e) => F(x({
493
+ descriptor: X,
494
+ executor: (e) => {
495
+ let t = e.id;
496
+ return {
497
+ table: "_voltro_workflow_runs",
498
+ order: [{
499
+ column: "startedAt",
500
+ direction: "desc"
501
+ }],
502
+ predicate: Mt(V("id", t), V("executionId", t)),
503
+ take: 1,
504
+ skip: void 0,
505
+ projection: void 0
506
+ };
507
+ }
508
+ }, e), t, `subscription.${X.name}`), C[Ht.name] = (e) => F(x({
509
+ descriptor: Ht,
510
+ executor: (e) => {
511
+ let t = e, n = [...t.tag === void 0 ? [] : [V("tag", t.tag)], ...t.status === void 0 ? [] : [V("status", t.status)]], r = Number.isFinite(t.limit) && t.limit !== void 0 ? Math.min(Math.max(Math.floor(t.limit), 1), 500) : 100;
512
+ return {
513
+ table: "_voltro_workflow_runs",
514
+ order: [{
515
+ column: "startedAt",
516
+ direction: "desc"
517
+ }],
518
+ predicate: n.length === 0 ? void 0 : n.length === 1 ? n[0] : At(...n),
519
+ take: r,
520
+ skip: void 0,
521
+ projection: void 0
522
+ };
523
+ }
524
+ }, e), t, `subscription.${Ht.name}`), C[Z.name] = (e) => F(x({
525
+ descriptor: Z,
526
+ executor: (e) => {
527
+ let t = e.runId;
528
+ return {
529
+ table: "_voltro_workflow_run_steps",
530
+ order: [{
531
+ column: "startedAt",
532
+ direction: "asc"
533
+ }],
534
+ predicate: V("runId", t),
535
+ take: 1e3,
536
+ skip: void 0,
537
+ projection: void 0
538
+ };
539
+ }
540
+ }, e), t, `subscription.${Z.name}`), C[Y.name] = (e) => F(x({
541
+ descriptor: Y,
542
+ executor: (e) => {
543
+ let t = e.runId;
544
+ return {
545
+ table: "_voltro_workflow_run_events",
546
+ order: [{
547
+ column: "occurredAt",
548
+ direction: "asc"
549
+ }],
550
+ predicate: V("runId", t),
551
+ take: 1e3,
552
+ skip: void 0,
553
+ projection: void 0
554
+ };
555
+ }
556
+ }, e), t, `subscription.${Y.name}`), C[Bt.name] = (e) => F(x({
557
+ descriptor: Bt,
558
+ executor: (e) => {
559
+ let t = e;
560
+ return {
561
+ table: "_voltro_workflow_events",
562
+ order: [{
563
+ column: "occurredAt",
564
+ direction: "desc"
565
+ }],
566
+ predicate: t.name === void 0 ? void 0 : V("name", t.name),
567
+ take: Math.max(1, Math.min(500, t.limit ?? 100)),
568
+ skip: void 0,
569
+ projection: void 0
570
+ };
571
+ }
572
+ }, e), t, `subscription.${Bt.name}`), C[J.name] = (e) => F(x({
573
+ descriptor: J,
574
+ executor: (e) => {
575
+ let t = e.eventId;
576
+ return {
577
+ table: "_voltro_workflow_event_deliveries",
578
+ order: [{
579
+ column: "createdAt",
580
+ direction: "asc"
581
+ }],
582
+ predicate: V("eventId", t),
583
+ take: 500,
584
+ skip: void 0,
585
+ projection: void 0
586
+ };
587
+ }
588
+ }, e), t, `subscription.${J.name}`), C[zt.name] = (t) => P(async (t, n) => {
589
+ let r = t;
590
+ return await w(e.store, n.subject, { executionId: r.executionId }), await d.cancel(r.workflowName, r.executionId), await Pe(r.workflowName, r.executionId, "workflow.cancel"), { ok: !0 };
591
+ }, t, `action.${zt.name}`), C[Vt.name] = (t) => P(async (t, n) => {
592
+ let r = t;
593
+ return await w(e.store, n.subject, { executionId: r.executionId }), await d.resume(r.workflowName, r.executionId), { ok: !0 };
594
+ }, t, `action.${Vt.name}`), C[Ut.name] = (t) => P(async (t, n) => {
595
+ let r = t;
596
+ return await w(e.store, n.subject, { id: r.id }), d.signal({ id: r.id }, r.signalName, r.payload);
597
+ }, t, `action.${Ut.name}`), C[Wt.name] = (t) => P(async (t, n) => {
598
+ let r = t;
599
+ return await w(e.store, n.subject, { id: r.id }), d.update({ id: r.id }, r.updateName, r.payload, r.timeoutMs === void 0 ? void 0 : { timeoutMs: r.timeoutMs });
600
+ }, t, `action.${Wt.name}`));
601
+ let Ee = [
602
+ ...e.discovered.queries.map((e) => q(e.descriptor)),
603
+ ...e.discovered.mutations.map((e) => Lt(e.descriptor)),
604
+ ...e.discovered.actions.map((e) => K(e.descriptor)),
605
+ ...me.queries.map((e) => q(e.descriptor)),
606
+ ...me.mutations.map((e) => Lt(e.descriptor)),
607
+ ...v.queries.map((e) => q(e.descriptor)),
608
+ ...v.mutations.map((e) => Lt(e.descriptor)),
609
+ ...v.actions.map((e) => K(e.descriptor)),
610
+ ...(e.discovered.streams ?? []).map((e) => Rt(e.descriptor)),
611
+ ...(e.discovered.workflows ?? []).map((e) => B(e.definition)),
612
+ ...f ? [
613
+ q(X),
614
+ q(Ht),
615
+ q(Z),
616
+ q(Y),
617
+ q(Bt),
618
+ q(J),
619
+ K(zt),
620
+ K(Vt),
621
+ K(Ut),
622
+ K(Wt)
623
+ ] : []
624
+ ], De = Ot.make(...Ee).middleware(Ft).middleware(G), Oe = A.succeed(Ft, Ft.of(({ headers: t, clientId: n }) => k.promise(() => e.resolveSubject(t, n)))), ke = A.succeed(G, G.of(({ clientId: e }) => k.succeed({ clientId: e }))), je = e.dormancyTenantId ?? "default", Me = e.dormancy === "sleep" ? {
625
+ register: (t, n, r) => yt(e.store, {
626
+ tenantId: r ?? je,
627
+ kind: "workflow",
628
+ refId: t,
629
+ wakeAt: n
630
+ }),
631
+ cancel: (t, n) => Je(e.store, {
632
+ tenantId: n ?? je,
633
+ kind: "workflow",
634
+ refId: t
635
+ }).then(() => {})
636
+ } : void 0, D = te ? await import("@voltro/workflow") : void 0, O = D?.makeWorkflowRunRecorder({
637
+ store: e.store,
638
+ ...Me === void 0 ? {} : { wakeups: Me }
639
+ }), Ne = async (t, n) => {
640
+ await D.closeWorkflowChildrenForParent({
641
+ store: e.store,
642
+ parentExecutionId: t,
643
+ parentStatus: n,
644
+ recorder: O,
645
+ log: { warn: (e, t) => {
646
+ process.stderr.write(`[workflow] ${e} ${t ? JSON.stringify(t) : ""}\n`);
647
+ } },
648
+ interruptChild: async (t, n) => {
649
+ let r = (e.discovered.workflows ?? []).find((e) => e.definition.name === t);
650
+ if (!r) throw Error(`Unknown child workflow: ${t}`);
651
+ if (!a) throw Error("Workflow runtime is not ready");
652
+ await a.runPromise(r.definition.interrupt(n));
653
+ }
654
+ });
655
+ }, Pe = async (t, n, r) => {
656
+ let i = (await e.store.query({
657
+ table: "_voltro_workflow_runs",
658
+ order: [],
659
+ predicate: V("executionId", n),
660
+ projection: void 0,
661
+ skip: void 0,
662
+ take: 1
663
+ }))[0];
664
+ if (i === void 0) return;
665
+ let a = await e.store.update("_voltro_workflow_runs", i.id, {
666
+ status: "cancelled",
667
+ cancelled: !0,
668
+ completedAt: /* @__PURE__ */ new Date()
669
+ }), o = i.subject?.tenantId ?? void 0;
670
+ a && await O.recordEvent({
671
+ runId: i.id,
672
+ eventType: "run-cancelled",
673
+ payload: {
674
+ reason: r,
675
+ workflowName: t,
676
+ executionId: n,
677
+ ...o == null ? {} : { tenantId: o }
678
+ }
679
+ }), a && await Ne(n, "cancelled");
680
+ }, Fe = [..._t(e.discovered.workflows ?? [], {
681
+ buildContext: (t, n) => e.buildContextForWorkflow?.(t, n) ?? y({
682
+ subject: t.subject,
683
+ traceId: t.traceId
684
+ }, e.store, void 0, `workflow:${n.workflowName}`, { parentExecutionId: n.executionId }),
685
+ resolveStartContext: u
686
+ }, (t, n, r) => {
687
+ let i = D.getWorkflowVersionMetadata(t.definition);
688
+ return D.wrapWorkflowExecuteWithRunRecording({
689
+ name: t.definition.name,
690
+ store: e.store,
691
+ subject: r.subject,
692
+ source: r.source ?? null,
693
+ traceId: r.traceId,
694
+ workflowVersion: i.version,
695
+ workflowCompatibleVersions: i.compatibleWith,
696
+ workflowPatches: i.patches,
697
+ parentExecutionId: r?.parentExecutionId ?? null,
698
+ parentClosePolicy: r?.parentClosePolicy ?? null,
699
+ onParentClose: ({ executionId: e, status: t }) => Ne(e, t),
700
+ recorder: O
701
+ }, n);
702
+ }), ...e.discovered.workflowWorkers ?? []], Ie = Fe.length > 0 ? A.mergeAll(...Fe) : A.empty;
703
+ if (((e.discovered.workflows?.length ?? 0) > 0 || (e.discovered.workflowWorkers?.length ?? 0) > 0 || e.scheduleCoordination === "cluster") && e.workflowEngineLayer !== void 0) {
704
+ let t = Ie.pipe(A.provideMerge(e.workflowEngineLayer));
705
+ a = ze.make(e.baseLayer === void 0 ? t : t.pipe(A.provideMerge(e.baseLayer))), await a.runPromise(k.void), i = (e.discovered.workflows?.length ?? 0) > 0 ? ht({
706
+ workflows: e.discovered.workflows ?? [],
707
+ runEffect: (e) => a.runPromise(e),
708
+ rememberStartContext: l,
709
+ signal: async (t, n, r) => {
710
+ let i = await D.sendWorkflowSignal({
711
+ store: e.store,
712
+ recorder: O,
713
+ target: t,
714
+ signalName: n,
715
+ payload: r
716
+ });
717
+ return await a.runPromise(D.completeSuspendingSignal({
718
+ store: e.store,
719
+ target: t,
720
+ signalName: n,
721
+ payload: r
722
+ })).catch(() => {}), i;
723
+ },
724
+ update: (t, n, r, i) => D.sendWorkflowUpdate({
725
+ store: e.store,
726
+ recorder: O,
727
+ target: t,
728
+ updateName: n,
729
+ payload: r,
730
+ ...i === void 0 ? {} : { options: i }
731
+ }),
732
+ listRuns: (t) => b(e.store, t),
733
+ retry: (t, n) => Ae({
734
+ store: e.store,
735
+ workflows: e.discovered.workflows ?? [],
736
+ runPromise: (e) => a.runPromise(e)
737
+ }, t, n)
738
+ }) : void 0;
739
+ }
740
+ let Le = A.mergeAll(De.toLayer(C), Oe, ke), Re = ee(C, e.discovered.queries.map((e) => e.descriptor.name), f), Be = A.mergeAll(De.toLayer(Re), Oe, ke), N = e.observability, We = await qe({
741
+ ...N && N.spanProcessors.length > 0 ? { extraSpanProcessors: N.spanProcessors } : {},
742
+ ...N && N.metricReaders.length > 0 ? { extraMetricReaders: N.metricReaders } : {},
743
+ ...N && Object.keys(N.resourceAttributes).length > 0 ? { resourceAttributes: N.resourceAttributes } : {},
744
+ ...N && N.sampler !== void 0 ? { sampler: N.sampler } : {}
745
+ }), Ye = !1, Xe = e.store.ping ? () => e.store.ping().then(() => !0).catch(() => !1) : void 0, { server: Ze, shutdown: Qe } = Tt({
746
+ group: De,
747
+ handlersLayer: Le,
748
+ httpHandlersLayer: Be,
749
+ port: e.port ?? 4e3,
750
+ path: e.path ?? "/ws",
751
+ tracerLayer: We.layer,
752
+ healthCheck: {
753
+ isReady: () => Ye,
754
+ ...Xe ? { ping: Xe } : {}
755
+ },
756
+ ...Te.length > 0 ? { httpRoutes: Te } : {},
757
+ ...e.getStore === void 0 ? {} : { getStore: e.getStore },
758
+ ...oe.size > 0 ? { webhookRoutes: oe } : {},
759
+ ...e.inspectRoute === void 0 ? {} : { inspectRoute: e.inspectRoute }
760
+ });
761
+ if (await Ge(Ze), (e.discovered.schedules?.length ?? 0) > 0) {
762
+ let t = (e.scheduleCoordination ?? "single") === "advisoryLock" ? nt(e.store, e.scheduleReplicaId ?? `pid-${process.pid}`) : wt;
763
+ o = await Et(e.discovered.schedules ?? [], {
764
+ store: e.store,
765
+ coordinator: t,
766
+ defaultTrigger: e.scheduleDefaultTrigger ?? "self",
767
+ replicaId: e.scheduleReplicaId ?? `pid-${process.pid}`,
768
+ armSelf: e.scheduleArmSelf ?? !0,
769
+ dormancy: e.dormancy ?? "always-on",
770
+ ...e.dormancyTenantId === void 0 ? {} : { dormancyTenantId: e.dormancyTenantId },
771
+ buildContext: ({ traceId: t, scheduleName: n, subject: r }) => y({
772
+ subject: r,
773
+ traceId: t
774
+ }, e.store, void 0, `schedule:${n}`),
775
+ log: {
776
+ info: (e, t) => {
777
+ process.stdout.write(`[schedule] ${e} ${t ? JSON.stringify(t) : ""}\n`);
778
+ },
779
+ warn: (e, t) => {
780
+ process.stderr.write(`[schedule] ${e} ${t ? JSON.stringify(t) : ""}\n`);
781
+ },
782
+ error: (e, t) => {
783
+ process.stderr.write(`[schedule] ERROR ${e} ${t ? JSON.stringify(t) : ""}\n`);
784
+ },
785
+ debug: () => {}
786
+ },
787
+ ...e.scheduleFireInterceptor === void 0 ? {} : { interceptFire: e.scheduleFireInterceptor },
788
+ ...e.onScheduleRunEvent === void 0 ? {} : { onRunEvent: e.onScheduleRunEvent }
789
+ }), e.onSchedulerReady?.(o);
790
+ }
791
+ let $e = e.log ?? j({ scope: "voltro:serve" }), rt, it;
792
+ if ((e.discovered.subscribers?.length ?? 0) > 0 && (rt = de(e.discovered.subscribers ?? [], e.store, $e.child("subscribe"), e.schemaRegistry)), (e.discovered.reactions?.length ?? 0) > 0) {
793
+ let t = $e.child("reaction");
794
+ it = ve(e.discovered.reactions ?? [], e.store, {
795
+ runAct: async (n, r) => {
796
+ if (n.kind === "workflow") {
797
+ if (d === void 0) {
798
+ t.warn("reaction workflow act skipped — no workflow engine in this app", { workflow: n.workflow });
799
+ return;
800
+ }
801
+ let e = r.new ?? r.old ?? {};
802
+ await gt(d, {
803
+ traceId: `reaction:${n.workflow}`,
804
+ source: `reaction:${n.workflow}`
805
+ }).start(n.workflow, e);
806
+ return;
807
+ }
808
+ await _(n.agent, r, {
809
+ findAgentSend: (t) => e.discovered.actions.find((e) => e.descriptor.name === `${t}.send`),
810
+ runAction: (e, t, n) => Promise.resolve(he(e, t, n)),
811
+ makeSubject: (e) => It(e),
812
+ now: () => Date.now(),
813
+ log: t
814
+ });
815
+ },
816
+ checkBudget: async (n, r) => {
817
+ try {
818
+ let { requireAiBudget: t } = await import("@voltro/ai");
819
+ return (await k.runPromise(k.either(t(e.store, {
820
+ tenantId: n,
821
+ limitUsd: r
822
+ }))))._tag === "Right";
823
+ } catch (e) {
824
+ return t.warn("reaction budget check failed — refusing the act", { tenantId: n }, e), !1;
825
+ }
826
+ }
827
+ }, t);
828
+ }
829
+ let at;
830
+ return (e.discovered.aggregates?.length ?? 0) > 0 && (at = await ne({
831
+ discovered: e.discovered.aggregates ?? [],
832
+ store: e.store,
833
+ log: $e.child("aggregate"),
834
+ ...e.analytics === void 0 ? {} : { analytics: e.analytics },
835
+ ...e.aggregateStorage === void 0 ? {} : { storage: e.aggregateStorage },
836
+ ...e.aggregateCoordinator === void 0 ? {} : { coordinator: e.aggregateCoordinator }
837
+ }), ue = A.succeed(M, at.registry)), Ye = !0, e.bootTiming?.mark("ready"), {
838
+ dispatcher: t,
839
+ server: Ze,
840
+ scheduler: o,
841
+ close: async () => {
842
+ Ye = !1, at?.detach(), it?.(), rt?.(), await o?.shutdown(), t.close(), await a?.dispose(), await new Promise((e) => Ze.close(() => e())), await Qe();
843
+ }
844
+ };
845
+ }, $ = j({ scope: "voltro:serve" }), Mn = (e, t, n) => (e === "production" || e === "staging") && t !== "memory" && n !== "0", Nn = Fe, Pn = async (e) => {
846
+ let t = O(process.cwd());
847
+ if (Be(t)) {
848
+ let n;
849
+ try {
850
+ let e = await import(Le(t).href);
851
+ typeof e.runServe == "function" ? n = e.runServe : $.warn("serve bundle has no runServe export — using the standard serve path");
852
+ } catch (e) {
853
+ $.warn("serve bundle failed to load — using the standard serve path", {}, e);
854
+ }
855
+ if (n) return $.info("serve: booting from the precompiled serve bundle"), n(e);
856
+ }
857
+ return Fn(e);
858
+ }, Fn = async (ee) => {
859
+ let p = Pe();
860
+ process.env.NODE_ENV || (process.env.NODE_ENV = "production");
861
+ try {
862
+ Gt();
863
+ } catch (e) {
864
+ throw mn(e instanceof Error ? e.message : String(e));
865
+ }
866
+ let m = process.cwd(), ne = Number(process.env.PORT ?? Nn(ee, "--port") ?? 4e3), g = await he(m);
867
+ xt(bt(g?.secrets)), await e({
868
+ rawEnv: g?.env,
869
+ appType: "api",
870
+ root: m,
871
+ log: $,
872
+ generateTypes: !1
873
+ }), p.mark("config");
874
+ let _ = (process.env.DB_DIALECT ?? g?.store ?? "memory").toLowerCase(), ce = (_ === "mariadb" || _ === "postgres" || _ === "mssql") && (process.env.CDC ?? "1") !== "0", le = _ === "mariadb" ? "mariadb" : _ === "mssql" ? "mssql" : void 0, de = Ne(m);
875
+ if (!i() && Be(de)) try {
876
+ let e = await import(Le(de).href);
877
+ if (e.modules) {
878
+ let t = {};
879
+ for (let [n, r] of Object.entries(e.modules)) t[Ie(m, n)] = r;
880
+ r(t), $.info("precompiled api bundle loaded", { modules: Object.keys(t).length });
881
+ }
882
+ } catch (e) {
883
+ $.warn("precompiled api bundle failed to load — falling back to source", {}, e);
884
+ }
885
+ let b = await be(m), S = await Oe(b, { cdc: ce && le !== void 0 });
886
+ {
887
+ let e = h(S.serverOnlyLeaks, re(process.env, "strict"), Qe, "`voltro serve`");
888
+ if (e.action === "fail") throw mn(e.message ?? "");
889
+ e.action === "warn" && $.warn(e.message ?? "");
890
+ }
891
+ let ve = b.filter((e) => je.test(e)), w = ve.length > 0 ? await ue(ve, $.child("webhooks")) : void 0, we = s({
892
+ mix: S.featureMix,
893
+ plugins: g?.plugins ?? [],
894
+ cdc: ce && le !== void 0,
895
+ ...le ? { cdcDialect: le } : {}
896
+ }), Ae = g?.analytics !== void 0 && g.analytics.kind !== "noop" && _ !== "memory" ? (await n(_)).makeSqlLayer(T()) : void 0, E = await ie({
897
+ spec: g?.analytics,
898
+ sqlLayer: Ae,
899
+ log: $
900
+ }), O = (() => {
901
+ let e = new Set(S.tables.map((e) => e.tableName)), t = [...S.tables];
902
+ for (let n of [...we, ...E.tables]) e.has(n.tableName) || (e.add(n.tableName), t.push(n));
903
+ return t;
904
+ })();
905
+ for (let e of O) jt(e);
906
+ let Fe = (process.env.NODE_ENV ?? "").toLowerCase();
907
+ if (Mn(Fe, _, process.env.VOLTRO_AUTO_MIGRATE)) {
908
+ let e = (await n(_)).makeSqlLayer(T()), t = await k.runPromise(kt.SqlClient.pipe(k.flatMap((e) => Xt(e, O, {
909
+ appliedBy: `serve:${Fe}`,
910
+ environment: "prod",
911
+ dialectId: _
912
+ })), k.provide(e)));
913
+ t.kind === "prod-mismatch" && ($.error(Yt(t, _)), $.error("serve: refusing to boot — apply the schema first (voltro db apply in a pre-deploy step), or set VOLTRO_AUTO_MIGRATE=0 to bypass this check."), process.exit(1)), $.info(Yt(t, _));
914
+ }
915
+ let j = mt(O);
916
+ p.mark("discover");
917
+ let M = await _e(g, void 0), Ve = Dt(M, _);
918
+ for (let e of Te({
919
+ dialect: String(g?.store ?? process.env.DB_DIALECT ?? "postgres"),
920
+ changeStrategy: (process.env.CDC ?? "1") === "0" ? "inline" : "cdc",
921
+ dbUrl: process.env.DB_URL,
922
+ tables: S.tables.map((e) => ({
923
+ tableName: e.tableName,
924
+ isReactive: e.isReactive === !0
925
+ })),
926
+ querySources: S.queries.flatMap((e) => {
927
+ let t = e.descriptor.source;
928
+ return t === void 0 ? [] : typeof t == "string" ? [t] : [...t];
929
+ })
930
+ })) e.level === "warn" ? $.warn(e.message) : $.info(e.message);
931
+ g?.cache && !process.env.CACHE_BACKEND && (process.env.CACHE_BACKEND = g.cache), g?.cacheRedisUrl && !process.env.CACHE_REDIS_URL && (process.env.CACHE_REDIS_URL = g.cacheRedisUrl), g?.cacheRedisDriver && !process.env.CACHE_REDIS_DRIVER && (process.env.CACHE_REDIS_DRIVER = g.cacheRedisDriver), g?.cacheKeyPrefix && !process.env.CACHE_KEY_PREFIX && (process.env.CACHE_KEY_PREFIX = g.cacheKeyPrefix);
932
+ let { service: He, invalidationBus: Ue, snapshotCache: Ge, cache: P, backend: Ke, dispose: F } = await xe({ env: process.env });
933
+ $.info(`cache backend resolved: ${Ke}` + (Ke === "redis" ? ` (driver ${process.env.CACHE_REDIS_DRIVER ?? "resp"})` : " — in-process, not cross-instance")), M.onChange((e) => {
934
+ k.runFork(Ue.publish(e.table));
935
+ }), g?.kv && !process.env.KV_BACKEND && (process.env.KV_BACKEND = g.kv), g?.kvRedisUrl && !process.env.KV_REDIS_URL && (process.env.KV_REDIS_URL = g.kvRedisUrl), g?.kvKeyPrefix && !process.env.KV_KEY_PREFIX && (process.env.KV_KEY_PREFIX = g.kvKeyPrefix);
936
+ let { kv: qe, service: Je } = await ot({ store: M });
937
+ p.mark("store");
938
+ let et = We({
939
+ store: M,
940
+ sink: E.sink,
941
+ log: $
942
+ }), tt = pe({
943
+ store: M,
944
+ dialect: _
945
+ }), I = g?.plugins ?? [], L = process.env.POD_NAME ?? process.env.HOSTNAME ?? `serve-${process.pid}`, ct, lt;
946
+ _ !== "memory" && (ct = ze.make((await n(_)).makeSqlLayer(T())), lt = await ct.runPromise(kt.SqlClient));
947
+ let ut = st({
948
+ coordinator: [
949
+ "postgres",
950
+ "mariadb",
951
+ "mysql",
952
+ "mssql"
953
+ ].includes(_) ? nt(M, L, $) : wt,
954
+ replicaId: L,
955
+ log: $
956
+ }), dt = [], ft = {
957
+ ...lt ? { sql: lt } : {},
958
+ scheduleCoordinated: (e, t, n) => {
959
+ let r = ut(e, t, n);
960
+ return dt.push(r), r;
961
+ }
962
+ };
963
+ for (let e of I) e.bindDataStore?.(M, ft);
964
+ let pt = I.filter((e) => typeof e.onChangeEvent == "function");
965
+ if (pt.length > 0) {
966
+ let e = M.changeScope ?? "local";
967
+ M.onChange((t) => {
968
+ let n = y(t, e);
969
+ for (let e of pt) k.runFork(e.onChangeEvent(n).pipe(k.catchAllCause((t) => k.sync(() => $.warn(`plugin ${e.name} onChangeEvent failed`, { error: Re.pretty(t) })))));
970
+ });
971
+ }
972
+ let ht = me({
973
+ plugins: I,
974
+ appName: g?.name ?? "voltro-api",
975
+ appType: "api",
976
+ voltroVersion: process.env.npm_package_version ?? "0.0.0",
977
+ log: $
978
+ });
979
+ I.length && await ht.activate(), p.mark("plugins");
980
+ let gt = await ht.gatherObservability(), _t = await x(M, g, _, {
981
+ info: (e, t) => process.stdout.write(`[broadcast] ${e} ${t ? JSON.stringify(t) : ""}\n`),
982
+ warn: (e, t) => process.stderr.write(`[broadcast] ${e} ${t ? JSON.stringify(t) : ""}\n`),
983
+ debug: () => {}
984
+ }), R = g?.apiKeys, vt = (typeof R == "object" ? R.prefix : void 0) ?? "voltro_", yt = R ? Xe(M) : void 0, z = yt ? it({ flush: at(yt) }) : void 0;
985
+ z && process.once("exit", () => {
986
+ z.shutdown();
987
+ });
988
+ let St = yt ? rt(yt, {
989
+ prefix: vt,
990
+ ...z ? { usage: z } : {}
991
+ }) : void 0, Ct = St ? [$e(St, { prefix: vt })] : [], Tt = Ce([...g?.auth?.strategies ?? [], ...Ct], Zt(g?.plugins ?? []), g?.auth?.anonymousTenantRequired ?? !1, g?.auth?.resolveScopes, () => Ve), Et = [...g?.restRoutes ?? [], ...St ? N(St, (typeof R == "object" ? R.managementPath : void 0) ?? "/v1/api-keys") : []], B = g?.idempotency, Ot = B ? {
992
+ store: Ze(M),
993
+ header: (typeof B == "object" ? B.header : void 0) ?? "Idempotency-Key",
994
+ ttlMs: (typeof B == "object" ? B.ttlMs : void 0) ?? 864e5
995
+ } : void 0, At = Et.length > 0 ? $t(Et, {
996
+ store: M,
997
+ resolveSubject: (e) => Tt({
998
+ headers: e,
999
+ clientId: -1
1000
+ }),
1001
+ ...Ot ? { idempotency: Ot } : {}
1002
+ }) : [], V = I.map((e) => e.services).filter((e) => e !== void 0), Mt = A.mergeAll(De({
1003
+ analyticsLayer: E.layer,
1004
+ cacheService: He,
1005
+ kvService: Je,
1006
+ pluginServices: V,
1007
+ userLayers: g?.layers ?? []
1008
+ }), ge(g?.http ?? {})), H = g?.scheduling ?? {}, Nt = H.trigger ?? "self", Pt = /* @__PURE__ */ new Set([
1009
+ "postgres",
1010
+ "mysql",
1011
+ "mariadb",
1012
+ "mssql"
1013
+ ]), U = H.coordination ?? (Pt.has(_) ? "advisoryLock" : "single"), W = U === "cluster" && Pt.has(_), Ft = W ? "cluster" : U === "advisoryLock" && Pt.has(_) ? "advisoryLock" : "single";
1014
+ U === "cluster" && !W && $.warn("scheduling.coordination=cluster needs a sql-backed store except sqlite — falling back to single"), U === "advisoryLock" && !Pt.has(_) && $.warn("scheduling.coordination=advisoryLock needs a SQL store (the claim-row gate) — falling back to single");
1015
+ let G, K = S.workflows.length > 0 || S.workflowWorkers.length > 0 || S.eventTriggers.length > 0 || (w?.outgoing.length ?? 0) > 0 || W, It;
1016
+ if (K) {
1017
+ if (_ === "mssql") {
1018
+ let e = await fe(process.cwd());
1019
+ e && $.warn(e);
1020
+ }
1021
+ let [{ WorkflowEngine: e }, { makeClusterCronLayer: t, workflowEngineLayer: r, resolveRunnerStorage: i }] = await Promise.all([import("@effect/workflow"), import("@voltro/workflow/cluster")]), a = W ? S.schedules.filter((e) => (e.trigger ?? Nt) === "self").map((e) => t({
1022
+ name: e.name,
1023
+ cron: Ye(e),
1024
+ execute: async () => {
1025
+ await G?.fireFromCluster(e.name);
1026
+ }
1027
+ })) : [];
1028
+ It = _ === "memory" ? e.layerMemory : await (async () => {
1029
+ let e = await n(_), t = i({ sqliteFamily: e.id === "sqlite" || e.id === "turso" });
1030
+ return $.info(`workflow engine: cluster-${t}, dialect=${e.id}` + (t === "memory" ? " — single-process durable replay, no cross-pod shard handoff" + (e.id !== "sqlite" && e.id !== "turso" ? " (VOLTRO_WORKFLOW_RUNNER_STORAGE=memory: SqlRunnerStorage/cluster_runners + GET_LOCK skipped)" : "") : "")), r({
1031
+ sqlClientLayer: e.makeSqlLayer(T()),
1032
+ runnerStorage: t,
1033
+ dialectId: e.id,
1034
+ ...process.env.VOLTRO_WORKFLOW_RUNNER_PORT ? { runnerListenPort: Number(process.env.VOLTRO_WORKFLOW_RUNNER_PORT) } : {},
1035
+ ...a.length > 0 ? { extraShardingLayers: a } : {}
1036
+ });
1037
+ })();
1038
+ }
1039
+ let Lt = Me(I, t()), q = b.filter((e) => /\.subscribe\.tsx?$/.test(e)), Rt = q.length > 0 ? await ae(q, $) : [], zt = b.filter((e) => /\.reaction\.tsx?$/.test(e)), Bt = zt.length > 0 ? await se(zt, $) : [], J = b.filter((e) => u.test(e)), Vt = J.length > 0 ? await D(J, $) : [], Y = b.filter((e) => /\.aggregate\.tsx?$/.test(e)), X = Y.length > 0 ? await v(Y, $) : [], Z = ye();
1040
+ if (X.length > 0 && _ !== "memory") try {
1041
+ Z = f((await n(_)).makeSqlLayer(T()));
1042
+ } catch (e) {
1043
+ $.warn("aggregate: SQL storage init failed — falling back to in-process", { err: String(e) });
1044
+ }
1045
+ let Ht = _ === "memory" ? wt : nt(M, `aggregate@${process.pid}`, $), Ut = [], Wt = [], Kt = b.filter((e) => l.test(e));
1046
+ if (Kt.length > 0) {
1047
+ let e = $.child("agent"), t = b.filter((e) => a.test(e));
1048
+ t.length > 0 && await o(t, e);
1049
+ let n = await c(Kt, e);
1050
+ for (let e of n.agents) for (let t of te(e)) (t.kind === "action" ? Ut : Wt).push({
1051
+ file: t.file,
1052
+ descriptor: t.descriptor,
1053
+ executor: t.executor
1054
+ });
1055
+ n.agents.length > 0 && e.info("synthesized agent routes", { agents: n.agents.map((e) => e.descriptor.name) });
1056
+ }
1057
+ p.mark("workflow");
1058
+ let qt = await jn({
1059
+ bootTiming: p,
1060
+ discovered: {
1061
+ queries: [...S.queries, ...Wt],
1062
+ mutations: S.mutations,
1063
+ actions: [...S.actions, ...Ut],
1064
+ streams: S.streams,
1065
+ workflows: S.workflows,
1066
+ workflowWorkers: S.workflowWorkers,
1067
+ eventTriggers: S.eventTriggers,
1068
+ schedules: S.schedules,
1069
+ subscribers: Rt,
1070
+ outboxHandlers: Vt,
1071
+ connections: S.connections,
1072
+ reactions: Bt,
1073
+ aggregates: X,
1074
+ ...w === void 0 ? {} : { webhooks: w }
1075
+ },
1076
+ log: $,
1077
+ analytics: E.sink,
1078
+ aggregateStorage: Z,
1079
+ aggregateCoordinator: Ht,
1080
+ store: M,
1081
+ kv: qe,
1082
+ cache: P,
1083
+ snapshotCache: Ge,
1084
+ schemaRegistry: j,
1085
+ tenantScopedTables: S.tenantScopedTables,
1086
+ softDeleteScopedTables: S.softDeleteScopedTables,
1087
+ dataTransferSnapshot: Jt(O),
1088
+ dataTransferDialect: _,
1089
+ tenantIsolation: (process.env.VOLTRO_TENANT_ISOLATION ?? g?.tenancy?.isolation) === "namespace" ? "namespace" : "shared-schema",
1090
+ resolveSubject: (e, t) => Tt({
1091
+ headers: e,
1092
+ clientId: t
1093
+ }),
1094
+ httpRoutes: [...I.flatMap((e) => e.httpRoutes ?? []), ...At],
1095
+ getStore: () => Ve,
1096
+ ...Mt ? { baseLayer: Mt } : {},
1097
+ ...It === void 0 ? {} : { workflowEngineLayer: It },
1098
+ scheduleDefaultTrigger: Nt,
1099
+ scheduleCoordination: Ft,
1100
+ scheduleArmSelf: !W,
1101
+ dormancy: process.env.VOLTRO_DORMANCY === "sleep" || process.env.VOLTRO_DORMANCY === "always-on" ? process.env.VOLTRO_DORMANCY : g?.dormancy ?? "always-on",
1102
+ scheduleReplicaId: process.env.HOSTNAME ?? `pid-${process.pid}`,
1103
+ ...Lt === void 0 ? {} : { scheduleFireInterceptor: Lt },
1104
+ onSchedulerReady: (e) => {
1105
+ G = e;
1106
+ },
1107
+ inspectRoute: { handle: (e, t, n, r) => d(e, {
1108
+ kind: "api",
1109
+ meta: {
1110
+ name: g?.name ?? "voltro-api",
1111
+ voltroVersion: Ee,
1112
+ port: ne,
1113
+ mode: "start",
1114
+ store: _,
1115
+ cdc: ce ? "on" : "off"
1116
+ },
1117
+ rpc: C(S, m),
1118
+ workflows: ke(S, m),
1119
+ inspectFireSchedule: async ({ name: e, trigger: t }) => {
1120
+ if (!G) throw Error("scheduler not started — this app registers no self-triggered schedules (all schedules are trigger:'external', or there are none).");
1121
+ return { runId: await G.fireNow(e, t) ?? null };
1122
+ }
1123
+ }, t, {
1124
+ method: n,
1125
+ ...r === void 0 ? {} : { body: r }
1126
+ }) ?? {
1127
+ status: 404,
1128
+ contentType: "application/json",
1129
+ body: JSON.stringify({ error: "not an inspect route" })
1130
+ } },
1131
+ observability: gt,
1132
+ port: ne,
1133
+ ...g?.transport?.wsPath ? { path: g.transport.wsPath } : {}
1134
+ });
1135
+ Se(oe([
1136
+ S.queries,
1137
+ S.mutations,
1138
+ S.actions,
1139
+ S.streams
1140
+ ]), (e) => {
1141
+ $.warn(e);
1142
+ }), $.info(`API listening on :${ne}`, {
1143
+ dialect: _,
1144
+ queries: S.queries.length,
1145
+ mutations: S.mutations.length,
1146
+ actions: S.actions.length,
1147
+ streams: S.streams.length,
1148
+ workflows: S.workflows.length,
1149
+ workflowWorkers: S.workflowWorkers.length,
1150
+ schedules: S.schedules.length,
1151
+ scheduleCoordination: Ft
1152
+ }), p.finish($);
1153
+ let Qt = () => {
1154
+ for (let e of dt) e.stop();
1155
+ et.detach(), tt.stop(), F(), ct?.dispose(), setTimeout(() => process.exit(0), 1e4).unref?.(), Promise.resolve(ht.deactivate()).then(() => _t?.close()).then(() => E.dispose()).then(() => qt.close()).then(() => M.close?.()).then(() => process.exit(0)).catch((e) => {
1156
+ console.error("serve: shutdown step failed, exiting anyway:", e), process.exit(0);
1157
+ });
1158
+ };
1159
+ return process.on("SIGINT", Qt), process.on("SIGTERM", Qt), await new Promise(() => {}), 0;
1160
+ };
1161
+ //#endregion
1162
+ export { Pn as n, On as r, Fn as t };