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,334 @@
|
|
|
1
|
+
import { n as dbError } from "../../errors-B11Duf73.js";
|
|
2
|
+
import { t as temporal } from "../../temporal-required-BVvW7SYJ.js";
|
|
3
|
+
import { a as ok, t as AsyncResult } from "../../result-DzUbqgdW.js";
|
|
4
|
+
import { a as problemResponse } from "../../problem-BreOl8b8.js";
|
|
5
|
+
import { a as withAuthMode, o as withJwtClaims, s as withUserClaims } from "../../claims-DDBQT6BK.js";
|
|
6
|
+
import { n as rpcTransport, r as sqlTransport } from "../../block-transport-BLr-ZgLc.js";
|
|
7
|
+
import { D as stringsOf, O as textOf, T as sha256Hex, h as optionalText, i as blockCall, m as optionalInstant, n as applyTemporal, u as instantArg, x as recordsOf, y as recordOf } from "../../block-helpers-DWHxHsEQ.js";
|
|
8
|
+
import { defineComposite, defineMiddleware } from "@supabase/middleware";
|
|
9
|
+
//#region src/blocks/api-keys/api-keys.ts
|
|
10
|
+
const TOKEN = /^([a-z][a-z0-9]*)_([0-9a-f]{16})_([A-Za-z0-9_-]{32,})$/;
|
|
11
|
+
const PREFIX = /^[a-z][a-z0-9]*$/;
|
|
12
|
+
const ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
13
|
+
const SECRET_LENGTH = 43;
|
|
14
|
+
const CHECKSUM_LENGTH = 6;
|
|
15
|
+
const CHECKED_TAIL = /^[A-Za-z0-9]{49}$/;
|
|
16
|
+
const CRC_TABLE = (() => {
|
|
17
|
+
const table = /* @__PURE__ */ new Uint32Array(256);
|
|
18
|
+
for (let index = 0; index < 256; index += 1) {
|
|
19
|
+
let value = index;
|
|
20
|
+
for (let bit = 0; bit < 8; bit += 1) value = value & 1 ? 3988292384 ^ value >>> 1 : value >>> 1;
|
|
21
|
+
table[index] = value >>> 0;
|
|
22
|
+
}
|
|
23
|
+
return table;
|
|
24
|
+
})();
|
|
25
|
+
/**
|
|
26
|
+
* The CRC-32 (IEEE 802.3) of `text` as 6 base62 characters: the checksum
|
|
27
|
+
* GitHub-style tokens end in, so a secret
|
|
28
|
+
* scanner or the server rejects a mistyped key without a lookup.
|
|
29
|
+
*/
|
|
30
|
+
function apiKeyChecksum(text) {
|
|
31
|
+
let crc = 4294967295;
|
|
32
|
+
for (let index = 0; index < text.length; index += 1) crc = (CRC_TABLE[(crc ^ (text.codePointAt(index) ?? 0)) & 255] ?? 0) ^ crc >>> 8;
|
|
33
|
+
let value = (crc ^ 4294967295) >>> 0;
|
|
34
|
+
let out = "";
|
|
35
|
+
for (let index = 0; index < CHECKSUM_LENGTH; index += 1) {
|
|
36
|
+
out = ALPHABET[value % 62] + out;
|
|
37
|
+
value = Math.floor(value / 62);
|
|
38
|
+
}
|
|
39
|
+
return out;
|
|
40
|
+
}
|
|
41
|
+
function base62Secret() {
|
|
42
|
+
let secret = "";
|
|
43
|
+
const bytes = /* @__PURE__ */ new Uint8Array(64);
|
|
44
|
+
while (secret.length < SECRET_LENGTH) {
|
|
45
|
+
crypto.getRandomValues(bytes);
|
|
46
|
+
for (const byte of bytes) if (byte < 248 && secret.length < SECRET_LENGTH) secret += ALPHABET[byte % 62];
|
|
47
|
+
}
|
|
48
|
+
return secret;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Splits `<prefix>_<public id>_<secret><checksum>`: a 43-character base62
|
|
52
|
+
* secret and the 6-character checksum of everything before it. A key from
|
|
53
|
+
* before the checksum (`<prefix>_<public id>_<secret>`) still parses. A
|
|
54
|
+
* checksum that doesn't match, or anything else (a JWT, say), is
|
|
55
|
+
* `undefined`.
|
|
56
|
+
*/
|
|
57
|
+
function parseApiKey(token) {
|
|
58
|
+
const match = TOKEN.exec(token.trim());
|
|
59
|
+
if (!match) return void 0;
|
|
60
|
+
const prefix = match[1];
|
|
61
|
+
const publicId = match[2];
|
|
62
|
+
const tail = match[3];
|
|
63
|
+
if (CHECKED_TAIL.test(tail)) {
|
|
64
|
+
const secret = tail.slice(0, SECRET_LENGTH);
|
|
65
|
+
return tail.slice(SECRET_LENGTH) === apiKeyChecksum(`${prefix}_${publicId}_${secret}`) ? {
|
|
66
|
+
prefix,
|
|
67
|
+
publicId,
|
|
68
|
+
secret,
|
|
69
|
+
checksum: true
|
|
70
|
+
} : void 0;
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
prefix,
|
|
74
|
+
publicId,
|
|
75
|
+
secret: tail,
|
|
76
|
+
checksum: false
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
function publicId() {
|
|
80
|
+
const bytes = crypto.getRandomValues(/* @__PURE__ */ new Uint8Array(8));
|
|
81
|
+
return Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
82
|
+
}
|
|
83
|
+
const STATES = [
|
|
84
|
+
"active",
|
|
85
|
+
"grace",
|
|
86
|
+
"revoked",
|
|
87
|
+
"expired"
|
|
88
|
+
];
|
|
89
|
+
function stateOf(value, revokedAt, expiresAt) {
|
|
90
|
+
const known = STATES.find((state) => state === value);
|
|
91
|
+
if (known) return known;
|
|
92
|
+
const now = temporal().Now.instant();
|
|
93
|
+
const past = (at) => at !== void 0 && temporal().Instant.compare(at, now) <= 0;
|
|
94
|
+
if (past(revokedAt)) return "revoked";
|
|
95
|
+
if (past(expiresAt)) return "expired";
|
|
96
|
+
return revokedAt === void 0 ? "active" : "grace";
|
|
97
|
+
}
|
|
98
|
+
function apiKeyOf(value) {
|
|
99
|
+
const row = recordOf(value, "api key");
|
|
100
|
+
const organizationId = optionalText(row["organization_id"]);
|
|
101
|
+
const userId = optionalText(row["user_id"]);
|
|
102
|
+
const expiresAt = optionalInstant(row["expires_at"]);
|
|
103
|
+
const lastUsedAt = optionalInstant(row["last_used_at"]);
|
|
104
|
+
const revokedAt = optionalInstant(row["revoked_at"]);
|
|
105
|
+
const rotatedFrom = optionalText(row["rotated_from"]);
|
|
106
|
+
const createdBy = optionalText(row["created_by"]);
|
|
107
|
+
const successorId = optionalText(row["successor_id"]);
|
|
108
|
+
const rateLimit = row["rate_limit"];
|
|
109
|
+
return {
|
|
110
|
+
id: textOf(row["id"]),
|
|
111
|
+
...organizationId ? { organizationId } : {},
|
|
112
|
+
...userId ? { userId } : {},
|
|
113
|
+
name: textOf(row["name"]),
|
|
114
|
+
prefix: textOf(row["prefix"]),
|
|
115
|
+
publicId: textOf(row["public_id"]),
|
|
116
|
+
scopes: stringsOf(row["scopes"]),
|
|
117
|
+
...typeof rateLimit === "number" ? { rateLimit } : {},
|
|
118
|
+
...expiresAt ? { expiresAt } : {},
|
|
119
|
+
...lastUsedAt ? { lastUsedAt } : {},
|
|
120
|
+
...revokedAt ? { revokedAt } : {},
|
|
121
|
+
...rotatedFrom ? { rotatedFrom } : {},
|
|
122
|
+
...createdBy ? { createdBy } : {},
|
|
123
|
+
createdAt: optionalInstant(row["created_at"]) ?? temporal().Now.instant(),
|
|
124
|
+
state: stateOf(row["state"], revokedAt, expiresAt),
|
|
125
|
+
...successorId ? { successorId } : {}
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
function checkOf(value) {
|
|
129
|
+
const row = recordOf(value, "verify_api_key");
|
|
130
|
+
switch (row["status"]) {
|
|
131
|
+
case "ok": return {
|
|
132
|
+
status: "ok",
|
|
133
|
+
key: apiKeyOf(row["key"])
|
|
134
|
+
};
|
|
135
|
+
case "rate_limited": return {
|
|
136
|
+
status: "rate_limited",
|
|
137
|
+
retryAfter: Number(row["retry_after"] ?? 60)
|
|
138
|
+
};
|
|
139
|
+
default: return { status: "invalid" };
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* API keys over the `api-keys` SQL module. Members create and rotate keys
|
|
144
|
+
* with their own transport; `verify` (and `apiKeyResolver`) need one that
|
|
145
|
+
* runs as the service role.
|
|
146
|
+
*/
|
|
147
|
+
function createApiKeys(options) {
|
|
148
|
+
applyTemporal(options);
|
|
149
|
+
const prefix = options.prefix ?? "bs";
|
|
150
|
+
if (!PREFIX.test(prefix)) throw new TypeError(`createApiKeys: prefix must be lowercase letters and digits, not "${prefix}"`);
|
|
151
|
+
const call = blockCall(options.transport, options.schema ?? "better_supabase");
|
|
152
|
+
const fresh = async () => {
|
|
153
|
+
const id = publicId();
|
|
154
|
+
const secret = base62Secret();
|
|
155
|
+
const key = `${prefix}_${id}_${secret}`;
|
|
156
|
+
return {
|
|
157
|
+
id,
|
|
158
|
+
token: `${key}${apiKeyChecksum(key)}`,
|
|
159
|
+
hash: await sha256Hex(secret)
|
|
160
|
+
};
|
|
161
|
+
};
|
|
162
|
+
return {
|
|
163
|
+
create: (input) => AsyncResult.from(async () => {
|
|
164
|
+
const { id, token, hash } = await fresh();
|
|
165
|
+
return call("create_api_key", {
|
|
166
|
+
name: input.name,
|
|
167
|
+
public_id: id,
|
|
168
|
+
secret_hash: hash,
|
|
169
|
+
tenant: input.organizationId ?? null,
|
|
170
|
+
personal: input.personal ?? false,
|
|
171
|
+
scopes: input.scopes ?? [],
|
|
172
|
+
expires_at: instantArg(input.expiresAt) ?? null,
|
|
173
|
+
rate_limit: input.rateLimit ?? null,
|
|
174
|
+
prefix
|
|
175
|
+
}, (value) => ({
|
|
176
|
+
key: apiKeyOf(value),
|
|
177
|
+
token
|
|
178
|
+
}));
|
|
179
|
+
}),
|
|
180
|
+
list: (organizationId) => call("list_api_keys", { tenant: organizationId ?? null }, (value) => recordsOf(value, "list_api_keys").map(apiKeyOf)),
|
|
181
|
+
revoke: (id) => call("revoke_api_key", { key: id }, (value) => value === true),
|
|
182
|
+
rotate: (id, rotateOptions = {}) => AsyncResult.from(async () => {
|
|
183
|
+
const { id: next, token, hash } = await fresh();
|
|
184
|
+
return call("rotate_api_key", {
|
|
185
|
+
key: id,
|
|
186
|
+
public_id: next,
|
|
187
|
+
secret_hash: hash,
|
|
188
|
+
grace: (rotateOptions.grace ?? temporal().Duration.from({ days: 1 })).toString()
|
|
189
|
+
}, (value) => ({
|
|
190
|
+
key: apiKeyOf(value),
|
|
191
|
+
token
|
|
192
|
+
}));
|
|
193
|
+
}),
|
|
194
|
+
verify: (token) => AsyncResult.from(async () => {
|
|
195
|
+
const parsed = parseApiKey(token);
|
|
196
|
+
if (!parsed || parsed.prefix !== prefix) return ok({ status: "invalid" });
|
|
197
|
+
return call("verify_api_key", {
|
|
198
|
+
public_id: parsed.publicId,
|
|
199
|
+
secret_hash: await sha256Hex(parsed.secret)
|
|
200
|
+
}, checkOf);
|
|
201
|
+
})
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* The claims queries run with for a key: `api_key` with `id`, `name`,
|
|
206
|
+
* `scopes` and `organization_id` for the module's `has_scope()` and
|
|
207
|
+
* `api_key_tenant()`, plus `options.claim`.
|
|
208
|
+
*/
|
|
209
|
+
function apiKeyClaims(key, options = {}) {
|
|
210
|
+
const scopes = key.scopes.includes("*") && options.allPermissions ? [.../* @__PURE__ */ new Set([...key.scopes.filter((scope) => scope !== "*"), ...options.allPermissions])] : key.scopes;
|
|
211
|
+
const base = {
|
|
212
|
+
id: key.id,
|
|
213
|
+
name: key.name,
|
|
214
|
+
scopes,
|
|
215
|
+
...key.organizationId ? { organization_id: key.organizationId } : {}
|
|
216
|
+
};
|
|
217
|
+
const claims = {
|
|
218
|
+
sub: key.userId ?? "",
|
|
219
|
+
role: "authenticated",
|
|
220
|
+
aud: "authenticated",
|
|
221
|
+
api_key: base
|
|
222
|
+
};
|
|
223
|
+
if (options.claim !== void 0) {
|
|
224
|
+
const names = options.claim;
|
|
225
|
+
const claim = names.name;
|
|
226
|
+
const service = key.userId === void 0 && key.organizationId !== void 0;
|
|
227
|
+
const roles = service ? options.serviceRoles?.(key) ?? names.serviceRoles : void 0;
|
|
228
|
+
const target = claim === "api_key" ? base : {
|
|
229
|
+
id: key.id,
|
|
230
|
+
name: key.name
|
|
231
|
+
};
|
|
232
|
+
target[names.scopes ?? "scopes"] = scopes.filter((scope) => scope !== "*");
|
|
233
|
+
if (service) target[names.tenant ?? "tenant"] = key.organizationId;
|
|
234
|
+
if (roles && roles.length > 0) target[names.roles ?? "roles"] = [...roles];
|
|
235
|
+
claims[claim] = target;
|
|
236
|
+
}
|
|
237
|
+
if (options.tenantClaim !== void 0 && key.userId !== void 0 && key.organizationId !== void 0) claims[options.tenantClaim] = key.organizationId;
|
|
238
|
+
return claims;
|
|
239
|
+
}
|
|
240
|
+
function presented(request, header) {
|
|
241
|
+
const direct = request.headers.get(header)?.trim();
|
|
242
|
+
if (direct) return direct;
|
|
243
|
+
const bearer = request.headers.get("authorization")?.match(/^Bearer\s+(.+)$/i)?.[1]?.trim();
|
|
244
|
+
return bearer && parseApiKey(bearer) ? bearer : void 0;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Resolves `x-api-key` (or a Bearer token shaped like a key) to an `apiKey`
|
|
248
|
+
* auth state. Requests without one fall through to the JWT and cookie
|
|
249
|
+
* resolution. Pass it to `createServer({ auth: { resolvers: [...] } })`.
|
|
250
|
+
*/
|
|
251
|
+
function apiKeyResolver(options) {
|
|
252
|
+
const header = options.header ?? "x-api-key";
|
|
253
|
+
return {
|
|
254
|
+
name: "api-keys",
|
|
255
|
+
async resolve(request) {
|
|
256
|
+
const token = presented(request, header);
|
|
257
|
+
if (token === void 0) return void 0;
|
|
258
|
+
const checked = await options.keys.verify(token);
|
|
259
|
+
if (!checked.ok) return {
|
|
260
|
+
kind: "invalid",
|
|
261
|
+
error: checked.error
|
|
262
|
+
};
|
|
263
|
+
const check = checked.data;
|
|
264
|
+
switch (check.status) {
|
|
265
|
+
case "ok": {
|
|
266
|
+
const { key } = check;
|
|
267
|
+
return {
|
|
268
|
+
kind: "apiKey",
|
|
269
|
+
keyId: key.id,
|
|
270
|
+
name: key.name,
|
|
271
|
+
...key.organizationId ? { organizationId: key.organizationId } : {},
|
|
272
|
+
...key.userId ? { userId: key.userId } : {},
|
|
273
|
+
scopes: key.scopes,
|
|
274
|
+
createdAt: key.createdAt,
|
|
275
|
+
...key.createdBy ? { createdBy: key.createdBy } : {},
|
|
276
|
+
claims: apiKeyClaims(key, options)
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
case "rate_limited": return {
|
|
280
|
+
kind: "invalid",
|
|
281
|
+
error: dbError("rate_limited", "API key rate limit exceeded", {
|
|
282
|
+
code: "API_KEY_RATE_LIMITED",
|
|
283
|
+
retryAfter: check.retryAfter
|
|
284
|
+
})
|
|
285
|
+
};
|
|
286
|
+
case "invalid": return {
|
|
287
|
+
kind: "invalid",
|
|
288
|
+
error: dbError("unauthorized", "Invalid API key", { code: "INVALID_API_KEY" })
|
|
289
|
+
};
|
|
290
|
+
default: return check;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
//#endregion
|
|
296
|
+
//#region src/blocks/api-keys/pipeline.ts
|
|
297
|
+
function withApiKeyAuth(options) {
|
|
298
|
+
const resolver = apiKeyResolver(options);
|
|
299
|
+
return defineMiddleware({
|
|
300
|
+
key: "auth",
|
|
301
|
+
run: () => async (request) => {
|
|
302
|
+
const instance = new URL(request.url).pathname;
|
|
303
|
+
const state = await resolver.resolve(request);
|
|
304
|
+
if (state?.kind === "apiKey") return { auth: state };
|
|
305
|
+
return problemResponse(state?.kind === "invalid" ? state.error : dbError("unauthorized", "An API key is required", { code: "API_KEY_REQUIRED" }), {
|
|
306
|
+
instance,
|
|
307
|
+
format: options.problem,
|
|
308
|
+
headers: { "www-authenticate": "Bearer realm=\"api\"" }
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
})();
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* A `@supabase/server` pipeline entry for routes that take API keys
|
|
315
|
+
* (`x-api-key`, or `Authorization: Bearer` with a key): it verifies the key
|
|
316
|
+
* with `keys.verify`, answers a missing, invalid or rate-limited key with
|
|
317
|
+
* Problem Details, and contributes `ctx.auth` and the `withSupabase` keys
|
|
318
|
+
* (`jwtClaims`, `userClaims`, `authMode`) from the key's claims, so
|
|
319
|
+
* `withPostgresClient` and `withBetterPostgres` run queries as the key.
|
|
320
|
+
*
|
|
321
|
+
* ```ts
|
|
322
|
+
* pipeline([withApiKey({ keys }), withPostgresClient(), withBetterPostgres(betterSupabase)()], (req, ctx) => ...)
|
|
323
|
+
* ```
|
|
324
|
+
*/
|
|
325
|
+
function withApiKey(options) {
|
|
326
|
+
return defineComposite({ build: () => [
|
|
327
|
+
withApiKeyAuth(options),
|
|
328
|
+
withJwtClaims(),
|
|
329
|
+
withUserClaims(),
|
|
330
|
+
withAuthMode()
|
|
331
|
+
] })();
|
|
332
|
+
}
|
|
333
|
+
//#endregion
|
|
334
|
+
export { apiKeyChecksum, apiKeyClaims, apiKeyResolver, createApiKeys, parseApiKey, rpcTransport, sqlTransport, withApiKey };
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/// <reference lib="esnext.temporal" />
|
|
2
|
+
import { t as AsyncResult, w as ErrorMapper } from "../../result-D7y2fT87.js";
|
|
3
|
+
import { i as sqlTransport, r as rpcTransport, t as BlockTransport } from "../../block-transport-DvaoPuZ9.js";
|
|
4
|
+
import { r as BlockTemporalOptions } from "../../block-helpers-CKtbFcRv.js";
|
|
5
|
+
import { m as JobHandler } from "../../queue-CLJurhdy.js";
|
|
6
|
+
import { r as EventSink } from "../../cloud-event-C1JCc1bH.js";
|
|
7
|
+
//#region src/blocks/attachments/attachments.d.ts
|
|
8
|
+
interface StorageReply<T> {
|
|
9
|
+
readonly data: T | null;
|
|
10
|
+
readonly error: unknown;
|
|
11
|
+
}
|
|
12
|
+
/** The `supabase.storage.from(bucket)` methods attachments use. */
|
|
13
|
+
interface AttachmentBucket {
|
|
14
|
+
createSignedUploadUrl(path: string): PromiseLike<StorageReply<{
|
|
15
|
+
readonly signedUrl: string;
|
|
16
|
+
readonly token: string;
|
|
17
|
+
}>>;
|
|
18
|
+
createSignedUrl(path: string, expiresIn: number, options?: {
|
|
19
|
+
download?: string | boolean;
|
|
20
|
+
}): PromiseLike<StorageReply<{
|
|
21
|
+
readonly signedUrl: string;
|
|
22
|
+
}>>;
|
|
23
|
+
download(path: string): PromiseLike<StorageReply<Blob>>;
|
|
24
|
+
remove(paths: string[]): PromiseLike<StorageReply<unknown>>;
|
|
25
|
+
/** Used by `put`, which uploads from the server. */
|
|
26
|
+
upload?(path: string, body: Blob | ArrayBuffer | Uint8Array, options?: {
|
|
27
|
+
readonly contentType?: string;
|
|
28
|
+
readonly upsert?: boolean;
|
|
29
|
+
}): PromiseLike<StorageReply<unknown>>;
|
|
30
|
+
}
|
|
31
|
+
/** `supabase.storage`, typed structurally. */
|
|
32
|
+
interface AttachmentStorage {
|
|
33
|
+
from(bucket: string): AttachmentBucket;
|
|
34
|
+
}
|
|
35
|
+
interface AttachmentsOptions extends BlockTemporalOptions {
|
|
36
|
+
/** The caller's transport (`rpcTransport(supabase)`). */
|
|
37
|
+
readonly transport: BlockTransport;
|
|
38
|
+
/** The caller's `supabase.storage`, so the bucket policies apply. */
|
|
39
|
+
readonly storage: AttachmentStorage;
|
|
40
|
+
/** The module schema (`sql.modules.attachments.schema`), default `better_supabase`. */
|
|
41
|
+
readonly schema?: string;
|
|
42
|
+
readonly mappers?: readonly ErrorMapper[];
|
|
43
|
+
/** Must match `sql.modules.attachments.options.requireScan`. Default `true`. */
|
|
44
|
+
readonly requireScan?: boolean;
|
|
45
|
+
/** Lifetime of a signed download URL in seconds. Default 300. */
|
|
46
|
+
readonly downloadTtl?: number;
|
|
47
|
+
}
|
|
48
|
+
type AttachmentStatus = "pending" | "clean" | "infected" | "failed";
|
|
49
|
+
interface Attachment {
|
|
50
|
+
readonly id: string;
|
|
51
|
+
/** `undefined` for a file of a subject without a tenant (`tenant: false`). */
|
|
52
|
+
readonly organizationId: string | undefined;
|
|
53
|
+
readonly subjectType: string | undefined;
|
|
54
|
+
readonly subjectId: string | undefined;
|
|
55
|
+
readonly bucket: string;
|
|
56
|
+
/** The object path in the bucket, `{organizationId}/attachments/{id}` unless `options.path` says otherwise. */
|
|
57
|
+
readonly path: string;
|
|
58
|
+
readonly name: string;
|
|
59
|
+
readonly mimeType: string;
|
|
60
|
+
readonly size: number;
|
|
61
|
+
readonly status: AttachmentStatus;
|
|
62
|
+
/** What the scanner reported, such as the signature it matched. */
|
|
63
|
+
readonly scanDetail: string | undefined;
|
|
64
|
+
/** What `upload` stored with the file; `{}` without any. */
|
|
65
|
+
readonly metadata: Readonly<Record<string, unknown>>;
|
|
66
|
+
readonly uploadedBy: string | undefined;
|
|
67
|
+
readonly createdAt: Temporal.Instant;
|
|
68
|
+
/** Set by `confirm()` once the object exists. */
|
|
69
|
+
readonly uploadedAt: Temporal.Instant | undefined;
|
|
70
|
+
readonly scannedAt: Temporal.Instant | undefined;
|
|
71
|
+
}
|
|
72
|
+
interface NewAttachment {
|
|
73
|
+
/** `null` for a subject type configured with `tenant: false`. */
|
|
74
|
+
readonly organizationId: string | null;
|
|
75
|
+
readonly name: string;
|
|
76
|
+
readonly mimeType: string;
|
|
77
|
+
/** Bytes; `confirm()` replaces it with the stored size. */
|
|
78
|
+
readonly size: number;
|
|
79
|
+
readonly subjectType?: string;
|
|
80
|
+
readonly subjectId?: string;
|
|
81
|
+
/** App data about the file, such as a caption or its source, kept with the record. */
|
|
82
|
+
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
83
|
+
}
|
|
84
|
+
interface AttachmentUpload {
|
|
85
|
+
readonly attachment: Attachment;
|
|
86
|
+
/** PUT the file here, or pass `token` to `uploadToSignedUrl(path, token, file)`. */
|
|
87
|
+
readonly signedUrl: string;
|
|
88
|
+
readonly token: string;
|
|
89
|
+
}
|
|
90
|
+
interface AttachmentDownload {
|
|
91
|
+
readonly attachment: Attachment;
|
|
92
|
+
readonly signedUrl: string;
|
|
93
|
+
}
|
|
94
|
+
interface Attachments {
|
|
95
|
+
/** Creates the pending record and a signed upload URL for its path. */
|
|
96
|
+
upload(attachment: NewAttachment): AsyncResult<AttachmentUpload>;
|
|
97
|
+
/** Marks the upload done after the file is stored; emits `attachment.uploaded`. */
|
|
98
|
+
confirm(id: string): AsyncResult<Attachment>;
|
|
99
|
+
get(id: string): AsyncResult<Attachment>;
|
|
100
|
+
list(organizationId: string | null, subject?: {
|
|
101
|
+
readonly type: string;
|
|
102
|
+
readonly id: string;
|
|
103
|
+
}): AsyncResult<readonly Attachment[]>;
|
|
104
|
+
/**
|
|
105
|
+
* A signed URL for a file the scanner passed. `invalid_request` with hint
|
|
106
|
+
* `ATTACHMENT_NOT_SCANNED` until then, and for an infected file.
|
|
107
|
+
*/
|
|
108
|
+
download(id: string, options?: {
|
|
109
|
+
readonly as?: string | boolean;
|
|
110
|
+
}): AsyncResult<AttachmentDownload>;
|
|
111
|
+
/** Deletes the file, then the record (the uploader, or `attachments.manage`). */
|
|
112
|
+
remove(id: string): AsyncResult<boolean>;
|
|
113
|
+
/**
|
|
114
|
+
* Creates the record, uploads `file` from the server and confirms it, for
|
|
115
|
+
* files the server makes or fetches (an export, a generated PDF, an
|
|
116
|
+
* import). Returns the confirmed attachment, which still waits for the
|
|
117
|
+
* scan when the module requires one.
|
|
118
|
+
*/
|
|
119
|
+
put(attachment: NewAttachment, file: Blob | ArrayBuffer | Uint8Array): AsyncResult<Attachment>;
|
|
120
|
+
/**
|
|
121
|
+
* The file's bytes, for server-side processing, behind the same scan gate
|
|
122
|
+
* as `download`: `ATTACHMENT_NOT_SCANNED` until the scan passes.
|
|
123
|
+
*/
|
|
124
|
+
read(id: string): AsyncResult<{
|
|
125
|
+
readonly attachment: Attachment;
|
|
126
|
+
readonly file: Blob;
|
|
127
|
+
}>;
|
|
128
|
+
}
|
|
129
|
+
/** Attachments as the caller: the table's and the bucket's policies apply. */
|
|
130
|
+
export declare function createAttachments(options: AttachmentsOptions): Attachments;
|
|
131
|
+
/** A scanner's verdict on one file. */
|
|
132
|
+
interface ScanVerdict {
|
|
133
|
+
readonly status: "clean" | "infected";
|
|
134
|
+
/** Stored as `scan_detail`, such as the matched signature. */
|
|
135
|
+
readonly detail?: string;
|
|
136
|
+
}
|
|
137
|
+
interface AttachmentScannerOptions extends BlockTemporalOptions {
|
|
138
|
+
/** A service-role transport: `set_attachment_status()` is granted to `service_role` only. */
|
|
139
|
+
readonly transport: BlockTransport;
|
|
140
|
+
/** A service-role `supabase.storage`, to read pending files. */
|
|
141
|
+
readonly storage: AttachmentStorage;
|
|
142
|
+
readonly schema?: string;
|
|
143
|
+
/** Scans the file (ClamAV, a scanning API). A throw records `failed` and rethrows. */
|
|
144
|
+
readonly scan: (file: Blob, attachment: Attachment, signal?: AbortSignal) => ScanVerdict | Promise<ScanVerdict>;
|
|
145
|
+
/** The outbox `typePrefix`. Default `dev.better-supabase`. */
|
|
146
|
+
readonly typePrefix?: string;
|
|
147
|
+
}
|
|
148
|
+
/** The payload `job` expects. */
|
|
149
|
+
interface AttachmentScanJob {
|
|
150
|
+
readonly attachmentId: string;
|
|
151
|
+
}
|
|
152
|
+
interface AttachmentScanner {
|
|
153
|
+
/** Scans one uploaded file and records the verdict. */
|
|
154
|
+
scan(id: string, signal?: AbortSignal): AsyncResult<Attachment>;
|
|
155
|
+
/** A jobs handler: `queue.work('attachment-scans', scanner.job)`. */
|
|
156
|
+
readonly job: JobHandler<AttachmentScanJob>;
|
|
157
|
+
/** An outbox sink that scans each `attachment.uploaded` event's file. */
|
|
158
|
+
sink(): EventSink;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Scans uploaded files with the app's `scan` function and records `clean`,
|
|
162
|
+
* `infected` or `failed`. A file already clean or infected is not scanned
|
|
163
|
+
* again, so replayed events and retried jobs are safe.
|
|
164
|
+
*/
|
|
165
|
+
export declare function createAttachmentScanner(options: AttachmentScannerOptions): AttachmentScanner;
|
|
166
|
+
/** A scanned object in any bucket (`scanned_objects`). */
|
|
167
|
+
interface ScannedObject {
|
|
168
|
+
readonly bucket: string;
|
|
169
|
+
readonly path: string;
|
|
170
|
+
readonly status: AttachmentStatus;
|
|
171
|
+
readonly detail: string | undefined;
|
|
172
|
+
readonly scannedAt: Temporal.Instant | undefined;
|
|
173
|
+
}
|
|
174
|
+
interface ObjectScannerOptions extends BlockTemporalOptions {
|
|
175
|
+
/** A service-role transport: `set_object_scan()` is granted to `service_role` only. */
|
|
176
|
+
readonly transport: BlockTransport;
|
|
177
|
+
/** A service-role `supabase.storage`, to read the objects. */
|
|
178
|
+
readonly storage: AttachmentStorage;
|
|
179
|
+
readonly schema?: string;
|
|
180
|
+
/** Scans the file. A throw records `failed` and rethrows. */
|
|
181
|
+
readonly scan: (file: Blob, object: {
|
|
182
|
+
readonly bucket: string;
|
|
183
|
+
readonly path: string;
|
|
184
|
+
}, signal?: AbortSignal) => ScanVerdict | Promise<ScanVerdict>;
|
|
185
|
+
/** The outbox `typePrefix`. Default `dev.better-supabase`. */
|
|
186
|
+
readonly typePrefix?: string;
|
|
187
|
+
}
|
|
188
|
+
/** The payload `ObjectScanner.job` expects. */
|
|
189
|
+
interface ObjectScanJob {
|
|
190
|
+
readonly bucket: string;
|
|
191
|
+
readonly path: string;
|
|
192
|
+
}
|
|
193
|
+
interface ObjectScanner {
|
|
194
|
+
/** Scans one object and records the verdict; a clean or infected object is not scanned again. */
|
|
195
|
+
scan(bucket: string, path: string, signal?: AbortSignal): AsyncResult<ScannedObject>;
|
|
196
|
+
/** A jobs handler: `queue.work('object-scans', scanner.job)`. */
|
|
197
|
+
readonly job: JobHandler<ObjectScanJob>;
|
|
198
|
+
/** An outbox sink that scans each `object.uploaded` event's object. */
|
|
199
|
+
sink(): EventSink;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* The scan gate for objects outside the attachments table, such as a file
|
|
203
|
+
* drive or avatars: scans an object with the app's `scan` function and
|
|
204
|
+
* records the verdict in `scanned_objects`, which storage policies read with
|
|
205
|
+
* `object_clean(bucket_id, name)`. With `options.scanBuckets`, new objects in
|
|
206
|
+
* those buckets get a pending row and an `object.uploaded` event.
|
|
207
|
+
*/
|
|
208
|
+
export declare function createObjectScanner(options: ObjectScannerOptions): ObjectScanner;
|
|
209
|
+
//#endregion
|
|
210
|
+
export { type Attachment, type AttachmentBucket, type AttachmentDownload, type AttachmentScanJob, type AttachmentScanner, type AttachmentScannerOptions, type AttachmentStatus, type AttachmentStorage, type AttachmentUpload, type Attachments, type AttachmentsOptions, type BlockTransport, type NewAttachment, type ObjectScanJob, type ObjectScanner, type ObjectScannerOptions, type ScanVerdict, type ScannedObject, rpcTransport, sqlTransport };
|