permdock 0.6.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-DCYe60Pi.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-DvSSPQJX.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-p1PGoVjb.js → approvals-CMRfsbBh.js} +74 -48
- package/dist/{arazzo-41WuzHou.js → arazzo-ClrF3PVb.js} +2 -2
- package/dist/{arazzo-CaUVBn7D.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-DabClFLQ.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-BNM3TtDo.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-CAvgUuKs.js → bind-D1nO6fiC.js} +5 -5
- package/dist/{bind-DOyrv6zi.d.ts → bind-JDuvxjuW.d.ts} +7 -7
- package/dist/{build-instance-Bu_eDqYw.js → build-instance-DxE7czo9.js} +1 -1
- package/dist/{canonical-json-BC8_nMTw.js → canonical-json-DwilZ1iB.js} +6 -3
- package/dist/{capability-Drg-1YhL.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-DZVbrF-z.js → catalog-BaMQfQ6Y.js} +3 -3
- package/dist/{catalog-HD2gf5mY.js → catalog-D69WhFii.js} +43 -13
- package/dist/{catalog-doc-Cdn7-0pQ.js → catalog-doc-CV9s6B1S.js} +28 -5
- package/dist/{catalog-fingerprint-CCP0-yQS.js → catalog-fingerprint-C144oW4M.js} +1 -1
- package/dist/{create-CQWIpUG-.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-ytQ3uviA.js → cloud-CO8pYtwr.js} +5 -5
- package/dist/{codemod-ua2hHy7w.js → codemod-BP6n8N9L.js} +3 -3
- package/dist/{codemod-5mpSpnUY.js → codemod-i4N2BhDc.js} +3 -3
- package/dist/{collect-mLTY4nwb.js → collect-BaWeMjwV.js} +17 -8
- package/dist/{collect-Ci6akVwH.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-1bsAezL0.d.ts → compile-COM2VKuN.d.ts} +3 -3
- package/dist/{completion-BTFrHZhX.js → completion-BNdVf7X2.js} +3 -3
- package/dist/{config-bs_kZeYq.js → config-CoQHDrDi.js} +7 -3
- package/dist/{config-Bj2Ixq3d.js → config-DGZzMV1B.js} +2 -2
- package/dist/{config-report-DSpsLpCE.js → config-report-Cm7UITNA.js} +3 -3
- package/dist/connector-schema-_VCSsdtD.js +433 -0
- package/dist/{context-B_u3_bDJ.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-B30OMUOJ.d.ts → create-B2-CQqCI.d.ts} +5 -5
- package/dist/{create-CGm28gyI.js → create-Cb86Z8Im.js} +9 -8
- package/dist/{create-DCF2SvoT.js → create-DJrlhEp9.js} +5 -5
- package/dist/{create-D_NmPOdH.d.ts → create-QHuuPw3q.d.ts} +7 -7
- package/dist/{create-CBMmFie-.d.ts → create-UTnUVETj.d.ts} +30 -10
- package/dist/{credential-BcoiejpY.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-j6-rc37o.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-CiFQNuMV.d.ts → denied-text-D4qkEtFz.d.ts} +2 -2
- package/dist/{describe-BybMRY7A.js → describe-DZlnEtLy.js} +1 -0
- package/dist/{describe-B5qgDvEW.d.ts → describe-O0SwYIK8.d.ts} +2 -2
- package/dist/{diff-CmuSD3vc.js → diff-Btr1c1Ow.js} +2 -2
- package/dist/{diff-3jbx6Rm4.js → diff-DzT-xD13.js} +10 -10
- package/dist/{doctor-BdZw53-k.js → doctor-BU1szn63.js} +241 -49
- package/dist/{doctor-3ZqNHX_G.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-DH5QEGXh.d.ts → errors-B_Qg9D3e.d.ts} +2 -2
- package/dist/{errors-CWTY6uih.js → errors-DpP_U6Bf.js} +1 -0
- package/dist/{evaluate-CNClBvcj.js → evaluate-B_oqFbWC.js} +55 -12
- package/dist/{evaluations-C_1vdSZc.d.ts → evaluations-BCddEOfO.d.ts} +4 -4
- package/dist/{evaluations-beAooV0n.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-Dw0MTS3D.d.ts → fetch-adapter-CuhyYwC1.d.ts} +4 -4
- package/dist/{fetch-adapter-DD_gfmrC.js → fetch-adapter-De-u6vhJ.js} +3 -3
- package/dist/{fields-OYG_JR78.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-CTCMsFZk.js → from-snapshot-Bz469dIh.js} +17 -10
- package/dist/generate-3FNO5P5Q.js +159 -0
- package/dist/{grantee-hxrUsbpM.js → grantee-BrRANrpT.js} +1 -1
- package/dist/{grantee-conditions-CcXf8hMM.js → grantee-conditions-C6P1Tvol.js} +1 -1
- package/dist/{grantee-match-DbENBHLB.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-CBYVMjwh.js → helpers-DY3vXuGs.js} +3 -3
- package/dist/hono/index.d.ts +5 -5
- package/dist/hono/index.js +3 -3
- package/dist/{hosted-BPk51-kX.d.ts → hosted-BmjzxQhp.d.ts} +14 -2
- package/dist/{hosted-B46-5LYE.js → hosted-XBgU6RGT.js} +34 -12
- package/dist/{http-DXJ37RDA.js → http-Ca3Sr5x1.js} +1 -1
- package/dist/{import-wyqXUyjm.js → import-Bz0GefWg.js} +5 -5
- package/dist/{import-CNV7I2Dw.js → import-DB2EG_iy.js} +3 -3
- package/dist/{index-C-6Letxg.d.ts → index-BE8y3moU.d.ts} +50 -8
- package/dist/{index-B8YjkEZ4.d.ts → index-BSfRl0hZ.d.ts} +6 -6
- package/dist/{index-DuWxc5dt.d.ts → index-BTkwrK7v.d.ts} +143 -14
- package/dist/index-CMiPH2Tv.d.ts +206 -0
- package/dist/{index-Ch8LpNDp.d.ts → index-DH9DUDEM.d.ts} +18 -3
- package/dist/{index-CueFnxQc.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-BsVpyGIk.d.ts → instance-options-CU0YQCLH.d.ts} +1 -1
- package/dist/{instance-snapshot-BOEhcqIF.js → instance-snapshot-CjcwnEiV.js} +16 -11
- package/dist/jwt/index.d.ts +83 -5
- package/dist/jwt/index.js +143 -5
- package/dist/{kernel-D0NVb1cK.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-dvL2XEe1.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-Dr70oA_3.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-CIq4-E9F.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-C4dDTVEd.js → openapi-DMocl1bh.js} +4 -4
- package/dist/{openapi-B7HZ0f-r.js → openapi-Ddb4628T.js} +2 -7
- package/dist/{openapi-DD1SV-5-.js → openapi-ztVaux6j.js} +8 -8
- package/dist/{operation-findings-DgATDpvh.js → operation-findings-kRcEp8lE.js} +1 -1
- package/dist/{operations-X0VM7F3m.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-1im__-08.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-DqaJNJPn.js → ownership-Z2LpxsGa.js} +443 -40
- 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-5ODwqu8b.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-BrAscV28.js → permdock-BfWEeMqk.js} +177 -49
- package/dist/{permdock-SV8ZINYT.d.ts → permdock-Dco6dyCK.d.ts} +34 -5
- package/dist/{permission-registry-Br4jSNVi.js → permission-registry-DpPtSKNZ.js} +1 -1
- package/dist/{vocabulary-CN8H_9UF.d.ts → permission-types-DhNEmoRG.d.ts} +4 -64
- package/dist/{permissions-u_KHg-sN.d.ts → permissions-CoqCOfJ3.d.ts} +2 -1
- package/dist/{permissions-B-wCP5ZC.js → permissions-CyH2MV_B.js} +1 -1
- package/dist/{permissions-BPxlwVhN.js → permissions-DArULThq.js} +4 -4
- package/dist/pkce-5h8NgMQJ.js +21 -0
- package/dist/{policies-DP2nqRoF.js → policies-B2lZIurj.js} +3 -3
- package/dist/{policy-77FSAq_V.d.ts → policy-B7dg_yzu.d.ts} +2 -2
- package/dist/{policy-DbM5YYtV.js → policy-DaJy4nK4.js} +17 -8
- package/dist/{policy-from-catalog-C2gMa2Dj.js → policy-from-catalog-DFWYkNdu.js} +9 -9
- package/dist/{policy-types-n0uRTsW8.d.ts → policy-types-B-F-qAZk.d.ts} +83 -4
- package/dist/postgres-store-BL9M_CA1.js +1001 -0
- package/dist/{postgrest-CEgRbefE.d.ts → postgrest-CYacM_u7.d.ts} +12 -1
- package/dist/{postgrest-DAjUkF9w.js → postgrest-r5faDIzD.js} +37 -4
- package/dist/{powersync-DISt6SUe.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-B45V5d2b.d.ts → problem-details-Tcfmj3bV.d.ts} +1 -1
- package/dist/prompt-DwtVemER.js +935 -0
- package/dist/{protected-RFGpakN9.d.ts → protected-BwZYL1X_.d.ts} +6 -5
- package/dist/{protected-BlF0F6wL.js → protected-DXE3cQYg.js} +2 -2
- package/dist/{provider-B1al-AZz.js → provider-BQsTYYy0.js} +2 -2
- package/dist/{provider-DILL9oPK.d.ts → provider-Csk-THAn.d.ts} +1 -1
- package/dist/{provider-store-DM6DNcta.js → provider-store-IgqQipCO.js} +2 -2
- package/dist/{pull-jEwbf80J.js → pull-CN5OLxrF.js} +7 -7
- package/dist/pull-Cty6Ovyu.js +1 -0
- package/dist/{push-BD4f15co.js → push-tVdG8dUL.js} +54 -14
- package/dist/{pushed-policy-DCW91KQU.d.ts → pushed-policy-BbcY9r_4.d.ts} +1 -1
- package/dist/{pushed-policy-CqtxkV4G.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 +209 -21
- package/dist/{refs-K6eWUJ0H.js → refs-CNJBiTFo.js} +15 -1
- package/dist/{replay-Bkm-Ne4l.d.ts → replay-DCDD_ZfL.d.ts} +1 -1
- package/dist/{request-context-C81Pip9n.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-BAqP4q66.js → rls-Ck_PocSp.js} +32 -8
- package/dist/{rls-DTvYd-lI.js → rls-CxBZb4rZ.js} +478 -534
- package/dist/{role-builder-uWQZ4v84.js → role-builder-C1VJzvcr.js} +3 -3
- package/dist/rolldown-runtime-C3I60J0A.js +4 -0
- package/dist/{rpc-VSl5ylaQ.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-DocwaTKn.d.ts → run-ticket-BpNi7BCi.d.ts} +8 -3
- package/dist/{run-CUKuz0A8.js → run-uLD2aWuO.js} +7 -7
- package/dist/{runtime-D3VTAiCA.js → runtime-Vif3_-zf.js} +1 -1
- package/dist/{saas-BCXRuXca.js → saas-Az_Kz-4D.js} +7 -7
- package/dist/{scan-qvOe0hS3.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-C3WXAHZj.js → server-Bnga6I50.js} +3 -3
- package/dist/{server-types-CKQiCnON.d.ts → server-types-C4gZUEZy.d.ts} +9 -9
- package/dist/{shared-DvvFzYXe.js → shared-C8LjUdVU.js} +1 -1
- package/dist/{shared-BAK8t4Uo.js → shared-fMKOv8hP.js} +44 -38
- package/dist/{sink-4-eQIRWf.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-B7DkYg6g.js → snapshot-CbGmYiJx.js} +4 -4
- package/dist/{snapshot-cache-DZHQ0KF6.js → snapshot-cache-DT2Kx1F8.js} +1 -1
- package/dist/{snapshot-cache-PXI-vGpY.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-Xc4zkszI.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-Cu2m75uo.js → src-DLFrtrrC.js} +140 -48
- package/dist/ssf/index.d.ts +4 -4
- package/dist/ssf/index.js +640 -211
- package/dist/{standard-webhooks-rbD7LS6h.d.ts → standard-webhooks-B_qRg0ws.d.ts} +2 -2
- package/dist/{store-BDutJkDL.js → store-DSP9oGvh.js} +15 -7
- package/dist/{store-options-u0ycEe8s.js → store-options-B_poyYvg.js} +6 -6
- package/dist/{stores-BUGNbJTt.d.ts → stores-BAZwSYZA.d.ts} +6 -5
- package/dist/{stores-CGhM8BN_.js → stores-BqEuHC05.js} +2 -2
- package/dist/{stream-CeCMJmBB.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-x5JtR2tc.js → supabase--0aJdLEd.js} +8 -6
- package/dist/{supabase-By_frk3U.js → supabase-Bqp7iIY2.js} +3 -3
- package/dist/supabase-hook-DJxC4PoP.js +1 -0
- package/dist/{supabase-hook-BMoEhZir.js → supabase-hook-Dg0SrQWR.js} +1060 -119
- 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-Dfv0aTER.d.ts → types-BWZybqs9.d.ts} +110 -8
- package/dist/{types-Druu9wLM.d.ts → types-BXMYB7BY.d.ts} +2 -2
- package/dist/{types-BzzaHxt3.d.ts → types-BfVmNJO5.d.ts} +14 -3
- package/dist/{types-lUlG3TVd.d.ts → types-CIeZcG8v.d.ts} +2 -2
- package/dist/{types-B3_ooZgZ.d.ts → types-CKV71kKh.d.ts} +4 -4
- package/dist/{types-CX7AvRqP.d.ts → types-CQVEQawv.d.ts} +4 -4
- package/dist/{types-C863OQiR.d.ts → types-CeIscIKp.d.ts} +4 -4
- package/dist/{types-C_IiEs64.d.ts → types-CfiKC5aN.d.ts} +1 -1
- package/dist/{types-_WhUP7ud.d.ts → types-D3A19w4A.d.ts} +8 -4
- package/dist/{types-8RnwUAvE.d.ts → types-DBHftjgS.d.ts} +15 -8
- package/dist/{types-BdtSDbBO.d.ts → types-DC44-hqb.d.ts} +2 -2
- package/dist/{types-CVZSNocA.d.ts → types-DXmwu78Z.d.ts} +4 -4
- package/dist/{types-C791HFu9.d.ts → types-cTos-H7p.d.ts} +2 -2
- package/dist/{types-BtHtcKMr.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-SveTRTyr.js → usage-Bybmck7f.js} +7 -7
- package/dist/{usage-CRVl9V3t.js → usage-CDaLXCfL.js} +2 -2
- package/dist/usage-y-kBNdqs.js +1 -0
- package/dist/{validation-error-DHUrAkku.d.ts → validation-error-CQpoquwj.d.ts} +1 -1
- package/dist/{verify-BaAKx7t6.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-B986w1oK.d.ts → waiter-DwEyouan.d.ts} +2 -2
- package/dist/watch-Bd9mx3rd.js +1 -0
- package/dist/{watch-vea54PRw.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-C9vfEphl.js → where-scope-wq2coopv.js} +41 -21
- package/dist/{who-can-DWBAcaCQ.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-C5jC6sKI.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 +4 -1
- package/skills/permdock-tenancy/SKILL.md +1 -1
- package/skills/permdock-tenancy/references/ownership-and-custom-roles.md +1 -0
- package/skills/permdock-wire/references/adapters.md +14 -0
- package/skills/permdock-wire/references/policy-options.md +1 -0
- package/dist/catalog-BoWglDPI.js +0 -1
- package/dist/collect-D7eQDffE.js +0 -1
- package/dist/index-Cp_ilKi1.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-BkWWCS1K.js +0 -538
- package/dist/powersync-MMJ2mI2q.js +0 -1
- package/dist/prompt-DfZLJLIn.js +0 -32
- package/dist/pull-CvpINcMK.js +0 -1
- package/dist/run-DDwUaJDU.js +0 -1
- package/dist/supabase-hook-CCw5m35C.js +0 -1
- package/dist/supautils-B6HYL9eL.js +0 -91
- package/dist/text-diff-BQcUapOb.js +0 -15
- package/dist/usage-CZpSQP6L.js +0 -1
- package/dist/watch--ovlPOc0.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-DAjUkF9w.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")}
|
|
@@ -1796,7 +2657,7 @@ function hookSql(parts) {
|
|
|
1796
2657
|
const schema = quoteIdent(parts.schema);
|
|
1797
2658
|
const fn = `${schema}.custom_access_token_hook`;
|
|
1798
2659
|
const rows = parts.roles;
|
|
1799
|
-
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)
|
|
1800
2661
|
into held
|
|
1801
2662
|
from ${rows.from}
|
|
1802
2663
|
where ${rows.userSql} = v_roles_user;`;
|
|
@@ -1828,11 +2689,29 @@ function hookSql(parts) {
|
|
|
1828
2689
|
if extra is not null then
|
|
1829
2690
|
claims := jsonb_set(claims, ${quoteLiteral(`{${entry.claim}}`)}, extra);
|
|
1830
2691
|
end if;`).join("");
|
|
2692
|
+
const dropTeams = parts.hook.teams === void 0 ? "" : " - 'team_ids'";
|
|
1831
2693
|
const suspended = parts.users === void 0 ? "" : `
|
|
1832
2694
|
if not ${activeRowSql(parts.users, "uid")} then
|
|
1833
|
-
claims := claims - 'memberships_truncated' - 'attrs' - ${quoteLiteral(parts.tenantClaim)}${dropExtra};
|
|
2695
|
+
claims := claims - 'memberships_truncated' - 'attrs'${dropTeams} - ${quoteLiteral(parts.tenantClaim)}${dropExtra};
|
|
1834
2696
|
claims := claims || jsonb_build_object('user_role', '[]'::jsonb, 'roles', '[]'::jsonb, 'memberships', '[]'::jsonb);${version}
|
|
1835
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);
|
|
1836
2715
|
end if;`;
|
|
1837
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)
|
|
1838
2717
|
returns jsonb
|
|
@@ -1850,9 +2729,9 @@ declare
|
|
|
1850
2729
|
in_active boolean := false;
|
|
1851
2730
|
budget integer := ${String(parts.budget)};
|
|
1852
2731
|
used integer := 0;
|
|
1853
|
-
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;"}
|
|
1854
2733
|
begin${beforeSql(parts.before)}${suspended}
|
|
1855
|
-
claims := claims - 'attrs'${dropExtra};
|
|
2734
|
+
claims := claims - 'attrs'${dropTeams}${dropExtra};
|
|
1856
2735
|
${roles}
|
|
1857
2736
|
claims := jsonb_set(claims, '{roles}', held);
|
|
1858
2737
|
if jsonb_array_length(held) = 1 then
|
|
@@ -1875,7 +2754,7 @@ ${entriesSql(parts).replaceAll(/^/gmu, " ")}
|
|
|
1875
2754
|
kept := kept || jsonb_build_array(item.entry);
|
|
1876
2755
|
in_active := in_active or (active is not null and item.current);
|
|
1877
2756
|
end loop;
|
|
1878
|
-
claims := jsonb_set(claims, '{memberships}', kept)
|
|
2757
|
+
claims := jsonb_set(claims, '{memberships}', kept);${teams}
|
|
1879
2758
|
if truncated then
|
|
1880
2759
|
claims := jsonb_set(claims, '{memberships_truncated}', 'true'::jsonb);
|
|
1881
2760
|
else
|
|
@@ -1902,11 +2781,11 @@ revoke execute on function ${fn}(jsonb) from authenticated, anon, public;${extra
|
|
|
1902
2781
|
].filter((chunk) => chunk !== "").join("\n");
|
|
1903
2782
|
}
|
|
1904
2783
|
function extraGrantsSql(extra) {
|
|
1905
|
-
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("");
|
|
1906
2785
|
}
|
|
1907
2786
|
function beforeGrantsSql(before, extra) {
|
|
1908
2787
|
const granted = new Set(extra.map((entry) => entry.fn.split(".")[0]));
|
|
1909
|
-
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("");
|
|
1910
2789
|
}
|
|
1911
2790
|
/**
|
|
1912
2791
|
* Execute on each `member_<scope>_ids_for(uuid)` for the `hook.claims`
|
|
@@ -1933,6 +2812,7 @@ function readsSql(parts) {
|
|
|
1933
2812
|
reads.set(rolesTable, reads.get(rolesTable) ?? "roles");
|
|
1934
2813
|
if (through !== void 0) reads.set(through.table, reads.get(through.table) ?? "role_keys");
|
|
1935
2814
|
}
|
|
2815
|
+
if (parts.hook.teams !== void 0) reads.set(parts.hook.teams.table, reads.get(parts.hook.teams.table) ?? "teams");
|
|
1936
2816
|
if (parts.attrs?.table !== void 0 && parts.attrs.columns.length > 0) reads.set(parts.attrs.table, reads.get(parts.attrs.table) ?? "attrs");
|
|
1937
2817
|
if (parts.users !== void 0) reads.set(parts.users.table, reads.get(parts.users.table) ?? "status_users");
|
|
1938
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");
|
|
@@ -2010,7 +2890,7 @@ function hookParts(scopes, config, overrides) {
|
|
|
2010
2890
|
...memberForPlan({
|
|
2011
2891
|
scopes,
|
|
2012
2892
|
...config.rls?.memberships === void 0 ? {} : { memberships: config.rls.memberships },
|
|
2013
|
-
memberSources: config
|
|
2893
|
+
memberSources: membershipSourcesOf(config)
|
|
2014
2894
|
})
|
|
2015
2895
|
}
|
|
2016
2896
|
};
|
|
@@ -2333,6 +3213,7 @@ function trustedHelpers(parts, config, types, tenantType, policy) {
|
|
|
2333
3213
|
const keyed = [
|
|
2334
3214
|
helperEntry(USER_ID_HELPER, "", "uuid", client),
|
|
2335
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)] : [],
|
|
2336
3217
|
...readOnlyActorKinds(config.rls?.readOnlyActors) === void 0 ? [] : [helperEntry(ACTOR_MAY_WRITE, "", "boolean", client)],
|
|
2337
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)],
|
|
2338
3219
|
...forUser
|
|
@@ -2380,7 +3261,8 @@ function rlsSettings(parts, config) {
|
|
|
2380
3261
|
...suspension.memberships === void 0 ? {} : { memberships: { keep: keptKeys(suspension.memberships) } }
|
|
2381
3262
|
} },
|
|
2382
3263
|
...assigned === void 0 ? {} : { assignments: { tables: assigned } },
|
|
2383
|
-
...rls?.apiKeys === void 0 ? {} : { apiKeys: apiKeyFields(rls.apiKeys) }
|
|
3264
|
+
...rls?.apiKeys === void 0 ? {} : { apiKeys: apiKeyFields(rls.apiKeys) },
|
|
3265
|
+
...rls?.tokenScopes === true ? { tokenScopes: true } : {}
|
|
2384
3266
|
};
|
|
2385
3267
|
}
|
|
2386
3268
|
/** The `supabase/sdk` release `requires.capabilities` names features of. */
|
|
@@ -2464,7 +3346,7 @@ function manifestOf(parts, out, config, policy) {
|
|
|
2464
3346
|
decidingColumns: decidingColumns(config, parts.attrs === void 0 ? void 0 : {
|
|
2465
3347
|
...parts.attrs.table === void 0 ? {} : { table: parts.attrs.table },
|
|
2466
3348
|
columns: parts.attrs.columns
|
|
2467
|
-
}),
|
|
3349
|
+
}, parts.hook.teams),
|
|
2468
3350
|
markers: {
|
|
2469
3351
|
hook: "v1",
|
|
2470
3352
|
grants: "v1"
|
|
@@ -2472,6 +3354,11 @@ function manifestOf(parts, out, config, policy) {
|
|
|
2472
3354
|
requires: requiredCapabilities(config, policy)
|
|
2473
3355
|
};
|
|
2474
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
|
+
}
|
|
2475
3362
|
/** The first line of the generated hook: fields `--check` compares before the full text. */
|
|
2476
3363
|
function hookMarker(manifest) {
|
|
2477
3364
|
return `${HOOK_MARKER} schema=${manifest.hook.schema} tenant=${manifest.tenantClaim} budget=${String(manifest.budget.bytes)} claims=${manifest.claims.map((claim) => claim.name).join(",")}`;
|
|
@@ -2519,6 +3406,24 @@ function supabaseHookManifest(scopes, config, overrides = {}, policy) {
|
|
|
2519
3406
|
};
|
|
2520
3407
|
}
|
|
2521
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
|
+
/**
|
|
2522
3427
|
* The hook migration. With `grantsOut`, the statements `supabase db diff`
|
|
2523
3428
|
* drops are left out of `sql` and returned in `grants` for that file.
|
|
2524
3429
|
*/
|
|
@@ -2564,14 +3469,33 @@ function markerDrift(onDisk, expected, outRel) {
|
|
|
2564
3469
|
const changed = Object.keys(want).filter((key) => found[key] !== want[key]).map((key) => `${key} ${found[key] ?? "(none)"} -> ${want[key] ?? ""}`);
|
|
2565
3470
|
return changed.length === 0 ? "supabase hook drift" : `supabase hook drift: ${changed.join("; ")}`;
|
|
2566
3471
|
}
|
|
2567
|
-
|
|
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) {
|
|
2568
3482
|
return [
|
|
2569
3483
|
`hook ${manifest.hook.schema}.${manifest.hook.function} (${manifest.hook.out})`,
|
|
2570
3484
|
`helpers ${manifest.helpers.functions.map((fn) => `${manifest.helpers.schema}.${fn}`).join(", ")}`,
|
|
2571
3485
|
`tenant claim ${manifest.tenantClaim}`,
|
|
2572
3486
|
`budget ${String(manifest.budget.bytes)} bytes of ${manifest.budget.measure}`,
|
|
2573
3487
|
`claims ${manifest.claims.map((claim) => `${claim.name}${claim.source === "permdock" ? "" : ` (${claim.source})`}${claim.budget ? " [budget]" : ""}`).join(", ")}`,
|
|
2574
|
-
`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}`
|
|
2575
3499
|
].join("\n");
|
|
2576
3500
|
}
|
|
2577
3501
|
/**
|
|
@@ -2632,15 +3556,30 @@ async function runSupabase(input) {
|
|
|
2632
3556
|
}).filter(([, value]) => value !== void 0));
|
|
2633
3557
|
if (area === "inspect" && action === void 0) {
|
|
2634
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
|
+
}
|
|
2635
3567
|
const manifest = supabaseHookManifest(scopeList(policy.scopes), input.config, {
|
|
2636
3568
|
...overrides,
|
|
2637
3569
|
out: hookOut(input.cwd, input.config, input.schema, flag),
|
|
2638
3570
|
schemas: schemas.mode
|
|
2639
3571
|
}, policy);
|
|
2640
|
-
|
|
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);
|
|
2641
3577
|
return {
|
|
2642
3578
|
code: 0,
|
|
2643
|
-
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)
|
|
2644
3583
|
};
|
|
2645
3584
|
}
|
|
2646
3585
|
if (area !== "hook" || action !== "generate") return {
|
|
@@ -2651,7 +3590,9 @@ async function runSupabase(input) {
|
|
|
2651
3590
|
code: 2,
|
|
2652
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`
|
|
2653
3592
|
};
|
|
2654
|
-
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;
|
|
2655
3596
|
const outRel = typeof input.out === "string" ? input.out : hookOut(input.cwd, input.config, input.schema, flag);
|
|
2656
3597
|
const outPath = resolve(input.cwd, outRel);
|
|
2657
3598
|
const hook = input.config.supabase?.hook;
|
|
@@ -2702,4 +3643,4 @@ async function runSupabase(input) {
|
|
|
2702
3643
|
};
|
|
2703
3644
|
}
|
|
2704
3645
|
//#endregion
|
|
2705
|
-
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 };
|