@voltro/cli 0.48.0 → 0.50.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 (101) hide show
  1. package/CHANGELOG.md +125 -0
  2. package/dist/apiBuild-BWo8KI6n.js +2 -0
  3. package/dist/{apiBuild-Dz8TJSxp.js → apiBuild-CFYXo06U.js} +1 -1
  4. package/dist/bin.js +1 -1
  5. package/dist/{build-DLme2ppa.js → build-CnSH-zru.js} +6 -6
  6. package/dist/{checkCommand-Dals7g-I.js → checkCommand-Do3SQbLx.js} +3 -3
  7. package/dist/{checkCommand-BUBqPBlI.js → checkCommand-OL41BMIb.js} +1 -1
  8. package/dist/{codegenCommand-L6vacVRW.js → codegenCommand-BJzaRz6q.js} +39 -47
  9. package/dist/{codemodRunner-DSZjgyCL.js → codemodRunner-De3k0pRd.js} +859 -629
  10. package/dist/{commands-CAxFLqG4.js → commands-By23Ljny.js} +68 -60
  11. package/dist/{dashboardCommand-CJC8Kg-s.js → dashboardCommand-DN1rAABE.js} +1 -1
  12. package/dist/dataCommand-B93TUBIx.js +1306 -0
  13. package/dist/dataProfile-Du3ztYxv.js +51 -0
  14. package/dist/{dbCommand-ZGNItjoJ.js → dbCommand-Bf7Cy0mn.js} +2 -2
  15. package/dist/dbCommand-Bnl7MSGC.js +2 -0
  16. package/dist/{dev-lvnVq5RD.js → dev-1yu42ubu.js} +2 -2
  17. package/dist/{dev-cGGsLNn6.js → dev-BWwE0QjK.js} +1 -1
  18. package/dist/doctorCommand-BmovAwb7.js +2 -0
  19. package/dist/{doctorCommand-BK0qu7eD.js → doctorCommand-y-EbP8st.js} +12 -12
  20. package/dist/{dormancyCommand-CyIk-zq4.js → dormancyCommand-Dc7KRNCG.js} +1 -1
  21. package/dist/{embeddingsCommand-D7TLklps.js → embeddingsCommand-kPs132bB.js} +1 -1
  22. package/dist/{envCommand-BHxKkGXq.js → envCommand-E12zSt51.js} +1 -1
  23. package/dist/{evolveCommand-CQh6dw21.js → evolveCommand-B3nagPVc.js} +2 -2
  24. package/dist/{frameworkTableAssembly-BNod_DKN.js → frameworkTableAssembly-BwJVEKLr.js} +3 -3
  25. package/dist/frameworkTableAssembly-CVDB2hCq.js +2 -0
  26. package/dist/index.js +1 -1
  27. package/dist/{infoCommand-CuNl9cbh.js → infoCommand-Cq0Yz98u.js} +1 -1
  28. package/dist/{interruptedReplace-C1ZI84xi.js → interruptedReplace-C3O3M1MM.js} +2 -1
  29. package/dist/interruptedReplace-CvmiAM9K.js +2 -0
  30. package/dist/{migrate-CL5Ed01M.js → migrate-D3MK9BpK.js} +2 -2
  31. package/dist/{runtimeTrace-C0SlIoQY.js → runtimeTrace-BpLUcrfy.js} +1 -1
  32. package/dist/{sdkgen-BXm7zx7F.js → sdkgen-dl4-WKF6.js} +1 -1
  33. package/dist/serveCommand-8CTzQCY0.js +2362 -0
  34. package/dist/serveCommand-C_WI4TTG.js +2 -0
  35. package/dist/serveEntry.js +5 -5
  36. package/dist/{subcommandNames-CKG5Dz3a.js → subcommandNames-DpYs3DXr.js} +12 -2
  37. package/dist/updateCommand-D91-TZ7E.js +2 -0
  38. package/dist/{updateCommand-BlyXavoG.js → updateCommand-i8JbrLAA.js} +2 -1
  39. package/dist/{webhooksCommand-QlAk_tED.js → webhooksCommand-B0bdyuQ4.js} +1 -1
  40. package/package.json +47 -17
  41. package/templates/AGENTS.md +1 -1
  42. package/templates/agent-docs/_index.md +1 -1
  43. package/templates/agent-docs/cli.md +124 -16
  44. package/templates/agent-docs/whats-new.md +30 -52
  45. package/templates/apps/api-ai/package.json +7 -7
  46. package/templates/apps/api-auth/package.json +8 -8
  47. package/templates/apps/api-backend/package.json +7 -7
  48. package/templates/apps/api-backend-deactivation/package.json +7 -7
  49. package/templates/apps/api-backend-mail/package.json +8 -8
  50. package/templates/apps/api-backend-mariadb/package.json +9 -9
  51. package/templates/apps/api-backend-sqlite/package.json +8 -8
  52. package/templates/apps/api-backend-storage/package.json +8 -8
  53. package/templates/apps/api-cms/package.json +10 -10
  54. package/templates/apps/api-collab/package.json +8 -8
  55. package/templates/apps/api-data-advanced/package.json +8 -8
  56. package/templates/apps/api-durable/package.json +8 -8
  57. package/templates/apps/api-feature-flags/package.json +9 -9
  58. package/templates/apps/api-governance/package.json +8 -8
  59. package/templates/apps/api-kv/package.json +8 -8
  60. package/templates/apps/api-moderation/package.json +8 -8
  61. package/templates/apps/api-observability/package.json +8 -8
  62. package/templates/apps/api-ratelimit/package.json +8 -8
  63. package/templates/apps/api-rbac/package.json +8 -8
  64. package/templates/apps/api-rest/package.json +7 -7
  65. package/templates/apps/api-saas/package.json +11 -11
  66. package/templates/apps/api-saas-starter/package.json +10 -10
  67. package/templates/apps/api-search/package.json +8 -8
  68. package/templates/apps/api-status/package.json +8 -8
  69. package/templates/apps/api-versioning/package.json +8 -8
  70. package/templates/apps/api-webhooks/package.json +9 -9
  71. package/templates/apps/changelog/package.json +6 -6
  72. package/templates/apps/edge-functions/package.json +2 -2
  73. package/templates/apps/frontend-admin/package.json +8 -8
  74. package/templates/apps/frontend-app/package.json +9 -9
  75. package/templates/apps/frontend-auth/package.json +8 -8
  76. package/templates/apps/frontend-blank/package.json +7 -7
  77. package/templates/apps/frontend-cms/package.json +9 -9
  78. package/templates/apps/frontend-collab/package.json +10 -10
  79. package/templates/apps/frontend-contact/package.json +7 -7
  80. package/templates/apps/frontend-dashboard/package.json +7 -7
  81. package/templates/apps/frontend-docs/package.json +7 -7
  82. package/templates/apps/frontend-i18n/package.json +6 -6
  83. package/templates/apps/frontend-landing/package.json +7 -7
  84. package/templates/apps/frontend-portal/package.json +8 -8
  85. package/templates/apps/frontend-saas/package.json +8 -8
  86. package/templates/apps/frontend-spa/package.json +7 -7
  87. package/templates/apps/frontend-ssr/package.json +7 -7
  88. package/templates/apps/frontend-ssr-api/package.json +8 -8
  89. package/templates/apps/frontend-static-blog/package.json +6 -6
  90. package/templates/apps/frontend-status/package.json +8 -8
  91. package/templates/apps/mobile-app/package.json +4 -4
  92. package/dist/apiBuild-DOnvi2zm.js +0 -2
  93. package/dist/dataCommand-hIaq2iKY.js +0 -1052
  94. package/dist/dataProfile-Cm0YVKSy.js +0 -18
  95. package/dist/dbCommand-D1Q33ktl.js +0 -2
  96. package/dist/doctorCommand-CWgUPye-.js +0 -2
  97. package/dist/frameworkTableAssembly-Rft-DPUg.js +0 -2
  98. package/dist/interruptedReplace-DNJ7MKph.js +0 -2
  99. package/dist/serveCommand-CV3YO9L3.js +0 -2035
  100. package/dist/serveCommand-ZP_Cb-yz.js +0 -2
  101. package/dist/updateCommand-CT5AvVg7.js +0 -2
@@ -1,2035 +0,0 @@
1
- import { t as e } from "./nodeEnvironment-cGFAj1J8.js";
2
- import { t } from "./frameworkInspectState-CX2250XB.js";
3
- import { r as n, t as r } from "./appModuleLoader-C9r9mxZt.js";
4
- import { t as i } from "./bootRefusal-pgvDxlrU.js";
5
- import { n as a, r as o } from "./startupRunner-CEqQq7ax.js";
6
- import { t as ee } from "./interruptedReplace-C1ZI84xi.js";
7
- import { $ as s, $t as c, A as l, At as u, Bt as d, C as f, Cn as p, Ct as m, D as h, Dt as g, E as _, En as te, Et as v, F as ne, Ft as re, G as ie, Gt as ae, H as y, Ht as oe, I as se, It as ce, J as le, Jt as b, K as x, Kt as ue, L as S, Lt as de, M as fe, Mt as pe, N as me, Nt as he, O as ge, Ot as _e, P as ve, Pt as ye, Q as be, Qt as xe, R as C, Rt as Se, S as Ce, St as we, T as Te, Tn as Ee, Tt as w, U as De, V as Oe, W as ke, Wt as Ae, X as je, Xt as Me, Y as Ne, Yt as T, Z as Pe, Zt as Fe, _ as E, _n as Ie, _t as Le, an as Re, at as ze, b as Be, bn as Ve, bt as He, c as Ue, cn as We, ct as Ge, dn as Ke, dt as qe, en as Je, et as Ye, f as Xe, fn as Ze, ft as Qe, g as $e, gt as et, h as tt, hn as nt, ht as rt, i as it, in as at, it as ot, j as st, jt as ct, k as lt, kt as ut, ln as dt, lt as ft, m as pt, mn as mt, mt as ht, nn as gt, nt as D, o as O, on as _t, ot as k, p as A, pn as vt, pt as yt, q as bt, qt as xt, r as St, rn as Ct, rt as wt, sn as j, st as Tt, t as Et, tn as Dt, tt as Ot, u as kt, un as At, ut as jt, v as Mt, vn as Nt, vt as M, w as N, wn as Pt, wt as Ft, x as It, xn as Lt, xt as Rt, y as zt, yn as Bt, yt as Vt, zt as Ht } from "./dev-lvnVq5RD.js";
8
- import { n as Ut } from "./cliArgs-D4p8n7EE.js";
9
- import { r as P } from "./appPort-B_HpJ_ck.js";
10
- import { ht as Wt, pt as Gt } from "./webDev-B4IEMB0n.js";
11
- import { r as F } from "./dialectDriver-czCHYpeH.js";
12
- import { i as Kt, n as qt } from "./connectionConfig-Bk9IC7D0.js";
13
- import { c as Jt, n as I, o as Yt } from "./seedRunner-Dgsiwk_e.js";
14
- import { b as Xt, d as Zt, h as Qt, m as $t, p as en, r as tn, y as nn } from "./frameworkTableAssembly-BNod_DKN.js";
15
- import { n as rn, r as an, t as on } from "./declaredSchemaGates-BlcwObhb.js";
16
- import { S as sn, c as cn, n as ln, p as un, s as dn, x as fn } from "./fileConventions-Cof68_BL.js";
17
- import { h as pn, o as mn } from "./inspect-B7U7Cl_Z.js";
18
- import { n as hn } from "./mssqlClusterPatch-_4cE_nun.js";
19
- import { i as gn, n as _n, r as vn, t as yn } from "./webhookDiscovery-CphsQe59.js";
20
- import { t as bn } from "./inspectMetrics-CfdKLh6t.js";
21
- import { r as xn, u as Sn } from "./apiBuild-Dz8TJSxp.js";
22
- import { t as Cn } from "./bootTiming-BdyP9nYw.js";
23
- import { t as wn } from "./dataProfile-Cm0YVKSy.js";
24
- import Tn, { basename as En, join as Dn } from "node:path";
25
- import { createWriteStream as On, existsSync as kn } from "node:fs";
26
- import { pathToFileURL as An } from "node:url";
27
- import { createLogger as L } from "@voltro/logger";
28
- import { AuthMiddleware as jn, ConnectionInfoMiddleware as Mn, actionToRpc as R, anonymousSubject as Nn, isWireReachable as Pn, mutationToRpc as Fn, queryToRpc as z, streamToRpc as In, wireErrorUnion as Ln, workflowCancelDescriptor as Rn, workflowDomainEventsQueryDescriptor as B, workflowEventDeliveriesQueryDescriptor as V, workflowResumeDescriptor as zn, workflowRunEventsQueryDescriptor as Bn, workflowRunQueryDescriptor as Vn, workflowRunStepsQueryDescriptor as Hn, workflowRunsQueryDescriptor as Un, workflowSignalDescriptor as Wn, workflowUpdateDescriptor as Gn } from "@voltro/protocol";
29
- import { IMPORT_RUNS_TABLE as H, allRegisteredTables as Kn, and as qn, connectionIdentity as Jn, describeImportRun as Yn, ensureTableRegistered as Xn, eq as U, or as Zn } from "@voltro/database";
30
- import { Cause as Qn, Effect as W, Layer as G, ManagedRuntime as $n } from "effect";
31
- import { SqlClient as er } from "@effect/sql";
32
- import { declaredSnapshot as tr, describeOutcome as nr, pendingFileMigrationIds as rr, runPlannedMigrations as ir } from "@voltro/database/sql";
33
- import { AggregateRegistry as ar, CostRegistry as K, DORMANCY_WAKEUP_TENANT as or, Dispatcher as sr, ExpectationRegistry as cr, ExperimentRegistry as lr, apiKeyManagementRoutes as ur, attachAnalyticsMirror as dr, attachExpectations as fr, attachExperiments as pr, attachFinops as mr, awaitServerListening as hr, bindMutation as q, bindStream as gr, bindSubscription as _r, buildTracingLayer as vr, cancelWakeup as yr, compileCron as br, dataStoreApiKeyStore as xr, formatServerOnlyLeaks as Sr, formatUnresolvedSources as Cr, frameworkApiKeyStrategy as wr, getResourcePolicy as Tr, installPolicyGuardResolver as Er, loadResourceTuples as Dr, makeActionRunner as Or, makeAdvisoryLockCoordinator as kr, makeApiKeyService as Ar, makeApiKeyUsageBuffer as jr, makeApiKeyUsageFlusher as Mr, makeAsyncKv as Nr, makeAuthMiddlewareLayers as Pr, makeCoordinatedScheduler as Fr, makeEffectStoreLayer as Ir, makeLazyWorkflowFacade as Lr, makeMutationOutputCodec as Rr, makeMutationRunner as zr, makeOneShotQueryRunner as Br, makeQueryDescriptorProducer as Vr, makeQueryFinalizer as Hr, makeQueryReauthorizer as J, makeQuerySubscriber as Ur, makeSchemaRegistry as Wr, makeWorkflowFacade as Gr, makeWorkflowFacadeWithCallerContext as Kr, makeWorkflowLayers as qr, noopKv as Jr, onProcessShutdown as Yr, recordSubscriptionDelivery as Xr, recordWorkflowRun as Zr, registerDefaultTupleSource as Y, registerWakeup as Qr, resolveSecretsBackend as $r, runProvidedEffect as ei, setSecretsBackend as ti, setSystemStoreHandle as ni, shutdownGraceMsFromEnv as ri, singleCoordinator as ii, startRpcServer as ai, startScheduler as oi, stripForbiddenForWire as si, undoCaptureEnabled as ci, unresolvedSources as li, withScopedRequest as ui, workflowToRpc as di, wrapStoreWithBootCodec as fi } from "@voltro/runtime";
34
- import pi, { tmpdir as mi } from "node:os";
35
- import { RpcGroup as hi } from "@effect/rpc";
36
- import { appStorageProvider as gi, durabilityNotice as _i, fromNodeReadable as vi, getObjectStream as yi, putObjectStream as bi, toNodeReadable as xi } from "@voltro/plugin-storage";
37
- import { isEnvContract as Si } from "@voltro/env";
38
- import { assertProductionSessionSecret as Ci } from "@voltro/protocol/session";
39
- import X from "node:fs/promises";
40
- import { createHash as wi, timingSafeEqual as Ti } from "node:crypto";
41
- import { buildDeliverWebhookExecute as Ei, buildWebhooksService as Di, defaultIncomingPath as Oi, deliverWebhookWorkflow as ki, makeDeferredEmitHandler as Ai, mountIncomingWebhook as ji } from "@voltro/plugin-webhooks";
42
- import { getAuthSessionStrategy as Mi } from "@voltro/plugin-auth";
43
- import { registerEmailTemplates as Ni } from "@voltro/plugin-mail";
44
- import { channelFor as Pi, getBroadcastPlugin as Fi } from "@voltro/plugin-broadcast";
45
- import { decideStaging as Ii, isEnvironmentLocal as Li, packBundle as Ri, peekBundle as zi, runExport as Bi, runImport as Vi, storageBlobSink as Hi, storageRefsBlobSource as Ui, unpackBundle as Wi, unpackBundleToDir as Gi } from "@voltro/data-transfer";
46
- //#region src/serveDrain.ts
47
- var Ki = () => Math.max(500, Math.floor(ri() * .6)), qi = (e) => new Promise((t) => setTimeout(t, e)), Ji = (e) => {
48
- let t = /* @__PURE__ */ new Set(), n = /* @__PURE__ */ new Set(), r = 0;
49
- e.on("connection", (e) => {
50
- t.add(e), e.once("close", () => {
51
- t.delete(e), n.delete(e);
52
- });
53
- }), e.on("upgrade", (e, t) => {
54
- n.add(t);
55
- }), e.on("request", (e, t) => {
56
- r += 1, t.once("close", () => {
57
- --r;
58
- });
59
- });
60
- let i, a = async (t = {}) => {
61
- let n = t.budgetMs ?? Ki();
62
- i ??= new Promise((t) => {
63
- e.close(() => {
64
- t();
65
- });
66
- }), e.closeIdleConnections();
67
- let a = Date.now() + n;
68
- for (; r > 0 && Date.now() < a;) await qi(25), e.closeIdleConnections();
69
- e.closeIdleConnections();
70
- }, o = async () => {
71
- i ??= new Promise((t) => {
72
- e.close(() => {
73
- t();
74
- });
75
- });
76
- for (let e of t) if (n.has(e)) try {
77
- e.write(Buffer.from([
78
- 136,
79
- 2,
80
- 3,
81
- 233
82
- ]));
83
- } catch {}
84
- else e.destroy();
85
- for (let e = 0; t.size > 0 && e < 250; e += 25) await qi(25);
86
- for (let e of t) e.destroy();
87
- await i;
88
- };
89
- return {
90
- activeRequests: () => r,
91
- drainRequests: a,
92
- finish: o,
93
- drain: async (e = {}) => {
94
- await a(e), await o();
95
- }
96
- };
97
- }, Yi = "/_voltro/admin/import", Xi = "/_voltro/admin/export", Zi = "/_voltro/admin/imports", Z = (e, t) => ({
98
- status: e,
99
- contentType: "application/json; charset=utf-8",
100
- body: JSON.stringify(t)
101
- }), Qi = (e) => {
102
- let t = e.authorization ?? e.Authorization, n = t ? /^Bearer\s+(.+)$/i.exec(t) : null;
103
- return n ? n[1] : null;
104
- }, $i = (e, t) => Ti(wi("sha256").update(e).digest(), wi("sha256").update(t).digest()), ea = (e, t, n = "POST") => {
105
- if (e.method.toUpperCase() !== n) return Z(405, { error: "method not allowed" });
106
- if (!t || t.length < 16) return Z(503, { error: "data transfer misconfigured (no/weak secret)" });
107
- let r = Qi(e.headers);
108
- return !r || !$i(r, t) ? Z(401, { error: "unauthorized" }) : null;
109
- }, ta = /^[A-Za-z0-9_-]{8,64}$/, na = (e) => ta.test(e), ra = () => Tn.join(pi.tmpdir(), "voltro-import-uploads"), ia = (e) => Tn.join(ra(), e), aa = (e) => Tn.join(ia(e), "archive.bin"), oa = (e) => Tn.join(ia(e), "meta.json"), sa = async (e = Date.now()) => {
110
- let t = 0;
111
- try {
112
- for (let n of await X.readdir(ra())) {
113
- let r = await X.stat(ia(n)).catch(() => null);
114
- r !== null && (e - r.mtimeMs <= 864e5 || (await X.rm(ia(n), {
115
- recursive: !0,
116
- force: !0
117
- }).catch(() => void 0), t++));
118
- }
119
- } catch {}
120
- return t;
121
- }, ca = async (e) => {
122
- if (!na(e)) return {
123
- bytes: 0,
124
- key: null
125
- };
126
- let t = await X.stat(aa(e)).catch(() => null);
127
- if (t === null) return {
128
- bytes: 0,
129
- key: null
130
- };
131
- let n = await X.readFile(oa(e), "utf8").then((e) => JSON.parse(e), () => ({}));
132
- return {
133
- bytes: t.size,
134
- key: n.key ?? null
135
- };
136
- }, la = async (e) => {
137
- if (!na(e.id)) return {
138
- reason: "bad-id",
139
- message: `upload id must match ${String(ta)}`
140
- };
141
- let t = await ca(e.id);
142
- return t.key !== null && t.key !== e.key ? {
143
- reason: "key-mismatch",
144
- message: "this upload id already holds a different bundle. Use a new upload id, or delete the partial upload."
145
- } : e.offset === t.bytes ? (await X.mkdir(ia(e.id), { recursive: !0 }), t.key === null && await X.writeFile(oa(e.id), JSON.stringify({
146
- key: e.key,
147
- startedAt: (/* @__PURE__ */ new Date()).toISOString()
148
- })), await new Promise((t, n) => {
149
- let r = On(aa(e.id), { flags: "a" });
150
- r.on("error", n), r.on("finish", () => t()), r.end(Buffer.from(e.bytes));
151
- }), { total: t.bytes + e.bytes.byteLength }) : {
152
- reason: "offset-mismatch",
153
- message: `chunk starts at ${e.offset} but the server holds ${t.bytes} byte(s)`,
154
- expectedOffset: t.bytes
155
- };
156
- }, ua = async (e) => {
157
- let t = await X.stat(aa(e));
158
- return {
159
- path: aa(e),
160
- bytes: t.size
161
- };
162
- }, da = async (e) => {
163
- na(e) && await X.rm(ia(e), {
164
- recursive: !0,
165
- force: !0
166
- }).catch(() => void 0);
167
- }, Q = L({ scope: "voltro:admin-import" }), fa = "VBUNDLE2", pa = (e) => {
168
- let t = e.req.headers["x-import-rollback-key"];
169
- if (e.mode !== "replace") return { options: {} };
170
- if (typeof t != "string" || t.length === 0) return Q.warn("admin.import: no rollback capture — this run empties the target first, and nothing was asked to be kept. Send `x-import-rollback-key: <storage key>` (voltro data import --rollback-key <key>) to have the instance store the target's current rows before deleting them."), { options: {} };
171
- if (e.deps.putArchive === void 0) return {
172
- options: {},
173
- refusal: Z(409, {
174
- error: "rollback capture requested but this instance has no object storage configured",
175
- hint: "A capture written to the pod would not survive the failure it exists for. Configure storage (the same one the storage-push export uses), or re-send without `x-import-rollback-key` to accept that a run which does not finish can leave the target emptied. Note that CONFIGURED is not the same question as SURVIVES: a `filesystem` provider pointed at a container directory with no volume behind it passes this check and dies with the pod. The run says so when it can observe it — the capture path being on the same filesystem as `/`."
176
- })
177
- };
178
- let n = Dn(mi(), `voltro-rollback-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`), r = e.deps.putArchive;
179
- return {
180
- key: t,
181
- options: {
182
- rollbackDir: n,
183
- onRollbackCaptured: async () => {
184
- let e = _i(n);
185
- e !== void 0 && Q.warn(`admin.import: ${e}`), await r(t, () => Ri({ dir: n })), Q.info("admin.import: rollback capture stored", { bundleKey: t });
186
- }
187
- }
188
- };
189
- }, ma = async function* (e) {
190
- yield e;
191
- }, ha = (e) => async (t) => {
192
- let n = ea(t, e.secret);
193
- if (n) return n;
194
- let r = t.headers["x-import-mode"], i = t.headers["x-import-on-conflict"], a = t.headers["x-import-atomic"], o = a === "0" || a === "false" ? !1 : a === "1" || a === "true" || r === "replace", ee = t.headers["x-import-force"] === "1" || t.headers["x-import-force"] === "true", s = pa({
195
- req: t,
196
- mode: r,
197
- deps: e
198
- });
199
- if (s.refusal !== void 0) return s.refusal;
200
- let c = t.headers["x-import-dry-run"] === "1" || t.headers["x-import-dry-run"] === "true", l = (t.headers["x-import-tables"] ?? "").split(",").map((e) => e.trim()).filter(Boolean);
201
- if (t.headers["x-import-preflight"] === "1" || t.headers["x-import-preflight"] === "true") {
202
- let n;
203
- try {
204
- n = JSON.parse(Buffer.from(t.rawBody).toString("utf8") || "{}");
205
- } catch {
206
- return Z(400, { error: "a preflight body must be JSON: { tables: string[] } or { bundleKey: string }" });
207
- }
208
- let i = Array.isArray(n.tables) ? n.tables.filter((e) => typeof e == "string") : [];
209
- if (i.length === 0 && typeof n.bundleKey == "string" && n.bundleKey !== "" && e.openArchive) {
210
- let t = await zi(e.openArchive(n.bundleKey), ["manifest.json"]).then((e) => e.get("manifest.json"), () => void 0);
211
- if (t !== void 0) try {
212
- i = (JSON.parse(Buffer.from(t).toString("utf8")).tables ?? []).map((e) => e.name).filter((e) => typeof e == "string");
213
- } catch {}
214
- }
215
- if (i.length === 0) return Z(400, {
216
- error: "a preflight needs { tables: string[] } — the bundle's table names, so the staging decision can be made against them",
217
- hint: "or { bundleKey } on an instance with storage configured, where this endpoint reads the table list out of the archive itself"
218
- });
219
- let a = Ii({
220
- mode: r ?? "upsert",
221
- ...e.dialect === void 0 ? {} : { targetDialect: e.dialect },
222
- ...e.snapshot === void 0 ? {} : { targetSnapshot: e.snapshot },
223
- bundleTables: i,
224
- isSkipped: Li,
225
- canRunSql: !0
226
- });
227
- return Z(200, {
228
- preflight: !0,
229
- mode: r ?? "upsert",
230
- atomic: o,
231
- staged: a.active,
232
- ...a.blocker === void 0 ? {} : { reason: a.blocker },
233
- stagedTables: a.tables.length,
234
- rollback: s.key === void 0 ? { taken: !1 } : {
235
- taken: !0,
236
- key: s.key
237
- },
238
- dialect: e.dialect ?? null
239
- });
240
- }
241
- let u = t.headers["x-import-upload-id"], d;
242
- if (u !== void 0 && u !== "") {
243
- if (sa(), t.headers["x-import-probe"] === "1") return Z(200, {
244
- uploadId: u,
245
- bytes: (await ca(u)).bytes
246
- });
247
- let e = t.headers["x-import-upload-key"] ?? "", n = Number(t.headers["x-import-chunk-offset"] ?? "0");
248
- if (e === "" || !Number.isFinite(n) || n < 0) return Z(400, { error: "a chunked upload needs x-import-upload-key and a numeric x-import-chunk-offset" });
249
- let r = await la({
250
- id: u,
251
- key: e,
252
- offset: n,
253
- bytes: t.rawBody
254
- });
255
- if ("reason" in r) return Q.warn("admin.import chunk refused", {
256
- uploadId: u,
257
- reason: r.reason
258
- }), Z(409, {
259
- error: "chunk refused",
260
- reason: r.reason,
261
- message: r.message,
262
- ...r.expectedOffset === void 0 ? {} : { expectedOffset: r.expectedOffset }
263
- });
264
- if (t.headers["x-import-chunk-final"] !== "1") return Z(202, {
265
- uploadId: u,
266
- bytes: r.total
267
- });
268
- d = (await ua(u)).path;
269
- }
270
- let f = t.rawBody.byteLength >= 8 && Buffer.from(t.rawBody.subarray(0, 8)).toString("latin1") === fa, p, m;
271
- if (d !== void 0) {
272
- let { createReadStream: e } = await import("node:fs");
273
- p = e(d), m = "chunked";
274
- } else if (f) p = ma(t.rawBody), m = "upload";
275
- else {
276
- let n;
277
- try {
278
- n = JSON.parse(Buffer.from(t.rawBody).toString("utf8") || "{}");
279
- } catch {
280
- return Z(400, { error: "body must be a packed bundle archive or { bundleKey } JSON" });
281
- }
282
- if (typeof n.bundleKey != "string" || !n.bundleKey) return Z(400, { error: "body.bundleKey (string) is required for the storage transport" });
283
- if (!e.openArchive) return Z(501, { error: "storage transport not configured on this instance" });
284
- p = e.openArchive(n.bundleKey), m = "storage";
285
- }
286
- let h = await import("node:os"), g = await import("node:fs/promises"), _ = await import("node:path"), te = await g.mkdtemp(_.join(h.tmpdir(), "voltro-admin-import-"));
287
- try {
288
- e.assetSink ? await Wi(p, {
289
- dir: te,
290
- blobs: e.assetSink
291
- }) : await Gi(p, te);
292
- let t = await W.runPromiseExit(Vi({
293
- store: e.store,
294
- bundleDir: te,
295
- ...r ? { mode: r } : {},
296
- ...i ? { onConflict: i } : {},
297
- atomic: o,
298
- ...s.options,
299
- recordInterruption: !0,
300
- via: "api",
301
- ...c ? { dryRun: c } : {},
302
- ...l.length > 0 ? { tables: l } : {},
303
- ...e.snapshot ? { targetSnapshot: e.snapshot } : {},
304
- ...e.dialect ? { targetDialect: e.dialect } : {},
305
- force: ee,
306
- onWarn: (e) => Q.warn("admin.import", { message: e }),
307
- ...e.assetSink ? { assetsAlreadyRestored: !0 } : {}
308
- }));
309
- if (t._tag === "Failure") {
310
- let e = t.cause._tag === "Fail" ? t.cause.error : void 0;
311
- if (e && e._tag === "SchemaDriftError") {
312
- let t = e;
313
- return Q.warn("admin.import refused (schema drift)", {
314
- transport: m,
315
- bundle: t.bundleFingerprint.slice(0, 16),
316
- target: t.targetFingerprint.slice(0, 16)
317
- }), Z(409, {
318
- error: "schema drift",
319
- bundleFingerprint: t.bundleFingerprint,
320
- targetFingerprint: t.targetFingerprint,
321
- diff: t.diff,
322
- hint: "each line above would break the load: a table or column the bundle carries that the target cannot take, or a column the target requires that the bundle has no value for. Fix the target schema, re-export against it, or resend with x-import-force: 1 to write anyway."
323
- });
324
- }
325
- let n = typeof e?.reason == "string" ? e.reason : void 0;
326
- if (n !== void 0 && e._tag === "ImportModeError") return Q.warn("admin.import refused (mode)", {
327
- transport: m,
328
- mode: e.mode
329
- }), Z(409, {
330
- error: "import mode refused",
331
- mode: e.mode,
332
- message: n
333
- });
334
- throw Error(n ?? String(e?.message ?? e ?? "import failed"));
335
- }
336
- let n = t.value, a = n.manifest.tables.reduce((e, t) => e + t.rowCount, 0), u = n.rowsWritten;
337
- return Q.info(c ? "admin.import (dry run — nothing written)" : "admin.import", {
338
- transport: m,
339
- tables: n.tablesWritten,
340
- rows: u,
341
- carried: a,
342
- mode: r ?? "upsert",
343
- atomic: o,
344
- ...n.tablesSkipped > 0 ? {
345
- skippedTables: n.tablesSkipped,
346
- skippedRows: n.rowsSkipped
347
- } : {}
348
- }), c || e.refreshSubscriptions?.(`data import: ${n.tablesWritten} table(s), mode ${r ?? "upsert"}`), Z(200, {
349
- tables: n.tablesWritten,
350
- rows: u,
351
- carried: a,
352
- transport: m,
353
- ...n.tablesSkipped > 0 ? {
354
- skippedTables: n.tablesSkipped,
355
- skippedRows: n.rowsSkipped,
356
- fullyResumed: n.fullyResumed
357
- } : {},
358
- ...c ? {
359
- dryRun: !0,
360
- wrote: !1
361
- } : {}
362
- });
363
- } catch (e) {
364
- return Q.warn("admin.import failed", {
365
- transport: m,
366
- error: e?.message ?? String(e)
367
- }), Z(500, {
368
- error: "import failed",
369
- message: e?.message ?? String(e)
370
- });
371
- } finally {
372
- await g.rm(te, {
373
- recursive: !0,
374
- force: !0
375
- }), u !== void 0 && u !== "" && d !== void 0 && await da(u);
376
- }
377
- }, ga = L({ scope: "voltro:admin-export" }), _a = async (e) => {
378
- let t = [];
379
- for await (let n of e) t.push(Buffer.from(n));
380
- return new Uint8Array(Buffer.concat(t));
381
- }, va = (e) => Array.isArray(e) ? e.filter((e) => typeof e == "string") : [], ya = (e) => {
382
- if (typeof e.tenant == "string" && e.tenant) return {
383
- kind: "tenant",
384
- tenantId: e.tenant
385
- };
386
- if (Array.isArray(e.tables) && e.tables.length) return {
387
- kind: "tables",
388
- tables: va(e.tables)
389
- };
390
- let t = va(e.exclude);
391
- return t.length > 0 ? {
392
- kind: "all",
393
- exclude: t
394
- } : { kind: "all" };
395
- }, ba = (e) => async (t) => {
396
- let n = ea(t, e.secret);
397
- if (n) return n;
398
- let r;
399
- try {
400
- r = JSON.parse(Buffer.from(t.rawBody).toString("utf8") || "{}");
401
- } catch {
402
- return Z(400, { error: "body must be JSON: { profile?, tenant?, tables?, consistency?, compression?, bundleKey? }" });
403
- }
404
- let i = {};
405
- if (typeof r.profile == "string" && r.profile) {
406
- if (!e.loadProfile) return Z(501, { error: "server-side profiles not configured on this instance" });
407
- try {
408
- i = await e.loadProfile(r.profile);
409
- } catch (e) {
410
- return Z(400, {
411
- error: `profile '${r.profile}' could not be loaded`,
412
- message: e?.message ?? String(e)
413
- });
414
- }
415
- }
416
- let a = r.consistency === "snapshot" ? "snapshot" : i.consistency ?? "live", o = (typeof r.compression == "string" ? r.compression : void 0) ?? i.compression, ee = i.scope ?? ya(r), s = typeof r.bundleKey == "string" && r.bundleKey.length > 0, c = r.assets === !0 && e.assetSource ? { blobs: e.assetSource } : {}, l = await import("node:os"), u = await import("node:fs/promises"), d = await import("node:path"), f = await u.mkdtemp(d.join(l.tmpdir(), "voltro-admin-export-"));
417
- try {
418
- let t = await W.runPromise(Bi({
419
- store: e.store,
420
- snapshot: e.snapshot,
421
- dialect: e.dialect,
422
- outDir: f,
423
- ...i.subset ? { subset: i.subset } : {
424
- scope: ee,
425
- ...e.tenantTables && e.tenantTables.length > 0 ? { tenantTables: e.tenantTables } : {}
426
- },
427
- consistency: a,
428
- ...o ? { compression: o } : {},
429
- ...i.masking ? { masking: i.masking } : {}
430
- })), n = t.tables.reduce((e, t) => e + t.rowCount, 0), l = t.masking?.transformed.length ?? 0;
431
- if (s) {
432
- if (!e.putArchive) return Z(501, { error: "storage transport not configured on this instance" });
433
- let i = r.bundleKey;
434
- return await e.putArchive(i, () => Ri({
435
- dir: f,
436
- ...c
437
- })), ga.info("admin.export", {
438
- transport: "storage",
439
- tables: t.tables.length,
440
- rows: n,
441
- masked: l,
442
- bundleKey: i
443
- }), Z(200, {
444
- bundleKey: i,
445
- tables: t.tables.length,
446
- rows: n,
447
- masked: l,
448
- transport: "storage"
449
- });
450
- }
451
- let u = await _a(Ri({
452
- dir: f,
453
- ...c
454
- }));
455
- return ga.info("admin.export", {
456
- transport: "download",
457
- tables: t.tables.length,
458
- rows: n,
459
- masked: l,
460
- bytes: u.byteLength
461
- }), {
462
- status: 200,
463
- contentType: "application/octet-stream",
464
- body: u,
465
- headers: {
466
- "x-export-tables": String(t.tables.length),
467
- "x-export-rows": String(n),
468
- "x-export-masked": String(l)
469
- }
470
- };
471
- } catch (e) {
472
- return ga.warn("admin.export failed", { error: e?.message ?? String(e) }), Z(500, {
473
- error: "export failed",
474
- message: e?.message ?? String(e)
475
- });
476
- } finally {
477
- await u.rm(f, {
478
- recursive: !0,
479
- force: !0
480
- });
481
- }
482
- }, xa = async (e, t) => await e.query({
483
- table: H,
484
- order: [{
485
- column: "startedAt",
486
- direction: "desc"
487
- }],
488
- predicate: void 0,
489
- projection: void 0,
490
- skip: 0,
491
- take: t
492
- }), Sa = (e) => ({
493
- ...e,
494
- startedAt: new Date(e.startedAt),
495
- finishedAt: e.finishedAt === null ? null : new Date(e.finishedAt)
496
- }), Ca = (e) => async (t) => {
497
- let n = ea(t, e.secret, "GET");
498
- if (n) return n;
499
- let r = Number(new URLSearchParams(t.query ?? "").get("limit") ?? "20"), i = Number.isFinite(r) ? Math.max(1, Math.min(200, Math.trunc(r))) : 20, a;
500
- try {
501
- a = (await xa(e.store, i)).map(Sa);
502
- } catch (e) {
503
- return Z(409, {
504
- error: "no import history",
505
- message: `this instance has no \`${H}\` table, so no import has been recorded. Run \`voltro db apply\` against it; imports themselves are unaffected.`,
506
- detail: e?.message ?? String(e)
507
- });
508
- }
509
- return Z(200, {
510
- running: a.filter((e) => e.finishedAt === null && e.failure === null).length,
511
- runs: a.map((e) => ({
512
- id: e.id,
513
- startedAt: e.startedAt.toISOString(),
514
- finishedAt: e.finishedAt === null ? null : e.finishedAt.toISOString(),
515
- mode: e.mode,
516
- via: e.via,
517
- bundle: e.bundle,
518
- sourceFingerprint: e.sourceFingerprint,
519
- tablesWritten: e.tablesWritten,
520
- rowsWritten: e.rowsWritten,
521
- failure: e.failure,
522
- line: Yn(e)
523
- }))
524
- });
525
- }, wa = (e, t, n = {}) => (async function* () {
526
- let r = await W.runPromise(yi(e, t).pipe(W.timeout(n.openTimeout ?? "30 seconds"))), i = await xi(r.stream), a = n.stallMs ?? 12e4, o, ee = () => {
527
- o && clearTimeout(o), o = setTimeout(() => i.destroy(/* @__PURE__ */ Error(`storage read stalled for ${a}ms reading '${t}'`)), a);
528
- };
529
- try {
530
- ee();
531
- for await (let e of i) ee(), yield e instanceof Uint8Array ? e : new Uint8Array(e);
532
- } finally {
533
- o && clearTimeout(o), i.destroy();
534
- }
535
- })(), Ta = {
536
- get: async () => void 0,
537
- set: async () => {},
538
- setWithTags: async () => {},
539
- remove: async () => !1,
540
- has: async () => !1,
541
- clear: async () => {},
542
- invalidateTag: async () => 0,
543
- wrap: async (e, t, n) => n()
544
- }, Ea = async (e) => {
545
- d(e.appProcedures ?? e.discovered, {
546
- defaultDeny: e.security?.defaultDeny ?? !0,
547
- commandHint: "`voltro serve`"
548
- }), ni({
549
- dataStore: e.store,
550
- schemaRegistry: e.schemaRegistry
551
- });
552
- let t = (e.discovered.budgets?.length ?? 0) > 0, n, r = new sr({
553
- store: e.store,
554
- ...e.snapshotCache ? { cache: e.snapshotCache } : {},
555
- ...e.reactive === void 0 ? {} : { reactive: e.reactive },
556
- ...t ? { recordCost: (e) => n?.record(e) } : {},
557
- recordDelivery: (e) => Xr({
558
- label: e.label,
559
- kind: e.kind,
560
- durationMs: e.durationMs,
561
- rowCount: e.rowCount
562
- })
563
- }), i = e.cache ?? Ta, a = e.kv ?? Jr, o, ee = () => void 0, c, l, u, f, p, m, h, _ = ue({
564
- store: e.store,
565
- warn: (e, t) => {
566
- process.stderr.write(`[workflow] ${e} ${JSON.stringify(t)}\n`);
567
- }
568
- }), te = _.remember, ae = _.resolve, oe = xt({
569
- authority: e.authority,
570
- getStore: () => e.store
571
- }), S = (e.discovered.workflows?.length ?? 0) > 0 ? Lr(() => o) : void 0, de = (e.discovered.workflows?.length ?? 0) > 0 || (e.discovered.eventTriggers?.length ?? 0) > 0, he = de || (e.discovered.workflowWorkers?.length ?? 0) > 0 || e.scheduleCoordination === "cluster", ge = e.tenantIsolation === "namespace", _e = (e.log ?? L({ scope: "voltro:serve" })).child("webhooks"), ve, ye, C = e.discovered.webhooks;
572
- if (C && C.outgoing.length > 0 && e.workflowEngineLayer !== void 0) {
573
- e.workflowEngineLayer;
574
- let t = dt({
575
- store: e.store,
576
- schemaRegistry: e.schemaRegistry,
577
- cache: i,
578
- kv: a
579
- }), n = C.outgoing.map((e) => e.descriptor);
580
- ye = ki.toLayer(Ei(t, { events: n })), ve = Di(t, async (e) => {
581
- let t = u;
582
- if (t === void 0) {
583
- _e.error("webhook delivery skipped — the workflow runtime was never built. This is a framework defect, not a configuration problem: report it with your engine setting. Deliveries are NOT queued and will not be retried.", {
584
- deliveryId: e.deliveryId,
585
- targetId: e.targetId
586
- });
587
- return;
588
- }
589
- t.runPromise(ki.execute(e)).catch((t) => {
590
- _e.error("deliverWebhook workflow crashed", {
591
- deliveryId: e.deliveryId,
592
- targetId: e.targetId
593
- }, t);
594
- });
595
- }, { events: n });
596
- }
597
- let Se = /* @__PURE__ */ new Map();
598
- if (C) for (let e of C.incoming) {
599
- let t = e.descriptor.path ?? Oi(e.descriptor.id), n = `VOLTRO_WEBHOOK_SECRET_${e.descriptor.id.toUpperCase().replace(/[^A-Z0-9]/g, "_")}`, r = ji(e.descriptor, {
600
- resolveSecret: async () => process.env[n] ?? null,
601
- resolveWorkflows: () => S === void 0 ? void 0 : Kr(S, {
602
- traceId: `incoming:${e.descriptor.id}`,
603
- source: `incoming:${e.descriptor.id}`
604
- }),
605
- log: (e) => {
606
- let t = {
607
- webhookId: e.webhookId,
608
- status: e.status,
609
- signatureOk: String(e.signatureOk),
610
- idempotency: e.idempotency,
611
- durationMs: e.durationMs
612
- };
613
- e.status >= 500 ? _e.error("incoming delivery failed", t) : e.status >= 400 ? _e.warn("incoming delivery rejected", t) : _e.info("incoming delivery handled", t);
614
- }
615
- });
616
- Se.set(t, { handle: r });
617
- }
618
- Er(), Y((t) => Dr(e.store, t.subjectId, t.resourceType, t.resourceId)) || L({ scope: "voltro:serve" }).info("policy guards: using the app-registered tuple source");
619
- let Ce = [], Te = [...e.discovered.outboxHandlers ?? [], ..._n((C?.outgoing.length ?? 0) + (C?.incoming.length ?? 0) + (C?.providers.length ?? 0), []) ? [{
620
- file: "<framework>/webhooks",
621
- id: "voltro-webhook-emit",
622
- definition: Ai(() => ve)
623
- }] : []], Ee = Te.length > 0 ? Fe({
624
- handlers: Te,
625
- store: e.store,
626
- log: (e.log ?? L({ scope: "voltro:serve" })).child("outbox"),
627
- onChange: (t) => e.store.onChange((e) => t({
628
- table: e.table,
629
- op: e.op
630
- })),
631
- onShutdown: (e) => {
632
- Ce.push(e);
633
- }
634
- }) : void 0, w = T({
635
- definitions: (e.discovered.connections ?? []).map((e) => e.definition),
636
- store: e.store,
637
- publicUrl: b(e.port ?? 4e3),
638
- log: (e.log ?? L({ scope: "voltro:serve" })).child("connections")
639
- });
640
- st({
641
- events: e.discovered.events ?? [],
642
- rpcTags: [
643
- ...e.discovered.queries.map((e) => e.descriptor.name),
644
- ...e.discovered.mutations.map((e) => e.descriptor.name),
645
- ...e.discovered.actions.map((e) => e.descriptor.name),
646
- ...(e.discovered.streams ?? []).map((e) => e.descriptor.name)
647
- ]
648
- });
649
- let Ae = (e.log ?? L({ scope: "voltro:serve" })).child("events"), je = e.broadcastNamespace ?? $e(e.plugins, void 0), Me = E(e.plugins, je, Ae), Ne = e.membership?.instanceId ?? process.env.POD_NAME ?? process.env.HOSTNAME ?? `serve-${process.pid}`, Ie = e.membership ?? Mt(e.plugins, {
650
- instanceId: Ne,
651
- namespace: je,
652
- meta: { mode: "serve" },
653
- logger: Ae
654
- }), Le = fe({
655
- events: e.discovered.events ?? [],
656
- origin: Ne,
657
- ...Me.publishRemote === void 0 ? {} : { publishRemote: Me.publishRemote }
658
- }), Re = (e.discovered.events ?? []).length > 0 ? await Me.attach(Le.bus) : null, ze = We({
659
- store: e.store,
660
- schemaRegistry: e.schemaRegistry,
661
- cache: i,
662
- kv: a,
663
- ...ve === void 0 ? {} : { webhooksService: ve },
664
- ...S === void 0 ? {} : { workflowsProxy: S },
665
- eventTriggers: e.discovered.eventTriggers ?? [],
666
- namespaceIsolationOn: ge,
667
- ...e.ensureTenantProvisioned === void 0 ? {} : { ensureTenantProvisioned: e.ensureTenantProvisioned },
668
- ...e.resolveResidentStore === void 0 ? {} : { resolveResidentStore: e.resolveResidentStore },
669
- ...Ee === void 0 ? {} : { outbox: { nudge: Ee.nudge } },
670
- ...w.active ? { connections: { registry: w.registry } } : {},
671
- eventBus: Le.bus
672
- }), Be = G.succeed(ar, g), Ve = G.succeed(cr, Rt), Ue = G.succeed(K, He), Ke = G.succeed(lr, we), Je = (t, n) => {
673
- let r = t.pipe(W.provide(Ir(n)));
674
- return (e.baseLayer ? r.pipe(W.provide(e.baseLayer)) : r).pipe(W.provide(Be)).pipe(W.provide(Ve)).pipe(W.provide(Ue)).pipe(W.provide(Ke));
675
- }, Xe = (e, t) => {
676
- let n = Je(e, t);
677
- return ei(n);
678
- }, Ze = bn(), tt = le(e.plugins ?? [], Ze), nt = Oe({
679
- plugins: e.plugins ?? [],
680
- metrics: Ze,
681
- log: e.log ?? L({ scope: "voltro:serve" })
682
- }), rt = x(e.plugins ?? [], Ze), it = e.security?.defaultDeny ?? !0, ot = zr({
683
- store: e.store,
684
- defaultDeny: it,
685
- recordMetric: (e) => {
686
- Ze.record(e);
687
- },
688
- ...tt.mutation === void 0 ? {} : { interceptor: tt.mutation },
689
- buildContext: (e, t, n) => ze(e, t, n),
690
- runEffect: Xe,
691
- undoCapture: s()
692
- }), lt = be();
693
- {
694
- let t = Ye();
695
- t !== void 0 && (e.log ?? L({ scope: "voltro:serve" })).info(t);
696
- }
697
- let ut = Pe({
698
- store: e.store,
699
- ...e.approvals === void 0 ? {} : { defaultExpiryMs: e.approvals.defaultExpiryMs }
700
- }), pt = Or({
701
- defaultDeny: it,
702
- buildContext: (e) => ze(e),
703
- runEffect: Xe,
704
- recordMetric: (e) => {
705
- Ze.record(e);
706
- },
707
- ...tt.action === void 0 ? {} : { interceptor: tt.action }
708
- }), mt = Hr({
709
- tenantScopedTables: e.tenantScopedTables,
710
- softDeleteScopedTables: e.softDeleteScopedTables
711
- }), ht = {
712
- defaultDeny: it,
713
- buildContext: (e) => ze(e),
714
- finalize: (e, t) => mt(e, t.subject),
715
- provideEffect: Je,
716
- ...tt.query === void 0 ? {} : { interceptor: tt.query }
717
- }, D = Vr(ht), O = Br({
718
- ...ht,
719
- queryRows: (t, n) => e.store.query(t).then((e) => si(t.table, e, n.subject))
720
- }), _t = Ur({
721
- ...ht,
722
- subscribeDescriptor: (e, t, n) => r.subscribe(e, t, n),
723
- subscribeComputed: (e, t, n) => r.subscribeComputed(e, t, n)
724
- }), k = (e) => e.filter((e) => Pn(e.descriptor)), A = {};
725
- for (let t of [
726
- ...k(e.discovered.queries),
727
- ...lt.queries,
728
- ...ut.queries,
729
- ...w.queries
730
- ]) A[t.descriptor.name] = (e) => _r(D(t, e), r, `subscription.${t.descriptor.name}`, void 0, void 0, J(t, e));
731
- for (let t of [
732
- ...k(e.discovered.mutations),
733
- ...lt.mutations,
734
- ...ut.mutations,
735
- ...w.mutations
736
- ]) {
737
- let n = Rr(t.descriptor.output);
738
- A[t.descriptor.name] = (r) => q(async (e, n) => ot(t, e, n), r, `mutation.${t.descriptor.name}`, n, e.idempotency, Ln(t.descriptor, "mutation"));
739
- }
740
- for (let t of [...k(e.discovered.actions), ...w.actions]) {
741
- let n = Rr(t.descriptor.output);
742
- A[t.descriptor.name] = (r) => q(async (e, n) => pt(t, e, n), r, `action.${t.descriptor.name}`, n, e.idempotency, Ln(t.descriptor, "action"));
743
- }
744
- let vt = () => `public-${Math.random().toString(36).slice(2, 10)}`, yt = [
745
- ...e.discovered.queries.filter((e) => e.descriptor.publicApi !== void 0).map((e) => ({
746
- descriptor: e.descriptor,
747
- invoke: (t, n) => O(e, t, {
748
- subject: n.subject,
749
- traceId: vt()
750
- }),
751
- subscribe: (t, n, r) => _t(e, t, {
752
- subject: n.subject,
753
- traceId: vt()
754
- }, r)
755
- })),
756
- ...e.discovered.mutations.filter((e) => e.descriptor.publicApi !== void 0).map((e) => ({
757
- descriptor: e.descriptor,
758
- invoke: (t, n) => ot(e, t, {
759
- subject: n.subject,
760
- traceId: vt()
761
- })
762
- })),
763
- ...e.discovered.actions.filter((e) => e.descriptor.publicApi !== void 0).map((e) => ({
764
- descriptor: e.descriptor,
765
- invoke: (t, n) => pt(e, t, {
766
- subject: n.subject,
767
- traceId: vt()
768
- })
769
- }))
770
- ], bt = {
771
- candidates: ce({
772
- queries: e.discovered.queries,
773
- mutations: e.discovered.mutations,
774
- actions: e.discovered.actions,
775
- descriptorOf: (e) => e.descriptor,
776
- runQuery: (e, t, n) => Promise.resolve(O(e, t, n)),
777
- runMutation: (e, t, n) => Promise.resolve(ot(e, t, n)),
778
- runAction: (e, t, n) => Promise.resolve(pt(e, t, n))
779
- }),
780
- policy: e.agents?.tools ?? {},
781
- mcpEnabled: e.agents?.mcp === !0,
782
- resolveSubject: (t) => e.resolveSubject(t, -1).then((e) => e.subject)
783
- }, St = gt({
784
- ...e.restRoutes === void 0 ? {} : { restRoutes: e.restRoutes },
785
- publicApiEntries: yt,
786
- store: e.store,
787
- resolveSubject: (t) => e.resolveSubject(t, -1).then((e) => e.subject),
788
- ...e.idempotency === void 0 ? {} : { idempotency: e.idempotency },
789
- log: e.log ?? L({ scope: "voltro:serve" })
790
- }), Ct = e.dataTransferSecret ?? process.env.VOLTRO_DATA_TRANSFER_SECRET, wt = async (e, t) => {
791
- let { Readable: n } = await import("node:stream"), r = gi(), i = vi("storage", () => n.from(t()));
792
- await W.runPromise(bi(r, e, i, { contentType: "application/octet-stream" }));
793
- }, Tt = Ct && Ct.length >= 16 ? [
794
- {
795
- method: "POST",
796
- path: Yi,
797
- handle: ha({
798
- secret: Ct,
799
- store: e.store,
800
- ...e.dataTransferSnapshot ? { snapshot: e.dataTransferSnapshot } : {},
801
- ...e.dataTransferDialect ? { dialect: e.dataTransferDialect } : {},
802
- assetSink: Hi(gi()),
803
- openArchive: (e) => wa(gi(), e),
804
- refreshSubscriptions: (e) => {
805
- r.refreshAll(e);
806
- },
807
- putArchive: wt,
808
- ...e.dataTransferDialect ? { dialect: e.dataTransferDialect } : {}
809
- })
810
- },
811
- {
812
- method: "GET",
813
- path: Zi,
814
- handle: Ca({
815
- secret: Ct,
816
- store: e.store
817
- })
818
- },
819
- {
820
- method: "POST",
821
- path: Xi,
822
- handle: ba({
823
- secret: Ct,
824
- store: e.store,
825
- snapshot: e.dataTransferSnapshot ?? { tables: [] },
826
- dialect: e.dataTransferDialect ?? "memory",
827
- tenantTables: [...e.tenantScopedTables],
828
- loadProfile: wn,
829
- assetSource: Ui(gi(), e.store),
830
- putArchive: wt
831
- })
832
- }
833
- ] : [], Et = [
834
- ...e.httpRoutes ?? [],
835
- ...St.httpRoutes,
836
- ...Tt,
837
- ...w.httpRoutes
838
- ];
839
- Object.assign(A, Le.handlers);
840
- for (let t of k(e.discovered.streams ?? [])) A[t.descriptor.name] = (n) => gr((r) => ui(r, (r) => {
841
- let i = ze(r), a = t.executor(n, i);
842
- if (W.isEffect(a)) {
843
- let t = a.pipe(W.provide(Ir(i.store)));
844
- return (e.baseLayer ? t.pipe(W.provide(e.baseLayer)) : t).pipe(W.provide(Be)).pipe(W.provide(Ve)).pipe(W.provide(Ue)).pipe(W.provide(Ke));
845
- }
846
- return typeof a == "object" && a && typeof a.then == "function" ? W.promise(() => a) : a;
847
- }), `stream.${t.descriptor.name}`);
848
- for (let t of e.discovered.workflows ?? []) A[t.definition.name] = (e) => q(async (e, n) => {
849
- let r = n;
850
- return Kr(S, {
851
- subject: r.subject,
852
- traceId: r.traceId,
853
- source: "workflow-rpc"
854
- }).start(t.definition.name, e);
855
- }, e, `workflow.${t.definition.name}`);
856
- de && (A[Vn.name] = (e) => _r(D({
857
- descriptor: Vn,
858
- executor: (e) => {
859
- let t = e.id;
860
- return {
861
- table: "_voltro_workflow_runs",
862
- order: [{
863
- column: "startedAt",
864
- direction: "desc"
865
- }],
866
- predicate: Zn(U("id", t), U("executionId", t)),
867
- take: 1,
868
- skip: void 0,
869
- projection: void 0
870
- };
871
- }
872
- }, e), r, `subscription.${Vn.name}`), A[Un.name] = (e) => _r(D({
873
- descriptor: Un,
874
- executor: (e) => {
875
- let t = e, n = [...t.tag === void 0 ? [] : [U("tag", t.tag)], ...t.status === void 0 ? [] : [U("status", t.status)]], r = Number.isFinite(t.limit) && t.limit !== void 0 ? Math.min(Math.max(Math.floor(t.limit), 1), 500) : 100;
876
- return {
877
- table: "_voltro_workflow_runs",
878
- order: [{
879
- column: "startedAt",
880
- direction: "desc"
881
- }],
882
- predicate: n.length === 0 ? void 0 : n.length === 1 ? n[0] : qn(...n),
883
- take: r,
884
- skip: void 0,
885
- projection: void 0
886
- };
887
- }
888
- }, e), r, `subscription.${Un.name}`), A[Hn.name] = (e) => _r(D({
889
- descriptor: Hn,
890
- executor: (e) => {
891
- let t = e.runId;
892
- return {
893
- table: "_voltro_workflow_run_steps",
894
- order: [{
895
- column: "startedAt",
896
- direction: "asc"
897
- }],
898
- predicate: U("runId", t),
899
- take: 1e3,
900
- skip: void 0,
901
- projection: void 0
902
- };
903
- }
904
- }, e), r, `subscription.${Hn.name}`), A[Bn.name] = (e) => _r(D({
905
- descriptor: Bn,
906
- executor: (e) => {
907
- let t = e.runId;
908
- return {
909
- table: "_voltro_workflow_run_events",
910
- order: [{
911
- column: "occurredAt",
912
- direction: "asc"
913
- }],
914
- predicate: U("runId", t),
915
- take: 1e3,
916
- skip: void 0,
917
- projection: void 0
918
- };
919
- }
920
- }, e), r, `subscription.${Bn.name}`), A[B.name] = (e) => _r(D({
921
- descriptor: B,
922
- executor: (e) => {
923
- let t = e;
924
- return {
925
- table: "_voltro_workflow_events",
926
- order: [{
927
- column: "occurredAt",
928
- direction: "desc"
929
- }],
930
- predicate: t.name === void 0 ? void 0 : U("name", t.name),
931
- take: Math.max(1, Math.min(500, t.limit ?? 100)),
932
- skip: void 0,
933
- projection: void 0
934
- };
935
- }
936
- }, e), r, `subscription.${B.name}`), A[V.name] = (e) => _r(D({
937
- descriptor: V,
938
- executor: (e) => {
939
- let t = e.eventId;
940
- return {
941
- table: "_voltro_workflow_event_deliveries",
942
- order: [{
943
- column: "createdAt",
944
- direction: "asc"
945
- }],
946
- predicate: U("eventId", t),
947
- take: 500,
948
- skip: void 0,
949
- projection: void 0
950
- };
951
- }
952
- }, e), r, `subscription.${V.name}`), A[Rn.name] = (t) => q(async (t, n) => {
953
- let r = t;
954
- return await j(e.store, n.subject, { executionId: r.executionId }), await S.cancel(r.workflowName, r.executionId), await Ft(r.workflowName, r.executionId, "workflow.cancel"), { ok: !0 };
955
- }, t, `action.${Rn.name}`), A[zn.name] = (t) => q(async (t, n) => {
956
- let r = t;
957
- return await j(e.store, n.subject, { executionId: r.executionId }), await S.resume(r.workflowName, r.executionId), { ok: !0 };
958
- }, t, `action.${zn.name}`), A[Wn.name] = (t) => q(async (t, n) => {
959
- let r = t;
960
- return await j(e.store, n.subject, { id: r.id }), S.signal({ id: r.id }, r.signalName, r.payload);
961
- }, t, `action.${Wn.name}`), A[Gn.name] = (t) => q(async (t, n) => {
962
- let r = t;
963
- return await j(e.store, n.subject, { id: r.id }), S.update({ id: r.id }, r.updateName, r.payload, r.timeoutMs === void 0 ? void 0 : { timeoutMs: r.timeoutMs });
964
- }, t, `action.${Gn.name}`));
965
- let Dt = [
966
- ...k(e.discovered.queries).map((e) => z(e.descriptor)),
967
- ...k(e.discovered.mutations).map((e) => Fn(e.descriptor)),
968
- ...k(e.discovered.actions).map((e) => R(e.descriptor)),
969
- ...lt.queries.map((e) => z(e.descriptor)),
970
- ...lt.mutations.map((e) => Fn(e.descriptor)),
971
- ...ut.queries.map((e) => z(e.descriptor)),
972
- ...ut.mutations.map((e) => Fn(e.descriptor)),
973
- ...w.queries.map((e) => z(e.descriptor)),
974
- ...w.mutations.map((e) => Fn(e.descriptor)),
975
- ...w.actions.map((e) => R(e.descriptor)),
976
- ...k(e.discovered.streams ?? []).map((e) => In(e.descriptor)),
977
- ...Le.rpcs,
978
- ...(e.discovered.workflows ?? []).map((e) => di(e.definition)),
979
- ...de ? [
980
- z(Vn),
981
- z(Un),
982
- z(Hn),
983
- z(Bn),
984
- z(B),
985
- z(V),
986
- R(Rn),
987
- R(zn),
988
- R(Wn),
989
- R(Gn)
990
- ] : []
991
- ], Ot = hi.make(...Dt).middleware(jn).middleware(Mn), kt = Pr({ resolveSubject: ({ headers: t, clientId: n }) => e.resolveSubject(t, n) }), At = e.dormancyTenantId ?? or, Nt = e.dormancy === "sleep" ? {
992
- register: (t, n, r) => Qr(e.store, {
993
- tenantId: r ?? At,
994
- kind: "workflow",
995
- refId: t,
996
- wakeAt: n
997
- }),
998
- cancel: (t, n) => yr(e.store, {
999
- tenantId: n ?? At,
1000
- kind: "workflow",
1001
- refId: t
1002
- }).then(() => {})
1003
- } : void 0, M = he ? await import("@voltro/workflow") : void 0, N = M?.makeWorkflowRunRecorder({
1004
- store: e.store,
1005
- ...e.workflowRecording === void 0 ? {} : { recording: e.workflowRecording },
1006
- ...Nt === void 0 ? {} : { wakeups: Nt }
1007
- }), Pt = async (t, n) => {
1008
- await M.closeWorkflowChildrenForParent({
1009
- store: e.store,
1010
- parentExecutionId: t,
1011
- parentStatus: n,
1012
- recorder: N,
1013
- log: { warn: (e, t) => {
1014
- process.stderr.write(`[workflow] ${e} ${t ? JSON.stringify(t) : ""}\n`);
1015
- } },
1016
- interruptChild: async (t, n) => {
1017
- let r = (e.discovered.workflows ?? []).find((e) => e.definition.name === t);
1018
- if (!r) throw Error(`Unknown child workflow: ${t}`);
1019
- if (!u) throw Error("Workflow runtime is not ready");
1020
- await u.runPromise(r.definition.interrupt(n));
1021
- }
1022
- });
1023
- }, Ft = async (t, n, r) => {
1024
- let i = (await e.store.query({
1025
- table: "_voltro_workflow_runs",
1026
- order: [],
1027
- predicate: U("executionId", n),
1028
- projection: void 0,
1029
- skip: void 0,
1030
- take: 1
1031
- }))[0];
1032
- if (i === void 0) return;
1033
- let a = await e.store.update("_voltro_workflow_runs", i.id, {
1034
- status: "cancelled",
1035
- cancelled: !0,
1036
- completedAt: /* @__PURE__ */ new Date()
1037
- }), o = i.subject?.tenantId ?? void 0;
1038
- a && await N.recordEvent({
1039
- runId: i.id,
1040
- eventType: "run-cancelled",
1041
- payload: {
1042
- reason: r,
1043
- workflowName: t,
1044
- executionId: n,
1045
- ...o == null ? {} : { tenantId: o }
1046
- }
1047
- }), a && await Pt(n, "cancelled");
1048
- }, It = [
1049
- ...qr(e.discovered.workflows ?? [], {
1050
- buildContext: (t, n) => e.buildContextForWorkflow?.(t, n) ?? ze({
1051
- subject: t.subject,
1052
- traceId: t.traceId
1053
- }, e.store, void 0, `workflow:${n.workflowName}`, { parentExecutionId: n.executionId }),
1054
- resolveStartContext: ae,
1055
- ...oe === void 0 ? {} : { resolveAuthority: oe }
1056
- }, (t, n, r) => {
1057
- let i = M.getWorkflowVersionMetadata(t.definition);
1058
- return M.wrapWorkflowExecuteWithRunRecording({
1059
- name: t.definition.name,
1060
- store: e.store,
1061
- subject: r.subject,
1062
- source: r.source ?? null,
1063
- traceId: r.traceId,
1064
- workflowVersion: i.version,
1065
- workflowCompatibleVersions: i.compatibleWith,
1066
- workflowPatches: i.patches,
1067
- parentExecutionId: r?.parentExecutionId ?? null,
1068
- parentClosePolicy: r?.parentClosePolicy ?? null,
1069
- onParentClose: ({ executionId: e, status: t }) => Pt(e, t),
1070
- ...ft(t.definition),
1071
- onTerminal: async ({ executionId: e }) => {
1072
- await l?.gate.release(e);
1073
- },
1074
- recorder: N,
1075
- pluginWorkflowStepLayer: rt,
1076
- recordRun: Zr
1077
- }, n);
1078
- }),
1079
- ...e.discovered.workflowWorkers ?? [],
1080
- ...ye === void 0 ? [] : [ye]
1081
- ], Lt = [...(e.discovered.workflows ?? []).map((e) => e.definition.name).filter(Boolean), ...ye === void 0 ? [] : ["voltro.deliverWebhook"]], zt = It.length > 0 ? G.mergeAll(...It) : G.empty;
1082
- if (((e.discovered.workflows?.length ?? 0) > 0 || (e.discovered.workflowWorkers?.length ?? 0) > 0 || e.scheduleCoordination === "cluster" || ye !== void 0) && e.workflowEngineLayer !== void 0) {
1083
- let t = zt.pipe(G.provideMerge(e.workflowEngineLayer));
1084
- u = $n.make(e.baseLayer === void 0 ? t : t.pipe(G.provideMerge(e.baseLayer))), await u.runPromise(W.void), (e.log ?? L({ scope: "voltro:serve" })).child("workflow").info(`workflow runtime ready — ${Lt.length} entity type(s) registered`, { entities: Lt });
1085
- let n = await import("@voltro/workflow/cluster"), r = (e) => u.runPromise(n.redriveFailedRun(e)), i = (e) => u.runPromise(n.resumeRunFromStep(e));
1086
- m = await Bt({
1087
- provider: Fi(e.plugins ?? [])?.broadcast?.provider,
1088
- crossReplica: Fi(e.plugins ?? [])?.broadcast?.crossReplica ?? !1,
1089
- namespace: je,
1090
- replicaId: crypto.randomUUID(),
1091
- pollStorage: () => u.runPromise(n.pollWorkflowStorage),
1092
- onChange: (t) => e.store.onChange((e) => t({
1093
- table: e.table,
1094
- op: e.op,
1095
- ...e.origin === void 0 ? {} : { origin: e.origin }
1096
- })),
1097
- log: (e.log ?? L({ scope: "voltro:serve" })).child("workflow")
1098
- }), f = async (t) => {
1099
- let n = await De({
1100
- store: e.store,
1101
- workflows: e.discovered.workflows ?? [],
1102
- runRedrive: r
1103
- }, t.runId);
1104
- return n.statusReset && await N.recordEvent({
1105
- runId: t.runId,
1106
- eventType: "run-redriven",
1107
- payload: {
1108
- reason: "inspect.redrive",
1109
- activitiesReset: n.outcome.activitiesReset
1110
- }
1111
- }), {
1112
- redriven: n.outcome.redriven,
1113
- activitiesReset: n.outcome.activitiesReset,
1114
- reason: n.outcome.reason
1115
- };
1116
- }, p = async (t) => {
1117
- let n = await ke({
1118
- store: e.store,
1119
- workflows: e.discovered.workflows ?? [],
1120
- runResume: i
1121
- }, t.runId, t.step);
1122
- return n.statusReset && await N.recordEvent({
1123
- runId: t.runId,
1124
- eventType: "run-redriven",
1125
- payload: {
1126
- reason: "inspect.resume-from-step",
1127
- step: n.stepName,
1128
- activitiesReset: n.outcome.activitiesReset
1129
- }
1130
- }), {
1131
- redriven: n.outcome.redriven,
1132
- stepName: n.stepName,
1133
- activitiesReset: n.outcome.activitiesReset,
1134
- reason: n.outcome.reason
1135
- };
1136
- };
1137
- let a = (e.scheduleCoordination ?? "single") === "advisoryLock" ? kr(e.store, e.scheduleReplicaId ?? `pid-${process.pid}`) : ii, s = Fr({
1138
- coordinator: a,
1139
- replicaId: e.scheduleReplicaId ?? `pid-${process.pid}`
1140
- }), d = {
1141
- info: (e, t) => {
1142
- process.stdout.write(`[flow-control] ${e} ${t ? JSON.stringify(t) : ""}\n`);
1143
- },
1144
- warn: (e, t) => {
1145
- process.stderr.write(`[flow-control] ${e} ${t ? JSON.stringify(t) : ""}\n`);
1146
- },
1147
- error: (e, t) => {
1148
- process.stderr.write(`[flow-control] ERROR ${e} ${t ? JSON.stringify(t) : ""}\n`);
1149
- }
1150
- }, h, g = () => {
1151
- if (h !== void 0) return h;
1152
- if (o !== void 0 && N !== void 0) return h = ne({
1153
- store: e.store,
1154
- log: I,
1155
- workflows: e.discovered.workflows ?? [],
1156
- workflowsProxy: o,
1157
- workflowRuntime: u,
1158
- workflowRunRecorder: N,
1159
- closeChildrenForParent: Pt
1160
- }), h;
1161
- };
1162
- ee = g, l = et({
1163
- store: e.store,
1164
- onChange: (t) => e.store.onChange((e) => t({
1165
- table: e.table,
1166
- op: e.op
1167
- })),
1168
- ...e.scheduling === void 0 ? {} : {
1169
- disarmWhenIdle: e.scheduling.disarmWhenIdle,
1170
- drainIntervalMs: e.scheduling.admissionDrainMs,
1171
- cancelSweepIntervalMs: e.scheduling.cancelSweepMs,
1172
- stalenessSweepIntervalMs: e.scheduling.stalenessSweepMs
1173
- },
1174
- workflows: e.discovered.workflows ?? [],
1175
- facade: () => o,
1176
- cancelRunWithReason: g,
1177
- recordRunEvent: () => N?.recordEvent,
1178
- ...e.workflowStaleness === void 0 ? {} : { staleness: e.workflowStaleness },
1179
- ...e.workflowSuspendSignalHintMs === void 0 ? {} : { suspendSignalHintMs: e.workflowSuspendSignalHintMs },
1180
- scheduleCoordinated: s,
1181
- onAbandoned: async (t) => {
1182
- await Ge({
1183
- workflows: e.discovered.workflows ?? [],
1184
- facade: () => o,
1185
- log: d,
1186
- ...t
1187
- });
1188
- },
1189
- log: d
1190
- });
1191
- let _ = l;
1192
- _ !== void 0 && Yr(() => _.stop()), c = Qe({
1193
- store: e.store,
1194
- onChange: (t) => e.store.onChange((e) => t({
1195
- table: e.table,
1196
- op: e.op
1197
- })),
1198
- ...e.scheduling === void 0 ? {} : {
1199
- disarmWhenIdle: e.scheduling.disarmWhenIdle,
1200
- tickIntervalMs: e.scheduling.inferenceTickMs
1201
- },
1202
- enabled: (e.discovered.workflows?.length ?? 0) > 0,
1203
- resumeSignal: () => u === void 0 || M === void 0 ? void 0 : async ({ executionId: t, workflowName: n, signalName: r, payload: i }) => {
1204
- await u.runPromise(M.completeSuspendingSignal({
1205
- store: e.store,
1206
- target: qe(t, n),
1207
- signalName: r,
1208
- payload: i
1209
- }));
1210
- },
1211
- runEffect: (e) => u.runPromise(e),
1212
- scheduleCoordinated: s,
1213
- log: d
1214
- });
1215
- let v = c;
1216
- v !== void 0 && Yr(() => v.stop()), o = (e.discovered.workflows?.length ?? 0) > 0 ? Gr({
1217
- workflows: e.discovered.workflows ?? [],
1218
- runEffect: (e) => u.runPromise(e),
1219
- onEnqueue: () => m?.publishWake(),
1220
- ..._ === void 0 ? {} : {
1221
- admitStart: _.gate.admitStart,
1222
- startPayloadSchema: _.gate.startPayloadSchema,
1223
- parkDelayedStart: _.gate.parkDelayed
1224
- },
1225
- rememberStartContext: te,
1226
- signal: async (t, n, r) => {
1227
- let i = await M.sendWorkflowSignal({
1228
- store: e.store,
1229
- recorder: N,
1230
- target: t,
1231
- signalName: n,
1232
- payload: r
1233
- });
1234
- return await u.runPromise(M.completeSuspendingSignal({
1235
- store: e.store,
1236
- target: t,
1237
- signalName: n,
1238
- payload: r
1239
- })).catch(() => {}), i;
1240
- },
1241
- update: (t, n, r, i) => M.sendWorkflowUpdate({
1242
- store: e.store,
1243
- recorder: N,
1244
- target: t,
1245
- updateName: n,
1246
- payload: r,
1247
- ...i === void 0 ? {} : { options: i }
1248
- }),
1249
- listRuns: (t) => y(e.store, t),
1250
- retry: (t, n) => ie({
1251
- store: e.store,
1252
- workflows: e.discovered.workflows ?? [],
1253
- runPromise: (e) => u.runPromise(e)
1254
- }, t, n),
1255
- redrive: (t) => De({
1256
- store: e.store,
1257
- workflows: e.discovered.workflows ?? [],
1258
- runRedrive: r
1259
- }, t).then((e) => e.outcome)
1260
- }) : void 0;
1261
- }
1262
- let Vt = G.mergeAll(Ot.toLayer(A), kt), Ht = at(A, e.discovered.queries.map((e) => e.descriptor.name), de), Ut = G.mergeAll(Ot.toLayer(Ht), kt), P = e.observability, Wt = await vr({
1263
- ...e.appName === void 0 ? {} : { serviceName: e.appName },
1264
- ...P && P.spanProcessors.length > 0 ? { extraSpanProcessors: P.spanProcessors } : {},
1265
- ...P && P.metricReaders.length > 0 ? { extraMetricReaders: P.metricReaders } : {},
1266
- ...P && Object.keys(P.resourceAttributes).length > 0 ? { resourceAttributes: P.resourceAttributes } : {},
1267
- ...P && P.sampler !== void 0 ? { sampler: P.sampler } : {}
1268
- }), Gt = !1, F = e.store.ping ? () => e.store.ping().then(() => !0).catch(() => !1) : void 0, { server: Kt, shutdown: qt } = ai({
1269
- group: Ot,
1270
- handlersLayer: Vt,
1271
- httpHandlersLayer: Ut,
1272
- port: e.port ?? 4e3,
1273
- ...e.host === void 0 ? {} : { host: e.host },
1274
- path: e.path ?? "/ws",
1275
- tracerLayer: Wt.layer,
1276
- security: re(e),
1277
- ...nt,
1278
- healthCheck: {
1279
- isReady: () => Gt,
1280
- ...F ? { ping: F } : {}
1281
- },
1282
- ...Et.length > 0 ? { httpRoutes: Et } : {},
1283
- ...e.getStore === void 0 ? {} : { getStore: e.getStore },
1284
- ...Se.size > 0 ? { webhookRoutes: Se } : {},
1285
- ...e.inspectRoute === void 0 ? {} : { inspectRoute: e.inspectRoute }
1286
- }), Jt = Ji(Kt);
1287
- if (await hr(Kt), (e.discovered.schedules?.length ?? 0) > 0) {
1288
- let t = (e.scheduleCoordination ?? "single") === "advisoryLock" ? kr(e.store, e.scheduleReplicaId ?? `pid-${process.pid}`) : ii;
1289
- h = await oi(e.discovered.schedules ?? [], {
1290
- store: e.store,
1291
- coordinator: t,
1292
- defaultTrigger: e.scheduleDefaultTrigger ?? "self",
1293
- replicaId: e.scheduleReplicaId ?? `pid-${process.pid}`,
1294
- armSelf: e.scheduleArmSelf ?? !0,
1295
- dormancy: e.dormancy ?? "always-on",
1296
- ...e.dormancyTenantId === void 0 ? {} : { dormancyTenantId: e.dormancyTenantId },
1297
- buildContext: ({ traceId: t, scheduleName: n, subject: r }) => ze({
1298
- subject: r,
1299
- traceId: t
1300
- }, e.store, void 0, `schedule:${n}`),
1301
- log: {
1302
- info: (e, t) => {
1303
- process.stdout.write(`[schedule] ${e} ${t ? JSON.stringify(t) : ""}\n`);
1304
- },
1305
- warn: (e, t) => {
1306
- process.stderr.write(`[schedule] ${e} ${t ? JSON.stringify(t) : ""}\n`);
1307
- },
1308
- error: (e, t) => {
1309
- process.stderr.write(`[schedule] ERROR ${e} ${t ? JSON.stringify(t) : ""}\n`);
1310
- },
1311
- debug: () => {}
1312
- },
1313
- ...e.scheduleFireInterceptor === void 0 ? {} : { interceptFire: e.scheduleFireInterceptor },
1314
- ...e.onScheduleRunEvent === void 0 ? {} : { onRunEvent: e.onScheduleRunEvent }
1315
- }), e.onSchedulerReady?.(h);
1316
- }
1317
- let I = e.log ?? L({ scope: "voltro:serve" }), Yt, Xt;
1318
- if ((e.discovered.subscribers?.length ?? 0) > 0 && (Yt = xe(e.discovered.subscribers ?? [], e.store, I.child("subscribe"), e.schemaRegistry, Le.bus)), (e.discovered.reactions?.length ?? 0) > 0) {
1319
- let t = I.child("reaction"), n = async (n, r) => {
1320
- if (n.kind === "workflow") {
1321
- if (S === void 0) {
1322
- t.warn("reaction workflow act skipped — no workflow engine in this app", { workflow: n.workflow });
1323
- return;
1324
- }
1325
- let e = n.payload === void 0 ? r.new ?? r.old ?? {} : n.payload(r);
1326
- await Kr(S, {
1327
- traceId: `reaction:${n.workflow}`,
1328
- source: `reaction:${n.workflow}`
1329
- }).start(n.workflow, e);
1330
- return;
1331
- }
1332
- await pe(n.agent, r, {
1333
- findAgentSend: (t) => e.discovered.actions.find((e) => e.descriptor.name === `${t}.send`),
1334
- runAction: (e, t, n) => Promise.resolve(pt(e, t, n)),
1335
- makeSubject: (e) => Nn(e),
1336
- now: () => Date.now(),
1337
- log: t
1338
- });
1339
- }, r = async (n, r) => {
1340
- try {
1341
- let { requireAiBudget: t } = await import("@voltro/ai");
1342
- return (await W.runPromise(W.either(t(e.store, {
1343
- tenantId: n,
1344
- limitUsd: r
1345
- }))))._tag === "Right";
1346
- } catch (e) {
1347
- return t.warn("reaction budget check failed — refusing the act", { tenantId: n }, e), !1;
1348
- }
1349
- }, i = jt(e.store, { onError: (e) => t.warn("reaction: rate-slot claim failed; refusing the act", { cause: String(e) }) });
1350
- Xt = ct(e.discovered.reactions ?? [], e.store, {
1351
- runAct: n,
1352
- checkBudget: r,
1353
- claimRateSlot: (e) => i.claim(e)
1354
- }, t);
1355
- }
1356
- let Zt;
1357
- (e.discovered.aggregates?.length ?? 0) > 0 && (Zt = await v({
1358
- discovered: e.discovered.aggregates ?? [],
1359
- store: e.store,
1360
- log: I.child("aggregate"),
1361
- ...e.analytics === void 0 ? {} : { analytics: e.analytics },
1362
- ...e.aggregateStorage === void 0 ? {} : { storage: e.aggregateStorage },
1363
- ...e.aggregateCoordinator === void 0 ? {} : { coordinator: e.aggregateCoordinator }
1364
- }), Be = G.succeed(ar, Zt.registry));
1365
- let Qt;
1366
- (e.discovered.expectations?.length ?? 0) > 0 && (Qt = fr({
1367
- discovered: e.discovered.expectations ?? [],
1368
- store: e.store,
1369
- log: I.child("expectation")
1370
- }), Ve = G.succeed(cr, Qt.registry)), (e.discovered.budgets?.length ?? 0) > 0 && (n = mr({
1371
- discovered: e.discovered.budgets ?? [],
1372
- log: I.child("finops")
1373
- }), Ue = G.succeed(K, n.registry));
1374
- let $t;
1375
- return (e.discovered.experiments?.length ?? 0) > 0 && ($t = pr({
1376
- discovered: e.discovered.experiments ?? [],
1377
- store: e.store,
1378
- log: I.child("experiment")
1379
- }), Ke = G.succeed(lr, $t.registry)), Gt = !0, e.bootTiming?.mark("ready"), {
1380
- dispatcher: r,
1381
- server: Kt,
1382
- scheduler: h,
1383
- eventsSnapshot: me(Le.bus, Le.declared),
1384
- membersSnapshot: () => ({
1385
- members: Ie.membership.list(),
1386
- capturedAt: Date.now()
1387
- }),
1388
- agentTools: () => bt,
1389
- rpcMetrics: () => Ze,
1390
- webhooksService: () => ve,
1391
- runCanceller: () => ee(),
1392
- flowControlHealth: () => l?.cancelHealth(),
1393
- inferenceHealth: () => c?.health(),
1394
- workflowWriteActions: () => S === void 0 || N === void 0 ? void 0 : se({
1395
- store: e.store,
1396
- log: I,
1397
- workflows: e.discovered.workflows ?? [],
1398
- workflowsProxy: o,
1399
- workflowRuntime: u,
1400
- workflowRunRecorder: N,
1401
- closeChildrenForParent: Pt
1402
- }),
1403
- redriveWorkflowRun: (e) => f ? f(e) : Promise.reject(/* @__PURE__ */ Error("redrive: this app registers no workflows")),
1404
- resumeWorkflowRunFromStep: (e) => p ? p(e) : Promise.reject(/* @__PURE__ */ Error("resume-from-step: this app registers no workflows")),
1405
- close: async () => {
1406
- Gt = !1, await Jt.drainRequests();
1407
- for (let e of Ce) try {
1408
- await e();
1409
- } catch (e) {
1410
- I.warn("serve: teardown step failed", {}, e);
1411
- }
1412
- await Re?.detach(), await Ie.detach(), Zt?.detach(), Qt?.detach(), n?.detach(), $t?.detach(), Xt?.(), Yt?.(), await h?.shutdown(), r.close(), await m?.detach(), await u?.dispose(), await qt(), await Jt.finish();
1413
- }
1414
- };
1415
- }, $ = L({ scope: "voltro:serve" }), Da = (e, t, n) => (e === "production" || e === "staging") && t !== "memory" && n !== "0", Oa = Ut, ka = async (e) => {
1416
- let t = Sn(process.cwd());
1417
- if (kn(t)) {
1418
- let n;
1419
- try {
1420
- let e = await import(An(t).href);
1421
- typeof e.runServe == "function" ? n = e.runServe : $.warn("serve bundle has no runServe export — using the standard serve path");
1422
- } catch (e) {
1423
- $.warn("serve bundle failed to load — using the standard serve path", {}, e);
1424
- }
1425
- if (n) return $.info("serve: booting from the precompiled serve bundle"), n(e);
1426
- }
1427
- return Aa(e);
1428
- }, Aa = async (s) => {
1429
- let d = Cn();
1430
- e("serve");
1431
- try {
1432
- Ci();
1433
- } catch (e) {
1434
- throw i(e instanceof Error ? e.message : String(e));
1435
- }
1436
- let g = process.cwd(), v = await Ue(g), ne = P({
1437
- kind: "api",
1438
- configPort: v?.port,
1439
- env: process.env,
1440
- flagPort: Oa(s, "--port")
1441
- });
1442
- for (let e of ne.warnings) $.warn(e);
1443
- let ie = ne.port;
1444
- ti($r(v?.secrets)), await Wt({
1445
- rawEnv: v?.env,
1446
- appType: "api",
1447
- root: g,
1448
- log: $,
1449
- generateTypes: !1
1450
- }), d.mark("config");
1451
- let y = (process.env.DB_DIALECT ?? v?.store ?? "memory").toLowerCase(), se = (y === "mariadb" || y === "postgres" || y === "mssql") && (process.env.CDC ?? "1") !== "0", ce = y === "mariadb" ? "mariadb" : y === "mssql" ? "mssql" : void 0, le = xn(g);
1452
- if (!r() && kn(le)) try {
1453
- let e = await import(An(le).href);
1454
- if (e.modules) {
1455
- let t = {};
1456
- for (let [n, r] of Object.entries(e.modules)) t[Dn(g, n)] = r;
1457
- n(t), $.info("precompiled api bundle loaded", { modules: Object.keys(t).length });
1458
- }
1459
- } catch (e) {
1460
- $.warn("precompiled api bundle failed to load — falling back to source", {}, e);
1461
- }
1462
- let b = await Xe(g), x = await kt(b, { cdc: se && ce !== void 0 }), ue = Ht(x);
1463
- {
1464
- let e = /* @__PURE__ */ new Set([
1465
- ...x.queries.filter((e) => e.descriptor.overridesPlugin === !0).map((e) => e.descriptor.name),
1466
- ...x.mutations.filter((e) => e.descriptor.overridesPlugin === !0).map((e) => e.descriptor.name),
1467
- ...x.actions.filter((e) => e.descriptor.overridesPlugin === !0).map((e) => e.descriptor.name)
1468
- ]);
1469
- nn(Xt(v?.plugins ?? []), [
1470
- ...x.queries.map((e) => e.descriptor.name),
1471
- ...x.mutations.map((e) => e.descriptor.name),
1472
- ...x.actions.map((e) => e.descriptor.name),
1473
- ...x.streams.map((e) => e.descriptor.name)
1474
- ], e);
1475
- let t = ae(x.serverOnlyLeaks, Ae(process.env, "strict"), Sr, "`voltro serve`");
1476
- if (t.action === "fail") throw i(t.message ?? "");
1477
- t.action === "warn" && $.warn(t.message ?? "");
1478
- }
1479
- let fe = b.filter((e) => yn.test(e)), pe = fe.length > 0 ? await vn(fe, $.child("webhooks")) : {
1480
- outgoing: [],
1481
- incoming: [],
1482
- providers: []
1483
- }, me = gn(x.events), be = pe.outgoing.length + pe.incoming.length + pe.providers.length + me.length === 0 ? void 0 : {
1484
- ...pe,
1485
- outgoing: [...pe.outgoing, ...me]
1486
- }, xe = rn({
1487
- nodeEnv: process.env.NODE_ENV,
1488
- cdcDialect: ce,
1489
- declared: v?.schema
1490
- }), we = an({
1491
- gates: xe,
1492
- runtime: {
1493
- traces: ve(),
1494
- undo: ci()
1495
- }
1496
- });
1497
- if (we !== void 0) throw i(`serve: ${we}`);
1498
- let De = tn({
1499
- mix: x.featureMix,
1500
- plugins: v?.plugins ?? [],
1501
- gates: xe,
1502
- ...ce ? { cdcDialect: ce } : {}
1503
- }), Oe = v?.analytics !== void 0 && v.analytics.kind !== "noop" && y !== "memory" ? (await F(y)).makeSqlLayer(O()) : void 0, ke = await Je({
1504
- spec: v?.analytics,
1505
- sqlLayer: Oe,
1506
- log: $
1507
- }), T = (() => {
1508
- let e = new Set(x.tables.map((e) => e.tableName)), t = [...x.tables];
1509
- for (let n of [...De, ...ke.tables]) e.has(n.tableName) || (e.add(n.tableName), t.push(n));
1510
- return t;
1511
- })();
1512
- for (let e of T) Xn(e);
1513
- {
1514
- let e = Cr(li(Ve(x), Lt(T)));
1515
- e !== void 0 && $.warn(e);
1516
- }
1517
- let Pe = (process.env.NODE_ENV ?? "").toLowerCase();
1518
- if (Da(Pe, y, process.env.VOLTRO_AUTO_MIGRATE)) {
1519
- let e = (await F(y)).makeSqlLayer(O()), t = await W.runPromise(er.SqlClient.pipe(W.flatMap((e) => rr(e, g)), W.provide(e), W.catchAll(() => W.succeed([]))));
1520
- t.length > 0 && ($.error(`serve: refusing to boot — ${t.length} pending file-based migration(s) have never run against this database. They perform the changes a schema diff cannot infer (data moves, backfills, table splits), so the declarative fingerprint check below cannot see them and would have let this process serve un-migrated data.`, { pending: t }), $.error("Run them from your pre-deploy job — `voltro db migrate .` (schema + files) or `voltro db files .` (files alone) — or set VOLTRO_AUTO_MIGRATE=0 to bypass every boot schema check. `voltro serve` never applies them itself: a rolling deploy would start N replicas and each would try."), process.exit(1));
1521
- let n = await W.runPromise(er.SqlClient.pipe(W.flatMap((e) => ir(e, T, {
1522
- appliedBy: `serve:${Pe}`,
1523
- environment: "prod",
1524
- dialectId: y
1525
- })), W.provide(e)));
1526
- n.kind === "prod-mismatch" && ($.error(nr(n, y)), $.error(on({
1527
- gates: xe,
1528
- nodeEnv: process.env.NODE_ENV,
1529
- cdcDialect: ce,
1530
- declared: v?.schema
1531
- })), $.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(nr(n, y));
1532
- }
1533
- await Yt({
1534
- dialectId: y,
1535
- tables: T,
1536
- mode: Jt(v?.reactiveTriggers),
1537
- lockSchema: O().schema,
1538
- makeLayer: async () => (await F(y)).makeSqlLayer(O()),
1539
- log: {
1540
- info: (e, t) => $.info(e, t ?? {}),
1541
- warn: (e, t) => $.warn(e, t ?? {})
1542
- }
1543
- });
1544
- let Fe = Wr(T);
1545
- d.mark("discover");
1546
- let E = await it(v, void 0);
1547
- {
1548
- let e = await ee(E);
1549
- if (e !== void 0) throw i(`serve: ${e}`);
1550
- }
1551
- let He = fi(E, y);
1552
- for (let e of nt({
1553
- dialect: String(v?.store ?? process.env.DB_DIALECT ?? "postgres"),
1554
- changeStrategy: (process.env.CDC ?? "1") === "0" ? "inline" : "cdc",
1555
- dbUrl: process.env.DB_URL,
1556
- crossReplicaBus: Fi(v?.plugins ?? [])?.broadcast.crossReplica === !0,
1557
- tables: x.tables.map((e) => ({
1558
- tableName: e.tableName,
1559
- isReactive: e.isReactive === !0
1560
- })),
1561
- querySources: x.queries.flatMap((e) => {
1562
- let t = e.descriptor.source;
1563
- return t === void 0 ? [] : typeof t == "string" ? [t] : [...t];
1564
- })
1565
- })) e.level === "warn" ? $.warn(e.message) : $.info(e.message);
1566
- {
1567
- let e = vt({
1568
- tables: Kn().map((e) => ({ tableName: e.tableName })),
1569
- queries: x.queries.map((e) => ({
1570
- name: e.descriptor.name,
1571
- source: e.descriptor.source
1572
- }))
1573
- }), t = mt(e);
1574
- t !== void 0 && $.warn(t);
1575
- }
1576
- v?.cache && !process.env.CACHE_BACKEND && (process.env.CACHE_BACKEND = v.cache), v?.cacheRedisUrl && !process.env.CACHE_REDIS_URL && (process.env.CACHE_REDIS_URL = v.cacheRedisUrl), v?.cacheRedisDriver && !process.env.CACHE_REDIS_DRIVER && (process.env.CACHE_REDIS_DRIVER = v.cacheRedisDriver), v?.cacheKeyPrefix && !process.env.CACHE_KEY_PREFIX && (process.env.CACHE_KEY_PREFIX = v.cacheKeyPrefix);
1577
- let { service: We, invalidationBus: Ge, snapshotCache: qe, cache: Ye, semantic: Qe, evictSource: et, backend: at, stats: st, dispose: ct } = await Ze({
1578
- env: process.env,
1579
- semantic: v?.cacheSemantic ?? !1
1580
- });
1581
- Qe !== void 0 && $.info("semantic cache enabled — reactive eviction on live writes"), $.info(`cache backend resolved: ${at}` + (at === "redis" ? ` (driver ${process.env.CACHE_REDIS_DRIVER ?? "resp"})` : " — in-process, not cross-instance")), E.onChange((e) => {
1582
- if (W.runFork(Ge.publish(e.table)), et !== void 0) {
1583
- let t = (e.new ?? e.old)?.id;
1584
- et({
1585
- table: e.table,
1586
- op: e.op,
1587
- ...t === void 0 ? {} : { id: t }
1588
- });
1589
- }
1590
- }), v?.kv && !process.env.KV_BACKEND && (process.env.KV_BACKEND = v.kv), v?.kvRedisUrl && !process.env.KV_REDIS_URL && (process.env.KV_REDIS_URL = v.kvRedisUrl), v?.kvKeyPrefix && !process.env.KV_KEY_PREFIX && (process.env.KV_KEY_PREFIX = v.kvKeyPrefix);
1591
- let { kv: dt, service: ft } = await Nr({ store: E });
1592
- Pt({
1593
- log: $,
1594
- max: qt(),
1595
- outOfPool: p(y, (process.env.CDC ?? "1") !== "0"),
1596
- readPools: t.replicationSnapshot()?.replicaCount ?? 0,
1597
- always: !0
1598
- }), d.mark("store");
1599
- let gt = dr({
1600
- store: E,
1601
- sink: ke.sink,
1602
- log: $
1603
- }), xt = Ke({
1604
- store: E,
1605
- dialect: y,
1606
- log: { info: (e) => $.info(e) }
1607
- }), j = v?.plugins ?? [], jt = process.env.POD_NAME ?? process.env.HOSTNAME ?? `serve-${process.pid}`, Rt, Bt;
1608
- y !== "memory" && (Rt = $n.make((await F(y)).makeSqlLayer(O())), Bt = await Rt.runPromise(er.SqlClient));
1609
- let Ut = [
1610
- "postgres",
1611
- "mariadb",
1612
- "mysql",
1613
- "mssql"
1614
- ].includes(y) ? kr(E, jt, $) : ii, _n = M(v?.scheduling), Sn = Fr({
1615
- maxIdleIntervalMs: _n.pollCeilingMs,
1616
- coordinator: Ut,
1617
- replicaId: jt,
1618
- log: $
1619
- }), wn = [], Tn = process.env.POD_NAME ?? process.env.HOSTNAME ?? `serve-${process.pid}`, On = Fi(v?.plugins ?? [])?.broadcast?.provider, L = $e(v?.plugins, v?.name ?? En(g));
1620
- {
1621
- let e = tt(v?.plugins, v?.name ?? En(g));
1622
- e !== void 0 && $.warn(e);
1623
- }
1624
- let jn = Mt(v?.plugins, {
1625
- instanceId: Tn,
1626
- namespace: L,
1627
- meta: { mode: "serve" },
1628
- logger: $
1629
- }), Mn = {
1630
- ...Bt ? { sql: Bt } : {},
1631
- instanceId: Tn,
1632
- membership: jn.membership,
1633
- ...On === void 0 ? {} : { broadcast: On },
1634
- broadcastChannels: { presence: Pi(L, "presence") },
1635
- scheduleCoordinated: (e, t, n) => {
1636
- let r = Sn(e, t, n);
1637
- return wn.push(r), r;
1638
- }
1639
- };
1640
- for (let e of j) e.bindDataStore?.(He, Mn);
1641
- l({
1642
- store: E,
1643
- ...lt(),
1644
- log: $
1645
- });
1646
- let R = j.filter((e) => typeof e.onChangeEvent == "function");
1647
- if (R.length > 0) {
1648
- let e = E.changeScope ?? "local";
1649
- E.onChange((t) => {
1650
- let n = ye(t, e);
1651
- for (let e of R) W.runFork(e.onChangeEvent(n).pipe(W.catchAllCause((t) => W.sync(() => $.warn(`plugin ${e.name} onChangeEvent failed`, { error: Qn.pretty(t) })))));
1652
- });
1653
- }
1654
- let Nn = Ne({
1655
- plugins: j,
1656
- appName: v?.name ?? "voltro-api",
1657
- appType: "api",
1658
- voltroVersion: process.env.npm_package_version ?? "0.0.0",
1659
- log: $
1660
- });
1661
- j.length && await Nn.activate(), d.mark("plugins");
1662
- let Pn = await Nn.gatherObservability(), Fn = {
1663
- info: (e, t) => process.stdout.write(`[broadcast] ${e} ${t ? JSON.stringify(t) : ""}\n`),
1664
- warn: (e, t) => process.stderr.write(`[broadcast] ${e} ${t ? JSON.stringify(t) : ""}\n`),
1665
- debug: () => {}
1666
- }, z, In = await A(E, v, y, L, Fn, (e, t) => {
1667
- z?.refreshAll(`broadcast gap: missed ${t} change(s) from ${e}`);
1668
- }), Ln = v?.apiKeys, Rn = (typeof Ln == "object" ? Ln.prefix : void 0) ?? "voltro_", B = Ln ? xr(E) : void 0, V = B ? jr({ flush: Mr(B) }) : void 0;
1669
- V && Yr(() => V.shutdown());
1670
- let zn = B ? Ar(B, {
1671
- prefix: Rn,
1672
- ...V ? { usage: V } : {}
1673
- }) : void 0, Bn = zn ? [wr(zn, { prefix: Rn })] : [], Vn = St([...v?.auth?.strategies ?? [], ...Bn], Mi(v?.plugins ?? []), v?.auth?.anonymousTenantRequired ?? !1, v?.auth, () => He), Hn = [...v?.restRoutes ?? [], ...zn ? ur(zn, (typeof Ln == "object" ? Ln.managementPath : void 0) ?? "/v1/api-keys") : []], Un = Ct(v?.idempotency, E), Wn = j.map((e) => e.services).filter((e) => e !== void 0), Gn = G.mergeAll(_t({
1674
- analyticsLayer: ke.layer,
1675
- cacheService: We,
1676
- kvService: ft,
1677
- ...Qe === void 0 ? {} : { semanticCache: Qe },
1678
- pluginServices: Wn,
1679
- userLayers: v?.layers ?? []
1680
- }), Re(v?.http ?? {})), H = await ze({
1681
- files: b,
1682
- store: E,
1683
- log: $,
1684
- seedPolicy: "report",
1685
- seedPattern: fn,
1686
- loadSeedFiles: I,
1687
- startupPattern: sn,
1688
- loadStartupFiles: a,
1689
- runStartups: o,
1690
- emailPattern: k,
1691
- loadEmailFiles: Tt,
1692
- registerEmailTemplates: Ni
1693
- });
1694
- (H.startupCount > 0 || H.emailCount > 0) && $.info("boot lifecycle", {
1695
- startups: H.startupCount,
1696
- emailTemplates: H.emailCount
1697
- }), H.startups !== void 0 && Yr(async () => {
1698
- await H.startups.stop();
1699
- }), de({
1700
- demands: Se(ue),
1701
- isRegistered: (e) => Tr(e) !== void 0
1702
- });
1703
- let qn = wt({
1704
- schedules: ot({
1705
- schedules: x.schedules,
1706
- seeds: H.seeds,
1707
- store: E,
1708
- log: $.child("seeds")
1709
- }),
1710
- workflows: x.workflows ?? [],
1711
- log: $.child("workflow-schedules")
1712
- }), Yn = v?.scheduling ?? {}, U = Yn.trigger ?? "self", Zn = /* @__PURE__ */ new Set([
1713
- "postgres",
1714
- "mysql",
1715
- "mariadb",
1716
- "mssql"
1717
- ]), ar = Yn.coordination ?? (Zn.has(y) ? "advisoryLock" : "single"), K = ar === "cluster" && Zn.has(y), or = K ? "cluster" : ar === "advisoryLock" && Zn.has(y) ? "advisoryLock" : "single";
1718
- ar === "cluster" && !K && $.warn("scheduling.coordination=cluster needs a sql-backed store except sqlite — falling back to single"), ar === "advisoryLock" && !Zn.has(y) && $.warn("scheduling.coordination=advisoryLock needs a SQL store (the claim-row gate) — falling back to single");
1719
- let sr, cr = x.workflows.length > 0 || x.workflowWorkers.length > 0 || x.eventTriggers.length > 0 || (be?.outgoing.length ?? 0) > 0 || K, lr;
1720
- if (cr) {
1721
- if (y === "mssql") {
1722
- let e = await hn(process.cwd());
1723
- e && $.warn(e);
1724
- }
1725
- let [{ WorkflowEngine: e }, { makeClusterCronLayer: t, workflowEngineLayer: n, resolveRunnerStorage: r, resolveFailoverTuning: i }] = await Promise.all([import("@effect/workflow"), import("@voltro/workflow/cluster")]), a = K ? qn.filter((e) => (e.trigger ?? U) === "self").map((e) => t({
1726
- name: e.name,
1727
- cron: br(e),
1728
- execute: async () => {
1729
- await sr?.fireFromCluster(e.name);
1730
- }
1731
- })) : [];
1732
- lr = y === "memory" ? e.layerMemory : await (async () => {
1733
- let e = await F(y), t = r({ sqliteFamily: e.id === "sqlite" || e.id === "turso" });
1734
- 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)" : "") : "")), n({
1735
- sqlClientLayer: e.makeSqlLayer(O()),
1736
- runnerStorage: t,
1737
- dialectId: e.id,
1738
- ...process.env.VOLTRO_WORKFLOW_RUNNER_PORT ? { runnerListenPort: Number(process.env.VOLTRO_WORKFLOW_RUNNER_PORT) } : {},
1739
- ...i(),
1740
- ...a.length > 0 ? { extraShardingLayers: a } : {}
1741
- });
1742
- })();
1743
- }
1744
- let fr = bt(j, bn()), pr = b.filter((e) => /\.subscribe\.tsx?$/.test(e)), mr = pr.length > 0 ? await c(pr, $) : [], hr = b.filter((e) => /\.reaction\.tsx?$/.test(e)), q = hr.length > 0 ? await he(hr, $) : [], gr = b.filter((e) => un.test(e)), _r = gr.length > 0 ? await Me(gr, $) : [], vr = b.filter((e) => /\.aggregate\.tsx?$/.test(e)), yr = vr.length > 0 ? await _e(vr, $) : [];
1745
- {
1746
- let e = Cr(li(Ve({ aggregates: yr.map((e) => e.definition) }), Lt(T)));
1747
- e !== void 0 && $.warn(e);
1748
- }
1749
- let Er = ut();
1750
- if (yr.length > 0 && y !== "memory") try {
1751
- let e = (await F(y)).makeSqlLayer(O());
1752
- Er = u(e);
1753
- } catch (e) {
1754
- $.warn("aggregate: SQL storage init failed — falling back to in-process", { err: String(e) });
1755
- }
1756
- let Dr = y === "memory" ? ii : kr(E, `aggregate@${process.pid}`, $), Or = b.filter((e) => dn.test(e)), Pr = Or.length > 0 ? await Ft(Or, $) : [], Ir = b.filter((e) => ln.test(e)), Lr = Ir.length > 0 ? await m(Ir, $) : [], Rr = b.filter((e) => cn.test(e)), zr = Rr.length > 0 ? await w(Rr, $) : [], Br = [], Vr = [], Hr = b.filter((e) => Zt.test(e));
1757
- if (Hr.length > 0) {
1758
- let e = $.child("agent"), t = b.filter((e) => en.test(e));
1759
- t.length > 0 && await Qt(t, e);
1760
- let n = await $t(Hr, e);
1761
- for (let e of n.agents) for (let t of Ot(e)) (t.kind === "action" ? Br : Vr).push({
1762
- file: t.file,
1763
- descriptor: t.descriptor,
1764
- executor: t.executor
1765
- });
1766
- n.agents.length > 0 && e.info("synthesized agent routes", { agents: n.agents.map((e) => e.descriptor.name) });
1767
- }
1768
- d.mark("workflow");
1769
- let J = () => {
1770
- let e = Y.workflowWriteActions();
1771
- if (e === void 0) throw Error("workflow actions: this app registers no workflows");
1772
- return e;
1773
- }, Ur = Jn({
1774
- dialect: y,
1775
- ...O()
1776
- }), Gr = y === "memory" ? void 0 : (await F(y)).makeSqlLayer(O()), Kr = async () => D({
1777
- sqlLayer: Gr,
1778
- declared: T,
1779
- log: $
1780
- }), qr = {
1781
- kind: "api",
1782
- meta: {
1783
- name: v?.name ?? "voltro-api",
1784
- voltroVersion: Et,
1785
- port: ie,
1786
- mode: "start",
1787
- store: y,
1788
- cdc: se ? "on" : "off",
1789
- ...Ur === void 0 ? {} : { databaseId: Ur }
1790
- },
1791
- rpc: Ie(x, g),
1792
- workflows: Nt(x, g),
1793
- migrations: Kr,
1794
- events: () => Y.eventsSnapshot(),
1795
- agentTools: () => Y.agentTools(),
1796
- invariantChecks: () => ({
1797
- mode: "serve",
1798
- accessGate: ue,
1799
- config: v,
1800
- serverOnlyLeaks: x.serverOnlyLeaks,
1801
- migrations: Kr
1802
- }),
1803
- members: () => Y.membersSnapshot(),
1804
- inspectFireSchedule: async ({ name: e, trigger: t }) => {
1805
- if (!sr) throw Error("scheduler not started — this app registers no self-triggered schedules (all schedules are trigger:'external', or there are none).");
1806
- return { runId: await sr.fireNow(e, t) ?? null };
1807
- },
1808
- inspectBackfillSchedule: _({
1809
- getHandle: () => sr,
1810
- getSchedules: () => qn
1811
- }),
1812
- ...be === void 0 ? {} : { webhooks: () => ge({
1813
- store: E,
1814
- discoveredWebhooks: be
1815
- }) },
1816
- plugins: () => ({
1817
- plugins: Nn.snapshot(),
1818
- capturedAt: Date.now()
1819
- }),
1820
- env: () => Gt(v?.name ?? En(g), {
1821
- ...v?.env !== void 0 && Si(v.env) ? { contract: v.env } : {},
1822
- plugins: v?.plugins ?? []
1823
- }),
1824
- dataCache: () => Be({
1825
- stats: st,
1826
- backendKind: at
1827
- }),
1828
- subscriptions: () => It(() => z),
1829
- inspectTables: () => S(x.tables),
1830
- inspectRows: C({
1831
- store: E,
1832
- tables: x.tables,
1833
- mask: !0
1834
- }),
1835
- metrics: (e) => Y.rpcMetrics().snapshot(e),
1836
- cluster: () => zt({
1837
- store: E,
1838
- dialect: y,
1839
- useClusterCron: K,
1840
- scheduleCoordChoice: ar
1841
- }),
1842
- inspectSchedules: () => Te({
1843
- schedules: qn,
1844
- defaultTrigger: U,
1845
- coordination: or
1846
- }),
1847
- inspectScheduleRuns: (e) => N(E, e),
1848
- ...f(E, {
1849
- controls: rt(x.workflows ?? []),
1850
- active: (x.workflows?.length ?? 0) > 0,
1851
- cancellation: () => Y.flowControlHealth()
1852
- }),
1853
- webhookActions: Ce(() => Y.webhooksService()),
1854
- inspectStartWorkflow: (e) => J().inspectStartWorkflow(e),
1855
- inspectCancelWorkflowRun: (e) => J().inspectCancelWorkflowRun(e),
1856
- inspectSuspendWorkflowRun: (e) => J().inspectSuspendWorkflowRun(e),
1857
- inspectResumeWorkflowRun: (e) => J().inspectResumeWorkflowRun(e),
1858
- inspectDiscardWorkflowRun: (e) => J().inspectDiscardWorkflowRun(e),
1859
- inspectRetryWorkflowRun: (e) => J().inspectRetryWorkflowRun(e),
1860
- inspectSignalWorkflowRun: (e) => J().inspectSignalWorkflowRun(e),
1861
- inspectUpdateWorkflowRun: (e) => J().inspectUpdateWorkflowRun(e),
1862
- inspectInferences: (e) => yt({
1863
- store: E,
1864
- active: (x.workflows?.length ?? 0) > 0,
1865
- dispatcher: () => Y.inferenceHealth()
1866
- }, e.limit === void 0 ? {} : { limit: e.limit }),
1867
- ...ht({
1868
- store: E,
1869
- cancelRun: async (e) => await Y.runCanceller()?.(e) ?? !1,
1870
- retryRun: async (e) => J().inspectRetryWorkflowRun({ runId: e }),
1871
- redriveRun: async (e) => Y.redriveWorkflowRun({ runId: e }),
1872
- log: $
1873
- }),
1874
- inspectRedriveWorkflowRun: (e) => Y.redriveWorkflowRun(e),
1875
- inspectResumeWorkflowRunFromStep: (e) => Y.resumeWorkflowRunFromStep(e)
1876
- }, Jr = (process.env.VOLTRO_TENANT_ISOLATION ?? v?.tenancy?.isolation) === "namespace", Xr = Jr && y !== "memory" ? await (async () => {
1877
- let e = await F(y);
1878
- return At({
1879
- tables: T,
1880
- sqlLayer: e.makeSqlLayer(O()),
1881
- dialect: y,
1882
- options: { retryFilter: e.retryFilter },
1883
- log: {
1884
- info: (e, t) => $.info(e, t),
1885
- error: (e, t, n) => $.error(e, t ?? {}, n)
1886
- }
1887
- });
1888
- })() : void 0, Zr = await pt({
1889
- input: v?.tenancy?.residency,
1890
- namespaceIsolationOn: Jr,
1891
- makeStoreForUrl: (e, t) => it(v, void 0, Kt(O(), t)),
1892
- log: {
1893
- info: (e, t) => $.info(e, t),
1894
- warn: (e, t) => $.warn(e, t)
1895
- }
1896
- });
1897
- Zr !== void 0 && Yr(async () => {
1898
- await Zr.close();
1899
- });
1900
- let Y = await Ea({
1901
- bootTiming: d,
1902
- broadcastNamespace: L,
1903
- scheduling: (() => {
1904
- let e = _n;
1905
- return {
1906
- admissionDrainMs: e.admissionDrainMs,
1907
- inferenceTickMs: e.inferenceTickMs,
1908
- cancelSweepMs: e.cancelSweepMs,
1909
- stalenessSweepMs: e.stalenessSweepMs,
1910
- disarmWhenIdle: Le({
1911
- changeScope: E.changeScope,
1912
- broadcastAttached: In !== void 0
1913
- })
1914
- };
1915
- })(),
1916
- ...v?.workflows?.staleness === void 0 ? {} : { workflowStaleness: v.workflows.staleness },
1917
- ...v?.workflows?.suspendSignalHintMs === void 0 ? {} : { workflowSuspendSignalHintMs: v.workflows.suspendSignalHintMs },
1918
- workflowRecording: Vt(v?.workflows?.recording),
1919
- membership: {
1920
- ...jn,
1921
- instanceId: Tn
1922
- },
1923
- security: {
1924
- defaultDeny: oe(v),
1925
- ...re(v)
1926
- },
1927
- approvals: { defaultExpiryMs: je(v) },
1928
- ...v?.plugins === void 0 ? {} : { plugins: v.plugins },
1929
- ...Un ? { idempotency: Un } : {},
1930
- restRoutes: Hn,
1931
- appProcedures: ue,
1932
- discovered: {
1933
- queries: [...x.queries, ...Vr],
1934
- mutations: x.mutations,
1935
- actions: [...x.actions, ...Br],
1936
- streams: x.streams,
1937
- events: x.events,
1938
- workflows: x.workflows,
1939
- workflowWorkers: x.workflowWorkers,
1940
- eventTriggers: x.eventTriggers,
1941
- schedules: qn,
1942
- subscribers: mr,
1943
- outboxHandlers: _r,
1944
- connections: x.connections,
1945
- reactions: q,
1946
- aggregates: yr,
1947
- expectations: Pr,
1948
- budgets: Lr,
1949
- experiments: zr,
1950
- ...be === void 0 ? {} : { webhooks: be }
1951
- },
1952
- log: $,
1953
- analytics: ke.sink,
1954
- aggregateStorage: Er,
1955
- aggregateCoordinator: Dr,
1956
- store: E,
1957
- kv: dt,
1958
- cache: Ye,
1959
- snapshotCache: qe,
1960
- ...v?.reactive === void 0 ? {} : { reactive: v.reactive },
1961
- schemaRegistry: Fe,
1962
- tenantScopedTables: x.tenantScopedTables,
1963
- softDeleteScopedTables: x.softDeleteScopedTables,
1964
- dataTransferSnapshot: tr(T, y),
1965
- dataTransferDialect: y,
1966
- ...Xr === void 0 ? {} : { ensureTenantProvisioned: Xr.ensure },
1967
- ...Zr === void 0 ? {} : { resolveResidentStore: Zr.resolveStore },
1968
- tenantIsolation: (process.env.VOLTRO_TENANT_ISOLATION ?? v?.tenancy?.isolation) === "namespace" ? "namespace" : "shared-schema",
1969
- resolveSubject: (e, t) => Vn({
1970
- headers: e,
1971
- clientId: t
1972
- }),
1973
- ...v?.auth === void 0 ? {} : { authority: v.auth },
1974
- ...v?.agents === void 0 ? {} : { agents: v.agents },
1975
- httpRoutes: j.flatMap((e) => e.httpRoutes ?? []),
1976
- getStore: () => He,
1977
- ...Gn ? { baseLayer: Gn } : {},
1978
- ...lr === void 0 ? {} : { workflowEngineLayer: lr },
1979
- scheduleDefaultTrigger: U,
1980
- scheduleCoordination: or,
1981
- scheduleArmSelf: !K,
1982
- dormancy: process.env.VOLTRO_DORMANCY === "sleep" || process.env.VOLTRO_DORMANCY === "always-on" ? process.env.VOLTRO_DORMANCY : v?.dormancy ?? "always-on",
1983
- scheduleReplicaId: process.env.HOSTNAME ?? `pid-${process.pid}`,
1984
- ...fr === void 0 ? {} : { scheduleFireInterceptor: fr },
1985
- onSchedulerReady: (e) => {
1986
- sr = e;
1987
- },
1988
- inspectRoute: { handle: async (e, t, n, r) => await h(e, qr, t, {
1989
- method: n,
1990
- ...r === void 0 ? {} : { body: r }
1991
- }) || ((n === "GET" ? await mn(e, qr, t, { method: n }) : null) ?? pn(e, qr, t, {
1992
- method: n,
1993
- ...r === void 0 ? {} : { body: r }
1994
- }) ?? {
1995
- status: 404,
1996
- contentType: "application/json",
1997
- body: JSON.stringify({ error: "not an inspect route" })
1998
- }) },
1999
- ...v?.name === void 0 ? {} : { appName: v.name },
2000
- observability: Pn,
2001
- port: ie,
2002
- ...v?.transport?.wsPath ? { path: v.transport.wsPath } : {}
2003
- });
2004
- return z = Y.dispatcher, te(Ee([
2005
- x.queries,
2006
- x.mutations,
2007
- x.actions,
2008
- x.streams
2009
- ]), (e) => {
2010
- $.warn(e);
2011
- }), $.info(`API listening on :${ie}`, {
2012
- dialect: y,
2013
- queries: x.queries.length,
2014
- mutations: x.mutations.length,
2015
- actions: x.actions.length,
2016
- streams: x.streams.length,
2017
- workflows: x.workflows.length,
2018
- workflowWorkers: x.workflowWorkers.length,
2019
- schedules: qn.length,
2020
- scheduleCoordination: or
2021
- }), d.finish($), Yr(async () => {
2022
- for (let e of wn) e.stop();
2023
- xt.stop();
2024
- try {
2025
- await Y.close(), ct(), Rt?.dispose(), await Nn.deactivate(), await In?.close(), await Dt({
2026
- mirror: gt,
2027
- log: $
2028
- }), await ke.dispose(), await E.close?.();
2029
- } catch (e) {
2030
- console.error("serve: shutdown step failed, exiting anyway:", e);
2031
- }
2032
- }), await new Promise(() => {}), 0;
2033
- };
2034
- //#endregion
2035
- export { ka as n, Da as r, Aa as t };