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,733 @@
|
|
|
1
|
+
import { s as nowInstant } from "../temporal-BJGitm-h.js";
|
|
2
|
+
import { n as rpcTransport, r as sqlTransport } from "../block-transport-BLr-ZgLc.js";
|
|
3
|
+
import { C as run, O as textOf, _ as randomToken, c as errorText, d as isRecord, h as optionalText, i as blockCall, k as toInstant } from "../block-helpers-DWHxHsEQ.js";
|
|
4
|
+
import { r as writeToStore } from "../tee-CoEppCER.js";
|
|
5
|
+
import { BaseFormatConverter, Message, defaultEmojiResolver, parseMarkdown, stringifyMarkdown } from "chat";
|
|
6
|
+
//#region src/chat-sdk/delivery.ts
|
|
7
|
+
const STATUSES = {
|
|
8
|
+
accepted: "queued",
|
|
9
|
+
queued: "queued",
|
|
10
|
+
sending: "queued",
|
|
11
|
+
scheduled: "queued",
|
|
12
|
+
sent: "sent",
|
|
13
|
+
delivered: "delivered",
|
|
14
|
+
read: "read",
|
|
15
|
+
failed: "failed",
|
|
16
|
+
undelivered: "failed",
|
|
17
|
+
canceled: "failed"
|
|
18
|
+
};
|
|
19
|
+
const statusOf = (value) => typeof value === "string" ? STATUSES[value.toLowerCase()] : void 0;
|
|
20
|
+
function json(body) {
|
|
21
|
+
try {
|
|
22
|
+
return JSON.parse(body);
|
|
23
|
+
} catch {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
const list = (value) => Array.isArray(value) ? value : [];
|
|
28
|
+
/** WhatsApp Cloud API: `entry[].changes[].value.statuses[]`. */
|
|
29
|
+
const whatsappDeliveries = ({ body }) => {
|
|
30
|
+
const payload = json(body);
|
|
31
|
+
if (!isRecord(payload) || payload["object"] !== "whatsapp_business_account") return null;
|
|
32
|
+
const updates = [];
|
|
33
|
+
let other = false;
|
|
34
|
+
for (const entry of list(payload["entry"])) for (const change of list(isRecord(entry) ? entry["changes"] : void 0)) {
|
|
35
|
+
const value = isRecord(change) ? change["value"] : void 0;
|
|
36
|
+
if (!isRecord(value)) continue;
|
|
37
|
+
if (list(value["messages"]).length > 0) other = true;
|
|
38
|
+
for (const item of list(value["statuses"])) {
|
|
39
|
+
if (!isRecord(item)) continue;
|
|
40
|
+
const status = statusOf(item["status"]);
|
|
41
|
+
const id = optionalText(item["id"]);
|
|
42
|
+
if (!status || id === void 0) continue;
|
|
43
|
+
const first = list(item["errors"])[0];
|
|
44
|
+
const error = isRecord(first) ? optionalText(first["title"]) ?? optionalText(first["message"]) : void 0;
|
|
45
|
+
updates.push({
|
|
46
|
+
externalId: id,
|
|
47
|
+
status,
|
|
48
|
+
...error === void 0 ? {} : { error }
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
updates,
|
|
54
|
+
only: updates.length > 0 && !other
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
/** Messenger and Instagram: `entry[].messaging[].delivery.mids`. Read receipts carry no ids and are skipped. */
|
|
58
|
+
const messengerDeliveries = ({ body }) => {
|
|
59
|
+
const payload = json(body);
|
|
60
|
+
if (!isRecord(payload) || payload["object"] !== "page" && payload["object"] !== "instagram") return null;
|
|
61
|
+
const events = list(payload["entry"]).flatMap((entry) => list(isRecord(entry) ? entry["messaging"] : void 0).filter(isRecord));
|
|
62
|
+
const receipts = events.filter((event) => isRecord(event["delivery"]) || isRecord(event["read"]));
|
|
63
|
+
return {
|
|
64
|
+
updates: receipts.flatMap((event) => {
|
|
65
|
+
const delivery = event["delivery"];
|
|
66
|
+
return isRecord(delivery) ? list(delivery["mids"]).flatMap((mid) => typeof mid === "string" ? [{
|
|
67
|
+
externalId: mid,
|
|
68
|
+
status: "delivered"
|
|
69
|
+
}] : []) : [];
|
|
70
|
+
}),
|
|
71
|
+
only: receipts.length > 0 && receipts.length === events.length
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
/** Twilio status callbacks: a form body with `MessageSid` and `MessageStatus` and no `Body`. */
|
|
75
|
+
const twilioDeliveries = ({ body, headers }) => {
|
|
76
|
+
if (!(headers["content-type"] ?? "").includes("application/x-www-form-urlencoded")) return null;
|
|
77
|
+
const form = new URLSearchParams(body);
|
|
78
|
+
const id = form.get("MessageSid") ?? form.get("SmsSid");
|
|
79
|
+
const status = statusOf(form.get("MessageStatus") ?? form.get("SmsStatus"));
|
|
80
|
+
if (id === null || !status || form.has("Body")) return null;
|
|
81
|
+
const error = form.get("ErrorMessage") ?? form.get("ErrorCode");
|
|
82
|
+
return {
|
|
83
|
+
updates: [{
|
|
84
|
+
externalId: id,
|
|
85
|
+
status,
|
|
86
|
+
...error === null ? {} : { error }
|
|
87
|
+
}],
|
|
88
|
+
only: true
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
/** The parsers `inboundHandler` uses by default, keyed by adapter name. */
|
|
92
|
+
const DELIVERY_PARSERS = {
|
|
93
|
+
whatsapp: whatsappDeliveries,
|
|
94
|
+
messenger: messengerDeliveries,
|
|
95
|
+
instagram: messengerDeliveries,
|
|
96
|
+
twilio: twilioDeliveries,
|
|
97
|
+
sms: twilioDeliveries
|
|
98
|
+
};
|
|
99
|
+
//#endregion
|
|
100
|
+
//#region src/chat-sdk/channels.ts
|
|
101
|
+
const APP$1 = { type: "app" };
|
|
102
|
+
const ECHO_TTL_MS = 864e5;
|
|
103
|
+
const echoKey = (adapter, id) => `better-supabase:inbox:echo:${adapter}:${id}`;
|
|
104
|
+
/** A platform adapter built from the token the credential provider holds, so no secret sits in env. */
|
|
105
|
+
async function channelAdapter(options) {
|
|
106
|
+
const token = await options.credentials.getToken(options.ref, { subject: options.subject ?? APP$1 }).orThrow();
|
|
107
|
+
return options.create(token);
|
|
108
|
+
}
|
|
109
|
+
const DROPPED_HEADERS = /* @__PURE__ */ new Set([
|
|
110
|
+
"cookie",
|
|
111
|
+
"authorization",
|
|
112
|
+
"x-forwarded-for"
|
|
113
|
+
]);
|
|
114
|
+
const defaultPassthrough = (request, body) => request.method === "GET" || body.includes("\"type\":\"url_verification\"");
|
|
115
|
+
/**
|
|
116
|
+
* A route handler that verifies a channel webhook, stores the raw event in
|
|
117
|
+
* the inbox's `inbound_events` and answers 200 at once. `inboundHandler`
|
|
118
|
+
* replays it into Chat SDK later, so a slow bot never makes the platform
|
|
119
|
+
* retry.
|
|
120
|
+
*/
|
|
121
|
+
function webhook(options) {
|
|
122
|
+
const passthrough = options.passthrough ?? defaultPassthrough;
|
|
123
|
+
return async (request) => {
|
|
124
|
+
const body = await request.clone().text();
|
|
125
|
+
if (passthrough(request, body)) return options.passthroughHandler ? options.passthroughHandler(request) : new Response("not found", { status: 404 });
|
|
126
|
+
if (options.ref) {
|
|
127
|
+
const provider = options.credentials;
|
|
128
|
+
if (!provider?.verifyInbound) return new Response("the credential provider cannot verify inbound requests", { status: 500 });
|
|
129
|
+
const verified = await provider.verifyInbound(request, options.ref);
|
|
130
|
+
if (!verified.ok || !verified.data) return new Response("unauthorized", { status: 401 });
|
|
131
|
+
} else if (options.verify && !await options.verify(request, body)) return new Response("unauthorized", { status: 401 });
|
|
132
|
+
const headers = {};
|
|
133
|
+
request.headers.forEach((value, key) => {
|
|
134
|
+
if (!DROPPED_HEADERS.has(key)) headers[key] = value;
|
|
135
|
+
});
|
|
136
|
+
const externalId = options.externalId?.(body, request);
|
|
137
|
+
const stored = await options.inbox.inbound.store({
|
|
138
|
+
adapter: options.adapter,
|
|
139
|
+
body,
|
|
140
|
+
headers,
|
|
141
|
+
...externalId === void 0 ? {} : { externalId },
|
|
142
|
+
...options.inboxId === void 0 ? {} : { inboxId: options.inboxId },
|
|
143
|
+
...options.tenant === void 0 ? {} : { tenant: options.tenant }
|
|
144
|
+
});
|
|
145
|
+
if (!stored.ok) return new Response("could not store the event", { status: 503 });
|
|
146
|
+
options.after?.(stored.data);
|
|
147
|
+
return new Response("ok", { status: 200 });
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
/** Replays stored webhook events and mirrors channel messages into the inbox. */
|
|
151
|
+
function inboundHandler(options) {
|
|
152
|
+
const { chat, inbox } = options;
|
|
153
|
+
const parsers = options.parsers ?? DELIVERY_PARSERS;
|
|
154
|
+
const baseUrl = options.baseUrl ?? "https://inbox.local";
|
|
155
|
+
const applyDeliveries = async (adapter, parsed) => {
|
|
156
|
+
for (const update of parsed.updates) await inbox.deliveries.setStatus({
|
|
157
|
+
channel: channelFor(adapter),
|
|
158
|
+
externalId: update.externalId,
|
|
159
|
+
status: update.status,
|
|
160
|
+
...update.error === void 0 ? {} : { error: update.error }
|
|
161
|
+
}).orThrow();
|
|
162
|
+
};
|
|
163
|
+
const process = async (event) => {
|
|
164
|
+
await inbox.inbound.setStatus(event.id, "processing").orThrow();
|
|
165
|
+
try {
|
|
166
|
+
const parsed = parsers[event.adapter]?.(event) ?? null;
|
|
167
|
+
if (parsed) await applyDeliveries(event.adapter, parsed);
|
|
168
|
+
if (parsed?.only) {
|
|
169
|
+
await inbox.inbound.setStatus(event.id, "processed").orThrow();
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
const handle = chat.webhooks[event.adapter];
|
|
173
|
+
if (!handle) {
|
|
174
|
+
await inbox.inbound.setStatus(event.id, "ignored", `no adapter named ${event.adapter}`).orThrow();
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
const tasks = [];
|
|
178
|
+
const response = await handle(new Request(`${baseUrl}/${encodeURIComponent(event.adapter)}`, {
|
|
179
|
+
method: "POST",
|
|
180
|
+
headers: event.headers,
|
|
181
|
+
body: event.body
|
|
182
|
+
}), { waitUntil: (task) => void tasks.push(task) });
|
|
183
|
+
await Promise.all(tasks);
|
|
184
|
+
if (response.status >= 400) throw new Error(`${event.adapter} answered ${String(response.status)}`);
|
|
185
|
+
await inbox.inbound.setStatus(event.id, "processed").orThrow();
|
|
186
|
+
} catch (error) {
|
|
187
|
+
await inbox.inbound.setStatus(event.id, "failed", errorText(error));
|
|
188
|
+
throw error;
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
const files = async (message, adapter, threadId) => {
|
|
192
|
+
const out = [];
|
|
193
|
+
for (const file of message.attachments) if (options.copyFile) {
|
|
194
|
+
const copied = await options.copyFile(file, {
|
|
195
|
+
adapter,
|
|
196
|
+
threadId
|
|
197
|
+
});
|
|
198
|
+
if (copied) out.push(copied);
|
|
199
|
+
} else if (file.url !== void 0) out.push({
|
|
200
|
+
url: file.url,
|
|
201
|
+
...file.name === void 0 ? {} : { name: file.name },
|
|
202
|
+
...file.mimeType === void 0 ? {} : { contentType: file.mimeType },
|
|
203
|
+
...file.size === void 0 ? {} : { size: file.size }
|
|
204
|
+
});
|
|
205
|
+
return out;
|
|
206
|
+
};
|
|
207
|
+
return {
|
|
208
|
+
process,
|
|
209
|
+
drain: async (drainOptions = {}) => {
|
|
210
|
+
const events = await inbox.inbound.pending({
|
|
211
|
+
limit: drainOptions.limit ?? 50,
|
|
212
|
+
...drainOptions.maxAttempts === void 0 ? {} : { maxAttempts: drainOptions.maxAttempts }
|
|
213
|
+
}).orThrow();
|
|
214
|
+
let processed = 0;
|
|
215
|
+
let failed = 0;
|
|
216
|
+
for (const event of events) try {
|
|
217
|
+
await process(event);
|
|
218
|
+
processed += 1;
|
|
219
|
+
} catch {
|
|
220
|
+
failed += 1;
|
|
221
|
+
}
|
|
222
|
+
return {
|
|
223
|
+
processed,
|
|
224
|
+
failed
|
|
225
|
+
};
|
|
226
|
+
},
|
|
227
|
+
mirror: async (thread, message) => {
|
|
228
|
+
const adapter = thread.adapter.name;
|
|
229
|
+
if (message.author.isMe || message.author.isBot === true) return null;
|
|
230
|
+
if (await chat.getState().get(echoKey(adapter, message.id)) !== null) return null;
|
|
231
|
+
const inboxId = options.inboxes[adapter];
|
|
232
|
+
if (inboxId === void 0) throw new Error(`inboundHandler: no inbox for adapter "${adapter}"`);
|
|
233
|
+
const attachments = await files(message, adapter, thread.id);
|
|
234
|
+
return inbox.inbound.record({
|
|
235
|
+
inboxId,
|
|
236
|
+
threadId: thread.id,
|
|
237
|
+
contact: {
|
|
238
|
+
externalId: message.author.userId,
|
|
239
|
+
name: message.author.fullName || message.author.userName,
|
|
240
|
+
...message.author.email === void 0 ? {} : { email: message.author.email }
|
|
241
|
+
},
|
|
242
|
+
message: {
|
|
243
|
+
body: message.text,
|
|
244
|
+
externalId: message.id,
|
|
245
|
+
...attachments.length > 0 ? { attachments } : {}
|
|
246
|
+
}
|
|
247
|
+
}).orThrow();
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
const CHANNELS = { twilio: "sms" };
|
|
252
|
+
const channelFor = (adapter) => CHANNELS[adapter] ?? adapter;
|
|
253
|
+
/** True while WhatsApp's customer service window is open: within 24 hours of the contact's last message. */
|
|
254
|
+
async function whatsappWindowOpen(inbox, conversationId, now = nowInstant()) {
|
|
255
|
+
const last = (await inbox.messages.list(conversationId, { limit: 200 }).orThrow()).findLast((message) => message.direction === "inbound" && message.kind === "message");
|
|
256
|
+
return last !== void 0 && last.createdAt.add({ hours: 24 }).epochMilliseconds > now.epochMilliseconds;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Posts a staff reply the `inbox` module queued on its channel, records
|
|
260
|
+
* the delivery with the platform's message id, and remembers the id so
|
|
261
|
+
* `mirror` skips the platform's echo. A failed post is recorded and thrown,
|
|
262
|
+
* so the job retries.
|
|
263
|
+
*/
|
|
264
|
+
function deliver(options) {
|
|
265
|
+
const { chat, inbox } = options;
|
|
266
|
+
return async (job) => {
|
|
267
|
+
const message = await inbox.messages.get(job.message_id).orThrow();
|
|
268
|
+
if (message?.kind !== "message" || message.deletedAt !== null) return null;
|
|
269
|
+
const conversation = await inbox.conversations.get(message.conversationId).orThrow();
|
|
270
|
+
if (!conversation) return null;
|
|
271
|
+
const name = options.adapterFor?.(conversation) ?? (conversation.inbox?.channel === "sms" ? "twilio" : conversation.inbox?.channel);
|
|
272
|
+
const adapter = name === void 0 ? void 0 : chat.getAdapter(name);
|
|
273
|
+
if (!adapter || name === void 0) throw new Error(`deliver: no adapter for conversation ${conversation.id}`);
|
|
274
|
+
const channel = conversation.inbox?.channel ?? name;
|
|
275
|
+
try {
|
|
276
|
+
const template = await options.template?.({
|
|
277
|
+
conversation,
|
|
278
|
+
message,
|
|
279
|
+
adapter
|
|
280
|
+
});
|
|
281
|
+
const raw = await adapter.postMessage(conversation.threadId, template ?? (message.format === "markdown" ? { markdown: message.body } : message.body));
|
|
282
|
+
await chat.getState().set(echoKey(name, raw.id), true, ECHO_TTL_MS);
|
|
283
|
+
await inbox.deliveries.record({
|
|
284
|
+
messageId: message.id,
|
|
285
|
+
channel,
|
|
286
|
+
externalId: raw.id,
|
|
287
|
+
status: "sent"
|
|
288
|
+
}).orThrow();
|
|
289
|
+
return raw;
|
|
290
|
+
} catch (error) {
|
|
291
|
+
await inbox.deliveries.record({
|
|
292
|
+
messageId: message.id,
|
|
293
|
+
channel,
|
|
294
|
+
status: "failed",
|
|
295
|
+
error: errorText(error)
|
|
296
|
+
});
|
|
297
|
+
throw error;
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
/** The inbox's periodic work: wake snoozed conversations, replay and purge webhook events, sweep state. Run it from a cron job. */
|
|
302
|
+
async function maintain(options) {
|
|
303
|
+
const woken = await options.inbox.wakeSnoozed().orThrow();
|
|
304
|
+
const replayed = options.handler ? await options.handler.drain() : {
|
|
305
|
+
processed: 0,
|
|
306
|
+
failed: 0
|
|
307
|
+
};
|
|
308
|
+
return {
|
|
309
|
+
woken,
|
|
310
|
+
purgedEvents: await options.inbox.inbound.purge({ olderThan: options.keepEvents ?? "7 days" }).orThrow(),
|
|
311
|
+
replayed,
|
|
312
|
+
purgedState: options.state ? await options.state.purge() : 0
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
//#endregion
|
|
316
|
+
//#region src/chat-sdk/inbox-adapter.ts
|
|
317
|
+
const PREFIX = "inbox:";
|
|
318
|
+
var MarkdownConverter = class extends BaseFormatConverter {
|
|
319
|
+
fromAst(ast) {
|
|
320
|
+
return stringifyMarkdown(ast).trimEnd();
|
|
321
|
+
}
|
|
322
|
+
toAst(text) {
|
|
323
|
+
return parseMarkdown(text);
|
|
324
|
+
}
|
|
325
|
+
};
|
|
326
|
+
const converter = new MarkdownConverter();
|
|
327
|
+
/** `inbox:<conversation id>` to the conversation id. */
|
|
328
|
+
function conversationIdOf(threadId) {
|
|
329
|
+
if (!threadId.startsWith(PREFIX) || threadId.length === 6) throw new Error(`"${threadId}" is not an inbox thread id`);
|
|
330
|
+
return threadId.slice(6);
|
|
331
|
+
}
|
|
332
|
+
function bodyOf(message) {
|
|
333
|
+
if (typeof message === "string") return {
|
|
334
|
+
body: message,
|
|
335
|
+
format: "text"
|
|
336
|
+
};
|
|
337
|
+
if ("raw" in message) return {
|
|
338
|
+
body: message.raw,
|
|
339
|
+
format: "text"
|
|
340
|
+
};
|
|
341
|
+
if ("markdown" in message) return {
|
|
342
|
+
body: message.markdown,
|
|
343
|
+
format: "markdown"
|
|
344
|
+
};
|
|
345
|
+
return {
|
|
346
|
+
body: converter.renderPostable(message),
|
|
347
|
+
format: "markdown"
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
const emojiOf = (value) => typeof value === "string" ? value : defaultEmojiResolver.toGChat(value);
|
|
351
|
+
function attachmentsOf(message) {
|
|
352
|
+
return message.attachments.flatMap((file) => {
|
|
353
|
+
const url = file.url;
|
|
354
|
+
if (url === void 0) return [];
|
|
355
|
+
return [{
|
|
356
|
+
type: file.contentType?.startsWith("image/") ? "image" : file.contentType?.startsWith("video/") ? "video" : file.contentType?.startsWith("audio/") ? "audio" : "file",
|
|
357
|
+
url,
|
|
358
|
+
...file.name === void 0 ? {} : { name: file.name },
|
|
359
|
+
...file.contentType === void 0 ? {} : { mimeType: file.contentType },
|
|
360
|
+
...file.size === void 0 ? {} : { size: file.size }
|
|
361
|
+
}];
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
async function* textOnly(source) {
|
|
365
|
+
for await (const chunk of source) if (typeof chunk === "string") yield chunk;
|
|
366
|
+
else if (chunk.type === "markdown_text") yield chunk.text;
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* A Chat SDK adapter for the in-app inbox: the bot reads and writes the
|
|
370
|
+
* `inbox` module's conversations, so one `Chat` instance answers the
|
|
371
|
+
* widget and the other channels. Contact messages reach the bot as jobs
|
|
372
|
+
* on the module's bot queue; pass them to `dispatch`.
|
|
373
|
+
*/
|
|
374
|
+
function inboxAdapter(options) {
|
|
375
|
+
const { inbox } = options;
|
|
376
|
+
const userName = options.userName ?? "bot";
|
|
377
|
+
let chat;
|
|
378
|
+
const parseMessage = (raw) => {
|
|
379
|
+
const isBot = raw.authorType === "bot" || raw.authorType === "system";
|
|
380
|
+
const userId = raw.authorType === "bot" ? userName : raw.authorId ?? raw.authorType;
|
|
381
|
+
const name = optionalText(raw.metadata["author_name"]) ?? (raw.authorType === "contact" ? "visitor" : userId);
|
|
382
|
+
return new Message({
|
|
383
|
+
id: raw.id,
|
|
384
|
+
threadId: `${PREFIX}${raw.conversationId}`,
|
|
385
|
+
text: raw.body,
|
|
386
|
+
formatted: raw.format === "markdown" ? parseMarkdown(raw.body) : {
|
|
387
|
+
type: "root",
|
|
388
|
+
children: [{
|
|
389
|
+
type: "paragraph",
|
|
390
|
+
children: [{
|
|
391
|
+
type: "text",
|
|
392
|
+
value: raw.body
|
|
393
|
+
}]
|
|
394
|
+
}]
|
|
395
|
+
},
|
|
396
|
+
raw,
|
|
397
|
+
author: {
|
|
398
|
+
userId,
|
|
399
|
+
userName: name,
|
|
400
|
+
fullName: name,
|
|
401
|
+
isBot,
|
|
402
|
+
isMe: raw.authorType === "bot",
|
|
403
|
+
...raw.authorType === "system" ? { isSystem: true } : {}
|
|
404
|
+
},
|
|
405
|
+
metadata: {
|
|
406
|
+
dateSent: new Date(raw.createdAt.epochMilliseconds),
|
|
407
|
+
edited: raw.editedAt !== null,
|
|
408
|
+
...raw.editedAt === null ? {} : { editedAt: new Date(raw.editedAt.epochMilliseconds) }
|
|
409
|
+
},
|
|
410
|
+
attachments: attachmentsOf(raw)
|
|
411
|
+
});
|
|
412
|
+
};
|
|
413
|
+
const rawOf = (message) => ({
|
|
414
|
+
id: message.id,
|
|
415
|
+
raw: message,
|
|
416
|
+
threadId: `${PREFIX}${message.conversationId}`
|
|
417
|
+
});
|
|
418
|
+
const post = async (threadId, body, format, metadata) => rawOf(await inbox.messages.send(conversationIdOf(threadId), {
|
|
419
|
+
body,
|
|
420
|
+
format,
|
|
421
|
+
authorType: "bot",
|
|
422
|
+
metadata: {
|
|
423
|
+
author_name: userName,
|
|
424
|
+
...metadata
|
|
425
|
+
}
|
|
426
|
+
}).orThrow());
|
|
427
|
+
const dispatch = async (job) => {
|
|
428
|
+
if (!chat) throw new Error("inboxAdapter: initialize() has not run");
|
|
429
|
+
const message = await inbox.messages.get(job.message_id).orThrow();
|
|
430
|
+
if (message?.conversationId !== job.conversation_id || message.authorType !== "contact" || message.kind !== "message") return;
|
|
431
|
+
await chat.processMessage(adapter, `${PREFIX}${message.conversationId}`, parseMessage(message));
|
|
432
|
+
};
|
|
433
|
+
const adapter = {
|
|
434
|
+
name: "inbox",
|
|
435
|
+
userName,
|
|
436
|
+
botUserId: userName,
|
|
437
|
+
lockScope: "thread",
|
|
438
|
+
initialize: (instance) => {
|
|
439
|
+
chat = instance;
|
|
440
|
+
return Promise.resolve();
|
|
441
|
+
},
|
|
442
|
+
encodeThreadId: (conversationId) => `${PREFIX}${conversationId}`,
|
|
443
|
+
decodeThreadId: conversationIdOf,
|
|
444
|
+
channelIdFromThreadId: () => "inbox",
|
|
445
|
+
isDM: () => true,
|
|
446
|
+
parseMessage,
|
|
447
|
+
renderFormatted: (content) => converter.fromAst(content),
|
|
448
|
+
dispatch,
|
|
449
|
+
handleWebhook: async (request) => {
|
|
450
|
+
if (!options.verify || !await options.verify(request)) return new Response("unauthorized", { status: 401 });
|
|
451
|
+
let job;
|
|
452
|
+
try {
|
|
453
|
+
job = await request.json();
|
|
454
|
+
} catch {
|
|
455
|
+
return new Response("invalid JSON", { status: 400 });
|
|
456
|
+
}
|
|
457
|
+
if (!isRecord(job) || typeof job["conversation_id"] !== "string" || typeof job["message_id"] !== "string") return new Response("expected conversation_id and message_id", { status: 400 });
|
|
458
|
+
await dispatch({
|
|
459
|
+
conversation_id: job["conversation_id"],
|
|
460
|
+
message_id: job["message_id"]
|
|
461
|
+
});
|
|
462
|
+
return new Response("ok", { status: 200 });
|
|
463
|
+
},
|
|
464
|
+
postMessage: (threadId, message) => {
|
|
465
|
+
const { body, format } = bodyOf(message);
|
|
466
|
+
return post(threadId, body, format);
|
|
467
|
+
},
|
|
468
|
+
editMessage: async (_threadId, messageId, message) => rawOf(await inbox.messages.edit(messageId, bodyOf(message).body).orThrow()),
|
|
469
|
+
deleteMessage: async (_threadId, messageId) => {
|
|
470
|
+
await inbox.messages.remove(messageId).orThrow();
|
|
471
|
+
},
|
|
472
|
+
addReaction: async (_threadId, messageId, value) => {
|
|
473
|
+
await inbox.messages.react(messageId, emojiOf(value), {
|
|
474
|
+
present: true,
|
|
475
|
+
actor: userName
|
|
476
|
+
}).orThrow();
|
|
477
|
+
},
|
|
478
|
+
removeReaction: async (_threadId, messageId, value) => {
|
|
479
|
+
await inbox.messages.react(messageId, emojiOf(value), {
|
|
480
|
+
present: false,
|
|
481
|
+
actor: userName
|
|
482
|
+
}).orThrow();
|
|
483
|
+
},
|
|
484
|
+
startTyping: async (threadId) => {
|
|
485
|
+
await inbox.conversations.typing(conversationIdOf(threadId), true, userName).orThrow();
|
|
486
|
+
},
|
|
487
|
+
endTyping: async (threadId) => {
|
|
488
|
+
await inbox.conversations.typing(conversationIdOf(threadId), false, userName).orThrow();
|
|
489
|
+
},
|
|
490
|
+
markAsRead: async (threadId) => {
|
|
491
|
+
await inbox.conversations.markRead(conversationIdOf(threadId)).orThrow();
|
|
492
|
+
},
|
|
493
|
+
fetchMessage: async (threadId, messageId) => {
|
|
494
|
+
const message = await inbox.messages.get(messageId).orThrow();
|
|
495
|
+
return message && message.conversationId === conversationIdOf(threadId) ? parseMessage(message) : null;
|
|
496
|
+
},
|
|
497
|
+
fetchMessages: async (threadId, fetchOptions = {}) => {
|
|
498
|
+
const limit = fetchOptions.limit ?? 50;
|
|
499
|
+
const before = fetchOptions.cursor === void 0 ? void 0 : toInstant(fetchOptions.cursor);
|
|
500
|
+
const page = await inbox.messages.list(conversationIdOf(threadId), {
|
|
501
|
+
limit,
|
|
502
|
+
...before === void 0 ? {} : { cursor: before }
|
|
503
|
+
}).orThrow();
|
|
504
|
+
const visible = page.filter((message) => message.kind === "message");
|
|
505
|
+
const oldest = page[0];
|
|
506
|
+
return {
|
|
507
|
+
messages: visible.map(parseMessage),
|
|
508
|
+
...oldest !== void 0 && page.length >= limit ? { nextCursor: oldest.createdAt.toString() } : {}
|
|
509
|
+
};
|
|
510
|
+
},
|
|
511
|
+
fetchThread: async (threadId) => {
|
|
512
|
+
const conversation = await inbox.conversations.get(conversationIdOf(threadId)).orThrow();
|
|
513
|
+
return {
|
|
514
|
+
id: threadId,
|
|
515
|
+
channelId: "inbox",
|
|
516
|
+
isDM: true,
|
|
517
|
+
metadata: conversation ? {
|
|
518
|
+
inboxId: conversation.inboxId,
|
|
519
|
+
contactId: conversation.contactId,
|
|
520
|
+
status: conversation.status,
|
|
521
|
+
botMode: conversation.botMode,
|
|
522
|
+
subject: conversation.subject
|
|
523
|
+
} : {}
|
|
524
|
+
};
|
|
525
|
+
},
|
|
526
|
+
stream: async (threadId, source, streamOptions) => {
|
|
527
|
+
const conversationId = conversationIdOf(threadId);
|
|
528
|
+
await inbox.conversations.typing(conversationId, true, userName);
|
|
529
|
+
let text = "";
|
|
530
|
+
const chunks = textOnly(source);
|
|
531
|
+
const store = options.streams;
|
|
532
|
+
const streamId = store ? `${PREFIX}${conversationId}:${randomToken(9)}` : void 0;
|
|
533
|
+
const readable = new ReadableStream({ async start(controller) {
|
|
534
|
+
for await (const chunk of chunks) {
|
|
535
|
+
if (streamOptions?.signal?.aborted) break;
|
|
536
|
+
text += chunk;
|
|
537
|
+
controller.enqueue(chunk);
|
|
538
|
+
}
|
|
539
|
+
controller.close();
|
|
540
|
+
} });
|
|
541
|
+
if (store && streamId) await writeToStore(store, streamId, readable);
|
|
542
|
+
else {
|
|
543
|
+
const reader = readable.getReader();
|
|
544
|
+
while (!(await reader.read()).done);
|
|
545
|
+
}
|
|
546
|
+
await inbox.conversations.typing(conversationId, false, userName);
|
|
547
|
+
if (text.trim().length === 0) return null;
|
|
548
|
+
return post(threadId, text, "markdown", streamId === void 0 ? void 0 : { stream_id: streamId });
|
|
549
|
+
}
|
|
550
|
+
};
|
|
551
|
+
return adapter;
|
|
552
|
+
}
|
|
553
|
+
//#endregion
|
|
554
|
+
//#region src/chat-sdk/installations.ts
|
|
555
|
+
function refOf(value) {
|
|
556
|
+
return isRecord(value) && typeof value["provider"] === "string" ? {
|
|
557
|
+
...value,
|
|
558
|
+
provider: value["provider"]
|
|
559
|
+
} : null;
|
|
560
|
+
}
|
|
561
|
+
function installationOf(value) {
|
|
562
|
+
if (!isRecord(value)) return null;
|
|
563
|
+
const metadata = value["metadata"];
|
|
564
|
+
const uninstalled = optionalText(value["uninstalled_at"]);
|
|
565
|
+
return {
|
|
566
|
+
id: textOf(value["id"]),
|
|
567
|
+
tenant: optionalText(value["tenant_id"]) ?? null,
|
|
568
|
+
adapter: textOf(value["adapter"]),
|
|
569
|
+
externalId: textOf(value["external_id"]),
|
|
570
|
+
credentialRef: refOf(value["credential_ref"]),
|
|
571
|
+
installedBy: optionalText(value["installed_by"]) ?? null,
|
|
572
|
+
metadata: isRecord(metadata) ? metadata : {},
|
|
573
|
+
installedAt: toInstant(textOf(value["installed_at"])),
|
|
574
|
+
uninstalledAt: uninstalled === void 0 ? null : toInstant(uninstalled)
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
const APP = { type: "app" };
|
|
578
|
+
const sameRef = (a, b) => JSON.stringify(a) === JSON.stringify(b);
|
|
579
|
+
/**
|
|
580
|
+
* The `chat_installations` registry with the credential lifecycle: every
|
|
581
|
+
* ref an install drops is revoked through the `CredentialProvider`.
|
|
582
|
+
*/
|
|
583
|
+
function createChatInstallations(options) {
|
|
584
|
+
const call = blockCall(options.transport, options.schema ?? "better_supabase", options.mappers);
|
|
585
|
+
const revoke = async (ref) => {
|
|
586
|
+
if (ref) await options.credentials.revoke(ref, { subject: APP }).orThrow();
|
|
587
|
+
};
|
|
588
|
+
const list = (filter = {}) => call("list_chat_installations", {
|
|
589
|
+
tenant: filter.tenant,
|
|
590
|
+
adapter: filter.adapter,
|
|
591
|
+
include_uninstalled: filter.includeUninstalled
|
|
592
|
+
}, (value) => Array.isArray(value) ? value.flatMap((row) => {
|
|
593
|
+
const parsed = installationOf(row);
|
|
594
|
+
return parsed ? [parsed] : [];
|
|
595
|
+
}) : []);
|
|
596
|
+
const uninstall = (adapter, externalId) => call("chat_uninstall", {
|
|
597
|
+
adapter,
|
|
598
|
+
external_id: externalId
|
|
599
|
+
}, async (value) => {
|
|
600
|
+
if (!isRecord(value)) return false;
|
|
601
|
+
await revoke(refOf(value["previous_credential_ref"]));
|
|
602
|
+
return true;
|
|
603
|
+
});
|
|
604
|
+
return {
|
|
605
|
+
install: (input) => call("chat_install", {
|
|
606
|
+
adapter: input.adapter,
|
|
607
|
+
external_id: input.externalId,
|
|
608
|
+
tenant: input.tenant,
|
|
609
|
+
credential_ref: input.credentialRef,
|
|
610
|
+
installed_by: input.installedBy,
|
|
611
|
+
metadata: input.metadata
|
|
612
|
+
}, async (value) => {
|
|
613
|
+
const row = installationOf(value);
|
|
614
|
+
if (!row) throw new Error("chat_install returned no row");
|
|
615
|
+
const previous = isRecord(value) ? refOf(value["previous_credential_ref"]) : null;
|
|
616
|
+
if (!sameRef(previous, row.credentialRef)) await revoke(previous);
|
|
617
|
+
return row;
|
|
618
|
+
}),
|
|
619
|
+
uninstall,
|
|
620
|
+
uninstallTenant: (tenant) => run(async () => {
|
|
621
|
+
const rows = await list({ tenant }).orThrow();
|
|
622
|
+
let count = 0;
|
|
623
|
+
for (const row of rows) if (await uninstall(row.adapter, row.externalId).orThrow()) count += 1;
|
|
624
|
+
return count;
|
|
625
|
+
}),
|
|
626
|
+
get: (adapter, externalId) => call("chat_installation", {
|
|
627
|
+
adapter,
|
|
628
|
+
external_id: externalId
|
|
629
|
+
}, installationOf),
|
|
630
|
+
list
|
|
631
|
+
};
|
|
632
|
+
}
|
|
633
|
+
//#endregion
|
|
634
|
+
//#region src/chat-sdk/state.ts
|
|
635
|
+
const wrap = (value) => ({ v: value === void 0 ? null : value });
|
|
636
|
+
const unwrap = (stored) => isRecord(stored) && "v" in stored ? stored["v"] : stored;
|
|
637
|
+
function lockOf(value) {
|
|
638
|
+
if (!isRecord(value)) return null;
|
|
639
|
+
const expires = value["expires_at"];
|
|
640
|
+
return {
|
|
641
|
+
threadId: String(value["thread_id"]),
|
|
642
|
+
token: String(value["token"]),
|
|
643
|
+
expiresAt: typeof expires === "string" || expires instanceof Date ? new Date(expires).getTime() : Date.now()
|
|
644
|
+
};
|
|
645
|
+
}
|
|
646
|
+
const isSerializedMessage = (value) => isRecord(value) && value["_type"] === "chat:Message";
|
|
647
|
+
function queueEntryOf(value) {
|
|
648
|
+
if (!isRecord(value)) return null;
|
|
649
|
+
const message = value["message"];
|
|
650
|
+
if (!isSerializedMessage(message)) return null;
|
|
651
|
+
return {
|
|
652
|
+
enqueuedAt: Number(value["enqueuedAt"]),
|
|
653
|
+
expiresAt: Number(value["expiresAt"]),
|
|
654
|
+
message: Message.fromJSON(message)
|
|
655
|
+
};
|
|
656
|
+
}
|
|
657
|
+
const ms = (value) => value === void 0 || value <= 0 ? void 0 : Math.ceil(value);
|
|
658
|
+
/**
|
|
659
|
+
* A Chat SDK `StateAdapter` on the `chat-sdk-state` SQL module: thread
|
|
660
|
+
* subscriptions, locks, the cache, lists and the per-thread queue in
|
|
661
|
+
* Postgres, so a bot needs no Redis. Service role only.
|
|
662
|
+
*/
|
|
663
|
+
function createSupabaseState(options) {
|
|
664
|
+
const prefix = options.keyPrefix ?? "chat-sdk";
|
|
665
|
+
const call = blockCall(options.transport, options.schema ?? "better_supabase", options.mappers);
|
|
666
|
+
const run = (fn, args, then) => call(fn, {
|
|
667
|
+
prefix,
|
|
668
|
+
...args
|
|
669
|
+
}, then).orThrow();
|
|
670
|
+
return {
|
|
671
|
+
keyPrefix: prefix,
|
|
672
|
+
connect: () => Promise.resolve(),
|
|
673
|
+
disconnect: () => Promise.resolve(),
|
|
674
|
+
subscribe: (threadId) => run("chat_state_subscribe", { thread_id: threadId }, () => void 0),
|
|
675
|
+
unsubscribe: (threadId) => run("chat_state_unsubscribe", { thread_id: threadId }, () => void 0),
|
|
676
|
+
isSubscribed: (threadId) => run("chat_state_is_subscribed", { thread_id: threadId }, (value) => value === true),
|
|
677
|
+
acquireLock: (threadId, ttlMs) => run("chat_state_acquire_lock", {
|
|
678
|
+
thread_id: threadId,
|
|
679
|
+
token: randomToken(),
|
|
680
|
+
ttl_ms: Math.max(1, Math.ceil(ttlMs))
|
|
681
|
+
}, lockOf),
|
|
682
|
+
extendLock: (lock, ttlMs) => run("chat_state_extend_lock", {
|
|
683
|
+
thread_id: lock.threadId,
|
|
684
|
+
token: lock.token,
|
|
685
|
+
ttl_ms: Math.max(1, Math.ceil(ttlMs))
|
|
686
|
+
}, (value) => value === true),
|
|
687
|
+
releaseLock: (lock) => run("chat_state_release_lock", {
|
|
688
|
+
thread_id: lock.threadId,
|
|
689
|
+
token: lock.token
|
|
690
|
+
}, () => void 0),
|
|
691
|
+
forceReleaseLock: (threadId) => run("chat_state_force_release_lock", { thread_id: threadId }, () => void 0),
|
|
692
|
+
get: (key) => run("chat_state_get", { key }, (value) => {
|
|
693
|
+
if (!isRecord(value)) return null;
|
|
694
|
+
return unwrap(value["value"]);
|
|
695
|
+
}),
|
|
696
|
+
set: (key, value, ttlMs) => run("chat_state_set", {
|
|
697
|
+
key,
|
|
698
|
+
value: wrap(value),
|
|
699
|
+
ttl_ms: ms(ttlMs)
|
|
700
|
+
}, () => void 0),
|
|
701
|
+
setIfNotExists: (key, value, ttlMs) => run("chat_state_set_if_not_exists", {
|
|
702
|
+
key,
|
|
703
|
+
value: wrap(value),
|
|
704
|
+
ttl_ms: ms(ttlMs)
|
|
705
|
+
}, (result) => result === true),
|
|
706
|
+
delete: (key) => run("chat_state_delete", { key }, () => void 0),
|
|
707
|
+
appendToList: (key, value, listOptions = {}) => run("chat_state_append_to_list", {
|
|
708
|
+
key,
|
|
709
|
+
value: wrap(value),
|
|
710
|
+
max_length: ms(listOptions.maxLength),
|
|
711
|
+
ttl_ms: ms(listOptions.ttlMs)
|
|
712
|
+
}, () => void 0),
|
|
713
|
+
getList: (key) => run("chat_state_get_list", { key }, (value) => {
|
|
714
|
+
if (!Array.isArray(value)) return [];
|
|
715
|
+
return value.map(unwrap);
|
|
716
|
+
}),
|
|
717
|
+
enqueue: (threadId, entry, maxSize) => run("chat_state_enqueue", {
|
|
718
|
+
thread_id: threadId,
|
|
719
|
+
entry: {
|
|
720
|
+
enqueuedAt: entry.enqueuedAt,
|
|
721
|
+
expiresAt: entry.expiresAt,
|
|
722
|
+
message: entry.message.toJSON()
|
|
723
|
+
},
|
|
724
|
+
expires_at: new Date(entry.expiresAt).toISOString(),
|
|
725
|
+
max_size: ms(maxSize)
|
|
726
|
+
}, Number),
|
|
727
|
+
dequeue: (threadId) => run("chat_state_dequeue", { thread_id: threadId }, queueEntryOf),
|
|
728
|
+
queueDepth: (threadId) => run("chat_state_queue_depth", { thread_id: threadId }, Number),
|
|
729
|
+
purge: (purgeOptions = {}) => call("purge_chat_state", { batch: purgeOptions.batch }, Number).orThrow()
|
|
730
|
+
};
|
|
731
|
+
}
|
|
732
|
+
//#endregion
|
|
733
|
+
export { DELIVERY_PARSERS, channelAdapter, conversationIdOf, createChatInstallations, createSupabaseState, deliver, inboundHandler, inboxAdapter, maintain, messengerDeliveries, rpcTransport, sqlTransport, twilioDeliveries, webhook, whatsappDeliveries, whatsappWindowOpen };
|