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