permdock 0.1.0 → 0.3.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 +106 -47
- package/dist/a2a/index.d.ts +7 -16
- package/dist/a2a/index.js +59 -98
- package/dist/adapter-context-mlWsVGGg.js +23 -0
- package/dist/ai-sdk/index.d.ts +37 -16
- package/dist/ai-sdk/index.js +30 -13
- package/dist/approvals/index.d.ts +3 -3
- package/dist/approvals/index.js +5 -4
- package/dist/{approvals-DaxY-Bdg.js → approvals-DbYAuNkG.js} +17 -11
- package/dist/approvers-DT4AVyIg.js +52 -0
- package/dist/{arazzo-CTeVuXr5.js → arazzo-BAgw9ap6.js} +2 -2
- package/dist/{arazzo-aoTkqYsJ.js → arazzo-CKwwqFWz.js} +2 -2
- package/dist/authzen/index.d.ts +4 -13
- package/dist/authzen/index.js +16 -50
- package/dist/better-auth/index.d.ts +20 -3
- package/dist/better-auth/index.js +27 -7
- package/dist/better-supabase/index.d.ts +223 -0
- package/dist/better-supabase/index.js +648 -0
- package/dist/bind-C_ob3LKa.d.ts +25 -0
- package/dist/bind-CuzGytRf.js +97 -0
- package/dist/boundary-BM8a_P6E.js +13 -0
- package/dist/boundary-BmHxVH1J.d.ts +15 -0
- package/dist/canonical-json-DemiK4Vp.js +26 -0
- package/dist/{capability-BDG_nkxt.d.ts → capability-2kYTMWDv.d.ts} +2 -2
- package/dist/{capability-B68OFnZx.js → capability-4qPdO9gk.js} +7 -5
- package/dist/catalog/index.d.ts +1 -1
- package/dist/catalog/index.js +1 -1
- package/dist/catalog-CRW5Mx_B.js +2 -0
- package/dist/{catalog-H-vFGwWK.js → catalog-DWF5cYqB.js} +4 -4
- package/dist/{catalog-B0E6bggc.js → catalog-dFZdWCGN.js} +2 -2
- package/dist/{catalog-doc-BSo_Q_-6.js → catalog-doc-DdGm82XT.js} +20 -32
- package/dist/claude-agent/index.d.ts +5 -14
- package/dist/claude-agent/index.js +4 -10
- package/dist/clerk/index.d.ts +12 -3
- package/dist/clerk/index.js +26 -5
- package/dist/cli/bin.js +1 -1
- package/dist/cli/index.d.ts +3 -3
- package/dist/cli/index.js +2 -2
- package/dist/clients-C7zLFuWT.d.ts +12 -0
- package/dist/clients-DjU5ABMy.js +23 -0
- package/dist/cloud/index.d.ts +4 -5
- package/dist/cloud/index.js +20 -6
- package/dist/{cloud-BNQTrmrr.js → cloud-CB_ELYuX.js} +2 -2
- package/dist/{cloud-Cuxr6Czw.js → cloud-DWLXO2af.js} +7 -6
- package/dist/collect-DClJsheJ.js +83 -0
- package/dist/{collect-O-tOtbnk.js → collect-DSTE3ml9.js} +194 -42
- package/dist/collect-DSWOk19R.js +2 -0
- package/dist/{commands-BMh_Etm2.js → commands-DSxCqG9A.js} +16 -12
- package/dist/compile/index.d.ts +3 -0
- package/dist/compile/index.js +2 -0
- package/dist/{compile-D22iwvuV.js → compile-Ba4blROR.js} +85 -30
- package/dist/compile-BkRyBDBw.d.ts +94 -0
- package/dist/config-BJiM-xAm.js +157 -0
- package/dist/config-Dnszbv-6.js +36 -0
- package/dist/config-report-DMvWKUxL.js +44 -0
- package/dist/{connection-JvqwHODC.js → connection-CU8MQxRi.js} +1 -1
- package/dist/{context-CKEAabd7.js → context-Bcy85rGi.js} +36 -27
- package/dist/convex/index.d.ts +9 -4
- package/dist/convex/index.js +14 -4
- package/dist/create-B1d519XK.d.ts +245 -0
- package/dist/create-CMwIl-w2.js +253 -0
- package/dist/{credential-B_rkUNlY.js → credential-8P81ff4u.js} +26 -46
- package/dist/delegation-D8pUEuce.js +103 -0
- package/dist/{describe-Bt1YD5uS.js → describe-B_gVZEVi.js} +10 -15
- package/dist/{describe-DernyItf.d.ts → describe-DMYiCjJV.d.ts} +9 -10
- package/dist/{diff-x5Il8LVa.js → diff-2VaeChzX.js} +44 -11
- package/dist/{diff-BUzf5Poi.js → diff-DBIhz_f2.js} +2 -2
- package/dist/{doctor-Bqo6FwUa.js → doctor-BwCAMLx_.js} +2 -2
- package/dist/doctor-collect-CHk6XWOA.js +665 -0
- package/dist/doctor-igIiM_Hl.js +1194 -0
- package/dist/drizzle/index.d.ts +4 -3
- package/dist/drizzle/index.js +3 -3
- package/dist/elysia/index.d.ts +6 -28
- package/dist/elysia/index.js +16 -60
- package/dist/{errors-DSMnAVNa.js → errors-CWfoNg9N.js} +8 -4
- package/dist/{errors-Iy71s7Oj.js → errors-Cz5zn0mW.js} +17 -71
- package/dist/{errors-DbZ1YOnb.d.ts → errors-DPdqI50v.d.ts} +8 -21
- package/dist/{errors-m3u9TmDu.js → errors-DRnGZHzF.js} +4 -1
- package/dist/evaluation-items-CfCCejQd.js +40 -0
- package/dist/{evaluations-DsAU9ppl.js → evaluations-tz6D9A2G.js} +28 -46
- package/dist/eve/index.d.ts +6 -15
- package/dist/eve/index.js +7 -12
- package/dist/expiry-BoBJ8Tvc.js +7 -0
- package/dist/express/index.d.ts +6 -29
- package/dist/express/index.js +28 -58
- package/dist/fastify/index.d.ts +6 -29
- package/dist/fastify/index.js +16 -65
- package/dist/fields-BMl1RxoX.js +26 -0
- package/dist/{files-B_wAGYmt.js → files-DWUN9PzI.js} +5 -1
- package/dist/{fixtures-Cvaw0gDG.js → fixtures-ht28Cplr.js} +5 -2
- package/dist/{freeze-y1_jQL4v.js → freeze-CrU8nQeX.js} +31 -2
- package/dist/{from-snapshot-BMGnhmgv.js → from-snapshot-CTLijvdm.js} +66 -48
- package/dist/{grantee-Bv04_Vzf.js → grantee-Cv5Sogfv.js} +88 -7
- package/dist/graph-sql-B-dsAT6j.d.ts +29 -0
- package/dist/{headers-B5RRv3Xm.js → headers-BZSDieNT.js} +1 -1
- package/dist/{headers-C8SHQccD.d.ts → headers-Cf-zWvsO.d.ts} +1 -1
- package/dist/helpers-H_KARDVC.js +421 -0
- package/dist/hono/index.d.ts +6 -28
- package/dist/hono/index.js +11 -43
- package/dist/{hosted-BwKQ1BTA.js → hosted-DJQw46hn.js} +6 -5
- package/dist/{http-GgVApX1k.js → http-BIhmLfCc.js} +4 -20
- package/dist/http-SO7qGttf.js +44 -0
- package/dist/ids-DC4V4CFu.js +18 -0
- package/dist/index-0nNqHspG.d.ts +6 -0
- package/dist/{index-xIxJLwOQ.d.ts → index-BNc7Wer_.d.ts} +75 -7
- package/dist/{index-CltcQ4Bf.d.ts → index-C7Tw7MaW.d.ts} +68 -5
- package/dist/{index-LF_hS-yn.d.ts → index-C8z4RjQV.d.ts} +1 -1
- package/dist/index.d.ts +14 -9
- package/dist/index.js +22 -17
- package/dist/instance-options-Dhhcnm3y.js +22 -0
- package/dist/instance-options-jARdwfPN.d.ts +11 -0
- package/dist/{parse-DPfIvFMU.js → json-schema-BsAflUGW.js} +28 -57
- package/dist/jwt/index.d.ts +10 -6
- package/dist/jwt/index.js +32 -13
- package/dist/kernel-_RRHmnMY.js +208 -0
- package/dist/kysely/index.d.ts +4 -3
- package/dist/kysely/index.js +3 -3
- package/dist/live-options-H2eG8dfJ.js +60 -0
- package/dist/{load-BZ24CpZP.js → load-DhWEB9P1.js} +16 -10
- package/dist/load-DwJUafYN.js +2 -0
- package/dist/manifest-iaoBXHKc.js +783 -0
- package/dist/manifest-uDS9y5de.d.ts +206 -0
- package/dist/{map-DowSO96j.js → map-AcxK9o_D.js} +4 -15
- package/dist/{map-claims-B_6I1Rn-.js → map-claims-Z4QZOiFF.js} +13 -4
- package/dist/map-error-pgUWNNtG.js +23 -0
- package/dist/may-use-DndQ5tQ-.js +77 -0
- package/dist/mcp/index.d.ts +54 -22
- package/dist/mcp/index.js +218 -178
- package/dist/nest/index.d.ts +26 -31
- package/dist/nest/index.js +75 -84
- package/dist/next/client.d.ts +7 -8
- package/dist/next/client.js +11 -9
- package/dist/next/index.d.ts +30 -47
- package/dist/next/index.js +45 -60
- package/dist/next/plugin.d.ts +1 -1
- package/dist/next/plugin.js +32 -1
- package/dist/node/index.d.ts +9 -28
- package/dist/node/index.js +11 -43
- package/dist/openai/index.d.ts +6 -15
- package/dist/openai/index.js +7 -20
- package/dist/openapi/index.d.ts +87 -4
- package/dist/openapi/index.js +3 -3
- package/dist/{openapi-DcqM8nU7.js → openapi-BqRBvAng.js} +237 -5
- package/dist/{openapi-DWD0Uc_4.js → openapi-CqqEbHsL.js} +5 -5
- package/dist/{openapi-import-BWRUNNeW.js → openapi-import-cmwetbzw.js} +1 -1
- package/dist/{openapi-CwePaF7C.js → openapi-l0xYHkcv.js} +3 -3
- package/dist/{openapi-schema-D8j_T9tO.js → openapi-schema--ARjyfQr.js} +2 -2
- package/dist/orpc/index.d.ts +15 -28
- package/dist/orpc/index.js +74 -117
- package/dist/otel/index.d.ts +2 -2
- package/dist/parse-BuyjxhZV.js +53 -0
- package/dist/parse-local-manifest-BrMozJCo.js +36 -0
- package/dist/parse-local-manifest-JLnaBH0S.d.ts +10 -0
- package/dist/pdp/index.d.ts +2 -2
- package/dist/pdp/index.js +14 -127
- package/dist/{permdock-yoZ7EjxX.js → permdock-CbgvLnuo.js} +672 -149
- package/dist/{permissions-B8vCg_bI.d.ts → permissions-CDgvKG5L.d.ts} +2 -2
- package/dist/{permissions-DC7GROPA.js → permissions-DVoF6dMt.js} +77 -15
- package/dist/{permissions-B4apnahQ.d.ts → permissions-DttnqqxC.d.ts} +34 -5
- package/dist/{permissions-CofRqesP.js → permissions-RJrovw98.js} +3 -3
- package/dist/{pins-CqE1jZuF.js → pins-8ILTftC9.js} +2 -2
- package/dist/{policy-Cq2fB8Q5.d.ts → policy-D2W7uv19.d.ts} +2 -2
- package/dist/{policy-CInmNGkM.d.ts → policy-IB6yxpC3.d.ts} +351 -42
- package/dist/{policy-ANp36PnI.js → policy-xyWg7QdR.js} +173 -22
- package/dist/powersync-BylawD_U.js +540 -0
- package/dist/powersync-DliZK_-y.js +62 -0
- package/dist/powersync-e_AZrKbg.js +2 -0
- package/dist/prisma/index.d.ts +3 -2
- package/dist/prisma/index.js +45 -20
- package/dist/{problem-Cgp9-KZA.js → problem-B43ztKIm.js} +74 -109
- package/dist/problem-details-DX075l9V.d.ts +7 -0
- package/dist/problem-details-_AMOYz-w.js +144 -0
- package/dist/{protected-BuPAycJT.d.ts → protected-BdnIEFkY.d.ts} +5 -4
- package/dist/protected-utU-SLuy.js +100 -0
- package/dist/protected-xAr24FEC.d.ts +40 -0
- package/dist/provider-CSQd7m92.js +52 -0
- package/dist/{provider-wTAUda2v.d.ts → provider-DZY281jO.d.ts} +1 -1
- package/dist/provider-store-Cfbvo4DE.js +43 -0
- package/dist/react/index.d.ts +7 -5
- package/dist/react/index.js +5 -4
- package/dist/react/provider-client.d.ts +1 -1
- package/dist/react/provider-client.js +1 -1
- package/dist/react-native/index.d.ts +166 -10
- package/dist/react-native/index.js +607 -85
- package/dist/{refs-ChLSxbST.js → refs-KYb4ntaz.js} +4 -3
- package/dist/{relations-r4soIFZB.js → relations-cjOL01hZ.js} +110 -31
- package/dist/replay-BsOyTrdV.js +28 -0
- package/dist/replay-CYyiLiwO.d.ts +5 -0
- package/dist/resource-ref-CaS9yVPi.js +20 -0
- package/dist/revocations-Bhr0aMIC.js +27 -0
- package/dist/{rls-BOFU3chG.js → rls-B4ur8nKQ.js} +8 -3
- package/dist/rls-DQtdgTHB.js +2521 -0
- package/dist/rls-fields-74oZPXWL.js +3582 -0
- package/dist/{rls-graph-DxQ39PJj.js → rls-graph-CHwx0V8q.js} +100 -36
- package/dist/{rls-import-CXV6LBlS.js → rls-import-BTFVk3jH.js} +7 -6
- package/dist/{rls-migrate-DrFPbf8p.js → rls-migrate-CN4TlJTO.js} +6 -5
- package/dist/rls-ownership-RuFqaqGz.js +843 -0
- package/dist/rls-shared-Cewd_-zI.js +495 -0
- package/dist/rls-verify-CVQTHTh5.js +746 -0
- package/dist/{row-check-BajTgQZ-.d.ts → row-check-Dt35czLy.d.ts} +12 -15
- package/dist/row-conditions-h2HythXQ.js +27 -0
- package/dist/rpc-DL9Sqvb1.js +89 -0
- package/dist/{run-CJ6UvS3a.js → run-DKDbM4Du.js} +31 -12
- package/dist/runtime-CB8gQFvS.js +11 -0
- package/dist/{saas-BRrZzJkM.js → saas-DhpJjnBA.js} +17 -7
- package/dist/{schema-P8yoma__.js → schema-D3MnDMxa.js} +8 -4
- package/dist/scim/index.d.ts +1 -1
- package/dist/scim/index.js +1 -1
- package/dist/{scim-9NFa0XVZ.js → scim-BFGBBAqR.js} +1 -1
- package/dist/{scopes-cKVp_WTw.js → scopes-CVdPrWN-.js} +35 -8
- package/dist/server/index.d.ts +22 -11
- package/dist/server/index.js +11 -8
- package/dist/{credentials-BgRX3WEg.js → server-DlZ28Oz5.js} +1 -1
- package/dist/shared-DRu8VFVM.js +123 -0
- package/dist/{sink-Cfr9-7YC.d.ts → sink-B1fZzIMf.d.ts} +1 -1
- package/dist/skills-Biq5uup3.js +192 -0
- package/dist/{skills-C_lpV4Jx.js → skills-Bx-U0irG.js} +10 -4
- package/dist/{snapshot-DE8dE_hz.js → snapshot-Enxd0n-s.js} +138 -214
- package/dist/snapshot-cache-B-LxUahj.d.ts +45 -0
- package/dist/snapshot-cache-D6jLelln.js +44 -0
- package/dist/solid/index.d.ts +39 -9
- package/dist/solid/index.js +76 -85
- package/dist/sources-4p0-4xQm.js +545 -0
- package/dist/sources-BdOYLw9j.d.ts +192 -0
- package/dist/{sql-Bll1d7y0.js → sql-xdg5f4Fi.js} +6 -1
- package/dist/{src-CTNT-PBW.js → src-BDwEZWrZ.js} +149 -11
- package/dist/ssf/index.d.ts +3 -2
- package/dist/ssf/index.js +3 -29
- package/dist/store-DMAWwAJV.js +371 -0
- package/dist/{store-Bq90395i.d.ts → store-jOBYpiXC.d.ts} +13 -4
- package/dist/store-options-ByhZq1jV.js +716 -0
- package/dist/{stores-CkG2HrSg.js → stores-BT2pSCub.js} +10 -63
- package/dist/{stores-CvOnu_2T.d.ts → stores-C0IMQrGI.d.ts} +20 -9
- package/dist/{stream-BhMfZOwr.d.ts → stream-D1RXubw2.d.ts} +2 -2
- package/dist/{stream-Q_xlB6Ko.js → stream-DDpvynSB.js} +16 -2
- package/dist/subject-settings-BwBmCdTR.js +128 -0
- package/dist/supabase/index.d.ts +133 -6
- package/dist/supabase/index.js +4 -3
- package/dist/supabase/middleware.d.ts +32 -27
- package/dist/supabase/middleware.js +56 -22
- package/dist/{supabase-D8UlBA7Z.js → supabase-Boqb9a_Y.js} +3 -3
- package/dist/{supabase-DTxGtYdi.js → supabase-C0qESOa-.js} +347 -367
- package/dist/supabase-config-BpPXt3x1.js +472 -0
- package/dist/supabase-hook-6sYLXg_u.js +2 -0
- package/dist/{supabase-hook-D_OqGb_V.js → supabase-hook-CSLQ4zJ3.js} +1037 -705
- package/dist/supautils-Cn4R4cJ4.js +91 -0
- package/dist/svelte/PermissionBoundary.svelte +37 -0
- package/dist/svelte/Protected.svelte +8 -2
- package/dist/svelte/index.d.ts +9 -6
- package/dist/svelte/index.js +61 -7
- package/dist/svelte/runtime.d.ts +4 -3
- package/dist/svelte/runtime.js +4 -3
- package/dist/svelte/source.d.ts +9 -6
- package/dist/svelte/source.js +7 -4
- package/dist/terminal/index.d.ts +6 -14
- package/dist/terminal/index.js +44 -32
- package/dist/testing/index.d.ts +105 -16
- package/dist/testing/index.js +504 -40
- package/dist/testing/saas/index.d.ts +4 -4
- 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/token-CIWxJOCh.js +50 -0
- package/dist/trpc/index.d.ts +7 -26
- package/dist/trpc/index.js +17 -100
- package/dist/types-BnIEz1sU.d.ts +48 -0
- package/dist/{types-CxquUByI.d.ts → types-Bvc4oWT6.d.ts} +1 -1
- package/dist/{sources-DOpW5Ila.d.ts → types-C97IskBw.d.ts} +86 -127
- package/dist/types-CKNSyIf_.d.ts +52 -0
- package/dist/types-Cq_H8N_X.d.ts +197 -0
- package/dist/{types-D6Z6-rKJ.d.ts → types-DbjRN55U.d.ts} +273 -22
- package/dist/{types-BBK-exvJ.d.ts → types-Dnemwd77.d.ts} +7 -1
- package/dist/{types-BvBk1wgn.d.ts → types-DxiCGmmd.d.ts} +5 -3
- package/dist/{types-B9dmiiab.d.ts → types-QCuYJh4q.d.ts} +1 -1
- package/dist/{types-B8w5PFtS.d.ts → types-aqOHTHcp.d.ts} +17 -1
- package/dist/unplugin/index.d.ts +1 -1
- package/dist/unplugin/index.js +10 -9
- package/dist/usage-DorAJiU_.js +2 -0
- package/dist/{usage-1ozMubLY.js → usage-GTixvDDU.js} +2 -2
- package/dist/{usage-CUnK6Ou9.js → usage-ItS7nLcl.js} +225 -62
- package/dist/validation-error-Ba264OaJ.d.ts +26 -0
- package/dist/validation-error-CnjZ4t92.js +33 -0
- package/dist/{validity-D0uRmJKJ.js → validity-uOp8UpYn.js} +57 -36
- package/dist/{verifier-B90agnhl.js → verifier-BxBo6I44.js} +10 -5
- package/dist/version-BvacVTZR.js +17 -0
- package/dist/views-Soe7bGSC.js +95 -0
- package/dist/{vocabulary-Dk0fs-Jk.d.ts → vocabulary-DA8a8zif.d.ts} +1 -1
- package/dist/vue/index.d.ts +35 -13
- package/dist/vue/index.js +86 -93
- package/dist/watch-BwxLTYMZ.js +2 -0
- package/dist/watch-DVBJ9cBq.js +128 -0
- package/dist/webmcp/index.d.ts +2 -2
- package/dist/webmcp/index.js +7 -13
- package/package.json +62 -36
- package/schemas/approval-request-v1.json +175 -0
- package/schemas/catalog-v1.json +29 -1
- package/schemas/supabase-claims-v1.json +6 -1
- package/schemas/supabase-manifest-v1.json +150 -6
- package/skills/permdock/SKILL.md +7 -7
- package/skills/permdock-agents/SKILL.md +5 -5
- package/skills/permdock-agents/references/runtimes.md +12 -10
- package/skills/permdock-approvals/SKILL.md +4 -4
- package/skills/permdock-approvals/references/stores-and-resume.md +15 -4
- package/skills/permdock-audit/SKILL.md +3 -3
- package/skills/permdock-credentials/SKILL.md +4 -4
- package/skills/permdock-credentials/references/tokens-keys-links.md +7 -2
- package/skills/permdock-data/SKILL.md +4 -4
- package/skills/permdock-data/references/queries-and-rls.md +14 -6
- package/skills/permdock-data/references/relationships.md +5 -3
- package/skills/permdock-tenancy/SKILL.md +9 -6
- package/skills/permdock-tenancy/references/ownership-and-custom-roles.md +14 -8
- package/skills/permdock-wire/SKILL.md +4 -4
- package/skills/permdock-wire/references/adapters.md +42 -30
- package/skills/permdock-wire/references/policy-options.md +5 -3
- package/dist/approvers-aH0PJkmf.js +0 -20
- package/dist/catalog-idsHc0vo.js +0 -2
- package/dist/collect-B7_TIfmg.js +0 -49
- package/dist/collect-fRPAQIWb.js +0 -2
- package/dist/compile-CQbvyIBr.d.ts +0 -30
- package/dist/config-BPYmjTOp.js +0 -26
- package/dist/context-gtAwAILx.js +0 -6
- package/dist/create-BKF3dgFk.d.ts +0 -162
- package/dist/create-CSkhDU9T.js +0 -222
- package/dist/doctor-BGle8Gqi.js +0 -1314
- package/dist/helpers-DnSOrhB9.js +0 -682
- package/dist/index-fG6NSXlc.d.ts +0 -9
- package/dist/kernel-YOGCWNLf.js +0 -211
- package/dist/load-QOOm1z70.js +0 -2
- package/dist/manifest-DDQbC6K0.d.ts +0 -118
- package/dist/map-error-RJ3ZsUyA.js +0 -16
- package/dist/may-use-CnFEjVEp.js +0 -37
- package/dist/pg-4GJWDUxG.js +0 -953
- package/dist/plugin-4gr7IxFJ.js +0 -65
- package/dist/protected-B4K3BKoX.js +0 -138
- package/dist/protected-wY7nXhY9.d.ts +0 -23
- package/dist/provider-_wx46HpB.js +0 -48
- package/dist/rls-CJVja9Ww.js +0 -2119
- package/dist/rls-helpers-BxRuif0l.js +0 -1346
- package/dist/runtime-DP9ttFh1.js +0 -27
- package/dist/skills-Dx3QLnMY.js +0 -110
- package/dist/source-DoBBYJi2.js +0 -6
- package/dist/sources-DVHM3Mwq.js +0 -284
- package/dist/store-C6hFW6ta.js +0 -508
- package/dist/subject-settings-xt7V845g.js +0 -82
- package/dist/supabase-hook-DW-xP4hU.js +0 -2
- package/dist/types-DbWdEfcm.d.ts +0 -87
- package/dist/types-bva3i4Gf.d.ts +0 -98
- package/dist/types-i4BAOvdb.d.ts +0 -97
- package/dist/usage-PyEor6GA.js +0 -2
- package/dist/version-CnSh33Fj.js +0 -16
|
@@ -1,35 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
function sanitizeFields(fields) {
|
|
6
|
-
if (fields === void 0) return;
|
|
7
|
-
return fields.filter((field) => field.length > 0 && !isForbiddenKey(field));
|
|
8
|
-
}
|
|
9
|
-
function grantCoversField(fields, field, effect) {
|
|
10
|
-
if (fields === void 0) return true;
|
|
11
|
-
if (fields.length === 0) return false;
|
|
12
|
-
if (field === void 0) return effect === "allow";
|
|
13
|
-
return fields.includes(field);
|
|
14
|
-
}
|
|
15
|
-
function pickVisible(row, canField) {
|
|
16
|
-
const out = {};
|
|
17
|
-
for (const key of ownKeys(row)) if (canField(key)) out[key] = ownGet(row, key);
|
|
18
|
-
return freezeDeep(out);
|
|
19
|
-
}
|
|
20
|
-
function sanitizeContext(value) {
|
|
21
|
-
if (value === null || typeof value !== "object" || Array.isArray(value)) return {};
|
|
22
|
-
const out = {};
|
|
23
|
-
for (const key of ownKeys(value)) out[key] = ownGet(value, key);
|
|
24
|
-
return out;
|
|
25
|
-
}
|
|
26
|
-
//#endregion
|
|
1
|
+
import { f as isFieldRelation } from "./permissions-DVoF6dMt.js";
|
|
2
|
+
import { t as expiredAt } from "./expiry-BoBJ8Tvc.js";
|
|
3
|
+
import { n as sameId } from "./ids-DC4V4CFu.js";
|
|
4
|
+
import { c as rootScope, l as scopeChain, m as tenantOf, o as resolveScope, r as findScope, t as activeFor, u as scopeIdOf } from "./scopes-CVdPrWN-.js";
|
|
27
5
|
//#region src/core/tenancy.ts
|
|
28
6
|
function nowSeconds(now) {
|
|
29
7
|
return now ?? Date.now() / 1e3;
|
|
30
8
|
}
|
|
31
9
|
function isMembershipExpired(membership, now) {
|
|
32
|
-
return membership
|
|
10
|
+
return expiredAt(membership, now ?? nowSeconds());
|
|
33
11
|
}
|
|
34
12
|
/** The instances of the first scope the subject holds a live membership in. */
|
|
35
13
|
function tenantsOf(principal, scopes, now) {
|
|
@@ -42,6 +20,11 @@ function tenantsOf(principal, scopes, now) {
|
|
|
42
20
|
}
|
|
43
21
|
return [...tenants];
|
|
44
22
|
}
|
|
23
|
+
function heldRoleNamesIn(principal, scopes, tenant, now) {
|
|
24
|
+
const names = /* @__PURE__ */ new Set();
|
|
25
|
+
for (const membership of principal?.memberships ?? []) if (!isMembershipExpired(membership, now) && membership.keep === void 0 && tenantOf(membership, scopes) === tenant) for (const name of membership.roles) names.add(name);
|
|
26
|
+
return [...names];
|
|
27
|
+
}
|
|
45
28
|
/** `requested` when a live membership sits in that instance of the first scope; never a default. */
|
|
46
29
|
function resolveActiveTenant(principal, requested, scopes, now) {
|
|
47
30
|
if (requested === void 0) return principal.tenant;
|
|
@@ -62,9 +45,30 @@ function relatesTo(resource, field, scope, scopes) {
|
|
|
62
45
|
if (resource === void 0) return false;
|
|
63
46
|
return Object.values(resource.relations).some((relation) => isFieldRelation(relation) && relation.field === field && relation.memberOf !== void 0 && resolveScope(scopes, relation.memberOf) === scope);
|
|
64
47
|
}
|
|
65
|
-
/** The
|
|
48
|
+
/** The fields of `resource`'s `memberOf` relations to `scope`. */
|
|
49
|
+
function memberOfFields(resource, scope, scopes) {
|
|
50
|
+
return [...new Set(Object.values(resource.relations).flatMap((relation) => isFieldRelation(relation) && relation.memberOf !== void 0 && resolveScope(scopes, relation.memberOf) === scope ? [relation.field] : []))];
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* The field of `resource` that holds `scope`'s instance id: the scope's
|
|
54
|
+
* `key` when one of the resource's `memberOf` relations names it, otherwise
|
|
55
|
+
* the field of its one `memberOf` relation to the scope. A table whose own
|
|
56
|
+
* id is the instance (`organizations.id`) declares
|
|
57
|
+
* `{ self: { field: 'id', memberOf: 'organization' } }`.
|
|
58
|
+
*/
|
|
59
|
+
function scopeField(resource, scope, scopes) {
|
|
60
|
+
const key = findScope(scopes, scope)?.key;
|
|
61
|
+
if (resource === void 0) return key;
|
|
62
|
+
const fields = memberOfFields(resource, scope, scopes);
|
|
63
|
+
if (key !== void 0 && fields.includes(key)) return key;
|
|
64
|
+
return fields.length === 1 ? fields[0] : key;
|
|
65
|
+
}
|
|
66
|
+
/** The scopes that partition `resource`, from its `memberOf` relations. */
|
|
66
67
|
function partitionsOf(resource, scopes) {
|
|
67
|
-
return scopes.filter((scope) =>
|
|
68
|
+
return scopes.filter((scope) => {
|
|
69
|
+
const field = scopeField(resource, scope.name, scopes);
|
|
70
|
+
return field !== void 0 && relatesTo(resource, field, scope.name, scopes);
|
|
71
|
+
}).map((scope) => scope.name);
|
|
68
72
|
}
|
|
69
73
|
/**
|
|
70
74
|
* Whether `row` lies inside a named membership's instance: for the scope and
|
|
@@ -72,23 +76,36 @@ function partitionsOf(resource, scopes) {
|
|
|
72
76
|
* resource declares it) must hold the membership's id for it. There is no
|
|
73
77
|
* cascade: the membership's own scope is checked, never a scope below it.
|
|
74
78
|
*/
|
|
75
|
-
function rowInScope(membership, scopes, row, partitioned) {
|
|
79
|
+
function rowInScope(membership, scopes, row, partitioned, fieldOf) {
|
|
76
80
|
if (membership.scope === void 0 || row === null || typeof row !== "object") return { ok: true };
|
|
77
81
|
const root = rootScope(scopes);
|
|
78
82
|
const chain = scopeChain(scopes, membership.scope).toReversed();
|
|
79
83
|
for (const name of chain) {
|
|
80
|
-
const key = findScope(scopes, name)?.key;
|
|
84
|
+
const key = fieldOf?.(name) ?? findScope(scopes, name)?.key;
|
|
81
85
|
if (key === void 0) continue;
|
|
82
86
|
const value = Object.hasOwn(row, key) ? row[key] : void 0;
|
|
83
|
-
if ((value !== void 0 || partitioned(name, key)) && value
|
|
87
|
+
if ((value !== void 0 || partitioned(name, key)) && !sameId(value, scopeIdOf(membership, name))) return {
|
|
84
88
|
ok: false,
|
|
85
89
|
reason: name === root ? "tenant-mismatch" : "scope"
|
|
86
90
|
};
|
|
87
91
|
}
|
|
88
92
|
return { ok: true };
|
|
89
93
|
}
|
|
90
|
-
|
|
94
|
+
/**
|
|
95
|
+
* Whether a membership answers an instance check for `row`: any membership
|
|
96
|
+
* with a row object, otherwise only the first scope or the instance of the
|
|
97
|
+
* second scope that `team(id)` selected.
|
|
98
|
+
*/
|
|
99
|
+
function nestedAppliesWithoutRow(membership, scopes, row, team) {
|
|
100
|
+
if (row !== null && typeof row === "object") return true;
|
|
101
|
+
return membership.scope === rootScope(scopes) || team !== void 0 && membership.scope === scopes[1]?.name;
|
|
102
|
+
}
|
|
103
|
+
function matchScopedMembership(subject, scope, roleName, row, scopes, resource, resources, now, rolesOf = (membership) => membership.roles, team, walk, instance = false, only) {
|
|
91
104
|
if (scope === "global") return { ok: true };
|
|
105
|
+
if (only !== void 0 && scope !== only) return {
|
|
106
|
+
ok: false,
|
|
107
|
+
reason: "scope"
|
|
108
|
+
};
|
|
92
109
|
const principal = subject.principal;
|
|
93
110
|
if (principal === null) return {
|
|
94
111
|
ok: false,
|
|
@@ -108,7 +125,11 @@ function matchScopedMembership(subject, scope, roleName, row, scopes, resource,
|
|
|
108
125
|
}
|
|
109
126
|
if (typeof scope === "string") {
|
|
110
127
|
if (findScope(scopes, scope) === void 0 || membership.scope !== scope || !inTeam(membership, scopes, team) || !activeFor(membership, scopes, principal.tenant)) continue;
|
|
111
|
-
|
|
128
|
+
if (instance && !nestedAppliesWithoutRow(membership, scopes, row, team)) {
|
|
129
|
+
sawWrongScope = true;
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
const inside = rowInScope(membership, scopes, row, (name, key) => relatesTo(resource, key, name, scopes), (name) => scopeField(resource, name, scopes));
|
|
112
133
|
if (!inside.ok) {
|
|
113
134
|
if (inside.reason === "tenant-mismatch") sawTenantMismatch = true;
|
|
114
135
|
else sawWrongScope = true;
|
|
@@ -165,7 +186,7 @@ function matchResourceMembership(membership, roleResource, row, resource, resour
|
|
|
165
186
|
if (row === null || typeof row !== "object") return false;
|
|
166
187
|
if (on.resource !== roleResource && membershipField(resources.get(roleResource), on.resource, resources) === void 0) return false;
|
|
167
188
|
const field = membershipField(resource, on.resource, resources);
|
|
168
|
-
return field !== void 0 && row[field]
|
|
189
|
+
return field !== void 0 && sameId(row[field], on.id);
|
|
169
190
|
}
|
|
170
191
|
/**
|
|
171
192
|
* The row field that holds the id of a `membershipResource` membership: the
|
|
@@ -221,4 +242,4 @@ function isActive(validity, now) {
|
|
|
221
242
|
return validity.until === void 0 || now < validity.until;
|
|
222
243
|
}
|
|
223
244
|
//#endregion
|
|
224
|
-
export {
|
|
245
|
+
export { isMembershipExpired as a, membershipField as c, partitionsOf as d, relatesTo as f, tenantsOf as g, scopeField as h, inTeam as i, nestedAppliesWithoutRow as l, rowInScope as m, normalizeValidity as n, matchScopedMembership as o, resolveActiveTenant as p, heldRoleNamesIn as r, memberOfFields as s, isActive as t, nowSeconds as u };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as isReadonlyArray, t as compact } from "./compact-y6vfu2_f.js";
|
|
2
|
-
import {
|
|
2
|
+
import { T as isForbiddenKey, k as splitPath } from "./permissions-DVoF6dMt.js";
|
|
3
3
|
import { t as loadJose } from "./load-jose-BL6LH4bL.js";
|
|
4
4
|
//#region src/jwt/header.ts
|
|
5
5
|
function compactParts(token) {
|
|
@@ -173,7 +173,9 @@ function createKeyCache(options) {
|
|
|
173
173
|
const jwksInFlight = /* @__PURE__ */ new Map();
|
|
174
174
|
let discoveryInFlight;
|
|
175
175
|
let discoveryCache;
|
|
176
|
+
/** Keyed by `jwks_uri`: keys cached for one URI never answer for another. */
|
|
176
177
|
let jwksCache;
|
|
178
|
+
const cachedJwks = (href, now) => jwksCache?.href === href && jwksCache.expiresAt > now ? jwksCache.value : void 0;
|
|
177
179
|
let cooldownUntil = 0;
|
|
178
180
|
let discoveryCause;
|
|
179
181
|
const readDiscovery = async (href, issuer, now) => {
|
|
@@ -251,9 +253,10 @@ function createKeyCache(options) {
|
|
|
251
253
|
};
|
|
252
254
|
};
|
|
253
255
|
const loadJwks = (href, now, force) => {
|
|
254
|
-
|
|
256
|
+
const cached = force ? void 0 : cachedJwks(href, now);
|
|
257
|
+
if (cached !== void 0) return Promise.resolve({
|
|
255
258
|
ok: true,
|
|
256
|
-
jwks:
|
|
259
|
+
jwks: cached
|
|
257
260
|
});
|
|
258
261
|
const pending = jwksInFlight.get(href);
|
|
259
262
|
if (pending !== void 0) return pending;
|
|
@@ -273,6 +276,7 @@ function createKeyCache(options) {
|
|
|
273
276
|
const body = await response.json();
|
|
274
277
|
if (!Array.isArray(body.keys) || body.keys.length === 0) throw new Error("empty jwks");
|
|
275
278
|
jwksCache = {
|
|
279
|
+
href,
|
|
276
280
|
value: body,
|
|
277
281
|
expiresAt: now + clampTtl(cacheControlMaxAge(response.headers.get("cache-control")) ?? maxTtl, minTtl, maxTtl)
|
|
278
282
|
};
|
|
@@ -281,9 +285,10 @@ function createKeyCache(options) {
|
|
|
281
285
|
jwks: body
|
|
282
286
|
};
|
|
283
287
|
} catch {
|
|
284
|
-
|
|
288
|
+
const stale = cachedJwks(href, now);
|
|
289
|
+
if (stale !== void 0) return {
|
|
285
290
|
ok: true,
|
|
286
|
-
jwks:
|
|
291
|
+
jwks: stale
|
|
287
292
|
};
|
|
288
293
|
return {
|
|
289
294
|
ok: false,
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { t as packageRoot } from "./package-root-zGkxO3oN.js";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
//#region src/cli/version.ts
|
|
5
|
+
function cliVersion() {
|
|
6
|
+
return JSON.parse(readFileSync(join(packageRoot(), "package.json"), "utf8")).version;
|
|
7
|
+
}
|
|
8
|
+
function generatorBanner() {
|
|
9
|
+
return `permdock@${cliVersion()}`;
|
|
10
|
+
}
|
|
11
|
+
const CATALOG_SCHEMA = "https://permdock.com/schemas/catalog-v1.json";
|
|
12
|
+
const SUPABASE_MANIFEST_SCHEMA = "https://permdock.com/schemas/supabase-manifest-v1.json";
|
|
13
|
+
const USAGE_REPORT_SCHEMA = "https://permdock.com/schemas/usage-report-v1.json";
|
|
14
|
+
const DOCTOR_REPORT_SCHEMA = "https://permdock.com/schemas/doctor-report-v1.json";
|
|
15
|
+
const CONFIG_REPORT_SCHEMA = "https://permdock.com/schemas/config-report-v1.json";
|
|
16
|
+
//#endregion
|
|
17
|
+
export { USAGE_REPORT_SCHEMA as a, SUPABASE_MANIFEST_SCHEMA as i, CONFIG_REPORT_SCHEMA as n, cliVersion as o, DOCTOR_REPORT_SCHEMA as r, generatorBanner as s, CATALOG_SCHEMA as t };
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
//#region src/client/views.ts
|
|
2
|
+
function permissionSet(store, permissions, data) {
|
|
3
|
+
const granted = [];
|
|
4
|
+
const byKey = {};
|
|
5
|
+
for (const permission of permissions) {
|
|
6
|
+
const state = store.permissionState(permission, data);
|
|
7
|
+
byKey[permission.key] = state;
|
|
8
|
+
if (state.allowed) granted.push(permission);
|
|
9
|
+
}
|
|
10
|
+
return new Proxy({
|
|
11
|
+
granted,
|
|
12
|
+
get(permission) {
|
|
13
|
+
return byKey[permission.key];
|
|
14
|
+
}
|
|
15
|
+
}, { get(target, prop, receiver) {
|
|
16
|
+
if (typeof prop === "string" && Object.hasOwn(byKey, prop)) return byKey[prop];
|
|
17
|
+
return Reflect.get(target, prop, receiver);
|
|
18
|
+
} });
|
|
19
|
+
}
|
|
20
|
+
function filterResult(permdock, permission, rows) {
|
|
21
|
+
const result = permdock.filter(permission, rows);
|
|
22
|
+
result.partial = permdock.where(permission).partial;
|
|
23
|
+
return result;
|
|
24
|
+
}
|
|
25
|
+
function tenantView(permdock) {
|
|
26
|
+
return {
|
|
27
|
+
tenant: permdock.subject.principal?.tenant ?? null,
|
|
28
|
+
tenants: permdock.tenants(),
|
|
29
|
+
switchTo: (id) => permdock.refresh({ tenant: id }),
|
|
30
|
+
status: permdock.status()
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function rolesView(permdock, options) {
|
|
34
|
+
return { roles: (options.team === void 0 ? permdock : permdock.team(options.team)).heldRoles(options.tenant === void 0 ? void 0 : { tenant: options.tenant }) };
|
|
35
|
+
}
|
|
36
|
+
function subjectView(permdock) {
|
|
37
|
+
const snapshot = permdock.snapshot();
|
|
38
|
+
return {
|
|
39
|
+
principal: permdock.subject.principal,
|
|
40
|
+
actor: permdock.subject.actor,
|
|
41
|
+
delegation: permdock.subject.delegation,
|
|
42
|
+
expiresAt: permdock.subject.expiresAt,
|
|
43
|
+
simulated: typeof snapshot === "object" && snapshot !== null && "simulated" in snapshot && snapshot.simulated === true
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/** The root's view of another tenant for a `Protected` with a `tenant` prop; `undefined` answers the active one. */
|
|
47
|
+
function scopedTenant(root, tenant) {
|
|
48
|
+
return tenant === void 0 ? void 0 : root.tenant(tenant);
|
|
49
|
+
}
|
|
50
|
+
/** An instance whose every read answers from `current()`, so a held reference follows the store. */
|
|
51
|
+
function livePermDock(current) {
|
|
52
|
+
return new Proxy({}, { get(_target, prop, _receiver) {
|
|
53
|
+
return Reflect.get(current(), prop);
|
|
54
|
+
} });
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* `local` answers the active tenant; `scoped`, the root's view of another
|
|
58
|
+
* tenant, is decided on the spot and shares the root's `pending` and `stale`.
|
|
59
|
+
*/
|
|
60
|
+
function protectedView(local, root, permission, data, scoped) {
|
|
61
|
+
const state = scoped === void 0 ? local : decideIn(root, scoped, permission, data);
|
|
62
|
+
if (state.status === "pending") return {
|
|
63
|
+
...state,
|
|
64
|
+
slot: "pending"
|
|
65
|
+
};
|
|
66
|
+
const decision = state.decision;
|
|
67
|
+
if (!state.allowed || decision.outcome !== "granted") return {
|
|
68
|
+
...state,
|
|
69
|
+
slot: "fallback"
|
|
70
|
+
};
|
|
71
|
+
return {
|
|
72
|
+
allowed: true,
|
|
73
|
+
status: state.status,
|
|
74
|
+
decision,
|
|
75
|
+
slot: "default"
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function decideIn(root, scoped, permission, data) {
|
|
79
|
+
const decision = scoped.decide(permission, data);
|
|
80
|
+
const status = root.status();
|
|
81
|
+
return {
|
|
82
|
+
allowed: decision.outcome === "granted",
|
|
83
|
+
status: status === "pending" || status === "stale" ? status : "ready",
|
|
84
|
+
decision
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function approvalHandle(store, decision) {
|
|
88
|
+
return {
|
|
89
|
+
state: store.approvalState(decision),
|
|
90
|
+
token: decision.outcome === "approval-required" ? decision.token : void 0,
|
|
91
|
+
request: (note) => store.requestApproval(decision, note)
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
//#endregion
|
|
95
|
+
export { protectedView as a, subjectView as c, permissionSet as i, tenantView as l, filterResult as n, rolesView as o, livePermDock as r, scopedTenant as s, approvalHandle as t };
|
package/dist/vue/index.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { r as Role } from "../vocabulary-
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
1
|
+
import { Ft as TokenVerifier, Mr as Membership, Tt as Snapshot, Yn as Decision } from "../policy-IB6yxpC3.js";
|
|
2
|
+
import { f as Permission } from "../permissions-DttnqqxC.js";
|
|
3
|
+
import { r as Role } from "../vocabulary-DA8a8zif.js";
|
|
4
|
+
import { n as requiredPlans } from "../problem-details-DX075l9V.js";
|
|
5
|
+
import { i as describe } from "../describe-DMYiCjJV.js";
|
|
6
|
+
import { t as PermissionBoundaryState } from "../boundary-BmHxVH1J.js";
|
|
7
|
+
import { t as approvalHeaders } from "../headers-Cf-zWvsO.js";
|
|
8
|
+
import { a as FilterResult, c as SubjectView, i as ClientStatus, l as TenantView, n as ApprovalState, o as PermissionSet, r as ClientPermDock, s as PermissionState, t as ApprovalHandle, u as UseRolesOptions } from "../types-CKNSyIf_.js";
|
|
7
9
|
import { ComputedRef, DefineComponent, MaybeRefOrGetter, Plugin } from "vue";
|
|
8
10
|
//#region src/vue/types.d.ts
|
|
9
11
|
type PermDockPluginOptions = {
|
|
@@ -13,13 +15,22 @@ type PermDockPluginOptions = {
|
|
|
13
15
|
* `setup` under `<Suspense>`).
|
|
14
16
|
*/
|
|
15
17
|
readonly snapshot: MaybeRefOrGetter<Snapshot | string> | PromiseLike<Snapshot | string>;
|
|
16
|
-
|
|
18
|
+
/**
|
|
19
|
+
* The AuthZEN evaluations endpoint for checks the snapshot cannot answer.
|
|
20
|
+
* `false` never calls one: such a check is denied with reason `server-only`.
|
|
21
|
+
*/
|
|
22
|
+
readonly endpoint?: string | false;
|
|
23
|
+
/** Where `refresh()` fetches a fresh snapshot. Defaults to `endpoint`. */
|
|
24
|
+
readonly snapshotUrl?: string;
|
|
17
25
|
readonly approvals?: string;
|
|
18
|
-
|
|
26
|
+
/** A ref or getter switches the active tenant (`refresh({ tenant })`) when it changes. */
|
|
27
|
+
readonly tenant?: MaybeRefOrGetter<string | undefined>;
|
|
19
28
|
readonly fetch?: typeof fetch;
|
|
20
|
-
|
|
29
|
+
/** Read on every request: a ref or getter carries a rotated token without rebuilding the store. */
|
|
30
|
+
readonly headers?: MaybeRefOrGetter<Readonly<Record<string, string>> | undefined>;
|
|
21
31
|
readonly maxAge?: number;
|
|
22
|
-
|
|
32
|
+
/** Read on every verification; set it at install to verify signed snapshots. */
|
|
33
|
+
readonly verifier?: MaybeRefOrGetter<TokenVerifier | undefined>;
|
|
23
34
|
};
|
|
24
35
|
//#endregion
|
|
25
36
|
//#region src/vue/composables.d.ts
|
|
@@ -37,12 +48,23 @@ export declare function useRoles(options?: MaybeRefOrGetter<UseRolesOptions>): C
|
|
|
37
48
|
readonly roles: readonly Role[];
|
|
38
49
|
}>;
|
|
39
50
|
export declare function useAssignableRoles(): ComputedRef<readonly Role[]>;
|
|
40
|
-
export declare function useAssignablePermissions(options?: {
|
|
51
|
+
export declare function useAssignablePermissions(options?: MaybeRefOrGetter<{
|
|
41
52
|
readonly tenant?: string;
|
|
42
|
-
}): ComputedRef<readonly Permission[]>;
|
|
53
|
+
}>): ComputedRef<readonly Permission[]>;
|
|
43
54
|
export declare function useSubject(): ComputedRef<SubjectView>;
|
|
44
55
|
export declare function useApproval(decision: MaybeRefOrGetter<Decision>): ComputedRef<ApprovalHandle>;
|
|
45
56
|
//#endregion
|
|
57
|
+
//#region src/vue/boundary.d.ts
|
|
58
|
+
/**
|
|
59
|
+
* Catches `PermDockDeniedError` and `PermDockApprovalRequiredError` thrown
|
|
60
|
+
* by a descendant and renders the `denied` slot, or the `approval` slot for
|
|
61
|
+
* an approval request (default `denied`). The slots receive the refused
|
|
62
|
+
* permission and `retry()`. Any other error propagates.
|
|
63
|
+
*/
|
|
64
|
+
export declare const PermissionBoundary: DefineComponent;
|
|
65
|
+
/** Inside a `PermissionBoundary`: what was refused and `retry()`, or `null` while the children render. */
|
|
66
|
+
export declare function usePermissionBoundary(): PermissionBoundaryState | null;
|
|
67
|
+
//#endregion
|
|
46
68
|
//#region src/vue/plugin.d.ts
|
|
47
69
|
export declare const permdockPlugin: Plugin<PermDockPluginOptions>;
|
|
48
70
|
//#endregion
|
|
@@ -54,4 +76,4 @@ type ProtectedProps = {
|
|
|
54
76
|
};
|
|
55
77
|
export declare const Protected: DefineComponent<ProtectedProps>;
|
|
56
78
|
//#endregion
|
|
57
|
-
export { type ApprovalHandle, type ApprovalState, type ClientPermDock, type ClientStatus, type FilterResult, type PermDockPluginOptions, type PermissionSet, type PermissionState, type SubjectView, type TenantView, type UseRolesOptions, approvalHeaders, describe, requiredPlans };
|
|
79
|
+
export { type ApprovalHandle, type ApprovalState, type ClientPermDock, type ClientStatus, type FilterResult, type PermDockPluginOptions, type PermissionBoundaryState, type PermissionSet, type PermissionState, type ProtectedProps, type SubjectView, type TenantView, type UseRolesOptions, approvalHeaders, describe, requiredPlans };
|
package/dist/vue/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { t as
|
|
4
|
-
import {
|
|
5
|
-
import { t as
|
|
6
|
-
import { t as
|
|
7
|
-
import {
|
|
1
|
+
import { r as requiredPlans } from "../problem-details-_AMOYz-w.js";
|
|
2
|
+
import { t as describe } from "../describe-B_gVZEVi.js";
|
|
3
|
+
import { t as approvalHeaders } from "../headers-BZSDieNT.js";
|
|
4
|
+
import { i as isPromiseLike } from "../store-options-ByhZq1jV.js";
|
|
5
|
+
import { a as protectedView, c as subjectView, i as permissionSet, l as tenantView, n as filterResult, o as rolesView, r as livePermDock, s as scopedTenant, t as approvalHandle } from "../views-Soe7bGSC.js";
|
|
6
|
+
import { n as boundaryFallback, t as boundaryDigest } from "../boundary-BM8a_P6E.js";
|
|
7
|
+
import { n as switchTenant, t as providerStore } from "../provider-store-Cfbvo4DE.js";
|
|
8
|
+
import { computed, defineComponent, effectScope, getCurrentScope, inject, isRef, onErrorCaptured, onScopeDispose, provide, shallowRef, toValue, watch } from "vue";
|
|
8
9
|
//#region src/vue/context.ts
|
|
9
10
|
const permDockKey = Symbol("permdock");
|
|
10
11
|
//#endregion
|
|
@@ -15,6 +16,7 @@ function useStore() {
|
|
|
15
16
|
return store;
|
|
16
17
|
}
|
|
17
18
|
function useTick(store) {
|
|
19
|
+
if (getCurrentScope() === void 0) throw new Error("PermDock: call composables in setup() or an effectScope, which removes their store subscription.");
|
|
18
20
|
const tick = shallowRef(0);
|
|
19
21
|
onScopeDispose(store.subscribe(() => {
|
|
20
22
|
tick.value += 1;
|
|
@@ -26,9 +28,7 @@ function useTick(store) {
|
|
|
26
28
|
}
|
|
27
29
|
function usePermDock() {
|
|
28
30
|
const permdock = useTick(useStore());
|
|
29
|
-
return
|
|
30
|
-
return Reflect.get(permdock.value, prop);
|
|
31
|
-
} });
|
|
31
|
+
return livePermDock(() => permdock.value);
|
|
32
32
|
}
|
|
33
33
|
function usePermission(permission, data) {
|
|
34
34
|
const store = useStore();
|
|
@@ -48,40 +48,16 @@ function usePermissions(permissions, data) {
|
|
|
48
48
|
const permdock = useTick(store);
|
|
49
49
|
return computed(() => {
|
|
50
50
|
permdock.value;
|
|
51
|
-
|
|
52
|
-
const byKey = {};
|
|
53
|
-
for (const permission of toValue(permissions)) {
|
|
54
|
-
const next = store.permissionState(permission, toValue(data));
|
|
55
|
-
byKey[permission.key] = next;
|
|
56
|
-
if (next.allowed) granted.push(permission);
|
|
57
|
-
}
|
|
58
|
-
return new Proxy({
|
|
59
|
-
granted,
|
|
60
|
-
get(permission) {
|
|
61
|
-
return byKey[permission.key];
|
|
62
|
-
}
|
|
63
|
-
}, { get(target, prop, receiver) {
|
|
64
|
-
if (typeof prop === "string" && Object.hasOwn(byKey, prop)) return byKey[prop];
|
|
65
|
-
return Reflect.get(target, prop, receiver);
|
|
66
|
-
} });
|
|
51
|
+
return permissionSet(store, toValue(permissions), toValue(data));
|
|
67
52
|
});
|
|
68
53
|
}
|
|
69
54
|
function useFilter(permission, rows) {
|
|
70
55
|
const permdock = useTick(useStore());
|
|
71
|
-
return computed(() =>
|
|
72
|
-
const result = [...permdock.value.filter(permission, toValue(rows))];
|
|
73
|
-
result.partial = permdock.value.where(permission).partial;
|
|
74
|
-
return result;
|
|
75
|
-
});
|
|
56
|
+
return computed(() => filterResult(permdock.value, permission, toValue(rows)));
|
|
76
57
|
}
|
|
77
58
|
function useTenant() {
|
|
78
59
|
const permdock = useTick(useStore());
|
|
79
|
-
return computed(() => (
|
|
80
|
-
tenant: permdock.value.subject.principal?.tenant ?? null,
|
|
81
|
-
tenants: permdock.value.tenants(),
|
|
82
|
-
switchTo: (id) => permdock.value.refresh({ tenant: id }),
|
|
83
|
-
status: permdock.value.status()
|
|
84
|
-
}));
|
|
60
|
+
return computed(() => tenantView(permdock.value));
|
|
85
61
|
}
|
|
86
62
|
function useMemberships() {
|
|
87
63
|
const permdock = useTick(useStore());
|
|
@@ -89,10 +65,7 @@ function useMemberships() {
|
|
|
89
65
|
}
|
|
90
66
|
function useRoles(options = {}) {
|
|
91
67
|
const permdock = useTick(useStore());
|
|
92
|
-
return computed(() =>
|
|
93
|
-
const next = toValue(options);
|
|
94
|
-
return { roles: (next.team === void 0 ? permdock.value : permdock.value.team(next.team)).heldRoles(next.tenant === void 0 ? void 0 : { tenant: next.tenant }) };
|
|
95
|
-
});
|
|
68
|
+
return computed(() => rolesView(permdock.value, toValue(options)));
|
|
96
69
|
}
|
|
97
70
|
function useAssignableRoles() {
|
|
98
71
|
const permdock = useTick(useStore());
|
|
@@ -100,62 +73,86 @@ function useAssignableRoles() {
|
|
|
100
73
|
}
|
|
101
74
|
function useAssignablePermissions(options = {}) {
|
|
102
75
|
const permdock = useTick(useStore());
|
|
103
|
-
return computed(() => permdock.value.assignablePermissions(options));
|
|
76
|
+
return computed(() => permdock.value.assignablePermissions(toValue(options)));
|
|
104
77
|
}
|
|
105
78
|
function useSubject() {
|
|
106
79
|
const permdock = useTick(useStore());
|
|
107
|
-
return computed(() =>
|
|
108
|
-
const snapshot = permdock.value.snapshot();
|
|
109
|
-
const simulated = typeof snapshot === "object" && snapshot !== null && "simulated" in snapshot && snapshot.simulated === true;
|
|
110
|
-
return {
|
|
111
|
-
principal: permdock.value.subject.principal,
|
|
112
|
-
actor: permdock.value.subject.actor,
|
|
113
|
-
delegation: permdock.value.subject.delegation,
|
|
114
|
-
expiresAt: permdock.value.subject.expiresAt,
|
|
115
|
-
simulated
|
|
116
|
-
};
|
|
117
|
-
});
|
|
80
|
+
return computed(() => subjectView(permdock.value));
|
|
118
81
|
}
|
|
119
82
|
function useApproval(decision) {
|
|
120
83
|
const store = useStore();
|
|
121
84
|
const permdock = useTick(store);
|
|
122
85
|
return computed(() => {
|
|
123
86
|
permdock.value;
|
|
124
|
-
|
|
125
|
-
return {
|
|
126
|
-
state: store.approvalState(next),
|
|
127
|
-
token: next.outcome === "approval-required" ? next.token : void 0,
|
|
128
|
-
request: (note) => store.requestApproval(next, note)
|
|
129
|
-
};
|
|
87
|
+
return approvalHandle(store, toValue(decision));
|
|
130
88
|
});
|
|
131
89
|
}
|
|
132
90
|
//#endregion
|
|
91
|
+
//#region src/vue/boundary.ts
|
|
92
|
+
const boundaryKey = Symbol("permdock-boundary");
|
|
93
|
+
/**
|
|
94
|
+
* Catches `PermDockDeniedError` and `PermDockApprovalRequiredError` thrown
|
|
95
|
+
* by a descendant and renders the `denied` slot, or the `approval` slot for
|
|
96
|
+
* an approval request (default `denied`). The slots receive the refused
|
|
97
|
+
* permission and `retry()`. Any other error propagates.
|
|
98
|
+
*/
|
|
99
|
+
const PermissionBoundary = defineComponent({
|
|
100
|
+
name: "PermissionBoundary",
|
|
101
|
+
setup(_props, { slots }) {
|
|
102
|
+
const state = shallowRef(null);
|
|
103
|
+
provide(boundaryKey, state);
|
|
104
|
+
onErrorCaptured((error) => {
|
|
105
|
+
const digest = boundaryDigest(error);
|
|
106
|
+
if (digest === null) return;
|
|
107
|
+
state.value = {
|
|
108
|
+
...digest,
|
|
109
|
+
retry: () => {
|
|
110
|
+
state.value = null;
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
return false;
|
|
114
|
+
});
|
|
115
|
+
return () => {
|
|
116
|
+
const current = state.value;
|
|
117
|
+
if (current === null) return slots["default"]?.() ?? null;
|
|
118
|
+
return boundaryFallback(current, {
|
|
119
|
+
denied: slots["denied"],
|
|
120
|
+
approval: slots["approval"]
|
|
121
|
+
})?.(current) ?? null;
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
/** Inside a `PermissionBoundary`: what was refused and `retry()`, or `null` while the children render. */
|
|
126
|
+
function usePermissionBoundary() {
|
|
127
|
+
return inject(boundaryKey, null)?.value ?? null;
|
|
128
|
+
}
|
|
129
|
+
//#endregion
|
|
133
130
|
//#region src/vue/plugin.ts
|
|
134
131
|
const permdockPlugin = { install(app, options) {
|
|
135
132
|
const source = options.snapshot;
|
|
136
133
|
const promised = isPromiseLike(source);
|
|
137
|
-
const store =
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
134
|
+
const store = providerStore({
|
|
135
|
+
...options,
|
|
136
|
+
tenant: toValue(options.tenant)
|
|
137
|
+
}, () => ({
|
|
138
|
+
headers: toValue(options.headers),
|
|
142
139
|
fetch: options.fetch,
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
const scope = effectScope(true);
|
|
150
|
-
scope.run(() => {
|
|
151
|
-
watch(() => toValue(source), (next) => {
|
|
152
|
-
store.replace(next);
|
|
153
|
-
});
|
|
140
|
+
verifier: toValue(options.verifier)
|
|
141
|
+
}), promised ? source : toValue(source));
|
|
142
|
+
const scope = effectScope(true);
|
|
143
|
+
scope.run(() => {
|
|
144
|
+
if (!promised && (isRef(source) || typeof source === "function")) watch(() => toValue(source), (next) => {
|
|
145
|
+
store.replace(next);
|
|
154
146
|
});
|
|
155
|
-
|
|
156
|
-
|
|
147
|
+
const tenant = options.tenant;
|
|
148
|
+
if (isRef(tenant) || typeof tenant === "function") watch(() => toValue(tenant), (next) => {
|
|
149
|
+
switchTenant(store, next);
|
|
157
150
|
});
|
|
158
|
-
}
|
|
151
|
+
});
|
|
152
|
+
app.onUnmount(() => {
|
|
153
|
+
scope.stop();
|
|
154
|
+
store.dispose();
|
|
155
|
+
});
|
|
159
156
|
app.provide(permDockKey, store);
|
|
160
157
|
} };
|
|
161
158
|
//#endregion
|
|
@@ -168,7 +165,7 @@ const Protected = defineComponent({
|
|
|
168
165
|
required: true
|
|
169
166
|
},
|
|
170
167
|
data: {
|
|
171
|
-
type:
|
|
168
|
+
type: null,
|
|
172
169
|
required: false
|
|
173
170
|
},
|
|
174
171
|
tenant: {
|
|
@@ -179,25 +176,21 @@ const Protected = defineComponent({
|
|
|
179
176
|
setup(props, { slots }) {
|
|
180
177
|
const local = usePermission(() => props.permission, () => props.data);
|
|
181
178
|
const root = usePermDock();
|
|
179
|
+
const scoped = computed(() => scopedTenant(root, props.tenant));
|
|
182
180
|
return () => {
|
|
183
|
-
const
|
|
181
|
+
const view = protectedView({
|
|
184
182
|
allowed: local.allowed.value,
|
|
185
183
|
status: local.status.value,
|
|
186
184
|
decision: local.decision.value
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
185
|
+
}, root, props.permission, props.data, scoped.value);
|
|
186
|
+
switch (view.slot) {
|
|
187
|
+
case "pending": return slots["pending"]?.() ?? null;
|
|
188
|
+
case "fallback": return slots["fallback"]?.({ decision: view.decision }) ?? null;
|
|
189
|
+
case "default": return slots["default"]?.({ decision: view.decision }) ?? null;
|
|
190
|
+
default: return view;
|
|
191
|
+
}
|
|
191
192
|
};
|
|
192
193
|
}
|
|
193
194
|
});
|
|
194
|
-
function tenantView(permdock, permission, data) {
|
|
195
|
-
const decision = permdock.decide(permission, data);
|
|
196
|
-
return {
|
|
197
|
-
allowed: decision.outcome === "granted",
|
|
198
|
-
status: "ready",
|
|
199
|
-
decision
|
|
200
|
-
};
|
|
201
|
-
}
|
|
202
195
|
//#endregion
|
|
203
|
-
export { Protected, approvalHeaders, describe, permdockPlugin, requiredPlans, useApproval, useAssignablePermissions, useAssignableRoles, useFilter, useMemberships, usePermDock, usePermission, usePermissions, useRoles, useSubject, useTenant };
|
|
196
|
+
export { PermissionBoundary, Protected, approvalHeaders, describe, permdockPlugin, requiredPlans, useApproval, useAssignablePermissions, useAssignableRoles, useFilter, useMemberships, usePermDock, usePermission, usePermissionBoundary, usePermissions, useRoles, useSubject, useTenant };
|