permdock 0.6.0 → 0.8.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 +2 -3
- package/dist/{2020-C9VN-x8c.js → 2020-CJbO8Bvz.js} +1 -3
- package/dist/a2a/index.d.ts +7 -7
- package/dist/a2a/index.js +9 -9
- package/dist/action-result-CL-QCITA.d.ts +19 -0
- package/dist/{adapter-context-CRhqyzCk.js → adapter-context-CIQpQxbE.js} +8 -2
- package/dist/{adoption-scan-DCYe60Pi.js → adoption-scan-BLs67P1l.js} +5 -5
- package/dist/agent/index.d.ts +3 -3
- package/dist/agent/index.js +1 -1
- package/dist/ai-sdk/index.d.ts +31 -10
- package/dist/ai-sdk/index.js +22 -12
- package/dist/{app-data-MuyzVqX8.js → app-data-UNNm07jV.js} +10 -7
- package/dist/{approval-header-CJACtHkv.js → approval-header-8QV6MU4H.js} +6 -3
- package/dist/{approval-prompt-Dg5LeAcT.js → approval-prompt-B8hQY69x.js} +5 -6
- package/dist/{approval-prompt-DvSSPQJX.d.ts → approval-prompt-PYagyQUj.d.ts} +13 -11
- package/dist/approvals/index.d.ts +5 -5
- package/dist/approvals/index.js +7 -7
- package/dist/{approvals-p1PGoVjb.js → approvals-DnIBTuXE.js} +128 -78
- package/dist/{approvers-CqPOLD-o.js → approvers-B4r0N_Uz.js} +8 -2
- package/dist/{arazzo-41WuzHou.js → arazzo-3RhGfkAK.js} +2 -2
- package/dist/{arazzo-CaUVBn7D.js → arazzo-B5-ulWif.js} +6 -6
- package/dist/{args-IIolxxKA.js → args-0FrVs5EH.js} +125 -8
- package/dist/astro/index.d.ts +30 -12
- package/dist/astro/index.js +2 -2
- package/dist/{audience-DabClFLQ.js → audience-BAkBDMqn.js} +8 -8
- package/dist/{auth-DRLEizbL.js → auth--yPyZNgr.js} +21 -10
- package/dist/authzen/index.d.ts +171 -25
- package/dist/authzen/index.js +321 -149
- package/dist/{automation-BNM3TtDo.d.ts → automation-DqEoWHBc.d.ts} +42 -32
- package/dist/{automation-DVjOckjV.js → automation-x3KEUusw.js} +22 -21
- package/dist/base-url-BQbddZO5.js +9 -0
- package/dist/better-auth/index.d.ts +2 -2
- package/dist/better-auth/index.js +13 -7
- package/dist/better-supabase/index.d.ts +392 -220
- package/dist/better-supabase/index.js +293 -152
- package/dist/{bind-DOyrv6zi.d.ts → bind-Cp2hBHzP.d.ts} +27 -12
- package/dist/{bind-CAvgUuKs.js → bind-D_sZSVA3.js} +22 -10
- package/dist/{body-CH5of8Ne.js → body-CJQwYVa8.js} +3 -3
- package/dist/{body-text-QcXok_SI.js → body-text-DQhcmqdY.js} +8 -4
- package/dist/{boundary-BM8a_P6E.js → boundary-BV3O1eud.js} +8 -2
- package/dist/{boundary-BmHxVH1J.d.ts → boundary-C9ck-3uK.d.ts} +13 -4
- package/dist/{budget-NbEtbJC_.js → budget-BELja5A9.js} +6 -3
- package/dist/{budget-JqcRqyhK.d.ts → budget-hYsPz_yE.d.ts} +6 -3
- package/dist/{build-instance-Bu_eDqYw.js → build-instance-CNWaYJyr.js} +3 -3
- package/dist/{canonical-json-BC8_nMTw.js → canonical-json-DwilZ1iB.js} +6 -3
- package/dist/{capability-N1K9IpqS.js → capability-BqX94r07.js} +31 -25
- package/dist/{capability-Drg-1YhL.d.ts → capability-ChuiONQU.d.ts} +41 -29
- package/dist/{casbin-Dyu2gnUD.js → casbin-H0rKxBx2.js} +16 -8
- package/dist/{casbin-Cr7RLtA3.js → casbin-cbSbhT_k.js} +2 -2
- package/dist/{casl-64gpT-8x.js → casl-C4OINZHI.js} +2 -2
- package/dist/{casl-DjEDhTCP.js → casl-CHHoCldP.js} +19 -10
- package/dist/catalog/index.d.ts +104 -23
- package/dist/catalog/index.js +117 -8
- package/dist/{catalog-HD2gf5mY.js → catalog-BFpz2EmT.js} +57 -26
- package/dist/{catalog-DZVbrF-z.js → catalog-DCspHDc8.js} +3 -3
- package/dist/{catalog-doc-Cdn7-0pQ.js → catalog-doc-DjMKzJp9.js} +53 -16
- package/dist/{catalog-fingerprint-CCP0-yQS.js → catalog-fingerprint-e6aCWosn.js} +19 -15
- package/dist/catalog-mRQQQhNK.js +1 -0
- package/dist/catalog-operations-Dadrl7Z-.js +60 -0
- package/dist/{create-CQWIpUG-.js → challenge-DImNcR7B.js} +157 -39
- package/dist/chat/index.d.ts +1 -1
- package/dist/chat/index.js +13 -10
- package/dist/chat-sdk/index.d.ts +44 -26
- package/dist/chat-sdk/index.js +17 -17
- package/dist/checks-CGkP3Z7A.js +40 -0
- package/dist/{claims-map-7oQ3ue4X.js → claims-map-CKkoAAYF.js} +5 -2
- package/dist/{claims-map-Ca-QX8C6.d.ts → claims-map-D1Pb5oRq.d.ts} +8 -5
- package/dist/claude-agent/index.d.ts +6 -6
- package/dist/claude-agent/index.js +6 -3
- package/dist/clerk/index.d.ts +11 -7
- package/dist/clerk/index.js +6 -6
- package/dist/cli/bin.js +4 -4
- package/dist/cli/index.d.ts +82 -7
- package/dist/cli/index.js +6 -6
- package/dist/{clients-C7zLFuWT.d.ts → clients-C_NOET3z.d.ts} +5 -5
- package/dist/{clients-DjU5ABMy.js → clients-DYr3U86j.js} +3 -3
- package/dist/cloud/index.d.ts +186 -38
- package/dist/cloud/index.js +293 -31
- package/dist/{cloud-ytQ3uviA.js → cloud-BFlGMaak.js} +5 -6
- package/dist/{codemod-5mpSpnUY.js → codemod-DLQ9Zpo4.js} +3 -4
- package/dist/{codemod-ua2hHy7w.js → codemod-DWSN2erG.js} +523 -201
- package/dist/collect-B5BL3klN.js +1 -0
- package/dist/{collect-mLTY4nwb.js → collect-B7ZFAJU3.js} +36 -64
- package/dist/{collect-Ci6akVwH.js → collect-Bzv3le0A.js} +6 -6
- package/dist/{compare-pfyVnBjE.js → compare-DTfyUunF.js} +2 -2
- package/dist/compile/index.d.ts +2 -2
- package/dist/compile/index.js +1 -1
- package/dist/{compile-1bsAezL0.d.ts → compile-BFzysW3o.d.ts} +36 -12
- package/dist/{compile-CMqMx_IN.js → compile-EzEMB-7v.js} +77 -33
- package/dist/{completion-BTFrHZhX.js → completion-saoYiRFO.js} +17 -8
- package/dist/config-BwPBfN0t.js +108 -0
- package/dist/{config-Bj2Ixq3d.js → config-DBeXXmBF.js} +2 -2
- package/dist/{config-report-DSpsLpCE.js → config-report-BipSWA6V.js} +9 -6
- package/dist/config-shape-ykV0Vm2n.js +134 -0
- package/dist/{connection-DjhIJSs2.js → connection-B72dg5Q2.js} +23 -22
- package/dist/connector-schema-CYLQNMYq.js +434 -0
- package/dist/{context-B_u3_bDJ.js → context-BnIzxTNE.js} +4 -3
- package/dist/convex/index.d.ts +13 -7
- package/dist/convex/index.js +9 -6
- package/dist/core-H-mbhpZc.js +341 -0
- package/dist/core-hWIARPDz.d.ts +206 -0
- package/dist/{create-CBMmFie-.d.ts → create-BSNrVuxh.d.ts} +87 -34
- package/dist/{create-B30OMUOJ.d.ts → create-BVq1lNQE.d.ts} +49 -28
- package/dist/{create-D_NmPOdH.d.ts → create-CM1FciYG.d.ts} +37 -29
- package/dist/{create-CGm28gyI.js → create-Cq4Uox0f.js} +13 -9
- package/dist/{create-DCF2SvoT.js → create-_noSrY1T.js} +15 -21
- package/dist/{credential-BcoiejpY.js → credential-CyyyvCsL.js} +42 -39
- package/dist/{credentials-DPyHmYz5.js → credentials-CdDxp7jN.js} +6 -6
- package/dist/{deciding-columns-Sq12mEA6.js → deciding-columns-NB4wcyBf.js} +13 -2
- package/dist/{delegation-j6-rc37o.js → delegation-CDB6_keF.js} +31 -22
- package/dist/delivery/index.d.ts +5 -5
- package/dist/delivery/index.js +6 -5
- package/dist/{delivery-DCAgNyCn.js → delivery-BupfvJIV.js} +81 -20
- package/dist/{delivery-event-xX4obB8F.js → delivery-event-JioK5YbS.js} +6 -6
- package/dist/denied-text-CHNlVInN.d.ts +22 -0
- package/dist/{describe-BybMRY7A.js → describe-Bb4hGK5d.js} +6 -5
- package/dist/{describe-B5qgDvEW.d.ts → describe-ByS9LgHK.d.ts} +5 -5
- package/dist/{device-BARQ8eYG.js → device-BwbJNmb2.js} +11 -8
- package/dist/{diff-CmuSD3vc.js → diff-CN8IYhC_.js} +2 -2
- package/dist/{diff-3jbx6Rm4.js → diff-iZWV65nC.js} +23 -14
- package/dist/{digest-B3kc_PgQ.d.ts → digest-8Yx2CchM.d.ts} +3 -3
- package/dist/{doctor-BdZw53-k.js → doctor-CHD1M9R5.js} +485 -141
- package/dist/{doctor-3ZqNHX_G.js → doctor-D3wo-yuz.js} +4 -4
- package/dist/drizzle/index.d.ts +33 -19
- package/dist/drizzle/index.js +17 -9
- package/dist/elysia/index.d.ts +17 -11
- package/dist/elysia/index.js +5 -5
- package/dist/{errors-BKy0EfhN.js → errors-B6R_lg2a.js} +13 -4
- package/dist/{errors-BWXBMaKK.d.ts → errors-CHwoRRpB.d.ts} +4 -1
- package/dist/{errors-CWTY6uih.js → errors-Vpu6rKHl.js} +14 -10
- package/dist/{errors-DH5QEGXh.d.ts → errors-zi_4T-rx.d.ts} +22 -6
- package/dist/{evaluate-CNClBvcj.js → evaluate-Dd8Ta0Ie.js} +185 -80
- package/dist/{evaluations-beAooV0n.js → evaluations-IBceAeKT.js} +41 -20
- package/dist/{evaluations-C_1vdSZc.d.ts → evaluations-z8dQFDaN.d.ts} +12 -6
- package/dist/eve/index.d.ts +9 -6
- package/dist/eve/index.js +4 -4
- package/dist/{event-time-CsegxXxB.js → event-time-BGy48400.js} +8 -4
- package/dist/{expiry-D4_YKRKD.js → expiry-6XByK0dm.js} +8 -5
- package/dist/express/index.d.ts +9 -6
- package/dist/express/index.js +9 -6
- package/dist/fastify/index.d.ts +16 -10
- package/dist/fastify/index.js +8 -5
- package/dist/{fetch-adapter-Dw0MTS3D.d.ts → fetch-adapter-C1DCvpqV.d.ts} +9 -6
- package/dist/{fetch-adapter-DD_gfmrC.js → fetch-adapter-JL43jD3E.js} +14 -11
- package/dist/fields-D0vUI6dq.js +498 -0
- package/dist/{files-C5ZI27eV.js → files-B3AA05f1.js} +21 -5
- package/dist/{files-D_JIzUrP.js → files-BSjrtIHw.js} +11 -4
- package/dist/{fixtures-B7XrLeY7.js → fixtures-A1_sp_tR.js} +15 -6
- package/dist/{flags-C3DktBDY.js → flags-DXjoTVbS.js} +2 -2
- package/dist/{freeze-CrU8nQeX.js → freeze-jjan0lCv.js} +4 -1
- package/dist/{from-snapshot-CTCMsFZk.js → from-snapshot-DCakWRsr.js} +26 -16
- package/dist/gen-B5kvbAoZ.js +58 -0
- package/dist/gen-DWCYcMQM.js +827 -0
- package/dist/generate-CRVV5V7l.js +165 -0
- package/dist/generate-CezbCaTI.js +275 -0
- package/dist/{grantee-hxrUsbpM.js → grantee-Dke-9rd1.js} +4 -4
- package/dist/{grantee-conditions-CcXf8hMM.js → grantee-conditions-BrYPe-w0.js} +12 -12
- package/dist/{grantee-match-DbENBHLB.js → grantee-match-7RZZvoT_.js} +12 -6
- package/dist/{graph-sql-B-dsAT6j.d.ts → graph-sql-BwFC4Qjs.d.ts} +3 -3
- package/dist/h3/index.d.ts +10 -7
- package/dist/h3/index.js +3 -3
- package/dist/headers-B9jQxjtW.d.ts +10 -0
- package/dist/{helpers-CBYVMjwh.js → helpers-DJicaG6f.js} +40 -28
- package/dist/hono/index.d.ts +16 -10
- package/dist/hono/index.js +5 -5
- package/dist/{hosted-BPk51-kX.d.ts → hosted-Cmtxogd0.d.ts} +44 -20
- package/dist/{hosted-B46-5LYE.js → hosted-D0IzESu_.js} +68 -25
- package/dist/{http-ujKm0JXE.js → http-DH94eh6f.js} +4 -4
- package/dist/{http-BBoKefeS.js → http-DKLXrFGk.js} +13 -7
- package/dist/{http-DXJ37RDA.js → http-DOL33cO0.js} +11 -8
- package/dist/{import-wyqXUyjm.js → import-CST57XLp.js} +64 -51
- package/dist/{import-CNV7I2Dw.js → import-_YqhhwvX.js} +6 -6
- package/dist/{index-B8YjkEZ4.d.ts → index-B8s204GL.d.ts} +64 -52
- package/dist/{index-Ch8LpNDp.d.ts → index-BT5-1VsX.d.ts} +64 -25
- package/dist/{index-DuWxc5dt.d.ts → index-BW_0MZOS.d.ts} +388 -149
- package/dist/index-BhxEUY9J.d.ts +233 -0
- package/dist/index-Bv5iXPqU.d.ts +210 -0
- package/dist/{index-C-6Letxg.d.ts → index-_9UiQIkt.d.ts} +164 -77
- package/dist/index.d.ts +22 -21
- package/dist/index.js +35 -33
- package/dist/{init-GG6Jh8HD.js → init-Dz_PsHdv.js} +5 -5
- package/dist/{init-DeMYsnYJ.js → init-cE3A8aXq.js} +10 -10
- package/dist/{instance-options-BsVpyGIk.d.ts → instance-options-B0KXqTrJ.d.ts} +4 -4
- package/dist/{instance-snapshot-BOEhcqIF.js → instance-snapshot--JWiTrvO.js} +81 -56
- package/dist/{instant-BluqDvyS.js → instant-DK3Iz83e.js} +2 -2
- package/dist/{internals-Dk8A8fX3.js → internals-B3IgHrvo.js} +6 -3
- package/dist/{json-schema-B-vAwlde.js → json-schema-BPGa-RjQ.js} +9 -3
- package/dist/{json-schema-CN_iLFH2.d.ts → json-schema-BfXgnRNT.d.ts} +4 -4
- package/dist/jwt/index.d.ts +125 -17
- package/dist/jwt/index.js +157 -16
- package/dist/{kernel-D0NVb1cK.js → kernel-C-fYydV2.js} +151 -16
- package/dist/kysely/index.d.ts +49 -33
- package/dist/kysely/index.js +9 -7
- package/dist/{live-options-BaAFCIiu.js → live-options-BBIT68le.js} +2 -2
- package/dist/{load-DFS_ry0W.js → load-DjSU5KXO.js} +6 -6
- package/dist/load-Dm0pSYH3.js +1 -0
- package/dist/{login-Dfe5RlYk.js → login-D-8tMqzo.js} +4 -4
- package/dist/{login-imhuwvn3.js → login-DplQ0s84.js} +18 -15
- package/dist/{manifest-dvL2XEe1.js → manifest-Cgiq5oqc.js} +67 -37
- package/dist/{manifest-mx5ghSFM.d.ts → manifest-CzzWtnAb.d.ts} +144 -28
- package/dist/{manifest-schema-C0kK_8V0.js → manifest-schema-2r37XRhD.js} +80 -9
- package/dist/{manifest-C8IzW3Do.js → manifest-wg8WkkpD.js} +11 -7
- package/dist/{map-claims-D3oRmTk0.js → map-claims-BNWCJtmP.js} +27 -18
- package/dist/{map-error-Dr70oA_3.js → map-error-pasIGqMT.js} +7 -7
- package/dist/{markers-C6joDI3o.js → markers-BeHZ4x9Q.js} +20 -5
- package/dist/mcp/index.d.ts +154 -47
- package/dist/mcp/index.js +200 -41
- package/dist/{migrate-CIq4-E9F.js → migrate-B7oP_sQU.js} +102 -31
- package/dist/module-values-BJTBdo6y.js +107 -0
- package/dist/nest/index.d.ts +23 -13
- package/dist/nest/index.js +18 -11
- package/dist/next/client.d.ts +5 -2
- package/dist/next/client.js +1 -1
- package/dist/next/index.d.ts +72 -26
- package/dist/next/index.js +110 -6
- package/dist/next/plugin.d.ts +1 -1
- package/dist/next/plugin.js +4 -3
- package/dist/node/index.d.ts +5 -5
- package/dist/node/index.js +3 -3
- package/dist/{ocsf-BFp-PZZA.js → ocsf-TcjRBgIs.js} +15 -5
- package/dist/openai/index.d.ts +13 -7
- package/dist/openai/index.js +3 -3
- package/dist/openapi/index.d.ts +61 -30
- package/dist/openapi/index.js +2 -2
- package/dist/{openapi-B7HZ0f-r.js → openapi-BOsx0xn9.js} +34 -24
- package/dist/{openapi-C4dDTVEd.js → openapi-CBZUhA3l.js} +4 -5
- package/dist/{openapi-DD1SV-5-.js → openapi-VeHHU2l9.js} +23 -14
- package/dist/{operation-findings-DgATDpvh.js → operation-findings-CXtFzlKJ.js} +3 -3
- package/dist/{operations-X0VM7F3m.d.ts → operations-Ci_rT6Uo.d.ts} +10 -7
- package/dist/orpc/index.d.ts +68 -14
- package/dist/orpc/index.js +62 -13
- package/dist/otel/index.d.ts +7 -4
- package/dist/otel/index.js +8 -5
- package/dist/output-files-BHOIlrfD.js +1 -0
- package/dist/{output-files-DhRBBE4n.js → output-files-BIQ_9pIs.js} +29 -17
- package/dist/{output-1im__-08.js → output-tkju6U7R.js} +15 -7
- package/dist/ownership-B4L59T9u.js +1054 -0
- package/dist/parse-1_ZheTW5.js +151 -0
- package/dist/parse-local-manifest-BQhTlLQS.d.ts +10 -0
- package/dist/parse-local-manifest-DEiCF4ah.js +69 -0
- package/dist/{parse-request-D_tUXG6M.js → parse-request-CwCZpyjV.js} +7 -8
- package/dist/{paths-DXSHAMIa.js → paths-CUvURzHp.js} +4 -1
- package/dist/pdp/index.d.ts +9 -6
- package/dist/pdp/index.js +23 -12
- package/dist/{peer-CRvC7Hg1.js → peer-C9LvBCcb.js} +1 -1
- package/dist/peer-Q0fuZ6hx.js +982 -0
- package/dist/{permdock-SV8ZINYT.d.ts → permdock-B6Sf4T_S.d.ts} +270 -117
- package/dist/{permdock-BrAscV28.js → permdock-L-_I_3zP.js} +226 -74
- package/dist/{permission-registry-Br4jSNVi.js → permission-registry-B8tYxPIt.js} +24 -11
- package/dist/{vocabulary-CN8H_9UF.d.ts → permission-types-CAY-GU7e.d.ts} +130 -104
- package/dist/{permissions-u_KHg-sN.d.ts → permissions-Bx6UI8n1.d.ts} +6 -2
- package/dist/{permissions-B-wCP5ZC.js → permissions-CVXmRILq.js} +3 -3
- package/dist/{permissions-BPxlwVhN.js → permissions-mDcTWoBs.js} +8 -5
- package/dist/pg-DQTqRrou.js +60 -0
- package/dist/{pins-8ILTftC9.js → pins-nqarl3oE.js} +4 -1
- package/dist/pkce-CnmmYqUZ.js +21 -0
- package/dist/{policy-77FSAq_V.d.ts → policy-Ba4bDhaj.d.ts} +5 -5
- package/dist/{policy-DbM5YYtV.js → policy-CLQ8__GF.js} +49 -20
- package/dist/{policy-from-catalog-C2gMa2Dj.js → policy-from-catalog-CJgOm6aq.js} +28 -25
- package/dist/{policy-module-CTlwMvLI.js → policy-module-xym9fnSq.js} +12 -6
- package/dist/{policy-types-n0uRTsW8.d.ts → policy-types-CCiDRZBH.d.ts} +802 -334
- package/dist/postgres-store-DcyrPS-r.js +1028 -0
- package/dist/{postgrest-DAjUkF9w.js → postgrest-D4nuPXIQ.js} +88 -36
- package/dist/{postgrest-CEgRbefE.d.ts → postgrest-DicQyqm-.d.ts} +60 -30
- package/dist/powersync-DHNQX06W.js +1117 -0
- package/dist/{powersync-DISt6SUe.js → powersync-DXqGuq9A.js} +3 -3
- package/dist/powersync-Djf-zCpB.js +1 -0
- package/dist/preset/index.d.ts +38 -28
- package/dist/preset/index.js +1 -1
- package/dist/{preset-DZdU0tne.js → preset-BjLzeFpp.js} +58 -34
- package/dist/{principal-source-pHneukrx.js → principal-source-C6N60GtM.js} +10 -10
- package/dist/prisma/index.d.ts +69 -41
- package/dist/prisma/index.js +21 -17
- package/dist/{problem-CTviyH5L.js → problem-BVLHFK33.js} +41 -21
- package/dist/{problem-details-cn5X30gZ.js → problem-details-CLDgX1KV.js} +13 -4
- package/dist/{problem-types-CJ2325SZ.js → problem-types-DSsRfONQ.js} +4 -1
- package/dist/prompt-BYc6drYW.js +938 -0
- package/dist/protected-action-BE7N_Luo.d.ts +58 -0
- package/dist/protected-action-DUYqb-Ma.js +80 -0
- package/dist/{protected-BlF0F6wL.js → protected-action-QEA8arRB.js} +48 -14
- package/dist/{provider-B1al-AZz.js → provider-C55OGXJ7.js} +5 -4
- package/dist/{provider-DILL9oPK.d.ts → provider-DXfq5c2d.d.ts} +1 -1
- package/dist/{provider-store-DM6DNcta.js → provider-store-CaTv00tr.js} +13 -9
- package/dist/pull-B65ndFNZ.js +1 -0
- package/dist/{pull-jEwbf80J.js → pull-CwpGaQSi.js} +12 -11
- package/dist/{push-BD4f15co.js → push-DgssgzkK.js} +62 -16
- package/dist/{pushed-policy-DCW91KQU.d.ts → pushed-policy-D1Eoi6NM.d.ts} +12 -6
- package/dist/{pushed-policy-CqtxkV4G.js → pushed-policy-ITwYKvvH.js} +10 -7
- package/dist/react/index.d.ts +9 -8
- package/dist/react/index.js +7 -6
- package/dist/react/provider-client.d.ts +1 -1
- package/dist/react/provider-client.js +1 -1
- package/dist/react-native/index.d.ts +104 -51
- package/dist/react-native/index.js +394 -67
- package/dist/{refs-K6eWUJ0H.js → refs-C8BKxc_e.js} +17 -3
- package/dist/{relation-walk-3OyDBF0S.js → relation-walk-DK_gkgL7.js} +12 -9
- package/dist/{relations-BnCWnJGI.js → relations-BxvRvDHK.js} +3 -3
- package/dist/{replay-Du1tJjG7.js → replay-BU09ad4L.js} +1 -1
- package/dist/{replay-Bkm-Ne4l.d.ts → replay-DNftIb_R.d.ts} +1 -1
- package/dist/{request-context-C81Pip9n.js → request-context-C25ilqiJ.js} +8 -8
- package/dist/{request-schema-CMreVuFM.js → request-schema-DhX7UbfQ.js} +4 -1
- package/dist/resend/index.d.ts +34 -28
- package/dist/resend/index.js +29 -29
- package/dist/resolve-names-CF7xXLSG.js +201 -0
- package/dist/{resource-relations-D_jw0BFx.js → resource-relations-8-pCScBO.js} +18 -9
- package/dist/{retire-CALjIQ7e.js → retire-B2xffQgY.js} +15 -6
- package/dist/{revocations-R07lFBnX.d.ts → revocations-BaUXHM1N.d.ts} +6 -3
- package/dist/{rls-DTvYd-lI.js → rls-CNEH2_BG.js} +743 -624
- package/dist/{rls-BAqP4q66.js → rls-Ca8Jz9b5.js} +41 -10
- package/dist/{role-builder-uWQZ4v84.js → role-builder-BK2-T6oD.js} +41 -20
- package/dist/rolldown-runtime-C3I60J0A.js +4 -0
- package/dist/{row-conditions-h2HythXQ.js → row-conditions-BAGHOmVq.js} +4 -3
- package/dist/{rpc-VSl5ylaQ.js → rpc-fNqAIqQk.js} +8 -5
- package/dist/{run-CUKuz0A8.js → run-Bz26OTfO.js} +26 -23
- package/dist/run-D-JE8QWb.js +1 -0
- package/dist/{run-ticket-DocwaTKn.d.ts → run-ticket-DbWI9f99.d.ts} +33 -13
- package/dist/{run-ticket-sxFI6LAk.js → run-ticket-Dv7aF7Dk.js} +29 -8
- package/dist/{runtime-D3VTAiCA.js → runtime-BGnrOkVH.js} +5 -2
- package/dist/{saas-BCXRuXca.js → saas-iWnUdwCt.js} +42 -29
- package/dist/{scan-qvOe0hS3.js → scan-DCj1KQfn.js} +1 -1
- package/dist/{schema-B4v0Qrac.js → schema-BOJjqlWL.js} +3 -2
- package/dist/{schema-yLuBWWsh.js → schema-Dst9I9Gs.js} +9 -5
- package/dist/scim/index.d.ts +3 -2
- package/dist/scim/index.js +3 -1
- package/dist/scim-D8YupzX1.js +44 -0
- package/dist/{scim-ClHtpyV3.js → scim-jJBJ7g1Z.js} +35 -551
- package/dist/{scopes-CUPSjo9q.js → scopes-0Up_UA2t.js} +42 -24
- package/dist/server/index.d.ts +12 -12
- package/dist/server/index.js +13 -13
- package/dist/{server-C3WXAHZj.js → server-3cVlTLde.js} +31 -31
- package/dist/{server-types-CKQiCnON.d.ts → server-types-CIlpSA2G.d.ts} +81 -46
- package/dist/{sha256-D9ihqmvd.js → sha256-C-4WXKIu.js} +4 -3
- package/dist/{shared-BAK8t4Uo.js → shared-Afctg7B0.js} +100 -61
- package/dist/{shared-DvvFzYXe.js → shared-l0oGGetg.js} +9 -6
- package/dist/{signals-D3NcTKUS.js → signals-B1vHR3fN.js} +2 -2
- package/dist/{sink-BEZSlMS_.js → sink-D9_vh372.js} +32 -21
- package/dist/{sink-4-eQIRWf.d.ts → sink-Dvi7YZG_.d.ts} +44 -20
- package/dist/{skills-B6lVdD_W.js → skills-Bjj7BNEQ.js} +16 -12
- package/dist/{skills-CTYwkl44.js → skills-OuoMR49L.js} +3 -3
- package/dist/{snapshot-B7DkYg6g.js → snapshot-CXlzi69u.js} +21 -18
- package/dist/{snapshot-cache-PXI-vGpY.d.ts → snapshot-cache-BAXZ0KOp.d.ts} +21 -12
- package/dist/{snapshot-cache-DZHQ0KF6.js → snapshot-cache-Bx_4xC_6.js} +14 -11
- package/dist/solid/index.d.ts +55 -15
- package/dist/solid/index.js +46 -12
- package/dist/solid-start/index.d.ts +30 -12
- package/dist/solid-start/index.js +3 -3
- package/dist/sources-B1Os_YUu.d.ts +312 -0
- package/dist/{sources-vs5dGOsS.js → sources-CMAM-2A3.js} +156 -51
- package/dist/sources-qoIJQrJv.js +11 -0
- package/dist/{sql-B5T1IL83.js → sql-0WjxIp9g.js} +32 -7
- package/dist/sql-B80DFdpG.d.ts +10 -0
- package/dist/{src-Cu2m75uo.js → src-DZ0l9UAg.js} +305 -123
- package/dist/ssf/index.d.ts +4 -4
- package/dist/ssf/index.js +665 -224
- package/dist/{standard-webhooks-rbD7LS6h.d.ts → standard-webhooks-C-qX4mJW.d.ts} +7 -7
- package/dist/{standard-webhooks-DgFFD-Ga.js → standard-webhooks-D67a3nzk.js} +5 -5
- package/dist/{store-BDutJkDL.js → store-RNFvaJJv.js} +43 -29
- package/dist/{store-options-u0ycEe8s.js → store-options-Dil3lraY.js} +105 -15
- package/dist/stores-C0Kta5Ft.d.ts +59 -0
- package/dist/{stores-CGhM8BN_.js → stores-DxZWDXCs.js} +42 -5
- package/dist/{stream-CvdUS9V1.js → stream-CDvF0sJm.js} +5 -5
- package/dist/{stream-CeCMJmBB.d.ts → stream-ltuLdtTG.d.ts} +4 -3
- package/dist/{style-DiKWnAvn.js → style-DblOtSga.js} +1 -1
- package/dist/{style-Uao76wO7.js → style-Ds11Hmk4.js} +3 -1
- package/dist/{subject-settings-CkEwrw3W.js → subject-settings-8sH5HlII.js} +8 -4
- package/dist/{row-check-Dt35czLy.d.ts → subject-settings-vNW8qmUH.d.ts} +30 -18
- package/dist/supabase/index.d.ts +48 -37
- package/dist/supabase/index.js +6 -6
- package/dist/supabase/middleware.d.ts +19 -13
- package/dist/supabase/middleware.js +7 -7
- package/dist/{supabase-x5JtR2tc.js → supabase-BL1qJzzY.js} +82 -36
- package/dist/{supabase-By_frk3U.js → supabase-D39cuGPt.js} +3 -3
- package/dist/{supabase-hook-BMoEhZir.js → supabase-hook-B-yXnzUl.js} +1206 -286
- package/dist/supabase-hook-H-MtE9Wd.js +1 -0
- package/dist/supautils-BU-pAEpf.js +808 -0
- package/dist/{support-session-C6xJQYut.js → support-session-BsmPCbz8.js} +22 -22
- package/dist/svelte/PermissionBoundary.svelte +2 -6
- package/dist/svelte/Protected.svelte +2 -8
- package/dist/svelte/index.d.ts +9 -8
- package/dist/svelte/index.js +10 -9
- package/dist/svelte/runtime.d.ts +4 -4
- package/dist/svelte/runtime.js +4 -4
- package/dist/svelte/source.d.ts +9 -8
- package/dist/svelte/source.js +6 -5
- package/dist/sveltekit/index.d.ts +30 -12
- package/dist/sveltekit/index.js +2 -2
- package/dist/{ownership-DqaJNJPn.js → tables-DeMNEy6V.js} +1025 -1085
- package/dist/tanstack-start/index.d.ts +22 -10
- package/dist/tanstack-start/index.js +2 -2
- package/dist/{target-Bw37TFNA.js → target-qdEAnnhU.js} +6 -6
- package/dist/{tenancy-DN2QAx9z.js → tenancy-5d1zVBvK.js} +36 -21
- package/dist/terminal/index.d.ts +23 -14
- package/dist/terminal/index.js +17 -20
- package/dist/testing/core.d.ts +2 -0
- package/dist/testing/core.js +1 -0
- package/dist/testing/fixtures/index.d.ts +15 -0
- package/dist/testing/fixtures/index.js +831 -0
- package/dist/testing/index.d.ts +235 -285
- package/dist/testing/index.js +502 -927
- package/dist/testing/saas/index.d.ts +43 -27
- 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-BtfSmdUo.js +444 -0
- package/dist/{thenable-yD7SabqG.js → thenable-BNSM1U2R.js} +12 -3
- package/dist/{time-DkWjdL98.js → time-nR1JesoH.js} +32 -8
- package/dist/{token-BLZcjQgt.js → token-DC9EQiet.js} +15 -13
- package/dist/{tool-refusal-CMLN5xhn.js → tool-refusal-Qpjs_W6M.js} +5 -2
- package/dist/trpc/index.d.ts +11 -8
- package/dist/trpc/index.js +15 -9
- package/dist/type-helpers-BIPIDa6a.d.ts +50 -0
- package/dist/{types-8RnwUAvE.d.ts → types-AMJ5qoU_.d.ts} +49 -30
- package/dist/{types-C_IiEs64.d.ts → types-B2mlGuhW.d.ts} +14 -11
- package/dist/{types-_WhUP7ud.d.ts → types-B4uqKDnp.d.ts} +25 -12
- package/dist/{types-CX7AvRqP.d.ts → types-BJk0BKRX.d.ts} +24 -14
- package/dist/types-B_d_g7T3.d.ts +262 -0
- package/dist/{types-BdtSDbBO.d.ts → types-B_tiYvk8.d.ts} +59 -32
- package/dist/{types-DqzsnlSA.js → types-CcUXciSj.js} +17 -5
- package/dist/{types-Dfv0aTER.d.ts → types-DC1Loeh3.d.ts} +449 -168
- package/dist/{types-lUlG3TVd.d.ts → types-DHKPcqzr.d.ts} +2 -2
- package/dist/{types-C791HFu9.d.ts → types-DjuMBNF9.d.ts} +68 -32
- package/dist/{types-C863OQiR.d.ts → types-HzqOtvsJ.d.ts} +23 -12
- package/dist/{types-Druu9wLM.d.ts → types-ZzRGoViD.d.ts} +77 -24
- package/dist/{types-BzzaHxt3.d.ts → types-ah9NlU6j.d.ts} +137 -48
- package/dist/{types-CVZSNocA.d.ts → types-djVzLlIV.d.ts} +31 -14
- package/dist/{types-BtHtcKMr.d.ts → types-yUuPR5Hy.d.ts} +47 -24
- package/dist/unplugin/index.d.ts +1 -1
- package/dist/unplugin/index.js +2 -2
- package/dist/usage-CYeXek0p.js +1 -0
- package/dist/{usage-SveTRTyr.js → usage-CxEzS4ey.js} +50 -26
- package/dist/{usage-CRVl9V3t.js → usage-ab0PdusX.js} +2 -2
- package/dist/{validation-error-ZfUHbKvf.js → validation-error-CYg2kJEw.js} +4 -1
- package/dist/{validation-error-DHUrAkku.d.ts → validation-error-YGg2mXyH.d.ts} +5 -2
- package/dist/{validity-CZ7-y0Cj.js → validity-Buc7w8E9.js} +13 -10
- package/dist/{verifier-DHuh-okk.js → verifier-DUV6pLqZ.js} +10 -4
- package/dist/{verify-BaAKx7t6.js → verify-DZeqoWu5.js} +417 -489
- package/dist/version-DMQ0dnN5.js +48 -0
- package/dist/version-DizhmD72.js +1 -0
- package/dist/{views-DTIIO-oQ.js → views-CD8wuL4Z.js} +19 -6
- package/dist/vocabulary-DEJ5j4mR.d.ts +70 -0
- package/dist/vue/index.d.ts +71 -21
- package/dist/vue/index.js +50 -13
- package/dist/{waiter-B986w1oK.d.ts → waiter-Bu9zAlE0.d.ts} +13 -10
- package/dist/{waiter-BGUtGYoU.js → waiter-aBLM63_f.js} +1 -1
- package/dist/{watch-vea54PRw.js → watch-Cx_WciLE.js} +8 -8
- package/dist/watch-DB42U1ib.js +1 -0
- package/dist/webmcp/index.d.ts +11 -11
- package/dist/webmcp/index.js +8 -5
- package/dist/{where-scope-C9vfEphl.js → where-scope-DlCdCM_8.js} +56 -30
- package/dist/{who-can-DWBAcaCQ.js → who-can-rI7dCR9Q.js} +23 -20
- package/dist/workflow/index.d.ts +3 -3
- package/dist/workflow/index.js +13 -13
- package/dist/workflow-sdk/index.d.ts +19 -13
- package/dist/workflow-sdk/index.js +6 -6
- package/dist/{wrap-gX61EtpB.js → wrap-B2wziJI_.js} +11 -5
- package/dist/{wrap-C5jC6sKI.d.ts → wrap-DlJE3gS_.d.ts} +8 -5
- package/package.json +25 -14
- package/schemas/catalog-v1.json +3 -0
- 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 +308 -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-credentials/references/tokens-keys-links.md +8 -6
- package/skills/permdock-data/references/queries-and-rls.md +6 -2
- package/skills/permdock-tenancy/SKILL.md +1 -1
- package/skills/permdock-tenancy/references/ownership-and-custom-roles.md +2 -1
- package/skills/permdock-wire/references/adapters.md +28 -22
- 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/config-bs_kZeYq.js +0 -162
- package/dist/denied-text-CiFQNuMV.d.ts +0 -19
- package/dist/fields-OYG_JR78.js +0 -203
- package/dist/generate-CNU1pIOo.js +0 -171
- package/dist/headers-BIjfMaoC.js +0 -8
- package/dist/headers-CIbDTUTK.d.ts +0 -7
- package/dist/index-Cp_ilKi1.d.ts +0 -91
- package/dist/index-CueFnxQc.d.ts +0 -110
- package/dist/load-BxEtwlBS.js +0 -1
- package/dist/output-files-B3IZJksC.js +0 -1
- package/dist/package-root-Dk_ETdkp.js +0 -31
- package/dist/parse-Cxq0WxrA.js +0 -53
- package/dist/parse-local-manifest-5ODwqu8b.d.ts +0 -10
- package/dist/parse-local-manifest-CVSs6J9I.js +0 -34
- package/dist/peer-C8swJ2GH.js +0 -50
- package/dist/policies-DP2nqRoF.js +0 -295
- package/dist/powersync-BkWWCS1K.js +0 -538
- package/dist/powersync-MMJ2mI2q.js +0 -1
- package/dist/problem-details-B45V5d2b.d.ts +0 -7
- package/dist/prompt-DfZLJLIn.js +0 -32
- package/dist/protected-RFGpakN9.d.ts +0 -38
- package/dist/pull-CvpINcMK.js +0 -1
- package/dist/run-DDwUaJDU.js +0 -1
- package/dist/sources-Xc4zkszI.d.ts +0 -190
- package/dist/stores-BUGNbJTt.d.ts +0 -30
- 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/types-B3_ooZgZ.d.ts +0 -172
- package/dist/usage-CZpSQP6L.js +0 -1
- package/dist/version-CEbQ5UeM.js +0 -18
- package/dist/version-DXkYUISx.js +0 -1
- package/dist/watch--ovlPOc0.js +0 -1
|
@@ -0,0 +1,498 @@
|
|
|
1
|
+
import { a as sole } from "./compact-CAf557ZB.js";
|
|
2
|
+
import { i as configError } from "./errors-Vpu6rKHl.js";
|
|
3
|
+
import { c as jsonSchemaOf } from "./catalog-doc-DjMKzJp9.js";
|
|
4
|
+
import { A as quoteQualified, D as qualified, E as helperSchema, O as quoteIdent, _ as subjectClaimJsonSql, k as quoteLiteral, s as signedIn } from "./shared-Afctg7B0.js";
|
|
5
|
+
//#region src/cli/sql/clauses.ts
|
|
6
|
+
/**
|
|
7
|
+
* True when `sql` is one parenthesised expression, so AND / OR need not wrap it
|
|
8
|
+
* again.
|
|
9
|
+
*/
|
|
10
|
+
function isWrapped(sql) {
|
|
11
|
+
if (!sql.startsWith("(") || !sql.endsWith(")")) return false;
|
|
12
|
+
let depth = 0;
|
|
13
|
+
let quoted = false;
|
|
14
|
+
for (let index = 0; index < sql.length; index += 1) {
|
|
15
|
+
const ch = sql[index];
|
|
16
|
+
if (ch === "'") quoted = !quoted;
|
|
17
|
+
else if (!quoted && ch === "(") depth += 1;
|
|
18
|
+
else if (!quoted && ch === ")") {
|
|
19
|
+
depth -= 1;
|
|
20
|
+
if (depth === 0 && index < sql.length - 1) return false;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return depth === 0;
|
|
24
|
+
}
|
|
25
|
+
function wrapSql(sql) {
|
|
26
|
+
return isWrapped(sql) ? sql : `(${sql})`;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* The grant's `validFrom` / `validUntil` as a clock check: `from` inclusive,
|
|
30
|
+
* `until` exclusive, matching the in-process evaluator.
|
|
31
|
+
*/
|
|
32
|
+
function validitySql(validity) {
|
|
33
|
+
if (validity === void 0) return;
|
|
34
|
+
return andSql(validity.from === void 0 ? void 0 : `now() >= to_timestamp(${validity.from})`, validity.until === void 0 ? void 0 : `now() < to_timestamp(${validity.until})`);
|
|
35
|
+
}
|
|
36
|
+
function andSql(...parts) {
|
|
37
|
+
const present = parts.filter((part) => part !== void 0 && part !== "true");
|
|
38
|
+
if (present.length === 0) return;
|
|
39
|
+
return present.length === 1 ? present[0] : present.map(wrapSql).join(" and ");
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* `USING` and `WITH CHECK` for a branch: its access check ANDed with its row
|
|
43
|
+
* conditions.
|
|
44
|
+
*/
|
|
45
|
+
function branchClauses(branch) {
|
|
46
|
+
const using = branch.command === "insert" ? void 0 : andSql(branch.access, branch.using) ?? "true";
|
|
47
|
+
const check = branch.command === "insert" || branch.command === "update" ? andSql(branch.access, branch.check) ?? "true" : void 0;
|
|
48
|
+
return {
|
|
49
|
+
...using === void 0 ? {} : { using },
|
|
50
|
+
...check === void 0 ? {} : { check }
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
//#endregion
|
|
54
|
+
//#region src/cli/rls/policies.ts
|
|
55
|
+
/**
|
|
56
|
+
* Each database role gets its own policy, so no role sees two permissive
|
|
57
|
+
* policies for one command.
|
|
58
|
+
*/
|
|
59
|
+
const AUDIENCES = ["authenticated", "anon"];
|
|
60
|
+
const DEFAULT_POLICY_NAME = "{table}_{op}";
|
|
61
|
+
const DEFAULT_PER_ROLE_NAME = "{role}_{permission}";
|
|
62
|
+
const PLACEHOLDER = /\{(table|op|role|permission)\}/gu;
|
|
63
|
+
function sanitize(name) {
|
|
64
|
+
return name.replaceAll(/[^A-Za-z0-9_]/gu, "_");
|
|
65
|
+
}
|
|
66
|
+
function render(template, values) {
|
|
67
|
+
return sanitize(template.replaceAll(PLACEHOLDER, (_match, key) => values[key]));
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Rejects a template that cannot name every policy of the chosen shape
|
|
71
|
+
* uniquely.
|
|
72
|
+
*/
|
|
73
|
+
function assertPolicyName(template, perRole) {
|
|
74
|
+
if (!perRole && /\{(role|permission)\}/u.test(template)) throw configError("PermDock CLI: --policy-name {role} and {permission} need --policy-per-role; a collapsed policy covers several roles");
|
|
75
|
+
if (!perRole && !(template.includes("{table}") && template.includes("{op}"))) throw configError("PermDock CLI: --policy-name needs {table} and {op} so each table and command gets its own policy");
|
|
76
|
+
}
|
|
77
|
+
function orSql(parts) {
|
|
78
|
+
const distinct = [...new Set(parts)];
|
|
79
|
+
if (distinct.includes("true")) return "true";
|
|
80
|
+
return sole(distinct) ?? distinct.map(wrapSql).join(" or ");
|
|
81
|
+
}
|
|
82
|
+
function negate(sql) {
|
|
83
|
+
return sql === void 0 ? void 0 : `(${sql}) is not true`;
|
|
84
|
+
}
|
|
85
|
+
function policyOf(name, branch, using, check) {
|
|
86
|
+
const deny = branch.effect === "deny";
|
|
87
|
+
const policy = {
|
|
88
|
+
name,
|
|
89
|
+
table: branch.table,
|
|
90
|
+
command: branch.command,
|
|
91
|
+
effect: branch.effect,
|
|
92
|
+
roles: branch.roles
|
|
93
|
+
};
|
|
94
|
+
const finalUsing = deny ? negate(using) : using;
|
|
95
|
+
const finalCheck = deny ? negate(check) : check;
|
|
96
|
+
if (finalUsing !== void 0) policy.using = finalUsing;
|
|
97
|
+
if (finalCheck !== void 0) policy.check = finalCheck;
|
|
98
|
+
return policy;
|
|
99
|
+
}
|
|
100
|
+
function uniqueName(names, name) {
|
|
101
|
+
const seen = names.get(name) ?? 0;
|
|
102
|
+
names.set(name, seen + 1);
|
|
103
|
+
return seen === 0 ? name : `${name}_${seen + 1}`;
|
|
104
|
+
}
|
|
105
|
+
function perRolePolicies(branches, template) {
|
|
106
|
+
const names = /* @__PURE__ */ new Map();
|
|
107
|
+
return branches.map((branch) => {
|
|
108
|
+
const clauses = branchClauses(branch);
|
|
109
|
+
const deny = branch.effect === "deny";
|
|
110
|
+
const base = render(template, {
|
|
111
|
+
table: branch.table,
|
|
112
|
+
op: branch.command,
|
|
113
|
+
role: branch.label,
|
|
114
|
+
permission: branch.permissionKey
|
|
115
|
+
});
|
|
116
|
+
const name = `${deny ? "deny_" : ""}${base}${branch.coverage === true ? "_select_coverage" : ""}`;
|
|
117
|
+
return policyOf(uniqueName(names, name), branch, clauses.using, clauses.check);
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Branches of one grant-key group share their row condition, so the group
|
|
122
|
+
* becomes one OR branch whose access ORs the helper calls of each scope.
|
|
123
|
+
*/
|
|
124
|
+
function mergeGroups(branches) {
|
|
125
|
+
const merged = [];
|
|
126
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
127
|
+
for (const branch of branches) {
|
|
128
|
+
const id = branch.grantKey === void 0 ? void 0 : `${branch.table}\u0000${branch.command}\u0000${branch.grantKey}\u0000${branch.coverage === true}`;
|
|
129
|
+
const entry = id === void 0 ? void 0 : byKey.get(id);
|
|
130
|
+
if (entry === void 0) {
|
|
131
|
+
const created = {
|
|
132
|
+
branch,
|
|
133
|
+
accesses: branch.access === void 0 ? [] : [branch.access]
|
|
134
|
+
};
|
|
135
|
+
if (id !== void 0) byKey.set(id, created);
|
|
136
|
+
merged.push(created);
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
if (branch.access !== void 0 && !entry.accesses.includes(branch.access)) entry.accesses.push(branch.access);
|
|
140
|
+
}
|
|
141
|
+
return merged.map(({ branch, accesses }) => accesses.length <= 1 ? branch : withAccess(branch, orSql(accesses)));
|
|
142
|
+
}
|
|
143
|
+
function withAccess(branch, access) {
|
|
144
|
+
return {
|
|
145
|
+
...branch,
|
|
146
|
+
access
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
function collapsedPolicies(branches, template) {
|
|
150
|
+
const groups = /* @__PURE__ */ new Map();
|
|
151
|
+
for (const branch of mergeGroups(branches)) {
|
|
152
|
+
const id = `${branch.table}\u0000${branch.command}\u0000${branch.effect}`;
|
|
153
|
+
groups.set(id, [...groups.get(id) ?? [], branch]);
|
|
154
|
+
}
|
|
155
|
+
const names = /* @__PURE__ */ new Map();
|
|
156
|
+
return [...groups.values()].flatMap((group) => AUDIENCES.flatMap((audience) => {
|
|
157
|
+
const members = group.filter((branch) => branch.roles.includes(audience));
|
|
158
|
+
const [first] = members;
|
|
159
|
+
if (first === void 0) return [];
|
|
160
|
+
const deny = first.effect === "deny";
|
|
161
|
+
const clauses = members.map(branchClauses);
|
|
162
|
+
const usings = clauses.flatMap((item) => item.using === void 0 ? [] : [item.using]);
|
|
163
|
+
const checks = clauses.flatMap((item) => item.check === void 0 ? [] : [item.check]);
|
|
164
|
+
const base = render(template, {
|
|
165
|
+
table: first.table,
|
|
166
|
+
op: first.command,
|
|
167
|
+
role: first.label,
|
|
168
|
+
permission: first.permissionKey
|
|
169
|
+
});
|
|
170
|
+
return [policyOf(uniqueName(names, `${deny ? "deny_" : ""}${base}${audience === "anon" ? "_anon" : ""}`), {
|
|
171
|
+
...first,
|
|
172
|
+
roles: [audience]
|
|
173
|
+
}, usings.length === 0 ? void 0 : orSql(usings), checks.length === 0 ? void 0 : orSql(checks))];
|
|
174
|
+
}));
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Assembles policies. The default is one PERMISSIVE policy per table, command
|
|
178
|
+
* and database role (Splinter `multiple_permissive_policies` stays quiet), with
|
|
179
|
+
* denies in one RESTRICTIVE policy per table, command and role.
|
|
180
|
+
*/
|
|
181
|
+
function assemblePolicies(branches, shape) {
|
|
182
|
+
const template = shape.name ?? (shape.perRole ? DEFAULT_PER_ROLE_NAME : DEFAULT_POLICY_NAME);
|
|
183
|
+
assertPolicyName(template, shape.perRole);
|
|
184
|
+
return shape.perRole ? perRolePolicies(branches, template) : collapsedPolicies(branches, template);
|
|
185
|
+
}
|
|
186
|
+
const DEFAULT_READ_ONLY_ACTORS = ["support", "impersonation"];
|
|
187
|
+
const ACTOR_KIND = /^[a-z][a-z0-9_-]*$/u;
|
|
188
|
+
/** The actor kinds `rls.readOnlyActors` names, or `undefined` when it is off. */
|
|
189
|
+
function readOnlyActorKinds(setting) {
|
|
190
|
+
if (setting === void 0 || setting === false) return;
|
|
191
|
+
const kinds = setting === true ? DEFAULT_READ_ONLY_ACTORS : setting;
|
|
192
|
+
if (kinds.length === 0 || kinds.some((kind) => !ACTOR_KIND.test(kind))) throw configError("PermDock CLI: rls.readOnlyActors must be true or a non-empty list of actor kinds such as 'support'");
|
|
193
|
+
return [...new Set(kinds)];
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* `permdock_actor_may_write()`, for hand-written write policies. Names are part
|
|
197
|
+
* of the SQL contract.
|
|
198
|
+
*/
|
|
199
|
+
const ACTOR_MAY_WRITE = "permdock_actor_may_write";
|
|
200
|
+
/**
|
|
201
|
+
* True unless the token's `act` claim (`act`, as SQL `jsonb`) is a session of
|
|
202
|
+
* one of `kinds` that is not `read_only: false`, or an agent with `read_only:
|
|
203
|
+
* true` (agents default to writable, as better-supabase reads them).
|
|
204
|
+
*/
|
|
205
|
+
function readOnlyActorPasses(act, kinds) {
|
|
206
|
+
const list = `array[${kinds.map((kind) => `'${kind}'`).join(", ")}]::text[]`;
|
|
207
|
+
const passes = `(not coalesce(${kinds.includes("support") ? `(${act} ->> 'kind') = any(${list}) or ((${act} ->> 'kind') is null and ${act} ? 'session_id')` : `(${act} ->> 'kind') = any(${list})`}, false) or coalesce((${act} ->> 'read_only') = 'false', false))`;
|
|
208
|
+
return kinds.includes("agent") ? passes : `${passes} and not coalesce((${act} ->> 'kind') = 'agent' and (${act} ->> 'read_only') = 'true', false)`;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* `permdock_actor_may_write()`: {@link readOnlyActorPasses} as a function, so
|
|
212
|
+
* hand-written write policies apply the same read-only default.
|
|
213
|
+
*/
|
|
214
|
+
function actorMayWriteSql(ctx, kinds) {
|
|
215
|
+
const fn = qualified(ctx, ACTOR_MAY_WRITE);
|
|
216
|
+
return `-- rls.readOnlyActors: false for a token whose act claim is a read-only ${kinds.join(" or ")} session; hand-written write policies call it
|
|
217
|
+
create or replace function ${fn}()
|
|
218
|
+
returns boolean
|
|
219
|
+
language sql
|
|
220
|
+
stable
|
|
221
|
+
set search_path = ''
|
|
222
|
+
as $$
|
|
223
|
+
select ${readOnlyActorPasses(subjectClaimJsonSql(ctx, "act"), kinds)}
|
|
224
|
+
$$;
|
|
225
|
+
revoke execute on function ${fn}() from public, anon;
|
|
226
|
+
grant execute on function ${fn}() to authenticated;
|
|
227
|
+
`;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* One restrictive policy per table and write command the allow policies grant
|
|
231
|
+
* to `authenticated`: the write passes unless the token's `act` claim (`act`,
|
|
232
|
+
* as SQL `jsonb`) is a session of one of `kinds` that is not `read_only:
|
|
233
|
+
* false`. Reads are never touched.
|
|
234
|
+
*/
|
|
235
|
+
function readOnlyActorPolicies(policies, act, kinds) {
|
|
236
|
+
const passes = readOnlyActorPasses(act, kinds);
|
|
237
|
+
const seen = /* @__PURE__ */ new Set();
|
|
238
|
+
const out = [];
|
|
239
|
+
for (const policy of policies) {
|
|
240
|
+
const key = `${policy.table}\u0000${policy.command}`;
|
|
241
|
+
if (policy.effect !== "allow" || policy.command === "select" || !policy.roles.includes("authenticated") || seen.has(key)) continue;
|
|
242
|
+
seen.add(key);
|
|
243
|
+
out.push({
|
|
244
|
+
name: sanitize(`${policy.table}_${policy.command}_read_only_actors`),
|
|
245
|
+
table: policy.table,
|
|
246
|
+
command: policy.command,
|
|
247
|
+
effect: "deny",
|
|
248
|
+
roles: ["authenticated"],
|
|
249
|
+
...policy.command === "insert" ? {} : { using: passes },
|
|
250
|
+
...policy.command === "delete" ? {} : { check: passes }
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
return out;
|
|
254
|
+
}
|
|
255
|
+
//#endregion
|
|
256
|
+
//#region src/cli/rls/fields.ts
|
|
257
|
+
/** Names of the field-view objects. Part of the SQL contract. */
|
|
258
|
+
const FIELD_VIEWS = {
|
|
259
|
+
/** `<table>_visible`: the `security_invoker` view clients read. */
|
|
260
|
+
view: "_visible",
|
|
261
|
+
/**
|
|
262
|
+
* `<table>_visible_fields`: the owner-rights companion `--revoke-columns`
|
|
263
|
+
* adds.
|
|
264
|
+
*/
|
|
265
|
+
companion: "_visible_fields",
|
|
266
|
+
/** The companion's row-key column, joined to the base table's key. */
|
|
267
|
+
key: "permdock_key",
|
|
268
|
+
/** Marks the companion so doctor PD022 knows it reads as its owner on purpose. */
|
|
269
|
+
comment: "permdock:field-companion",
|
|
270
|
+
/** `<table>_mask(p_row)`: the row-masking function `fields: 'mask'` adds. */
|
|
271
|
+
mask: "_mask"
|
|
272
|
+
};
|
|
273
|
+
function covers(branch, column) {
|
|
274
|
+
return branch.fields === void 0 || branch.fields.includes(column);
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* A read grant that only shapes columns: a field-limited deny (it never denies
|
|
278
|
+
* the row) or an allow with an empty list (it grants nothing). With field views
|
|
279
|
+
* it leaves the row policy and lives in the view's masks.
|
|
280
|
+
*/
|
|
281
|
+
function fieldOnly(branch) {
|
|
282
|
+
if (branch.command !== "select" || branch.fields === void 0) return false;
|
|
283
|
+
return branch.effect === "deny" || branch.fields.length === 0;
|
|
284
|
+
}
|
|
285
|
+
/** Branches the row policies keep when field views compile. */
|
|
286
|
+
function rowBranches(branches) {
|
|
287
|
+
return branches.filter((branch) => !fieldOnly(branch));
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Whether the reader is signed in, for branches with no helper call: a grant to
|
|
291
|
+
* any signed-in user relies on `to authenticated` in its policy, which a view
|
|
292
|
+
* does not have.
|
|
293
|
+
*/
|
|
294
|
+
function audience(ctx, branch) {
|
|
295
|
+
if (branch.access !== void 0 || branch.roles.length !== 1) return;
|
|
296
|
+
if (branch.roles[0] === "authenticated") return signedIn(ctx);
|
|
297
|
+
return branch.roles[0] === "anon" ? `not (${signedIn(ctx)})` : void 0;
|
|
298
|
+
}
|
|
299
|
+
function clause(ctx, branch) {
|
|
300
|
+
return andSql(audience(ctx, branch), branchClauses(branch).using) ?? "true";
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* `can(permission, row, { field })` in SQL: an allow that covers the column
|
|
304
|
+
* holds for the row and no covering deny does. Every access term is the
|
|
305
|
+
* uncorrelated helper call the row policy uses, so it runs once per statement.
|
|
306
|
+
*/
|
|
307
|
+
function maskSql(ctx, allows, denies, column) {
|
|
308
|
+
const allowed = allows.filter((branch) => covers(branch, column)).map((branch) => clause(ctx, branch));
|
|
309
|
+
if (allowed.length === 0) return "false";
|
|
310
|
+
const denied = denies.filter((branch) => covers(branch, column)).map((branch) => clause(ctx, branch));
|
|
311
|
+
const allow = orSql(allowed);
|
|
312
|
+
if (denied.length === 0) return allow;
|
|
313
|
+
const deny = orSql(denied);
|
|
314
|
+
return allow === "true" ? `not ${wrapSql(deny)}` : `${wrapSql(allow)} and not ${wrapSql(deny)}`;
|
|
315
|
+
}
|
|
316
|
+
function schemaColumns(policy, resource) {
|
|
317
|
+
const node = policy.resources.get(resource);
|
|
318
|
+
const schema = node === void 0 ? null : jsonSchemaOf(node);
|
|
319
|
+
const properties = schema !== null && typeof schema === "object" ? schema.properties : void 0;
|
|
320
|
+
return properties !== null && typeof properties === "object" ? Object.keys(properties) : void 0;
|
|
321
|
+
}
|
|
322
|
+
function viewName(table, suffix) {
|
|
323
|
+
return `${table}${suffix}`;
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* `<helper schema>.<table><suffix>`: outside the Data API's schemas, so the
|
|
327
|
+
* companion's owner rights reach clients only through the `_visible` join and
|
|
328
|
+
* the mask function is neither an RPC nor a computed field.
|
|
329
|
+
*/
|
|
330
|
+
function helperObjectName(ctx, table, suffix) {
|
|
331
|
+
const base = table.startsWith("public.") ? table.slice(7) : table.replaceAll(".", "_");
|
|
332
|
+
return `${helperSchema(ctx)}.${viewName(base, suffix)}`;
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* One view per table whose read grants limit fields. A column is restricted
|
|
336
|
+
* when some read allow lists fields without it or some read deny lists it;
|
|
337
|
+
* every other column, and the row key, passes through unchanged.
|
|
338
|
+
*/
|
|
339
|
+
function fieldViews(policy, ctx, branches, options, warnings) {
|
|
340
|
+
const byTable = /* @__PURE__ */ new Map();
|
|
341
|
+
for (const branch of branches) {
|
|
342
|
+
if (branch.command !== "select" || branch.coverage === true) continue;
|
|
343
|
+
byTable.set(branch.table, [...byTable.get(branch.table) ?? [], branch]);
|
|
344
|
+
}
|
|
345
|
+
const views = [];
|
|
346
|
+
for (const [table, reads] of byTable) {
|
|
347
|
+
const allows = reads.filter((branch) => branch.effect === "allow" && branch.fields?.length !== 0);
|
|
348
|
+
const denies = reads.filter((branch) => branch.effect === "deny");
|
|
349
|
+
const limited = reads.some((branch) => branch.fields !== void 0);
|
|
350
|
+
const resource = reads.find((branch) => branch.resource !== void 0)?.resource;
|
|
351
|
+
if (!limited || allows.length === 0 || resource === void 0) continue;
|
|
352
|
+
const names = schemaColumns(policy, resource);
|
|
353
|
+
if (names === void 0) throw configError(`PermDock CLI: --fields ${options.mask === true ? "mask" : "views"} needs the ${resource} schema's JSON Schema (Standard JSON Schema) to list the columns of ${table}`);
|
|
354
|
+
const key = policy.resources.get(resource)?.id ?? "id";
|
|
355
|
+
const restricted = (column) => column !== key && (allows.some((branch) => branch.fields !== void 0 && !branch.fields.includes(column)) || denies.some((branch) => branch.fields?.includes(column) === true));
|
|
356
|
+
const columns = names.map((name) => {
|
|
357
|
+
quoteIdent(name);
|
|
358
|
+
return restricted(name) ? {
|
|
359
|
+
name,
|
|
360
|
+
mask: maskSql(ctx, allows, denies, name)
|
|
361
|
+
} : { name };
|
|
362
|
+
});
|
|
363
|
+
if (columns.every((column) => column.mask === void 0)) continue;
|
|
364
|
+
const view = viewName(table, FIELD_VIEWS.view);
|
|
365
|
+
if (allows.some((branch) => branch.fields !== void 0 && !branch.fields.includes(key))) warnings.push(`field view ${view}: the key ${key} passes through, although a read grant on ${resource} omits it`);
|
|
366
|
+
const hidden = columns.filter((column) => column.mask !== void 0).map((column) => column.name);
|
|
367
|
+
if (options.helpersOnly === true) warnings.push(`field view ${view}: ${table} still returns ${hidden.join(", ")} to direct reads; revoke select on those columns from client roles in your own grants, or read them through a function`);
|
|
368
|
+
else if (!options.revokeColumns) warnings.push(`field view ${view}: ${table} still returns ${hidden.join(", ")} to direct reads; add --revoke-columns so clients read through the view`);
|
|
369
|
+
views.push({
|
|
370
|
+
resource,
|
|
371
|
+
table,
|
|
372
|
+
view,
|
|
373
|
+
key,
|
|
374
|
+
columns,
|
|
375
|
+
roles: reads.some((branch) => branch.roles.includes("anon")) ? ["anon", "authenticated"] : ["authenticated"],
|
|
376
|
+
...options.revokeColumns ? { companion: helperObjectName(ctx, table, FIELD_VIEWS.companion) } : {},
|
|
377
|
+
...options.mask === true ? { maskFunction: helperObjectName(ctx, table, FIELD_VIEWS.mask) } : {}
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
return views;
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Columns of `view`'s table that `anon` and `authenticated` keep on the base
|
|
384
|
+
* table with `--revoke-columns`.
|
|
385
|
+
*/
|
|
386
|
+
function readableColumns(view) {
|
|
387
|
+
return view.columns.filter((column) => column.mask === void 0).map((column) => column.name);
|
|
388
|
+
}
|
|
389
|
+
function restrictedColumns(view) {
|
|
390
|
+
return view.columns.filter((column) => column.mask !== void 0).map((column) => column.name);
|
|
391
|
+
}
|
|
392
|
+
function columnList(names) {
|
|
393
|
+
return names.map(quoteIdent).join(", ");
|
|
394
|
+
}
|
|
395
|
+
function selectList(lines) {
|
|
396
|
+
return lines.map((line) => ` ${line}`).join(",\n");
|
|
397
|
+
}
|
|
398
|
+
function grantView(name, roles) {
|
|
399
|
+
return [`revoke all on table ${quoteQualified(name)} from anon, authenticated, public;`, `grant select on table ${quoteQualified(name)} to ${roles.join(", ")};`].join("\n");
|
|
400
|
+
}
|
|
401
|
+
function inlineViewSql(view) {
|
|
402
|
+
const targets = view.columns.map((column) => column.mask === void 0 ? quoteIdent(column.name) : `case when ${column.mask} then ${quoteIdent(column.name)} end as ${quoteIdent(column.name)}`);
|
|
403
|
+
return `create or replace view ${quoteQualified(view.view)} with (security_invoker = true) as
|
|
404
|
+
select
|
|
405
|
+
${selectList(targets)}
|
|
406
|
+
from ${quoteQualified(view.table)};`;
|
|
407
|
+
}
|
|
408
|
+
function companionSql(view, companion) {
|
|
409
|
+
const restricted = view.columns.filter((column) => column.mask !== void 0);
|
|
410
|
+
const targets = [`${quoteIdent(view.key)} as ${quoteIdent(FIELD_VIEWS.key)}`, ...restricted.map((column) => `case when ${column.mask} then ${quoteIdent(column.name)} end as ${quoteIdent(column.name)}`)];
|
|
411
|
+
const any = orSql(restricted.map((column) => column.mask ?? "false"));
|
|
412
|
+
const name = companion.slice(0, companion.indexOf("."));
|
|
413
|
+
const schema = quoteIdent(name);
|
|
414
|
+
return `${name === "public" ? "" : `create schema if not exists ${schema};
|
|
415
|
+
revoke all on schema ${schema} from public;
|
|
416
|
+
grant usage on schema ${schema} to ${view.roles.join(", ")};
|
|
417
|
+
`}create or replace view ${quoteQualified(companion)} with (security_barrier = true) as
|
|
418
|
+
select
|
|
419
|
+
${selectList(targets)}
|
|
420
|
+
from ${quoteQualified(view.table)}
|
|
421
|
+
where ${any};
|
|
422
|
+
comment on view ${quoteQualified(companion)} is ${quoteLiteral(`${FIELD_VIEWS.comment} ${view.view}`)};`;
|
|
423
|
+
}
|
|
424
|
+
function joinedViewSql(view, companion) {
|
|
425
|
+
const targets = view.columns.map((column) => column.mask === void 0 ? `t.${quoteIdent(column.name)}` : `f.${quoteIdent(column.name)}`);
|
|
426
|
+
return `create or replace view ${quoteQualified(view.view)} with (security_invoker = true) as
|
|
427
|
+
select
|
|
428
|
+
${selectList(targets)}
|
|
429
|
+
from ${quoteQualified(view.table)} t
|
|
430
|
+
left join ${quoteQualified(companion)} f on f.${quoteIdent(FIELD_VIEWS.key)} = t.${quoteIdent(view.key)};`;
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* `select` on only the unrestricted columns (and the key) of the base table,
|
|
434
|
+
* for `--revoke-columns`.
|
|
435
|
+
*/
|
|
436
|
+
function columnGrantSql(view, role) {
|
|
437
|
+
return `grant select (${columnList(readableColumns(view))}) on table ${quoteQualified(view.table)} to ${role};`;
|
|
438
|
+
}
|
|
439
|
+
function columnRevokeSql(view) {
|
|
440
|
+
return `revoke select (${columnList(restrictedColumns(view))}) on table ${quoteQualified(view.table)} from anon, authenticated;`;
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
443
|
+
* `<table>_mask(p_row)`: the row with each restricted column the caller may not
|
|
444
|
+
* read set to null, by the same masks as the view. It reads only the row it is
|
|
445
|
+
* given, so its caller decides which rows; `security invoker`, because it needs
|
|
446
|
+
* nothing beyond the helpers the masks call. The body names the parameter `$1`,
|
|
447
|
+
* since a column called `p_row` would shadow the name.
|
|
448
|
+
*/
|
|
449
|
+
function maskFunctionSql(view, fn) {
|
|
450
|
+
const table = quoteQualified(view.table);
|
|
451
|
+
const name = quoteQualified(fn);
|
|
452
|
+
const nulls = view.columns.flatMap((column) => column.mask === void 0 ? [] : [`case when ${column.mask} then '{}'::jsonb else pg_catalog.jsonb_build_object(${quoteLiteral(column.name)}, null) end`]);
|
|
453
|
+
return `-- ${fn}: a row of ${view.table} with ${restrictedColumns(view).join(", ")} null unless a read grant covers the column for the row, for SQL that reads ${view.table} without ${view.view}
|
|
454
|
+
create or replace function ${name}(p_row ${table})
|
|
455
|
+
returns ${table}
|
|
456
|
+
language sql
|
|
457
|
+
stable
|
|
458
|
+
security invoker
|
|
459
|
+
set search_path = ''
|
|
460
|
+
as $$
|
|
461
|
+
select pg_catalog.jsonb_populate_record(
|
|
462
|
+
$1,
|
|
463
|
+
${nulls.join("\n || ")}
|
|
464
|
+
)
|
|
465
|
+
from (select ($1).*) r
|
|
466
|
+
$$;
|
|
467
|
+
revoke all on function ${name}(${table}) from public, anon, authenticated;
|
|
468
|
+
grant execute on function ${name}(${table}) to ${view.roles.join(", ")};`;
|
|
469
|
+
}
|
|
470
|
+
/**
|
|
471
|
+
* The view SQL: the `security_invoker` view, and with `--revoke-columns` the
|
|
472
|
+
* owner-rights companion it joins for the restricted columns. The companion
|
|
473
|
+
* masks every column with the full field decision and keeps only rows where one
|
|
474
|
+
* is readable, so reading it directly shows nothing `pick` would not.
|
|
475
|
+
*/
|
|
476
|
+
function fieldViewsSql(views) {
|
|
477
|
+
return views.map((view) => {
|
|
478
|
+
const head = `-- field view over ${view.table}: ${restrictedColumns(view).join(", ")} read as null unless a read grant covers the column for the row`;
|
|
479
|
+
const mask = view.maskFunction === void 0 ? [] : [maskFunctionSql(view, view.maskFunction)];
|
|
480
|
+
if (view.companion === void 0) return [
|
|
481
|
+
head,
|
|
482
|
+
inlineViewSql(view),
|
|
483
|
+
grantView(view.view, view.roles),
|
|
484
|
+
...mask
|
|
485
|
+
].join("\n");
|
|
486
|
+
return [
|
|
487
|
+
head,
|
|
488
|
+
`-- ${view.companion} reads ${view.table} as its owner; ${view.view} reads the rows as the caller and joins it`,
|
|
489
|
+
companionSql(view, view.companion),
|
|
490
|
+
grantView(view.companion, view.roles),
|
|
491
|
+
joinedViewSql(view, view.companion),
|
|
492
|
+
grantView(view.view, view.roles),
|
|
493
|
+
...mask
|
|
494
|
+
].join("\n");
|
|
495
|
+
}).join("\n\n");
|
|
496
|
+
}
|
|
497
|
+
//#endregion
|
|
498
|
+
export { wrapSql as _, fieldViewsSql as a, ACTOR_MAY_WRITE as c, orSql as d, readOnlyActorKinds as f, validitySql as g, branchClauses as h, fieldViews as i, actorMayWriteSql as l, andSql as m, columnGrantSql as n, rowBranches as o, readOnlyActorPolicies as p, columnRevokeSql as r, viewName as s, FIELD_VIEWS as t, assemblePolicies as u };
|
|
@@ -1,10 +1,22 @@
|
|
|
1
|
-
import { n as CliError } from "./errors-
|
|
2
|
-
import { existsSync, mkdirSync, readFileSync, realpathSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
1
|
+
import { n as CliError } from "./errors-Vpu6rKHl.js";
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, realpathSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { dirname, relative, resolve } from "node:path";
|
|
4
4
|
import { execFileSync } from "node:child_process";
|
|
5
5
|
//#region src/cli/core/files.ts
|
|
6
|
+
/**
|
|
7
|
+
* `/dev/null` and its kin: a rename over a device is refused, so it is written
|
|
8
|
+
* in place.
|
|
9
|
+
*/
|
|
10
|
+
function isCharacterDevice(abs) {
|
|
11
|
+
try {
|
|
12
|
+
return statSync(abs).isCharacterDevice();
|
|
13
|
+
} catch {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
6
17
|
function outcomeOf(abs, text) {
|
|
7
18
|
if (!existsSync(abs)) return "created";
|
|
19
|
+
if (isCharacterDevice(abs)) return "updated";
|
|
8
20
|
return readFileSync(abs, "utf8") === text ? "unchanged" : "updated";
|
|
9
21
|
}
|
|
10
22
|
/** What writing `files` would do, without writing. */
|
|
@@ -27,6 +39,10 @@ function applyFiles(cwd, files, options = {}) {
|
|
|
27
39
|
for (const [index, file] of files.entries()) {
|
|
28
40
|
if (planned[index]?.outcome === "unchanged") continue;
|
|
29
41
|
const target = resolve(cwd, file.path);
|
|
42
|
+
if (isCharacterDevice(target)) {
|
|
43
|
+
writeFileSync(target, file.text);
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
30
46
|
const temp = `${target}.permdock-${String(process.pid)}.tmp`;
|
|
31
47
|
mkdirSync(dirname(target), { recursive: true });
|
|
32
48
|
writeFileSync(temp, file.text);
|
|
@@ -58,8 +74,8 @@ function fileSummary(applied, dryRun) {
|
|
|
58
74
|
return applied.map((file) => `${VERBS[file.outcome][dryRun ? 1 : 0]} ${file.path}`).join("\n");
|
|
59
75
|
}
|
|
60
76
|
/**
|
|
61
|
-
* The files among `paths` with uncommitted changes in git. Outside a git
|
|
62
|
-
*
|
|
77
|
+
* The files among `paths` with uncommitted changes in git. Outside a git work
|
|
78
|
+
* tree, or without git, nothing counts as dirty.
|
|
63
79
|
*/
|
|
64
80
|
function dirtyFiles(cwd, paths) {
|
|
65
81
|
if (paths.length === 0) return [];
|
|
@@ -121,4 +137,4 @@ function refuseDirty(input) {
|
|
|
121
137
|
});
|
|
122
138
|
}
|
|
123
139
|
//#endregion
|
|
124
|
-
export { fileSummary as n,
|
|
140
|
+
export { refuseDirty as i, fileSummary as n, planFiles as r, applyFiles as t };
|
|
@@ -37,7 +37,10 @@ function listSourceFiles(cwd, srcPath) {
|
|
|
37
37
|
function segments(path) {
|
|
38
38
|
return path.split(/[\\/]/u).filter((part) => part !== "" && part !== ".");
|
|
39
39
|
}
|
|
40
|
-
/**
|
|
40
|
+
/**
|
|
41
|
+
* Installed packages often ship only `dist`; their own dependencies are never
|
|
42
|
+
* walked.
|
|
43
|
+
*/
|
|
41
44
|
function skipDirsFor(path) {
|
|
42
45
|
return segments(path).includes("node_modules") ? PACKAGE_SKIP_DIRS : SKIP_DIRS;
|
|
43
46
|
}
|
|
@@ -85,7 +88,8 @@ function walkDir(dir, out, skip) {
|
|
|
85
88
|
/**
|
|
86
89
|
* The `.sql` files under each entry: a glob, a file, or a directory searched
|
|
87
90
|
* recursively. `order: 'entry'` keeps each entry's matches together in entry
|
|
88
|
-
* order (how `supabase db diff` reads `schema_paths`); the default sorts all
|
|
91
|
+
* order (how `supabase db diff` reads `schema_paths`); the default sorts all
|
|
92
|
+
* paths.
|
|
89
93
|
*/
|
|
90
94
|
function sqlFiles(cwd, entries, options = {}) {
|
|
91
95
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -93,7 +97,7 @@ function sqlFiles(cwd, entries, options = {}) {
|
|
|
93
97
|
for (const entry of entries) {
|
|
94
98
|
const abs = resolve(cwd, entry);
|
|
95
99
|
const isGlob = /[*?[{]/u.test(entry);
|
|
96
|
-
if (!isGlob && statSync(abs, { throwIfNoEntry: false })?.isFile()) {
|
|
100
|
+
if (!isGlob && statSync(abs, { throwIfNoEntry: false })?.isFile() === true) {
|
|
97
101
|
if (!seen.has(abs)) {
|
|
98
102
|
seen.add(abs);
|
|
99
103
|
ordered.push(abs);
|
|
@@ -117,7 +121,10 @@ function rel(cwd, abs) {
|
|
|
117
121
|
function defaultSrcPath() {
|
|
118
122
|
return ["./src"];
|
|
119
123
|
}
|
|
120
|
-
/**
|
|
124
|
+
/**
|
|
125
|
+
* Where `doctor` reads source files: `doctor.srcPath`, else `collect.srcPath`,
|
|
126
|
+
* else `./src`.
|
|
127
|
+
*/
|
|
121
128
|
function doctorSrcPath(config) {
|
|
122
129
|
return config.doctor?.srcPath ?? config.collect?.srcPath ?? defaultSrcPath();
|
|
123
130
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { r as isRecord } from "./compact-CAf557ZB.js";
|
|
2
|
-
import { i as configError } from "./errors-
|
|
3
|
-
import { i as readJsonFile } from "./files-
|
|
4
|
-
import { a as loadModule, s as pickNamed } from "./load-
|
|
2
|
+
import { i as configError } from "./errors-Vpu6rKHl.js";
|
|
3
|
+
import { i as readJsonFile } from "./files-BSjrtIHw.js";
|
|
4
|
+
import { a as loadModule, s as pickNamed } from "./load-DjSU5KXO.js";
|
|
5
5
|
import { existsSync } from "node:fs";
|
|
6
6
|
import { resolve } from "node:path";
|
|
7
7
|
//#region src/cli/fixtures.ts
|
|
@@ -26,7 +26,10 @@ function asCustomRoles(value) {
|
|
|
26
26
|
if (!Array.isArray(value["customRoles"])) throw new TypeError("PermDock CLI: fixtures customRoles must be an array");
|
|
27
27
|
return value["customRoles"];
|
|
28
28
|
}
|
|
29
|
-
/**
|
|
29
|
+
/**
|
|
30
|
+
* A `.json` file or a module exporting `fixtures` (or default) and optionally
|
|
31
|
+
* `customRoles`.
|
|
32
|
+
*/
|
|
30
33
|
async function loadFixtures(cwd, path) {
|
|
31
34
|
const abs = resolve(cwd, path);
|
|
32
35
|
if (!existsSync(abs)) throw configError(`PermDock CLI: fixtures not found: ${path}`);
|
|
@@ -43,7 +46,10 @@ async function loadFixtures(cwd, path) {
|
|
|
43
46
|
customRoles: asCustomRoles(mod)
|
|
44
47
|
};
|
|
45
48
|
}
|
|
46
|
-
/**
|
|
49
|
+
/**
|
|
50
|
+
* The fixture subject as a `Subject`: a principal with no actor and an empty
|
|
51
|
+
* context.
|
|
52
|
+
*/
|
|
47
53
|
function fixtureSubject(fixture) {
|
|
48
54
|
return {
|
|
49
55
|
principal: {
|
|
@@ -56,7 +62,10 @@ function fixtureSubject(fixture) {
|
|
|
56
62
|
context: {}
|
|
57
63
|
};
|
|
58
64
|
}
|
|
59
|
-
/**
|
|
65
|
+
/**
|
|
66
|
+
* The row `can` receives: `{ current, next }` for an instance action with a
|
|
67
|
+
* `newRow`.
|
|
68
|
+
*/
|
|
60
69
|
function fixtureRow(fixture, kind) {
|
|
61
70
|
return fixture.newRow === void 0 || kind === "collection" ? fixture.row : {
|
|
62
71
|
current: fixture.row,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as CliError } from "./errors-
|
|
2
|
-
import { n as secretInput } from "./credentials-
|
|
1
|
+
import { n as CliError } from "./errors-Vpu6rKHl.js";
|
|
2
|
+
import { n as secretInput } from "./credentials-CdDxp7jN.js";
|
|
3
3
|
//#region src/cli/core/flags.ts
|
|
4
4
|
/** The flag vocabulary shared with better-supabase: one spelling per meaning. */
|
|
5
5
|
const dbUrlFlags = { "db-url-stdin": {
|
|
@@ -47,7 +47,10 @@ function isPlain(value) {
|
|
|
47
47
|
const proto = Object.getPrototypeOf(value);
|
|
48
48
|
return proto === Object.prototype || proto === null;
|
|
49
49
|
}
|
|
50
|
-
/**
|
|
50
|
+
/**
|
|
51
|
+
* A deeply frozen copy of the plain objects and arrays in `value`; the caller's
|
|
52
|
+
* own objects stay writable.
|
|
53
|
+
*/
|
|
51
54
|
function freezeCopy(value) {
|
|
52
55
|
if (value === null || typeof value !== "object") return value;
|
|
53
56
|
if (Array.isArray(value)) return Object.freeze(value.map((item) => freezeCopy(item)));
|