better-supabase 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +299 -41
- package/dist/access-sql-B0dF-SoF.js +181 -0
- package/dist/actor-CQTlc1Hh.d.ts +43 -0
- package/dist/adapter-Bc1o3zyy.js +1106 -0
- package/dist/agents-CVHGd7It.d.ts +94 -0
- package/dist/ai-cache-CBWs1W0k.js +80 -0
- package/dist/ai-cache-DaDu_G5L.d.ts +64 -0
- package/dist/ai-chat-7amvXjmQ.d.ts +590 -0
- package/dist/ai-chat-B24UI962.js +743 -0
- package/dist/ai-files-CSPNswUY.js +319 -0
- package/dist/ai-sdk/agents/index.d.ts +74 -0
- package/dist/ai-sdk/agents/index.js +159 -0
- package/dist/ai-sdk/batches/index.d.ts +74 -0
- package/dist/ai-sdk/batches/index.js +180 -0
- package/dist/ai-sdk/cache/index.d.ts +38 -0
- package/dist/ai-sdk/cache/index.js +127 -0
- package/dist/ai-sdk/chat/index.d.ts +2 -0
- package/dist/ai-sdk/chat/index.js +246 -0
- package/dist/ai-sdk/embeddings/index.d.ts +3 -0
- package/dist/ai-sdk/embeddings/index.js +2 -0
- package/dist/ai-sdk/files/index.d.ts +61 -0
- package/dist/ai-sdk/files/index.js +111 -0
- package/dist/ai-sdk/index.d.ts +145 -0
- package/dist/ai-sdk/index.js +174 -0
- package/dist/ai-sdk/mcp/index.d.ts +102 -0
- package/dist/ai-sdk/mcp/index.js +362 -0
- package/dist/ai-sdk/memory/index.d.ts +67 -0
- package/dist/ai-sdk/memory/index.js +175 -0
- package/dist/ai-sdk/react/index.d.ts +2 -0
- package/dist/ai-sdk/react/index.js +3 -0
- package/dist/ai-sdk/react/server.d.ts +6 -0
- package/dist/ai-sdk/react/server.js +7 -0
- package/dist/ai-sdk/workflow/index.d.ts +249 -0
- package/dist/ai-sdk/workflow/index.js +575 -0
- package/dist/ai-sdk/workflow/react/index.d.ts +20 -0
- package/dist/ai-sdk/workflow/react/index.js +66 -0
- package/dist/ai-sdk/workflow/react/server.d.ts +10 -0
- package/dist/ai-sdk/workflow/react/server.js +12 -0
- package/dist/ai-tasks-Cd1HMFvB.d.ts +131 -0
- package/dist/announcements-CiyOs-xP.js +107 -0
- package/dist/announcements-ZRGnScWI.d.ts +72 -0
- package/dist/api-keys-rCGtKaZA.d.ts +156 -0
- package/dist/assistant-DwdpDH1q.d.ts +147 -0
- package/dist/astro/index.d.ts +86 -0
- package/dist/astro/index.js +93 -0
- package/dist/attributes-5dYul0u0.js +13 -0
- package/dist/auth-link-BjFPqwLz.d.ts +97 -0
- package/dist/auth-link-DrDX9KOT.js +114 -0
- package/dist/authorization-BFCqamMs.d.ts +172 -0
- package/dist/before-route-CnR0C0Jr.js +30 -0
- package/dist/bind-Bu_ZNa3W.d.ts +62 -0
- package/dist/bind-l4kAvYSv.js +97 -0
- package/dist/block-events-CrT8r7Fe.js +76 -0
- package/dist/block-fields-GFkxl4dP.js +49 -0
- package/dist/block-fields-SJ6fEf3o.d.ts +31 -0
- package/dist/block-helpers-CKtbFcRv.d.ts +37 -0
- package/dist/block-helpers-DWHxHsEQ.js +190 -0
- package/dist/block-hooks-BmjMyXTa.js +114 -0
- package/dist/block-hooks-plbZ0AbJ.d.ts +107 -0
- package/dist/{kit-transport-DJlHQUBU.js → block-transport-BLr-ZgLc.js} +11 -7
- package/dist/block-transport-DvaoPuZ9.d.ts +48 -0
- package/dist/blocks/agents/index.d.ts +3 -0
- package/dist/blocks/agents/index.js +123 -0
- package/dist/blocks/ai-cache/index.d.ts +3 -0
- package/dist/blocks/ai-cache/index.js +3 -0
- package/dist/blocks/ai-chat/index.d.ts +31 -0
- package/dist/blocks/ai-chat/index.js +5 -0
- package/dist/blocks/ai-chat/react/index.d.ts +77 -0
- package/dist/blocks/ai-chat/react/index.js +387 -0
- package/dist/blocks/ai-chat/react/server.d.ts +16 -0
- package/dist/blocks/ai-chat/react/server.js +14 -0
- package/dist/blocks/ai-files/index.d.ts +14 -0
- package/dist/blocks/ai-files/index.js +3 -0
- package/dist/blocks/ai-providers/index.d.ts +7 -0
- package/dist/blocks/ai-providers/index.js +211 -0
- package/dist/blocks/ai-tasks/index.d.ts +3 -0
- package/dist/blocks/ai-tasks/index.js +203 -0
- package/dist/blocks/announcements/index.d.ts +3 -0
- package/dist/blocks/announcements/index.js +3 -0
- package/dist/blocks/announcements/react/index.d.ts +31 -0
- package/dist/blocks/announcements/react/index.js +86 -0
- package/dist/blocks/announcements/react/server.d.ts +6 -0
- package/dist/blocks/announcements/react/server.js +7 -0
- package/dist/blocks/api-keys/index.d.ts +35 -0
- package/dist/blocks/api-keys/index.js +334 -0
- package/dist/blocks/attachments/index.d.ts +210 -0
- package/dist/blocks/attachments/index.js +222 -0
- package/dist/blocks/audit/index.d.ts +366 -0
- package/dist/blocks/audit/index.js +714 -0
- package/dist/blocks/billing/index.d.ts +265 -0
- package/dist/blocks/billing/index.js +400 -0
- package/dist/blocks/comments/index.d.ts +200 -0
- package/dist/blocks/comments/index.js +207 -0
- package/dist/blocks/connectors/index.d.ts +3 -0
- package/dist/blocks/connectors/index.js +164 -0
- package/dist/blocks/data-lifecycle/index.d.ts +251 -0
- package/dist/blocks/data-lifecycle/index.js +353 -0
- package/dist/blocks/entitlements/index.d.ts +14 -0
- package/dist/blocks/entitlements/index.js +25 -0
- package/dist/blocks/flags/index.d.ts +226 -0
- package/dist/blocks/flags/index.js +282 -0
- package/dist/blocks/inbox/index.d.ts +6 -0
- package/dist/blocks/inbox/index.js +499 -0
- package/dist/blocks/inbox/react/index.d.ts +2 -0
- package/dist/blocks/inbox/react/index.js +225 -0
- package/dist/blocks/inbox/react/server.d.ts +10 -0
- package/dist/blocks/inbox/react/server.js +12 -0
- package/dist/blocks/index.d.ts +65 -0
- package/dist/blocks/index.js +77 -0
- package/dist/blocks/jobs/index.d.ts +297 -0
- package/dist/blocks/jobs/index.js +1051 -0
- package/dist/blocks/knowledge/index.d.ts +3 -0
- package/dist/blocks/knowledge/index.js +3 -0
- package/dist/blocks/memory/index.d.ts +8 -0
- package/dist/blocks/memory/index.js +289 -0
- package/dist/blocks/notifications/index.d.ts +297 -0
- package/dist/blocks/notifications/index.js +425 -0
- package/dist/blocks/notifications/react/index.d.ts +44 -0
- package/dist/blocks/notifications/react/index.js +67 -0
- package/dist/blocks/notifications/react/server.d.ts +6 -0
- package/dist/blocks/notifications/react/server.js +7 -0
- package/dist/blocks/onboarding/index.d.ts +3 -0
- package/dist/blocks/onboarding/index.js +64 -0
- package/dist/blocks/onboarding/react/index.d.ts +28 -0
- package/dist/blocks/onboarding/react/index.js +78 -0
- package/dist/blocks/onboarding/react/server.d.ts +7 -0
- package/dist/blocks/onboarding/react/server.js +7 -0
- package/dist/blocks/organizations/index.d.ts +241 -0
- package/dist/blocks/organizations/index.js +400 -0
- package/dist/blocks/outbox/index.d.ts +3 -0
- package/dist/blocks/outbox/index.js +266 -0
- package/dist/blocks/profiles/index.d.ts +40 -0
- package/dist/blocks/profiles/index.js +28 -0
- package/dist/blocks/push/index.d.ts +185 -0
- package/dist/blocks/push/index.js +258 -0
- package/dist/blocks/settings/index.d.ts +89 -0
- package/dist/blocks/settings/index.js +104 -0
- package/dist/blocks/sso/index.d.ts +198 -0
- package/dist/blocks/sso/index.js +1297 -0
- package/dist/blocks/usage/index.d.ts +4 -0
- package/dist/blocks/usage/index.js +233 -0
- package/dist/blocks/waitlist/index.d.ts +117 -0
- package/dist/blocks/waitlist/index.js +132 -0
- package/dist/blocks/webhooks/index.d.ts +304 -0
- package/dist/{webhooks → blocks/webhooks}/index.js +468 -148
- package/dist/blocks/workflow-builder/index.d.ts +21 -0
- package/dist/blocks/workflow-builder/index.js +5 -0
- package/dist/blocks/workflow-builder/react/index.d.ts +47 -0
- package/dist/blocks/workflow-builder/react/index.js +119 -0
- package/dist/blocks/workflow-builder/react/server.d.ts +8 -0
- package/dist/blocks/workflow-builder/react/server.js +11 -0
- package/dist/blocks/workflows/index.d.ts +3 -0
- package/dist/blocks/workflows/index.js +3 -0
- package/dist/blocks/workflows/react/index.d.ts +47 -0
- package/dist/blocks/workflows/react/index.js +137 -0
- package/dist/blocks/workflows/react/server.d.ts +8 -0
- package/dist/blocks/workflows/react/server.js +11 -0
- package/dist/{index-SaTsEfGP.d.ts → bucket-Cl46E3jS.d.ts} +134 -91
- package/dist/{simplify-_0oUKqCd.js → build-BXIzE6Xv.js} +222 -124
- package/dist/{channel-FQW-CnGR.d.ts → channel-_2Mx1Oyu.d.ts} +2 -2
- package/dist/channels-CkgQ_X60.js +114 -0
- package/dist/chat-sdk/index.d.ts +303 -0
- package/dist/chat-sdk/index.js +733 -0
- package/dist/chat-sdk/react/index.d.ts +2 -0
- package/dist/chat-sdk/react/index.js +3 -0
- package/dist/chat-sdk/react/server.d.ts +3 -0
- package/dist/chat-sdk/react/server.js +2 -0
- package/dist/claims-DDBQT6BK.js +61 -0
- package/dist/{claims-BAf6c7is.js → claims-PqzCxaTD.js} +39 -2
- package/dist/cli/bin.js +1 -1
- package/dist/cli/{codemod-DqV7612m.js → codemod-Bl_tQpHn.js} +105 -2
- package/dist/cli/config-B9HkL8nF.js +2 -0
- package/dist/cli/config-DU7EJImt.js +49 -0
- package/dist/cli/config-NiPxAmUF.js +1077 -0
- package/dist/cli/{dist-xn4wlboc.js → dist-DRAVaE6w.js} +111 -1
- package/dist/cli/{doctor-L7Z8mYTx.js → doctor-B4JOm_ox.js} +992 -316
- package/dist/cli/{env-DmKv_G4A.js → env-CJLbUVPB.js} +1 -1
- package/dist/cli/{env-jIFUADLY.js → env-qXgyMV6r.js} +2 -2
- package/dist/cli/fresh-import-BeYf9I3x.js +40 -0
- package/dist/cli/gen-BGLb_zou.js +3100 -0
- package/dist/cli/gen-DAH8FM2W.js +2 -0
- package/dist/cli/index.d.ts +44 -5
- package/dist/cli/index.js +7 -7
- package/dist/cli/{init-Saf5-R9T.js → init-BIIwclPg.js} +242 -27
- package/dist/cli/{introspect--H7oGmcd.js → introspect-DNUTuNvb.js} +5 -5
- package/dist/cli/{io-k41_z-jT.js → io-DI1mTdSA.js} +12 -3
- package/dist/cli/{keys-ByKHnvP9.js → keys-BGCnnb-s.js} +8 -6
- package/dist/cli/{ohash-D7bG_EOb.js → ohash-BjQY1cBb.js} +1 -1
- package/dist/cli/{openapi-Cp5Fyta-.js → openapi-BlRJ18s3.js} +2 -2
- package/dist/cli/{project-B_GeXyHh.js → project-DZRaBaY7.js} +11 -6
- package/dist/cli/read-sets-CETOSFx4.js +223 -0
- package/dist/cli/{run-BKR2W_79.js → run-DNWxHynX.js} +33 -23
- package/dist/cli/{seed-CUlqWh-8.js → seed-DQzqT7LP.js} +8 -6
- package/dist/cli/{skills-LJJIhLFR.js → skills-QQs4q68J.js} +3 -2
- package/dist/cli/sql-D0GUtUPp.js +536 -0
- package/dist/cli/{config-CPVpXP5I.js → supabase-toml-B-bIukQF.js} +72 -942
- package/dist/cli/typegen-version-DeFbtzYI.js +8 -0
- package/dist/cli/{version-BDJuO0UR.js → version-hr88OZG0.js} +1 -1
- package/dist/client/index.d.ts +3 -2
- package/dist/client/index.js +11 -71
- package/dist/client/native/index.d.ts +228 -0
- package/dist/client/native/index.js +361 -0
- package/dist/client-CI0Z2zWX.js +277 -0
- package/dist/cloud-event-BnmD5fb9.js +46 -0
- package/dist/cloud-event-C1JCc1bH.d.ts +50 -0
- package/dist/{compiler-BXH_aZ7N.d.ts → compiler-DY_wkj4R.d.ts} +2 -2
- package/dist/compose-BIBNgAnq.js +53 -0
- package/dist/composite-Bt1YK3Ke.d.ts +146 -0
- package/dist/composite-DhE66P5u.js +130 -0
- package/dist/config/index.d.ts +6 -4
- package/dist/config/index.js +5 -5
- package/dist/{config-T_ejwyd3.d.ts → config-D44Y7PAv.d.ts} +406 -205
- package/dist/{config-DreERlKo.js → config-Dn7F5k9A.js} +62 -14
- package/dist/connector-Dv8kK0MO.d.ts +107 -0
- package/dist/connectors-hkLCwyEz.d.ts +120 -0
- package/dist/context-BCrWe7ow.d.ts +237 -0
- package/dist/credentials/index.d.ts +31 -0
- package/dist/credentials/index.js +168 -0
- package/dist/cron-DVPUg5k3.js +145 -0
- package/dist/csv-CPAzEmB6.js +25 -0
- package/dist/db-exception-CnWcYPxL.js +15 -0
- package/dist/{define-cNKzqwL_.js → define-B-TVjC25.js} +784 -227
- package/dist/{define-Bp_BZa5h.d.ts → define-CJJkkr1-.d.ts} +353 -61
- package/dist/edge/index.d.ts +69 -11
- package/dist/edge/index.js +191 -75
- package/dist/elysia/index.d.ts +59 -0
- package/dist/elysia/index.js +62 -0
- package/dist/embeddings-4ZvFzjsU.js +127 -0
- package/dist/embeddings-C9KGQnXt.d.ts +68 -0
- package/dist/{refresh-BTrQ_ZTp.d.ts → ended-jLfvw8h-.d.ts} +20 -2
- package/dist/{entitlements-DUxU4oHe.d.ts → entitlements-DHrY2UDZ.d.ts} +16 -7
- package/dist/entitlements-DRl6ZJUm.js +24 -0
- package/dist/envelope-DqnYGRw7.js +47 -0
- package/dist/{errors-DtwXa6b8.js → errors-B11Duf73.js} +82 -13
- package/dist/errors-DLjJHPLK.js +44 -0
- package/dist/escape-like-DHfx6jRr.js +7 -0
- package/dist/escape-like-ImTK0ps_.d.ts +15 -0
- package/dist/eve/index.d.ts +220 -0
- package/dist/eve/index.js +504 -0
- package/dist/eve-gT2Fpjut.d.ts +151 -0
- package/dist/events/index.d.ts +4 -3
- package/dist/events/index.js +9 -50
- package/dist/events-DWDhx77e.d.ts +549 -0
- package/dist/executor-Bq28caBo.js +718 -0
- package/dist/executor-C-R4pucm.js +83 -0
- package/dist/executor-CaWigTyR.d.ts +148 -0
- package/dist/executor-D14tGopJ.d.ts +36 -0
- package/dist/{executor-Cghdstwu.d.ts → executor-DbvExCFC.d.ts} +7 -1
- package/dist/{sql-Coh6n4cC.js → executor-De1Of3m3.js} +210 -11
- package/dist/executor-DvsBbNBS.d.ts +261 -0
- package/dist/expo/index.d.ts +79 -0
- package/dist/expo/index.js +129 -0
- package/dist/expo-sqlite/index.d.ts +58 -0
- package/dist/expo-sqlite/index.js +104 -0
- package/dist/field-errors-BFOa7WhB.d.ts +99 -0
- package/dist/field-errors-VF1yb8yI.js +13 -0
- package/dist/framework-CONDyPYx.js +51 -0
- package/dist/framework-DuVb4Xa8.d.ts +25 -0
- package/dist/gateway-C1ssRHnf.d.ts +130 -0
- package/dist/graph-BGyLLFLX.js +265 -0
- package/dist/h3/index.d.ts +59 -0
- package/dist/h3/index.js +55 -0
- package/dist/h3/v1/index.d.ts +63 -0
- package/dist/h3/v1/index.js +49 -0
- package/dist/history-BZih6SFP.js +64 -0
- package/dist/hono/index.d.ts +56 -7
- package/dist/hono/index.js +97 -45
- package/dist/{react-C_s7kiNz.js → hooks-1BTCJsiw.js} +104 -133
- package/dist/http-Cv4T29xh.js +40 -0
- package/dist/http-DdYadv-o.js +126 -0
- package/dist/image-url-pIVlO6R1.js +41 -0
- package/dist/impersonation-DcqaTBHx.js +148 -0
- package/dist/inbox-i7E1ppo6.d.ts +384 -0
- package/dist/index-ACiNPN4Z.d.ts +74 -0
- package/dist/{index-DgILJRXj.d.ts → index-Bepi-Hgg.d.ts} +91 -28
- package/dist/index-BkWT_uBO.d.ts +51 -0
- package/dist/index-BpFYMsi0.d.ts +53 -0
- package/dist/{index-C7f8cOBM.d.ts → index-Bxih3l0u.d.ts} +2 -2
- package/dist/index-CaxrMD1A.d.ts +1 -0
- package/dist/index-ClmjK_o-.d.ts +55 -0
- package/dist/index-CtuakVRc.d.ts +267 -0
- package/dist/index-D48jVS-N.d.ts +246 -0
- package/dist/index-DDrYaUcq.d.ts +138 -0
- package/dist/index-DQh4VCc9.d.ts +98 -0
- package/dist/{live-D9W2M5aO.d.ts → index-DunNRdnT.d.ts} +136 -38
- package/dist/index.d.ts +65 -18
- package/dist/index.js +42 -14
- package/dist/invalidate-BBqhpxyB.d.ts +19 -0
- package/dist/json-CEnpTHlZ.js +16 -0
- package/dist/json-schema-CvER4kgT.js +502 -0
- package/dist/keys-4MnkWTTh.js +35 -0
- package/dist/kit-B5tid-q5.d.ts +60 -0
- package/dist/kit-Fm-Fv7q5.js +78 -0
- package/dist/knowledge-BXBbT0Tr.d.ts +176 -0
- package/dist/knowledge-CDmiMLew.js +255 -0
- package/dist/lint/index.d.ts +1 -1
- package/dist/lint/index.js +37 -0
- package/dist/list/index.d.ts +3 -2
- package/dist/list/index.js +1 -444
- package/dist/{index-fag8VJZ2.d.ts → list-query-BRt-zDF7.d.ts} +20 -12
- package/dist/list-query-gl808ac1.js +459 -0
- package/dist/{live-CdJBOc4f.js → live-CTAZQkwl.js} +99 -14
- package/dist/logger-DWVYUmwi.d.ts +18 -0
- package/dist/mcp/index.d.ts +38 -11
- package/dist/mcp/index.js +82 -46
- package/dist/mcp/sdk/index.d.ts +105 -0
- package/dist/mcp/sdk/index.js +126 -0
- package/dist/message-CaKlqdsX.js +219 -0
- package/dist/message-CfDoR0Y6.d.ts +94 -0
- package/dist/messages-B9-5887d.js +715 -0
- package/dist/messages-DYP0sUTe.d.ts +59 -0
- package/dist/{mfa-CusDgPaD.d.ts → mfa-Daak8ukG.d.ts} +8 -2
- package/dist/modules-DpPwzC7E.d.ts +192 -0
- package/dist/modules-dxrVK3ID.js +228 -0
- package/dist/nestjs/index.d.ts +68 -0
- package/dist/nestjs/index.js +164 -0
- package/dist/next/client/index.d.ts +35 -0
- package/dist/next/client/index.js +36 -0
- package/dist/next/image/index.js +3 -24
- package/dist/next/index.d.ts +150 -51
- package/dist/next/index.js +261 -107
- package/dist/node/index.d.ts +4 -0
- package/dist/node/index.js +210 -0
- package/dist/node-headers-AO06VhqH.d.ts +24 -0
- package/dist/node-headers-C71zNQHe.js +55 -0
- package/dist/nuxt/index.d.ts +60 -0
- package/dist/nuxt/index.js +64 -0
- package/dist/onboarding-BZGHYJks.d.ts +62 -0
- package/dist/openapi/index.d.ts +1 -1
- package/dist/openapi/index.js +3 -3
- package/dist/orpc/index.d.ts +70 -11
- package/dist/orpc/index.js +73 -24
- package/dist/otel/index.d.ts +7 -7
- package/dist/otel/index.js +87 -57
- package/dist/outbox-Cq7pPYvl.d.ts +161 -0
- package/dist/{plugin-o144f322.d.ts → plugin-FGY8UhYm.d.ts} +30 -10
- package/dist/plugin-tfXW1-qO.js +45 -0
- package/dist/plugins/actor/index.d.ts +2 -2
- package/dist/plugins/actor/index.js +3 -3
- package/dist/plugins/rules/index.d.ts +11 -4
- package/dist/plugins/rules/index.js +40 -13
- package/dist/plugins/soft-delete/index.d.ts +5 -4
- package/dist/plugins/soft-delete/index.js +10 -5
- package/dist/plugins/tenant/index.d.ts +2 -2
- package/dist/plugins/tenant/index.js +18 -11
- package/dist/plugins/timestamps/index.d.ts +5 -3
- package/dist/plugins/timestamps/index.js +6 -4
- package/dist/plugins/validation/index.d.ts +2 -2
- package/dist/plugins/validation/index.js +10 -6
- package/dist/{pool-C9voM4Kw.d.ts → pool-CAu2nLrL.d.ts} +2 -2
- package/dist/postgres/index.d.ts +4 -4
- package/dist/postgres/index.js +1 -2
- package/dist/{postgrest-CruYKAvV.d.ts → postgrest-BLVdEnfe.d.ts} +13 -3
- package/dist/powersync/index.d.ts +43 -0
- package/dist/powersync/index.js +199 -0
- package/dist/powersync/react/index.d.ts +87 -0
- package/dist/powersync/react/index.js +108 -0
- package/dist/{problem-BW1KhzSG.js → problem-BreOl8b8.js} +14 -3
- package/dist/{problem-Blxe8S31.d.ts → problem-DD8LZFjc.d.ts} +21 -3
- package/dist/provider-BH5UWZJ6.d.ts +113 -0
- package/dist/provider-Di3sRutW.js +57 -0
- package/dist/query/index.d.ts +4 -2
- package/dist/query/index.js +4 -3
- package/dist/{query-CCbo44lG.js → query-BQ-NaZon.js} +141 -24
- package/dist/{queue-BYUCjr59.d.ts → queue-CLJurhdy.d.ts} +258 -83
- package/dist/react/index.d.ts +11 -7
- package/dist/react/index.js +7 -3
- package/dist/react/native/index.d.ts +116 -0
- package/dist/react/native/index.js +130 -0
- package/dist/react/server.d.ts +28 -10
- package/dist/react/server.js +22 -5
- package/dist/react/session.d.ts +2 -2
- package/dist/react-4ZqkP8da.js +79 -0
- package/dist/react-F80mF4-t.js +409 -0
- package/dist/react-router/index.d.ts +83 -0
- package/dist/react-router/index.js +89 -0
- package/dist/react-topic-seAWjL3_.js +38 -0
- package/dist/{read-set-DQFt1N_Y.js → read-set-DuKWC9Mj.js} +67 -25
- package/dist/realtime/index.d.ts +4 -5
- package/dist/realtime/index.js +144 -82
- package/dist/refusal-CeJWxmkH.js +61 -0
- package/dist/refusal-D1rgbzNq.d.ts +15 -0
- package/dist/replicas-CwrYp5Zj.js +94 -0
- package/dist/{view-Bq64ki8-.js → resolve-D_IcnvFd.js} +239 -289
- package/dist/{resolve-C15TJq77.d.ts → resolve-KW8nCeL6.d.ts} +29 -45
- package/dist/{resource-CRxxwkQq.js → resource-BsvzCMlX.js} +4 -4
- package/dist/{resource-D8iqWMr-.d.ts → resource-D6Uc7Sk7.d.ts} +5 -5
- package/dist/respond-BUgsXNgk.js +91 -0
- package/dist/respond-DoBijysA.d.ts +93 -0
- package/dist/result-D7y2fT87.d.ts +282 -0
- package/dist/{result-BKiliPY7.js → result-DzUbqgdW.js} +27 -2
- package/dist/run-state-CPo-1X2B.d.ts +12 -0
- package/dist/run-state-CgBKzYMW.js +13 -0
- package/dist/search-CUWCRYKL.js +9 -0
- package/dist/server/index.d.ts +143 -21
- package/dist/server/index.js +46 -14
- package/dist/{respond-D2OQl62-.d.ts → server-CeVeeXwz.d.ts} +225 -80
- package/dist/session-ChiXDZdZ.d.ts +72 -0
- package/dist/shared-CBxosKK3.js +75 -0
- package/dist/{shared-D1dRUrAg.js → shared-CxWmcyqB.js} +2 -1
- package/dist/shared-DDSjEGDR.d.ts +11 -0
- package/dist/sign-in-BCV5S2WZ.d.ts +49 -0
- package/dist/sign-in-Cb1mwv6X.js +86 -0
- package/dist/{signers-Cc6r98SW.d.ts → signers-4y62_VIi.d.ts} +13 -9
- package/dist/simplify-DDO0j0LI.js +83 -0
- package/dist/solid/index.d.ts +131 -0
- package/dist/solid/index.js +344 -0
- package/dist/solid-start/index.d.ts +75 -0
- package/dist/solid-start/index.js +58 -0
- package/dist/{spec-pins-C3oc-Tdp.js → spec-pins--j6mTok4.js} +8 -1
- package/dist/{spec-pins-CqorWDnO.d.ts → spec-pins-C89s6DyW.d.ts} +7 -0
- package/dist/sql/index.d.ts +330 -194
- package/dist/sql/index.js +34901 -6489
- package/dist/ssr/index.d.ts +6 -5
- package/dist/ssr/index.js +3 -3
- package/dist/{standard-D7r6dMUu.js → standard-BK0cqJ7y.js} +4 -3
- package/dist/{standard-J4YgMOLm.d.ts → standard-CYsm7xpT.d.ts} +1 -1
- package/dist/stats-D_AD9GGu.js +1123 -0
- package/dist/storage/index.d.ts +5 -5
- package/dist/storage/index.js +1027 -368
- package/dist/store-BdH5ruDx.js +66 -0
- package/dist/store-CGjgWu5n.d.ts +68 -0
- package/dist/streams/index.d.ts +76 -0
- package/dist/streams/index.js +77 -0
- package/dist/streams/redis/index.d.ts +52 -0
- package/dist/streams/redis/index.js +185 -0
- package/dist/stripe-BMj5LtsT.js +38 -0
- package/dist/stripe-D04h-QBT.d.ts +136 -0
- package/dist/{support-Dk6vdmEw.js → support-BivNqSpK.js} +35 -12
- package/dist/{support-view-Da5peKFg.d.ts → support-view-33Oi07TT.d.ts} +1 -1
- package/dist/svelte/index.d.ts +114 -0
- package/dist/svelte/index.js +344 -0
- package/dist/sveltekit/index.d.ts +116 -0
- package/dist/sveltekit/index.js +106 -0
- package/dist/tags-B99_U9Pp.js +39 -0
- package/dist/tags-Cx-LnIQP.d.ts +30 -0
- package/dist/tanstack-db/index.d.ts +71 -0
- package/dist/tanstack-db/index.js +72 -0
- package/dist/tanstack-start/index.d.ts +75 -0
- package/dist/tanstack-start/index.js +95 -0
- package/dist/tee-CoEppCER.js +101 -0
- package/dist/{template-TxrGI5jR.js → template--jDkl3UP.js} +34 -13
- package/dist/template-CwO38Do8.d.ts +6 -0
- package/dist/temporal-BJGitm-h.js +79 -0
- package/dist/{temporal-required-CAt4Dc9Z.js → temporal-required-BVvW7SYJ.js} +3 -2
- package/dist/tenant-I1TEZ_BX.js +27 -0
- package/dist/tenant-icPeuUBN.d.ts +17 -0
- package/dist/testing/index.d.ts +343 -37
- package/dist/testing/index.js +1186 -79
- package/dist/timing-CyTQPubY.js +92 -0
- package/dist/ttl-Hr34gRu8.js +12 -0
- package/dist/{types-Dnf_wRDz.d.ts → types-6BdhkmZe.d.ts} +111 -45
- package/dist/types-BI-0Sl2v.d.ts +359 -0
- package/dist/types-C05bxW-W.d.ts +220 -0
- package/dist/types-DGs5L0VN.d.ts +192 -0
- package/dist/types-TaiEeBGA.d.ts +156 -0
- package/dist/usage-CrvrL2vw.d.ts +177 -0
- package/dist/user-change-XzvgafU4.js +130 -0
- package/dist/vault-CSO7ss5C.d.ts +50 -0
- package/dist/vercel-connect/index.d.ts +47 -0
- package/dist/vercel-connect/index.js +119 -0
- package/dist/{verify-Ce49ETPz.js → verify-DL41hbvY.js} +85 -13
- package/dist/verify-DPuWngD4.d.ts +172 -0
- package/dist/{version-DM_Roffb.js → version-Bvv6aLjZ.js} +1 -1
- package/dist/view-BeFcRV6G.js +99 -0
- package/dist/{view-BEf0diC5.d.ts → view-DbxLNu8L.d.ts} +35 -32
- package/dist/vue/index.d.ts +141 -0
- package/dist/vue/index.js +362 -0
- package/dist/watch-DI34G86j.d.ts +60 -0
- package/dist/watch-Xuxrvxq-.js +122 -0
- package/dist/{wire-D2dT86vi.js → wire-DtZQ4sdE.js} +15 -5
- package/dist/workflow-builder-DJ1oHn8g.js +398 -0
- package/dist/workflow-sdk/builder/index.d.ts +85 -0
- package/dist/workflow-sdk/builder/index.js +250 -0
- package/dist/workflow-sdk/index.d.ts +14 -0
- package/dist/workflow-sdk/index.js +3 -0
- package/dist/workflow-sdk/world/index.d.ts +107 -0
- package/dist/workflow-sdk/world/index.js +702 -0
- package/dist/workflow-sdk-B3yLD6Br.d.ts +98 -0
- package/dist/workflow-sdk-C2WJ_G2O.js +173 -0
- package/dist/workflow-sdk-world-D-prir6O.js +1397 -0
- package/dist/workflows-B0j9WKPu.d.ts +185 -0
- package/dist/workflows-wu1WWBn7.js +216 -0
- package/package.json +470 -29
- package/schemas/ai-message-v1.json +258 -0
- package/schemas/config-v1.json +1074 -140
- package/schemas/doctor-report-v1.json +21 -1
- package/schemas/snapshot-v2.json +8 -0
- package/skills/better-supabase/SKILL.md +41 -12
- package/skills/better-supabase/references/frontend.md +96 -0
- package/skills/better-supabase/references/plugins.md +10 -6
- package/skills/better-supabase/references/troubleshooting.md +2 -1
- package/skills/better-supabase-api/SKILL.md +76 -22
- package/skills/better-supabase-api/references/adapters.md +207 -0
- package/skills/better-supabase-api/references/ai.md +125 -0
- package/skills/better-supabase-api/references/expo.md +65 -0
- package/skills/better-supabase-api/references/powersync.md +35 -0
- package/skills/better-supabase-api/references/streams-credentials.md +105 -0
- package/skills/better-supabase-auth/SKILL.md +62 -18
- package/skills/better-supabase-auth/references/authorization-providers.md +51 -0
- package/skills/better-supabase-testing/SKILL.md +3 -1
- package/dist/cli/config-dtoekM0v.js +0 -2
- package/dist/cli/gen-BJc9vdyu.js +0 -2
- package/dist/cli/gen-C2osRcr5.js +0 -2204
- package/dist/cli/read-sets-BfMQcKy8.js +0 -289
- package/dist/cli/sql-DzPbfngx.js +0 -348
- package/dist/entitlements-CTEBm7IB.js +0 -20
- package/dist/events-aIO7vsIk.d.ts +0 -230
- package/dist/executor-BunPOO-k.d.ts +0 -402
- package/dist/executor-XycESQPH.js +0 -94
- package/dist/impersonation-VfaGc4Q_.js +0 -41
- package/dist/index-BGdgBPdf.d.ts +0 -161
- package/dist/index-DOESKG27.d.ts +0 -100
- package/dist/index-DmXSxbLi.d.ts +0 -62
- package/dist/index-Dxn2a5cw.d.ts +0 -50
- package/dist/jobs/index.d.ts +0 -226
- package/dist/jobs/index.js +0 -1007
- package/dist/json-schema-m1fiwKgN.js +0 -208
- package/dist/kit-events-CTFDfSwb.js +0 -60
- package/dist/kit-transport-B82k1djG.d.ts +0 -33
- package/dist/kits-CGLLrNPd.js +0 -157
- package/dist/notifications/index.d.ts +0 -162
- package/dist/notifications/index.js +0 -264
- package/dist/orgs/index.d.ts +0 -132
- package/dist/orgs/index.js +0 -245
- package/dist/permdock-sql-C2Inc6Xc.d.ts +0 -29
- package/dist/permdock-sql-DgOfeixi.js +0 -51
- package/dist/plugin-DwARMuQp.js +0 -59
- package/dist/server-Csx2sRjg.js +0 -655
- package/dist/stats-Bqob3WqT.js +0 -592
- package/dist/support-DT-OhSxD.d.ts +0 -88
- package/dist/template-mbvlysOo.d.ts +0 -6
- package/dist/temporal-CVlIV2DZ.js +0 -40
- package/dist/user-change-CHFEUro1.js +0 -49
- package/dist/webhooks/index.d.ts +0 -285
- package/skills/better-supabase-auth/references/permdock.md +0 -100
|
@@ -0,0 +1,702 @@
|
|
|
1
|
+
import { n as dbError } from "../../errors-B11Duf73.js";
|
|
2
|
+
import { a as problemResponse } from "../../problem-BreOl8b8.js";
|
|
3
|
+
import { r as sqlIdent } from "../../template--jDkl3UP.js";
|
|
4
|
+
import { Y as WORLD_POSTGRES_VERSION, r as WORKFLOW_VAULT_SECRETS } from "../../workflow-sdk-world-D-prir6O.js";
|
|
5
|
+
import { Pool } from "pg";
|
|
6
|
+
import { reenqueueActiveRuns } from "@workflow/world";
|
|
7
|
+
import { createWorld as createWorld$1 } from "@workflow/world-postgres";
|
|
8
|
+
//#region src/workflow-sdk/world/analytics.ts
|
|
9
|
+
/** world-postgres stores UTC in `timestamp without time zone` columns. */
|
|
10
|
+
const utc = (column) => `(${column} at time zone 'UTC')`;
|
|
11
|
+
const RUN_COLUMNS = `
|
|
12
|
+
r.id as "runId", r.status::text as status, r.deployment_id as "deploymentId",
|
|
13
|
+
r.name as "workflowName", nullif(r.spec_version, '')::int as "specVersion",
|
|
14
|
+
coalesce(r.attributes, '{}'::jsonb) as attributes,
|
|
15
|
+
${utc("r.created_at")} as "createdAt", ${utc("r.updated_at")} as "updatedAt",
|
|
16
|
+
${utc("r.started_at")} as "startedAt", ${utc("r.completed_at")} as "completedAt",
|
|
17
|
+
r.error_code as "errorCode",
|
|
18
|
+
r.encryption_public_key is not null as "workflowEncryptionEnabled"`;
|
|
19
|
+
const STEP_COLUMNS = `
|
|
20
|
+
s.run_id as "runId", s.step_id as "stepId", s.step_name as "stepName",
|
|
21
|
+
s.status::text as status, s.attempt,
|
|
22
|
+
${utc("s.created_at")} as "createdAt", ${utc("s.updated_at")} as "updatedAt",
|
|
23
|
+
${utc("s.started_at")} as "startedAt", ${utc("s.completed_at")} as "completedAt",
|
|
24
|
+
${utc("s.retry_after")} as "retryAfter"`;
|
|
25
|
+
const EVENT_COLUMNS = `
|
|
26
|
+
e.run_id as "runId", e.id as "eventId", e.type as "eventType",
|
|
27
|
+
e.correlation_id as "correlationId", e.correlation_id as "entityId",
|
|
28
|
+
(select s.step_name from workflow.workflow_steps s
|
|
29
|
+
where s.run_id = e.run_id and s.step_id = e.correlation_id) as "stepName",
|
|
30
|
+
r.name as "workflowName", r.deployment_id as "deploymentId",
|
|
31
|
+
e.spec_version as "specVersion", ${utc("r.created_at")} as "runCreatedAt",
|
|
32
|
+
${utc("e.created_at")} as "createdAt",
|
|
33
|
+
case when e.payload ? 'resumeAt' then (e.payload ->> 'resumeAt')::timestamptz end as "resumeAt",
|
|
34
|
+
case when e.payload ? 'retryAfter' then (e.payload ->> 'retryAfter')::timestamptz end as "retryAfter",
|
|
35
|
+
e.payload ->> 'errorCode' as "errorCode"`;
|
|
36
|
+
/** world-postgres keys waits `<runId>-<correlationId>`; analytics names them by the correlation id, as steps and hooks. */
|
|
37
|
+
const WAIT_COLUMNS = `
|
|
38
|
+
w.run_id as "runId",
|
|
39
|
+
case when starts_with(w.wait_id, w.run_id || '-')
|
|
40
|
+
then substr(w.wait_id, length(w.run_id) + 2) else w.wait_id end as "waitId",
|
|
41
|
+
w.status::text as status,
|
|
42
|
+
${utc("w.resume_at")} as "resumeAt", ${utc("w.created_at")} as "createdAt",
|
|
43
|
+
${utc("w.updated_at")} as "updatedAt", ${utc("w.completed_at")} as "completedAt"`;
|
|
44
|
+
/** Hooks keep their row only while active, so the status comes from the event log. */
|
|
45
|
+
const HOOKS = `
|
|
46
|
+
select e.run_id as "runId", e.correlation_id as "hookId",
|
|
47
|
+
case
|
|
48
|
+
when bool_or(e.type = 'hook_conflict') then 'conflict'
|
|
49
|
+
when bool_or(e.type = 'hook_disposed') then 'disposed'
|
|
50
|
+
when bool_or(e.type = 'hook_received') then 'received'
|
|
51
|
+
else 'created'
|
|
52
|
+
end as status,
|
|
53
|
+
${utc("min(e.created_at)")} as "createdAt",
|
|
54
|
+
${utc("max(e.created_at)")} as "updatedAt",
|
|
55
|
+
${utc("max(e.created_at) filter (where e.type = 'hook_received')")} as "receivedAt",
|
|
56
|
+
${utc("max(e.created_at) filter (where e.type = 'hook_disposed')")} as "disposedAt",
|
|
57
|
+
bool_or(h.is_webhook) as "isWebhook", bool_or(h.is_system) as "isSystem"
|
|
58
|
+
from workflow.workflow_events e
|
|
59
|
+
left join workflow.workflow_hooks h on h.hook_id = e.correlation_id
|
|
60
|
+
where e.type like 'hook\\_%' and e.correlation_id is not null`;
|
|
61
|
+
function page(pagination, max) {
|
|
62
|
+
const limit = Math.min(max, Math.max(1, pagination?.limit ?? max));
|
|
63
|
+
if (pagination?.limit !== void 0 && pagination.limit > max) throw new RangeError(`better-supabase: the analytics page limit is ${String(max)}, got ${String(pagination.limit)}`);
|
|
64
|
+
const offset = Number(pagination?.cursor ?? 0);
|
|
65
|
+
return {
|
|
66
|
+
limit,
|
|
67
|
+
offset: Number.isSafeInteger(offset) && offset > 0 ? offset : 0,
|
|
68
|
+
order: pagination?.sortOrder === "asc" ? "asc" : "desc"
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function paged(rows, limit, offset) {
|
|
72
|
+
const hasMore = rows.length > limit;
|
|
73
|
+
return {
|
|
74
|
+
data: rows.slice(0, limit),
|
|
75
|
+
hasMore,
|
|
76
|
+
cursor: hasMore ? String(offset + limit) : null
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/** Converts SQL nulls to the optional fields the analytics schemas allow. */
|
|
80
|
+
function compact(row) {
|
|
81
|
+
const out = {};
|
|
82
|
+
for (const [key, value] of Object.entries(row)) if (value !== null) out[key] = value;
|
|
83
|
+
return out;
|
|
84
|
+
}
|
|
85
|
+
function notFound(what, id) {
|
|
86
|
+
return /* @__PURE__ */ new Error(`better-supabase: workflow ${what} "${id}" not found`);
|
|
87
|
+
}
|
|
88
|
+
const RUN_SCOPED_LIMIT = 1e3;
|
|
89
|
+
const LIMIT = 100;
|
|
90
|
+
const MAX_ATTRIBUTE_FILTERS = 8;
|
|
91
|
+
/**
|
|
92
|
+
* The World's `analytics` namespace over the world-postgres tables: the run
|
|
93
|
+
* listing filters by status, name, window and latest attributes (the GIN
|
|
94
|
+
* index on `workflow_runs.attributes` serves the filter).
|
|
95
|
+
*/
|
|
96
|
+
function createAnalytics(pool) {
|
|
97
|
+
const rows = async (sql, params) => {
|
|
98
|
+
return (await pool.query(sql, [...params])).rows.map((row) => compact(row));
|
|
99
|
+
};
|
|
100
|
+
const one = async (sql, params, what, id) => {
|
|
101
|
+
const [row] = await rows(sql, params);
|
|
102
|
+
if (row === void 0) throw notFound(what, id);
|
|
103
|
+
return row;
|
|
104
|
+
};
|
|
105
|
+
const window = (params, column, values) => {
|
|
106
|
+
if (params.startTime === void 0 !== (params.endTime === void 0)) throw new TypeError("better-supabase: analytics startTime and endTime go together");
|
|
107
|
+
if (params.startTime === void 0 || params.endTime === void 0) return "";
|
|
108
|
+
values.push(params.startTime, params.endTime);
|
|
109
|
+
return ` and ${utc(column)} between $${String(values.length - 1)}::timestamptz and $${String(values.length)}::timestamptz`;
|
|
110
|
+
};
|
|
111
|
+
const listEvents = async (params) => {
|
|
112
|
+
const { limit, offset, order } = page(params.pagination, RUN_SCOPED_LIMIT);
|
|
113
|
+
const values = [params.runId];
|
|
114
|
+
let where = "e.run_id = $1";
|
|
115
|
+
if (params.eventType !== void 0) {
|
|
116
|
+
values.push(params.eventType);
|
|
117
|
+
where += ` and e.type = $${String(values.length)}`;
|
|
118
|
+
}
|
|
119
|
+
if (params.correlationId !== void 0) {
|
|
120
|
+
values.push(params.correlationId);
|
|
121
|
+
where += ` and e.correlation_id = $${String(values.length)}`;
|
|
122
|
+
}
|
|
123
|
+
values.push(limit + 1, offset);
|
|
124
|
+
return paged(await rows(`select ${EVENT_COLUMNS} from workflow.workflow_events e
|
|
125
|
+
join workflow.workflow_runs r on r.id = e.run_id
|
|
126
|
+
where ${where} order by e.id ${order}
|
|
127
|
+
limit $${String(values.length - 1)} offset $${String(values.length)}`, values), limit, offset);
|
|
128
|
+
};
|
|
129
|
+
return {
|
|
130
|
+
runs: {
|
|
131
|
+
get: (runId) => one(`select ${RUN_COLUMNS} from workflow.workflow_runs r where r.id = $1`, [runId], "run", runId),
|
|
132
|
+
async list(params = {}) {
|
|
133
|
+
const { limit, offset, order } = page(params.pagination, LIMIT);
|
|
134
|
+
const values = [];
|
|
135
|
+
let where = "true";
|
|
136
|
+
if (params.workflowName !== void 0) {
|
|
137
|
+
values.push(params.workflowName);
|
|
138
|
+
where += ` and r.name = $${String(values.length)}`;
|
|
139
|
+
}
|
|
140
|
+
if (params.status !== void 0) {
|
|
141
|
+
values.push(params.status);
|
|
142
|
+
where += ` and r.status::text = $${String(values.length)}`;
|
|
143
|
+
}
|
|
144
|
+
if (params.attributes !== void 0) {
|
|
145
|
+
if (Object.keys(params.attributes).length > MAX_ATTRIBUTE_FILTERS) throw new RangeError(`better-supabase: analytics filters by at most ${String(MAX_ATTRIBUTE_FILTERS)} attributes`);
|
|
146
|
+
values.push(JSON.stringify(params.attributes));
|
|
147
|
+
where += ` and r.attributes @> $${String(values.length)}::jsonb`;
|
|
148
|
+
}
|
|
149
|
+
where += window(params, "r.updated_at", values);
|
|
150
|
+
values.push(limit + 1, offset);
|
|
151
|
+
return paged(await rows(`select ${RUN_COLUMNS} from workflow.workflow_runs r where ${where}
|
|
152
|
+
order by r.created_at ${order}, r.id ${order}
|
|
153
|
+
limit $${String(values.length - 1)} offset $${String(values.length)}`, values), limit, offset);
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
attributes: { async list(params = {}) {
|
|
157
|
+
const { limit, offset } = page(params.pagination, LIMIT);
|
|
158
|
+
const values = [];
|
|
159
|
+
let where = "true";
|
|
160
|
+
if (params.workflowName !== void 0) {
|
|
161
|
+
values.push(params.workflowName);
|
|
162
|
+
where += ` and r.name = $${String(values.length)}`;
|
|
163
|
+
}
|
|
164
|
+
where += window(params, "r.updated_at", values);
|
|
165
|
+
values.push(limit + 1, offset);
|
|
166
|
+
return paged(await rows(`select k.key, count(*)::int as "runCount",
|
|
167
|
+
${utc("min(r.created_at)")} as "firstSeenAt",
|
|
168
|
+
${utc("max(r.updated_at)")} as "lastSeenAt"
|
|
169
|
+
from workflow.workflow_runs r
|
|
170
|
+
cross join lateral jsonb_object_keys(coalesce(r.attributes, '{}'::jsonb)) as k(key)
|
|
171
|
+
where ${where}
|
|
172
|
+
group by k.key order by k.key
|
|
173
|
+
limit $${String(values.length - 1)} offset $${String(values.length)}`, values), limit, offset);
|
|
174
|
+
} },
|
|
175
|
+
steps: {
|
|
176
|
+
get: (runId, stepId) => one(`select ${STEP_COLUMNS} from workflow.workflow_steps s where s.run_id = $1 and s.step_id = $2`, [runId, stepId], "step", stepId),
|
|
177
|
+
async list(params) {
|
|
178
|
+
const { limit, offset, order } = page(params.pagination, RUN_SCOPED_LIMIT);
|
|
179
|
+
return paged(await rows(`select ${STEP_COLUMNS} from workflow.workflow_steps s where s.run_id = $1
|
|
180
|
+
order by s.created_at ${order}, s.step_id ${order} limit $2 offset $3`, [
|
|
181
|
+
params.runId,
|
|
182
|
+
limit + 1,
|
|
183
|
+
offset
|
|
184
|
+
]), limit, offset);
|
|
185
|
+
}
|
|
186
|
+
},
|
|
187
|
+
events: {
|
|
188
|
+
get: (runId, eventId) => one(`select ${EVENT_COLUMNS} from workflow.workflow_events e
|
|
189
|
+
join workflow.workflow_runs r on r.id = e.run_id
|
|
190
|
+
where e.run_id = $1 and e.id = $2`, [runId, eventId], "event", eventId),
|
|
191
|
+
getMany(runId, eventIds) {
|
|
192
|
+
if (eventIds.length > LIMIT) throw new RangeError(`better-supabase: analytics looks up at most ${String(LIMIT)} events at once`);
|
|
193
|
+
return rows(`select ${EVENT_COLUMNS} from workflow.workflow_events e
|
|
194
|
+
join workflow.workflow_runs r on r.id = e.run_id
|
|
195
|
+
where e.run_id = $1 and e.id = any($2::text[])`, [runId, [...new Set(eventIds)]]);
|
|
196
|
+
},
|
|
197
|
+
list: listEvents,
|
|
198
|
+
listByCorrelationId(params) {
|
|
199
|
+
return listEvents({
|
|
200
|
+
runId: params.runId,
|
|
201
|
+
correlationId: params.correlationId,
|
|
202
|
+
...params.pagination === void 0 ? {} : { pagination: params.pagination }
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
},
|
|
206
|
+
hooks: {
|
|
207
|
+
get: (hookId, params) => one(`${HOOKS} and e.correlation_id = $1 and ($2::text is null or e.run_id = $2)
|
|
208
|
+
group by e.run_id, e.correlation_id`, [hookId, params?.runId ?? null], "hook", hookId),
|
|
209
|
+
async list(params) {
|
|
210
|
+
const { limit, offset, order } = page(params.pagination, LIMIT);
|
|
211
|
+
return paged(await rows(`${HOOKS} and e.run_id = $1 group by e.run_id, e.correlation_id
|
|
212
|
+
order by "createdAt" ${order}, "hookId" ${order} limit $2 offset $3`, [
|
|
213
|
+
params.runId,
|
|
214
|
+
limit + 1,
|
|
215
|
+
offset
|
|
216
|
+
]), limit, offset);
|
|
217
|
+
}
|
|
218
|
+
},
|
|
219
|
+
waits: {
|
|
220
|
+
get: (runId, waitId) => one(`select ${WAIT_COLUMNS} from workflow.workflow_waits w
|
|
221
|
+
where w.run_id = $1 and w.wait_id in ($2::text, $1::text || '-' || $2::text)`, [runId, waitId], "wait", waitId),
|
|
222
|
+
async list(params) {
|
|
223
|
+
const { limit, offset, order } = page(params.pagination, RUN_SCOPED_LIMIT);
|
|
224
|
+
const values = [params.runId];
|
|
225
|
+
let where = "w.run_id = $1";
|
|
226
|
+
if (params.status !== void 0) {
|
|
227
|
+
values.push(params.status);
|
|
228
|
+
where += ` and w.status::text = $${String(values.length)}`;
|
|
229
|
+
}
|
|
230
|
+
values.push(limit + 1, offset);
|
|
231
|
+
return paged(await rows(`select ${WAIT_COLUMNS} from workflow.workflow_waits w where ${where}
|
|
232
|
+
order by w.created_at ${order}, w.wait_id ${order}
|
|
233
|
+
limit $${String(values.length - 1)} offset $${String(values.length)}`, values), limit, offset);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
//#endregion
|
|
239
|
+
//#region src/workflow-sdk/world/world.ts
|
|
240
|
+
/**
|
|
241
|
+
* The `@workflow/world` protocol this World speaks: the package version its
|
|
242
|
+
* types and queue format come from. Its tables come from
|
|
243
|
+
* `@workflow/world-postgres` at `WORLD_POSTGRES_VERSION`.
|
|
244
|
+
*/
|
|
245
|
+
const WORKFLOW_WORLD_PROTOCOL = "5.0.2";
|
|
246
|
+
/** The deliveries one message may take; matches world-postgres (49 plus 24 retries of the terminal write). */
|
|
247
|
+
const MAX_DELIVERIES = 73;
|
|
248
|
+
const SIGNATURE_TOLERANCE_SECONDS = 300;
|
|
249
|
+
const JOB_HEADER = "x-bs-job";
|
|
250
|
+
const SIGNATURE_HEADER = "x-bs-signature";
|
|
251
|
+
const FLOW_PATH = "/.well-known/workflow/v1/flow";
|
|
252
|
+
const HKDF_SALT = "better-supabase/workflow";
|
|
253
|
+
const encoder = new TextEncoder();
|
|
254
|
+
/** JSON with Uint8Array values as `{ __type: "Uint8Array", data: <base64> }`, as world-postgres sends them. */
|
|
255
|
+
function serialize(value) {
|
|
256
|
+
return Buffer.from(JSON.stringify(value, (_key, inner) => inner instanceof Uint8Array ? {
|
|
257
|
+
__type: "Uint8Array",
|
|
258
|
+
data: Buffer.from(inner).toString("base64")
|
|
259
|
+
} : inner));
|
|
260
|
+
}
|
|
261
|
+
function isStoredMessage(value) {
|
|
262
|
+
if (typeof value !== "object" || value === null) return false;
|
|
263
|
+
const record = { ...value };
|
|
264
|
+
return typeof record["queueName"] === "string" && typeof record["messageId"] === "string" && typeof record["attempt"] === "number" && typeof record["body"] === "string";
|
|
265
|
+
}
|
|
266
|
+
function env(name) {
|
|
267
|
+
const value = process.env[name];
|
|
268
|
+
return value === void 0 || value === "" ? void 0 : value;
|
|
269
|
+
}
|
|
270
|
+
function positiveInt(value) {
|
|
271
|
+
const parsed = Math.trunc(Number(value ?? ""));
|
|
272
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : void 0;
|
|
273
|
+
}
|
|
274
|
+
/** The flow route: `flowUrl`, `WORKFLOW_FLOW_URL`, or the local server. */
|
|
275
|
+
function resolveFlowUrl(flowUrl) {
|
|
276
|
+
const explicit = flowUrl ?? env("WORKFLOW_FLOW_URL");
|
|
277
|
+
if (explicit !== void 0) return explicit;
|
|
278
|
+
const base = env("WORKFLOW_LOCAL_BASE_URL") ?? `http://localhost:${env("PORT") ?? "3000"}`;
|
|
279
|
+
const url = new URL(base);
|
|
280
|
+
url.pathname = `${url.pathname.replace(/\/+$/, "")}${FLOW_PATH}`;
|
|
281
|
+
url.search = "";
|
|
282
|
+
url.hash = "";
|
|
283
|
+
return url.toString();
|
|
284
|
+
}
|
|
285
|
+
/** A 32-byte key from base64 or hex. */
|
|
286
|
+
function parseMasterKey(value) {
|
|
287
|
+
const text = value.trim();
|
|
288
|
+
const bytes = /^[0-9a-f]{64,}$/i.test(text) ? Buffer.from(text, "hex") : Buffer.from(text, "base64");
|
|
289
|
+
if (bytes.byteLength < 32) throw new TypeError("better-supabase: the workflow encryption key must be at least 32 bytes, base64 or hex");
|
|
290
|
+
return new Uint8Array(bytes);
|
|
291
|
+
}
|
|
292
|
+
/** The run's AES-256 key: HKDF-SHA256 of the master key with info `run:<runId>`. */
|
|
293
|
+
async function deriveRunKey(master, runId) {
|
|
294
|
+
const key = await crypto.subtle.importKey("raw", Uint8Array.from(master), "HKDF", false, ["deriveBits"]);
|
|
295
|
+
const bits = await crypto.subtle.deriveBits({
|
|
296
|
+
name: "HKDF",
|
|
297
|
+
hash: "SHA-256",
|
|
298
|
+
salt: encoder.encode(HKDF_SALT),
|
|
299
|
+
info: encoder.encode(`run:${runId}`)
|
|
300
|
+
}, key, 256);
|
|
301
|
+
return new Uint8Array(bits);
|
|
302
|
+
}
|
|
303
|
+
async function hmacHex(secret, message) {
|
|
304
|
+
const key = await crypto.subtle.importKey("raw", encoder.encode(secret), {
|
|
305
|
+
name: "HMAC",
|
|
306
|
+
hash: "SHA-256"
|
|
307
|
+
}, false, ["sign"]);
|
|
308
|
+
const signature = await crypto.subtle.sign("HMAC", key, encoder.encode(message));
|
|
309
|
+
return Buffer.from(signature).toString("hex");
|
|
310
|
+
}
|
|
311
|
+
function constantTimeEqual(a, b) {
|
|
312
|
+
if (a.length !== b.length) return false;
|
|
313
|
+
let diff = 0;
|
|
314
|
+
for (let index = 0; index < a.length; index += 1) diff |= (a.codePointAt(index) ?? 0) ^ (b.codePointAt(index) ?? 0);
|
|
315
|
+
return diff === 0;
|
|
316
|
+
}
|
|
317
|
+
/** `t=<unix>,v1=<hex>` over `<t>.<job>.<body>`. */
|
|
318
|
+
async function signDelivery(secret, job, body, now = Date.now()) {
|
|
319
|
+
const t = String(Math.floor(now / 1e3));
|
|
320
|
+
return `t=${t},v1=${await hmacHex(secret, `${t}.${job}.${body}`)}`;
|
|
321
|
+
}
|
|
322
|
+
/** Whether `header` signs `job` and `body` with `secret` within five minutes of `now`. */
|
|
323
|
+
async function verifyDelivery(secret, header, job, body, now = Date.now()) {
|
|
324
|
+
if (header === null) return false;
|
|
325
|
+
const parts = new Map(header.split(",").map((part) => {
|
|
326
|
+
const index = part.indexOf("=");
|
|
327
|
+
return [part.slice(0, index).trim(), part.slice(index + 1).trim()];
|
|
328
|
+
}));
|
|
329
|
+
const t = parts.get("t");
|
|
330
|
+
const v1 = parts.get("v1");
|
|
331
|
+
if (t === void 0 || v1 === void 0 || !/^\d+$/.test(t)) return false;
|
|
332
|
+
if (Math.abs(now / 1e3 - Number(t)) > SIGNATURE_TOLERANCE_SECONDS) return false;
|
|
333
|
+
return constantTimeEqual(await hmacHex(secret, `${t}.${job}.${body}`), v1);
|
|
334
|
+
}
|
|
335
|
+
/** `load` once; a rejection is not kept, so the next call reads again. */
|
|
336
|
+
function memoized(load) {
|
|
337
|
+
let promise;
|
|
338
|
+
return () => promise ??= load().catch((cause) => {
|
|
339
|
+
promise = void 0;
|
|
340
|
+
throw cause;
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
/** Unsigned poll deliveries are accepted only when `NODE_ENV` is `development` or `test`. */
|
|
344
|
+
function unsignedAllowed() {
|
|
345
|
+
const mode = env("NODE_ENV");
|
|
346
|
+
return mode === "development" || mode === "test";
|
|
347
|
+
}
|
|
348
|
+
function deliveryProblem(kind, detail) {
|
|
349
|
+
return problemResponse(dbError(kind, detail, { code: "WORKFLOW_DELIVERY_REJECTED" }), { expose: true });
|
|
350
|
+
}
|
|
351
|
+
/** Retry delay after a failed delivery, as world-postgres (exp(min(attempt, 10)) seconds). */
|
|
352
|
+
const backoffSeconds = (attempt) => Math.ceil(Math.exp(Math.min(attempt, 10)));
|
|
353
|
+
/**
|
|
354
|
+
* A Workflow SDK World on Supabase Postgres: the run, step, event, hook and
|
|
355
|
+
* stream tables of `@workflow/world-postgres` (installed by the
|
|
356
|
+
* `workflow-sdk-world` SQL module), with messages in the jobs module's
|
|
357
|
+
* queue instead of graphile-worker.
|
|
358
|
+
*
|
|
359
|
+
* ```ts
|
|
360
|
+
* // workflow.config or WORKFLOW_TARGET_WORLD=better-supabase/workflow-sdk/world
|
|
361
|
+
* export default createSupabaseWorld({ delivery: "pg_net" });
|
|
362
|
+
* ```
|
|
363
|
+
*/
|
|
364
|
+
function createSupabaseWorld(options = {}) {
|
|
365
|
+
const delivery = options.delivery ?? "poll";
|
|
366
|
+
const queueName = options.queue ?? "workflow_deliveries";
|
|
367
|
+
const schema = sqlIdent(options.schema ?? "better_supabase");
|
|
368
|
+
const concurrency = Math.max(1, options.concurrency ?? 50);
|
|
369
|
+
const pollInterval = Math.max(10, options.pollInterval ?? 250);
|
|
370
|
+
const lease = Math.max(5, options.lease ?? 60);
|
|
371
|
+
const deliveryTimeout = Math.max(lease, options.deliveryTimeout ?? 300);
|
|
372
|
+
const pool = options.pool ?? new Pool({ connectionString: options.connectionString ?? env("WORKFLOW_POSTGRES_URL") ?? env("SUPABASE_DB_URL") ?? env("DATABASE_URL") });
|
|
373
|
+
const base = createWorld$1({
|
|
374
|
+
pool,
|
|
375
|
+
...options.namespace === void 0 ? {} : { namespace: options.namespace }
|
|
376
|
+
});
|
|
377
|
+
/** The Vault secret, `undefined` when no row has the name; a failed read rejects. */
|
|
378
|
+
const vault = async (name) => {
|
|
379
|
+
return (await pool.query("select decrypted_secret as secret from vault.decrypted_secrets where name = $1", [name])).rows[0]?.secret ?? void 0;
|
|
380
|
+
};
|
|
381
|
+
const deliverySecret = memoized(async () => options.deliverySecret ?? vault(WORKFLOW_VAULT_SECRETS.deliverySecret));
|
|
382
|
+
const masterKey = memoized(async () => {
|
|
383
|
+
const text = options.encryptionKey ?? await vault(WORKFLOW_VAULT_SECRETS.encryptionKey);
|
|
384
|
+
return text === void 0 ? void 0 : parseMasterKey(text);
|
|
385
|
+
});
|
|
386
|
+
const allowUnsigned = unsignedAllowed();
|
|
387
|
+
const call = async (fn, args) => {
|
|
388
|
+
const list = args.map((_, index) => `$${String(index + 1)}`).join(", ");
|
|
389
|
+
return (await pool.query(`select * from ${schema}.${sqlIdent(fn)}(${list})`, [...args])).rows;
|
|
390
|
+
};
|
|
391
|
+
const store = async (message, delaySeconds) => {
|
|
392
|
+
await call("enqueue_job", [
|
|
393
|
+
queueName,
|
|
394
|
+
JSON.stringify(message),
|
|
395
|
+
Math.max(0, Math.ceil(delaySeconds ?? 0)),
|
|
396
|
+
MAX_DELIVERIES,
|
|
397
|
+
message.idempotencyKey ?? message.messageId,
|
|
398
|
+
false
|
|
399
|
+
]);
|
|
400
|
+
};
|
|
401
|
+
const queue = async (name, message, opts) => {
|
|
402
|
+
const messageId = `msg_${crypto.randomUUID()}`;
|
|
403
|
+
await store({
|
|
404
|
+
queueName: name,
|
|
405
|
+
messageId,
|
|
406
|
+
attempt: 1,
|
|
407
|
+
body: serialize(message).toString("base64"),
|
|
408
|
+
...opts?.headers === void 0 ? {} : { headers: opts.headers },
|
|
409
|
+
...opts?.idempotencyKey === void 0 ? {} : { idempotencyKey: opts.idempotencyKey }
|
|
410
|
+
}, opts?.delaySeconds);
|
|
411
|
+
startPolling();
|
|
412
|
+
return { messageId };
|
|
413
|
+
};
|
|
414
|
+
const queueBatch = (name, messages) => Promise.all(messages.map(({ message, opts }) => queue(name, message, opts).then(({ messageId }) => ({ messageId }), (cause) => ({
|
|
415
|
+
messageId: null,
|
|
416
|
+
error: cause instanceof Error ? cause.message : String(cause),
|
|
417
|
+
retryable: true
|
|
418
|
+
}))));
|
|
419
|
+
const complete = (id, attempts) => call("complete_job", [
|
|
420
|
+
queueName,
|
|
421
|
+
id,
|
|
422
|
+
attempts
|
|
423
|
+
]);
|
|
424
|
+
const fail = (id, attempts, error, attempt) => call("fail_job", [
|
|
425
|
+
queueName,
|
|
426
|
+
id,
|
|
427
|
+
attempts,
|
|
428
|
+
error.slice(0, 2e3),
|
|
429
|
+
backoffSeconds(attempt)
|
|
430
|
+
]);
|
|
431
|
+
const heartbeat = (id, attempts) => {
|
|
432
|
+
const timer = setInterval(() => {
|
|
433
|
+
call("extend_job_lease", [
|
|
434
|
+
queueName,
|
|
435
|
+
id,
|
|
436
|
+
attempts,
|
|
437
|
+
lease
|
|
438
|
+
]).catch(() => void 0);
|
|
439
|
+
}, Math.max(1e3, lease * 1e3 / 2));
|
|
440
|
+
return () => {
|
|
441
|
+
clearInterval(timer);
|
|
442
|
+
};
|
|
443
|
+
};
|
|
444
|
+
/** Settles a delivered job from the flow route's response. */
|
|
445
|
+
const settle = async (job, message, attempt, status, text) => {
|
|
446
|
+
if (status < 200 || status >= 300) {
|
|
447
|
+
await fail(job.id, job.attempts, `Flow route answered ${String(status)}: ${text}`, attempt);
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
let timeoutSeconds;
|
|
451
|
+
try {
|
|
452
|
+
const parsed = JSON.parse(text);
|
|
453
|
+
if (typeof parsed === "object" && parsed !== null && "timeoutSeconds" in parsed) {
|
|
454
|
+
const value = Number(parsed.timeoutSeconds);
|
|
455
|
+
if (Number.isFinite(value) && value >= 0) timeoutSeconds = value;
|
|
456
|
+
}
|
|
457
|
+
} catch {
|
|
458
|
+
timeoutSeconds = void 0;
|
|
459
|
+
}
|
|
460
|
+
if (timeoutSeconds !== void 0) await store({
|
|
461
|
+
...message,
|
|
462
|
+
attempt: attempt + 1
|
|
463
|
+
}, timeoutSeconds);
|
|
464
|
+
await complete(job.id, job.attempts);
|
|
465
|
+
};
|
|
466
|
+
const deliveryHeaders = (message, attempt) => {
|
|
467
|
+
const headers = new Headers(message.headers);
|
|
468
|
+
headers.set("content-type", "application/json");
|
|
469
|
+
headers.set("x-vqs-queue-name", message.queueName);
|
|
470
|
+
headers.set("x-vqs-message-id", message.messageId);
|
|
471
|
+
headers.set("x-vqs-message-attempt", String(attempt));
|
|
472
|
+
headers.delete(JOB_HEADER);
|
|
473
|
+
headers.delete(SIGNATURE_HEADER);
|
|
474
|
+
return headers;
|
|
475
|
+
};
|
|
476
|
+
const flowUrl = () => resolveFlowUrl(options.flowUrl);
|
|
477
|
+
const deliver = async (job) => {
|
|
478
|
+
const payload = job.message.payload;
|
|
479
|
+
if (!isStoredMessage(payload)) {
|
|
480
|
+
await fail(job.id, job.attempts, "Not a workflow message", 99);
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
483
|
+
const attempt = payload.attempt + job.attempts - 1;
|
|
484
|
+
const body = Buffer.from(payload.body, "base64");
|
|
485
|
+
const headers = deliveryHeaders(payload, attempt);
|
|
486
|
+
const beat = heartbeat(job.id, job.attempts);
|
|
487
|
+
const controller = new AbortController();
|
|
488
|
+
const timer = setTimeout(() => {
|
|
489
|
+
controller.abort(/* @__PURE__ */ new Error(`The flow route did not answer within ${String(deliveryTimeout)} seconds`));
|
|
490
|
+
}, deliveryTimeout * 1e3);
|
|
491
|
+
const stop = () => {
|
|
492
|
+
clearTimeout(timer);
|
|
493
|
+
beat();
|
|
494
|
+
};
|
|
495
|
+
controller.signal.addEventListener("abort", stop, { once: true });
|
|
496
|
+
try {
|
|
497
|
+
const secret = await deliverySecret();
|
|
498
|
+
if (secret !== void 0) headers.set(SIGNATURE_HEADER, await signDelivery(secret, "", body.toString("utf8")));
|
|
499
|
+
const response = await fetch(flowUrl(), {
|
|
500
|
+
method: "POST",
|
|
501
|
+
headers,
|
|
502
|
+
body,
|
|
503
|
+
signal: controller.signal
|
|
504
|
+
});
|
|
505
|
+
const text = await response.text();
|
|
506
|
+
stop();
|
|
507
|
+
await settle(job, payload, attempt, response.status, text);
|
|
508
|
+
} catch (cause) {
|
|
509
|
+
stop();
|
|
510
|
+
await fail(job.id, job.attempts, cause instanceof Error ? cause.message : String(cause), attempt);
|
|
511
|
+
}
|
|
512
|
+
};
|
|
513
|
+
const claim = (batch) => call("claim_jobs", [
|
|
514
|
+
queueName,
|
|
515
|
+
lease,
|
|
516
|
+
batch
|
|
517
|
+
]).then((rows) => rows.map((row) => ({
|
|
518
|
+
...row,
|
|
519
|
+
id: String(row.id)
|
|
520
|
+
})));
|
|
521
|
+
let running = false;
|
|
522
|
+
let closed = false;
|
|
523
|
+
let loop;
|
|
524
|
+
const inflight = /* @__PURE__ */ new Set();
|
|
525
|
+
let wake;
|
|
526
|
+
const deliverOnce = async () => {
|
|
527
|
+
const jobs = await claim(concurrency);
|
|
528
|
+
await Promise.all(jobs.map((job) => deliver(job)));
|
|
529
|
+
return jobs.length;
|
|
530
|
+
};
|
|
531
|
+
const track = (job) => {
|
|
532
|
+
const task = deliver(job).catch(() => void 0).finally(() => {
|
|
533
|
+
inflight.delete(task);
|
|
534
|
+
wake?.();
|
|
535
|
+
});
|
|
536
|
+
inflight.add(task);
|
|
537
|
+
};
|
|
538
|
+
/** Waits `pollInterval`, or until a delivery finishes and frees a slot. */
|
|
539
|
+
const idle = () => new Promise((resolve) => {
|
|
540
|
+
const timer = setTimeout(done, pollInterval);
|
|
541
|
+
function done() {
|
|
542
|
+
clearTimeout(timer);
|
|
543
|
+
wake = void 0;
|
|
544
|
+
resolve();
|
|
545
|
+
}
|
|
546
|
+
wake = done;
|
|
547
|
+
});
|
|
548
|
+
const claimInto = async (room) => {
|
|
549
|
+
try {
|
|
550
|
+
const jobs = await claim(room);
|
|
551
|
+
jobs.forEach(track);
|
|
552
|
+
return jobs.length;
|
|
553
|
+
} catch {
|
|
554
|
+
return 0;
|
|
555
|
+
}
|
|
556
|
+
};
|
|
557
|
+
const isRunning = () => running;
|
|
558
|
+
const poll = async () => {
|
|
559
|
+
while (isRunning()) {
|
|
560
|
+
const room = concurrency - inflight.size;
|
|
561
|
+
const claimed = room > 0 ? await claimInto(room) : 0;
|
|
562
|
+
if (claimed === 0 || room <= claimed) await idle();
|
|
563
|
+
}
|
|
564
|
+
};
|
|
565
|
+
function startPolling() {
|
|
566
|
+
if (delivery !== "poll" || running || closed) return;
|
|
567
|
+
running = true;
|
|
568
|
+
loop = poll();
|
|
569
|
+
}
|
|
570
|
+
const createQueueHandler = (prefix, handler) => {
|
|
571
|
+
const inner = base.createQueueHandler(prefix, handler);
|
|
572
|
+
return async (req) => {
|
|
573
|
+
const job = req.headers.get(JOB_HEADER);
|
|
574
|
+
let secret;
|
|
575
|
+
try {
|
|
576
|
+
secret = await deliverySecret();
|
|
577
|
+
} catch {
|
|
578
|
+
return deliveryProblem("network", "The workflow delivery secret could not be read from Vault");
|
|
579
|
+
}
|
|
580
|
+
if (job === null) {
|
|
581
|
+
if (secret === void 0 && delivery === "poll") {
|
|
582
|
+
if (allowUnsigned) return inner(req);
|
|
583
|
+
return deliveryProblem("unauthorized", "Unsigned workflow delivery: set WORKFLOW_DELIVERY_SECRET or the Vault secret workflow_delivery_secret");
|
|
584
|
+
}
|
|
585
|
+
const text = await req.text();
|
|
586
|
+
if (secret === void 0 || !await verifyDelivery(secret, req.headers.get(SIGNATURE_HEADER), "", text)) return deliveryProblem("unauthorized", "Unsigned workflow delivery");
|
|
587
|
+
return inner(new Request(req.url, {
|
|
588
|
+
method: "POST",
|
|
589
|
+
headers: req.headers,
|
|
590
|
+
body: text
|
|
591
|
+
}));
|
|
592
|
+
}
|
|
593
|
+
const text = await req.text();
|
|
594
|
+
if (secret === void 0 || !await verifyDelivery(secret, req.headers.get(SIGNATURE_HEADER), job, text)) return deliveryProblem("unauthorized", "Bad workflow delivery signature");
|
|
595
|
+
const [jobQueue, id, readCount] = job.split(":");
|
|
596
|
+
const attempts = Number(readCount);
|
|
597
|
+
let payload;
|
|
598
|
+
try {
|
|
599
|
+
payload = JSON.parse(text);
|
|
600
|
+
} catch {
|
|
601
|
+
payload = void 0;
|
|
602
|
+
}
|
|
603
|
+
if (jobQueue !== queueName || id === void 0 || !/^\d+$/.test(id) || !Number.isInteger(attempts) || !isStoredMessage(payload)) return deliveryProblem("invalid_request", "Malformed workflow delivery");
|
|
604
|
+
const claimed = {
|
|
605
|
+
id,
|
|
606
|
+
attempts
|
|
607
|
+
};
|
|
608
|
+
const attempt = payload.attempt + attempts - 1;
|
|
609
|
+
const stop = heartbeat(id, attempts);
|
|
610
|
+
try {
|
|
611
|
+
const response = await inner(new Request(req.url, {
|
|
612
|
+
method: "POST",
|
|
613
|
+
headers: deliveryHeaders(payload, attempt),
|
|
614
|
+
body: Buffer.from(payload.body, "base64")
|
|
615
|
+
}));
|
|
616
|
+
const answer = await response.text();
|
|
617
|
+
await settle(claimed, payload, attempt, response.status, answer);
|
|
618
|
+
return new Response(answer, {
|
|
619
|
+
status: response.status,
|
|
620
|
+
headers: response.headers
|
|
621
|
+
});
|
|
622
|
+
} catch (cause) {
|
|
623
|
+
await fail(id, attempts, cause instanceof Error ? cause.message : String(cause), attempt).catch(() => void 0);
|
|
624
|
+
throw cause;
|
|
625
|
+
} finally {
|
|
626
|
+
stop();
|
|
627
|
+
}
|
|
628
|
+
};
|
|
629
|
+
};
|
|
630
|
+
async function getEncryptionKeyForRun(run) {
|
|
631
|
+
const master = await masterKey();
|
|
632
|
+
if (master === void 0) return void 0;
|
|
633
|
+
return deriveRunKey(master, typeof run === "string" ? run : run.runId);
|
|
634
|
+
}
|
|
635
|
+
return {
|
|
636
|
+
...base,
|
|
637
|
+
analytics: createAnalytics(pool),
|
|
638
|
+
queue,
|
|
639
|
+
queueBatch,
|
|
640
|
+
createQueueHandler,
|
|
641
|
+
getEncryptionKeyForRun,
|
|
642
|
+
deliverOnce,
|
|
643
|
+
async start() {
|
|
644
|
+
startPolling();
|
|
645
|
+
await reenqueueActiveRuns(base.runs, queue, "better-supabase", options.namespace);
|
|
646
|
+
},
|
|
647
|
+
async close() {
|
|
648
|
+
closed = true;
|
|
649
|
+
running = false;
|
|
650
|
+
wake?.();
|
|
651
|
+
await loop;
|
|
652
|
+
await Promise.all(inflight);
|
|
653
|
+
await base.close?.();
|
|
654
|
+
if (options.pool === void 0) await pool.end();
|
|
655
|
+
}
|
|
656
|
+
};
|
|
657
|
+
}
|
|
658
|
+
/** The options `createWorld()` reads from the environment. */
|
|
659
|
+
function worldOptionsFromEnv(source = process.env) {
|
|
660
|
+
const read = (name) => {
|
|
661
|
+
const value = source[name];
|
|
662
|
+
return value === void 0 || value === "" ? void 0 : value;
|
|
663
|
+
};
|
|
664
|
+
const delivery = read("WORKFLOW_DELIVERY");
|
|
665
|
+
if (delivery !== void 0 && delivery !== "poll" && delivery !== "pg_net") throw new TypeError(`better-supabase: WORKFLOW_DELIVERY must be "poll" or "pg_net", got "${delivery}"`);
|
|
666
|
+
const connectionString = read("WORKFLOW_POSTGRES_URL") ?? read("SUPABASE_DB_URL") ?? read("DATABASE_URL");
|
|
667
|
+
const flowUrl = read("WORKFLOW_FLOW_URL");
|
|
668
|
+
const deliverySecret = read("WORKFLOW_DELIVERY_SECRET");
|
|
669
|
+
const encryptionKey = read("WORKFLOW_ENCRYPTION_KEY");
|
|
670
|
+
const queue = read("WORKFLOW_DELIVERY_QUEUE");
|
|
671
|
+
const namespace = read("WORKFLOW_QUEUE_NAMESPACE");
|
|
672
|
+
const concurrency = positiveInt(read("WORKFLOW_POSTGRES_WORKER_CONCURRENCY"));
|
|
673
|
+
const pollInterval = positiveInt(read("WORKFLOW_POSTGRES_POLL_INTERVAL_MS"));
|
|
674
|
+
return {
|
|
675
|
+
...connectionString === void 0 ? {} : { connectionString },
|
|
676
|
+
...delivery === void 0 ? {} : { delivery },
|
|
677
|
+
...flowUrl === void 0 ? {} : { flowUrl },
|
|
678
|
+
...deliverySecret === void 0 ? {} : { deliverySecret },
|
|
679
|
+
...encryptionKey === void 0 ? {} : { encryptionKey },
|
|
680
|
+
...queue === void 0 ? {} : { queue },
|
|
681
|
+
...namespace === void 0 ? {} : { namespace },
|
|
682
|
+
...concurrency === void 0 ? {} : { concurrency },
|
|
683
|
+
...pollInterval === void 0 ? {} : { pollInterval }
|
|
684
|
+
};
|
|
685
|
+
}
|
|
686
|
+
/**
|
|
687
|
+
* The World from the environment, the factory the Workflow SDK calls for
|
|
688
|
+
* `WORKFLOW_TARGET_WORLD=better-supabase/workflow-sdk/world`: the connection
|
|
689
|
+
* from `WORKFLOW_POSTGRES_URL`, `SUPABASE_DB_URL` or `DATABASE_URL`, and
|
|
690
|
+
* `WORKFLOW_DELIVERY`, `WORKFLOW_FLOW_URL`, `WORKFLOW_DELIVERY_SECRET`,
|
|
691
|
+
* `WORKFLOW_ENCRYPTION_KEY`, `WORKFLOW_DELIVERY_QUEUE`,
|
|
692
|
+
* `WORKFLOW_QUEUE_NAMESPACE`, `WORKFLOW_POSTGRES_WORKER_CONCURRENCY` and
|
|
693
|
+
* `WORKFLOW_POSTGRES_POLL_INTERVAL_MS`.
|
|
694
|
+
*/
|
|
695
|
+
function createWorld() {
|
|
696
|
+
return createSupabaseWorld(worldOptionsFromEnv());
|
|
697
|
+
}
|
|
698
|
+
//#endregion
|
|
699
|
+
//#region src/workflow-sdk/world/index.ts
|
|
700
|
+
var world_default = createWorld;
|
|
701
|
+
//#endregion
|
|
702
|
+
export { WORKFLOW_WORLD_PROTOCOL, WORLD_POSTGRES_VERSION, createSupabaseWorld, createWorld, world_default as default, deriveRunKey, parseMasterKey, resolveFlowUrl, signDelivery, verifyDelivery, worldOptionsFromEnv };
|