permdock 0.15.0 → 0.17.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/dist/a2a/index.d.ts +4 -4
- package/dist/a2a/index.js +3 -3
- package/dist/{adapter-context-CIQpQxbE.js → adapter-context-OHikyRqV.js} +1 -1
- package/dist/{adoption-scan-DLel53Oa.js → adoption-scan-Ci0xiJ3T.js} +1 -1
- package/dist/agent/index.d.ts +2 -2
- package/dist/agent/index.js +1 -1
- package/dist/ai-sdk/index.d.ts +3 -3
- package/dist/ai-sdk/index.js +3 -3
- package/dist/approval-normalize-4KxMRdJC.js +189 -0
- package/dist/approval-policies-9VagPixq.d.ts +138 -0
- package/dist/{approval-prompt-3BqWczTt.d.ts → approval-prompt-BSh-yxbH.d.ts} +1 -1
- package/dist/approvals/index.d.ts +5 -4
- package/dist/approvals/index.js +7 -6
- package/dist/{approvals-DnIBTuXE.js → approvals-DdFcTncq.js} +3 -3
- package/dist/{approvers-B4r0N_Uz.js → approvers-CNtl4Vc5.js} +22 -1
- package/dist/{arazzo-CL8CZnpL.js → arazzo-7kbeh1yi.js} +2 -2
- package/dist/{arazzo-CHK9NT6u.js → arazzo-_zUmT8ZT.js} +4 -4
- package/dist/{args-0FrVs5EH.js → args-iafbHiXn.js} +2 -5
- package/dist/astro/index.d.ts +4 -4
- package/dist/astro/index.js +2 -2
- package/dist/{audience-DTjR8xet.js → audience-jRO819i3.js} +1 -1
- package/dist/{auth--yPyZNgr.js → auth-j3Eu-j4h.js} +1 -1
- package/dist/authz-topic-Dbc-HDOS.js +15 -0
- package/dist/authzen/index.d.ts +5 -5
- package/dist/authzen/index.js +2 -2
- package/dist/{automation-C6Jg75xq.d.ts → automation-DCWuVKtd.d.ts} +1 -1
- package/dist/better-auth/index.d.ts +1 -1
- package/dist/better-auth/index.js +10 -8
- package/dist/better-supabase/index.d.ts +273 -38
- package/dist/better-supabase/index.js +493 -102
- package/dist/{better-supabase-Dirf_8Ec.js → better-supabase-BJtQ-kNf.js} +26 -10
- package/dist/{bind-BNQA9JK9.js → bind-BJFeLX1V.js} +6 -6
- package/dist/{bind-YYjvfpB9.d.ts → bind-DjFNX0Pq.d.ts} +7 -7
- package/dist/{budget-BELja5A9.js → budget-BBCPDOGP.js} +1 -1
- package/dist/{budget-hYsPz_yE.d.ts → budget-CNLsV2SL.d.ts} +1 -1
- package/dist/{build-instance-BWXqwQYU.js → build-instance-lye7oEqf.js} +3 -2
- package/dist/{capability-Di9tiUvi.d.ts → capability-BzjWdKmP.d.ts} +1 -1
- package/dist/{capability-BqX94r07.js → capability-zN6T9fxe.js} +2 -3
- package/dist/{casbin-iAEXjmca.js → casbin-C3O_O9nu.js} +2 -2
- package/dist/{casbin-DRFwgVIP.js → casbin-DFzk_so3.js} +2 -2
- package/dist/{casl-C4OINZHI.js → casl-CjBVJj8R.js} +2 -2
- package/dist/{casl-CHHoCldP.js → casl-CkBssiB1.js} +1 -1
- package/dist/catalog/index.d.ts +5 -5
- package/dist/catalog/index.js +6 -6
- package/dist/catalog-BpnjesqX.js +1 -0
- package/dist/{catalog-CGlSwU6j.js → catalog-DGDd_ww1.js} +5 -5
- package/dist/{catalog-amPDr0JQ.js → catalog-DJJIkR9P.js} +3 -3
- package/dist/{catalog-doc-DjMKzJp9.js → catalog-doc-C4DGfJCO.js} +3 -3
- package/dist/{catalog-operations-DeHTrJSV.js → catalog-operations-DVI5QO5R.js} +3 -3
- package/dist/{challenge-DImNcR7B.js → challenge-M_ghKJnT.js} +2 -2
- 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-CGkP3Z7A.js → checks-fyDOhcz0.js} +33 -1
- package/dist/claude-agent/index.d.ts +3 -3
- package/dist/claude-agent/index.js +2 -2
- package/dist/clerk/index.d.ts +2 -2
- package/dist/clerk/index.js +10 -7
- package/dist/cli/bin.js +1 -1
- package/dist/cli/index.d.ts +5 -5
- package/dist/cli/index.js +3 -3
- package/dist/cloud/index.d.ts +8 -8
- package/dist/cloud/index.js +1 -1
- package/dist/{cloud-eOtmuonF.js → cloud-DYqzmh5i.js} +4 -4
- package/dist/{codemod-KEDj_3zl.js → codemod-DNGMGqBS.js} +395 -8
- package/dist/{codemod-D6NYu4AK.js → codemod-DqB9klYI.js} +3 -3
- package/dist/{collect-DnXL4B8c.js → collect-C44RrKCI.js} +4 -4
- package/dist/collect-CAibhmCi.js +1 -0
- package/dist/{collect-WCl8cJQV.js → collect-HfJXl8Tr.js} +4 -4
- package/dist/compile/index.d.ts +1 -1
- package/dist/compile/index.js +1 -1
- package/dist/{compile-EzEMB-7v.js → compile-B_oJqmIg.js} +4 -4
- package/dist/{compile-BEklRUYo.d.ts → compile-BxiwRotu.d.ts} +2 -2
- package/dist/{completion-DCza8aQY.js → completion-pwVjJlek.js} +3 -3
- package/dist/{config-CcLlvEYW.js → config-COHmivz9.js} +4 -4
- package/dist/{config-BAM3a3z8.js → config-DnfH6_eT.js} +2 -2
- package/dist/{config-report-VZcQ0ZpS.js → config-report-C1jl7Na-.js} +2 -2
- package/dist/{context-BnIzxTNE.js → context-DeammvFl.js} +2 -2
- package/dist/convex/index.d.ts +4 -4
- package/dist/convex/index.js +3 -3
- package/dist/{core-CFepFiDP.d.ts → core-0iYZ5HUx.d.ts} +2 -2
- package/dist/{core-lxoANyai.js → core-W5f4Rjt0.js} +7 -7
- package/dist/{create-DBvUsgzK.d.ts → create-DNN3OtsO.d.ts} +4 -4
- package/dist/{create-CDd9c22W.d.ts → create-DrHUmKvG.d.ts} +6 -6
- package/dist/{create-BPUopdfL.d.ts → create-bzQlBzG4.d.ts} +7 -7
- package/dist/{create-Coq5fIrq.js → create-gqtDb1nU.js} +5 -5
- package/dist/{create-BLPKnJKa.js → create-jCPwPWXf.js} +6 -5
- package/dist/{credential-CyyyvCsL.js → credential-B3Hj4puZ.js} +4 -3
- package/dist/{credentials-CdDxp7jN.js → credentials-dkycUsY3.js} +1 -1
- package/dist/decision-CaG5_eNJ.js +21 -0
- package/dist/{delegation-CDB6_keF.js → delegation-aK4T_5WU.js} +3 -3
- package/dist/delivery/index.d.ts +4 -4
- package/dist/delivery/index.js +1 -1
- package/dist/{denied-text-DHldhVUv.d.ts → denied-text-DyzWwxEB.d.ts} +1 -1
- package/dist/{describe-Bb4hGK5d.js → describe-CogP1loh.js} +2 -1
- package/dist/{describe-BbFPBSms.d.ts → describe-nalX_HHE.d.ts} +1 -1
- package/dist/{diff-DfmYaIhB.js → diff-BTsLiW59.js} +7 -7
- package/dist/{diff-CxtbOi2l.js → diff-CcxYooMu.js} +2 -2
- package/dist/{doctor-gIO9WTYo.js → doctor-BNRhJegR.js} +3 -3
- package/dist/{doctor-CMqPKuN_.js → doctor-DS-9ApID.js} +195 -30
- package/dist/drizzle/index.d.ts +3 -3
- package/dist/drizzle/index.js +1 -1
- package/dist/elysia/index.d.ts +4 -4
- package/dist/elysia/index.js +3 -3
- package/dist/{errors-Vpu6rKHl.js → errors-BhRkoNS7.js} +0 -2
- package/dist/{errors-BIM4MFsJ.d.ts → errors-Dc9FdamT.d.ts} +1 -1
- package/dist/{evaluate-BAmf_AQd.js → evaluate-CsjXeLRo.js} +18 -15
- package/dist/{evaluations-DOWuBpWv.d.ts → evaluations-BasA9zXp.d.ts} +3 -3
- package/dist/{evaluations-IBceAeKT.js → evaluations-DG40eSJa.js} +3 -22
- package/dist/eve/index.d.ts +4 -4
- package/dist/eve/index.js +3 -3
- package/dist/express/index.d.ts +4 -4
- package/dist/express/index.js +3 -3
- package/dist/fastify/index.d.ts +4 -4
- package/dist/fastify/index.js +3 -3
- package/dist/{fetch-adapter-BIbBAtPZ.d.ts → fetch-adapter-BgqpOOpd.d.ts} +2 -2
- package/dist/{fetch-adapter-dPTgJVHd.js → fetch-adapter-UZOW0PRC.js} +2 -2
- package/dist/{fields-DI8s3cPl.js → fields-CrjL6A49.js} +3 -3
- package/dist/{files-B3AA05f1.js → files-CfiRtQ-m.js} +1 -1
- package/dist/{fixtures-Bm4_K1ke.js → fixtures-0VTW5oNq.js} +2 -2
- package/dist/{flags-DXjoTVbS.js → flags-BlmpmXoY.js} +2 -2
- package/dist/{from-snapshot-DCakWRsr.js → from-snapshot-DMlSSo9b.js} +14 -12
- package/dist/{gen-DwgCSC6V.js → gen-CNCzG4sB.js} +2 -2
- package/dist/{gen-DuAhghDw.js → gen-DnpZwQPo.js} +9 -9
- package/dist/{generate-CRVV5V7l.js → generate-BqkZq8Dr.js} +2 -2
- package/dist/{grantee-conditions-BrYPe-w0.js → grantee-conditions-DX4K_gGI.js} +1 -1
- package/dist/{grantee-match-7RZZvoT_.js → grantee-match-BP-k4vRJ.js} +2 -2
- package/dist/h3/index.d.ts +4 -4
- package/dist/h3/index.js +3 -3
- package/dist/{helpers-DJicaG6f.js → helpers-DNnZffrI.js} +76 -12
- package/dist/hono/index.d.ts +4 -4
- package/dist/hono/index.js +3 -3
- package/dist/{hosted-DVxlLZMe.d.ts → hosted-DxRLLiFU.d.ts} +1 -1
- package/dist/{hosted-D0IzESu_.js → hosted-tPZnyjQS.js} +12 -10
- package/dist/{http-DOL33cO0.js → http-DhMWeB_h.js} +1 -1
- package/dist/{import-DK_J8tVE.js → import-BYVbSKx0.js} +3 -3
- package/dist/{import-CNBF96hB.js → import-C1XXpG_m.js} +4 -4
- package/dist/{index-Cay5-Kvx.d.ts → index-Bt-UoBWu.d.ts} +11 -10
- package/dist/{index-DJwEgYzA.d.ts → index-CXXUFWtG.d.ts} +17 -11
- package/dist/{index-Dj2qF9VC.d.ts → index-CZ5mixHO.d.ts} +1 -1
- package/dist/{index-ymept53A.d.ts → index-DFwUOkvt.d.ts} +4 -4
- package/dist/{index-CV-7DWeD.d.ts → index-DtGtDzjb.d.ts} +4 -4
- package/dist/{index-BinlXeU-.d.ts → index-z44pfWar.d.ts} +2 -2
- package/dist/index.d.ts +18 -16
- package/dist/index.js +20 -18
- package/dist/{init-Buibrl9h.js → init-Dr1qAStu.js} +5 -5
- package/dist/{init-jLSyPMM7.js → init-YSDySeMy.js} +5 -5
- package/dist/{instance-options-CoHn-0e8.d.ts → instance-options-BOCRxEFb.d.ts} +2 -2
- package/dist/{instance-snapshot-DuWf1cT3.js → instance-snapshot-BgOGtyCy.js} +15 -12
- package/dist/jwt/index.d.ts +4 -4
- package/dist/jwt/index.js +3 -3
- package/dist/{kernel-BD8QuMnv.js → kernel-CDDU93dI.js} +10 -10
- package/dist/kysely/index.d.ts +3 -3
- package/dist/kysely/index.js +1 -1
- package/dist/{load-DjSU5KXO.js → load-BaEamml-.js} +1 -1
- package/dist/load-CjnlPxpL.js +1 -0
- package/dist/{login-CB55O4Gv.js → login-CXgEKLaW.js} +4 -4
- package/dist/{login-VVpkkund.js → login-DEVXDTX8.js} +4 -4
- package/dist/{manifest-CbEyvPN2.js → manifest-Dij1U0hx.js} +37 -37
- package/dist/{map-claims-C-nv08_n.js → map-claims-PQwHynxV.js} +25 -11
- package/dist/{map-error-pasIGqMT.js → map-error-B_f3C5cs.js} +1 -1
- package/dist/mcp/index.d.ts +8 -8
- package/dist/mcp/index.js +9 -9
- package/dist/{migrate-BJHxQqT5.js → migrate-BbY5-Khy.js} +4 -4
- package/dist/{module-values-B1EVTkHP.js → module-values-B8tNIxdd.js} +2 -2
- package/dist/nest/index.d.ts +4 -4
- package/dist/nest/index.js +3 -3
- package/dist/next/index.d.ts +32 -13
- package/dist/next/index.js +43 -25
- package/dist/next/plugin.d.ts +1 -1
- package/dist/next/plugin.js +2 -2
- package/dist/node/index.d.ts +4 -4
- package/dist/node/index.js +2 -2
- package/dist/openai/index.d.ts +4 -4
- package/dist/openai/index.js +3 -3
- package/dist/openapi/index.d.ts +2 -2
- package/dist/{openapi-eHZ5hwUJ.js → openapi-D3wkvOoU.js} +4 -4
- package/dist/{openapi-CleDZYVf.js → openapi-GM-kTdkq.js} +5 -5
- package/dist/orpc/index.d.ts +5 -5
- package/dist/orpc/index.js +3 -3
- package/dist/otel/index.d.ts +3 -3
- package/dist/otel/index.js +1 -1
- package/dist/{output-BVZpQDad.js → output-DhTpe8v1.js} +1 -1
- package/dist/output-files-BYscrQl-.js +1 -0
- package/dist/{output-files-BIQ_9pIs.js → output-files-CM0BnH05.js} +1 -1
- package/dist/{ownership-qqBuGJXr.js → ownership-moSRhxl_.js} +6 -6
- package/dist/{parse-1_ZheTW5.js → parse-UTC-sDrt.js} +2 -2
- package/dist/{parse-local-manifest-CCmbhnxP.d.ts → parse-local-manifest-BgTYdR3q.d.ts} +1 -1
- package/dist/{parse-request-CwCZpyjV.js → parse-request-DOBVaeiQ.js} +1 -1
- package/dist/pdp/index.d.ts +3 -3
- package/dist/pdp/index.js +3 -3
- package/dist/{peer-Q0fuZ6hx.js → peer-BuK9F53f.js} +1 -1
- package/dist/{peer-C9LvBCcb.js → peer-n-swIV4H.js} +1 -1
- package/dist/{permdock-CprAPN3w.d.ts → permdock-DUWZEOLR.d.ts} +88 -131
- package/dist/{permdock-BvjivVb9.js → permdock-DdzMv5-F.js} +195 -102
- package/dist/{permissions-CYcHj_w7.js → permissions-CvpPtz5O.js} +1 -1
- package/dist/{pg-DQTqRrou.js → pg-Ddxsd5ZB.js} +2 -2
- package/dist/{policy-BycVKnXv.d.ts → policy-CTNl7pvN.d.ts} +1 -1
- package/dist/{policy-CLQ8__GF.js → policy-DxQyHKPB.js} +5 -4
- package/dist/{policy-from-catalog-CU3An8uP.js → policy-from-catalog-DVa1faOr.js} +8 -7
- package/dist/{policy-types-DGIO_gxq.d.ts → policy-types-IRJVABmm.d.ts} +63 -19
- package/dist/{postgrest-D5nUGm-c.d.ts → postgrest-B_cEDd4e.d.ts} +12 -7
- package/dist/{postgrest-DAxFltvO.js → postgrest-BrjrckDG.js} +74 -19
- package/dist/{powersync-CFWILHjb.js → powersync-BZxw_v-A.js} +3 -3
- package/dist/{powersync-uqYWxTjq.js → powersync-C0nsyULQ.js} +15 -15
- package/dist/powersync-Cqzx25dI.js +1 -0
- package/dist/preset/index.js +1 -1
- package/dist/{preset-BjLzeFpp.js → preset-pPrVyGU5.js} +74 -7
- package/dist/prisma/index.d.ts +2 -2
- package/dist/prisma/index.js +1 -1
- package/dist/{protected-action-DUYqb-Ma.js → protected-action-B6n6w7Rl.js} +1 -1
- package/dist/{protected-action-D8x73IGm.d.ts → protected-action-D3S9U4nc.d.ts} +14 -7
- package/dist/{protected-action-QEA8arRB.js → protected-action-qowj6nxN.js} +15 -5
- package/dist/{provider-C55OGXJ7.js → provider-CY4TSSJo.js} +2 -2
- package/dist/{provider-DfLeek9O.d.ts → provider-CjAu39fJ.d.ts} +1 -1
- package/dist/{provider-store-CaTv00tr.js → provider-store-BQP_pp8s.js} +2 -2
- package/dist/pull-CUVdB04v.js +1 -0
- package/dist/{pull-BBmCxnqX.js → pull-DVoZ0V9_.js} +6 -6
- package/dist/{push-Dq_ca4-j.js → push-eJl1Tvqm.js} +7 -7
- package/dist/{pushed-policy-CryQheKq.d.ts → pushed-policy-CUQuvlS3.d.ts} +1 -1
- package/dist/{pushed-policy-CDuOL2de.js → pushed-policy-DMXAOmEW.js} +1 -1
- package/dist/react/index.d.ts +8 -8
- package/dist/react/index.js +6 -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 +10 -10
- package/dist/react-native/index.js +9 -9
- package/dist/refresh-on-L9UOwATg.d.ts +49 -0
- package/dist/{replay-Bs9Df2fQ.d.ts → replay-Dc3d8LhG.d.ts} +1 -1
- package/dist/{request-context-Duzdf0cd.js → request-context-Ch052blg.js} +2 -2
- package/dist/{request-schema-DhX7UbfQ.js → request-schema-CMP8Cmxd.js} +5 -0
- package/dist/resend/index.d.ts +4 -4
- package/dist/{resolve-names-Y1Cb22cp.js → resolve-names-1nCei24V.js} +6 -6
- package/dist/{rls-yK2nZUcm.js → rls-BVzoZCn3.js} +4 -4
- package/dist/{rls-BwKXdVEW.js → rls-ClJRblnR.js} +19 -19
- package/dist/{role-builder-BK2-T6oD.js → role-builder-BrmOcXch.js} +3 -157
- package/dist/{rpc-vHIwyXCp.js → rpc-BOu3FD6X.js} +2 -2
- package/dist/{run-D5WIJfs7.js → run-CnCaTjWX.js} +8 -40
- package/dist/run-D9N6V5WQ.js +1 -0
- package/dist/{run-ticket-ylovhyFQ.d.ts → run-ticket-C6lXvHM_.d.ts} +2 -2
- package/dist/{run-ticket-DfnZCh-u.js → run-ticket-CjvXr6wj.js} +1 -1
- package/dist/{runtime-BGnrOkVH.js → runtime-CBXkOcg9.js} +1 -1
- package/dist/{saas-DK4V-3Is.js → saas-BqM9mJkk.js} +13 -10
- package/dist/{scan-CzdMtHnq.js → scan-CepUXrFt.js} +1 -1
- package/dist/{schema-BDGEVO4g.js → schema-9_NDz8fx.js} +1 -1
- package/dist/{schema-BOJjqlWL.js → schema-CuX70xgH.js} +15 -2
- package/dist/scim/index.d.ts +1 -1
- package/dist/scim/index.js +1 -1
- package/dist/{scim-jJBJ7g1Z.js → scim-C30QBBoF.js} +2 -1
- package/dist/{scim-D8YupzX1.js → scim-CovliQUg.js} +2 -2
- package/dist/{scopes-0Up_UA2t.js → scopes-BSdYaGHs.js} +9 -40
- package/dist/server/index.d.ts +11 -11
- package/dist/server/index.js +8 -8
- package/dist/{server-3cVlTLde.js → server-D0PW6ZCw.js} +2 -2
- package/dist/{server-types-CyRN0-Cd.d.ts → server-types-Bw-lWqzR.d.ts} +8 -8
- package/dist/{shared-l0oGGetg.js → shared-BRmCJxDK.js} +2 -2
- package/dist/{shared-DrGLwM3s.js → shared-DyYVEjKC.js} +2 -2
- package/dist/{sink-B5zoUW_O.d.ts → sink-DUzt0e4B.d.ts} +2 -2
- package/dist/{skills-BZxPQ_09.js → skills-BUuH-QFt.js} +2 -2
- package/dist/{skills-BIsm1n26.js → skills-a4N6Y2Xm.js} +2 -2
- package/dist/{snapshot-CXlzi69u.js → snapshot-DN_8J27z.js} +6 -2
- package/dist/{snapshot-cache-Bx_4xC_6.js → snapshot-cache-B66h7FBK.js} +25 -8
- package/dist/{snapshot-cache-BjAWkchD.d.ts → snapshot-cache-Dbk-Gnij.d.ts} +20 -6
- package/dist/solid/index.d.ts +7 -7
- package/dist/solid/index.js +6 -6
- package/dist/solid-start/index.d.ts +4 -4
- package/dist/solid-start/index.js +3 -3
- package/dist/{sources-oB1Hg1Fm.d.ts → sources-CXY05xtB.d.ts} +1 -1
- package/dist/{src-C_pi2Rnh.js → src-nYNBfmgq.js} +187 -39
- package/dist/ssf/index.d.ts +3 -3
- package/dist/ssf/index.js +1 -1
- package/dist/{standard-webhooks-DOYEuOLx.d.ts → standard-webhooks-BFeEpjxy.d.ts} +2 -2
- package/dist/{store-RNFvaJJv.js → store-XgBMbfDy.js} +13 -7
- package/dist/{types-tQB2CEnY.d.ts → store-g5ctUrOI.d.ts} +114 -113
- package/dist/{store-options-Dil3lraY.js → store-options--zWn48PK.js} +76 -7
- package/dist/{stores-DxZWDXCs.js → stores-53_kOwPi.js} +3 -3
- package/dist/{stores-DZJvxFIZ.d.ts → stores-BtdN3eDO.d.ts} +5 -6
- package/dist/{stream-9y9qw51m.d.ts → stream-BMJg56jU.d.ts} +1 -1
- package/dist/{subject-BGoM5o8B.js → subject-C7RddW0G.js} +8 -1
- package/dist/supabase/client.d.ts +31 -0
- package/dist/supabase/client.js +21 -0
- package/dist/supabase/index.d.ts +37 -6
- package/dist/supabase/index.js +5 -4
- package/dist/supabase/middleware.d.ts +8 -7
- package/dist/supabase/middleware.js +6 -6
- package/dist/{supabase-DYWnT800.js → supabase-C6FyUeSh.js} +3 -3
- package/dist/{supabase-CDHMsDD0.js → supabase-C8cNzp4i.js} +31 -8
- package/dist/supabase-hook-CPBX4dy5.js +1 -0
- package/dist/{supabase-hook-HPgwYb9V.js → supabase-hook-Cj85nccs.js} +167 -21
- package/dist/{supautils-CGk4YpvC.js → supautils-BP_5WAIc.js} +20 -18
- package/dist/svelte/index.d.ts +7 -7
- package/dist/svelte/index.js +8 -8
- package/dist/svelte/runtime.d.ts +3 -3
- package/dist/svelte/runtime.js +3 -3
- package/dist/svelte/source.d.ts +7 -7
- package/dist/svelte/source.js +5 -5
- package/dist/sveltekit/index.d.ts +4 -4
- package/dist/sveltekit/index.js +2 -2
- package/dist/{tables-DimBcVWY.js → tables-BsGE6HBR.js} +7 -7
- package/dist/tanstack-start/index.d.ts +4 -4
- package/dist/tanstack-start/index.js +2 -2
- package/dist/{tenancy-5d1zVBvK.js → tenancy-DvOHHk3-.js} +1 -1
- package/dist/terminal/index.d.ts +5 -5
- package/dist/terminal/index.js +6 -6
- package/dist/testing/core.d.ts +1 -1
- package/dist/testing/core.js +1 -1
- package/dist/testing/fixtures/index.d.ts +1 -1
- package/dist/testing/fixtures/index.js +1 -1
- package/dist/testing/index.d.ts +29 -22
- package/dist/testing/index.js +118 -46
- package/dist/testing/saas/index.d.ts +3 -3
- package/dist/testing/saas/index.js +2 -2
- package/dist/testing/saas/permissions.js +1 -1
- package/dist/token-D6pWn8Uj.d.ts +11 -0
- package/dist/{token-DC9EQiet.js → token-DaMnIU9O.js} +24 -8
- package/dist/{tool-refusal-Qpjs_W6M.js → tool-refusal-C1UlhU0V.js} +1 -1
- package/dist/trpc/index.d.ts +5 -5
- package/dist/trpc/index.js +3 -3
- package/dist/{type-helpers-c7Xo_2Cu.d.ts → type-helpers-C_OnZW8c.d.ts} +1 -1
- package/dist/{types-B2efzoSX.d.ts → types-AOP5HQku.d.ts} +1 -1
- package/dist/{types-DlelvQk4.d.ts → types-B3BOcI0J.d.ts} +2 -2
- package/dist/{types-DLvhVm1r.d.ts → types-BvBbkAu1.d.ts} +16 -7
- package/dist/{types-BB-zWDcR.d.ts → types-CA-A33Q5.d.ts} +5 -5
- package/dist/{types-Cklw5hJo.d.ts → types-CAAN7evk.d.ts} +24 -1
- package/dist/{types-DsHGPtkR.d.ts → types-CJC1aaoJ.d.ts} +2 -2
- package/dist/{types-CWBsAwqn.d.ts → types-D29K5ZNP.d.ts} +4 -4
- package/dist/{types-CEinc15V.d.ts → types-DVZNTkU0.d.ts} +3 -4
- package/dist/{types-ZzRGoViD.d.ts → types-NYoj8JBm.d.ts} +2 -2
- package/dist/{types-B6ExllNo.d.ts → types-Sj1U8HMm.d.ts} +2 -2
- package/dist/{types-CN0LsqbK.d.ts → types-UfpcY575.d.ts} +3 -3
- package/dist/{types-rCRV4Ge-.d.ts → types-e82uzrTn.d.ts} +4 -4
- package/dist/unplugin/index.d.ts +1 -1
- package/dist/unplugin/index.js +2 -2
- package/dist/{usage-e6M1Mls1.js → usage-COsGLht5.js} +6 -6
- package/dist/{usage-DBNrpwoT.js → usage-CqcMeQgX.js} +2 -2
- package/dist/usage-D1cpHO7p.js +1 -0
- package/dist/{validation-error-uvp-kyfO.d.ts → validation-error-DpvsBwZJ.d.ts} +1 -1
- package/dist/{verify-CgIpJRcG.js → verify-C8G8D5mk.js} +19 -19
- package/dist/{version-cache-Df11C2Qp.d.ts → version-cache-9Vq5QVFC.d.ts} +9 -3
- package/dist/{views-CD8wuL4Z.js → views-TrZYlDnM.js} +1 -1
- package/dist/vue/index.d.ts +7 -7
- package/dist/vue/index.js +6 -6
- package/dist/{waiter-CqUKX6CY.d.ts → waiter-C2cXXLFZ.d.ts} +2 -2
- package/dist/{watch-DAkjm75Y.js → watch-DXRDBSCu.js} +3 -3
- package/dist/watch-DnymTAfe.js +1 -0
- package/dist/webmcp/index.d.ts +1 -1
- package/dist/webmcp/index.js +1 -1
- package/dist/{where-scope-DlCdCM_8.js → where-scope-BKrqUDVk.js} +5 -5
- package/dist/{who-can-BoDJm0Nc.js → who-can-BY5d3HPw.js} +4 -4
- package/dist/workflow/index.d.ts +3 -3
- package/dist/workflow/index.js +5 -4
- package/dist/workflow-sdk/index.d.ts +4 -4
- package/dist/{wrap-B2wziJI_.js → wrap-C5PWzgkq.js} +1 -1
- package/dist/{wrap-DxXB54Wu.d.ts → wrap-DpZAbxuD.d.ts} +2 -2
- package/package.json +8 -5
- package/schemas/approval-request-v1.json +5 -0
- package/schemas/catalog-v1.json +18 -2
- package/schemas/cli-result-v1.json +0 -2
- package/schemas/snapshot-v1.json +9 -0
- package/skills/permdock-approvals/SKILL.md +8 -8
- package/skills/permdock-approvals/references/stores-and-resume.md +7 -3
- package/skills/permdock-audit/SKILL.md +1 -1
- package/skills/permdock-data/references/queries-and-rls.md +1 -1
- package/dist/action-result-BcudBQOF.d.ts +0 -19
- package/dist/catalog-D3oS2GH3.js +0 -1
- package/dist/collect-D-eroIfV.js +0 -1
- package/dist/load-Dm0pSYH3.js +0 -1
- package/dist/output-files-BHOIlrfD.js +0 -1
- package/dist/powersync-CnGzxvEl.js +0 -1
- package/dist/pull-D6dloyrc.js +0 -1
- package/dist/renames-CGj7YwcQ.js +0 -175
- package/dist/run-DlQYPtPv.js +0 -1
- package/dist/supabase-hook-qsewAVZY.js +0 -1
- package/dist/usage-D3KJyaNS.js +0 -1
- package/dist/watch-CuPz0D2M.js +0 -1
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { r as isRecord, t as compact } from "../compact-CAf557ZB.js";
|
|
2
2
|
import { n as freezeDeep } from "../freeze-jjan0lCv.js";
|
|
3
|
-
import {
|
|
4
|
-
import { a as holder, i as flattenApprovers, r as approverLeaves } from "../approvers-B4r0N_Uz.js";
|
|
3
|
+
import { a as flattenApprovers, o as holder, r as approverLeaves } from "../approvers-CNtl4Vc5.js";
|
|
5
4
|
import { t as loadPrincipal } from "../principal-source-C6N60GtM.js";
|
|
6
5
|
import { a as isId, r as idList } from "../expiry-6XByK0dm.js";
|
|
7
6
|
import { c as listPermissions, n as findPermission, o as isPermission } from "../permission-registry-B8tYxPIt.js";
|
|
@@ -9,21 +8,30 @@ import { i as dateAt, m as rfc3339, p as nowSeconds, u as isoAt } from "../time-
|
|
|
9
8
|
import { t as canonicalJson } from "../canonical-json-DwilZ1iB.js";
|
|
10
9
|
import { r as sha256Digest } from "../sha256-C-4WXKIu.js";
|
|
11
10
|
import { t as decideSupportSession } from "../support-session-BsmPCbz8.js";
|
|
12
|
-
import {
|
|
11
|
+
import { d as scopeList } from "../scopes-BSdYaGHs.js";
|
|
13
12
|
import { o as flattenGrantee } from "../grantee-Dke-9rd1.js";
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
13
|
+
import { n as asApprover } from "../approval-normalize-4KxMRdJC.js";
|
|
14
|
+
import { r as isSubject, t as anonymousSubject } from "../subject-C7RddW0G.js";
|
|
15
|
+
import { I as decisionTenant } from "../evaluate-CsjXeLRo.js";
|
|
16
|
+
import { _ as claimsFirst } from "../instance-snapshot-BgOGtyCy.js";
|
|
17
|
+
import { a as permissionStates } from "../checks-fyDOhcz0.js";
|
|
18
|
+
import { a as delegatedScopeMap, s as scopesReaching } from "../permdock-DdzMv5-F.js";
|
|
19
|
+
import { i as linkPolicyViolation, n as capabilityOf, r as capabilitySubject } from "../capability-zN6T9fxe.js";
|
|
20
|
+
import { r as credentialSubject, s as parseCredential } from "../credential-B3Hj4puZ.js";
|
|
21
|
+
import { s as resumeDecision } from "../helpers-DNnZffrI.js";
|
|
19
22
|
import { t as AccessReviewError } from "../errors-BDUwg2qC.js";
|
|
23
|
+
import { t as parseApprovalRequest } from "../parse-request-DOBVaeiQ.js";
|
|
24
|
+
import { n as parseApprovalHeader } from "../approval-header-8QV6MU4H.js";
|
|
25
|
+
import { i as snapshotTag } from "../snapshot-cache-B66h7FBK.js";
|
|
26
|
+
import { t as buildInstance } from "../build-instance-lye7oEqf.js";
|
|
27
|
+
import { n as NO_GRANT } from "../decision-CaG5_eNJ.js";
|
|
20
28
|
import { t as policyRowConditionKeys } from "../row-conditions-BAGHOmVq.js";
|
|
21
|
-
import { n as subscribersFor } from "../audience-
|
|
29
|
+
import { n as subscribersFor } from "../audience-jRO819i3.js";
|
|
22
30
|
import { i as qualifySqlTable, l as sqlIdent, s as quoteSqlLiteral } from "../sql-0WjxIp9g.js";
|
|
23
31
|
import { o as junctionMembershipSource } from "../sources-C4vkzZJV.js";
|
|
24
|
-
import { c as subjectFromSupabaseSession, t as callRpc } from "../postgrest-
|
|
32
|
+
import { c as subjectFromSupabaseSession, t as callRpc } from "../postgrest-BrjrckDG.js";
|
|
25
33
|
import { n as parseSupabaseManifest, t as hasTokenHook } from "../manifest-BXTbHNIV.js";
|
|
26
|
-
import { t as parseCatalog } from "../parse-
|
|
34
|
+
import { t as parseCatalog } from "../parse-UTC-sDrt.js";
|
|
27
35
|
import { n as activeTenantMismatch, t as activeOrganizationFrom } from "../active-tenant-DVee32-T.js";
|
|
28
36
|
import { AsyncResult, dbError } from "better-supabase";
|
|
29
37
|
//#region src/better-supabase/access-reviews.ts
|
|
@@ -155,6 +163,218 @@ function accessReviewApplier(options) {
|
|
|
155
163
|
};
|
|
156
164
|
}
|
|
157
165
|
//#endregion
|
|
166
|
+
//#region src/better-supabase/approvals-block.ts
|
|
167
|
+
const PAGE = 100;
|
|
168
|
+
const MAX_SCANNED = 2e3;
|
|
169
|
+
function statusOf(status) {
|
|
170
|
+
switch (status) {
|
|
171
|
+
case "pending":
|
|
172
|
+
case "approved":
|
|
173
|
+
case "rejected":
|
|
174
|
+
case "expired": return status;
|
|
175
|
+
case "cancelled": return "rejected";
|
|
176
|
+
default: return status;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
function instantOf(value) {
|
|
180
|
+
if (value === void 0) return;
|
|
181
|
+
const ms = Date.parse(value.toJSON());
|
|
182
|
+
return Number.isNaN(ms) ? void 0 : isoAt(ms);
|
|
183
|
+
}
|
|
184
|
+
/** The PermDock request a block record carries, with the block's state. */
|
|
185
|
+
function requestOf(record) {
|
|
186
|
+
const stored = parseApprovalRequest(record.payload["permdock"]);
|
|
187
|
+
if (stored === null) return null;
|
|
188
|
+
const status = statusOf(record.status);
|
|
189
|
+
return freezeDeep(compact({
|
|
190
|
+
...stored,
|
|
191
|
+
status,
|
|
192
|
+
expiresAt: instantOf(record.expiresAt) ?? stored.expiresAt,
|
|
193
|
+
resolvedAt: status === "pending" ? void 0 : instantOf(record.decidedAt),
|
|
194
|
+
consumedAt: instantOf(record.consumedAt),
|
|
195
|
+
fingerprint: record.fingerprint ?? stored.fingerprint
|
|
196
|
+
}));
|
|
197
|
+
}
|
|
198
|
+
async function unwrap(result, call) {
|
|
199
|
+
const awaited = await result;
|
|
200
|
+
if (!awaited.ok) throw new Error(`PermDock: the approvals block's ${call} failed`, { cause: awaited.error });
|
|
201
|
+
return awaited.data;
|
|
202
|
+
}
|
|
203
|
+
/** Every block record carrying a PermDock request, newest first, capped. */
|
|
204
|
+
async function scan(approvals, found) {
|
|
205
|
+
const out = [];
|
|
206
|
+
let before;
|
|
207
|
+
for (let scanned = 0; scanned < MAX_SCANNED; scanned += PAGE) {
|
|
208
|
+
const page = await unwrap(approvals.list({
|
|
209
|
+
status: null,
|
|
210
|
+
pageSize: PAGE,
|
|
211
|
+
...before === void 0 ? {} : { before }
|
|
212
|
+
}), "list");
|
|
213
|
+
for (const record of page) {
|
|
214
|
+
const request = requestOf(record);
|
|
215
|
+
if (request !== null) {
|
|
216
|
+
const pair = {
|
|
217
|
+
record,
|
|
218
|
+
request
|
|
219
|
+
};
|
|
220
|
+
out.push(pair);
|
|
221
|
+
if (found(pair)) return out;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
const last = page.at(-1);
|
|
225
|
+
if (page.length < PAGE || last === void 0) break;
|
|
226
|
+
before = last.createdAt;
|
|
227
|
+
}
|
|
228
|
+
return out;
|
|
229
|
+
}
|
|
230
|
+
function actionOf(permission) {
|
|
231
|
+
const dot = permission.lastIndexOf(".");
|
|
232
|
+
return dot === -1 ? permission : permission.slice(dot + 1);
|
|
233
|
+
}
|
|
234
|
+
function matchesQuery(request, query) {
|
|
235
|
+
return (query.status === void 0 || request.status === query.status) && (query.principalId === void 0 || request.subject.principal?.id === query.principalId) && (query.actorId === void 0 || request.subject.actor?.id === query.actorId) && (query.tenant === void 0 || decisionTenant(request.subject, request.membership) === query.tenant) && (query.session === void 0 || request.subject.session === query.session);
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* An `ApprovalStore` over better-supabase's approvals block, so a PermDock
|
|
239
|
+
* `approval-required` decision files a block request and is decided in the
|
|
240
|
+
* block's own approve and reject flow. `create` files the request on the
|
|
241
|
+
* resource under the permission's action, with the PermDock request in
|
|
242
|
+
* `payload.permdock` and its `fingerprint`. `get`, `getById` and `list` read
|
|
243
|
+
* the block's latest 2,000 requests in the block's tenant. `consume` calls the
|
|
244
|
+
* block's `consume`, which refuses a second use and another fingerprint.
|
|
245
|
+
* `resolve` throws: approvers decide through the block, never through
|
|
246
|
+
* `approvalsHandler`. `expire` answers 0, since the block expires requests
|
|
247
|
+
* itself.
|
|
248
|
+
*/
|
|
249
|
+
function blockApprovalStore(approvals) {
|
|
250
|
+
const byToken = async (token) => (await scan(approvals, ({ request }) => request.token === token)).find(({ request }) => request.token === token);
|
|
251
|
+
return Object.freeze({
|
|
252
|
+
name: "better-supabase-approvals",
|
|
253
|
+
async create(request) {
|
|
254
|
+
await unwrap(approvals.request({
|
|
255
|
+
type: request.resource.type,
|
|
256
|
+
id: request.resource.id ?? request.id
|
|
257
|
+
}, compact({
|
|
258
|
+
action: actionOf(request.permission),
|
|
259
|
+
reason: request.detail,
|
|
260
|
+
payload: { permdock: request },
|
|
261
|
+
fingerprint: request.fingerprint
|
|
262
|
+
})), "request");
|
|
263
|
+
},
|
|
264
|
+
async get(token) {
|
|
265
|
+
return (await byToken(token))?.request ?? null;
|
|
266
|
+
},
|
|
267
|
+
async getById(id) {
|
|
268
|
+
return (await scan(approvals, ({ request }) => request.id === id)).find(({ request }) => request.id === id)?.request ?? null;
|
|
269
|
+
},
|
|
270
|
+
resolve() {
|
|
271
|
+
throw new Error("PermDock: blockApprovalStore requests are decided through the approvals block's approve and reject, not resolve");
|
|
272
|
+
},
|
|
273
|
+
async list(query) {
|
|
274
|
+
const limit = Math.min(Math.max(query.limit ?? 50, 1), 200);
|
|
275
|
+
const offset = query.cursor === void 0 ? 0 : Number(query.cursor);
|
|
276
|
+
if (!Number.isSafeInteger(offset) || offset < 0) return { items: [] };
|
|
277
|
+
const all = (await scan(approvals, () => false)).map(({ request }) => request).filter((request) => matchesQuery(request, query)).toReversed().toSorted((a, b) => Date.parse(a.createdAt) - Date.parse(b.createdAt));
|
|
278
|
+
const items = all.slice(offset, offset + limit);
|
|
279
|
+
return offset + limit < all.length ? {
|
|
280
|
+
items,
|
|
281
|
+
next: String(offset + limit)
|
|
282
|
+
} : { items };
|
|
283
|
+
},
|
|
284
|
+
expire() {
|
|
285
|
+
return 0;
|
|
286
|
+
},
|
|
287
|
+
async consume(token) {
|
|
288
|
+
const found = await byToken(token);
|
|
289
|
+
if (found === void 0) return null;
|
|
290
|
+
const consumed = await approvals.consume(found.record.id, found.request.fingerprint);
|
|
291
|
+
return consumed.ok ? requestOf(consumed.data) : null;
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
const INTERVAL_UNITS = {
|
|
296
|
+
second: 1,
|
|
297
|
+
minute: 60,
|
|
298
|
+
hour: 3600,
|
|
299
|
+
day: 86400,
|
|
300
|
+
week: 604800
|
|
301
|
+
};
|
|
302
|
+
/** Seconds in a Postgres interval such as `3 days` or `1 day 2 hours`. */
|
|
303
|
+
function intervalSeconds(interval) {
|
|
304
|
+
const parts = interval.trim().toLowerCase().split(/\s+/u);
|
|
305
|
+
let seconds = 0;
|
|
306
|
+
for (let index = 0; index < parts.length; index += 2) {
|
|
307
|
+
const amount = Number(parts[index]);
|
|
308
|
+
const unit = parts[index + 1]?.replace(/s$/u, "");
|
|
309
|
+
const size = unit === void 0 ? void 0 : INTERVAL_UNITS[unit];
|
|
310
|
+
if (!Number.isSafeInteger(amount) || amount < 0 || size === void 0) throw new TypeError(`PermDock: the approval policy interval '${interval}' is not whole seconds, minutes, hours, days or weeks`);
|
|
311
|
+
seconds += amount * size;
|
|
312
|
+
}
|
|
313
|
+
if (seconds === 0) throw new TypeError(`PermDock: the approval policy interval '${interval}' is empty`);
|
|
314
|
+
return seconds;
|
|
315
|
+
}
|
|
316
|
+
function stageApprovers(approvers, roleScope) {
|
|
317
|
+
const leaves = [
|
|
318
|
+
...approvers.permission === void 0 ? [] : [{
|
|
319
|
+
kind: "permission",
|
|
320
|
+
permission: approvers.permission
|
|
321
|
+
}],
|
|
322
|
+
...approvers.role === void 0 ? [] : [{
|
|
323
|
+
kind: "role",
|
|
324
|
+
role: approvers.role,
|
|
325
|
+
scope: roleScope
|
|
326
|
+
}],
|
|
327
|
+
...(approvers.users ?? []).map((id) => ({
|
|
328
|
+
kind: "user",
|
|
329
|
+
id
|
|
330
|
+
})),
|
|
331
|
+
...approvers.manager === true ? [{ kind: "manager" }] : []
|
|
332
|
+
];
|
|
333
|
+
if (leaves.length === 0) throw new TypeError("PermDock: an approval policy step names no approver PermDock can check (team approvers are not supported)");
|
|
334
|
+
return {
|
|
335
|
+
kind: "any-of",
|
|
336
|
+
of: leaves
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
function policyOf(entry, roleScope) {
|
|
340
|
+
const approval = compact({
|
|
341
|
+
stages: entry.steps.length === 0 ? void 0 : entry.steps.map((step) => ({
|
|
342
|
+
by: stageApprovers(step.approvers, roleScope),
|
|
343
|
+
quorum: step.required
|
|
344
|
+
})),
|
|
345
|
+
combine: entry.steps.length > 1 ? "sequential" : void 0,
|
|
346
|
+
mode: entry.mode === "confirm" && entry.selfApproval ? "confirm" : void 0,
|
|
347
|
+
ttl: entry.expiresIn === void 0 ? void 0 : intervalSeconds(entry.expiresIn)
|
|
348
|
+
});
|
|
349
|
+
return {
|
|
350
|
+
permission: `${entry.subjectType}.${entry.action}`,
|
|
351
|
+
tenant: entry.organizationId,
|
|
352
|
+
approval
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* An `ApprovalPolicySource` over the approvals block's tenant policies, so a
|
|
357
|
+
* PermDock decision asks for approval wherever the block would. A policy keys
|
|
358
|
+
* the permission `<subjectType>.<action>`; its steps become sequential stages
|
|
359
|
+
* whose approvers are any of the step's permission, role, users and manager;
|
|
360
|
+
* `confirm` with `selfApproval` lets the principal approve; `expiresIn` caps
|
|
361
|
+
* the request's `ttl`. `conditions` are not read, so a conditional policy
|
|
362
|
+
* applies to every call: stricter, never looser. A step with only a `team`
|
|
363
|
+
* approver, an interval it cannot read or a failed read makes the source fail,
|
|
364
|
+
* and every call an allow would grant denies.
|
|
365
|
+
*/
|
|
366
|
+
function blockApprovalPolicySource(approvals, options = {}) {
|
|
367
|
+
const roleScope = options.roleScope ?? "tenant";
|
|
368
|
+
return Object.freeze({
|
|
369
|
+
name: "better-supabase-approvals",
|
|
370
|
+
async approvalPoliciesFor(query) {
|
|
371
|
+
const entries = await unwrap(approvals.listPolicies({ pageSize: 200 }), "listPolicies");
|
|
372
|
+
if (!Array.isArray(entries)) throw new TypeError("PermDock: listPolicies answered no list");
|
|
373
|
+
return entries.filter((entry) => isRecord(entry) && entry["enabled"] === true && typeof entry["organizationId"] === "string" && query.tenants.includes(entry["organizationId"])).map((entry) => policyOf(entry, roleScope));
|
|
374
|
+
}
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
//#endregion
|
|
158
378
|
//#region src/better-supabase/api-keys.ts
|
|
159
379
|
const EPOCH = "1970-01-01T00:00:00.000Z";
|
|
160
380
|
const rfc3339Of = (instant) => isoAt(instant.epochMilliseconds);
|
|
@@ -341,6 +561,98 @@ function subjectFromBetterSupabase(session, options = {}) {
|
|
|
341
561
|
});
|
|
342
562
|
}
|
|
343
563
|
//#endregion
|
|
564
|
+
//#region src/better-supabase/permdock-for.ts
|
|
565
|
+
function isResult(source) {
|
|
566
|
+
return isRecord(source) && Object.hasOwn(source, "session") && Object.hasOwn(source, "authzVersion") && !Object.hasOwn(source, "kind");
|
|
567
|
+
}
|
|
568
|
+
function knownVersion(value) {
|
|
569
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0 ? value : void 0;
|
|
570
|
+
}
|
|
571
|
+
function subjectOf(source, result, signedOut, options) {
|
|
572
|
+
if (isSubject(source)) return source;
|
|
573
|
+
if (result !== void 0) return subjectFromBetterSupabase(signedOut ? null : result.session, options);
|
|
574
|
+
return subjectFromBetterSupabase(source, options);
|
|
575
|
+
}
|
|
576
|
+
/**
|
|
577
|
+
* The resolver behind `permdockFor`, the authorizer and the hooks: one sources
|
|
578
|
+
* object per version cache, so every instance of one subject at one version
|
|
579
|
+
* shares an `instances` entry.
|
|
580
|
+
*/
|
|
581
|
+
function permdockResolver(options) {
|
|
582
|
+
const byCache = /* @__PURE__ */ new WeakMap();
|
|
583
|
+
let uncached;
|
|
584
|
+
const sourcesOf = (versions) => ({
|
|
585
|
+
...options.options,
|
|
586
|
+
...options.instances === void 0 ? {} : { instances: options.instances },
|
|
587
|
+
...options.memberships === void 0 ? {} : { memberships: claimsFirst(options.memberships, {
|
|
588
|
+
onStale: "reread",
|
|
589
|
+
...options.version === void 0 ? {} : { version: options.version },
|
|
590
|
+
...versions === void 0 ? {} : { versions }
|
|
591
|
+
}) }
|
|
592
|
+
});
|
|
593
|
+
const sourcesFor = (versions) => {
|
|
594
|
+
if (versions === void 0) {
|
|
595
|
+
uncached ??= sourcesOf(void 0);
|
|
596
|
+
return uncached;
|
|
597
|
+
}
|
|
598
|
+
const known = byCache.get(versions);
|
|
599
|
+
if (known !== void 0) return known;
|
|
600
|
+
const created = sourcesOf(versions);
|
|
601
|
+
byCache.set(versions, created);
|
|
602
|
+
return created;
|
|
603
|
+
};
|
|
604
|
+
return async (source, query, runtimeVersions) => {
|
|
605
|
+
const result = isResult(source) ? source : void 0;
|
|
606
|
+
const signedOut = result?.sessionActive === false;
|
|
607
|
+
const user = subjectOf(source, result, signedOut, options.subject);
|
|
608
|
+
const tenant = query.tenant ?? result?.tenant ?? void 0;
|
|
609
|
+
const known = signedOut ? void 0 : knownVersion(result?.authzVersion);
|
|
610
|
+
const sources = sourcesFor(runtimeVersions ?? options.versions);
|
|
611
|
+
const { permdock } = await buildInstance({
|
|
612
|
+
policy: options.policy,
|
|
613
|
+
user,
|
|
614
|
+
sources,
|
|
615
|
+
scope: {
|
|
616
|
+
...options.options,
|
|
617
|
+
memberships: sources.memberships,
|
|
618
|
+
intent: query.intent ?? "read",
|
|
619
|
+
tenant: tenant ?? void 0,
|
|
620
|
+
version: known === void 0 ? void 0 : { known }
|
|
621
|
+
}
|
|
622
|
+
});
|
|
623
|
+
return permdock;
|
|
624
|
+
};
|
|
625
|
+
}
|
|
626
|
+
/**
|
|
627
|
+
* One resolver for every instance of the app: `permdockFor(await
|
|
628
|
+
* bsb.claims())`, `permdockFor(await bsb.bootstrap(...))` or `permdockFor(await
|
|
629
|
+
* bsb.getAccess(...))`. A bootstrap or access result passes its `authzVersion`
|
|
630
|
+
* as `version.known`, so the instance reads no version, and a `sessionActive:
|
|
631
|
+
* false` bootstrap is anonymous. With `instances`, a subject at an unchanged
|
|
632
|
+
* version reuses its instance across requests.
|
|
633
|
+
*/
|
|
634
|
+
function permdockFor(options) {
|
|
635
|
+
const resolve = permdockResolver(options);
|
|
636
|
+
return (source, query) => resolve(source, typeof query === "string" || query === null ? { tenant: query } : query ?? {});
|
|
637
|
+
}
|
|
638
|
+
/**
|
|
639
|
+
* One `{ allowed, outcome, reason? }` per named check for `input`, from one
|
|
640
|
+
* `permdockFor` instance: frozen plain JSON an island returns from `'use cache:
|
|
641
|
+
* private'`. A check that throws denies its entry; an instance that cannot be
|
|
642
|
+
* built denies them all.
|
|
643
|
+
*/
|
|
644
|
+
async function getPermissions(resolve, input, checks, query) {
|
|
645
|
+
let permdock;
|
|
646
|
+
try {
|
|
647
|
+
permdock = await resolve(input, query);
|
|
648
|
+
} catch {
|
|
649
|
+
permdock = void 0;
|
|
650
|
+
}
|
|
651
|
+
if (permdock === void 0) return permissionStates(() => NO_GRANT, checks);
|
|
652
|
+
const decide = permdock.decide;
|
|
653
|
+
return permissionStates(decide, checks);
|
|
654
|
+
}
|
|
655
|
+
//#endregion
|
|
344
656
|
//#region src/better-supabase/subscribers.ts
|
|
345
657
|
function permissionFor(events, type) {
|
|
346
658
|
if (Object.hasOwn(events, type)) return events[type];
|
|
@@ -356,6 +668,14 @@ function permissionFor(events, type) {
|
|
|
356
668
|
* tenant and a throw reach no one.
|
|
357
669
|
*/
|
|
358
670
|
function subscriberPolicy(options) {
|
|
671
|
+
const resolve = permdockFor({
|
|
672
|
+
policy: options.policy,
|
|
673
|
+
options: {
|
|
674
|
+
...options.options,
|
|
675
|
+
principals: options.principals
|
|
676
|
+
},
|
|
677
|
+
...options.instances === void 0 ? {} : { instances: options.instances }
|
|
678
|
+
});
|
|
359
679
|
return async (event, subscribers) => {
|
|
360
680
|
try {
|
|
361
681
|
const permission = permissionFor(options.events, event.type);
|
|
@@ -364,14 +684,10 @@ function subscriberPolicy(options) {
|
|
|
364
684
|
if (permission === void 0 || tenant === null || senderId === null || senderId === void 0) return [];
|
|
365
685
|
const sender = await loadPrincipal(options.principals, senderId, tenant);
|
|
366
686
|
if (sender === null) return [];
|
|
367
|
-
const permdock = await
|
|
687
|
+
const permdock = await resolve({
|
|
368
688
|
principal: sender,
|
|
369
689
|
context: {}
|
|
370
|
-
},
|
|
371
|
-
...options.options,
|
|
372
|
-
principals: options.principals,
|
|
373
|
-
tenant
|
|
374
|
-
});
|
|
690
|
+
}, tenant);
|
|
375
691
|
if (permdock.subject.principal?.tenant !== tenant) return [];
|
|
376
692
|
return await subscribersFor(permdock, {
|
|
377
693
|
permission,
|
|
@@ -407,12 +723,13 @@ function requestId(input) {
|
|
|
407
723
|
* is `false`.
|
|
408
724
|
*/
|
|
409
725
|
function supportPolicy(options) {
|
|
726
|
+
const resolve = permdockFor(options);
|
|
410
727
|
return async (input) => {
|
|
411
728
|
try {
|
|
412
|
-
const base = await
|
|
729
|
+
const base = await resolve({
|
|
413
730
|
kind: "user",
|
|
414
731
|
claims: input.admin.claims
|
|
415
|
-
}
|
|
732
|
+
});
|
|
416
733
|
if (base.subject.principal?.id !== input.admin.user.id) return false;
|
|
417
734
|
if (!input.readOnly && options.writable === void 0) return false;
|
|
418
735
|
const permdock = input.tenant === void 0 ? base : base.tenant(input.tenant);
|
|
@@ -483,6 +800,7 @@ function matches(approvers, userId, permdock) {
|
|
|
483
800
|
case "assurance":
|
|
484
801
|
case "authenticated":
|
|
485
802
|
case "inherit":
|
|
803
|
+
case "manager":
|
|
486
804
|
case "plan":
|
|
487
805
|
case "relation":
|
|
488
806
|
case "role": return false;
|
|
@@ -495,25 +813,23 @@ function matches(approvers, userId, permdock) {
|
|
|
495
813
|
* authorization })`), decided by `policy`. Every hook builds the principal's
|
|
496
814
|
* instance from the claims `claims` loads now, never from the request, and
|
|
497
815
|
* fails closed: a throw, an unknown key and `approval-required` refuse.
|
|
498
|
-
* `automation` and `
|
|
499
|
-
* `
|
|
500
|
-
* `
|
|
501
|
-
*
|
|
502
|
-
* `
|
|
816
|
+
* `automation`, `delegation` and `sessionTags` (`snapshotTag(userId)`, so
|
|
817
|
+
* `evictSession` and sign-out clear PermDock snapshots) are always set;
|
|
818
|
+
* `identities`, `delivery`, `approverOf`, `support` and `tickets` only with the
|
|
819
|
+
* options they read. `delegation.permissions` maps each scope to the keys whose
|
|
820
|
+
* `.scope` it is, was renamed from, or that a policy `oauthScopes` entry
|
|
821
|
+
* covers, and reads no `authorization_details`.
|
|
503
822
|
*/
|
|
504
823
|
function authorizationHooks(options) {
|
|
505
824
|
const { policy } = options;
|
|
825
|
+
const resolve = permdockFor(options);
|
|
506
826
|
const instance = async (claims, tenant) => {
|
|
507
|
-
const
|
|
827
|
+
const permdock = await resolve({
|
|
508
828
|
kind: "user",
|
|
509
829
|
claims
|
|
510
|
-
},
|
|
511
|
-
if (subject.principal === null) return null;
|
|
512
|
-
|
|
513
|
-
...options.options,
|
|
514
|
-
...tenant === null || tenant === void 0 ? {} : { tenant }
|
|
515
|
-
});
|
|
516
|
-
return tenant === null || tenant === void 0 || permdock.subject.principal?.tenant === tenant ? permdock : null;
|
|
830
|
+
}, tenant);
|
|
831
|
+
if (permdock.subject.principal === null) return null;
|
|
832
|
+
return tenant === null || tenant === void 0 || permdock.subject.principal.tenant === tenant ? permdock : null;
|
|
517
833
|
};
|
|
518
834
|
const holdsAll = async (claims, automation) => {
|
|
519
835
|
const permdock = await instance(claims, automation.tenant);
|
|
@@ -589,6 +905,7 @@ function authorizationHooks(options) {
|
|
|
589
905
|
return Object.freeze({
|
|
590
906
|
apiVersion: 1,
|
|
591
907
|
name: "PermDock",
|
|
908
|
+
sessionTags: (userId) => [snapshotTag(userId)],
|
|
592
909
|
automation: Object.freeze(automation),
|
|
593
910
|
delegation: Object.freeze(delegation),
|
|
594
911
|
...approverOf === void 0 ? {} : { approverOf },
|
|
@@ -879,12 +1196,14 @@ function tokenHookOf(manifest, activeTenant) {
|
|
|
879
1196
|
const owned = manifest.claims.filter((claim) => claim.source === "permdock");
|
|
880
1197
|
const registered = manifest.claims.filter((claim) => claim.source !== "permdock");
|
|
881
1198
|
const budgeted = manifest.claims.filter((claim) => claim.budget);
|
|
1199
|
+
const truncated = owned.some((claim) => claim.name === "memberships_truncated") ? "memberships_truncated" : void 0;
|
|
882
1200
|
const activeFrom = activeTenant === "resolver" || manifest.hook.activeFrom === void 0 ? void 0 : activeOrganizationFrom(manifest.hook.activeFrom, manifest.tenantClaim);
|
|
883
1201
|
return {
|
|
884
1202
|
function: `${manifest.hook.schema}.${manifest.hook.function}`,
|
|
885
1203
|
tenantClaim: manifest.tenantClaim,
|
|
886
1204
|
...activeFrom === void 0 ? {} : { activeOrganizationFrom: activeFrom },
|
|
887
1205
|
ownedClaims: owned.map((claim) => claim.name),
|
|
1206
|
+
...truncated === void 0 ? {} : { truncatedClaim: truncated },
|
|
888
1207
|
...registered.length > 0 ? { registeredClaims: registered.map((claim) => ({
|
|
889
1208
|
name: claim.name,
|
|
890
1209
|
function: claim.source
|
|
@@ -892,7 +1211,7 @@ function tokenHookOf(manifest, activeTenant) {
|
|
|
892
1211
|
budget: {
|
|
893
1212
|
claims: budgeted.map((claim) => claim.name),
|
|
894
1213
|
bytes: manifest.budget.bytes,
|
|
895
|
-
...
|
|
1214
|
+
...truncated === void 0 ? {} : { truncatedClaim: truncated }
|
|
896
1215
|
},
|
|
897
1216
|
markers: {
|
|
898
1217
|
hook: `-- permdock:hook ${manifest.markers.hook}`,
|
|
@@ -1197,9 +1516,6 @@ const denied = (reason) => ({
|
|
|
1197
1516
|
outcome: "denied",
|
|
1198
1517
|
reason
|
|
1199
1518
|
});
|
|
1200
|
-
function isVersionCache(value) {
|
|
1201
|
-
return isRecord(value) && typeof value["maxStaleMs"] === "number" && typeof value["current"] === "function" && typeof value["evict"] === "function";
|
|
1202
|
-
}
|
|
1203
1519
|
function outcomeOf(decision, key) {
|
|
1204
1520
|
switch (decision.outcome) {
|
|
1205
1521
|
case "granted": return { outcome: "granted" };
|
|
@@ -1211,10 +1527,31 @@ function outcomeOf(decision, key) {
|
|
|
1211
1527
|
default: return decision;
|
|
1212
1528
|
}
|
|
1213
1529
|
}
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1530
|
+
/**
|
|
1531
|
+
* The row a check decides on. A write is `change`: a create checks the new
|
|
1532
|
+
* values, an update the stored row against the stored row with the new values
|
|
1533
|
+
* over it. Only a row better-supabase loaded itself, with no change, skips
|
|
1534
|
+
* schema validation.
|
|
1535
|
+
*/
|
|
1536
|
+
function dataOf(resource) {
|
|
1537
|
+
const { change } = resource;
|
|
1538
|
+
if (change !== void 0) return change.current === void 0 ? {
|
|
1539
|
+
data: change.next,
|
|
1540
|
+
trusted: false
|
|
1541
|
+
} : {
|
|
1542
|
+
data: {
|
|
1543
|
+
current: change.current,
|
|
1544
|
+
next: {
|
|
1545
|
+
...change.current,
|
|
1546
|
+
...change.next
|
|
1547
|
+
}
|
|
1548
|
+
},
|
|
1549
|
+
trusted: false
|
|
1550
|
+
};
|
|
1551
|
+
return {
|
|
1552
|
+
data: resource.properties,
|
|
1553
|
+
trusted: resource.source === "loaded"
|
|
1554
|
+
};
|
|
1218
1555
|
}
|
|
1219
1556
|
/**
|
|
1220
1557
|
* The verified claims better-supabase passes in `subject.properties.claims`,
|
|
@@ -1227,7 +1564,7 @@ function claimsOf(request) {
|
|
|
1227
1564
|
return isRecord(claims) ? claims : void 0;
|
|
1228
1565
|
}
|
|
1229
1566
|
const tenantOf = (request) => {
|
|
1230
|
-
const tenant = request.context
|
|
1567
|
+
const { tenant } = request.context;
|
|
1231
1568
|
return typeof tenant === "string" ? tenant : null;
|
|
1232
1569
|
};
|
|
1233
1570
|
const keyOf = (request) => isPermission(request.action) ? request.action.key : null;
|
|
@@ -1241,38 +1578,61 @@ const keyOf = (request) => isPermission(request.action) ? request.action.key : n
|
|
|
1241
1578
|
* request scope share an instance per claims, tenant and intent.
|
|
1242
1579
|
*/
|
|
1243
1580
|
function authorizer(options) {
|
|
1244
|
-
const { operations } = options;
|
|
1581
|
+
const { operations, store } = options;
|
|
1245
1582
|
const intentOf = (request, batch) => {
|
|
1246
1583
|
if (options.intent !== void 0) return options.intent(request);
|
|
1584
|
+
const { intent } = request.context;
|
|
1585
|
+
if (intent === "read" || intent === "write") return intent;
|
|
1247
1586
|
if (batch) return "read";
|
|
1248
1587
|
return isPermission(request.action) && READ_ACTIONS.has(request.action.action) ? "read" : "write";
|
|
1249
1588
|
};
|
|
1250
|
-
const
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
claims
|
|
1263
|
-
};
|
|
1264
|
-
const base = await getPermDock(options.policy, subjectFromBetterSupabase(session, options.subject), {
|
|
1265
|
-
...options.options,
|
|
1266
|
-
...membershipsFor(runtime),
|
|
1589
|
+
const resolve = permdockResolver(options);
|
|
1590
|
+
const instanceFor = (claims, tenant, intent, runtime) => resolve(claims === void 0 ? null : {
|
|
1591
|
+
kind: "user",
|
|
1592
|
+
claims
|
|
1593
|
+
}, {
|
|
1594
|
+
tenant,
|
|
1595
|
+
intent
|
|
1596
|
+
}, runtime?.versions);
|
|
1597
|
+
const scoped = (claims, tenant, intent, runtime, batch) => {
|
|
1598
|
+
const key = `permdock:authorizer:${canonicalJson([
|
|
1599
|
+
claims ?? null,
|
|
1600
|
+
tenant,
|
|
1267
1601
|
intent
|
|
1602
|
+
])}`;
|
|
1603
|
+
const build = () => instanceFor(claims, tenant, intent, runtime);
|
|
1604
|
+
if (runtime?.memo !== void 0) return runtime.memo.once(key, build);
|
|
1605
|
+
if (batch === void 0) return build();
|
|
1606
|
+
const known = batch.get(key);
|
|
1607
|
+
if (known !== void 0) return known;
|
|
1608
|
+
const created = build();
|
|
1609
|
+
batch.set(key, created);
|
|
1610
|
+
return created;
|
|
1611
|
+
};
|
|
1612
|
+
const decideWith = async (permdock, request, consume) => {
|
|
1613
|
+
const { action } = request;
|
|
1614
|
+
if (!isPermission(action)) return denied("Unknown permission.");
|
|
1615
|
+
const { data, trusted } = dataOf(request.resource);
|
|
1616
|
+
const decision = permdock.decide(action, data, {
|
|
1617
|
+
trusted,
|
|
1618
|
+
adapter: "better-supabase"
|
|
1268
1619
|
});
|
|
1269
|
-
|
|
1620
|
+
if (store === void 0 || decision.outcome !== "approval-required") return outcomeOf(decision, action.key);
|
|
1621
|
+
const { id } = request.resource;
|
|
1622
|
+
return outcomeOf(await resumeDecision({
|
|
1623
|
+
decision,
|
|
1624
|
+
permission: action,
|
|
1625
|
+
subject: permdock.subject,
|
|
1626
|
+
store,
|
|
1627
|
+
resource: id === void 0 ? { type: action.resource } : {
|
|
1628
|
+
type: action.resource,
|
|
1629
|
+
id
|
|
1630
|
+
},
|
|
1631
|
+
adapter: "better-supabase",
|
|
1632
|
+
token: parseApprovalHeader(request.context.approval ?? null),
|
|
1633
|
+
consume
|
|
1634
|
+
}), action.key);
|
|
1270
1635
|
};
|
|
1271
|
-
const scoped = (claims, tenant, intent, runtime) => runtime?.memo === void 0 ? instanceFor(claims, tenant, intent, runtime) : runtime.memo.once(`permdock:authorizer:${JSON.stringify([
|
|
1272
|
-
claims ?? null,
|
|
1273
|
-
tenant,
|
|
1274
|
-
intent
|
|
1275
|
-
])}`, () => instanceFor(claims, tenant, intent, runtime));
|
|
1276
1636
|
const failed = (error, request) => {
|
|
1277
1637
|
report(options.onError, error, {
|
|
1278
1638
|
permission: keyOf(request),
|
|
@@ -1293,33 +1653,17 @@ function authorizer(options) {
|
|
|
1293
1653
|
} },
|
|
1294
1654
|
async evaluate(request, runtime) {
|
|
1295
1655
|
try {
|
|
1296
|
-
return decideWith(await scoped(claimsOf(request), tenantOf(request), intentOf(request, false), runtime), request);
|
|
1656
|
+
return await decideWith(await scoped(claimsOf(request), tenantOf(request), intentOf(request, false), runtime), request, true);
|
|
1297
1657
|
} catch (error) {
|
|
1298
1658
|
return failed(error, request);
|
|
1299
1659
|
}
|
|
1300
1660
|
},
|
|
1301
1661
|
evaluations(requests, runtime) {
|
|
1302
|
-
const
|
|
1303
|
-
const shared = (request) =>
|
|
1304
|
-
const claims = claimsOf(request);
|
|
1305
|
-
const tenant = tenantOf(request);
|
|
1306
|
-
const intent = intentOf(request, true);
|
|
1307
|
-
let byKey = cache.get(claims);
|
|
1308
|
-
if (byKey === void 0) {
|
|
1309
|
-
byKey = /* @__PURE__ */ new Map();
|
|
1310
|
-
cache.set(claims, byKey);
|
|
1311
|
-
}
|
|
1312
|
-
const key = JSON.stringify([tenant, intent]);
|
|
1313
|
-
let instance = byKey.get(key);
|
|
1314
|
-
if (instance === void 0) {
|
|
1315
|
-
instance = scoped(claims, tenant, intent, runtime);
|
|
1316
|
-
byKey.set(key, instance);
|
|
1317
|
-
}
|
|
1318
|
-
return instance;
|
|
1319
|
-
};
|
|
1662
|
+
const batch = /* @__PURE__ */ new Map();
|
|
1663
|
+
const shared = (request) => scoped(claimsOf(request), tenantOf(request), intentOf(request, true), runtime, batch);
|
|
1320
1664
|
return Promise.all(requests.map(async (request) => {
|
|
1321
1665
|
try {
|
|
1322
|
-
return decideWith(await shared(request), request);
|
|
1666
|
+
return await decideWith(await shared(request), request, false);
|
|
1323
1667
|
} catch (error) {
|
|
1324
1668
|
return failed(error, request);
|
|
1325
1669
|
}
|
|
@@ -1332,14 +1676,17 @@ function authorizer(options) {
|
|
|
1332
1676
|
function roleOf(options, columns) {
|
|
1333
1677
|
const column = columns.role;
|
|
1334
1678
|
if (options.roles !== void 0 && options.roleThrough !== void 0) throw new TypeError("PermDock: blockMembershipSource takes roles or roleThrough, not both; a junction holds role keys");
|
|
1335
|
-
if (options.roles === "many")
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1679
|
+
if (options.roles === "many") {
|
|
1680
|
+
const junction = options.tables?.membershipRoles;
|
|
1681
|
+
return {
|
|
1682
|
+
through: junction?.table ?? `${qualifySqlTable(columns.table).split(".")[0] ?? "better_supabase"}.membership_roles`,
|
|
1683
|
+
on: {
|
|
1684
|
+
[columns.tenant]: junction?.columns.tenant ?? columns.tenant,
|
|
1685
|
+
[columns.user]: junction?.columns.user ?? columns.user
|
|
1686
|
+
},
|
|
1687
|
+
column: junction?.columns.role ?? "role"
|
|
1688
|
+
};
|
|
1689
|
+
}
|
|
1343
1690
|
if (options.roles !== void 0) return {
|
|
1344
1691
|
through: options.roles.table,
|
|
1345
1692
|
on: { [options.roles.id ?? "id"]: options.roles.membership },
|
|
@@ -1361,11 +1708,14 @@ function roleOf(options, columns) {
|
|
|
1361
1708
|
*/
|
|
1362
1709
|
function blockMembershipSource(options = {}) {
|
|
1363
1710
|
const c = options.columns ?? {};
|
|
1711
|
+
const block = options.tables?.memberships;
|
|
1364
1712
|
const scope = options.scope ?? "organization";
|
|
1365
|
-
const
|
|
1366
|
-
const
|
|
1367
|
-
const
|
|
1368
|
-
const
|
|
1713
|
+
const disabled = c.disabledAt === void 0 ? block?.columns.disabledAt : c.disabledAt;
|
|
1714
|
+
const disabledAt = disabled === null ? void 0 : disabled ?? "disabled_at";
|
|
1715
|
+
const table = options.table ?? block?.table ?? "better_supabase.memberships";
|
|
1716
|
+
const tenant = c.tenant ?? block?.columns.tenant ?? "organization_id";
|
|
1717
|
+
const user = c.user ?? block?.columns.user ?? "user_id";
|
|
1718
|
+
const role = c.role ?? block?.columns.role ?? "role";
|
|
1369
1719
|
return junctionMembershipSource({
|
|
1370
1720
|
table,
|
|
1371
1721
|
scope,
|
|
@@ -1373,7 +1723,7 @@ function blockMembershipSource(options = {}) {
|
|
|
1373
1723
|
user,
|
|
1374
1724
|
roles: roleOf(options, {
|
|
1375
1725
|
table,
|
|
1376
|
-
role
|
|
1726
|
+
role,
|
|
1377
1727
|
tenant,
|
|
1378
1728
|
user
|
|
1379
1729
|
}),
|
|
@@ -1515,9 +1865,10 @@ const refused = (reason) => ({
|
|
|
1515
1865
|
* The `authorize` and `visible` hooks of better-supabase's `createMcp`, for
|
|
1516
1866
|
* tools whose `meta` is a PermDock permission. A tool without a permission is
|
|
1517
1867
|
* hidden and refused. `authorize` grants only a `granted` decision: an
|
|
1518
|
-
* approval-required call is refused, because `
|
|
1519
|
-
* A
|
|
1520
|
-
*
|
|
1868
|
+
* approval-required call is refused, because `authorize` has no approval
|
|
1869
|
+
* outcome. A tool whose `permission` goes through `authorizer` with a `store`
|
|
1870
|
+
* returns the approval id and resumes it instead. A denial's text names the
|
|
1871
|
+
* first denial reason. A throw anywhere refuses and reaches `onError`.
|
|
1521
1872
|
*/
|
|
1522
1873
|
function toolPolicy(options) {
|
|
1523
1874
|
return Object.freeze({
|
|
@@ -1828,4 +2179,44 @@ function handlerCan(source, options = {}) {
|
|
|
1828
2179
|
};
|
|
1829
2180
|
}
|
|
1830
2181
|
//#endregion
|
|
1831
|
-
|
|
2182
|
+
//#region src/better-supabase/workflow-resource.ts
|
|
2183
|
+
const MAX_ID_LENGTH = 256;
|
|
2184
|
+
function invalid(detail) {
|
|
2185
|
+
return freezeDeep({
|
|
2186
|
+
ok: false,
|
|
2187
|
+
cause: "validation",
|
|
2188
|
+
decision: {
|
|
2189
|
+
outcome: "denied",
|
|
2190
|
+
denials: [{
|
|
2191
|
+
role: null,
|
|
2192
|
+
reason: "validation",
|
|
2193
|
+
detail
|
|
2194
|
+
}],
|
|
2195
|
+
alternatives: []
|
|
2196
|
+
}
|
|
2197
|
+
});
|
|
2198
|
+
}
|
|
2199
|
+
/**
|
|
2200
|
+
* The resource a `workflow.start` check decides on for a run started on
|
|
2201
|
+
* `subject`: `{ type, id }`, with the type `types` maps the subject type to. A
|
|
2202
|
+
* subject type `types` does not name, a missing or empty id, or an id over 256
|
|
2203
|
+
* characters is `{ ok: false, cause: 'validation' }` with the denial to
|
|
2204
|
+
* return.
|
|
2205
|
+
*/
|
|
2206
|
+
function workflowResource(subject, types) {
|
|
2207
|
+
if (!isRecord(subject)) return invalid("subject is not a { type, id } record");
|
|
2208
|
+
const { type, id } = subject;
|
|
2209
|
+
if (typeof type !== "string" || !Object.hasOwn(types, type)) return invalid(`unknown subject type ${JSON.stringify(type) ?? "undefined"}`);
|
|
2210
|
+
if (typeof id !== "string" || id === "" || id.length > MAX_ID_LENGTH) return invalid("subject id is not a non-empty string of at most 256 characters");
|
|
2211
|
+
const resource = types[type];
|
|
2212
|
+
if (typeof resource !== "string" || resource === "") return invalid(`subject type ${type} maps to no resource`);
|
|
2213
|
+
return freezeDeep({
|
|
2214
|
+
ok: true,
|
|
2215
|
+
resource: {
|
|
2216
|
+
type: resource,
|
|
2217
|
+
id
|
|
2218
|
+
}
|
|
2219
|
+
});
|
|
2220
|
+
}
|
|
2221
|
+
//#endregion
|
|
2222
|
+
export { accessReviewApplier, apiKeyClaimOptions, apiKeyVerifier, authorizationHooks, authorizationProvider, authorizer, blockApprovalPolicySource, blockApprovalStore, blockMembershipSource, bucketPolicy, credentialGuard, getPermissions, handlerCan, hookCan, permdockFor, principalFromMemberships, principalSource, roleOrderFromCatalog, subjectFromBetterSupabase, subjectFromShareLink, subscriberPolicy, supportPolicy, toolPolicy, topicPolicy, workflowResource };
|