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,265 @@
|
|
|
1
|
+
/// <reference lib="esnext.temporal" />
|
|
2
|
+
import { t as AsyncResult, w as ErrorMapper } from "../../result-D7y2fT87.js";
|
|
3
|
+
import { t as SqlClient } from "../../executor-DbvExCFC.js";
|
|
4
|
+
import { i as sqlTransport, r as rpcTransport, t as BlockTransport } from "../../block-transport-DvaoPuZ9.js";
|
|
5
|
+
import { E as BlockEventType, a as EventHub, x as BillingEventData } from "../../events-DWDhx77e.js";
|
|
6
|
+
import { i as CursorPageOptions, r as BlockTemporalOptions } from "../../block-helpers-CKtbFcRv.js";
|
|
7
|
+
import { n as StripeSource, r as StripeTaxId, t as StripeClient } from "../../stripe-D04h-QBT.js";
|
|
8
|
+
import { r as EventSink } from "../../cloud-event-C1JCc1bH.js";
|
|
9
|
+
import { h as stripeInboxVerify, p as signStripeWebhook, v as verifyStripeWebhook } from "../../verify-DPuWngD4.js";
|
|
10
|
+
//#region src/blocks/billing/billing.d.ts
|
|
11
|
+
interface BillingOptions extends BlockTemporalOptions {
|
|
12
|
+
readonly stripe: StripeSource;
|
|
13
|
+
/** A service-role transport: linking customers and reading seats are granted to `service_role` only. */
|
|
14
|
+
readonly transport: BlockTransport;
|
|
15
|
+
/** The module schema (`sql.modules.billing.schema`), default `better_supabase`. */
|
|
16
|
+
readonly schema?: string;
|
|
17
|
+
readonly mappers?: readonly ErrorMapper[];
|
|
18
|
+
/** `betterSupabase.events`, for `billing.*` block events. */
|
|
19
|
+
readonly events?: EventHub;
|
|
20
|
+
/** The per-seat price `syncSeats` updates; default the subscription's first item. */
|
|
21
|
+
readonly seatPrice?: string;
|
|
22
|
+
/** Stripe `proration_behavior` for seat changes, default `create_prorations`. */
|
|
23
|
+
readonly prorationBehavior?: "create_prorations" | "none" | "always_invoice";
|
|
24
|
+
/**
|
|
25
|
+
* Invalidates the cached sessions of a customer's members after a plan
|
|
26
|
+
* change (`entitlementMembers`), so their next request reads the new
|
|
27
|
+
* entitlements. Needs the `entitlements` module.
|
|
28
|
+
*/
|
|
29
|
+
readonly sessions?: {
|
|
30
|
+
readonly sql: SqlClient;
|
|
31
|
+
readonly invalidate: (userId: string) => void;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
interface CustomerDetails {
|
|
35
|
+
readonly email?: string;
|
|
36
|
+
readonly name?: string;
|
|
37
|
+
}
|
|
38
|
+
interface CheckoutOptions extends CustomerDetails {
|
|
39
|
+
/** A Stripe price id. Pass this or `plan`. */
|
|
40
|
+
readonly price?: string;
|
|
41
|
+
/**
|
|
42
|
+
* A plan key from `sql.modules.billing.options.plans`, resolved to its
|
|
43
|
+
* Stripe price in the app's plan catalog (with `interval` when plans have
|
|
44
|
+
* monthly and yearly prices).
|
|
45
|
+
*/
|
|
46
|
+
readonly plan?: string;
|
|
47
|
+
readonly interval?: string;
|
|
48
|
+
/** One of the plan's prices, from the catalog's `variant` column. */
|
|
49
|
+
readonly variant?: string;
|
|
50
|
+
/**
|
|
51
|
+
* More line items, such as add-on packages next to the plan: each a
|
|
52
|
+
* price, or a plan key with `interval` and `variant`. Quantity defaults to 1.
|
|
53
|
+
*/
|
|
54
|
+
readonly items?: readonly CheckoutItem[];
|
|
55
|
+
readonly successUrl: string;
|
|
56
|
+
readonly cancelUrl?: string;
|
|
57
|
+
/** A number, or `seats` for the tenant's seat count. Default 1. */
|
|
58
|
+
readonly quantity?: number | "seats";
|
|
59
|
+
/** Default `subscription`. */
|
|
60
|
+
readonly mode?: "subscription" | "payment";
|
|
61
|
+
/**
|
|
62
|
+
* More Checkout Session parameters, merged deeply over the block's (nested
|
|
63
|
+
* objects such as `metadata` merge, arrays replace). The customer,
|
|
64
|
+
* `client_reference_id` and the tenant's `metadata.organization_id` always
|
|
65
|
+
* stay.
|
|
66
|
+
*/
|
|
67
|
+
readonly params?: Readonly<Record<string, unknown>>;
|
|
68
|
+
readonly idempotencyKey?: string;
|
|
69
|
+
}
|
|
70
|
+
/** An extra Checkout line item. */
|
|
71
|
+
interface CheckoutItem {
|
|
72
|
+
readonly price?: string;
|
|
73
|
+
readonly plan?: string;
|
|
74
|
+
readonly interval?: string;
|
|
75
|
+
readonly variant?: string;
|
|
76
|
+
readonly quantity?: number;
|
|
77
|
+
}
|
|
78
|
+
interface SubscriptionItem {
|
|
79
|
+
readonly subscriptionId: string;
|
|
80
|
+
readonly itemId: string;
|
|
81
|
+
readonly price: string | undefined;
|
|
82
|
+
readonly quantity: number;
|
|
83
|
+
readonly status: string;
|
|
84
|
+
}
|
|
85
|
+
interface BillingStatus {
|
|
86
|
+
readonly customerId: string | undefined;
|
|
87
|
+
readonly seats: number;
|
|
88
|
+
readonly subscription: SubscriptionItem | undefined;
|
|
89
|
+
}
|
|
90
|
+
interface SeatSync {
|
|
91
|
+
readonly quantity: number;
|
|
92
|
+
readonly previousQuantity: number | undefined;
|
|
93
|
+
/** False when there is no subscription item or the quantity already matches. */
|
|
94
|
+
readonly changed: boolean;
|
|
95
|
+
}
|
|
96
|
+
/** The parts of a Stripe event the block reads. */
|
|
97
|
+
interface StripeEvent {
|
|
98
|
+
readonly id: string;
|
|
99
|
+
readonly type: string;
|
|
100
|
+
readonly data: {
|
|
101
|
+
readonly object: unknown;
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
interface StripeEventOutcome {
|
|
105
|
+
/** The `billing.*` block event it emitted, if any. */
|
|
106
|
+
readonly event: BlockEventType | undefined;
|
|
107
|
+
readonly organizationId: string | undefined;
|
|
108
|
+
readonly customerId: string | undefined;
|
|
109
|
+
/** Members whose sessions were invalidated. */
|
|
110
|
+
readonly invalidated: readonly string[];
|
|
111
|
+
}
|
|
112
|
+
/** A plan change: a price id, or a plan key from the catalog. */
|
|
113
|
+
interface PlanChange {
|
|
114
|
+
readonly price?: string;
|
|
115
|
+
readonly plan?: string;
|
|
116
|
+
readonly interval?: string;
|
|
117
|
+
readonly variant?: string;
|
|
118
|
+
/** Stripe `proration_behavior`, default `create_prorations`. */
|
|
119
|
+
readonly prorationBehavior?: "create_prorations" | "none" | "always_invoice";
|
|
120
|
+
/** Also clears a scheduled cancellation. Default true. */
|
|
121
|
+
readonly resume?: boolean;
|
|
122
|
+
readonly idempotencyKey?: string;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* A row of the Stripe Sync Engine's `stripe` schema as stored, such as an
|
|
126
|
+
* invoice (`id`, `status`, `total`, `currency`, `hosted_invoice_url`) or a
|
|
127
|
+
* payment method (`id`, `type`, `card`).
|
|
128
|
+
*/
|
|
129
|
+
type StripeRow = Readonly<Record<string, unknown>>;
|
|
130
|
+
/** A Sync Engine row with the tenant and customer it belongs to, from a platform read. */
|
|
131
|
+
interface TenantStripeRow {
|
|
132
|
+
readonly organizationId: string;
|
|
133
|
+
readonly customerId: string;
|
|
134
|
+
readonly row: StripeRow;
|
|
135
|
+
}
|
|
136
|
+
/** A linked Stripe customer, from `billing_all_customers`. */
|
|
137
|
+
interface BillingCustomer {
|
|
138
|
+
readonly organizationId: string;
|
|
139
|
+
readonly customerId: string;
|
|
140
|
+
/** From the Sync Engine's `stripe.customers`; `undefined` before it syncs. */
|
|
141
|
+
readonly email: string | undefined;
|
|
142
|
+
readonly name: string | undefined;
|
|
143
|
+
readonly created: Temporal.Instant | undefined;
|
|
144
|
+
}
|
|
145
|
+
interface PlatformListOptions extends CursorPageOptions<number> {
|
|
146
|
+
/** Only rows with this Stripe status, such as `active` or `open`. */
|
|
147
|
+
readonly status?: string;
|
|
148
|
+
/** Defaults to 100, at most 500. */
|
|
149
|
+
readonly limit?: number;
|
|
150
|
+
/** Only rows Stripe created before this (epoch seconds), for the next page. */
|
|
151
|
+
readonly cursor?: number;
|
|
152
|
+
}
|
|
153
|
+
interface BillingCustomerUpdate {
|
|
154
|
+
readonly email?: string;
|
|
155
|
+
readonly name?: string;
|
|
156
|
+
readonly phone?: string;
|
|
157
|
+
readonly address?: Readonly<Record<string, string>>;
|
|
158
|
+
/** Stripe customer parameters merged over these, such as `invoice_settings`. */
|
|
159
|
+
readonly params?: Readonly<Record<string, unknown>>;
|
|
160
|
+
}
|
|
161
|
+
interface Billing {
|
|
162
|
+
/** The tenant's Stripe customer, or `undefined` before the first checkout. */
|
|
163
|
+
customer(organizationId: string): AsyncResult<string | undefined>;
|
|
164
|
+
/** The tenant's customer, created in Stripe (with the tenant in `metadata`) when there is none. */
|
|
165
|
+
ensureCustomer(organizationId: string, details?: CustomerDetails): AsyncResult<string>;
|
|
166
|
+
checkout(organizationId: string, options: CheckoutOptions): AsyncResult<{
|
|
167
|
+
readonly id: string;
|
|
168
|
+
readonly url: string | undefined;
|
|
169
|
+
}>;
|
|
170
|
+
/** A customer portal session; `not_found` before the tenant has a customer. */
|
|
171
|
+
portal(organizationId: string, options: {
|
|
172
|
+
readonly returnUrl: string;
|
|
173
|
+
}): AsyncResult<{
|
|
174
|
+
readonly url: string;
|
|
175
|
+
}>;
|
|
176
|
+
status(organizationId: string): AsyncResult<BillingStatus>;
|
|
177
|
+
/**
|
|
178
|
+
* The tenant's newest subscription as the Sync Engine stores it (every
|
|
179
|
+
* column, with `items`), preferring an active one; `undefined` without
|
|
180
|
+
* one. For `billing.read` in the tenant, or platform staff.
|
|
181
|
+
*/
|
|
182
|
+
subscription(organizationId: string): AsyncResult<StripeRow | undefined>;
|
|
183
|
+
/**
|
|
184
|
+
* Every tenant's newest subscription, newest first, for platform staff
|
|
185
|
+
* (`billing.read` in the platform scope) or a service transport.
|
|
186
|
+
*/
|
|
187
|
+
allSubscriptions(options?: PlatformListOptions): AsyncResult<readonly TenantStripeRow[]>;
|
|
188
|
+
/**
|
|
189
|
+
* Every linked customer, with or without a subscription, by tenant, for
|
|
190
|
+
* platform staff (`billing.read` in the platform scope) or a service
|
|
191
|
+
* transport.
|
|
192
|
+
*/
|
|
193
|
+
allCustomers(): AsyncResult<readonly BillingCustomer[]>;
|
|
194
|
+
/**
|
|
195
|
+
* Cancels the tenant's active subscription in Stripe now; `undefined`
|
|
196
|
+
* when it has none. The `customer.subscription.deleted` webhook then
|
|
197
|
+
* emits `billing.subscription_deleted`.
|
|
198
|
+
*/
|
|
199
|
+
cancelSubscription(organizationId: string): AsyncResult<string | undefined>;
|
|
200
|
+
/** Sets the seat item's quantity to the tenant's seat count. */
|
|
201
|
+
syncSeats(organizationId: string, options?: {
|
|
202
|
+
readonly key?: string;
|
|
203
|
+
}): AsyncResult<SeatSync>;
|
|
204
|
+
/**
|
|
205
|
+
* An outbox sink that syncs seats after `organization.member_*` and
|
|
206
|
+
* `organization.role_changed` events: `outbox.relay('billing-seats', billing.seatSink())`.
|
|
207
|
+
*/
|
|
208
|
+
seatSink(): EventSink;
|
|
209
|
+
/**
|
|
210
|
+
* Moves the tenant's subscription item to another price (an upgrade or
|
|
211
|
+
* downgrade). Needs a subscription; `not_found` otherwise. Admin consoles
|
|
212
|
+
* call it with a service transport after their own permission check.
|
|
213
|
+
*/
|
|
214
|
+
changePlan(organizationId: string, change: PlanChange): AsyncResult<SubscriptionItem>;
|
|
215
|
+
/** Schedules (true) or clears (false) the cancellation at the end of the period. */
|
|
216
|
+
cancelAtPeriodEnd(organizationId: string, cancel: boolean): AsyncResult<string>;
|
|
217
|
+
/**
|
|
218
|
+
* Every tenant's invoices, newest first, for platform staff (`billing.read`
|
|
219
|
+
* in the platform scope) or a service transport.
|
|
220
|
+
*/
|
|
221
|
+
allInvoices(options?: PlatformListOptions): AsyncResult<readonly TenantStripeRow[]>;
|
|
222
|
+
/** The tenant's invoices from the Sync Engine, newest first (`billing.read`, or platform staff). */
|
|
223
|
+
invoices(organizationId: string, options?: {
|
|
224
|
+
readonly limit?: number;
|
|
225
|
+
}): AsyncResult<readonly StripeRow[]>;
|
|
226
|
+
/** The tenant's payment methods from the Sync Engine (`billing.read`). */
|
|
227
|
+
paymentMethods(organizationId: string): AsyncResult<readonly StripeRow[]>;
|
|
228
|
+
/** Voids an open invoice of the tenant's customer. */
|
|
229
|
+
voidInvoice(organizationId: string, invoiceId: string): AsyncResult<string>;
|
|
230
|
+
/** Marks an open invoice of the tenant's customer uncollectible. */
|
|
231
|
+
markInvoiceUncollectible(organizationId: string, invoiceId: string): AsyncResult<string>;
|
|
232
|
+
/** The billing contact as Stripe holds it, from the Sync Engine's customers table. */
|
|
233
|
+
customerDetails(organizationId: string): AsyncResult<StripeRow | undefined>;
|
|
234
|
+
/**
|
|
235
|
+
* The tenant customer's tax ids, `[]` before the tenant has a customer.
|
|
236
|
+
* From Stripe by default, which needs `customers.listTaxIds` on the
|
|
237
|
+
* client; `{ from: "sync" }` reads the Sync Engine's `stripe.tax_ids`
|
|
238
|
+
* through `billing_tax_ids` instead (`billing.read`, or platform staff).
|
|
239
|
+
*/
|
|
240
|
+
taxIds(organizationId: string, options?: {
|
|
241
|
+
readonly from?: "stripe" | "sync";
|
|
242
|
+
}): AsyncResult<readonly StripeTaxId[]>;
|
|
243
|
+
/**
|
|
244
|
+
* Adds a tax id (`{ type: 'eu_vat', value: 'DE123456789' }`) to the
|
|
245
|
+
* tenant's customer, creating the customer first when there is none.
|
|
246
|
+
*/
|
|
247
|
+
addTaxId(organizationId: string, taxId: {
|
|
248
|
+
readonly type: string;
|
|
249
|
+
readonly value: string;
|
|
250
|
+
}): AsyncResult<StripeTaxId>;
|
|
251
|
+
/** Removes a tax id from the tenant's customer; `not_found` before the tenant has a customer. */
|
|
252
|
+
removeTaxId(organizationId: string, taxId: string): AsyncResult<string>;
|
|
253
|
+
/** Updates the billing contact on the Stripe customer, the record for it. */
|
|
254
|
+
updateCustomer(organizationId: string, update: BillingCustomerUpdate): AsyncResult<string>;
|
|
255
|
+
/**
|
|
256
|
+
* Handles `checkout.session.completed` and `customer.subscription.*`:
|
|
257
|
+
* links the customer, emits `billing.*` events and invalidates sessions.
|
|
258
|
+
* Other events are ignored. Call it from `inbox.process`.
|
|
259
|
+
*/
|
|
260
|
+
handleStripeEvent(event: unknown): AsyncResult<StripeEventOutcome>;
|
|
261
|
+
}
|
|
262
|
+
/** Stripe customers, checkout, the portal and seat sync over the `billing` module. */
|
|
263
|
+
export declare function createBilling(options: BillingOptions): Billing;
|
|
264
|
+
//#endregion
|
|
265
|
+
export { type Billing, type BillingCustomer, type BillingCustomerUpdate, type BillingEventData, type BillingOptions, type BillingStatus, type BlockTransport, type CheckoutItem, type CheckoutOptions, type CustomerDetails, type PlanChange, type PlatformListOptions, type SeatSync, type StripeClient, type StripeEvent, type StripeEventOutcome, type StripeRow, type StripeSource, type StripeTaxId, type SubscriptionItem, type TenantStripeRow, rpcTransport, signStripeWebhook, sqlTransport, stripeInboxVerify, verifyStripeWebhook };
|
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
import { n as dbError } from "../../errors-B11Duf73.js";
|
|
2
|
+
import { a as ok, r as err, s as toDbError, t as AsyncResult } from "../../result-DzUbqgdW.js";
|
|
3
|
+
import { i as emitBlockEvent } from "../../block-events-CrT8r7Fe.js";
|
|
4
|
+
import { n as rpcTransport, r as sqlTransport } from "../../block-transport-BLr-ZgLc.js";
|
|
5
|
+
import { O as textOf, d as isRecord, g as pageOf, h as optionalText, i as blockCall, m as optionalInstant, n as applyTemporal, y as recordOf } from "../../block-helpers-DWHxHsEQ.js";
|
|
6
|
+
import { a as signStripeWebhook, s as stripeInboxVerify, u as verifyStripeWebhook } from "../../verify-DL41hbvY.js";
|
|
7
|
+
import { n as entitlementMembers } from "../../entitlements-DRl6ZJUm.js";
|
|
8
|
+
import { t as lazyStripe } from "../../stripe-BMj5LtsT.js";
|
|
9
|
+
//#region src/blocks/billing/billing.ts
|
|
10
|
+
const ORGANIZATION_KEY = "organization_id";
|
|
11
|
+
const SEAT_EVENT = /(?:^|\.)organization\.(?:member_added|member_removed|member_left|role_changed)$/;
|
|
12
|
+
function subscriptionItemOf(value) {
|
|
13
|
+
if (!isRecord(value)) return void 0;
|
|
14
|
+
return {
|
|
15
|
+
subscriptionId: textOf(value["subscription"]),
|
|
16
|
+
itemId: textOf(value["item"]),
|
|
17
|
+
price: optionalText(value["price"]),
|
|
18
|
+
quantity: Number(value["quantity"] ?? 0),
|
|
19
|
+
status: textOf(value["status"])
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/** A row of `billing_tax_ids` as Stripe's tax id object. */
|
|
23
|
+
function syncedTaxId(row) {
|
|
24
|
+
const verification = row["verification"];
|
|
25
|
+
const raw = row["created"];
|
|
26
|
+
const created = typeof raw === "number" || typeof raw === "string" && /^\d+$/.test(raw) ? Number(raw) : NaN;
|
|
27
|
+
return {
|
|
28
|
+
id: textOf(row["id"]),
|
|
29
|
+
type: textOf(row["type"]),
|
|
30
|
+
value: textOf(row["value"]),
|
|
31
|
+
country: optionalText(row["country"]) ?? null,
|
|
32
|
+
verification: isRecord(verification) ? { status: optionalText(verification["status"]) ?? null } : null,
|
|
33
|
+
created: Number.isSafeInteger(created) ? created : null
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
const customerIdOf = (value) => {
|
|
37
|
+
if (typeof value === "string") return value;
|
|
38
|
+
return isRecord(value) ? optionalText(value["id"]) : void 0;
|
|
39
|
+
};
|
|
40
|
+
const metadataTenant = (object) => {
|
|
41
|
+
const metadata = object["metadata"];
|
|
42
|
+
return isRecord(metadata) ? optionalText(metadata[ORGANIZATION_KEY]) : void 0;
|
|
43
|
+
};
|
|
44
|
+
function isStripeEvent(value) {
|
|
45
|
+
return isRecord(value) && typeof value["id"] === "string" && typeof value["type"] === "string" && isRecord(value["data"]);
|
|
46
|
+
}
|
|
47
|
+
/** `extra` merged into `base`: nested objects merge, arrays and other values replace. */
|
|
48
|
+
function deepMerge(base, extra) {
|
|
49
|
+
const merged = { ...base };
|
|
50
|
+
for (const [key, value] of Object.entries(extra)) {
|
|
51
|
+
const current = merged[key];
|
|
52
|
+
merged[key] = isRecord(current) && isRecord(value) ? deepMerge(current, value) : value;
|
|
53
|
+
}
|
|
54
|
+
return merged;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* The block's Checkout Session parameters with the app's `params` merged in
|
|
58
|
+
* deeply, then the customer, `client_reference_id` and the tenant metadata
|
|
59
|
+
* (on the session and, for a subscription, on `subscription_data`) set
|
|
60
|
+
* again, so `params` adds metadata without dropping the link the webhook needs.
|
|
61
|
+
*/
|
|
62
|
+
function checkoutParams(base, extra, organizationId, customerId) {
|
|
63
|
+
const merged = extra === void 0 ? { ...base } : deepMerge(base, extra);
|
|
64
|
+
const tenant = { metadata: { [ORGANIZATION_KEY]: organizationId } };
|
|
65
|
+
return deepMerge(merged, {
|
|
66
|
+
customer: customerId,
|
|
67
|
+
client_reference_id: organizationId,
|
|
68
|
+
...tenant,
|
|
69
|
+
...merged["mode"] === "subscription" ? { subscription_data: tenant } : {}
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
/** Stripe calls as results: a thrown Stripe error becomes a `DbError`. */
|
|
73
|
+
function stripeCall(work) {
|
|
74
|
+
return AsyncResult.from(async () => {
|
|
75
|
+
try {
|
|
76
|
+
return ok(await work());
|
|
77
|
+
} catch (cause) {
|
|
78
|
+
return err(toDbError(cause));
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
/** Stripe customers, checkout, the portal and seat sync over the `billing` module. */
|
|
83
|
+
function createBilling(options) {
|
|
84
|
+
applyTemporal(options);
|
|
85
|
+
const call = blockCall(options.transport, options.schema, options.mappers);
|
|
86
|
+
const stripe = lazyStripe(options.stripe);
|
|
87
|
+
const withStripe = (work) => stripeCall(async () => work(await stripe()));
|
|
88
|
+
const emit = (type, data) => {
|
|
89
|
+
if (!options.events) return;
|
|
90
|
+
emitBlockEvent(options.events, type, data, {
|
|
91
|
+
tenant: data.organizationId,
|
|
92
|
+
subject: `organizations/${data.organizationId}`
|
|
93
|
+
});
|
|
94
|
+
};
|
|
95
|
+
const customer = (organizationId) => call("billing_customer", { tenant: organizationId }, optionalText);
|
|
96
|
+
const link = (organizationId, customerId) => call("link_billing_customer", {
|
|
97
|
+
tenant: organizationId,
|
|
98
|
+
customer: customerId
|
|
99
|
+
}, textOf);
|
|
100
|
+
const ensureCustomer = (organizationId, details = {}) => customer(organizationId).andThen(async (existing) => {
|
|
101
|
+
if (existing !== void 0) return ok(existing);
|
|
102
|
+
const created = await withStripe((client) => client.customers.create({
|
|
103
|
+
...details.email === void 0 ? {} : { email: details.email },
|
|
104
|
+
...details.name === void 0 ? {} : { name: details.name },
|
|
105
|
+
metadata: { [ORGANIZATION_KEY]: organizationId }
|
|
106
|
+
}, { idempotencyKey: `customer:${organizationId}` }));
|
|
107
|
+
if (!created.ok) return created;
|
|
108
|
+
const linked = await link(organizationId, created.data.id);
|
|
109
|
+
if (linked.ok && linked.data === created.data.id) emit("billing.customer_linked", {
|
|
110
|
+
organizationId,
|
|
111
|
+
customerId: linked.data
|
|
112
|
+
});
|
|
113
|
+
return linked;
|
|
114
|
+
});
|
|
115
|
+
const seats = (organizationId) => call("billing_seat_count", { tenant: organizationId }, (value) => Number(value ?? 0));
|
|
116
|
+
const item = (organizationId) => call("billing_subscription_item", {
|
|
117
|
+
tenant: organizationId,
|
|
118
|
+
price: options.seatPrice
|
|
119
|
+
}, subscriptionItemOf);
|
|
120
|
+
const syncSeats = (organizationId, sync = {}) => seats(organizationId).andThen(async (quantity) => {
|
|
121
|
+
const current = await item(organizationId);
|
|
122
|
+
if (!current.ok) return current;
|
|
123
|
+
const found = current.data;
|
|
124
|
+
if (found === void 0 || found.quantity === quantity) return ok({
|
|
125
|
+
quantity,
|
|
126
|
+
previousQuantity: found?.quantity,
|
|
127
|
+
changed: false
|
|
128
|
+
});
|
|
129
|
+
const key = `seats:${found.itemId}:${String(found.quantity)}:${String(quantity)}:${sync.key ?? crypto.randomUUID()}`;
|
|
130
|
+
const updated = await withStripe((client) => client.subscriptionItems.update(found.itemId, {
|
|
131
|
+
quantity,
|
|
132
|
+
proration_behavior: options.prorationBehavior ?? "create_prorations"
|
|
133
|
+
}, { idempotencyKey: key }));
|
|
134
|
+
if (!updated.ok) return updated;
|
|
135
|
+
emit("billing.seats_synced", {
|
|
136
|
+
organizationId,
|
|
137
|
+
subscriptionId: found.subscriptionId,
|
|
138
|
+
quantity,
|
|
139
|
+
previousQuantity: found.quantity
|
|
140
|
+
});
|
|
141
|
+
return ok({
|
|
142
|
+
quantity,
|
|
143
|
+
previousQuantity: found.quantity,
|
|
144
|
+
changed: true
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
const invalidate = async (event) => {
|
|
148
|
+
if (!options.sessions) return [];
|
|
149
|
+
const members = await entitlementMembers(options.sessions.sql, event);
|
|
150
|
+
if (!members.ok) return [];
|
|
151
|
+
for (const userId of members.data) options.sessions.invalidate(userId);
|
|
152
|
+
return members.data;
|
|
153
|
+
};
|
|
154
|
+
const handleStripeEvent = (input) => AsyncResult.from(async () => {
|
|
155
|
+
const ignored = {
|
|
156
|
+
event: void 0,
|
|
157
|
+
organizationId: void 0,
|
|
158
|
+
customerId: void 0,
|
|
159
|
+
invalidated: []
|
|
160
|
+
};
|
|
161
|
+
if (!isStripeEvent(input)) return ok(ignored);
|
|
162
|
+
const object = input.data.object;
|
|
163
|
+
if (!isRecord(object)) return ok(ignored);
|
|
164
|
+
const customerId = customerIdOf(object["customer"]);
|
|
165
|
+
if (input.type === "checkout.session.completed") {
|
|
166
|
+
const organizationId = metadataTenant(object) ?? optionalText(object["client_reference_id"]);
|
|
167
|
+
if (organizationId === void 0 || customerId === void 0) return ok({
|
|
168
|
+
...ignored,
|
|
169
|
+
customerId
|
|
170
|
+
});
|
|
171
|
+
const linked = await link(organizationId, customerId);
|
|
172
|
+
if (!linked.ok) return linked;
|
|
173
|
+
emit("billing.checkout_completed", {
|
|
174
|
+
organizationId,
|
|
175
|
+
customerId: linked.data,
|
|
176
|
+
stripeEventId: input.id,
|
|
177
|
+
...typeof object["subscription"] === "string" ? { subscriptionId: object["subscription"] } : {}
|
|
178
|
+
});
|
|
179
|
+
return ok({
|
|
180
|
+
event: "billing.checkout_completed",
|
|
181
|
+
organizationId,
|
|
182
|
+
customerId: linked.data,
|
|
183
|
+
invalidated: []
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
const type = {
|
|
187
|
+
"customer.subscription.created": "billing.subscription_created",
|
|
188
|
+
"customer.subscription.updated": "billing.subscription_updated",
|
|
189
|
+
"customer.subscription.deleted": "billing.subscription_deleted"
|
|
190
|
+
}[input.type];
|
|
191
|
+
if (type === void 0 || customerId === void 0) return ok(ignored);
|
|
192
|
+
const tenant = await call("billing_customer_tenant", { customer: customerId }, optionalText);
|
|
193
|
+
if (!tenant.ok) return tenant;
|
|
194
|
+
let organizationId = tenant.data;
|
|
195
|
+
const claimed = metadataTenant(object);
|
|
196
|
+
if (organizationId === void 0 && claimed !== void 0) {
|
|
197
|
+
const linked = await link(claimed, customerId);
|
|
198
|
+
if (!linked.ok) return linked;
|
|
199
|
+
if (linked.data === customerId) organizationId = claimed;
|
|
200
|
+
}
|
|
201
|
+
if (organizationId === void 0) return ok({
|
|
202
|
+
...ignored,
|
|
203
|
+
customerId
|
|
204
|
+
});
|
|
205
|
+
emit(type, {
|
|
206
|
+
organizationId,
|
|
207
|
+
customerId,
|
|
208
|
+
subscriptionId: textOf(object["id"]),
|
|
209
|
+
stripeEventId: input.id,
|
|
210
|
+
...typeof object["status"] === "string" ? { status: object["status"] } : {}
|
|
211
|
+
});
|
|
212
|
+
return ok({
|
|
213
|
+
event: type,
|
|
214
|
+
organizationId,
|
|
215
|
+
customerId,
|
|
216
|
+
invalidated: await invalidate(input)
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
const priceOf = (choice) => {
|
|
220
|
+
const given = choice.price;
|
|
221
|
+
if (given !== void 0) return AsyncResult.from(() => Promise.resolve(ok(given)));
|
|
222
|
+
if (choice.plan === void 0) return AsyncResult.from(() => Promise.resolve(err(dbError("invalid_input", "Pass a price or a plan", { hint: "BILLING_PRICE_REQUIRED" }))));
|
|
223
|
+
const plan = choice.plan;
|
|
224
|
+
return call("billing_plan_price", {
|
|
225
|
+
plan,
|
|
226
|
+
billing_interval: choice.interval,
|
|
227
|
+
variant: choice.variant
|
|
228
|
+
}, optionalText).andThen((price) => Promise.resolve(price === void 0 ? err(dbError("not_found", `No price for plan "${plan}"`, { hint: "BILLING_PLAN_UNKNOWN" })) : ok(price)));
|
|
229
|
+
};
|
|
230
|
+
const missing = (what) => err(dbError("invalid_request", `The Stripe client has no ${what}`, { hint: "BILLING_STRIPE_CLIENT" }));
|
|
231
|
+
const subscription = (organizationId) => call("billing_subscription_item", { tenant: organizationId }, subscriptionItemOf).andThen((found) => Promise.resolve(found === void 0 ? err(dbError("not_found", "This tenant has no active subscription", { hint: "BILLING_NO_SUBSCRIPTION" })) : ok(found)));
|
|
232
|
+
const rows = (value) => Array.isArray(value) ? value.filter(isRecord) : [];
|
|
233
|
+
const tenantRows = (key) => (value) => rows(value).flatMap((entry) => {
|
|
234
|
+
const row = entry[key];
|
|
235
|
+
return isRecord(row) ? [{
|
|
236
|
+
organizationId: textOf(entry["tenant"]),
|
|
237
|
+
customerId: textOf(entry["customer"]),
|
|
238
|
+
row
|
|
239
|
+
}] : [];
|
|
240
|
+
});
|
|
241
|
+
const platformArgs = (list = {}) => ({
|
|
242
|
+
for_status: list.status,
|
|
243
|
+
max_rows: list.limit ?? 100,
|
|
244
|
+
before_created: pageOf(list).cursor
|
|
245
|
+
});
|
|
246
|
+
const invoices = (organizationId, list = {}) => call("billing_invoices", {
|
|
247
|
+
tenant: organizationId,
|
|
248
|
+
max_rows: list.limit ?? 50
|
|
249
|
+
}, rows);
|
|
250
|
+
const ownInvoice = (organizationId, invoiceId) => invoices(organizationId, { limit: 500 }).andThen((list) => Promise.resolve(list.some((row) => row["id"] === invoiceId) ? ok(invoiceId) : err(dbError("not_found", "This tenant has no such invoice", { hint: "BILLING_INVOICE_NOT_FOUND" }))));
|
|
251
|
+
return {
|
|
252
|
+
customer,
|
|
253
|
+
ensureCustomer,
|
|
254
|
+
changePlan: (organizationId, change) => priceOf(change).andThen((price) => subscription(organizationId).andThen(async (found) => {
|
|
255
|
+
const updated = await withStripe(async (client) => client.subscriptions.update?.(found.subscriptionId, {
|
|
256
|
+
items: [{
|
|
257
|
+
id: found.itemId,
|
|
258
|
+
price
|
|
259
|
+
}],
|
|
260
|
+
proration_behavior: change.prorationBehavior ?? "create_prorations",
|
|
261
|
+
...change.resume === false ? {} : { cancel_at_period_end: false }
|
|
262
|
+
}, change.idempotencyKey === void 0 ? void 0 : { idempotencyKey: change.idempotencyKey }));
|
|
263
|
+
if (!updated.ok) return updated;
|
|
264
|
+
if (updated.data === void 0) return missing("subscriptions.update");
|
|
265
|
+
emit("billing.subscription_updated", {
|
|
266
|
+
organizationId,
|
|
267
|
+
subscriptionId: found.subscriptionId
|
|
268
|
+
});
|
|
269
|
+
return ok({
|
|
270
|
+
...found,
|
|
271
|
+
price
|
|
272
|
+
});
|
|
273
|
+
})),
|
|
274
|
+
cancelAtPeriodEnd: (organizationId, cancel) => subscription(organizationId).andThen(async (found) => {
|
|
275
|
+
const updated = await withStripe(async (client) => client.subscriptions.update?.(found.subscriptionId, { cancel_at_period_end: cancel }));
|
|
276
|
+
if (!updated.ok) return updated;
|
|
277
|
+
return updated.data === void 0 ? missing("subscriptions.update") : ok(updated.data.id);
|
|
278
|
+
}),
|
|
279
|
+
invoices,
|
|
280
|
+
paymentMethods: (organizationId) => call("billing_payment_methods", { tenant: organizationId }, rows),
|
|
281
|
+
voidInvoice: (organizationId, invoiceId) => ownInvoice(organizationId, invoiceId).andThen(async () => {
|
|
282
|
+
const voided = await withStripe(async (client) => client.invoices?.voidInvoice(invoiceId));
|
|
283
|
+
if (!voided.ok) return voided;
|
|
284
|
+
return voided.data === void 0 ? missing("invoices.voidInvoice") : ok(voided.data.id);
|
|
285
|
+
}),
|
|
286
|
+
markInvoiceUncollectible: (organizationId, invoiceId) => ownInvoice(organizationId, invoiceId).andThen(async () => {
|
|
287
|
+
const marked = await withStripe(async (client) => client.invoices?.markUncollectible(invoiceId));
|
|
288
|
+
if (!marked.ok) return marked;
|
|
289
|
+
return marked.data === void 0 ? missing("invoices.markUncollectible") : ok(marked.data.id);
|
|
290
|
+
}),
|
|
291
|
+
customerDetails: (organizationId) => call("billing_customer_details", { tenant: organizationId }, (value) => isRecord(value) ? value : void 0),
|
|
292
|
+
taxIds: (organizationId, taxOptions = {}) => taxOptions.from === "sync" ? call("billing_tax_ids", { tenant: organizationId }, (value) => Array.isArray(value) ? value.filter(isRecord).map(syncedTaxId) : []) : customer(organizationId).andThen(async (customerId) => {
|
|
293
|
+
if (customerId === void 0) return ok([]);
|
|
294
|
+
const listed = await withStripe(async (client) => client.customers.listTaxIds?.(customerId, { limit: 100 }));
|
|
295
|
+
if (!listed.ok) return listed;
|
|
296
|
+
return listed.data === void 0 ? missing("customers.listTaxIds") : ok(listed.data.data);
|
|
297
|
+
}),
|
|
298
|
+
addTaxId: (organizationId, taxId) => ensureCustomer(organizationId).andThen(async (customerId) => {
|
|
299
|
+
const created = await withStripe(async (client) => client.customers.createTaxId?.(customerId, {
|
|
300
|
+
type: taxId.type,
|
|
301
|
+
value: taxId.value
|
|
302
|
+
}));
|
|
303
|
+
if (!created.ok) return created;
|
|
304
|
+
return created.data === void 0 ? missing("customers.createTaxId") : ok(created.data);
|
|
305
|
+
}),
|
|
306
|
+
removeTaxId: (organizationId, taxId) => customer(organizationId).andThen(async (customerId) => {
|
|
307
|
+
if (customerId === void 0) return err(dbError("not_found", "This tenant has no Stripe customer yet", { hint: "BILLING_NO_CUSTOMER" }));
|
|
308
|
+
const deleted = await withStripe(async (client) => client.customers.deleteTaxId?.(customerId, taxId));
|
|
309
|
+
if (!deleted.ok) return deleted;
|
|
310
|
+
return deleted.data === void 0 ? missing("customers.deleteTaxId") : ok(deleted.data.id);
|
|
311
|
+
}),
|
|
312
|
+
updateCustomer: (organizationId, update) => ensureCustomer(organizationId).andThen(async (customerId) => {
|
|
313
|
+
const updated = await withStripe(async (client) => client.customers.update?.(customerId, {
|
|
314
|
+
...update.email === void 0 ? {} : { email: update.email },
|
|
315
|
+
...update.name === void 0 ? {} : { name: update.name },
|
|
316
|
+
...update.phone === void 0 ? {} : { phone: update.phone },
|
|
317
|
+
...update.address === void 0 ? {} : { address: update.address },
|
|
318
|
+
...update.params
|
|
319
|
+
}));
|
|
320
|
+
if (!updated.ok) return updated;
|
|
321
|
+
return updated.data === void 0 ? missing("customers.update") : ok(updated.data.id);
|
|
322
|
+
}),
|
|
323
|
+
checkout: (organizationId, checkout) => priceOf(checkout).andThen((price) => ensureCustomer(organizationId, checkout).andThen(async (customerId) => {
|
|
324
|
+
const quantity = checkout.quantity === "seats" ? await seats(organizationId) : ok(checkout.quantity ?? 1);
|
|
325
|
+
if (!quantity.ok) return quantity;
|
|
326
|
+
const lineItems = [{
|
|
327
|
+
price,
|
|
328
|
+
quantity: quantity.data
|
|
329
|
+
}];
|
|
330
|
+
for (const extra of checkout.items ?? []) {
|
|
331
|
+
const extraPrice = await priceOf(extra);
|
|
332
|
+
if (!extraPrice.ok) return extraPrice;
|
|
333
|
+
lineItems.push({
|
|
334
|
+
price: extraPrice.data,
|
|
335
|
+
quantity: extra.quantity ?? 1
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
const mode = checkout.mode ?? "subscription";
|
|
339
|
+
return withStripe(async (client) => {
|
|
340
|
+
const params = checkoutParams({
|
|
341
|
+
customer: customerId,
|
|
342
|
+
mode,
|
|
343
|
+
client_reference_id: organizationId,
|
|
344
|
+
line_items: lineItems,
|
|
345
|
+
success_url: checkout.successUrl,
|
|
346
|
+
...checkout.cancelUrl === void 0 ? {} : { cancel_url: checkout.cancelUrl }
|
|
347
|
+
}, checkout.params, organizationId, customerId);
|
|
348
|
+
const session = await client.checkout.sessions.create(params, checkout.idempotencyKey === void 0 ? void 0 : { idempotencyKey: checkout.idempotencyKey });
|
|
349
|
+
return {
|
|
350
|
+
id: session.id,
|
|
351
|
+
url: session.url ?? void 0
|
|
352
|
+
};
|
|
353
|
+
});
|
|
354
|
+
})),
|
|
355
|
+
portal: (organizationId, portal) => customer(organizationId).andThen(async (customerId) => {
|
|
356
|
+
if (customerId === void 0) return err(dbError("not_found", "This tenant has no Stripe customer yet", { hint: "BILLING_NO_CUSTOMER" }));
|
|
357
|
+
return withStripe(async (client) => {
|
|
358
|
+
return { url: (await client.billingPortal.sessions.create({
|
|
359
|
+
customer: customerId,
|
|
360
|
+
return_url: portal.returnUrl
|
|
361
|
+
})).url };
|
|
362
|
+
});
|
|
363
|
+
}),
|
|
364
|
+
status: (organizationId) => call("billing_status", { tenant: organizationId }, (value) => {
|
|
365
|
+
const row = recordOf(value, "billing_status");
|
|
366
|
+
return {
|
|
367
|
+
customerId: optionalText(row["customer"]),
|
|
368
|
+
seats: Number(row["seats"] ?? 0),
|
|
369
|
+
subscription: subscriptionItemOf(row["subscription"])
|
|
370
|
+
};
|
|
371
|
+
}),
|
|
372
|
+
syncSeats,
|
|
373
|
+
subscription: (organizationId) => call("billing_subscription", { tenant: organizationId }, (value) => isRecord(value) ? value : void 0),
|
|
374
|
+
allInvoices: (list) => call("billing_all_invoices", platformArgs(list), tenantRows("invoice")),
|
|
375
|
+
allCustomers: () => call("billing_all_customers", {}, (value) => (Array.isArray(value) ? value : []).filter(isRecord).map((row) => ({
|
|
376
|
+
organizationId: textOf(row["tenant"]),
|
|
377
|
+
customerId: textOf(row["customer"]),
|
|
378
|
+
email: optionalText(row["email"]),
|
|
379
|
+
name: optionalText(row["name"]),
|
|
380
|
+
created: optionalInstant(row["created"])
|
|
381
|
+
}))),
|
|
382
|
+
allSubscriptions: (list) => call("billing_all_subscriptions", platformArgs(list), tenantRows("subscription")),
|
|
383
|
+
cancelSubscription: (organizationId) => item(organizationId).andThen(async (found) => {
|
|
384
|
+
if (found === void 0) return ok(void 0);
|
|
385
|
+
const cancelled = await withStripe((client) => client.subscriptions.cancel(found.subscriptionId));
|
|
386
|
+
return cancelled.ok ? ok(cancelled.data.id) : cancelled;
|
|
387
|
+
}),
|
|
388
|
+
seatSink: () => ({ async send(events) {
|
|
389
|
+
const latest = /* @__PURE__ */ new Map();
|
|
390
|
+
for (const event of events) {
|
|
391
|
+
const tenant = optionalText(event["partitionkey"]);
|
|
392
|
+
if (tenant !== void 0 && SEAT_EVENT.test(event.type)) latest.set(tenant, event.id);
|
|
393
|
+
}
|
|
394
|
+
for (const [tenant, id] of latest) await syncSeats(tenant, { key: id }).orThrow();
|
|
395
|
+
} }),
|
|
396
|
+
handleStripeEvent
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
//#endregion
|
|
400
|
+
export { createBilling, rpcTransport, signStripeWebhook, sqlTransport, stripeInboxVerify, verifyStripeWebhook };
|