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,718 @@
|
|
|
1
|
+
import { t as DbException } from "./db-exception-CnWcYPxL.js";
|
|
2
|
+
import { c as mapDbError, n as dbError } from "./errors-B11Duf73.js";
|
|
3
|
+
import { n as invalidRequest } from "./build-BXIzE6Xv.js";
|
|
4
|
+
import { t as lookupOf } from "./lookup-BaP5bI27.js";
|
|
5
|
+
import { a as ok, r as err, s as toDbError } from "./result-DzUbqgdW.js";
|
|
6
|
+
import { n as simplifyOrFalse } from "./simplify-DDO0j0LI.js";
|
|
7
|
+
//#region src/compile/sqlite.ts
|
|
8
|
+
/**
|
|
9
|
+
* The operation needs something the SQLite dialect can't express: an
|
|
10
|
+
* include (embedding), full-text search, a function source. Thrown while
|
|
11
|
+
* compiling, before anything runs; executors return it as a `DbError` of
|
|
12
|
+
* kind `unsupported`, with the feature in `details`.
|
|
13
|
+
*/
|
|
14
|
+
function unsupported(feature, table) {
|
|
15
|
+
throw new DbException(dbError("unsupported", `SQLite can't run ${feature} on "${table.key}"; run this query on the server (PostgREST) instead`, {
|
|
16
|
+
table: table.key,
|
|
17
|
+
details: feature
|
|
18
|
+
}));
|
|
19
|
+
}
|
|
20
|
+
function quoteSqliteIdent(name) {
|
|
21
|
+
return `"${name.replaceAll("\"", "\"\"")}"`;
|
|
22
|
+
}
|
|
23
|
+
const TIMESTAMPS = /* @__PURE__ */ new Set(["timestamptz", "timestamp"]);
|
|
24
|
+
const TEXT = /* @__PURE__ */ new Set([
|
|
25
|
+
"text",
|
|
26
|
+
"varchar",
|
|
27
|
+
"bpchar",
|
|
28
|
+
"citext",
|
|
29
|
+
"name"
|
|
30
|
+
]);
|
|
31
|
+
const KEYS_PER_STATEMENT = 500;
|
|
32
|
+
function columnMeta(table, db) {
|
|
33
|
+
return lookupOf(table).byDb.get(db)?.[1];
|
|
34
|
+
}
|
|
35
|
+
function decodeOf(meta, cast) {
|
|
36
|
+
if (!meta) return "raw";
|
|
37
|
+
if (meta.type === "timestamptz") return "timestamptz";
|
|
38
|
+
if (cast === "text") return "raw";
|
|
39
|
+
if (meta.json || meta.array) return "json";
|
|
40
|
+
if (meta.type === "bool") return "boolean";
|
|
41
|
+
return "raw";
|
|
42
|
+
}
|
|
43
|
+
/** A JavaScript value as a SQLite parameter. */
|
|
44
|
+
function sqliteValue(value) {
|
|
45
|
+
if (value === null || value === void 0) return null;
|
|
46
|
+
if (typeof value === "boolean") return value ? 1 : 0;
|
|
47
|
+
if (typeof value === "number" || typeof value === "string") return value;
|
|
48
|
+
if (typeof value === "bigint") return value >= BigInt(Number.MIN_SAFE_INTEGER) && value <= BigInt(Number.MAX_SAFE_INTEGER) ? Number(value) : value;
|
|
49
|
+
return JSON.stringify(value);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* A LIKE pattern (backslash escapes) as a GLOB pattern, which SQLite
|
|
53
|
+
* matches case-sensitively, like Postgres `like`.
|
|
54
|
+
*/
|
|
55
|
+
function likeToGlob(pattern) {
|
|
56
|
+
let out = "";
|
|
57
|
+
for (let index = 0; index < pattern.length; index += 1) {
|
|
58
|
+
const char = pattern[index];
|
|
59
|
+
if (char === "\\" && index + 1 < pattern.length) {
|
|
60
|
+
index += 1;
|
|
61
|
+
out += globLiteral(pattern[index]);
|
|
62
|
+
} else if (char === "%") out += "*";
|
|
63
|
+
else if (char === "_") out += "?";
|
|
64
|
+
else out += globLiteral(char);
|
|
65
|
+
}
|
|
66
|
+
return out;
|
|
67
|
+
}
|
|
68
|
+
function globLiteral(char) {
|
|
69
|
+
return char === "*" || char === "?" || char === "[" ? `[${char}]` : char;
|
|
70
|
+
}
|
|
71
|
+
var SqliteCompiler = class {
|
|
72
|
+
params = [];
|
|
73
|
+
#tableName;
|
|
74
|
+
#aliases = 0;
|
|
75
|
+
constructor(tableName) {
|
|
76
|
+
this.#tableName = tableName;
|
|
77
|
+
}
|
|
78
|
+
alias() {
|
|
79
|
+
const alias = `t${this.#aliases}`;
|
|
80
|
+
this.#aliases += 1;
|
|
81
|
+
return alias;
|
|
82
|
+
}
|
|
83
|
+
table(table) {
|
|
84
|
+
return quoteSqliteIdent(this.#tableName(table));
|
|
85
|
+
}
|
|
86
|
+
param(value) {
|
|
87
|
+
this.params.push(sqliteValue(value));
|
|
88
|
+
return "?";
|
|
89
|
+
}
|
|
90
|
+
column(alias, name) {
|
|
91
|
+
return `${alias}.${quoteSqliteIdent(name)}`;
|
|
92
|
+
}
|
|
93
|
+
/** A column as compared and sorted: timestamps by their instant, not their text. */
|
|
94
|
+
comparable(table, alias, name) {
|
|
95
|
+
const column = this.column(alias, name);
|
|
96
|
+
return TIMESTAMPS.has(columnMeta(table, name)?.type ?? "") ? `julianday(${column})` : column;
|
|
97
|
+
}
|
|
98
|
+
comparableParam(table, name, value) {
|
|
99
|
+
const param = this.param(value);
|
|
100
|
+
return TIMESTAMPS.has(columnMeta(table, name)?.type ?? "") ? `julianday(${param})` : param;
|
|
101
|
+
}
|
|
102
|
+
condition(condition, table, alias) {
|
|
103
|
+
switch (condition.kind) {
|
|
104
|
+
case "and":
|
|
105
|
+
case "or": {
|
|
106
|
+
if (condition.items.length === 0) return condition.kind === "and" ? "1" : "0";
|
|
107
|
+
const joiner = condition.kind === "and" ? " and " : " or ";
|
|
108
|
+
return `(${condition.items.map((item) => this.condition(item, table, alias)).join(joiner)})`;
|
|
109
|
+
}
|
|
110
|
+
case "not": return `not ${this.condition(condition.item, table, alias)}`;
|
|
111
|
+
case "column": return this.columnCondition(condition, table, alias);
|
|
112
|
+
case "relation": {
|
|
113
|
+
const target = this.alias();
|
|
114
|
+
const join = this.join(condition, table, alias, target);
|
|
115
|
+
const where = condition.quantifier === "every" && condition.where ? `not ${this.condition(condition.where, condition.target, target)}` : condition.where ? this.condition(condition.where, condition.target, target) : void 0;
|
|
116
|
+
const body = `select 1 from ${this.table(condition.target)} as ${target} where ${join}${where ? ` and ${where}` : ""}`;
|
|
117
|
+
return condition.quantifier === "some" ? `exists (${body})` : `not exists (${body})`;
|
|
118
|
+
}
|
|
119
|
+
default: return condition;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
join(condition, source, sourceAlias, targetAlias) {
|
|
123
|
+
const { relation, target } = condition;
|
|
124
|
+
if (relation.columns.length !== relation.references.length) invalidRequest(`Relation to "${target.key}" has mismatched columns`);
|
|
125
|
+
return relation.columns.map((column, index) => {
|
|
126
|
+
const reference = relation.references[index];
|
|
127
|
+
return `${this.column(targetAlias, dbName(target, reference))} = ${this.column(sourceAlias, dbName(source, column))}`;
|
|
128
|
+
}).join(" and ");
|
|
129
|
+
}
|
|
130
|
+
columnCondition(condition, table, alias) {
|
|
131
|
+
const name = condition.column;
|
|
132
|
+
if (condition.path) unsupported("a json path filter", table);
|
|
133
|
+
const column = this.comparable(table, alias, name);
|
|
134
|
+
const raw = this.column(alias, name);
|
|
135
|
+
const { value } = condition;
|
|
136
|
+
const operand = () => this.comparableParam(table, name, value);
|
|
137
|
+
switch (condition.op) {
|
|
138
|
+
case "eq": return `${column} = ${operand()}`;
|
|
139
|
+
case "neq": return `${column} <> ${operand()}`;
|
|
140
|
+
case "gt": return `${column} > ${operand()}`;
|
|
141
|
+
case "gte": return `${column} >= ${operand()}`;
|
|
142
|
+
case "lt": return `${column} < ${operand()}`;
|
|
143
|
+
case "lte": return `${column} <= ${operand()}`;
|
|
144
|
+
case "like": return `${raw} glob ${this.param(likeToGlob(String(value)))}`;
|
|
145
|
+
case "ilike": return `${raw} like ${this.param(value)} escape '\\'`;
|
|
146
|
+
case "in":
|
|
147
|
+
if (!Array.isArray(value)) invalidRequest("\"in\" needs an array");
|
|
148
|
+
if (value.length === 0) return "0";
|
|
149
|
+
return `${column} in (${value.map((item) => this.comparableParam(table, name, item)).join(", ")})`;
|
|
150
|
+
case "is":
|
|
151
|
+
if (value === null) return `${raw} is null`;
|
|
152
|
+
if (value === true) return `${raw} is 1`;
|
|
153
|
+
if (value === false) return `${raw} is 0`;
|
|
154
|
+
return invalidRequest("\"is\" needs null, true or false");
|
|
155
|
+
case "contains":
|
|
156
|
+
case "containedBy":
|
|
157
|
+
case "overlaps": return this.jsonCondition(condition.op, table, raw, value);
|
|
158
|
+
case "fts": return unsupported("full-text search", table);
|
|
159
|
+
case "match":
|
|
160
|
+
case "imatch": return unsupported("a regular expression filter", table);
|
|
161
|
+
default: return condition.op;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/** Arrays and jsonb sync to SQLite as JSON text; `json_each` reads them. */
|
|
165
|
+
jsonCondition(op, table, column, value) {
|
|
166
|
+
if (Array.isArray(value)) {
|
|
167
|
+
const distinct = [...new Set(value.map(sqliteValue))];
|
|
168
|
+
if (distinct.some((item) => item === null)) unsupported(`"${op}" with null elements`, table);
|
|
169
|
+
const list = distinct.map((item) => this.param(item)).join(", ");
|
|
170
|
+
switch (op) {
|
|
171
|
+
case "contains": return distinct.length === 0 ? `${column} is not null` : `(select count(distinct value) from json_each(${column}) where value in (${list})) = ${distinct.length}`;
|
|
172
|
+
case "overlaps": return distinct.length === 0 ? "0" : `exists (select 1 from json_each(${column}) where value in (${list}))`;
|
|
173
|
+
case "containedBy": return `(${column} is not null and not exists (select 1 from json_each(${column})${distinct.length === 0 ? "" : ` where value not in (${list})`}))`;
|
|
174
|
+
default: return op;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
if (op !== "contains" || typeof value !== "object" || value === null) return unsupported(`"${op}" on a JSON object`, table);
|
|
178
|
+
const parts = [];
|
|
179
|
+
for (const [key, item] of Object.entries(value)) {
|
|
180
|
+
if (key.includes("\"") || typeof item === "object" && item !== null) unsupported("\"contains\" with a nested JSON value", table);
|
|
181
|
+
parts.push(item === null ? `json_type(${column}, ${this.param(`$."${key}"`)}) = 'null'` : `json_extract(${column}, ${this.param(`$."${key}"`)}) = ${this.param(item)}`);
|
|
182
|
+
}
|
|
183
|
+
return parts.length === 0 ? `${column} is not null` : `(${parts.join(" and ")})`;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* A column as sorted. Postgres sorts text by the database collation, which
|
|
187
|
+
* ignores case at the first level, and enum types by their declared order.
|
|
188
|
+
*/
|
|
189
|
+
sortable(table, alias, name) {
|
|
190
|
+
const meta = columnMeta(table, name);
|
|
191
|
+
const column = this.column(alias, name);
|
|
192
|
+
if (meta?.enum && !TEXT.has(meta.type)) return `case ${column} ${meta.enum.map((value, index) => `when ${this.param(value)} then ${index}`).join(" ")} end`;
|
|
193
|
+
if (meta && TEXT.has(meta.type) && !meta.array && !meta.json) return `${column} collate nocase`;
|
|
194
|
+
return this.comparable(table, alias, name);
|
|
195
|
+
}
|
|
196
|
+
/** Postgres sorts nulls last ascending and first descending; SQLite does the opposite. */
|
|
197
|
+
orderBy(terms, table, alias) {
|
|
198
|
+
return terms.map((term) => {
|
|
199
|
+
if (term.relation) unsupported(`a sort by the relation "${term.relation.name}"`, table);
|
|
200
|
+
const nulls = term.nulls ?? (term.direction === "asc" ? "last" : "first");
|
|
201
|
+
return `${term.aggregate === "count" ? "count(*)" : term.aggregate ? `${term.aggregate}(${this.sortable(table, alias, term.column)})` : this.sortable(table, alias, term.column)} ${term.direction} nulls ${nulls}`;
|
|
202
|
+
}).join(", ");
|
|
203
|
+
}
|
|
204
|
+
selection(selection, table, alias) {
|
|
205
|
+
if (selection.includes.length > 0) {
|
|
206
|
+
const include = selection.includes[0];
|
|
207
|
+
unsupported(include.count === void 0 && include.aggregate === void 0 ? `the include "${include.alias}" (embedding a related table)` : `the related ${include.count === void 0 ? "aggregate" : "count"} "${include.alias}"`, table);
|
|
208
|
+
}
|
|
209
|
+
const items = [];
|
|
210
|
+
const columns = [];
|
|
211
|
+
for (const entry of selection.columns) {
|
|
212
|
+
const meta = columnMeta(table, entry.column);
|
|
213
|
+
const column = this.column(alias, entry.column);
|
|
214
|
+
const decode = decodeOf(meta, entry.cast);
|
|
215
|
+
items.push(`${entry.cast === "text" && decode !== "timestamptz" ? `cast(${column} as text)` : column} as ${quoteSqliteIdent(entry.alias)}`);
|
|
216
|
+
columns.push({
|
|
217
|
+
alias: entry.alias,
|
|
218
|
+
decode
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
if (selection.aggregate) {
|
|
222
|
+
if (selection.aggregate.count) {
|
|
223
|
+
items.push(`count(*) as "_count"`);
|
|
224
|
+
columns.push({
|
|
225
|
+
alias: "_count",
|
|
226
|
+
decode: "raw"
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
for (const measure of selection.aggregate.measures) {
|
|
230
|
+
const meta = columnMeta(table, measure.column);
|
|
231
|
+
const inner = `${measure.fn}(${this.comparable(table, alias, measure.column)})`;
|
|
232
|
+
const timestamp = TIMESTAMPS.has(meta?.type ?? "") && measure.fn !== "avg";
|
|
233
|
+
const expression = timestamp ? `${measure.fn}(${this.column(alias, measure.column)})` : measure.cast === "text" ? `cast(${inner} as text)` : inner;
|
|
234
|
+
items.push(`${expression} as ${quoteSqliteIdent(measure.key)}`);
|
|
235
|
+
columns.push({
|
|
236
|
+
alias: measure.key,
|
|
237
|
+
decode: timestamp && meta?.type === "timestamptz" ? "timestamptz" : "raw"
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
if (items.length === 0) items.push("1 as \"_\"");
|
|
242
|
+
return {
|
|
243
|
+
list: items.join(", "),
|
|
244
|
+
columns
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
function dbName(table, app) {
|
|
249
|
+
const meta = table.columns[app];
|
|
250
|
+
if (!meta) invalidRequest(`Unknown column "${app}" on "${table.key}"`, table.key);
|
|
251
|
+
return meta.db;
|
|
252
|
+
}
|
|
253
|
+
function integer(value) {
|
|
254
|
+
if (!Number.isInteger(value) || value < 0) invalidRequest(`Expected a non-negative integer, got ${value}`);
|
|
255
|
+
return value;
|
|
256
|
+
}
|
|
257
|
+
function whereClause(parts) {
|
|
258
|
+
const present = parts.filter((part) => part !== void 0);
|
|
259
|
+
return present.length > 0 ? ` where ${present.join(" and ")}` : "";
|
|
260
|
+
}
|
|
261
|
+
function keyColumns(table) {
|
|
262
|
+
if (table.primaryKey.length === 0) unsupported("a write to a table without a primary key", table);
|
|
263
|
+
return table.primaryKey.map((app) => dbName(table, app));
|
|
264
|
+
}
|
|
265
|
+
/** `where (a, b) in (values (?, ?), ...)` for a page of keys. */
|
|
266
|
+
function byKeys(compiler, table, alias, keys) {
|
|
267
|
+
const columns = keyColumns(table);
|
|
268
|
+
if (keys.length === 0) return "0";
|
|
269
|
+
if (columns.length === 1) return `${compiler.column(alias, columns[0])} in (${keys.map((key) => compiler.param(key[0])).join(", ")})`;
|
|
270
|
+
return `${`(${columns.map((column) => compiler.column(alias, column)).join(", ")})`} in (values ${keys.map((key) => `(${key.map((value) => compiler.param(value)).join(", ")})`).join(", ")})`;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Compiles IR operations for SQLite (PowerSync's local database). Reads
|
|
274
|
+
* become one statement; writes become steps the executor runs in a write
|
|
275
|
+
* transaction. Throws a `DbException` with kind `unsupported` for what
|
|
276
|
+
* SQLite can't express, before anything runs.
|
|
277
|
+
*/
|
|
278
|
+
function compileSqlite(op, options = {}) {
|
|
279
|
+
const tableName = options.tableName ?? ((table) => table.name);
|
|
280
|
+
const make = () => new SqliteCompiler(tableName);
|
|
281
|
+
if (op.kind === "select" && op.source) unsupported(`the function source "${op.source.name}"`, op.table);
|
|
282
|
+
switch (op.kind) {
|
|
283
|
+
case "select": return selectPlan(make(), op);
|
|
284
|
+
case "insert": return insertPlan(make, op);
|
|
285
|
+
case "update":
|
|
286
|
+
case "delete": return keyedPlan(make, op);
|
|
287
|
+
default: return op;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
function selectPlan(compiler, op) {
|
|
291
|
+
const simple = simplifyOrFalse(op.where);
|
|
292
|
+
if (simple.never) return { kind: "never" };
|
|
293
|
+
const alias = compiler.alias();
|
|
294
|
+
const { list, columns } = compiler.selection(op.selection, op.table, alias);
|
|
295
|
+
const filter = whereClause([simple.condition ? compiler.condition(simple.condition, op.table, alias) : void 0]);
|
|
296
|
+
const from = `${compiler.table(op.table)} as ${alias}`;
|
|
297
|
+
const filterParams = [...compiler.params];
|
|
298
|
+
const count = op.count || op.head ? {
|
|
299
|
+
text: `select count(*) as count from ${from}${filter}`,
|
|
300
|
+
params: filterParams
|
|
301
|
+
} : void 0;
|
|
302
|
+
if (op.head) return {
|
|
303
|
+
kind: "select",
|
|
304
|
+
rows: void 0,
|
|
305
|
+
count,
|
|
306
|
+
columns: []
|
|
307
|
+
};
|
|
308
|
+
return {
|
|
309
|
+
kind: "select",
|
|
310
|
+
rows: {
|
|
311
|
+
text: `select ${list} from ${from}${filter}${op.selection.aggregate && op.selection.columns.length > 0 ? ` group by ${op.selection.columns.map((entry) => compiler.column(alias, entry.column)).join(", ")}` : ""}${op.orderBy.length > 0 ? ` order by ${compiler.orderBy(op.orderBy, op.table, alias)}` : ""}${op.limit === void 0 ? op.offset === void 0 ? "" : " limit -1" : ` limit ${integer(op.limit)}`}${op.offset === void 0 ? "" : ` offset ${integer(op.offset)}`}`,
|
|
312
|
+
params: compiler.params
|
|
313
|
+
},
|
|
314
|
+
count,
|
|
315
|
+
columns
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
function returning(make, op) {
|
|
319
|
+
if (!op.returning) return void 0;
|
|
320
|
+
const columns = make().selection(op.returning, op.table, "t0").columns;
|
|
321
|
+
const selection = op.returning;
|
|
322
|
+
return {
|
|
323
|
+
columns,
|
|
324
|
+
read: (keys) => {
|
|
325
|
+
const compiler = make();
|
|
326
|
+
const alias = compiler.alias();
|
|
327
|
+
const { list } = compiler.selection(selection, op.table, alias);
|
|
328
|
+
return {
|
|
329
|
+
text: `select ${list} from ${compiler.table(op.table)} as ${alias} where ${byKeys(compiler, op.table, alias, keys)}`,
|
|
330
|
+
params: compiler.params
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
function insertPlan(make, op) {
|
|
336
|
+
if (op.rows.length === 0) return { kind: "never" };
|
|
337
|
+
const keys = keyColumns(op.table);
|
|
338
|
+
const columns = /* @__PURE__ */ new Set();
|
|
339
|
+
for (const row of op.rows) for (const key of Object.keys(row)) columns.add(key);
|
|
340
|
+
const ordered = [...columns];
|
|
341
|
+
const conflict = op.onConflict;
|
|
342
|
+
const tenant = op.table.flags.tenant;
|
|
343
|
+
const tenantColumn = tenant === void 0 ? void 0 : op.table.columns[tenant]?.db;
|
|
344
|
+
return {
|
|
345
|
+
kind: "insert",
|
|
346
|
+
rows: op.rows.map((row) => {
|
|
347
|
+
const missing = keys.filter((key) => row[key] === void 0);
|
|
348
|
+
if (missing.length > 0) invalidRequest(`Insert into "${op.table.key}" needs ${missing.join(", ")}: SQLite has no column defaults for keys`, op.table.key);
|
|
349
|
+
const own = ordered.filter((column) => column in row || op.defaultToNull);
|
|
350
|
+
const insertCompiler = make();
|
|
351
|
+
const values = own.map((column) => insertCompiler.param(row[column] ?? null));
|
|
352
|
+
const insert = {
|
|
353
|
+
text: own.length === 0 ? `insert into ${insertCompiler.table(op.table)} default values` : `insert into ${insertCompiler.table(op.table)} (${own.map(quoteSqliteIdent).join(", ")}) values (${values.join(", ")})`,
|
|
354
|
+
params: insertCompiler.params
|
|
355
|
+
};
|
|
356
|
+
let existing;
|
|
357
|
+
let update;
|
|
358
|
+
if (conflict) {
|
|
359
|
+
const find = make();
|
|
360
|
+
const alias = find.alias();
|
|
361
|
+
const match = conflict.columns.map((column) => `${find.column(alias, column)} = ${find.param(row[column] ?? null)}`).join(" and ");
|
|
362
|
+
existing = {
|
|
363
|
+
text: `select ${keys.map((key) => find.column(alias, key)).join(", ")}${tenantColumn ? `, ${find.column(alias, tenantColumn)} as "_tenant"` : ""} from ${find.table(op.table)} as ${alias} where ${match} limit 1`,
|
|
364
|
+
params: find.params
|
|
365
|
+
};
|
|
366
|
+
const sets = own.filter((column) => !conflict.columns.includes(column) && !keys.includes(column));
|
|
367
|
+
if (conflict.action === "update" && sets.length > 0) update = (key) => {
|
|
368
|
+
const compiler = make();
|
|
369
|
+
const alias = compiler.alias();
|
|
370
|
+
const set = sets.map((column) => `${quoteSqliteIdent(column)} = ${compiler.param(row[column] ?? null)}`).join(", ");
|
|
371
|
+
const where = byKeys(compiler, op.table, alias, [key]);
|
|
372
|
+
return {
|
|
373
|
+
text: `update ${compiler.table(op.table)} as ${alias} set ${set} where ${where}`,
|
|
374
|
+
params: compiler.params
|
|
375
|
+
};
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
return {
|
|
379
|
+
key: keys.map((key) => sqliteValue(row[key])),
|
|
380
|
+
tenant: tenantColumn === void 0 ? void 0 : sqliteValue(row[tenantColumn]),
|
|
381
|
+
insert,
|
|
382
|
+
existing,
|
|
383
|
+
update
|
|
384
|
+
};
|
|
385
|
+
}),
|
|
386
|
+
conflict: conflict?.action,
|
|
387
|
+
returning: returning(make, op)
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
function keyedPlan(make, op) {
|
|
391
|
+
const simple = simplifyOrFalse(op.where);
|
|
392
|
+
if (simple.never) return { kind: "never" };
|
|
393
|
+
const { maxAffected } = op;
|
|
394
|
+
if (maxAffected !== void 0 && (!Number.isInteger(maxAffected) || maxAffected < 0)) invalidRequest(`"maxAffected" must be a non-negative integer, got ${maxAffected}`, op.table.key);
|
|
395
|
+
const keys = keyColumns(op.table);
|
|
396
|
+
const compiler = make();
|
|
397
|
+
const alias = compiler.alias();
|
|
398
|
+
const where = simple.condition ? compiler.condition(simple.condition, op.table, alias) : void 0;
|
|
399
|
+
const select = {
|
|
400
|
+
text: `select ${keys.map((key) => compiler.column(alias, key)).join(", ")} from ${compiler.table(op.table)} as ${alias}${whereClause([where])}`,
|
|
401
|
+
params: compiler.params
|
|
402
|
+
};
|
|
403
|
+
let set = [];
|
|
404
|
+
if (op.kind === "update") {
|
|
405
|
+
set = Object.entries(op.set);
|
|
406
|
+
if (set.length === 0) invalidRequest(`Update on "${op.table.key}" sets no columns`);
|
|
407
|
+
}
|
|
408
|
+
return {
|
|
409
|
+
kind: op.kind,
|
|
410
|
+
keys: select,
|
|
411
|
+
apply: (rows) => {
|
|
412
|
+
const own = make();
|
|
413
|
+
const ownAlias = own.alias();
|
|
414
|
+
const assignments = set.map(([column, value]) => `${quoteSqliteIdent(column)} = ${own.param(value)}`).join(", ");
|
|
415
|
+
const target = byKeys(own, op.table, ownAlias, rows);
|
|
416
|
+
return {
|
|
417
|
+
text: op.kind === "update" ? `update ${own.table(op.table)} as ${ownAlias} set ${assignments} where ${target}` : `delete from ${own.table(op.table)} as ${ownAlias} where ${target}`,
|
|
418
|
+
params: own.params
|
|
419
|
+
};
|
|
420
|
+
},
|
|
421
|
+
returning: returning(make, op),
|
|
422
|
+
...maxAffected === void 0 ? {} : { maxAffected }
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
/** Splits keys into pages that stay under SQLite's parameter limit. */
|
|
426
|
+
function keyPages(keys) {
|
|
427
|
+
const pages = [];
|
|
428
|
+
for (let start = 0; start < keys.length; start += KEYS_PER_STATEMENT) pages.push(keys.slice(start, start + KEYS_PER_STATEMENT));
|
|
429
|
+
return pages;
|
|
430
|
+
}
|
|
431
|
+
//#endregion
|
|
432
|
+
//#region src/powersync/compiler.ts
|
|
433
|
+
const sqliteCompiler = {
|
|
434
|
+
target: "sqlite",
|
|
435
|
+
compile: (op) => compileSqlite(op)
|
|
436
|
+
};
|
|
437
|
+
/**
|
|
438
|
+
* Compiles every operation a list definition runs (the page, its count and
|
|
439
|
+
* the facet counts) for SQLite, without a database. Returns the first
|
|
440
|
+
* `unsupported` or `invalid_request` error, so a test or a dev build fails
|
|
441
|
+
* before a native screen does.
|
|
442
|
+
*
|
|
443
|
+
* ```ts
|
|
444
|
+
* expect(await checkSqlite(betterSupabase, customerList)).toEqual({ ok: true, data: undefined });
|
|
445
|
+
* ```
|
|
446
|
+
*/
|
|
447
|
+
async function checkSqlite(betterSupabase, list, options = {}) {
|
|
448
|
+
let failure;
|
|
449
|
+
const probe = {
|
|
450
|
+
name: "sqlite-check",
|
|
451
|
+
execute(op) {
|
|
452
|
+
try {
|
|
453
|
+
compileSqlite(op, options);
|
|
454
|
+
} catch (cause) {
|
|
455
|
+
failure ??= toDbError(cause);
|
|
456
|
+
return Promise.resolve(err(failure));
|
|
457
|
+
}
|
|
458
|
+
return Promise.resolve(ok({
|
|
459
|
+
rows: [],
|
|
460
|
+
count: 0
|
|
461
|
+
}));
|
|
462
|
+
}
|
|
463
|
+
};
|
|
464
|
+
const facets = {};
|
|
465
|
+
for (const facet of list.facets) facets[facet.key] = [facet.values?.[0] ?? "x"];
|
|
466
|
+
const query = {
|
|
467
|
+
...list.defaults,
|
|
468
|
+
q: "x",
|
|
469
|
+
facets
|
|
470
|
+
};
|
|
471
|
+
const db = betterSupabase.connect(probe);
|
|
472
|
+
await list.run(db, query);
|
|
473
|
+
return failure ? err(failure) : ok(void 0);
|
|
474
|
+
}
|
|
475
|
+
//#endregion
|
|
476
|
+
//#region src/powersync/executor.ts
|
|
477
|
+
const UNIQUE = /(?:UNIQUE|PRIMARY KEY) constraint failed: (.+)$/m;
|
|
478
|
+
const NOT_NULL = /NOT NULL constraint failed: (?:[^.\s]+\.)?(\S+)/;
|
|
479
|
+
const CHECK = /CHECK constraint failed: ?(\S+)?/;
|
|
480
|
+
const unqualified = (column) => column.trim().replace(/^[^.]+\./, "");
|
|
481
|
+
/**
|
|
482
|
+
* A SQLite constraint error in the shape `mapDbError` reads from Postgres:
|
|
483
|
+
* its SQLSTATE, and the columns in Postgres's `Key (...)` detail format.
|
|
484
|
+
*/
|
|
485
|
+
function fromSqliteError(cause) {
|
|
486
|
+
if (!(cause instanceof Error)) return void 0;
|
|
487
|
+
const message = cause.message;
|
|
488
|
+
const unique = UNIQUE.exec(message);
|
|
489
|
+
if (unique?.[1]) return {
|
|
490
|
+
code: "23505",
|
|
491
|
+
message,
|
|
492
|
+
details: `Key (${unique[1].split(",").map(unqualified).join(", ")})=(...) already exists.`
|
|
493
|
+
};
|
|
494
|
+
if (message.includes("FOREIGN KEY constraint failed")) return {
|
|
495
|
+
code: "23503",
|
|
496
|
+
message
|
|
497
|
+
};
|
|
498
|
+
const notNull = NOT_NULL.exec(message);
|
|
499
|
+
if (notNull?.[1]) return {
|
|
500
|
+
code: "23502",
|
|
501
|
+
message,
|
|
502
|
+
column: notNull[1]
|
|
503
|
+
};
|
|
504
|
+
const check = CHECK.exec(message);
|
|
505
|
+
if (check) return {
|
|
506
|
+
code: "23514",
|
|
507
|
+
message,
|
|
508
|
+
...check[1] ? { constraint: check[1] } : {}
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
const TIMESTAMP = /^(\d{4,}-\d{2}-\d{2})[Tt ](\d{2}:\d{2}:\d{2})(?:\.(\d+))?(Z|z|[+-]\d{2}(?::?\d{2})?)?$/;
|
|
512
|
+
/**
|
|
513
|
+
* Timestamp text as PostgREST sends it (`2026-01-02T10:00:00.5+00:00`), from
|
|
514
|
+
* whatever the sync wrote (`2026-01-02 10:00:00.500000Z`).
|
|
515
|
+
*/
|
|
516
|
+
function postgrestTimestamp(value) {
|
|
517
|
+
const match = TIMESTAMP.exec(value);
|
|
518
|
+
if (!match) return value;
|
|
519
|
+
const [, date, time, fraction, zone] = match;
|
|
520
|
+
const trimmed = fraction?.replace(/0+$/, "");
|
|
521
|
+
let offset = "+00:00";
|
|
522
|
+
if (zone && zone !== "Z" && zone !== "z") {
|
|
523
|
+
const digits = zone.replace(":", "");
|
|
524
|
+
offset = `${digits.slice(0, 3)}:${digits.slice(3, 5) || "00"}`;
|
|
525
|
+
}
|
|
526
|
+
return `${date}T${time}${trimmed ? `.${trimmed}` : ""}${offset}`;
|
|
527
|
+
}
|
|
528
|
+
function decodeValue(column, value) {
|
|
529
|
+
if (value === null || value === void 0) return null;
|
|
530
|
+
switch (column.decode) {
|
|
531
|
+
case "boolean": return value === 1 || value === true || value === "1" || value === "true";
|
|
532
|
+
case "json":
|
|
533
|
+
if (typeof value !== "string") return value;
|
|
534
|
+
try {
|
|
535
|
+
return JSON.parse(value);
|
|
536
|
+
} catch {
|
|
537
|
+
return value;
|
|
538
|
+
}
|
|
539
|
+
case "timestamptz": return typeof value === "string" ? postgrestTimestamp(value) : value;
|
|
540
|
+
case "raw":
|
|
541
|
+
if (typeof value !== "bigint") return value;
|
|
542
|
+
return value >= Number.MIN_SAFE_INTEGER && value <= Number.MAX_SAFE_INTEGER ? Number(value) : value.toString();
|
|
543
|
+
default: return column.decode;
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
function decode(rows, columns) {
|
|
547
|
+
return rows.map((row) => {
|
|
548
|
+
const out = {};
|
|
549
|
+
for (const column of columns) out[column.alias] = decodeValue(column, row[column.alias]);
|
|
550
|
+
return out;
|
|
551
|
+
});
|
|
552
|
+
}
|
|
553
|
+
async function all(context, query) {
|
|
554
|
+
return context.getAll(query.text, [...query.params]);
|
|
555
|
+
}
|
|
556
|
+
function keyValue(value) {
|
|
557
|
+
if (value === null || value === void 0) return null;
|
|
558
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "bigint") return value;
|
|
559
|
+
return String(value);
|
|
560
|
+
}
|
|
561
|
+
async function keysOf(context, query) {
|
|
562
|
+
return (await all(context, query)).map((row) => Object.values(row).map(keyValue));
|
|
563
|
+
}
|
|
564
|
+
async function readBack(context, plan, keys) {
|
|
565
|
+
if (!plan.returning) return [];
|
|
566
|
+
const rows = [];
|
|
567
|
+
for (const page of keyPages(keys)) rows.push(...await all(context, plan.returning.read(page)));
|
|
568
|
+
return decode(rows, plan.returning.columns);
|
|
569
|
+
}
|
|
570
|
+
async function runInsert(tx, plan) {
|
|
571
|
+
const written = [];
|
|
572
|
+
for (const row of plan.rows) {
|
|
573
|
+
const [found] = row.existing ? await all(tx, row.existing) : [];
|
|
574
|
+
if (found) {
|
|
575
|
+
const { _tenant: tenant, ...key } = found;
|
|
576
|
+
const otherTenant = row.tenant !== void 0 && tenant !== row.tenant;
|
|
577
|
+
if (plan.conflict === "ignore" || otherTenant || !row.update) continue;
|
|
578
|
+
const existingKey = Object.values(key).map(keyValue);
|
|
579
|
+
const statement = row.update(existingKey);
|
|
580
|
+
await tx.execute(statement.text, [...statement.params]);
|
|
581
|
+
written.push(existingKey);
|
|
582
|
+
continue;
|
|
583
|
+
}
|
|
584
|
+
await tx.execute(row.insert.text, [...row.insert.params]);
|
|
585
|
+
written.push(row.key);
|
|
586
|
+
}
|
|
587
|
+
return {
|
|
588
|
+
rows: await readBack(tx, plan, written),
|
|
589
|
+
count: written.length
|
|
590
|
+
};
|
|
591
|
+
}
|
|
592
|
+
/** Thrown inside the write transaction so it rolls back; mapped to `max_affected`. */
|
|
593
|
+
var MaxAffected = class extends Error {
|
|
594
|
+
error;
|
|
595
|
+
constructor(affected, maxAffected) {
|
|
596
|
+
const message = `The write affects ${affected} rows, more than maxAffected (${maxAffected}) allows`;
|
|
597
|
+
super(message);
|
|
598
|
+
this.error = dbError("max_affected", message, { maxAffected });
|
|
599
|
+
}
|
|
600
|
+
};
|
|
601
|
+
async function runKeyed(tx, plan) {
|
|
602
|
+
const keys = await keysOf(tx, plan.keys);
|
|
603
|
+
if (keys.length === 0) return {
|
|
604
|
+
rows: [],
|
|
605
|
+
count: 0
|
|
606
|
+
};
|
|
607
|
+
if (plan.maxAffected !== void 0 && keys.length > plan.maxAffected) throw new MaxAffected(keys.length, plan.maxAffected);
|
|
608
|
+
const before = plan.kind === "delete" ? await readBack(tx, plan, keys) : void 0;
|
|
609
|
+
for (const page of keyPages(keys)) {
|
|
610
|
+
const statement = plan.apply(page);
|
|
611
|
+
await tx.execute(statement.text, [...statement.params]);
|
|
612
|
+
}
|
|
613
|
+
return {
|
|
614
|
+
rows: before ?? await readBack(tx, plan, keys),
|
|
615
|
+
count: keys.length
|
|
616
|
+
};
|
|
617
|
+
}
|
|
618
|
+
async function runSelect(context, plan) {
|
|
619
|
+
const [rows, counted] = await Promise.all([plan.rows ? all(context, plan.rows) : [], plan.count ? all(context, plan.count) : void 0]);
|
|
620
|
+
return {
|
|
621
|
+
rows: decode(rows, plan.columns),
|
|
622
|
+
count: counted ? Number(counted[0]?.["count"] ?? 0) : null
|
|
623
|
+
};
|
|
624
|
+
}
|
|
625
|
+
async function run(db, plan) {
|
|
626
|
+
switch (plan.kind) {
|
|
627
|
+
case "select": return plan.rows && plan.count && db.readTransaction ? db.readTransaction((tx) => runSelect(tx, plan)) : runSelect(db, plan);
|
|
628
|
+
case "insert": return db.writeTransaction((tx) => runInsert(tx, plan));
|
|
629
|
+
case "update":
|
|
630
|
+
case "delete": return db.writeTransaction((tx) => runKeyed(tx, plan));
|
|
631
|
+
default: return plan;
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
/** Hermes has no `crypto` unless the app installs a polyfill. */
|
|
635
|
+
function randomId() {
|
|
636
|
+
const { crypto } = globalThis;
|
|
637
|
+
return crypto?.randomUUID?.();
|
|
638
|
+
}
|
|
639
|
+
/** Inserts with a missing single-column key get one, as PowerSync needs. */
|
|
640
|
+
async function withIds(db, op, newId) {
|
|
641
|
+
const [key, ...rest] = op.table.primaryKey;
|
|
642
|
+
if (key === void 0 || rest.length > 0) return op;
|
|
643
|
+
const column = op.table.columns[key];
|
|
644
|
+
if (!column || column.type !== "uuid" && column.type !== "text") return op;
|
|
645
|
+
if (op.rows.every((row) => row[column.db] !== void 0)) return op;
|
|
646
|
+
const next = async () => {
|
|
647
|
+
if (newId) return newId(op.table);
|
|
648
|
+
const random = randomId();
|
|
649
|
+
if (random !== void 0) return random;
|
|
650
|
+
const [row] = await db.getAll("select uuid() as id");
|
|
651
|
+
if (!row) throw new TypeError("select uuid() returned no row");
|
|
652
|
+
return row.id;
|
|
653
|
+
};
|
|
654
|
+
const rows = [];
|
|
655
|
+
for (const row of op.rows) rows.push(row[column.db] === void 0 ? {
|
|
656
|
+
...row,
|
|
657
|
+
[column.db]: await next()
|
|
658
|
+
} : row);
|
|
659
|
+
return {
|
|
660
|
+
...op,
|
|
661
|
+
rows
|
|
662
|
+
};
|
|
663
|
+
}
|
|
664
|
+
async function executeOn(db, op, context, options) {
|
|
665
|
+
const aborted = () => context.signal?.aborted === true;
|
|
666
|
+
if (aborted()) return err(dbError("aborted", "The request was aborted"));
|
|
667
|
+
let plan;
|
|
668
|
+
try {
|
|
669
|
+
plan = compileSqlite(op.kind === "insert" ? await withIds(db, op, options.newId) : op, options);
|
|
670
|
+
} catch (cause) {
|
|
671
|
+
return err(toDbError(cause));
|
|
672
|
+
}
|
|
673
|
+
if (plan.kind === "never") return ok({
|
|
674
|
+
rows: [],
|
|
675
|
+
count: 0
|
|
676
|
+
});
|
|
677
|
+
if (aborted()) return err(dbError("aborted", "The request was aborted"));
|
|
678
|
+
let result;
|
|
679
|
+
try {
|
|
680
|
+
result = await run(db, plan);
|
|
681
|
+
} catch (cause) {
|
|
682
|
+
return err(mapped(cause, context.errorMappers));
|
|
683
|
+
}
|
|
684
|
+
if (op.kind === "select" && op.single) {
|
|
685
|
+
if (result.rows.length > 1) return err(dbError("multiple_rows", `Expected one ${op.table.key} row`));
|
|
686
|
+
if (result.rows.length === 0 && op.single === "one") return err(dbError("not_found", `No ${op.table.key} row matched`));
|
|
687
|
+
}
|
|
688
|
+
return ok(result);
|
|
689
|
+
}
|
|
690
|
+
function mapped(cause, mappers) {
|
|
691
|
+
if (cause instanceof MaxAffected) return cause.error;
|
|
692
|
+
const raw = fromSqliteError(cause);
|
|
693
|
+
return raw ? mapDbError(raw, mappers) : toDbError(cause);
|
|
694
|
+
}
|
|
695
|
+
/**
|
|
696
|
+
* Runs repository operations on PowerSync's local SQLite database, so the
|
|
697
|
+
* same repositories and list definitions work offline on native. Reads
|
|
698
|
+
* return rows in the PostgREST shape (booleans, parsed JSON, ISO
|
|
699
|
+
* timestamps); writes go through PowerSync's upload queue. What SQLite
|
|
700
|
+
* can't express (includes, full-text search, function sources) returns a
|
|
701
|
+
* `DbError` of kind `unsupported` without running anything.
|
|
702
|
+
* `maxAffected` is checked against the selected keys before any write; a
|
|
703
|
+
* call's `timeout` and `signal` are checked before the statements start,
|
|
704
|
+
* and `retry` does nothing here. A `bigint` beyond `Number.MAX_SAFE_INTEGER`
|
|
705
|
+
* comes back as its decimal string instead of a rounded number.
|
|
706
|
+
*
|
|
707
|
+
* ```ts
|
|
708
|
+
* const db = betterSupabase.connect(powersyncExecutor(powersync));
|
|
709
|
+
* ```
|
|
710
|
+
*/
|
|
711
|
+
function powersyncExecutor(db, options = {}) {
|
|
712
|
+
return {
|
|
713
|
+
name: "powersync",
|
|
714
|
+
execute: (op, context) => executeOn(db, op, context, options)
|
|
715
|
+
};
|
|
716
|
+
}
|
|
717
|
+
//#endregion
|
|
718
|
+
export { sqliteCompiler as a, quoteSqliteIdent as c, checkSqlite as i, sqliteValue as l, postgrestTimestamp as n, compileSqlite as o, powersyncExecutor as r, likeToGlob as s, fromSqliteError as t };
|