permdock 0.5.0 → 0.7.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 +1 -0
- package/dist/{2020-C9VN-x8c.js → 2020-CJbO8Bvz.js} +1 -3
- package/dist/a2a/index.d.ts +5 -5
- package/dist/a2a/index.js +4 -4
- package/dist/{adoption-scan-B4R5fnMU.js → adoption-scan-D-feE7BE.js} +1 -1
- package/dist/agent/index.d.ts +3 -3
- package/dist/agent/index.js +1 -1
- package/dist/ai-sdk/index.d.ts +21 -6
- package/dist/ai-sdk/index.js +19 -9
- package/dist/{approval-prompt-Djo_PyZc.d.ts → approval-prompt-K0faOLFp.d.ts} +2 -2
- package/dist/approvals/index.d.ts +4 -4
- package/dist/approvals/index.js +4 -4
- package/dist/{approvals-DJ6Yd5z1.js → approvals-CMRfsbBh.js} +74 -48
- package/dist/{arazzo-B6lebmiQ.js → arazzo-ClrF3PVb.js} +2 -2
- package/dist/{arazzo-BWhNF-k0.js → arazzo-rdeJ8n1J.js} +4 -4
- package/dist/{args-IIolxxKA.js → args-CC3OwyHW.js} +112 -2
- package/dist/astro/index.d.ts +6 -6
- package/dist/astro/index.js +2 -2
- package/dist/{audience-Dg8XsRaO.js → audience-BrMs8c4o.js} +1 -1
- package/dist/{auth-DRLEizbL.js → auth-CscUX8Sy.js} +3 -4
- package/dist/authzen/index.d.ts +162 -22
- package/dist/authzen/index.js +315 -146
- package/dist/{automation-BMZPIVUM.d.ts → automation-DOtAFWdy.d.ts} +3 -3
- package/dist/{automation-DVjOckjV.js → automation-ySsxp_Yp.js} +1 -1
- package/dist/base-url-BQbddZO5.js +9 -0
- package/dist/better-auth/index.d.ts +2 -2
- package/dist/better-auth/index.js +2 -2
- package/dist/better-supabase/index.d.ts +50 -8
- package/dist/better-supabase/index.js +94 -32
- package/dist/{bind-CZzhx-Vj.js → bind-D1nO6fiC.js} +5 -5
- package/dist/{bind--9EFVYWF.d.ts → bind-JDuvxjuW.d.ts} +7 -7
- package/dist/{build-instance-BMnAudHn.js → build-instance-DxE7czo9.js} +1 -1
- package/dist/{canonical-json-BC8_nMTw.js → canonical-json-DwilZ1iB.js} +6 -3
- package/dist/{capability-BSslw1QV.d.ts → capability-D4UC9TTW.d.ts} +2 -2
- package/dist/{capability-N1K9IpqS.js → capability-L7NnfhiE.js} +1 -1
- package/dist/{casbin-Cr7RLtA3.js → casbin-BHijLuHY.js} +2 -2
- package/dist/{casbin-Dyu2gnUD.js → casbin-BW9pS47J.js} +1 -1
- package/dist/{casl-64gpT-8x.js → casl-CmJlgziS.js} +2 -2
- package/dist/{casl-DjEDhTCP.js → casl-UbI8v-Wq.js} +1 -1
- package/dist/catalog/index.d.ts +70 -10
- package/dist/catalog/index.js +112 -6
- package/dist/catalog-BCCjSAdH.js +1 -0
- package/dist/{catalog-R_A__RsH.js → catalog-BaMQfQ6Y.js} +3 -3
- package/dist/{catalog-BECMPrwc.js → catalog-D69WhFii.js} +43 -13
- package/dist/{catalog-doc-C9wjsfNY.js → catalog-doc-CV9s6B1S.js} +28 -5
- package/dist/{catalog-fingerprint-CCP0-yQS.js → catalog-fingerprint-C144oW4M.js} +1 -1
- package/dist/{create-BWRSXgOF.js → challenge-nGWma08S.js} +122 -25
- package/dist/chat/index.d.ts +1 -1
- package/dist/chat/index.js +2 -2
- package/dist/chat-sdk/index.d.ts +3 -3
- package/dist/checks-BC_0mPIq.js +37 -0
- package/dist/claude-agent/index.d.ts +3 -3
- package/dist/claude-agent/index.js +2 -2
- package/dist/clerk/index.d.ts +3 -3
- package/dist/clerk/index.js +1 -1
- package/dist/cli/bin.js +2 -2
- package/dist/cli/index.d.ts +3 -3
- package/dist/cli/index.js +3 -3
- package/dist/cloud/index.d.ts +127 -11
- package/dist/cloud/index.js +251 -3
- package/dist/{cloud-CIoHNevm.js → cloud-CO8pYtwr.js} +5 -5
- package/dist/{codemod-Cxvvc70T.js → codemod-BP6n8N9L.js} +3 -3
- package/dist/{codemod-Bmj9dWMH.js → codemod-i4N2BhDc.js} +3 -3
- package/dist/{collect-CrZJJnEF.js → collect-BaWeMjwV.js} +17 -8
- package/dist/{collect-DloHbDVa.js → collect-DNm3oKOk.js} +6 -5
- package/dist/collect-k_Dulxr5.js +1 -0
- package/dist/compile/index.d.ts +1 -1
- package/dist/compile/index.js +1 -1
- package/dist/{compile-CMqMx_IN.js → compile-BAEO5bOk.js} +2 -2
- package/dist/{compile-Ckm2HqBZ.d.ts → compile-COM2VKuN.d.ts} +3 -3
- package/dist/{completion-BqhRBJD8.js → completion-BNdVf7X2.js} +3 -3
- package/dist/{config-bs_kZeYq.js → config-CoQHDrDi.js} +7 -3
- package/dist/{config-B46rm9sc.js → config-DGZzMV1B.js} +2 -2
- package/dist/{config-report-DUgj62Ai.js → config-report-Cm7UITNA.js} +3 -3
- package/dist/connector-schema-_VCSsdtD.js +433 -0
- package/dist/{context-bbFHR-0D.js → context--uM9V3Ui.js} +2 -2
- package/dist/convex/index.d.ts +5 -5
- package/dist/convex/index.js +2 -2
- package/dist/core-B5-w6Kw9.js +335 -0
- package/dist/core-CQkE8Esr.d.ts +179 -0
- package/dist/{create-0VZ7Pdiu.d.ts → create-B2-CQqCI.d.ts} +5 -5
- package/dist/{create-C3b4B5eF.js → create-Cb86Z8Im.js} +9 -8
- package/dist/{create-DnrmLnLW.js → create-DJrlhEp9.js} +5 -5
- package/dist/{create-BFfm17UA.d.ts → create-QHuuPw3q.d.ts} +7 -7
- package/dist/{create-BDS7wc3y.d.ts → create-UTnUVETj.d.ts} +30 -10
- package/dist/{credential-DM2um3ha.js → credential-CIM7wHwA.js} +4 -4
- package/dist/{credentials-DPyHmYz5.js → credentials-BpuTwd7a.js} +1 -1
- package/dist/{deciding-columns-Sq12mEA6.js → deciding-columns-DRo2QM6E.js} +13 -2
- package/dist/{delegation-DaXVdDhM.js → delegation-C5rOdTp5.js} +5 -5
- package/dist/delivery/index.d.ts +5 -5
- package/dist/delivery/index.js +4 -3
- package/dist/{delivery-DCAgNyCn.js → delivery-rwOKLWRm.js} +51 -2
- package/dist/{denied-text-D8jDHgsl.d.ts → denied-text-D4qkEtFz.d.ts} +2 -2
- package/dist/{describe-BybMRY7A.js → describe-DZlnEtLy.js} +1 -0
- package/dist/{describe-BZUsixiL.d.ts → describe-O0SwYIK8.d.ts} +2 -2
- package/dist/{diff-CxZo9pTq.js → diff-Btr1c1Ow.js} +2 -2
- package/dist/{diff-DCePiN6M.js → diff-DzT-xD13.js} +10 -10
- package/dist/{doctor-DFjUxf2f.js → doctor-BU1szn63.js} +241 -49
- package/dist/{doctor-CxiwSfqH.js → doctor-BoK_y0KO.js} +4 -4
- package/dist/drizzle/index.d.ts +3 -3
- package/dist/drizzle/index.js +1 -1
- package/dist/elysia/index.d.ts +5 -5
- package/dist/elysia/index.js +3 -3
- package/dist/{errors-C2PXIv4c.d.ts → errors-B_Qg9D3e.d.ts} +2 -2
- package/dist/{errors-CWTY6uih.js → errors-DpP_U6Bf.js} +1 -0
- package/dist/{evaluate-_R8QkWaf.js → evaluate-B_oqFbWC.js} +130 -34
- package/dist/{evaluations-16UqqQ6W.d.ts → evaluations-BCddEOfO.d.ts} +4 -4
- package/dist/{evaluations-DZ2CbV5k.js → evaluations-DReoiVBw.js} +4 -4
- package/dist/eve/index.d.ts +5 -5
- package/dist/eve/index.js +3 -3
- package/dist/express/index.d.ts +5 -5
- package/dist/express/index.js +3 -3
- package/dist/fastify/index.d.ts +5 -5
- package/dist/fastify/index.js +3 -3
- package/dist/{fetch-adapter-qKJBuRqy.d.ts → fetch-adapter-CuhyYwC1.d.ts} +4 -4
- package/dist/{fetch-adapter-g0ypLkID.js → fetch-adapter-De-u6vhJ.js} +3 -3
- package/dist/{fields-D9tPVUUS.js → fields-ClcQLrVc.js} +48 -13
- package/dist/{files-C5ZI27eV.js → files-acUbNwWt.js} +15 -2
- package/dist/{fixtures-B7XrLeY7.js → fixtures-BTMW6zgU.js} +2 -2
- package/dist/{flags-C3DktBDY.js → flags-aaeRAdiD.js} +2 -2
- package/dist/{from-snapshot-D2lZt4Dd.js → from-snapshot-Bz469dIh.js} +17 -10
- package/dist/generate-3FNO5P5Q.js +159 -0
- package/dist/{grantee-Cn1HyUsI.js → grantee-BrRANrpT.js} +14 -4
- package/dist/{grantee-conditions-CcXf8hMM.js → grantee-conditions-C6P1Tvol.js} +1 -1
- package/dist/{grantee-match-DHArqY82.js → grantee-match-0RtHWQDx.js} +3 -3
- package/dist/h3/index.d.ts +4 -4
- package/dist/h3/index.js +3 -3
- package/dist/{helpers-DTcZOzhF.js → helpers-DY3vXuGs.js} +3 -3
- package/dist/hono/index.d.ts +5 -5
- package/dist/hono/index.js +3 -3
- package/dist/{hosted-DBDX0M-P.d.ts → hosted-BmjzxQhp.d.ts} +14 -2
- package/dist/{hosted-BZIAYvon.js → hosted-XBgU6RGT.js} +34 -12
- package/dist/{http-DXJ37RDA.js → http-Ca3Sr5x1.js} +1 -1
- package/dist/{import-DMmOG27O.js → import-Bz0GefWg.js} +5 -5
- package/dist/{import-CNV7I2Dw.js → import-DB2EG_iy.js} +3 -3
- package/dist/{index-CxGUswIC.d.ts → index-BE8y3moU.d.ts} +50 -8
- package/dist/{index-Chrs5fQ-.d.ts → index-BSfRl0hZ.d.ts} +6 -6
- package/dist/{index-DOVf7RJv.d.ts → index-BTkwrK7v.d.ts} +155 -17
- package/dist/index-CMiPH2Tv.d.ts +206 -0
- package/dist/{index-SGdIQyzc.d.ts → index-DH9DUDEM.d.ts} +18 -3
- package/dist/{index-BcHcPyIo.d.ts → index-DLwcuCN_.d.ts} +86 -7
- package/dist/index.d.ts +18 -17
- package/dist/index.js +27 -25
- package/dist/{init-GG6Jh8HD.js → init-5TXNji88.js} +5 -5
- package/dist/{init-DeMYsnYJ.js → init-B-4t1NzC.js} +4 -4
- package/dist/{instance-options-Omfd793B.d.ts → instance-options-CU0YQCLH.d.ts} +1 -1
- package/dist/{instance-snapshot-Cxq4ygFc.js → instance-snapshot-CjcwnEiV.js} +20 -14
- package/dist/jwt/index.d.ts +83 -5
- package/dist/jwt/index.js +143 -5
- package/dist/{kernel-5JatXyND.js → kernel-DVExUwkp.js} +138 -12
- package/dist/kysely/index.d.ts +3 -3
- package/dist/kysely/index.js +1 -1
- package/dist/load-DrMHXzgN.js +1 -0
- package/dist/{load-DFS_ry0W.js → load-DxroEzH1.js} +2 -2
- package/dist/{login-Dfe5RlYk.js → login-ClSJh5t5.js} +4 -4
- package/dist/{login-imhuwvn3.js → login-WC9HPJpU.js} +6 -10
- package/dist/{manifest-C8IzW3Do.js → manifest-B79YuF2T.js} +6 -2
- package/dist/{manifest-mx5ghSFM.d.ts → manifest-BVhExYhw.d.ts} +23 -2
- package/dist/{manifest-CtKR3GXL.js → manifest-Dv6q4i5s.js} +54 -35
- package/dist/{manifest-schema-C0kK_8V0.js → manifest-schema-Cv492Qev.js} +37 -7
- package/dist/{map-claims-D3oRmTk0.js → map-claims-etGIS_Dv.js} +14 -11
- package/dist/{map-error-TCAdw-eW.js → map-error-BQGyDm_M.js} +1 -1
- package/dist/mcp/index.d.ts +64 -10
- package/dist/mcp/index.js +151 -22
- package/dist/{migrate-BShP7Vf4.js → migrate-Dodel0IJ.js} +77 -24
- package/dist/nest/index.d.ts +5 -5
- package/dist/nest/index.js +3 -3
- package/dist/next/index.d.ts +9 -9
- package/dist/next/index.js +5 -5
- package/dist/next/plugin.d.ts +1 -1
- package/dist/next/plugin.js +2 -2
- package/dist/node/index.d.ts +5 -5
- package/dist/node/index.js +2 -2
- package/dist/openai/index.d.ts +5 -5
- package/dist/openai/index.js +3 -3
- package/dist/openapi/index.d.ts +14 -4
- package/dist/openapi/index.js +1 -1
- package/dist/{openapi-ahr8rHu3.js → openapi-DMocl1bh.js} +4 -4
- package/dist/{openapi-B7HZ0f-r.js → openapi-Ddb4628T.js} +2 -7
- package/dist/{openapi-DTaEmTSW.js → openapi-ztVaux6j.js} +8 -8
- package/dist/{operation-findings-DgATDpvh.js → operation-findings-kRcEp8lE.js} +1 -1
- package/dist/{operations-CxybZErY.d.ts → operations-BNLes61x.d.ts} +1 -1
- package/dist/orpc/index.d.ts +6 -6
- package/dist/orpc/index.js +4 -4
- package/dist/otel/index.d.ts +3 -3
- package/dist/otel/index.js +1 -1
- package/dist/{output-Dyw8fyPF.js → output-DgSDLrta.js} +7 -3
- package/dist/{output-files-DhRBBE4n.js → output-files-CCMdcFWb.js} +2 -2
- package/dist/output-files-DPAY7-GX.js +1 -0
- package/dist/{ownership-BatFgAA4.js → ownership-Z2LpxsGa.js} +1349 -883
- package/dist/parse-Ddhz2xf4.js +148 -0
- package/dist/{parse-local-manifest-CVSs6J9I.js → parse-local-manifest-T1Q8X3A2.js} +24 -1
- package/dist/{parse-local-manifest-DgqtruPn.d.ts → parse-local-manifest-e4mdwAKd.d.ts} +1 -1
- package/dist/pdp/index.d.ts +3 -3
- package/dist/pdp/index.js +7 -3
- package/dist/peer-12Q5I_RH.js +976 -0
- package/dist/{peer-CRvC7Hg1.js → peer-DOzzMfZL.js} +1 -1
- package/dist/{permdock-B9JxkBwC.js → permdock-BfWEeMqk.js} +177 -49
- package/dist/{permdock-D7eeLJER.d.ts → permdock-Dco6dyCK.d.ts} +34 -5
- package/dist/{permission-registry-Br4jSNVi.js → permission-registry-DpPtSKNZ.js} +1 -1
- package/dist/{vocabulary-D6lPdb4Z.d.ts → permission-types-DhNEmoRG.d.ts} +4 -62
- package/dist/{permissions-oEWfl-kl.d.ts → permissions-CoqCOfJ3.d.ts} +2 -1
- package/dist/{permissions-B-wCP5ZC.js → permissions-CyH2MV_B.js} +1 -1
- package/dist/{permissions-CZKiUfFM.js → permissions-DArULThq.js} +4 -4
- package/dist/pkce-5h8NgMQJ.js +21 -0
- package/dist/{policies-CO1oOymN.js → policies-B2lZIurj.js} +3 -3
- package/dist/{policy-Czo4n3Hs.d.ts → policy-B7dg_yzu.d.ts} +2 -2
- package/dist/{policy-DLZJ5gAp.js → policy-DaJy4nK4.js} +17 -8
- package/dist/{policy-from-catalog-DzhEc3Y9.js → policy-from-catalog-DFWYkNdu.js} +9 -9
- package/dist/{policy-types-DzwivBgR.d.ts → policy-types-B-F-qAZk.d.ts} +109 -5
- package/dist/postgres-store-BL9M_CA1.js +1001 -0
- package/dist/{postgrest-NUqZT-RB.d.ts → postgrest-CYacM_u7.d.ts} +12 -1
- package/dist/{postgrest-CW0IqC-U.js → postgrest-r5faDIzD.js} +47 -5
- package/dist/{powersync-BHfuehf3.js → powersync-13odBwiM.js} +3 -3
- package/dist/powersync-53ryOZip.js +1059 -0
- package/dist/powersync-CExtTLyA.js +1 -0
- package/dist/preset/index.js +1 -1
- package/dist/{preset-DZdU0tne.js → preset-CHTbd-DQ.js} +2 -2
- package/dist/prisma/index.d.ts +2 -2
- package/dist/prisma/index.js +1 -1
- package/dist/{problem-details-DXlt-vks.d.ts → problem-details-Tcfmj3bV.d.ts} +1 -1
- package/dist/prompt-DwtVemER.js +935 -0
- package/dist/{protected-DEPHc2xV.d.ts → protected-BwZYL1X_.d.ts} +6 -5
- package/dist/{protected-DfjY5mLA.js → protected-DXE3cQYg.js} +2 -2
- package/dist/{provider-CC-u3bYP.js → provider-BQsTYYy0.js} +2 -2
- package/dist/{provider-DMVt6yYn.d.ts → provider-Csk-THAn.d.ts} +1 -1
- package/dist/{provider-store-B5Yrkhzr.js → provider-store-IgqQipCO.js} +2 -2
- package/dist/{pull-BgIfno6w.js → pull-CN5OLxrF.js} +7 -7
- package/dist/pull-Cty6Ovyu.js +1 -0
- package/dist/{push-CmFVBOeI.js → push-tVdG8dUL.js} +54 -14
- package/dist/{pushed-policy-BImMTTIM.d.ts → pushed-policy-BbcY9r_4.d.ts} +1 -1
- package/dist/{pushed-policy-DobP7AHI.js → pushed-policy-CmYeSQqq.js} +1 -1
- package/dist/react/index.d.ts +6 -6
- package/dist/react/index.js +3 -3
- package/dist/react/provider-client.d.ts +1 -1
- package/dist/react/provider-client.js +1 -1
- package/dist/react-native/index.d.ts +25 -11
- package/dist/react-native/index.js +214 -24
- package/dist/{refs-K6eWUJ0H.js → refs-CNJBiTFo.js} +15 -1
- package/dist/{replay-D7iKcLFe.d.ts → replay-DCDD_ZfL.d.ts} +1 -1
- package/dist/{request-context-BTRTG7OT.js → request-context-BykKLmyE.js} +2 -2
- package/dist/resend/index.d.ts +4 -4
- package/dist/{retire-CALjIQ7e.js → retire-Wj6dkyDE.js} +2 -2
- package/dist/{rls-BA8an5Ap.js → rls-Ck_PocSp.js} +32 -8
- package/dist/{rls-j6t43t7n.js → rls-CxBZb4rZ.js} +478 -534
- package/dist/{role-builder-CXbis5-X.js → role-builder-C1VJzvcr.js} +3 -3
- package/dist/rolldown-runtime-C3I60J0A.js +4 -0
- package/dist/{rpc-aPyNi6tA.js → rpc-Bk1bE-ch.js} +1 -1
- package/dist/run-Bz7DXGEv.js +1 -0
- package/dist/{run-ticket-sxFI6LAk.js → run-ticket-B5d_63Ma.js} +22 -1
- package/dist/{run-ticket-BjhTOi6u.d.ts → run-ticket-BpNi7BCi.d.ts} +8 -3
- package/dist/{run-DOfMtc9V.js → run-uLD2aWuO.js} +7 -7
- package/dist/{runtime-D3VTAiCA.js → runtime-Vif3_-zf.js} +1 -1
- package/dist/{saas-FO-Q8oj0.js → saas-Az_Kz-4D.js} +7 -7
- package/dist/{scan-BOI5tJ-6.js → scan-DSljDE1Y.js} +1 -1
- package/dist/{schema-yLuBWWsh.js → schema-gIcCx7zM.js} +1 -1
- package/dist/scim/index.d.ts +3 -2
- package/dist/scim/index.js +3 -1
- package/dist/scim-C7JYhySg.js +44 -0
- package/dist/{scim-ClHtpyV3.js → scim-YNieBO1U.js} +3 -537
- package/dist/{scopes-CUPSjo9q.js → scopes-BHsc-wp-.js} +1 -1
- package/dist/server/index.d.ts +11 -11
- package/dist/server/index.js +7 -7
- package/dist/{server-DqCT4CgZ.js → server-Bnga6I50.js} +3 -3
- package/dist/{server-types-BLd4MnBX.d.ts → server-types-C4gZUEZy.d.ts} +9 -9
- package/dist/{shared-DvvFzYXe.js → shared-C8LjUdVU.js} +1 -1
- package/dist/{shared-CD11nBbC.js → shared-fMKOv8hP.js} +46 -39
- package/dist/{sink-Bj_lDUDq.d.ts → sink-Cp_Eot9W.d.ts} +4 -4
- package/dist/{skills-B6lVdD_W.js → skills-Dcjw9_1C.js} +5 -5
- package/dist/{skills-CTYwkl44.js → skills-g_3BS9NC.js} +3 -3
- package/dist/{snapshot-CXUWfsNy.js → snapshot-CbGmYiJx.js} +4 -4
- package/dist/{snapshot-cache-DZHQ0KF6.js → snapshot-cache-DT2Kx1F8.js} +1 -1
- package/dist/{snapshot-cache-DqK9eDmM.d.ts → snapshot-cache-Pahd3IYJ.d.ts} +1 -1
- package/dist/solid/index.d.ts +6 -5
- package/dist/solid/index.js +4 -4
- package/dist/solid-start/index.d.ts +6 -6
- package/dist/solid-start/index.js +3 -3
- package/dist/{sources-vs5dGOsS.js → sources-B-zYB4GS.js} +111 -25
- package/dist/{sources-BV9j0DeZ.d.ts → sources-DEEuGb8S.d.ts} +63 -14
- package/dist/sources-qoIJQrJv.js +11 -0
- package/dist/{sql-B5T1IL83.js → sql-B96movIM.js} +5 -1
- package/dist/sql-CDEPCA0g.d.ts +10 -0
- package/dist/{src-DLfUWFAI.js → src-DLFrtrrC.js} +154 -53
- package/dist/ssf/index.d.ts +4 -4
- package/dist/ssf/index.js +640 -211
- package/dist/{standard-webhooks-6lg8v_is.d.ts → standard-webhooks-B_qRg0ws.d.ts} +2 -2
- package/dist/{store-4u_hxjWa.js → store-DSP9oGvh.js} +15 -7
- package/dist/{store-options-BqEakYRa.js → store-options-B_poyYvg.js} +6 -6
- package/dist/{stores-ClZUgeoP.d.ts → stores-BAZwSYZA.d.ts} +6 -5
- package/dist/{stores-BbsD4fAR.js → stores-BqEuHC05.js} +2 -2
- package/dist/{stream-7-xmnf3U.d.ts → stream-2Vwhl7Er.d.ts} +2 -2
- package/dist/{style-Uao76wO7.js → style-Cqo7-73x.js} +1 -0
- package/dist/{style-DiKWnAvn.js → style-Ds1gNm77.js} +1 -1
- package/dist/supabase/index.d.ts +8 -7
- package/dist/supabase/index.js +5 -5
- package/dist/supabase/middleware.d.ts +6 -6
- package/dist/supabase/middleware.js +6 -6
- package/dist/{supabase-Dxlp8A94.js → supabase--0aJdLEd.js} +9 -7
- package/dist/{supabase-9pqI57pW.js → supabase-Bqp7iIY2.js} +3 -3
- package/dist/supabase-hook-DJxC4PoP.js +1 -0
- package/dist/{supabase-hook-DdDQhMlw.js → supabase-hook-Dg0SrQWR.js} +1069 -123
- package/dist/supautils-MESd81bF.js +689 -0
- package/dist/{support-session-C6xJQYut.js → support-session-Cna49-3f.js} +2 -2
- package/dist/svelte/index.d.ts +5 -5
- package/dist/svelte/index.js +5 -5
- package/dist/svelte/runtime.d.ts +3 -3
- package/dist/svelte/runtime.js +3 -3
- package/dist/svelte/source.d.ts +5 -5
- package/dist/svelte/source.js +2 -2
- package/dist/sveltekit/index.d.ts +6 -6
- package/dist/sveltekit/index.js +2 -2
- package/dist/tanstack-start/index.d.ts +6 -6
- package/dist/tanstack-start/index.js +2 -2
- package/dist/{tenancy-DN2QAx9z.js → tenancy-CmeBQ6Nv.js} +12 -3
- package/dist/terminal/index.d.ts +6 -6
- package/dist/terminal/index.js +3 -3
- package/dist/testing/core.d.ts +2 -0
- package/dist/testing/core.js +1 -0
- package/dist/testing/fixtures/index.d.ts +12 -0
- package/dist/testing/fixtures/index.js +770 -0
- package/dist/testing/index.d.ts +41 -174
- package/dist/testing/index.js +241 -731
- package/dist/testing/saas/index.d.ts +5 -5
- package/dist/testing/saas/index.js +2 -2
- package/dist/testing/saas/permissions.d.ts +1 -1
- package/dist/testing/saas/permissions.js +1 -1
- package/dist/text-diff-DhITNCnD.js +444 -0
- package/dist/{token-BLZcjQgt.js → token-2qYDvXz2.js} +1 -1
- package/dist/{tool-refusal-CMLN5xhn.js → tool-refusal-reAhIzdl.js} +1 -1
- package/dist/trpc/index.d.ts +6 -6
- package/dist/trpc/index.js +3 -3
- package/dist/{types-5Ut_pbKy.d.ts → types-BWZybqs9.d.ts} +112 -8
- package/dist/{types-CZTnPFzM.d.ts → types-BXMYB7BY.d.ts} +2 -2
- package/dist/{types-CdlxsYQh.d.ts → types-BfVmNJO5.d.ts} +14 -3
- package/dist/{types-BqAKcRNW.d.ts → types-CIeZcG8v.d.ts} +2 -2
- package/dist/{types-BNORmDM8.d.ts → types-CKV71kKh.d.ts} +4 -4
- package/dist/{types-tIgIeIKJ.d.ts → types-CQVEQawv.d.ts} +4 -4
- package/dist/{types-BjV-fqcA.d.ts → types-CeIscIKp.d.ts} +4 -4
- package/dist/{types-_sHy8BQf.d.ts → types-CfiKC5aN.d.ts} +1 -1
- package/dist/{types-ClZaWzfb.d.ts → types-D3A19w4A.d.ts} +8 -4
- package/dist/{types-C8-KNsFf.d.ts → types-DBHftjgS.d.ts} +15 -8
- package/dist/{types-CCpc2Dcv.d.ts → types-DC44-hqb.d.ts} +2 -2
- package/dist/{types-fbZ7JEXr.d.ts → types-DXmwu78Z.d.ts} +4 -4
- package/dist/{types-DiQjupG2.d.ts → types-cTos-H7p.d.ts} +2 -2
- package/dist/{types-DX0LaKTb.d.ts → types-g7Oy6Zg4.d.ts} +3 -3
- package/dist/unplugin/index.d.ts +1 -1
- package/dist/unplugin/index.js +2 -2
- package/dist/{usage-T5mXq98v.js → usage-Bybmck7f.js} +7 -7
- package/dist/{usage-DHtE8j4E.js → usage-CDaLXCfL.js} +2 -2
- package/dist/usage-y-kBNdqs.js +1 -0
- package/dist/{validation-error-Bg5Tpluk.d.ts → validation-error-CQpoquwj.d.ts} +1 -1
- package/dist/{verify-DbCL9bnB.js → verify-pe8rL_Qw.js} +350 -83
- package/dist/{views-DTIIO-oQ.js → views-BB8E9dTP.js} +1 -1
- package/dist/vocabulary-Bg3eeT2H.d.ts +67 -0
- package/dist/vue/index.d.ts +6 -5
- package/dist/vue/index.js +4 -4
- package/dist/{waiter-CKy4MQSY.d.ts → waiter-DwEyouan.d.ts} +2 -2
- package/dist/watch-Bd9mx3rd.js +1 -0
- package/dist/{watch-CszoTJMq.js → watch-C-4VmFlL.js} +3 -3
- package/dist/webmcp/index.d.ts +2 -2
- package/dist/webmcp/index.js +2 -2
- package/dist/{where-scope-Dv-WTP-w.js → where-scope-wq2coopv.js} +41 -21
- package/dist/{who-can-D0QoYbEb.js → who-can-BwNsI_Js.js} +6 -6
- package/dist/workflow/index.d.ts +3 -3
- package/dist/workflow/index.js +5 -5
- package/dist/workflow-sdk/index.d.ts +5 -5
- package/dist/{wrap-Bd1Tejur.d.ts → wrap-B6R0cMRL.d.ts} +2 -2
- package/dist/{wrap-gX61EtpB.js → wrap-CiSc_KCq.js} +8 -2
- package/package.json +22 -11
- package/schemas/cli-result-v1.json +1 -0
- package/schemas/cloud-api-v1.json +152 -7
- package/schemas/connector-v1.json +8 -0
- package/schemas/supabase-claims-v1.json +5 -0
- package/schemas/supabase-manifest-v1.json +276 -75
- package/skills/permdock/SKILL.md +1 -0
- package/skills/permdock-agents/references/runtimes.md +3 -1
- package/skills/permdock-approvals/references/stores-and-resume.md +2 -1
- package/skills/permdock-data/references/queries-and-rls.md +5 -2
- package/skills/permdock-tenancy/SKILL.md +1 -1
- package/skills/permdock-tenancy/references/ownership-and-custom-roles.md +2 -0
- package/skills/permdock-wire/references/adapters.md +14 -0
- package/skills/permdock-wire/references/policy-options.md +1 -0
- package/dist/catalog-DjhMYYCq.js +0 -1
- package/dist/collect-FlXJlhus.js +0 -1
- package/dist/index-D8EovfsP.d.ts +0 -91
- package/dist/load-BxEtwlBS.js +0 -1
- package/dist/output-files-B3IZJksC.js +0 -1
- package/dist/parse-Cxq0WxrA.js +0 -53
- package/dist/peer-C8swJ2GH.js +0 -50
- package/dist/powersync-CbzkqL_M.js +0 -1
- package/dist/powersync-bYUDLOAO.js +0 -538
- package/dist/prompt-DfZLJLIn.js +0 -32
- package/dist/pull-ByOks_Tg.js +0 -1
- package/dist/run-CNsApDpd.js +0 -1
- package/dist/supabase-hook-CXcGpHqq.js +0 -1
- package/dist/supautils-B6HYL9eL.js +0 -91
- package/dist/text-diff-BQcUapOb.js +0 -15
- package/dist/usage-CHOtwL19.js +0 -1
- package/dist/watch-Cb-NcaUw.js +0 -1
|
@@ -1,29 +1,896 @@
|
|
|
1
1
|
import { r as isRecord } from "./compact-CAf557ZB.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { o as hasConditionOp } from "./refs-CNJBiTFo.js";
|
|
3
|
+
import { f as scopeList, l as rootScope, s as resolveScope, u as scopeChain } from "./scopes-BHsc-wp-.js";
|
|
4
4
|
import { t as APPROVAL_REQUEST_SCHEMA } from "./request-schema-CMreVuFM.js";
|
|
5
|
-
import { a as describeError, i as configError } from "./errors-
|
|
5
|
+
import { a as describeError, i as configError } from "./errors-DpP_U6Bf.js";
|
|
6
6
|
import { i as readJsonFile, o as sqlFiles, s as writeFileEnsuringDir } from "./files-D_JIzUrP.js";
|
|
7
7
|
import { a as SUPABASE_MANIFEST_SCHEMA } from "./version-CEbQ5UeM.js";
|
|
8
|
-
import { c as requirePolicy } from "./load-
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
8
|
+
import { c as requirePolicy } from "./load-DxroEzH1.js";
|
|
9
|
+
import { i as qualifySqlTable } from "./sql-B96movIM.js";
|
|
10
|
+
import { r as scopeColumn } from "./compile-BAEO5bOk.js";
|
|
11
|
+
import { t as authorizeSql } from "./supabase--0aJdLEd.js";
|
|
11
12
|
import "./budget-NbEtbJC_.js";
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import { o as readMemberships } from "./postgrest-CW0IqC-U.js";
|
|
13
|
+
import { a as hookApiNames, d as keptKeys, t as AUTHZ_VERSION_TABLE, u as roleManifest } from "./sources-B-zYB4GS.js";
|
|
14
|
+
import { o as readMemberships } from "./postgrest-r5faDIzD.js";
|
|
15
15
|
import { t as beforeFirst } from "./text-BMFRfBqc.js";
|
|
16
16
|
import { n as GRANTS_MARKER, r as HOOK_MARKER, s as hookMarkerFields } from "./markers-C6joDI3o.js";
|
|
17
17
|
import { n as formatManifestJson, t as MANIFEST_FILE } from "./manifest-json-CAGzls-C.js";
|
|
18
18
|
import { n as MIGRATION_DIRS } from "./constants-DcJABbLW.js";
|
|
19
|
-
import { f as writeOutputFiles, l as partPath, r as driftOf, u as pgDeltaPath } from "./output-files-
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
19
|
+
import { f as writeOutputFiles, l as partPath, r as driftOf, u as pgDeltaPath } from "./output-files-CCMdcFWb.js";
|
|
20
|
+
import { A as quoteQualified, D as qualified, F as scopeTypeOf, L as tenantTypeOf, O as quoteIdent, a as customRolesOn, j as quoteTable, k as quoteLiteral, l as USER_ID_HELPER, r as HELPERS, y as subjectIdSql } from "./shared-fMKOv8hP.js";
|
|
21
|
+
import { $ as permittedForHelper, A as apiKeyFields, C as globalRoleSource, G as hasMemberFor, I as roleNames, J as memberForHelper, K as hasPermittedUsers, O as API_KEY_ALLOWS, Q as memberRoleOf, S as globalRoleRows, X as memberForTable, Y as memberForSources, Z as memberIdsHelper, c as OWNERSHIP, et as permittedIdsHelper, f as permissionKeysForHelper, i as holderSources, it as activeRowSql, l as PERMISSION_HELPERS, o as guardedTables, ot as checkSuspension, p as permittedByPermissionHelper, rt as scopeTable, s as ASSIGNMENTS, t as ownershipRules, u as checkName, v as TOKEN_SCOPE_ALLOWS } from "./ownership-Z2LpxsGa.js";
|
|
22
|
+
import { t as membershipSourcesOf } from "./sources-qoIJQrJv.js";
|
|
23
|
+
import { a as splitUndiffed, r as tableKey, t as decidingColumns } from "./deciding-columns-DRo2QM6E.js";
|
|
24
|
+
import { a as readOnlyActorKinds, f as pgConnector, t as ACTOR_MAY_WRITE } from "./policies-B2lZIurj.js";
|
|
24
25
|
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
25
26
|
import { dirname, join, posix, resolve } from "node:path";
|
|
26
|
-
|
|
27
|
+
//#region ../../node_modules/.pnpm/smol-toml@1.9.1/node_modules/smol-toml/dist/error.js
|
|
28
|
+
/*!
|
|
29
|
+
* Copyright (c) Squirrel Chat et al., All rights reserved.
|
|
30
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
31
|
+
*
|
|
32
|
+
* Redistribution and use in source and binary forms, with or without
|
|
33
|
+
* modification, are permitted provided that the following conditions are met:
|
|
34
|
+
*
|
|
35
|
+
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
36
|
+
* list of conditions and the following disclaimer.
|
|
37
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
38
|
+
* this list of conditions and the following disclaimer in the
|
|
39
|
+
* documentation and/or other materials provided with the distribution.
|
|
40
|
+
* 3. Neither the name of the copyright holder nor the names of its contributors
|
|
41
|
+
* may be used to endorse or promote products derived from this software without
|
|
42
|
+
* specific prior written permission.
|
|
43
|
+
*
|
|
44
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
45
|
+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
46
|
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
47
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
48
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
49
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
50
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
51
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
52
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
53
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
54
|
+
*/
|
|
55
|
+
function getLineColFromPtr(string, ptr) {
|
|
56
|
+
let lines = string.slice(0, ptr).split(/\r?\n/);
|
|
57
|
+
return [lines.length, lines.pop().length + 1];
|
|
58
|
+
}
|
|
59
|
+
function makeCodeBlock(string, line, column) {
|
|
60
|
+
let lines = string.split(/\r?\n/);
|
|
61
|
+
let codeblock = "";
|
|
62
|
+
let numberLen = (Math.log10(line + 1) | 0) + 1;
|
|
63
|
+
for (let i = line - 1; i <= line + 1; i++) {
|
|
64
|
+
let l = lines[i - 1];
|
|
65
|
+
if (!l) continue;
|
|
66
|
+
codeblock += i.toString().padEnd(numberLen, " ");
|
|
67
|
+
codeblock += ": ";
|
|
68
|
+
codeblock += l;
|
|
69
|
+
codeblock += "\n";
|
|
70
|
+
if (i === line) {
|
|
71
|
+
codeblock += " ".repeat(numberLen + column + 2);
|
|
72
|
+
codeblock += "^\n";
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return codeblock;
|
|
76
|
+
}
|
|
77
|
+
var TomlError = class TomlError extends Error {
|
|
78
|
+
line;
|
|
79
|
+
column;
|
|
80
|
+
codeblock;
|
|
81
|
+
constructor(message, options) {
|
|
82
|
+
const [line, column] = getLineColFromPtr(options.toml, options.ptr);
|
|
83
|
+
const codeblock = makeCodeBlock(options.toml, line, column);
|
|
84
|
+
super(`Invalid TOML document: ${message}\n\n${codeblock}`, options);
|
|
85
|
+
this.line = line;
|
|
86
|
+
this.column = column;
|
|
87
|
+
this.codeblock = codeblock;
|
|
88
|
+
}
|
|
89
|
+
/** @internal */
|
|
90
|
+
static x(message, ctx, ptr) {
|
|
91
|
+
throw new TomlError(message, {
|
|
92
|
+
toml: ctx.s,
|
|
93
|
+
ptr: ptr ?? ctx.p
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
//#endregion
|
|
98
|
+
//#region ../../node_modules/.pnpm/smol-toml@1.9.1/node_modules/smol-toml/dist/primitive.js
|
|
99
|
+
/*!
|
|
100
|
+
* Copyright (c) Squirrel Chat et al., All rights reserved.
|
|
101
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
102
|
+
*
|
|
103
|
+
* Redistribution and use in source and binary forms, with or without
|
|
104
|
+
* modification, are permitted provided that the following conditions are met:
|
|
105
|
+
*
|
|
106
|
+
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
107
|
+
* list of conditions and the following disclaimer.
|
|
108
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
109
|
+
* this list of conditions and the following disclaimer in the
|
|
110
|
+
* documentation and/or other materials provided with the distribution.
|
|
111
|
+
* 3. Neither the name of the copyright holder nor the names of its contributors
|
|
112
|
+
* may be used to endorse or promote products derived from this software without
|
|
113
|
+
* specific prior written permission.
|
|
114
|
+
*
|
|
115
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
116
|
+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
117
|
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
118
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
119
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
120
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
121
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
122
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
123
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
124
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
125
|
+
*/
|
|
126
|
+
/** @internal */
|
|
127
|
+
function parseString(ctx) {
|
|
128
|
+
let startPtr = ctx.p;
|
|
129
|
+
let c = ctx.s.charCodeAt(ctx.p++);
|
|
130
|
+
let first = c;
|
|
131
|
+
let isLiteral = c === 39;
|
|
132
|
+
let isMultiline = c === ctx.s.charCodeAt(ctx.p) && c === ctx.s.charCodeAt(ctx.p + 1);
|
|
133
|
+
if (isMultiline) {
|
|
134
|
+
if ((c = ctx.s.charCodeAt(ctx.p += 2)) === 10) ctx.p++;
|
|
135
|
+
else if (c === 13 && ctx.s.charCodeAt(ctx.p + 1) === 10) ctx.p += 2;
|
|
136
|
+
}
|
|
137
|
+
let parsed = "";
|
|
138
|
+
let sliceStart = ctx.p;
|
|
139
|
+
let state = 0;
|
|
140
|
+
for (; ctx.p < ctx.s.length; ctx.p++) {
|
|
141
|
+
c = ctx.s.charCodeAt(ctx.p);
|
|
142
|
+
if (isMultiline && (c === 10 || c === 13 && ctx.s.charCodeAt(ctx.p + 1) === 10)) state = state && 3;
|
|
143
|
+
else if (c < 32 && c !== 9 || c === 127) TomlError.x("control characters are not allowed in strings", ctx);
|
|
144
|
+
else if ((!state || state === 3) && c === first && (!isMultiline || ctx.s.charCodeAt(ctx.p + 1) === first && ctx.s.charCodeAt(ctx.p + 2) === first)) {
|
|
145
|
+
if (isMultiline) {
|
|
146
|
+
if (ctx.s.charCodeAt(ctx.p + 3) === first) ctx.p++;
|
|
147
|
+
if (ctx.s.charCodeAt(ctx.p + 3) === first) ctx.p++;
|
|
148
|
+
}
|
|
149
|
+
if (!state) {
|
|
150
|
+
let s = ctx.s.slice(sliceStart, ctx.p);
|
|
151
|
+
parsed = parsed ? parsed + s : s;
|
|
152
|
+
}
|
|
153
|
+
ctx.p += isMultiline ? 3 : 1;
|
|
154
|
+
return parsed;
|
|
155
|
+
} else if (!state) {
|
|
156
|
+
if (!isLiteral && c === 92) {
|
|
157
|
+
parsed += ctx.s.slice(sliceStart, sliceStart = ctx.p);
|
|
158
|
+
state = 1;
|
|
159
|
+
}
|
|
160
|
+
} else if (state === 1) {
|
|
161
|
+
if (c === 120 || c === 117 || c === 85) {
|
|
162
|
+
let errPtr = ctx.p++ - 1;
|
|
163
|
+
let value = 0;
|
|
164
|
+
let len = c === 120 ? 2 : c === 117 ? 4 : 8;
|
|
165
|
+
for (let j = 0; j < len; j++, ctx.p++) {
|
|
166
|
+
let hex = ctx.s.charCodeAt(ctx.p);
|
|
167
|
+
let digit = hex >= 48 && hex <= 57 ? hex - 48 : hex >= 65 && hex <= 70 ? hex - 65 + 10 : hex >= 97 && hex <= 102 ? hex - 97 + 10 : -1;
|
|
168
|
+
if (digit < 0) TomlError.x("invalid non-hex character in unicode escape", ctx);
|
|
169
|
+
value = value << 4 | digit;
|
|
170
|
+
}
|
|
171
|
+
if (value < 0 || value > 1114111 || value >= 55296 && value <= 57343) TomlError.x("invalid unicode escape", ctx, errPtr);
|
|
172
|
+
parsed += String.fromCodePoint(value);
|
|
173
|
+
sliceStart = ctx.p--;
|
|
174
|
+
state = 0;
|
|
175
|
+
} else if (isMultiline && (c === 32 || c === 9)) state = 2;
|
|
176
|
+
else {
|
|
177
|
+
if (c === 98) parsed += "\b";
|
|
178
|
+
else if (c === 116) parsed += " ";
|
|
179
|
+
else if (c === 110) parsed += "\n";
|
|
180
|
+
else if (c === 102) parsed += "\f";
|
|
181
|
+
else if (c === 114) parsed += "\r";
|
|
182
|
+
else if (c === 101) parsed += "\x1B";
|
|
183
|
+
else if (c === 34) parsed += "\"";
|
|
184
|
+
else if (c === 92) parsed += "\\";
|
|
185
|
+
else TomlError.x("unrecognised escape sequence", ctx);
|
|
186
|
+
sliceStart = ctx.p + 1;
|
|
187
|
+
state = 0;
|
|
188
|
+
}
|
|
189
|
+
} else if (c !== 32 && c !== 9) {
|
|
190
|
+
if (state === 2) TomlError.x("invalid escape: only line-ending whitespace may be escaped", ctx, sliceStart);
|
|
191
|
+
state = !isLiteral && c === 92 ? 1 : 0;
|
|
192
|
+
sliceStart = ctx.p;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
TomlError.x("unfinished string", ctx, startPtr);
|
|
196
|
+
}
|
|
197
|
+
//#endregion
|
|
198
|
+
//#region ../../node_modules/.pnpm/smol-toml@1.9.1/node_modules/smol-toml/dist/date.js
|
|
199
|
+
/*!
|
|
200
|
+
* Copyright (c) Squirrel Chat et al., All rights reserved.
|
|
201
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
202
|
+
*
|
|
203
|
+
* Redistribution and use in source and binary forms, with or without
|
|
204
|
+
* modification, are permitted provided that the following conditions are met:
|
|
205
|
+
*
|
|
206
|
+
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
207
|
+
* list of conditions and the following disclaimer.
|
|
208
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
209
|
+
* this list of conditions and the following disclaimer in the
|
|
210
|
+
* documentation and/or other materials provided with the distribution.
|
|
211
|
+
* 3. Neither the name of the copyright holder nor the names of its contributors
|
|
212
|
+
* may be used to endorse or promote products derived from this software without
|
|
213
|
+
* specific prior written permission.
|
|
214
|
+
*
|
|
215
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
216
|
+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
217
|
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
218
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
219
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
220
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
221
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
222
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
223
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
224
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
225
|
+
*/
|
|
226
|
+
let DATE_TIME_RE = /^(\d{4}-\d{2}-\d{2})?[Tt ]?(?:(\d{2}):\d{2}(?::\d{2}(?:\.\d+)?)?)?(Z|z|[-+]\d{2}:\d{2})?$/i;
|
|
227
|
+
var TomlDate = class TomlDate extends Date {
|
|
228
|
+
#hasDate = false;
|
|
229
|
+
#hasTime = false;
|
|
230
|
+
#offset = null;
|
|
231
|
+
constructor(date, fasttype, unsafeDelim) {
|
|
232
|
+
let hasDate = true;
|
|
233
|
+
let hasTime = true;
|
|
234
|
+
let offset = "Z";
|
|
235
|
+
let c;
|
|
236
|
+
if (typeof date === "string") {
|
|
237
|
+
if (fasttype) prep: {
|
|
238
|
+
if (fasttype < 3) {
|
|
239
|
+
if (+date.slice(11, 13) > 23) {
|
|
240
|
+
date = "";
|
|
241
|
+
break prep;
|
|
242
|
+
}
|
|
243
|
+
if (fasttype === 2) {
|
|
244
|
+
offset = null;
|
|
245
|
+
date += "Z";
|
|
246
|
+
} else if ((c = date.charCodeAt(date.length - 1)) !== 90 && c !== 122) offset = date.slice(date.length - 6);
|
|
247
|
+
if (unsafeDelim) date = date.slice(0, 10) + "T" + date.slice(11);
|
|
248
|
+
} else if (fasttype === 4) date = +date.slice(0, 2) > 23 ? "" : `0000-01-01T${date}Z`;
|
|
249
|
+
hasDate = fasttype !== 4;
|
|
250
|
+
hasTime = fasttype !== 3;
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
let match = date.match(DATE_TIME_RE);
|
|
254
|
+
if (match) {
|
|
255
|
+
if (!match[1]) {
|
|
256
|
+
hasDate = false;
|
|
257
|
+
date = `0000-01-01T${date}`;
|
|
258
|
+
}
|
|
259
|
+
hasTime = !!match[2];
|
|
260
|
+
hasTime && date[10] === " " && (date = date.replace(" ", "T"));
|
|
261
|
+
if (match[2] && +match[2] > 23) date = "";
|
|
262
|
+
else {
|
|
263
|
+
offset = match[3] || null;
|
|
264
|
+
if (!offset && hasTime) date += "Z";
|
|
265
|
+
}
|
|
266
|
+
} else date = "";
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
super(date);
|
|
270
|
+
if (!isNaN(this.getTime())) {
|
|
271
|
+
this.#hasDate = hasDate;
|
|
272
|
+
this.#hasTime = hasTime;
|
|
273
|
+
this.#offset = offset;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
isDateTime() {
|
|
277
|
+
return this.#hasDate && this.#hasTime;
|
|
278
|
+
}
|
|
279
|
+
isLocal() {
|
|
280
|
+
return !this.#hasDate || !this.#hasTime || !this.#offset;
|
|
281
|
+
}
|
|
282
|
+
isDate() {
|
|
283
|
+
return this.#hasDate && !this.#hasTime;
|
|
284
|
+
}
|
|
285
|
+
isTime() {
|
|
286
|
+
return this.#hasTime && !this.#hasDate;
|
|
287
|
+
}
|
|
288
|
+
isValid() {
|
|
289
|
+
return this.#hasDate || this.#hasTime;
|
|
290
|
+
}
|
|
291
|
+
toISOString() {
|
|
292
|
+
let iso = super.toISOString();
|
|
293
|
+
if (this.isDate()) return iso.slice(0, 10);
|
|
294
|
+
if (this.isTime()) return iso.slice(11, 23);
|
|
295
|
+
if (this.#offset === null) return iso.slice(0, -1);
|
|
296
|
+
if (this.#offset === "Z" || this.#offset === "z") return iso;
|
|
297
|
+
let offset = +this.#offset.slice(1, 3) * 60 + +this.#offset.slice(4, 6);
|
|
298
|
+
offset = this.#offset[0] === "-" ? offset : -offset;
|
|
299
|
+
return (/* @__PURE__ */ new Date(this.getTime() - offset * 6e4)).toISOString().slice(0, -1) + this.#offset;
|
|
300
|
+
}
|
|
301
|
+
static wrapAsOffsetDateTime(jsDate, offset = "Z") {
|
|
302
|
+
let date = new TomlDate(jsDate);
|
|
303
|
+
date.#offset = offset;
|
|
304
|
+
return date;
|
|
305
|
+
}
|
|
306
|
+
static wrapAsLocalDateTime(jsDate) {
|
|
307
|
+
let date = new TomlDate(jsDate);
|
|
308
|
+
date.#offset = null;
|
|
309
|
+
return date;
|
|
310
|
+
}
|
|
311
|
+
static wrapAsLocalDate(jsDate) {
|
|
312
|
+
let date = new TomlDate(jsDate);
|
|
313
|
+
date.#hasTime = false;
|
|
314
|
+
date.#offset = null;
|
|
315
|
+
return date;
|
|
316
|
+
}
|
|
317
|
+
static wrapAsLocalTime(jsDate) {
|
|
318
|
+
let date = new TomlDate(jsDate);
|
|
319
|
+
date.#hasDate = false;
|
|
320
|
+
date.#offset = null;
|
|
321
|
+
return date;
|
|
322
|
+
}
|
|
323
|
+
};
|
|
324
|
+
//#endregion
|
|
325
|
+
//#region ../../node_modules/.pnpm/smol-toml@1.9.1/node_modules/smol-toml/dist/extract.js
|
|
326
|
+
/*!
|
|
327
|
+
* Copyright (c) Squirrel Chat et al., All rights reserved.
|
|
328
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
329
|
+
*
|
|
330
|
+
* Redistribution and use in source and binary forms, with or without
|
|
331
|
+
* modification, are permitted provided that the following conditions are met:
|
|
332
|
+
*
|
|
333
|
+
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
334
|
+
* list of conditions and the following disclaimer.
|
|
335
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
336
|
+
* this list of conditions and the following disclaimer in the
|
|
337
|
+
* documentation and/or other materials provided with the distribution.
|
|
338
|
+
* 3. Neither the name of the copyright holder nor the names of its contributors
|
|
339
|
+
* may be used to endorse or promote products derived from this software without
|
|
340
|
+
* specific prior written permission.
|
|
341
|
+
*
|
|
342
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
343
|
+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
344
|
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
345
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
346
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
347
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
348
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
349
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
350
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
351
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
352
|
+
*/
|
|
353
|
+
function isDigit(char, base = 10) {
|
|
354
|
+
return base === 16 ? char > 47 && char < 58 || char > 64 && char < 71 || char > 96 && char < 103 : char > 47 && char < 48 + base;
|
|
355
|
+
}
|
|
356
|
+
function isEndOfValue(char, delim) {
|
|
357
|
+
return char === 32 || char === 9 || char === 10 || char === 13 || delim && (char === delim || char === 44) || char === 35;
|
|
358
|
+
}
|
|
359
|
+
/** @internal */
|
|
360
|
+
function extractValue(ctx, end) {
|
|
361
|
+
let errPtr = ctx.p;
|
|
362
|
+
let c = ctx.s.charCodeAt(ctx.p);
|
|
363
|
+
if (c === 91 || c === 123) {
|
|
364
|
+
ctx.d-- || TomlError.x("document contains excessively nested structures. aborting.", ctx);
|
|
365
|
+
let value = c === 91 ? parseArray(ctx) : parseInlineTable(ctx);
|
|
366
|
+
ctx.d++;
|
|
367
|
+
return value;
|
|
368
|
+
}
|
|
369
|
+
if (c === 34 || c === 39) return parseString(ctx);
|
|
370
|
+
if (c === 116) {
|
|
371
|
+
if (ctx.s.charCodeAt(++ctx.p) !== 114 || ctx.s.charCodeAt(++ctx.p) !== 117 || ctx.s.charCodeAt(++ctx.p) !== 101) TomlError.x("invalid value", ctx, errPtr);
|
|
372
|
+
return ctx.p++, true;
|
|
373
|
+
}
|
|
374
|
+
if (c === 102) {
|
|
375
|
+
if (ctx.s.charCodeAt(++ctx.p) !== 97 || ctx.s.charCodeAt(++ctx.p) !== 108 || ctx.s.charCodeAt(++ctx.p) !== 115 || ctx.s.charCodeAt(++ctx.p) !== 101) TomlError.x("invalid value", ctx, errPtr);
|
|
376
|
+
return ctx.p++, false;
|
|
377
|
+
}
|
|
378
|
+
if (c === 43 || c === 45) return parseNumber(ctx, ctx.p, ctx.s.charCodeAt(++ctx.p), 44 - c, end);
|
|
379
|
+
if (ctx.s.charCodeAt(ctx.p + 4) === 45 && ctx.s.charCodeAt(ctx.p + 7) === 45) return parseDate(ctx, c, end);
|
|
380
|
+
if (ctx.s.charCodeAt(ctx.p + 2) === 58) return parseTime(ctx, c, end);
|
|
381
|
+
return parseNumber(ctx, ctx.p, c, 0, end);
|
|
382
|
+
}
|
|
383
|
+
function parseNumber(ctx, startPtr, startChr, sign, endChr) {
|
|
384
|
+
let c = startChr;
|
|
385
|
+
let state = 0;
|
|
386
|
+
let hasUnderscores = false;
|
|
387
|
+
if (c === 105) {
|
|
388
|
+
if (ctx.s.charCodeAt(++ctx.p) !== 110 || ctx.s.charCodeAt(++ctx.p) !== 102) TomlError.x("invalid value", ctx, startPtr);
|
|
389
|
+
return ctx.p++, (sign || 1) / 0;
|
|
390
|
+
}
|
|
391
|
+
if (c === 110) {
|
|
392
|
+
if (ctx.s.charCodeAt(++ctx.p) !== 97 || ctx.s.charCodeAt(++ctx.p) !== 110) TomlError.x("invalid value", ctx, startPtr);
|
|
393
|
+
return ctx.p++, NaN;
|
|
394
|
+
}
|
|
395
|
+
if (c === 48) {
|
|
396
|
+
if (++ctx.p >= ctx.s.length || isEndOfValue(c = ctx.s.charCodeAt(ctx.p), endChr)) return ctx.bi === true ? 0n : 0;
|
|
397
|
+
if (!sign) {
|
|
398
|
+
if (c === 120) return parseIntegerBaseN(ctx, startPtr, 16, endChr);
|
|
399
|
+
else if (c === 98) return parseIntegerBaseN(ctx, startPtr, 2, endChr);
|
|
400
|
+
else if (c === 111) return parseIntegerBaseN(ctx, startPtr, 8, endChr);
|
|
401
|
+
}
|
|
402
|
+
if (c === 46) state = 2;
|
|
403
|
+
else if (c === 101 || c === 69) state = 4;
|
|
404
|
+
else TomlError.x("illegal leading zero", ctx, startPtr);
|
|
405
|
+
} else if (!isDigit(c)) TomlError.x("invalid value", ctx, startPtr);
|
|
406
|
+
while (++ctx.p < ctx.s.length && (c = ctx.s.charCodeAt(ctx.p), !isEndOfValue(c, endChr))) {
|
|
407
|
+
if (!state) state = 1;
|
|
408
|
+
if (c === 95) {
|
|
409
|
+
if (!(state & 1)) TomlError.x("illegal underscore", ctx);
|
|
410
|
+
state += 11;
|
|
411
|
+
hasUnderscores = true;
|
|
412
|
+
} else if (state === 1 && c === 46) state = 2;
|
|
413
|
+
else if ((state === 1 || state === 3) && (c === 101 || c === 69)) state = 4;
|
|
414
|
+
else if (state === 4 && (c === 43 || c === 45)) state = 6;
|
|
415
|
+
else if (!isDigit(c)) TomlError.x(`illegal character in numeric literal`, ctx);
|
|
416
|
+
else if (state > 9) state -= 11;
|
|
417
|
+
else if (!(state & 1)) state++;
|
|
418
|
+
}
|
|
419
|
+
if (!state) {
|
|
420
|
+
let val = (startChr - 48) * (sign || 1);
|
|
421
|
+
return ctx.bi === true ? BigInt(val) : val;
|
|
422
|
+
}
|
|
423
|
+
if (!(state & 1)) TomlError.x("unfinished numeric value", ctx, startPtr);
|
|
424
|
+
let str = ctx.s.slice(startPtr, ctx.p);
|
|
425
|
+
if (hasUnderscores) str = str.replaceAll("_", "");
|
|
426
|
+
return state > 1 ? parseFloat(str) : parseInteger(ctx, str, 10, startPtr);
|
|
427
|
+
}
|
|
428
|
+
function parseIntegerBaseN(ctx, startPtr, base, endChr) {
|
|
429
|
+
let c, underscore = 1;
|
|
430
|
+
while (++ctx.p < ctx.s.length && (c = ctx.s.charCodeAt(ctx.p), !isEndOfValue(c, endChr))) if (c === 95) {
|
|
431
|
+
if (underscore & 1) TomlError.x("illegal underscore", ctx);
|
|
432
|
+
underscore = 3;
|
|
433
|
+
} else if (!isDigit(c, base)) TomlError.x(`illegal character in numeric literal`, ctx);
|
|
434
|
+
else if (underscore & 1) underscore--;
|
|
435
|
+
if (underscore & 1) TomlError.x("unfinished numeric value", ctx);
|
|
436
|
+
let str = ctx.s.slice(startPtr + 2, ctx.p);
|
|
437
|
+
if (underscore) str = str.replaceAll("_", "");
|
|
438
|
+
return parseInteger(ctx, str, base, startPtr);
|
|
439
|
+
}
|
|
440
|
+
function parseInteger(ctx, str, base, startPtr) {
|
|
441
|
+
if (ctx.bi !== true) int: {
|
|
442
|
+
let val = parseInt(str, base);
|
|
443
|
+
if (!Number.isSafeInteger(val)) {
|
|
444
|
+
if (ctx.bi) break int;
|
|
445
|
+
TomlError.x("integer value cannot be represented losslessly", ctx, startPtr);
|
|
446
|
+
}
|
|
447
|
+
return val;
|
|
448
|
+
}
|
|
449
|
+
return base === 10 ? BigInt(str) : BigInt((base === 2 ? "0b" : base === 8 ? "0o" : "0x") + str);
|
|
450
|
+
}
|
|
451
|
+
function parseDate(ctx, c, endChr) {
|
|
452
|
+
let startPtr = ctx.p++, unsafeSeparator;
|
|
453
|
+
if (!isDigit(c) || !isDigit(ctx.s.charCodeAt(ctx.p++)) || !isDigit(ctx.s.charCodeAt(ctx.p++)) || !isDigit(ctx.s.charCodeAt(ctx.p++))) return parseNumber(ctx, ctx.p = startPtr, c, 0, endChr);
|
|
454
|
+
ctx.p += 5;
|
|
455
|
+
if (!isDigit(ctx.s.charCodeAt(ctx.p++))) TomlError.x("invalid date-time: date part is malformed", ctx, startPtr);
|
|
456
|
+
if (ctx.p >= ctx.s.length || ((c = ctx.s.charCodeAt(ctx.p)) !== 32 || (unsafeSeparator = true, !isDigit(ctx.s.charCodeAt(ctx.p + 1)))) && c !== 84 && c !== 116) return readDate(ctx, ctx.s.slice(startPtr, ctx.p), 3, false, startPtr);
|
|
457
|
+
if (ctx.s.charCodeAt(ctx.p += 3) !== 58) TomlError.x("invalid date-time: time part is malformed", ctx, startPtr);
|
|
458
|
+
if (ctx.s.charCodeAt(ctx.p += 3) === 58) ctx.p += 3;
|
|
459
|
+
if (ctx.s.charCodeAt(ctx.p) === 46) while (isDigit(ctx.s.charCodeAt(++ctx.p)));
|
|
460
|
+
if (c = ctx.s.charCodeAt(ctx.p)) {
|
|
461
|
+
if (c === 90 || c === 122) return readDate(ctx, ctx.s.slice(startPtr, ++ctx.p), 1, unsafeSeparator, startPtr, "[+00:00]");
|
|
462
|
+
if (c === 43 || c === 45) return readDate(ctx, ctx.s.slice(startPtr, ctx.p += 6), 1, unsafeSeparator, startPtr, !ctx.ld && "[" + ctx.s.slice(ctx.p - 6, ctx.p) + "]");
|
|
463
|
+
}
|
|
464
|
+
return readDate(ctx, ctx.s.slice(startPtr, ctx.p), 2, unsafeSeparator, startPtr);
|
|
465
|
+
}
|
|
466
|
+
function parseTime(ctx, c, endChr) {
|
|
467
|
+
let start = ctx.p;
|
|
468
|
+
if (!isDigit(c) || !isDigit(ctx.s.charCodeAt(++ctx.p))) return parseNumber(ctx, --ctx.p, c, 0, endChr);
|
|
469
|
+
if (ctx.s.charCodeAt(ctx.p += 4) === 58) ctx.p += 3;
|
|
470
|
+
if (ctx.s.charCodeAt(ctx.p) === 46) while (isDigit(ctx.s.charCodeAt(++ctx.p)));
|
|
471
|
+
return readDate(ctx, ctx.s.slice(start, ctx.p), 4, false, start);
|
|
472
|
+
}
|
|
473
|
+
function readDate(ctx, str, type, unsafeDelim, errPtr, temporalSuffix) {
|
|
474
|
+
if (ctx.ld) {
|
|
475
|
+
let date = new TomlDate(str, type, unsafeDelim);
|
|
476
|
+
if (!date.isValid()) TomlError.x("invalid date", ctx, errPtr);
|
|
477
|
+
return date;
|
|
478
|
+
}
|
|
479
|
+
try {
|
|
480
|
+
if (temporalSuffix) str += temporalSuffix;
|
|
481
|
+
switch (type) {
|
|
482
|
+
case 1: return Temporal.ZonedDateTime.from(str);
|
|
483
|
+
case 2: return Temporal.PlainDateTime.from(str);
|
|
484
|
+
case 3: return Temporal.PlainDate.from(str);
|
|
485
|
+
case 4: return Temporal.PlainTime.from(str);
|
|
486
|
+
}
|
|
487
|
+
} catch (e) {
|
|
488
|
+
TomlError.x(e instanceof Error ? e.message : "" + e, ctx, errPtr);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
//#endregion
|
|
492
|
+
//#region ../../node_modules/.pnpm/smol-toml@1.9.1/node_modules/smol-toml/dist/util.js
|
|
493
|
+
/*!
|
|
494
|
+
* Copyright (c) Squirrel Chat et al., All rights reserved.
|
|
495
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
496
|
+
*
|
|
497
|
+
* Redistribution and use in source and binary forms, with or without
|
|
498
|
+
* modification, are permitted provided that the following conditions are met:
|
|
499
|
+
*
|
|
500
|
+
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
501
|
+
* list of conditions and the following disclaimer.
|
|
502
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
503
|
+
* this list of conditions and the following disclaimer in the
|
|
504
|
+
* documentation and/or other materials provided with the distribution.
|
|
505
|
+
* 3. Neither the name of the copyright holder nor the names of its contributors
|
|
506
|
+
* may be used to endorse or promote products derived from this software without
|
|
507
|
+
* specific prior written permission.
|
|
508
|
+
*
|
|
509
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
510
|
+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
511
|
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
512
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
513
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
514
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
515
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
516
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
517
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
518
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
519
|
+
*/
|
|
520
|
+
/** @internal */
|
|
521
|
+
function skipComment(ctx) {
|
|
522
|
+
for (; ctx.p < ctx.s.length; ctx.p++) {
|
|
523
|
+
let c = ctx.s.charCodeAt(ctx.p);
|
|
524
|
+
if (c === 10) break;
|
|
525
|
+
if (c === 13 && ctx.s.charCodeAt(ctx.p + 1) === 10) {
|
|
526
|
+
ctx.p++;
|
|
527
|
+
break;
|
|
528
|
+
}
|
|
529
|
+
if (c < 32 && c !== 9 || c === 127) TomlError.x("control characters are not allowed in comments", ctx);
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
/** @internal */
|
|
533
|
+
function skipVoid(ctx, banNewLines, banComments) {
|
|
534
|
+
let c;
|
|
535
|
+
while (ctx.p < ctx.s.length) {
|
|
536
|
+
while (ctx.p < ctx.s.length && ((c = ctx.s.charCodeAt(ctx.p)) === 32 || c === 9 || !banNewLines && (c === 10 || c === 13 && ctx.s.charCodeAt(ctx.p + 1) === 10))) ctx.p++;
|
|
537
|
+
if (banComments || c !== 35) break;
|
|
538
|
+
skipComment(ctx);
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
//#endregion
|
|
542
|
+
//#region ../../node_modules/.pnpm/smol-toml@1.9.1/node_modules/smol-toml/dist/struct.js
|
|
543
|
+
/*!
|
|
544
|
+
* Copyright (c) Squirrel Chat et al., All rights reserved.
|
|
545
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
546
|
+
*
|
|
547
|
+
* Redistribution and use in source and binary forms, with or without
|
|
548
|
+
* modification, are permitted provided that the following conditions are met:
|
|
549
|
+
*
|
|
550
|
+
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
551
|
+
* list of conditions and the following disclaimer.
|
|
552
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
553
|
+
* this list of conditions and the following disclaimer in the
|
|
554
|
+
* documentation and/or other materials provided with the distribution.
|
|
555
|
+
* 3. Neither the name of the copyright holder nor the names of its contributors
|
|
556
|
+
* may be used to endorse or promote products derived from this software without
|
|
557
|
+
* specific prior written permission.
|
|
558
|
+
*
|
|
559
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
560
|
+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
561
|
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
562
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
563
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
564
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
565
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
566
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
567
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
568
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
569
|
+
*/
|
|
570
|
+
/** @internal */
|
|
571
|
+
function parseKey(ctx, end = 61) {
|
|
572
|
+
let startPtr;
|
|
573
|
+
let state = 0;
|
|
574
|
+
let parsed = [];
|
|
575
|
+
let sliceStart;
|
|
576
|
+
let c = ctx.s.charCodeAt(startPtr = ctx.p);
|
|
577
|
+
do
|
|
578
|
+
if (c === end) {
|
|
579
|
+
if (!state) TomlError.x("unexpected end of key", ctx);
|
|
580
|
+
if (state === 1) parsed.push(ctx.s.slice(sliceStart, ctx.p));
|
|
581
|
+
return ctx.p++, parsed;
|
|
582
|
+
} else if (c === 46) {
|
|
583
|
+
if (!state) TomlError.x("illegal empty bare key", ctx);
|
|
584
|
+
if (state === 1) parsed.push(ctx.s.slice(sliceStart, ctx.p));
|
|
585
|
+
state = 0;
|
|
586
|
+
} else if (!state && (c === 34 || c === 39)) {
|
|
587
|
+
if (c === ctx.s.charCodeAt(ctx.p + 1) && c === ctx.s.charCodeAt(ctx.p + 2)) TomlError.x("illegal quoted key: multiline strings are not allowed", ctx);
|
|
588
|
+
parsed.push(parseString(ctx));
|
|
589
|
+
state = 2;
|
|
590
|
+
ctx.p--;
|
|
591
|
+
} else if (c === 32 || c === 9) {
|
|
592
|
+
if (state === 1) {
|
|
593
|
+
parsed.push(ctx.s.slice(sliceStart, ctx.p));
|
|
594
|
+
state = 2;
|
|
595
|
+
}
|
|
596
|
+
} else if (state === 2 || c < 48 && c !== 45 || c > 57 && c < 65 || c > 90 && c < 97 && c !== 95 || c > 122) TomlError.x("illegal character in key", ctx);
|
|
597
|
+
else if (!state) {
|
|
598
|
+
state = 1;
|
|
599
|
+
sliceStart = ctx.p;
|
|
600
|
+
}
|
|
601
|
+
while (c = ctx.s.charCodeAt(++ctx.p));
|
|
602
|
+
TomlError.x("incomplete key-value: cannot find end of key", ctx, startPtr);
|
|
603
|
+
}
|
|
604
|
+
/** @internal */
|
|
605
|
+
function parseInlineTable(ctx) {
|
|
606
|
+
let startPtr = ctx.p++;
|
|
607
|
+
let res = Object.create(null);
|
|
608
|
+
let seen = /* @__PURE__ */ new Set();
|
|
609
|
+
let c;
|
|
610
|
+
while (ctx.p < ctx.s.length) {
|
|
611
|
+
skipVoid(ctx);
|
|
612
|
+
if ((c = ctx.s.charCodeAt(ctx.p)) === 125) {
|
|
613
|
+
ctx.p++;
|
|
614
|
+
return res;
|
|
615
|
+
}
|
|
616
|
+
let k;
|
|
617
|
+
let t = res;
|
|
618
|
+
let hasOwn = false;
|
|
619
|
+
let errPtr = ctx.p;
|
|
620
|
+
let key = parseKey(ctx);
|
|
621
|
+
for (let i = 0; i < key.length; i++) {
|
|
622
|
+
if (i) t = hasOwn ? t[k] : t[k] = Object.create(null);
|
|
623
|
+
k = key[i];
|
|
624
|
+
if ((hasOwn = Object.hasOwn(t, k)) && (typeof t[k] !== "object" || seen.has(t[k]))) TomlError.x("trying to redefine an already defined value", ctx, errPtr);
|
|
625
|
+
let unsafe = k === "__proto__";
|
|
626
|
+
if (ctx.uk && (unsafe || k === "constructor")) {
|
|
627
|
+
t = ctx.uk !== 1 && TomlError.x("document contains an unsafe property", ctx, errPtr);
|
|
628
|
+
break;
|
|
629
|
+
}
|
|
630
|
+
if (!hasOwn && unsafe) Object.defineProperty(t, k, {
|
|
631
|
+
enumerable: true,
|
|
632
|
+
configurable: true,
|
|
633
|
+
writable: true
|
|
634
|
+
});
|
|
635
|
+
}
|
|
636
|
+
if (hasOwn) TomlError.x("trying to redefine an already defined value", ctx, errPtr);
|
|
637
|
+
skipVoid(ctx, true, true);
|
|
638
|
+
let value = extractValue(ctx, 125);
|
|
639
|
+
if (t && typeof (t[k] = value) === "object") seen.add(value);
|
|
640
|
+
skipVoid(ctx);
|
|
641
|
+
if ((c = ctx.s.charCodeAt(ctx.p++)) === 125) return res;
|
|
642
|
+
if (c !== 44) TomlError.x("expected comma or end of structure", ctx, ctx.p - 1);
|
|
643
|
+
}
|
|
644
|
+
TomlError.x("unfinished table", ctx, startPtr);
|
|
645
|
+
}
|
|
646
|
+
/** @internal */
|
|
647
|
+
function parseArray(ctx) {
|
|
648
|
+
let startPtr = ctx.p++;
|
|
649
|
+
let res = [];
|
|
650
|
+
let c;
|
|
651
|
+
while (ctx.p < ctx.s.length) {
|
|
652
|
+
skipVoid(ctx);
|
|
653
|
+
if ((c = ctx.s.charCodeAt(ctx.p)) === 93) {
|
|
654
|
+
ctx.p++;
|
|
655
|
+
return res;
|
|
656
|
+
}
|
|
657
|
+
res.push(extractValue(ctx, 93));
|
|
658
|
+
skipVoid(ctx);
|
|
659
|
+
if ((c = ctx.s.charCodeAt(ctx.p++)) === 93) return res;
|
|
660
|
+
if (c !== 44) TomlError.x("expected comma or end of structure", ctx, ctx.p - 1);
|
|
661
|
+
}
|
|
662
|
+
TomlError.x("unfinished array", ctx, startPtr);
|
|
663
|
+
}
|
|
664
|
+
//#endregion
|
|
665
|
+
//#region ../../node_modules/.pnpm/smol-toml@1.9.1/node_modules/smol-toml/dist/parse.js
|
|
666
|
+
/*!
|
|
667
|
+
* Copyright (c) Squirrel Chat et al., All rights reserved.
|
|
668
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
669
|
+
*
|
|
670
|
+
* Redistribution and use in source and binary forms, with or without
|
|
671
|
+
* modification, are permitted provided that the following conditions are met:
|
|
672
|
+
*
|
|
673
|
+
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
674
|
+
* list of conditions and the following disclaimer.
|
|
675
|
+
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
676
|
+
* this list of conditions and the following disclaimer in the
|
|
677
|
+
* documentation and/or other materials provided with the distribution.
|
|
678
|
+
* 3. Neither the name of the copyright holder nor the names of its contributors
|
|
679
|
+
* may be used to endorse or promote products derived from this software without
|
|
680
|
+
* specific prior written permission.
|
|
681
|
+
*
|
|
682
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
683
|
+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
684
|
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
685
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
686
|
+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
687
|
+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
688
|
+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
689
|
+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
690
|
+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
691
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
692
|
+
*/
|
|
693
|
+
function peekTable(ctx, key, table, meta, type) {
|
|
694
|
+
let t = table;
|
|
695
|
+
let m = meta;
|
|
696
|
+
let k;
|
|
697
|
+
let hasOwn = false;
|
|
698
|
+
let state;
|
|
699
|
+
for (let i = 0; i < key.length; i++) {
|
|
700
|
+
if (i) {
|
|
701
|
+
t = hasOwn ? t[k] : t[k] = Object.create(null);
|
|
702
|
+
m = (state = m[k]).c;
|
|
703
|
+
if (type === 0 && (state.t === 1 || state.t === 2)) return null;
|
|
704
|
+
if (state.t === 2) {
|
|
705
|
+
let l = t.length - 1;
|
|
706
|
+
t = t[l];
|
|
707
|
+
m = m[l].c;
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
k = key[i];
|
|
711
|
+
if ((hasOwn = Object.hasOwn(t, k)) && m[k]?.t === 0 && m[k]?.d) return null;
|
|
712
|
+
if (!hasOwn) {
|
|
713
|
+
let unsafe = k === "__proto__";
|
|
714
|
+
if (ctx.uk && (unsafe || k === "constructor")) return false;
|
|
715
|
+
if (unsafe) {
|
|
716
|
+
Object.defineProperty(t, k, {
|
|
717
|
+
enumerable: true,
|
|
718
|
+
configurable: true,
|
|
719
|
+
writable: true
|
|
720
|
+
});
|
|
721
|
+
Object.defineProperty(m, k, {
|
|
722
|
+
enumerable: true,
|
|
723
|
+
configurable: true,
|
|
724
|
+
writable: true
|
|
725
|
+
});
|
|
726
|
+
}
|
|
727
|
+
m[k] = {
|
|
728
|
+
t: i < key.length - 1 && type === 2 ? 3 : type,
|
|
729
|
+
d: false,
|
|
730
|
+
i: 0,
|
|
731
|
+
c: Object.create(null)
|
|
732
|
+
};
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
state = m[k];
|
|
736
|
+
if (state.t !== type && !(type === 1 && state.t === 3)) return null;
|
|
737
|
+
if (type === 2) {
|
|
738
|
+
if (!state.d) {
|
|
739
|
+
state.d = true;
|
|
740
|
+
t[k] = [];
|
|
741
|
+
}
|
|
742
|
+
t[k].push(t = Object.create(null));
|
|
743
|
+
state.c[state.i++] = state = {
|
|
744
|
+
t: 1,
|
|
745
|
+
d: false,
|
|
746
|
+
i: 0,
|
|
747
|
+
c: Object.create(null)
|
|
748
|
+
};
|
|
749
|
+
}
|
|
750
|
+
if (state.d) return null;
|
|
751
|
+
state.d = true;
|
|
752
|
+
if (type === 1) t = hasOwn ? t[k] : t[k] = Object.create(null);
|
|
753
|
+
else if (type === 0 && hasOwn) return null;
|
|
754
|
+
return [
|
|
755
|
+
k,
|
|
756
|
+
t,
|
|
757
|
+
state.c
|
|
758
|
+
];
|
|
759
|
+
}
|
|
760
|
+
function validateTablePeek(ctx, peek, ptr) {
|
|
761
|
+
if (peek === null || ctx.uk === 2) TomlError.x(peek === null ? "trying to redefine an already defined table or value" : "document contains an unsafe property", ctx, ptr);
|
|
762
|
+
}
|
|
763
|
+
function parse(toml, options = {}) {
|
|
764
|
+
let ctx = {
|
|
765
|
+
s: toml,
|
|
766
|
+
p: 0,
|
|
767
|
+
d: options.maxDepth ?? 1e3,
|
|
768
|
+
bi: options.integersAsBigInt ?? false,
|
|
769
|
+
ld: options.useLegacyDate ?? true,
|
|
770
|
+
uk: options.unsafeKeyBehaviour === "throw" ? 2 : options.unsafeKeyBehaviour === "drop" ? 1 : 0
|
|
771
|
+
};
|
|
772
|
+
let res = Object.create(null);
|
|
773
|
+
let meta = Object.create(null);
|
|
774
|
+
let tmp;
|
|
775
|
+
let skipping = false;
|
|
776
|
+
let tbl = res;
|
|
777
|
+
let m = meta;
|
|
778
|
+
if (toml.charCodeAt(0) === 65279) ctx.p++;
|
|
779
|
+
skipVoid(ctx);
|
|
780
|
+
while (ctx.p < toml.length) {
|
|
781
|
+
if (toml.charCodeAt(ctx.p) === 91) {
|
|
782
|
+
let isTableArray = toml.charCodeAt(++ctx.p) === 91;
|
|
783
|
+
tmp = ctx.p += +isTableArray;
|
|
784
|
+
skipping = false;
|
|
785
|
+
let k = parseKey(ctx, 93);
|
|
786
|
+
if (isTableArray) {
|
|
787
|
+
if (toml.charCodeAt(ctx.p) !== 93) TomlError.x("expected end of table array declaration", ctx);
|
|
788
|
+
ctx.p++;
|
|
789
|
+
}
|
|
790
|
+
let p = peekTable(ctx, k, res, meta, isTableArray ? 2 : 1);
|
|
791
|
+
if (!p) {
|
|
792
|
+
validateTablePeek(ctx, p, tmp);
|
|
793
|
+
skipping = true;
|
|
794
|
+
} else {
|
|
795
|
+
m = p[2];
|
|
796
|
+
tbl = p[1];
|
|
797
|
+
}
|
|
798
|
+
} else {
|
|
799
|
+
tmp = ctx.p;
|
|
800
|
+
let p = peekTable(ctx, parseKey(ctx), tbl, m, 0);
|
|
801
|
+
if (!p && !skipping) validateTablePeek(ctx, p, tmp);
|
|
802
|
+
skipVoid(ctx, true, true);
|
|
803
|
+
let v = extractValue(ctx, void 0);
|
|
804
|
+
if (p && !skipping) p[1][p[0]] = v;
|
|
805
|
+
}
|
|
806
|
+
skipVoid(ctx, true);
|
|
807
|
+
if (ctx.p < toml.length && (tmp = toml.charCodeAt(ctx.p)) !== 10 && (tmp !== 13 || toml.charCodeAt(ctx.p + 1) !== 10)) TomlError.x("each key-value declaration must be followed by an end-of-line", ctx);
|
|
808
|
+
skipVoid(ctx);
|
|
809
|
+
}
|
|
810
|
+
return res;
|
|
811
|
+
}
|
|
812
|
+
//#endregion
|
|
813
|
+
//#region src/cli/rls/rbac.ts
|
|
814
|
+
/**
|
|
815
|
+
* Where the helpers read roles and memberships: the flag, `rls.authorize`,
|
|
816
|
+
* `rls.rbac.authorize`, then `database` with `rls.membershipSources`, with
|
|
817
|
+
* `--rbac` or with a mapped memberships table, else `jwt`.
|
|
818
|
+
*/
|
|
819
|
+
function resolveAuthorize(config, flags = {}) {
|
|
820
|
+
const rls = config.rls;
|
|
821
|
+
const explicit = flags.authorize ?? rls?.authorize ?? rls?.rbac?.authorize;
|
|
822
|
+
if (explicit !== void 0) return explicit;
|
|
823
|
+
if (rls?.membershipSources !== void 0 || flags.rbac === true) return "database";
|
|
824
|
+
const memberships = flags.memberships ?? rls?.memberships;
|
|
825
|
+
return memberships?.tenant !== void 0 || memberships?.team !== void 0 || Object.keys(memberships?.scopes ?? {}).length > 0 ? "database" : "jwt";
|
|
826
|
+
}
|
|
827
|
+
function parseRbacAuthorize(raw) {
|
|
828
|
+
if (raw === void 0) return;
|
|
829
|
+
if (raw === "database" || raw === "jwt") return raw;
|
|
830
|
+
throw configError(`PermDock CLI: --authorize must be database or jwt, got '${raw}'`);
|
|
831
|
+
}
|
|
832
|
+
function hookUri(schema) {
|
|
833
|
+
return `pg-functions://postgres/${schema}/custom_access_token_hook`;
|
|
834
|
+
}
|
|
835
|
+
function createEnum(schema, name, values) {
|
|
836
|
+
const list = values.map((value) => quoteLiteral(value)).join(", ");
|
|
837
|
+
return `do $$ begin
|
|
838
|
+
create type ${quoteTable(`${schema}.${name}`)} as enum (${list});
|
|
839
|
+
exception when duplicate_object then null;
|
|
840
|
+
end $$;`;
|
|
841
|
+
}
|
|
842
|
+
/** A read policy and `select` grant for `supabase_auth_admin` on a table the hook reads. */
|
|
843
|
+
function authAdminRead(table, label) {
|
|
844
|
+
const t = quoteQualified(table);
|
|
845
|
+
const policy = quoteIdent(`permdock_auth_admin_read_${label}`);
|
|
846
|
+
return `grant select on table ${t} to supabase_auth_admin;
|
|
847
|
+
drop policy if exists ${policy} on ${t};
|
|
848
|
+
create policy ${policy} on ${t}
|
|
849
|
+
as permissive for select
|
|
850
|
+
to supabase_auth_admin
|
|
851
|
+
using (true);`;
|
|
852
|
+
}
|
|
853
|
+
/**
|
|
854
|
+
* Supabase's Custom Claims and RBAC scaffold on top of the PermDock helpers:
|
|
855
|
+
* enums, `user_roles` and `authorize()` over the shared `role_permissions`.
|
|
856
|
+
* The token hook comes only from `permdock supabase hook generate`, so one
|
|
857
|
+
* function writes the claims. Policies never call `authorize()` per row; they
|
|
858
|
+
* call the helpers. Never grants anything to `service_role`.
|
|
859
|
+
*/
|
|
860
|
+
function rbacScaffold(policy, options) {
|
|
861
|
+
const schema = options.schema;
|
|
862
|
+
const q = (name) => quoteTable(`${schema}.${name}`);
|
|
863
|
+
const s = quoteIdent(schema);
|
|
864
|
+
const permissions = [...new Set(policy.grants.map((grant) => grant.permission.key))];
|
|
865
|
+
const authorizeFn = authorizeSql({
|
|
866
|
+
schema,
|
|
867
|
+
authorize: options.authorize,
|
|
868
|
+
...options.scope === void 0 ? {} : { scope: options.scope },
|
|
869
|
+
...options.memberships === void 0 ? {} : { tenant: options.memberships },
|
|
870
|
+
...options.customRoles === void 0 ? {} : { customRoles: options.customRoles },
|
|
871
|
+
...options.context?.suspension === void 0 ? {} : { suspension: options.context.suspension }
|
|
872
|
+
});
|
|
873
|
+
return {
|
|
874
|
+
head: `-- rbac scaffold (Supabase Custom Claims and RBAC)
|
|
875
|
+
-- authorize: ${options.authorize}${options.authorize === "jwt" ? " (reads the hook claims; stale until the token refreshes)" : " (reads user_roles on every statement)"}
|
|
876
|
+
-- the custom access token hook that writes user_role${options.authorize === "jwt" ? " and memberships" : ""}: permdock supabase hook generate
|
|
877
|
+
${schema === "public" ? "" : `create schema if not exists ${s};\n`}${createEnum(schema, "app_role", roleNames(policy))}
|
|
878
|
+
${createEnum(schema, "app_permission", permissions)}
|
|
879
|
+
|
|
880
|
+
create table if not exists ${q("user_roles")} (
|
|
881
|
+
user_id uuid not null references auth.users on delete cascade,
|
|
882
|
+
role ${options.customRoles === void 0 ? q("app_role") : "text"} not null,
|
|
883
|
+
primary key (user_id, role)
|
|
884
|
+
);
|
|
885
|
+
|
|
886
|
+
alter table ${q("user_roles")} enable row level security;
|
|
887
|
+
revoke all on table ${q("user_roles")} from authenticated, anon, public;
|
|
888
|
+
`,
|
|
889
|
+
tail: authorizeFn,
|
|
890
|
+
warnings: []
|
|
891
|
+
};
|
|
892
|
+
}
|
|
893
|
+
//#endregion
|
|
27
894
|
//#region src/cli/supabase-config.ts
|
|
28
895
|
const SUPABASE_CONFIG = "supabase/config.toml";
|
|
29
896
|
function table(value) {
|
|
@@ -50,6 +917,9 @@ function readSupabaseConfig(cwd) {
|
|
|
50
917
|
const paths = table(table(root["db"])?.["migrations"])?.["schema_paths"];
|
|
51
918
|
const schemaPaths = strings(paths);
|
|
52
919
|
const apiSchemas = strings(table(root["api"])?.["schemas"]);
|
|
920
|
+
const hookTable = table(table(table(root["auth"])?.["hook"])?.["custom_access_token"]);
|
|
921
|
+
const hookEnabled = hookTable?.["enabled"];
|
|
922
|
+
const hookUriValue = hookTable?.["uri"];
|
|
53
923
|
const pgDelta = table(table(root["experimental"])?.["pgdelta"]);
|
|
54
924
|
const schemaPath = pgDelta?.["declarative_schema_path"];
|
|
55
925
|
const enabled = pgDelta?.["enabled"];
|
|
@@ -59,6 +929,10 @@ function readSupabaseConfig(cwd) {
|
|
|
59
929
|
...typeof expiry === "number" ? { jwtExpiry: expiry } : {},
|
|
60
930
|
...schemaPaths === void 0 ? {} : { schemaPaths },
|
|
61
931
|
...apiSchemas === void 0 ? {} : { apiSchemas },
|
|
932
|
+
...hookTable === void 0 ? {} : { customAccessTokenHook: {
|
|
933
|
+
...typeof hookEnabled === "boolean" ? { enabled: hookEnabled } : {},
|
|
934
|
+
...typeof hookUriValue === "string" ? { uri: hookUriValue } : {}
|
|
935
|
+
} },
|
|
62
936
|
...pgDelta === void 0 ? {} : { pgDelta: {
|
|
63
937
|
...typeof enabled === "boolean" ? { enabled } : {},
|
|
64
938
|
schemaDir: declarativeSchemaDir(schemaPath)
|
|
@@ -86,6 +960,32 @@ function pd045(cwd) {
|
|
|
86
960
|
fix: `fix the TOML syntax in ${SUPABASE_CONFIG}; until then PermDock assumes Supabase's defaults for jwt_expiry, schema_paths and [experimental.pgdelta], and generates for pg-delta`
|
|
87
961
|
}];
|
|
88
962
|
}
|
|
963
|
+
/**
|
|
964
|
+
* PD074: `supabase.hook` is configured but `[auth.hook.custom_access_token]`
|
|
965
|
+
* in `supabase/config.toml` does not enable the generated function, so a
|
|
966
|
+
* local stack and every branch push issue tokens without memberships.
|
|
967
|
+
*/
|
|
968
|
+
function pd074(cwd, config) {
|
|
969
|
+
const hook = config.supabase?.hook;
|
|
970
|
+
const read = readSupabaseConfig(cwd);
|
|
971
|
+
if (hook === void 0 || read === void 0 || !read.ok) return [];
|
|
972
|
+
const expected = hookUri(hook.schema ?? config.rls?.schema ?? "permdock");
|
|
973
|
+
const found = read.config.customAccessTokenHook;
|
|
974
|
+
const fix = `add to ${SUPABASE_CONFIG}:\n[auth.hook.custom_access_token]\nenabled = true\nuri = "${expected}"`;
|
|
975
|
+
if (found?.enabled !== true) return [{
|
|
976
|
+
code: "PD074",
|
|
977
|
+
severity: "warning",
|
|
978
|
+
message: `supabase.hook is configured but ${SUPABASE_CONFIG} does not set [auth.hook.custom_access_token] enabled = true, so Auth never calls the hook`,
|
|
979
|
+
fix
|
|
980
|
+
}];
|
|
981
|
+
if (found.uri !== expected) return [{
|
|
982
|
+
code: "PD074",
|
|
983
|
+
severity: "warning",
|
|
984
|
+
message: `[auth.hook.custom_access_token] uri is ${found.uri ?? "missing"}, but the generated hook is ${expected}`,
|
|
985
|
+
fix: `set uri = "${expected}" in ${SUPABASE_CONFIG}`
|
|
986
|
+
}];
|
|
987
|
+
return [];
|
|
988
|
+
}
|
|
89
989
|
//#endregion
|
|
90
990
|
//#region src/cli/claims-schema.ts
|
|
91
991
|
/**
|
|
@@ -123,6 +1023,11 @@ const PERMDOCK_CLAIMS_SCHEMA = {
|
|
|
123
1023
|
description: "true when the size budget cut memberships or attrs.",
|
|
124
1024
|
type: "boolean"
|
|
125
1025
|
},
|
|
1026
|
+
team_ids: {
|
|
1027
|
+
description: "The uuid of every team the user belongs to (supabase.hook.teams), cut by the memberships budget.",
|
|
1028
|
+
type: "array",
|
|
1029
|
+
items: { type: "string" }
|
|
1030
|
+
},
|
|
126
1031
|
tenant_id: {
|
|
127
1032
|
description: "The active tenant (the default rls.tenantClaim): the canonical text of one instance of the first scope.",
|
|
128
1033
|
type: "string"
|
|
@@ -268,6 +1173,7 @@ const RESERVED_CLAIMS = /* @__PURE__ */ new Set([
|
|
|
268
1173
|
"user_role",
|
|
269
1174
|
"memberships",
|
|
270
1175
|
"memberships_truncated",
|
|
1176
|
+
"team_ids",
|
|
271
1177
|
"attrs",
|
|
272
1178
|
"authz_ver",
|
|
273
1179
|
"sub",
|
|
@@ -346,6 +1252,7 @@ function validateSql(parts) {
|
|
|
346
1252
|
"roles",
|
|
347
1253
|
"memberships",
|
|
348
1254
|
"memberships_truncated",
|
|
1255
|
+
...parts.hook.teams === void 0 ? [] : ["team_ids"],
|
|
349
1256
|
"attrs",
|
|
350
1257
|
"authz_ver",
|
|
351
1258
|
parts.tenantClaim
|
|
@@ -398,6 +1305,7 @@ function hookClaims(parts) {
|
|
|
398
1305
|
permdockClaim("memberships", true),
|
|
399
1306
|
permdockClaim("memberships_truncated"),
|
|
400
1307
|
permdockClaim(parts.tenantClaim),
|
|
1308
|
+
...parts.hook.teams === void 0 ? [] : [permdockClaim("team_ids", true)],
|
|
401
1309
|
...parts.attrs === void 0 ? [] : [permdockClaim("attrs", true)],
|
|
402
1310
|
...parts.version ? [permdockClaim("authz_ver")] : [],
|
|
403
1311
|
...parts.extra.map((entry) => ({
|
|
@@ -408,6 +1316,18 @@ function hookClaims(parts) {
|
|
|
408
1316
|
];
|
|
409
1317
|
}
|
|
410
1318
|
//#endregion
|
|
1319
|
+
//#region src/cli/sql/declarative.ts
|
|
1320
|
+
/**
|
|
1321
|
+
* A migration's SQL as a declarative schema file: pg-delta diffs the file
|
|
1322
|
+
* against the database itself, so a `drop trigger if exists` or
|
|
1323
|
+
* `drop policy if exists` before its `create` is an error, and a trigger is
|
|
1324
|
+
* `create or replace trigger`. A constraint trigger stays `create constraint trigger`, because
|
|
1325
|
+
* pg-delta has no `create or replace constraint trigger`. A policy keeps its plain `create policy`.
|
|
1326
|
+
*/
|
|
1327
|
+
function declarativeSql(sql) {
|
|
1328
|
+
return sql.replaceAll(/^drop (?:trigger|policy) if exists [^;\n]+;\n/gmu, "").replaceAll(/^create trigger /gmu, "create or replace trigger ");
|
|
1329
|
+
}
|
|
1330
|
+
//#endregion
|
|
411
1331
|
//#region src/cli/supabase-schemas.ts
|
|
412
1332
|
const MODES = [
|
|
413
1333
|
"pg-delta",
|
|
@@ -576,87 +1496,6 @@ function readClaimsFixture(path) {
|
|
|
576
1496
|
}
|
|
577
1497
|
}
|
|
578
1498
|
//#endregion
|
|
579
|
-
//#region src/cli/rls/rbac.ts
|
|
580
|
-
/**
|
|
581
|
-
* Where the helpers read roles and memberships: the flag, `rls.authorize`,
|
|
582
|
-
* `rls.rbac.authorize`, then `database` with `rls.membershipSources`, with
|
|
583
|
-
* `--rbac` or with a mapped memberships table, else `jwt`.
|
|
584
|
-
*/
|
|
585
|
-
function resolveAuthorize(config, flags = {}) {
|
|
586
|
-
const rls = config.rls;
|
|
587
|
-
const explicit = flags.authorize ?? rls?.authorize ?? rls?.rbac?.authorize;
|
|
588
|
-
if (explicit !== void 0) return explicit;
|
|
589
|
-
if (rls?.membershipSources !== void 0 || flags.rbac === true) return "database";
|
|
590
|
-
const memberships = flags.memberships ?? rls?.memberships;
|
|
591
|
-
return memberships?.tenant !== void 0 || memberships?.team !== void 0 || Object.keys(memberships?.scopes ?? {}).length > 0 ? "database" : "jwt";
|
|
592
|
-
}
|
|
593
|
-
function parseRbacAuthorize(raw) {
|
|
594
|
-
if (raw === void 0) return;
|
|
595
|
-
if (raw === "database" || raw === "jwt") return raw;
|
|
596
|
-
throw configError(`PermDock CLI: --authorize must be database or jwt, got '${raw}'`);
|
|
597
|
-
}
|
|
598
|
-
function hookUri(schema) {
|
|
599
|
-
return `pg-functions://postgres/${schema}/custom_access_token_hook`;
|
|
600
|
-
}
|
|
601
|
-
function createEnum(schema, name, values) {
|
|
602
|
-
const list = values.map((value) => quoteLiteral(value)).join(", ");
|
|
603
|
-
return `do $$ begin
|
|
604
|
-
create type ${quoteTable(`${schema}.${name}`)} as enum (${list});
|
|
605
|
-
exception when duplicate_object then null;
|
|
606
|
-
end $$;`;
|
|
607
|
-
}
|
|
608
|
-
/** A read policy and `select` grant for `supabase_auth_admin` on a table the hook reads. */
|
|
609
|
-
function authAdminRead(table, label) {
|
|
610
|
-
const t = quoteQualified(table);
|
|
611
|
-
const policy = quoteIdent(`permdock_auth_admin_read_${label}`);
|
|
612
|
-
return `grant select on table ${t} to supabase_auth_admin;
|
|
613
|
-
drop policy if exists ${policy} on ${t};
|
|
614
|
-
create policy ${policy} on ${t}
|
|
615
|
-
as permissive for select
|
|
616
|
-
to supabase_auth_admin
|
|
617
|
-
using (true);`;
|
|
618
|
-
}
|
|
619
|
-
/**
|
|
620
|
-
* Supabase's Custom Claims and RBAC scaffold on top of the PermDock helpers:
|
|
621
|
-
* enums, `user_roles` and `authorize()` over the shared `role_permissions`.
|
|
622
|
-
* The token hook comes only from `permdock supabase hook generate`, so one
|
|
623
|
-
* function writes the claims. Policies never call `authorize()` per row; they
|
|
624
|
-
* call the helpers. Never grants anything to `service_role`.
|
|
625
|
-
*/
|
|
626
|
-
function rbacScaffold(policy, options) {
|
|
627
|
-
const schema = options.schema;
|
|
628
|
-
const q = (name) => quoteTable(`${schema}.${name}`);
|
|
629
|
-
const s = quoteIdent(schema);
|
|
630
|
-
const permissions = [...new Set(policy.grants.map((grant) => grant.permission.key))];
|
|
631
|
-
const authorizeFn = authorizeSql({
|
|
632
|
-
schema,
|
|
633
|
-
authorize: options.authorize,
|
|
634
|
-
...options.scope === void 0 ? {} : { scope: options.scope },
|
|
635
|
-
...options.memberships === void 0 ? {} : { tenant: options.memberships },
|
|
636
|
-
...options.customRoles === void 0 ? {} : { customRoles: options.customRoles },
|
|
637
|
-
...options.context?.suspension === void 0 ? {} : { suspension: options.context.suspension }
|
|
638
|
-
});
|
|
639
|
-
return {
|
|
640
|
-
head: `-- rbac scaffold (Supabase Custom Claims and RBAC)
|
|
641
|
-
-- authorize: ${options.authorize}${options.authorize === "jwt" ? " (reads the hook claims; stale until the token refreshes)" : " (reads user_roles on every statement)"}
|
|
642
|
-
-- the custom access token hook that writes user_role${options.authorize === "jwt" ? " and memberships" : ""}: permdock supabase hook generate
|
|
643
|
-
${schema === "public" ? "" : `create schema if not exists ${s};\n`}${createEnum(schema, "app_role", roleNames(policy))}
|
|
644
|
-
${createEnum(schema, "app_permission", permissions)}
|
|
645
|
-
|
|
646
|
-
create table if not exists ${q("user_roles")} (
|
|
647
|
-
user_id uuid not null references auth.users on delete cascade,
|
|
648
|
-
role ${options.customRoles === void 0 ? q("app_role") : "text"} not null,
|
|
649
|
-
primary key (user_id, role)
|
|
650
|
-
);
|
|
651
|
-
|
|
652
|
-
alter table ${q("user_roles")} enable row level security;
|
|
653
|
-
revoke all on table ${q("user_roles")} from authenticated, anon, public;
|
|
654
|
-
`,
|
|
655
|
-
tail: authorizeFn,
|
|
656
|
-
warnings: []
|
|
657
|
-
};
|
|
658
|
-
}
|
|
659
|
-
//#endregion
|
|
660
1499
|
//#region src/cli/supabase-hook/memberships.ts
|
|
661
1500
|
function memberForPlan(input) {
|
|
662
1501
|
const memberFor = input.scopes.map((scope) => scope.name).filter((name) => hasMemberFor({
|
|
@@ -792,7 +1631,7 @@ function subjectForSql(parts, config) {
|
|
|
792
1631
|
const schema = quoteIdent(parts.schema);
|
|
793
1632
|
const fn = `${schema}.${SUBJECT_FOR}`;
|
|
794
1633
|
const rows = parts.roles;
|
|
795
|
-
const roles = rows === void 0 ? ` held := '[]'::jsonb;` : ` select coalesce(jsonb_agg(distinct ${rows.roleSql} order by ${rows.roleSql}), '[]'::jsonb)
|
|
1634
|
+
const roles = rows === void 0 ? ` held := '[]'::jsonb;` : ` select coalesce(jsonb_agg(distinct ${rows.roleSql} order by ${rows.roleSql}) filter (where ${rows.roleSql} is not null), '[]'::jsonb)
|
|
796
1635
|
into held
|
|
797
1636
|
from ${rows.from}
|
|
798
1637
|
where ${rows.userSql} = v_roles_user;`;
|
|
@@ -803,6 +1642,20 @@ function subjectForSql(parts, config) {
|
|
|
803
1642
|
const version = parts.version ? `
|
|
804
1643
|
select v.version into ver from ${schema}.${quoteIdent(AUTHZ_VERSION_TABLE)} v where v.user_id = uid;
|
|
805
1644
|
ver := coalesce(ver, 0);` : "";
|
|
1645
|
+
const teamsConfig = parts.hook.teams;
|
|
1646
|
+
const teams = teamsConfig === void 0 ? "" : `
|
|
1647
|
+
select coalesce(jsonb_agg(to_jsonb(t.${quoteIdent(teamsConfig.team)}::text) order by t.${quoteIdent(teamsConfig.team)}), '[]'::jsonb)
|
|
1648
|
+
into team_ids
|
|
1649
|
+
from ${quoteQualified(teamsConfig.table)} t
|
|
1650
|
+
where t.${quoteIdent(teamsConfig.user)} = uid;
|
|
1651
|
+
if team_ids <> '[]'::jsonb then
|
|
1652
|
+
claims := jsonb_set(claims, '{team_ids}', team_ids);
|
|
1653
|
+
end if;`;
|
|
1654
|
+
const extra = parts.extra.map((entry) => `
|
|
1655
|
+
extra := ${quoteTable(entry.fn)}(uid);
|
|
1656
|
+
if extra is not null then
|
|
1657
|
+
claims := jsonb_set(claims, ${quoteLiteral(`{${entry.claim}}`)}, extra);
|
|
1658
|
+
end if;`).join("");
|
|
806
1659
|
const custom = customRolesOn(config.rls) && resolveAuthorize(config) === "database" ? customRolesOfSql(parts) : "";
|
|
807
1660
|
return `-- the subject the hook would mint for p_user, for a backend acting for a stored user; no client role may execute it
|
|
808
1661
|
create or replace function ${fn}(p_user uuid)
|
|
@@ -817,7 +1670,8 @@ declare
|
|
|
817
1670
|
held jsonb;
|
|
818
1671
|
memberships jsonb;
|
|
819
1672
|
custom jsonb := '[]'::jsonb;
|
|
820
|
-
ver bigint
|
|
1673
|
+
ver bigint;
|
|
1674
|
+
claims jsonb := '{}'::jsonb;${teamsConfig === void 0 ? "" : "\n team_ids jsonb := '[]'::jsonb;"}${parts.extra.length === 0 ? "" : "\n extra jsonb;"}${typedUsers(parts)}
|
|
821
1675
|
begin
|
|
822
1676
|
if uid is null or not exists (select 1 from auth.users u where u.id = uid) then
|
|
823
1677
|
return null;
|
|
@@ -827,8 +1681,9 @@ ${roles}
|
|
|
827
1681
|
into memberships
|
|
828
1682
|
from (
|
|
829
1683
|
${entriesSql(parts).replaceAll(/^/gmu, " ")}
|
|
830
|
-
) x;${custom}${version}
|
|
1684
|
+
) x;${custom}${version}${teams}${extra}
|
|
831
1685
|
return jsonb_strip_nulls(jsonb_build_object(
|
|
1686
|
+
'claims', case when claims = '{}'::jsonb then null else claims end,
|
|
832
1687
|
'id', uid::text,
|
|
833
1688
|
'active', true,
|
|
834
1689
|
'roles', held,
|
|
@@ -841,8 +1696,11 @@ $$;
|
|
|
841
1696
|
revoke execute on function ${fn}(uuid) from public, anon, authenticated;`;
|
|
842
1697
|
}
|
|
843
1698
|
/**
|
|
844
|
-
* The PostgREST wrappers `supabase.hook.api` asks for: one `security
|
|
1699
|
+
* The PostgREST wrappers `supabase.hook.api` asks for: one `security invoker`
|
|
845
1700
|
* function per reader, in the API schema, executable by `service_role` only.
|
|
1701
|
+
* The `security definer` readers stay in the hook schema, which the Data API
|
|
1702
|
+
* does not expose; `service_role` gets `usage` on it and `execute` on each
|
|
1703
|
+
* reader, so no definer function sits in an exposed schema.
|
|
846
1704
|
*/
|
|
847
1705
|
function apiWrappersSql(parts) {
|
|
848
1706
|
const api = parts.hook.api;
|
|
@@ -857,13 +1715,16 @@ function apiWrappersSql(parts) {
|
|
|
857
1715
|
returns ${returns}
|
|
858
1716
|
language sql
|
|
859
1717
|
stable
|
|
860
|
-
security
|
|
1718
|
+
security invoker
|
|
861
1719
|
set search_path = ''
|
|
862
1720
|
as $$ select ${source}.${inner}(${args}) $$;
|
|
863
1721
|
revoke execute on function ${fn}(${types}) from public, anon, authenticated;
|
|
864
|
-
grant execute on function ${fn}(${types}) to service_role
|
|
1722
|
+
grant execute on function ${fn}(${types}) to service_role;
|
|
1723
|
+
grant execute on function ${source}.${inner}(${types}) to service_role;`;
|
|
865
1724
|
};
|
|
866
|
-
return `-- supabase.hook.api: wrappers in ${quoteIdent(target)} for a backend that reaches the hook schema through the Data API; only service_role may execute them
|
|
1725
|
+
return `-- supabase.hook.api: security invoker wrappers in ${quoteIdent(target)} for a backend that reaches the hook schema through the Data API; only service_role may execute them, and the security definer readers stay in ${source}
|
|
1726
|
+
grant usage on schema ${source} to service_role;
|
|
1727
|
+
|
|
867
1728
|
${wrapper(names.subjectFor, SUBJECT_FOR, "p_user uuid", "p_user", "uuid", "jsonb")}
|
|
868
1729
|
|
|
869
1730
|
${wrapper(names.membersOf, MEMBERS_OF, "p_scope text, p_id text", "p_scope, p_id", "text, text", "jsonb")}
|
|
@@ -935,9 +1796,10 @@ $$;
|
|
|
935
1796
|
revoke execute on function ${fn}(text, text) from public, anon, authenticated;`;
|
|
936
1797
|
}
|
|
937
1798
|
/**
|
|
938
|
-
* The custom roles `p_user` holds: tenant roles named on a
|
|
939
|
-
* scope (and instance) they live at, and platform roles
|
|
940
|
-
* roles, each with its grants and includes in `CustomRole`
|
|
1799
|
+
* The custom roles `p_user` holds: tenant and shared roles named on a
|
|
1800
|
+
* membership of the scope (and instance) they live at, and platform roles
|
|
1801
|
+
* among the global roles, each with its grants and includes in `CustomRole`
|
|
1802
|
+
* form. A shadowed tenant role comes along; `resolveCustomRole`'s callers drop it.
|
|
941
1803
|
*/
|
|
942
1804
|
function customRolesOfSql(parts) {
|
|
943
1805
|
const helpers = quoteIdent(parts.helpers.schema);
|
|
@@ -948,6 +1810,7 @@ function customRolesOfSql(parts) {
|
|
|
948
1810
|
return `
|
|
949
1811
|
select coalesce(jsonb_agg(jsonb_strip_nulls(jsonb_build_object(
|
|
950
1812
|
'name', c.role,
|
|
1813
|
+
'shared', case when c.tenant_id is null and c.scope <> 'global' then true end,
|
|
951
1814
|
'tenant', c.tenant_id::text,
|
|
952
1815
|
'scope', c.scope,
|
|
953
1816
|
'id', c.scope_id,
|
|
@@ -978,7 +1841,10 @@ function customRolesOfSql(parts) {
|
|
|
978
1841
|
from jsonb_array_elements(memberships) m
|
|
979
1842
|
where m -> 'roles' ? c.role
|
|
980
1843
|
and m ->> 'scope' = c.scope
|
|
981
|
-
and
|
|
1844
|
+
and (
|
|
1845
|
+
(c.tenant_id is null and c.scope_id is null)
|
|
1846
|
+
or c.tenant_id::text = case when m ->> 'scope' = ${root} then m ->> 'id' else m -> 'within' ->> ${root} end
|
|
1847
|
+
)
|
|
982
1848
|
and (c.scope_id is null or c.scope_id = m ->> 'id')
|
|
983
1849
|
);`;
|
|
984
1850
|
}
|
|
@@ -1791,7 +2657,7 @@ function hookSql(parts) {
|
|
|
1791
2657
|
const schema = quoteIdent(parts.schema);
|
|
1792
2658
|
const fn = `${schema}.custom_access_token_hook`;
|
|
1793
2659
|
const rows = parts.roles;
|
|
1794
|
-
const roles = rows === void 0 ? ` held := '[]'::jsonb;` : ` select coalesce(jsonb_agg(distinct ${rows.roleSql} order by ${rows.roleSql}), '[]'::jsonb)
|
|
2660
|
+
const roles = rows === void 0 ? ` held := '[]'::jsonb;` : ` select coalesce(jsonb_agg(distinct ${rows.roleSql} order by ${rows.roleSql}) filter (where ${rows.roleSql} is not null), '[]'::jsonb)
|
|
1795
2661
|
into held
|
|
1796
2662
|
from ${rows.from}
|
|
1797
2663
|
where ${rows.userSql} = v_roles_user;`;
|
|
@@ -1823,11 +2689,29 @@ function hookSql(parts) {
|
|
|
1823
2689
|
if extra is not null then
|
|
1824
2690
|
claims := jsonb_set(claims, ${quoteLiteral(`{${entry.claim}}`)}, extra);
|
|
1825
2691
|
end if;`).join("");
|
|
2692
|
+
const dropTeams = parts.hook.teams === void 0 ? "" : " - 'team_ids'";
|
|
1826
2693
|
const suspended = parts.users === void 0 ? "" : `
|
|
1827
2694
|
if not ${activeRowSql(parts.users, "uid")} then
|
|
1828
|
-
claims := claims - 'memberships_truncated' - 'attrs' - ${quoteLiteral(parts.tenantClaim)}${dropExtra};
|
|
2695
|
+
claims := claims - 'memberships_truncated' - 'attrs'${dropTeams} - ${quoteLiteral(parts.tenantClaim)}${dropExtra};
|
|
1829
2696
|
claims := claims || jsonb_build_object('user_role', '[]'::jsonb, 'roles', '[]'::jsonb, 'memberships', '[]'::jsonb);${version}
|
|
1830
2697
|
return jsonb_set(event, '{claims}', claims);
|
|
2698
|
+
end if;`;
|
|
2699
|
+
const teamsConfig = parts.hook.teams;
|
|
2700
|
+
const teams = teamsConfig === void 0 ? "" : `
|
|
2701
|
+
for team in
|
|
2702
|
+
select t.${quoteIdent(teamsConfig.team)}::text as id
|
|
2703
|
+
from ${quoteQualified(teamsConfig.table)} t
|
|
2704
|
+
where t.${quoteIdent(teamsConfig.user)} = uid
|
|
2705
|
+
order by ${teamsConfig.tenant === void 0 ? "" : `(t.${quoteIdent(teamsConfig.tenant)}::text is not distinct from active) desc, `}t.${quoteIdent(teamsConfig.team)}
|
|
2706
|
+
loop
|
|
2707
|
+
if octet_length(kept::text) + used + octet_length((team_ids || to_jsonb(team.id))::text) > budget then
|
|
2708
|
+
truncated := true;
|
|
2709
|
+
exit;
|
|
2710
|
+
end if;
|
|
2711
|
+
team_ids := team_ids || jsonb_build_array(team.id);
|
|
2712
|
+
end loop;
|
|
2713
|
+
if team_ids <> '[]'::jsonb then
|
|
2714
|
+
claims := jsonb_set(claims, '{team_ids}', team_ids);
|
|
1831
2715
|
end if;`;
|
|
1832
2716
|
return `${parts.schema === "public" ? "" : `create schema if not exists ${schema};\nrevoke all on schema ${schema} from public;\n\n`}create or replace function ${fn}(event jsonb)
|
|
1833
2717
|
returns jsonb
|
|
@@ -1845,9 +2729,9 @@ declare
|
|
|
1845
2729
|
in_active boolean := false;
|
|
1846
2730
|
budget integer := ${String(parts.budget)};
|
|
1847
2731
|
used integer := 0;
|
|
1848
|
-
item record;${typedUsers(parts)}${plan === void 0 ? "" : "\n attrs jsonb;"}${parts.extra.length === 0 ? "" : "\n extra jsonb;"}${parts.version ? "\n ver bigint;" : ""}${parts.before.length === 0 ? "" : "\n checked jsonb;"}
|
|
2732
|
+
item record;${teamsConfig === void 0 ? "" : "\n team record;\n team_ids jsonb := '[]'::jsonb;"}${typedUsers(parts)}${plan === void 0 ? "" : "\n attrs jsonb;"}${parts.extra.length === 0 ? "" : "\n extra jsonb;"}${parts.version ? "\n ver bigint;" : ""}${parts.before.length === 0 ? "" : "\n checked jsonb;"}
|
|
1849
2733
|
begin${beforeSql(parts.before)}${suspended}
|
|
1850
|
-
claims := claims - 'attrs'${dropExtra};
|
|
2734
|
+
claims := claims - 'attrs'${dropTeams}${dropExtra};
|
|
1851
2735
|
${roles}
|
|
1852
2736
|
claims := jsonb_set(claims, '{roles}', held);
|
|
1853
2737
|
if jsonb_array_length(held) = 1 then
|
|
@@ -1870,7 +2754,7 @@ ${entriesSql(parts).replaceAll(/^/gmu, " ")}
|
|
|
1870
2754
|
kept := kept || jsonb_build_array(item.entry);
|
|
1871
2755
|
in_active := in_active or (active is not null and item.current);
|
|
1872
2756
|
end loop;
|
|
1873
|
-
claims := jsonb_set(claims, '{memberships}', kept)
|
|
2757
|
+
claims := jsonb_set(claims, '{memberships}', kept);${teams}
|
|
1874
2758
|
if truncated then
|
|
1875
2759
|
claims := jsonb_set(claims, '{memberships_truncated}', 'true'::jsonb);
|
|
1876
2760
|
else
|
|
@@ -1897,11 +2781,11 @@ revoke execute on function ${fn}(jsonb) from authenticated, anon, public;${extra
|
|
|
1897
2781
|
].filter((chunk) => chunk !== "").join("\n");
|
|
1898
2782
|
}
|
|
1899
2783
|
function extraGrantsSql(extra) {
|
|
1900
|
-
return [...[...new Set(extra.map((entry) => entry.fn.split(".")[0]))].map((name) => `\ngrant usage on schema ${quoteIdent(name ?? "")} to supabase_auth_admin;`), ...extra.map((entry) => `\ngrant execute on function ${quoteTable(entry.fn)}(uuid) to supabase_auth_admin;`)].join("");
|
|
2784
|
+
return [...[...new Set(extra.map((entry) => entry.fn.split(".")[0]))].map((name) => `\ngrant usage on schema ${quoteIdent(name ?? "")} to supabase_auth_admin;`), ...extra.map((entry) => `\nrevoke all on function ${quoteTable(entry.fn)}(uuid) from public, anon, authenticated;\ngrant execute on function ${quoteTable(entry.fn)}(uuid) to supabase_auth_admin;`)].join("");
|
|
1901
2785
|
}
|
|
1902
2786
|
function beforeGrantsSql(before, extra) {
|
|
1903
2787
|
const granted = new Set(extra.map((entry) => entry.fn.split(".")[0]));
|
|
1904
|
-
return [...[...new Set(before.map((fn) => beforeFirst(fn, ".")))].filter((name) => !granted.has(name)).map((name) => `\ngrant usage on schema ${quoteIdent(name)} to supabase_auth_admin;`), ...before.map((fn) => `\ngrant execute on function ${quoteTable(fn)}(jsonb) to supabase_auth_admin;`)].join("");
|
|
2788
|
+
return [...[...new Set(before.map((fn) => beforeFirst(fn, ".")))].filter((name) => !granted.has(name)).map((name) => `\ngrant usage on schema ${quoteIdent(name)} to supabase_auth_admin;`), ...before.map((fn) => `\nrevoke all on function ${quoteTable(fn)}(jsonb) from public, anon, authenticated;\ngrant execute on function ${quoteTable(fn)}(jsonb) to supabase_auth_admin;`)].join("");
|
|
1905
2789
|
}
|
|
1906
2790
|
/**
|
|
1907
2791
|
* Execute on each `member_<scope>_ids_for(uuid)` for the `hook.claims`
|
|
@@ -1928,6 +2812,7 @@ function readsSql(parts) {
|
|
|
1928
2812
|
reads.set(rolesTable, reads.get(rolesTable) ?? "roles");
|
|
1929
2813
|
if (through !== void 0) reads.set(through.table, reads.get(through.table) ?? "role_keys");
|
|
1930
2814
|
}
|
|
2815
|
+
if (parts.hook.teams !== void 0) reads.set(parts.hook.teams.table, reads.get(parts.hook.teams.table) ?? "teams");
|
|
1931
2816
|
if (parts.attrs?.table !== void 0 && parts.attrs.columns.length > 0) reads.set(parts.attrs.table, reads.get(parts.attrs.table) ?? "attrs");
|
|
1932
2817
|
if (parts.users !== void 0) reads.set(parts.users.table, reads.get(parts.users.table) ?? "status_users");
|
|
1933
2818
|
return [...[...new Set([...reads.keys()].map((name) => name.includes(".") ? name.split(".")[0] : "public").filter((schema) => schema !== void 0 && schema !== parts.schema && schema !== "auth"))].map((schema) => `grant usage on schema ${quoteIdent(schema)} to supabase_auth_admin;`), ...[...reads].map(([name, label]) => authAdminRead(name, label))].join("\n");
|
|
@@ -2005,7 +2890,7 @@ function hookParts(scopes, config, overrides) {
|
|
|
2005
2890
|
...memberForPlan({
|
|
2006
2891
|
scopes,
|
|
2007
2892
|
...config.rls?.memberships === void 0 ? {} : { memberships: config.rls.memberships },
|
|
2008
|
-
memberSources: config
|
|
2893
|
+
memberSources: membershipSourcesOf(config)
|
|
2009
2894
|
})
|
|
2010
2895
|
}
|
|
2011
2896
|
};
|
|
@@ -2328,6 +3213,7 @@ function trustedHelpers(parts, config, types, tenantType, policy) {
|
|
|
2328
3213
|
const keyed = [
|
|
2329
3214
|
helperEntry(USER_ID_HELPER, "", "uuid", client),
|
|
2330
3215
|
...config.rls?.apiKeys === void 0 ? [] : [helperEntry(API_KEY_ALLOWS, "p_grant text", "boolean", client)],
|
|
3216
|
+
...config.rls?.tokenScopes === true ? [helperEntry(TOKEN_SCOPE_ALLOWS, "p_grant text", "boolean", client)] : [],
|
|
2331
3217
|
...readOnlyActorKinds(config.rls?.readOnlyActors) === void 0 ? [] : [helperEntry(ACTOR_MAY_WRITE, "", "boolean", client)],
|
|
2332
3218
|
...!config.rls?.approvals ? [] : [helperEntry(IS_APPROVER, typeof config.rls.approvals === "object" && config.rls.approvals.delegations === true ? "p_approvers jsonb, p_tenant text, p_requester text, p_resource text" : "p_approvers jsonb, p_tenant text", "boolean", client)],
|
|
2333
3219
|
...forUser
|
|
@@ -2375,7 +3261,8 @@ function rlsSettings(parts, config) {
|
|
|
2375
3261
|
...suspension.memberships === void 0 ? {} : { memberships: { keep: keptKeys(suspension.memberships) } }
|
|
2376
3262
|
} },
|
|
2377
3263
|
...assigned === void 0 ? {} : { assignments: { tables: assigned } },
|
|
2378
|
-
...rls?.apiKeys === void 0 ? {} : { apiKeys: apiKeyFields(rls.apiKeys) }
|
|
3264
|
+
...rls?.apiKeys === void 0 ? {} : { apiKeys: apiKeyFields(rls.apiKeys) },
|
|
3265
|
+
...rls?.tokenScopes === true ? { tokenScopes: true } : {}
|
|
2379
3266
|
};
|
|
2380
3267
|
}
|
|
2381
3268
|
/** The `supabase/sdk` release `requires.capabilities` names features of. */
|
|
@@ -2459,7 +3346,7 @@ function manifestOf(parts, out, config, policy) {
|
|
|
2459
3346
|
decidingColumns: decidingColumns(config, parts.attrs === void 0 ? void 0 : {
|
|
2460
3347
|
...parts.attrs.table === void 0 ? {} : { table: parts.attrs.table },
|
|
2461
3348
|
columns: parts.attrs.columns
|
|
2462
|
-
}),
|
|
3349
|
+
}, parts.hook.teams),
|
|
2463
3350
|
markers: {
|
|
2464
3351
|
hook: "v1",
|
|
2465
3352
|
grants: "v1"
|
|
@@ -2467,6 +3354,11 @@ function manifestOf(parts, out, config, policy) {
|
|
|
2467
3354
|
requires: requiredCapabilities(config, policy)
|
|
2468
3355
|
};
|
|
2469
3356
|
}
|
|
3357
|
+
/** The manifest without the token hook: what a project with no `supabase.hook` records. */
|
|
3358
|
+
function databaseManifestOf(parts, out, config, policy) {
|
|
3359
|
+
const { hook: _hook, budget: _budget, claims: _claims, authzVersion: _authzVersion, authzVersionBump: _authzVersionBump, memberships: _memberships, ...rest } = manifestOf(parts, out, config, policy);
|
|
3360
|
+
return rest;
|
|
3361
|
+
}
|
|
2470
3362
|
/** The first line of the generated hook: fields `--check` compares before the full text. */
|
|
2471
3363
|
function hookMarker(manifest) {
|
|
2472
3364
|
return `${HOOK_MARKER} schema=${manifest.hook.schema} tenant=${manifest.tenantClaim} budget=${String(manifest.budget.bytes)} claims=${manifest.claims.map((claim) => claim.name).join(",")}`;
|
|
@@ -2514,6 +3406,24 @@ function supabaseHookManifest(scopes, config, overrides = {}, policy) {
|
|
|
2514
3406
|
};
|
|
2515
3407
|
}
|
|
2516
3408
|
/**
|
|
3409
|
+
* The manifest of a project in `rls.authorize: 'database'` mode with no
|
|
3410
|
+
* `supabase.hook`: the helpers, scopes, membership sources and grants, and no
|
|
3411
|
+
* token hook.
|
|
3412
|
+
*/
|
|
3413
|
+
function supabaseDatabaseManifest(scopes, config, overrides = {}, policy) {
|
|
3414
|
+
return databaseManifestOf(hookParts(scopes, {
|
|
3415
|
+
...config,
|
|
3416
|
+
supabase: {
|
|
3417
|
+
...config.supabase,
|
|
3418
|
+
hook: { memberships: membershipSourcesOf(config) }
|
|
3419
|
+
}
|
|
3420
|
+
}, overrides), overrides.out ?? defaultOut(config), config, policy);
|
|
3421
|
+
}
|
|
3422
|
+
/** Whether the project is in the one case that has a manifest without a hook. */
|
|
3423
|
+
function hooklessDatabase(config) {
|
|
3424
|
+
return config.supabase?.hook === void 0 && resolveAuthorize(config) === "database";
|
|
3425
|
+
}
|
|
3426
|
+
/**
|
|
2517
3427
|
* The hook migration. With `grantsOut`, the statements `supabase db diff`
|
|
2518
3428
|
* drops are left out of `sql` and returned in `grants` for that file.
|
|
2519
3429
|
*/
|
|
@@ -2559,14 +3469,33 @@ function markerDrift(onDisk, expected, outRel) {
|
|
|
2559
3469
|
const changed = Object.keys(want).filter((key) => found[key] !== want[key]).map((key) => `${key} ${found[key] ?? "(none)"} -> ${want[key] ?? ""}`);
|
|
2560
3470
|
return changed.length === 0 ? "supabase hook drift" : `supabase hook drift: ${changed.join("; ")}`;
|
|
2561
3471
|
}
|
|
2562
|
-
|
|
3472
|
+
/** Supabase's default access token lifetime when `[auth] jwt_expiry` is unset. */
|
|
3473
|
+
const DEFAULT_JWT_EXPIRY = 3600;
|
|
3474
|
+
function managementApi(cwd, manifest) {
|
|
3475
|
+
return {
|
|
3476
|
+
hook_custom_access_token_enabled: true,
|
|
3477
|
+
hook_custom_access_token_uri: hookUri(manifest.hook.schema),
|
|
3478
|
+
jwt_exp: supabaseConfig(cwd).jwtExpiry ?? DEFAULT_JWT_EXPIRY
|
|
3479
|
+
};
|
|
3480
|
+
}
|
|
3481
|
+
function inspectText(manifest, api) {
|
|
2563
3482
|
return [
|
|
2564
3483
|
`hook ${manifest.hook.schema}.${manifest.hook.function} (${manifest.hook.out})`,
|
|
2565
3484
|
`helpers ${manifest.helpers.functions.map((fn) => `${manifest.helpers.schema}.${fn}`).join(", ")}`,
|
|
2566
3485
|
`tenant claim ${manifest.tenantClaim}`,
|
|
2567
3486
|
`budget ${String(manifest.budget.bytes)} bytes of ${manifest.budget.measure}`,
|
|
2568
3487
|
`claims ${manifest.claims.map((claim) => `${claim.name}${claim.source === "permdock" ? "" : ` (${claim.source})`}${claim.budget ? " [budget]" : ""}`).join(", ")}`,
|
|
2569
|
-
`authz_ver ${manifest.authzVersion ? "on" : "off"}
|
|
3488
|
+
`authz_ver ${manifest.authzVersion ? "on" : "off"}`,
|
|
3489
|
+
`hook_custom_access_token_enabled ${String(api.hook_custom_access_token_enabled)}`,
|
|
3490
|
+
`hook_custom_access_token_uri ${api.hook_custom_access_token_uri}`,
|
|
3491
|
+
`jwt_exp ${String(api.jwt_exp)}`
|
|
3492
|
+
].join("\n");
|
|
3493
|
+
}
|
|
3494
|
+
function databaseInspectText(manifest) {
|
|
3495
|
+
return [
|
|
3496
|
+
"no token hook (rls.authorize: database, no supabase.hook)",
|
|
3497
|
+
`helpers ${manifest.helpers.functions.map((fn) => `${manifest.helpers.schema}.${fn}`).join(", ")}`,
|
|
3498
|
+
`tenant claim ${manifest.tenantClaim}`
|
|
2570
3499
|
].join("\n");
|
|
2571
3500
|
}
|
|
2572
3501
|
/**
|
|
@@ -2627,15 +3556,30 @@ async function runSupabase(input) {
|
|
|
2627
3556
|
}).filter(([, value]) => value !== void 0));
|
|
2628
3557
|
if (area === "inspect" && action === void 0) {
|
|
2629
3558
|
const policy = await loadHookPolicy(input.cwd, input.config);
|
|
3559
|
+
if (hooklessDatabase(input.config)) {
|
|
3560
|
+
const bare = supabaseDatabaseManifest(scopeList(policy.scopes), input.config, overrides, policy);
|
|
3561
|
+
if (input.out !== void 0 || input.check) return manifestFile(input.cwd, typeof input.out === "string" ? input.out : MANIFEST_FILE, bare, input.check);
|
|
3562
|
+
return {
|
|
3563
|
+
code: 0,
|
|
3564
|
+
output: input.json === true ? JSON.stringify(bare, null, 2) : databaseInspectText(bare)
|
|
3565
|
+
};
|
|
3566
|
+
}
|
|
2630
3567
|
const manifest = supabaseHookManifest(scopeList(policy.scopes), input.config, {
|
|
2631
3568
|
...overrides,
|
|
2632
3569
|
out: hookOut(input.cwd, input.config, input.schema, flag),
|
|
2633
3570
|
schemas: schemas.mode
|
|
2634
3571
|
}, policy);
|
|
2635
|
-
|
|
3572
|
+
const api = managementApi(input.cwd, manifest);
|
|
3573
|
+
if (input.out !== void 0 || input.check) return manifestFile(input.cwd, typeof input.out === "string" ? input.out : MANIFEST_FILE, {
|
|
3574
|
+
...manifest,
|
|
3575
|
+
managementApi: api
|
|
3576
|
+
}, input.check);
|
|
2636
3577
|
return {
|
|
2637
3578
|
code: 0,
|
|
2638
|
-
output: input.json === true ? JSON.stringify(
|
|
3579
|
+
output: input.json === true ? JSON.stringify({
|
|
3580
|
+
...manifest,
|
|
3581
|
+
managementApi: managementApi(input.cwd, manifest)
|
|
3582
|
+
}, null, 2) : inspectText(manifest, api)
|
|
2639
3583
|
};
|
|
2640
3584
|
}
|
|
2641
3585
|
if (area !== "hook" || action !== "generate") return {
|
|
@@ -2646,7 +3590,9 @@ async function runSupabase(input) {
|
|
|
2646
3590
|
code: 2,
|
|
2647
3591
|
output: `supabase hook generate --grants-out is for --schemas migra: ${schemas.mode === "pg-delta" ? "pg-delta keeps the grants in the hook file" : "a hand-written migration keeps its grants"}, so drop --grants-out`
|
|
2648
3592
|
};
|
|
2649
|
-
const
|
|
3593
|
+
const generated = supabaseHookSql(await loadScopes(input.cwd, input.config), input.config, overrides, grantsLabel(input.grantsOut));
|
|
3594
|
+
const { grants, manifest } = generated;
|
|
3595
|
+
const sql = schemas.mode === "pg-delta" && typeof input.out !== "string" && input.config.supabase?.hook?.out === void 0 ? declarativeSql(generated.sql) : generated.sql;
|
|
2650
3596
|
const outRel = typeof input.out === "string" ? input.out : hookOut(input.cwd, input.config, input.schema, flag);
|
|
2651
3597
|
const outPath = resolve(input.cwd, outRel);
|
|
2652
3598
|
const hook = input.config.supabase?.hook;
|
|
@@ -2697,4 +3643,4 @@ async function runSupabase(input) {
|
|
|
2697
3643
|
};
|
|
2698
3644
|
}
|
|
2699
3645
|
//#endregion
|
|
2700
|
-
export {
|
|
3646
|
+
export { readSupabaseConfig as _, supabaseHookManifest as a, rbacScaffold as b, approvalsSql as c, resolveSchemas as d, schemasRefusal as f, pd074 as g, pd045 as h, runSupabase as i, pd039 as l, attrsPlan as m, hookOut as n, supabaseHookSql as o, declarativeSql as p, loadScopes as r, permissionHoldersSql as s, grantsLabel as t, isSupabaseSchemas as u, supabaseConfig as v, resolveAuthorize as x, parseRbacAuthorize as y };
|