permdock 0.1.0 → 0.2.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-cmvX2jDe.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 +206 -0
- package/dist/better-supabase/index.js +620 -0
- package/dist/bind-CVy3Espv.d.ts +25 -0
- package/dist/bind-VnYn2HKq.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-B68OFnZx.js → capability-4qPdO9gk.js} +7 -5
- package/dist/{capability-BDG_nkxt.d.ts → capability-Dq43tT1u.d.ts} +2 -2
- package/dist/catalog/index.d.ts +1 -1
- package/dist/catalog/index.js +1 -1
- package/dist/catalog-BjZSovXQ.js +2 -0
- package/dist/{catalog-doc-BSo_Q_-6.js → catalog-doc-Dsc9y7sd.js} +23 -12
- package/dist/{catalog-B0E6bggc.js → catalog-h2tlKFkq.js} +2 -2
- package/dist/{catalog-H-vFGwWK.js → catalog-z8q6bi_r.js} +4 -4
- 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-BGhHS-lY.js} +2 -2
- package/dist/{cloud-Cuxr6Czw.js → cloud-Bo3e9Ak3.js} +7 -6
- package/dist/{collect-O-tOtbnk.js → collect-DDDv_ESs.js} +194 -42
- package/dist/collect-DLlujdHC.js +83 -0
- package/dist/collect-rG2IQ3t0.js +2 -0
- package/dist/{commands-BMh_Etm2.js → commands-DWOrSQic.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-CNnl6uIt.d.ts +94 -0
- package/dist/config-BJiM-xAm.js +157 -0
- package/dist/config-Bn00Z3ks.js +36 -0
- package/dist/config-report-Dw_JcUqT.js +44 -0
- package/dist/{connection-JvqwHODC.js → connection-CU8MQxRi.js} +1 -1
- package/dist/{context-CKEAabd7.js → context-Ttp0ekMT.js} +36 -27
- package/dist/convex/index.d.ts +9 -4
- package/dist/convex/index.js +14 -4
- package/dist/create-BWyx3jua.d.ts +245 -0
- package/dist/create-CPhDL6qx.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-PdoqESvg.d.ts} +9 -10
- package/dist/{diff-x5Il8LVa.js → diff-B8Tunc3o.js} +44 -11
- package/dist/{diff-BUzf5Poi.js → diff-CzqLxZ77.js} +2 -2
- package/dist/doctor-WpvG6p4k.js +1194 -0
- package/dist/doctor-collect-ByfYlNv1.js +664 -0
- package/dist/{doctor-Bqo6FwUa.js → doctor-rOr-4ZfS.js} +2 -2
- 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-DAqevpNk.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-C3sHpZNS.js} +65 -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-LF_hS-yn.d.ts → index-A0YNL8jZ.d.ts} +1 -1
- package/dist/index-CtE07CBF.d.ts +6 -0
- package/dist/{index-xIxJLwOQ.d.ts → index-D3vbkoSI.d.ts} +75 -7
- package/dist/{index-CltcQ4Bf.d.ts → index-D6_cSa1z.d.ts} +68 -5
- package/dist/index.d.ts +14 -9
- package/dist/index.js +22 -17
- package/dist/instance-options-BK_rNOSC.d.ts +11 -0
- package/dist/instance-options-Dhhcnm3y.js +22 -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-GSQnMz3O.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-CwePaF7C.js → openapi-Bbg4wGVL.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-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-BkGQNzAh.d.ts +10 -0
- package/dist/parse-local-manifest-BrMozJCo.js +36 -0
- package/dist/pdp/index.d.ts +2 -2
- package/dist/pdp/index.js +14 -127
- package/dist/{permdock-yoZ7EjxX.js → permdock-CzqXjCpU.js} +641 -126
- package/dist/{permissions-B8vCg_bI.d.ts → permissions-CDgvKG5L.d.ts} +2 -2
- package/dist/{permissions-CofRqesP.js → permissions-CpZrivYv.js} +3 -3
- package/dist/{permissions-DC7GROPA.js → permissions-DVoF6dMt.js} +77 -15
- package/dist/{permissions-B4apnahQ.d.ts → permissions-DttnqqxC.d.ts} +34 -5
- package/dist/{pins-CqE1jZuF.js → pins-8ILTftC9.js} +2 -2
- package/dist/{policy-CInmNGkM.d.ts → policy-CFZAr_Al.d.ts} +330 -37
- package/dist/{policy-Cq2fB8Q5.d.ts → policy-D8UFyERw.d.ts} +2 -2
- package/dist/{policy-ANp36PnI.js → policy-xyWg7QdR.js} +173 -22
- package/dist/powersync-A8x_Yyvh.js +2 -0
- package/dist/powersync-C7kLglqX.js +540 -0
- package/dist/powersync-yW1UUFzp.js +62 -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-CkL50EEf.d.ts +7 -0
- package/dist/problem-details-_AMOYz-w.js +144 -0
- package/dist/{protected-BuPAycJT.d.ts → protected-CNsMzrVd.d.ts} +5 -4
- package/dist/protected-Cs6kTaHo.js +100 -0
- package/dist/protected-bZs6rbT1.d.ts +40 -0
- package/dist/{provider-wTAUda2v.d.ts → provider-Cjr62YMV.d.ts} +1 -1
- package/dist/provider-DLzpb2Xz.js +52 -0
- package/dist/provider-store-DNyC1y48.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-sqBGMnNs.d.ts +5 -0
- package/dist/resource-ref-CaS9yVPi.js +20 -0
- package/dist/revocations-Bhr0aMIC.js +27 -0
- package/dist/rls-BMNydpHk.js +2521 -0
- package/dist/{rls-BOFU3chG.js → rls-CEvs64Kj.js} +8 -3
- package/dist/rls-fields-BMasREhR.js +3502 -0
- package/dist/{rls-graph-DxQ39PJj.js → rls-graph-pc9fuXYm.js} +100 -36
- package/dist/{rls-import-CXV6LBlS.js → rls-import-D8F7j35Q.js} +7 -6
- package/dist/{rls-migrate-DrFPbf8p.js → rls-migrate-7wikfrVI.js} +6 -5
- package/dist/rls-ownership-B5Lkq62W.js +843 -0
- package/dist/rls-shared-aOQ4hGTO.js +493 -0
- package/dist/rls-verify-D8B7dOTh.js +745 -0
- package/dist/{row-check-BajTgQZ-.d.ts → row-check-Dt35czLy.d.ts} +12 -15
- package/dist/rpc-DOK54_CS.js +89 -0
- package/dist/{run-CJ6UvS3a.js → run-YXCJDNYk.js} +31 -12
- package/dist/runtime-CB8gQFvS.js +11 -0
- package/dist/{saas-BRrZzJkM.js → saas-Bj_FFkjN.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-Gs6TTVa-.d.ts} +1 -1
- package/dist/skills-Biq5uup3.js +192 -0
- package/dist/{skills-C_lpV4Jx.js → skills-JaymNCdK.js} +10 -4
- package/dist/{snapshot-DE8dE_hz.js → snapshot-Enxd0n-s.js} +138 -214
- package/dist/snapshot-cache-D6jLelln.js +44 -0
- package/dist/snapshot-cache-DwQH8ufx.d.ts +45 -0
- package/dist/solid/index.d.ts +39 -9
- package/dist/solid/index.js +76 -85
- package/dist/sources-B0UvrJ21.js +534 -0
- package/dist/sources-BcJgw0lt.d.ts +192 -0
- package/dist/{sql-Bll1d7y0.js → sql-xdg5f4Fi.js} +6 -1
- package/dist/{src-CTNT-PBW.js → src-CSbUiozF.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-D_pjn91-.d.ts} +13 -4
- package/dist/store-options-yO0V6gRn.js +716 -0
- package/dist/{stores-CkG2HrSg.js → stores-4_sqiOA1.js} +10 -63
- package/dist/{stores-CvOnu_2T.d.ts → stores-DVR5NHLE.d.ts} +20 -9
- package/dist/{stream-Q_xlB6Ko.js → stream-DDpvynSB.js} +16 -2
- package/dist/{stream-BhMfZOwr.d.ts → stream-DlvG2hs-.d.ts} +2 -2
- package/dist/subject-settings-BwBmCdTR.js +128 -0
- package/dist/supabase/index.d.ts +122 -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-CwafwxxF.js} +3 -3
- package/dist/{supabase-DTxGtYdi.js → supabase-DTBaC20O.js} +345 -367
- package/dist/supabase-config-Bs44dare.js +472 -0
- package/dist/{supabase-hook-D_OqGb_V.js → supabase-hook-BuxLQLpU.js} +994 -708
- package/dist/supabase-hook-D5qVd_D8.js +2 -0
- package/dist/supautils-DYZnzRWV.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-9AWO9EGt.d.ts +197 -0
- package/dist/{types-D6Z6-rKJ.d.ts → types-BPxgszlT.d.ts} +260 -22
- package/dist/{types-BvBk1wgn.d.ts → types-BVyImy5I.d.ts} +5 -3
- package/dist/{types-CxquUByI.d.ts → types-Bvc4oWT6.d.ts} +1 -1
- package/dist/types-C3s9xVJG.d.ts +48 -0
- package/dist/{types-BBK-exvJ.d.ts → types-Dnemwd77.d.ts} +7 -1
- package/dist/types-kxznc7cn.d.ts +52 -0
- package/dist/{types-B8w5PFtS.d.ts → types-vKyAMtcX.d.ts} +17 -1
- package/dist/{types-B9dmiiab.d.ts → types-vNSDF7Dq.d.ts} +1 -1
- package/dist/{sources-DOpW5Ila.d.ts → types-yF5LmQVD.d.ts} +86 -127
- package/dist/unplugin/index.d.ts +1 -1
- package/dist/unplugin/index.js +10 -9
- package/dist/{usage-1ozMubLY.js → usage-D07N9QJ3.js} +2 -2
- package/dist/usage-D82l1CwK.js +2 -0
- package/dist/{usage-CUnK6Ou9.js → usage-DG1oeCca.js} +225 -62
- package/dist/validation-error-CnjZ4t92.js +33 -0
- package/dist/validation-error-CtF23SrC.d.ts +26 -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-Etoa_Mvr.js +2 -0
- package/dist/watch-UihESpsJ.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,38 +1,11 @@
|
|
|
1
1
|
import { n as isReadonlyArray, t as compact } from "./compact-y6vfu2_f.js";
|
|
2
|
-
import { n as freezeDeep } from "./freeze-
|
|
3
|
-
import {
|
|
4
|
-
import { u as coveredByDelegation } from "./snapshot-DE8dE_hz.js";
|
|
2
|
+
import { n as freezeDeep } from "./freeze-CrU8nQeX.js";
|
|
3
|
+
import { _ as listPermissions, a as formerKeys } from "./permissions-DVoF6dMt.js";
|
|
5
4
|
import { n as sha256, t as bytesToBase64Url } from "./sha256-BO0swRXL.js";
|
|
5
|
+
import { t as coveredByDelegation } from "./delegation-D8pUEuce.js";
|
|
6
6
|
import { t as anonymousSubject } from "./subject-C6dLxqHU.js";
|
|
7
|
-
import { a as ownRecord, n as idList, r as isId } from "./capability-
|
|
8
|
-
//#region src/core/revocations.ts
|
|
9
|
-
function isRevocationEvent(value) {
|
|
10
|
-
if (value === null || typeof value !== "object") return false;
|
|
11
|
-
const event = value;
|
|
12
|
-
return typeof event["principal"] === "string" && event["principal"].length > 0 && (event["kind"] === "session-revoked" || event["kind"] === "changed") && (event["session"] === void 0 || typeof event["session"] === "string") && (event["tenant"] === void 0 || typeof event["tenant"] === "string");
|
|
13
|
-
}
|
|
14
|
-
/** In-process feed; a multi-replica app bridges `revoke` to its own pub/sub. */
|
|
15
|
-
function memoryRevocationFeed() {
|
|
16
|
-
const listeners = /* @__PURE__ */ new Set();
|
|
17
|
-
return Object.freeze({
|
|
18
|
-
subscribe(listener) {
|
|
19
|
-
listeners.add(listener);
|
|
20
|
-
return () => {
|
|
21
|
-
listeners.delete(listener);
|
|
22
|
-
};
|
|
23
|
-
},
|
|
24
|
-
revoke(event) {
|
|
25
|
-
if (!isRevocationEvent(event)) throw new TypeError("PermDock: invalid revocation event.");
|
|
26
|
-
const frozen = Object.freeze({ ...event });
|
|
27
|
-
for (const listener of listeners) try {
|
|
28
|
-
listener(frozen);
|
|
29
|
-
} catch {}
|
|
30
|
-
}
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
//#endregion
|
|
7
|
+
import { a as ownRecord, n as idList, r as isId } from "./capability-4qPdO9gk.js";
|
|
34
8
|
//#region src/core/credential.ts
|
|
35
|
-
const MAX_ENTRIES = 64;
|
|
36
9
|
const MAX_NAME = 256;
|
|
37
10
|
function policies(policy) {
|
|
38
11
|
return isReadonlyArray(policy) ? policy : [policy];
|
|
@@ -52,7 +25,7 @@ function credentialPolicyViolation(credential, policy) {
|
|
|
52
25
|
}
|
|
53
26
|
}
|
|
54
27
|
function parsePermissions(value) {
|
|
55
|
-
if (!Array.isArray(value) || value.length === 0
|
|
28
|
+
if (!Array.isArray(value) || value.length === 0) return;
|
|
56
29
|
const out = [];
|
|
57
30
|
for (const item of value) {
|
|
58
31
|
const entry = ownRecord(item);
|
|
@@ -73,7 +46,7 @@ function isTime(value) {
|
|
|
73
46
|
* Validates an untrusted credential record and returns a frozen copy with
|
|
74
47
|
* only the v1 fields, or `undefined`. Unknown fields are dropped; a wrong
|
|
75
48
|
* type in a known field, a service credential without `tenant` and `roles`,
|
|
76
|
-
* or a user credential with
|
|
49
|
+
* or a user credential with `roles`, rejects the whole record.
|
|
77
50
|
*/
|
|
78
51
|
function parseCredential(input) {
|
|
79
52
|
const value = ownRecord(input);
|
|
@@ -90,7 +63,8 @@ function parseCredential(input) {
|
|
|
90
63
|
roles = idList(value["roles"]);
|
|
91
64
|
if (!isId(value["tenant"]) || roles === void 0) return;
|
|
92
65
|
tenant = value["tenant"];
|
|
93
|
-
} else if (value["
|
|
66
|
+
} else if (value["roles"] !== void 0 || value["tenant"] !== void 0 && !isId(value["tenant"])) return;
|
|
67
|
+
else tenant = value["tenant"];
|
|
94
68
|
return freezeDeep(compact({
|
|
95
69
|
v: 1,
|
|
96
70
|
id: value["id"],
|
|
@@ -145,7 +119,9 @@ function credentialDelegation(credential, permissions) {
|
|
|
145
119
|
* The subject a verified credential acts as. A `user` credential is its
|
|
146
120
|
* owner, passed live as `owner` (roles and memberships as of this request),
|
|
147
121
|
* with the credential's delegation: every check is the owner's rights
|
|
148
|
-
* intersected with the key's.
|
|
122
|
+
* intersected with the key's. One that names a `tenant` makes it the active
|
|
123
|
+
* tenant, and `createPermDock` then keeps only the owner's memberships
|
|
124
|
+
* inside it and no global role. A `service` credential is a `service`
|
|
149
125
|
* principal whose only membership is `roles` in `tenant`. An owner whose id
|
|
150
126
|
* is not the credential's `principal`, or who is not a user, is anonymous.
|
|
151
127
|
*/
|
|
@@ -158,11 +134,12 @@ function credentialSubject(credential, options) {
|
|
|
158
134
|
kind: "user"
|
|
159
135
|
};
|
|
160
136
|
if (owner.id !== credential.principal || owner.kind !== void 0 && owner.kind !== "user") return anonymousSubject();
|
|
161
|
-
principal = {
|
|
137
|
+
principal = compact({
|
|
162
138
|
...owner,
|
|
163
139
|
kind: "user",
|
|
140
|
+
tenant: credential.tenant ?? owner.tenant,
|
|
164
141
|
credential
|
|
165
|
-
};
|
|
142
|
+
});
|
|
166
143
|
} else {
|
|
167
144
|
const membership = compact({
|
|
168
145
|
tenant: credential.tenant,
|
|
@@ -210,7 +187,7 @@ function denied(reason, detail) {
|
|
|
210
187
|
});
|
|
211
188
|
}
|
|
212
189
|
function permissionEntries(request, declared) {
|
|
213
|
-
if (!isReadonlyArray(request.permissions) || request.permissions.length === 0
|
|
190
|
+
if (!isReadonlyArray(request.permissions) || request.permissions.length === 0) return;
|
|
214
191
|
const out = [];
|
|
215
192
|
for (const item of request.permissions) {
|
|
216
193
|
const entry = permissionEntry(item);
|
|
@@ -249,7 +226,7 @@ function checkRequest(permdock, request, now) {
|
|
|
249
226
|
id: request.id,
|
|
250
227
|
kind: request.kind,
|
|
251
228
|
principal: request.kind === "service" ? request.principal ?? request.id : creator.id,
|
|
252
|
-
tenant: request.
|
|
229
|
+
tenant: request.tenant,
|
|
253
230
|
roles: request.kind === "service" ? request.roles : void 0,
|
|
254
231
|
permissions: entries.map((entry) => compact({
|
|
255
232
|
permission: entry.leaf.key,
|
|
@@ -264,6 +241,9 @@ function checkRequest(permdock, request, now) {
|
|
|
264
241
|
if (credential.tenant !== void 0) {
|
|
265
242
|
const tenant = credential.tenant;
|
|
266
243
|
if (!permdock.tenants().includes(tenant)) return refuse("exceeds-creator", { tenant });
|
|
244
|
+
}
|
|
245
|
+
if (credential.kind === "service" && credential.tenant !== void 0) {
|
|
246
|
+
const tenant = credential.tenant;
|
|
267
247
|
const roles = new Set(permdock.assignableRoles({ tenant }).map((role) => role.key));
|
|
268
248
|
for (const name of credential.roles ?? []) if (!roles.has(name)) return refuse("exceeds-creator", { role: name });
|
|
269
249
|
const ceiling = new Set(permdock.assignablePermissions({ tenant }).map((leaf) => leaf.key));
|
|
@@ -275,8 +255,8 @@ function checkRequest(permdock, request, now) {
|
|
|
275
255
|
};
|
|
276
256
|
}
|
|
277
257
|
/**
|
|
278
|
-
* The tenant whose `credentials` policy governs a credential:
|
|
279
|
-
*
|
|
258
|
+
* The tenant whose `credentials` policy governs a credential: the key's own
|
|
259
|
+
* tenant, otherwise `active` (the creator's or the request's).
|
|
280
260
|
*/
|
|
281
261
|
function credentialTenant(credential, active) {
|
|
282
262
|
return credential.tenant ?? active;
|
|
@@ -285,11 +265,11 @@ function credentialTenant(credential, active) {
|
|
|
285
265
|
* Decides whether the subject of `permdock` may create the credential in
|
|
286
266
|
* `request`. The creator must be a signed-in user or service that is not
|
|
287
267
|
* itself a link or a credential; a delegated creator hands out only what its
|
|
288
|
-
* delegation covers. A
|
|
289
|
-
*
|
|
268
|
+
* delegation covers. A key's tenant must be one the creator is a member of;
|
|
269
|
+
* a service key's roles among the creator's `assignableRoles` there and its
|
|
290
270
|
* permissions within `assignablePermissions` there (`exceeds-creator`). The
|
|
291
|
-
* `credentials` policy of the key's tenant (
|
|
292
|
-
*
|
|
271
|
+
* `credentials` policy of the key's tenant (its own, or for a user key
|
|
272
|
+
* without one the creator's active tenant) then applies (`credential-policy`; a
|
|
293
273
|
* settings source that throws denies with `rule: 'unavailable'`), and
|
|
294
274
|
* `approval` makes the result `approval-required` until `approved` carries
|
|
295
275
|
* its token. PermDock never stores the credential; the application does,
|
|
@@ -323,4 +303,4 @@ async function decideCredential(permdock, request, options = {}) {
|
|
|
323
303
|
});
|
|
324
304
|
}
|
|
325
305
|
//#endregion
|
|
326
|
-
export { decideCredential as a, credentialTenant as i, credentialPolicyViolation as n, parseCredential as o, credentialSubject as r,
|
|
306
|
+
export { decideCredential as a, credentialTenant as i, credentialPolicyViolation as n, parseCredential as o, credentialSubject as r, credentialDelegation as t };
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { i as findPermission, o as formerScopes, t as annotationsFor } from "./permissions-DVoF6dMt.js";
|
|
2
|
+
import { d as matchGrantee, s as flattenGrantee } from "./grantee-Cv5Sogfv.js";
|
|
3
|
+
import { t as isActive } from "./validity-uOp8UpYn.js";
|
|
4
|
+
//#region src/core/delegation.ts
|
|
5
|
+
/** The permission's scope and any scope it was renamed from: tokens issued before a rename keep working. */
|
|
6
|
+
function scopeNames(permission) {
|
|
7
|
+
return [permission.scope, ...formerScopes(permission)];
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Whether a delegated caller may use a permission its principal holds, through
|
|
11
|
+
* OAuth `scopes`, RFC 9396 `authorizationDetails` or GNAP `access`.
|
|
12
|
+
* `undefined` means covered; otherwise the denial reason `decide` would add.
|
|
13
|
+
*/
|
|
14
|
+
function coveredByDelegation(permission, delegation, resourceId, hasActor = false) {
|
|
15
|
+
const unscoped = hasActor ? "no-delegation" : void 0;
|
|
16
|
+
if (delegation === void 0) return unscoped;
|
|
17
|
+
const hasScopes = delegation.scopes !== void 0;
|
|
18
|
+
const hasDetails = delegation.authorizationDetails !== void 0;
|
|
19
|
+
const hasAccess = delegation.access !== void 0;
|
|
20
|
+
if (!hasScopes && !hasDetails && !hasAccess) return unscoped;
|
|
21
|
+
const emptyScopes = hasScopes && (delegation.scopes?.length ?? 0) === 0;
|
|
22
|
+
const emptyAccess = hasAccess && (delegation.access?.length ?? 0) === 0;
|
|
23
|
+
if (emptyScopes && !hasDetails && !hasAccess) return "no-delegation";
|
|
24
|
+
if (emptyAccess && !hasScopes && !hasDetails) return "no-delegation";
|
|
25
|
+
if (emptyScopes && emptyAccess && !hasDetails) return "no-delegation";
|
|
26
|
+
const scopes = scopeNames(permission);
|
|
27
|
+
const scopeOk = delegation.scopes?.some((scope) => scopes.includes(scope)) ?? false;
|
|
28
|
+
const detailOk = delegation.authorizationDetails?.some((detail) => {
|
|
29
|
+
if (detail.type !== permission.resource) return false;
|
|
30
|
+
const identifier = detail["identifier"];
|
|
31
|
+
if (identifier !== void 0 && (typeof identifier !== "string" || identifier !== resourceId)) return false;
|
|
32
|
+
const actions = detail.actions;
|
|
33
|
+
if (actions === void 0) return true;
|
|
34
|
+
return Array.isArray(actions) && actions.includes(permission.action);
|
|
35
|
+
}) ?? false;
|
|
36
|
+
const accessOk = accessCovers(permission, delegation.access, resourceId);
|
|
37
|
+
if (scopeOk || detailOk || accessOk) return;
|
|
38
|
+
return "not-delegated";
|
|
39
|
+
}
|
|
40
|
+
function coversRequirements(tree, requires, delegation, resourceId, hasActor = false) {
|
|
41
|
+
return (requires ?? []).every((key) => {
|
|
42
|
+
const leaf = findPermission(tree, key);
|
|
43
|
+
return leaf !== void 0 && coveredByDelegation(leaf, delegation, resourceId, hasActor) === void 0;
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
function requiresStandIn(grant) {
|
|
47
|
+
return (grant.requires ?? []).length > 0 && annotationsFor(grant.permission).readOnlyHint && !flattenGrantee(grant.to).some((item) => item.kind === "role");
|
|
48
|
+
}
|
|
49
|
+
function accessCovers(permission, access, resourceId) {
|
|
50
|
+
if (access === void 0) return false;
|
|
51
|
+
return access.some((entry) => {
|
|
52
|
+
if (typeof entry === "string") return scopeNames(permission).includes(entry);
|
|
53
|
+
if (entry === null || typeof entry !== "object") return false;
|
|
54
|
+
const type = entry["type"];
|
|
55
|
+
if (typeof type !== "string" || !typeMatches(type, permission.resource)) return false;
|
|
56
|
+
const actions = entry["actions"];
|
|
57
|
+
if (actions !== void 0 && (!Array.isArray(actions) || !actions.includes(permission.action))) return false;
|
|
58
|
+
const identifier = entry["identifier"];
|
|
59
|
+
if (identifier !== void 0 && (typeof identifier !== "string" || identifier !== resourceId)) return false;
|
|
60
|
+
return true;
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
function typeMatches(type, resource) {
|
|
64
|
+
if (type === resource) return true;
|
|
65
|
+
return type.endsWith(`/${resource}`);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Whether the subject's principal is a `from` of the delegation: every item
|
|
69
|
+
* matches, with roles checked against the roles the principal holds here
|
|
70
|
+
* (`matchGrantee` leaves role holding to the caller) and nothing that needs a
|
|
71
|
+
* row.
|
|
72
|
+
*/
|
|
73
|
+
function handsOver(delegation, subject, heldRoles, now) {
|
|
74
|
+
const items = flattenGrantee(delegation.from);
|
|
75
|
+
if (items.length === 0 || subject.principal === null) return false;
|
|
76
|
+
return items.every((item) => {
|
|
77
|
+
if (item.kind === "role") return heldRoles.has(item.role);
|
|
78
|
+
if (item.kind === "relation") return false;
|
|
79
|
+
const match = matchGrantee(item, subject, now, void 0);
|
|
80
|
+
return match.matched && match.where === void 0;
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* The permission keys the policy's delegations let `subject.actor` use for
|
|
85
|
+
* `subject.principal` right now: the union over every active delegation whose
|
|
86
|
+
* `to` matches the actor and whose `from` the principal holds. `undefined`
|
|
87
|
+
* when none applies, so the call falls back to the token delegation alone.
|
|
88
|
+
* An actor with `readOnly: true` gets only each delegation's read-only keys.
|
|
89
|
+
* Attenuation only: a key here still needs a matching allow and no deny.
|
|
90
|
+
*/
|
|
91
|
+
function delegatedPermissions(delegations, subject, heldRoles, now) {
|
|
92
|
+
const actor = subject.actor;
|
|
93
|
+
if (actor === void 0 || delegations === void 0) return;
|
|
94
|
+
let keys;
|
|
95
|
+
for (const delegation of delegations) {
|
|
96
|
+
if (delegation.to.kind !== actor.kind || delegation.to.id !== void 0 && delegation.to.id !== actor.id || delegation.to.client !== void 0 && delegation.to.client !== actor.client || !isActive(delegation.validity, now) || !handsOver(delegation, subject, heldRoles, now)) continue;
|
|
97
|
+
keys ??= /* @__PURE__ */ new Set();
|
|
98
|
+
for (const key of actor.readOnly === true ? delegation.readOnly : delegation.permissions) keys.add(key);
|
|
99
|
+
}
|
|
100
|
+
return keys;
|
|
101
|
+
}
|
|
102
|
+
//#endregion
|
|
103
|
+
export { requiresStandIn as i, coversRequirements as n, delegatedPermissions as r, coveredByDelegation as t };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { i as flattenApprovers } from "./approvers-DT4AVyIg.js";
|
|
2
|
+
import { r as requiredPlans } from "./problem-details-_AMOYz-w.js";
|
|
3
3
|
//#region src/core/describe.ts
|
|
4
4
|
const TENANT_REASONS = /* @__PURE__ */ new Set([
|
|
5
5
|
"tenant-mismatch",
|
|
@@ -16,6 +16,7 @@ function labelGrantee(grantee) {
|
|
|
16
16
|
case "authenticated": return "an authenticated user";
|
|
17
17
|
case "anyone": return "anyone";
|
|
18
18
|
case "relation": return grantee.relation;
|
|
19
|
+
case "inherit": return grantee.permission;
|
|
19
20
|
case "assurance": {
|
|
20
21
|
const parts = [];
|
|
21
22
|
if (grantee.acr !== void 0 && grantee.acr.length > 0) parts.push(`acr ${grantee.acr.join("/")}`);
|
|
@@ -25,16 +26,6 @@ function labelGrantee(grantee) {
|
|
|
25
26
|
default: return grantee;
|
|
26
27
|
}
|
|
27
28
|
}
|
|
28
|
-
/**
|
|
29
|
-
* The plans named by the `not-entitled` denials of a decision, when every
|
|
30
|
-
* denial is `not-entitled`; otherwise empty, since a plan alone would not grant.
|
|
31
|
-
*/
|
|
32
|
-
function requiredPlans(decision) {
|
|
33
|
-
if (decision.outcome !== "denied" || decision.denials.length === 0 || decision.denials.some((denial) => denial.reason !== "not-entitled")) return [];
|
|
34
|
-
const plans = /* @__PURE__ */ new Set();
|
|
35
|
-
for (const denial of decision.denials) for (const item of flattenGrantee(denial.to)) if (item.kind === "plan") plans.add(item.plan);
|
|
36
|
-
return [...plans];
|
|
37
|
-
}
|
|
38
29
|
const TITLES = {
|
|
39
30
|
granted: "Granted",
|
|
40
31
|
denied: "Denied",
|
|
@@ -45,7 +36,10 @@ const TITLES = {
|
|
|
45
36
|
upgrade: "Upgrade required"
|
|
46
37
|
};
|
|
47
38
|
function labelApprover(approver) {
|
|
48
|
-
|
|
39
|
+
if (approver.kind === "user") return `user ${approver.id}`;
|
|
40
|
+
if (approver.kind === "permission") return `a holder of ${approver.permission}`;
|
|
41
|
+
if (approver.kind === "any-of") return `one of (${approver.of.map((entry) => flattenApprovers(entry).map(labelApprover).join(" and ")).join(", ")})`;
|
|
42
|
+
return labelGrantee(approver);
|
|
49
43
|
}
|
|
50
44
|
function approvers(approval) {
|
|
51
45
|
if (approval === void 0 || approval === "human") return [];
|
|
@@ -87,7 +81,8 @@ function describe(decision, options) {
|
|
|
87
81
|
};
|
|
88
82
|
const reasons = decision.denials.map((denial) => denial.reason);
|
|
89
83
|
const kind = reasons.some((reason) => TENANT_REASONS.has(reason)) ? "tenant" : reasons.some((reason) => DELEGATION_REASONS.has(reason)) ? "delegation" : reasons.includes("opaque-condition") || reasons.includes("server-only") ? "server-only" : "denied";
|
|
90
|
-
const
|
|
84
|
+
const texts = messages?.reasons;
|
|
85
|
+
const detail = reasons.map((reason) => (typeof texts === "function" ? texts(reason, decision) : texts?.[reason]) ?? reason).join(messages?.separator ?? ", ");
|
|
91
86
|
return {
|
|
92
87
|
kind,
|
|
93
88
|
title: titleOf(kind),
|
|
@@ -96,4 +91,4 @@ function describe(decision, options) {
|
|
|
96
91
|
};
|
|
97
92
|
}
|
|
98
93
|
//#endregion
|
|
99
|
-
export {
|
|
94
|
+
export { describe as t };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { Qn as DeniedDecision, Yn as Decision, Zn as DenialReason } from "./policy-CFZAr_Al.js";
|
|
2
|
+
import { f as Permission } from "./permissions-DttnqqxC.js";
|
|
3
3
|
//#region src/core/describe.d.ts
|
|
4
4
|
type DecisionDescription = {
|
|
5
5
|
readonly kind: "granted" | "denied" | "approval" | "tenant" | "delegation" | "server-only" | "upgrade";
|
|
@@ -9,19 +9,18 @@ type DecisionDescription = {
|
|
|
9
9
|
/** On `upgrade`: the plans any of which would grant the permission. */
|
|
10
10
|
readonly plans?: readonly string[];
|
|
11
11
|
};
|
|
12
|
-
/**
|
|
13
|
-
* The plans named by the `not-entitled` denials of a decision, when every
|
|
14
|
-
* denial is `not-entitled`; otherwise empty, since a plan alone would not grant.
|
|
15
|
-
*/
|
|
16
|
-
declare function requiredPlans(decision: Decision): readonly string[];
|
|
17
12
|
/**
|
|
18
13
|
* Localised text for `describe`. Every entry is optional and falls back to the
|
|
19
14
|
* English default; `kind` and `alternatives` never change.
|
|
20
15
|
*/
|
|
21
16
|
type DescribeMessages = {
|
|
22
17
|
readonly titles?: Partial<Record<DecisionDescription["kind"], string>>;
|
|
23
|
-
/**
|
|
24
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Text per denial reason; a denied detail joins the texts of its reasons
|
|
20
|
+
* with `separator`. The function form also sees the decision; `undefined`
|
|
21
|
+
* keeps the reason code, as a missing record entry does.
|
|
22
|
+
*/
|
|
23
|
+
readonly reasons?: Partial<Record<DenialReason, string>> | ((reason: DenialReason, decision: DeniedDecision) => string | undefined);
|
|
25
24
|
/** Joins denial reason texts. Default `', '`. */
|
|
26
25
|
readonly separator?: string;
|
|
27
26
|
readonly granted?: (permission: string) => string;
|
|
@@ -34,4 +33,4 @@ type DescribeOptions = {
|
|
|
34
33
|
};
|
|
35
34
|
declare function describe(decision: Decision, options?: DescribeOptions): DecisionDescription;
|
|
36
35
|
//#endregion
|
|
37
|
-
export {
|
|
36
|
+
export { describe as i, DescribeMessages as n, DescribeOptions as r, DecisionDescription as t };
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { i as findPermission } from "./permissions-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { t as createPermDock } from "./permdock-
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { n as fixtureSubject, r as loadFixtures, t as fixtureRow } from "./fixtures-
|
|
1
|
+
import { i as findPermission } from "./permissions-DVoF6dMt.js";
|
|
2
|
+
import { _ as memoryRoleSource } from "./src-CSbUiozF.js";
|
|
3
|
+
import { t as canonicalJson } from "./canonical-json-DemiK4Vp.js";
|
|
4
|
+
import { t as createPermDock } from "./permdock-CzqXjCpU.js";
|
|
5
|
+
import { o as usageResult } from "./errors-CWfoNg9N.js";
|
|
6
|
+
import { t as buildCatalog } from "./catalog-doc-Dsc9y7sd.js";
|
|
7
|
+
import { a as loadModule, n as asPolicy, o as pickNamed } from "./load-DhWEB9P1.js";
|
|
8
|
+
import { t as parseCatalog } from "./parse-BuyjxhZV.js";
|
|
9
|
+
import { n as fixtureSubject, r as loadFixtures, t as fixtureRow } from "./fixtures-ht28Cplr.js";
|
|
10
10
|
import { existsSync, readFileSync } from "node:fs";
|
|
11
11
|
import { resolve } from "node:path";
|
|
12
12
|
//#region src/cli/diff.ts
|
|
@@ -19,7 +19,8 @@ const EMPTY_SCAN = {
|
|
|
19
19
|
roleNames: [],
|
|
20
20
|
planNames: [],
|
|
21
21
|
allowKeys: [],
|
|
22
|
-
snapshots: []
|
|
22
|
+
snapshots: [],
|
|
23
|
+
unparsed: []
|
|
23
24
|
};
|
|
24
25
|
async function loadSide(cwd, source, now) {
|
|
25
26
|
const abs = resolve(cwd, source);
|
|
@@ -109,7 +110,8 @@ function delegationIdentity(delegation) {
|
|
|
109
110
|
});
|
|
110
111
|
}
|
|
111
112
|
function describeDelegation(delegation) {
|
|
112
|
-
const
|
|
113
|
+
const narrowed = delegation.to.id ?? delegation.to.client;
|
|
114
|
+
const to = narrowed === void 0 ? delegation.to.kind : `${delegation.to.kind} ${narrowed}`;
|
|
113
115
|
return `delegation ${canonicalJson(delegation.from)} → ${to} (${delegation.permissions.join(", ")})`;
|
|
114
116
|
}
|
|
115
117
|
function delegationChanges(before, after) {
|
|
@@ -187,6 +189,29 @@ function underNames(a, aliases) {
|
|
|
187
189
|
}
|
|
188
190
|
};
|
|
189
191
|
}
|
|
192
|
+
/** Levels of permissions on both sides, with `a`'s keys under `b`'s names. */
|
|
193
|
+
function diffLevels(a, b, aliases) {
|
|
194
|
+
const after = new Map(b.permissions.map((item) => [item.key, new Set(item.levels ?? [])]));
|
|
195
|
+
const before = new Map(a.permissions.map((item) => [aliases.get(item.key) ?? item.key, new Set(item.levels ?? [])]));
|
|
196
|
+
const added = [];
|
|
197
|
+
const removed = [];
|
|
198
|
+
for (const [permission, levels] of before) {
|
|
199
|
+
const kept = after.get(permission);
|
|
200
|
+
if (kept === void 0) continue;
|
|
201
|
+
for (const level of levels) if (!kept.has(level)) removed.push({
|
|
202
|
+
permission,
|
|
203
|
+
level
|
|
204
|
+
});
|
|
205
|
+
for (const level of kept) if (!levels.has(level)) added.push({
|
|
206
|
+
permission,
|
|
207
|
+
level
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
return {
|
|
211
|
+
added,
|
|
212
|
+
removed
|
|
213
|
+
};
|
|
214
|
+
}
|
|
190
215
|
function diffCatalogs(original, b) {
|
|
191
216
|
const breaking = [];
|
|
192
217
|
const aliasesA = aliasesOf(original.catalog);
|
|
@@ -219,6 +244,12 @@ function diffCatalogs(original, b) {
|
|
|
219
244
|
permission: to,
|
|
220
245
|
detail: `${old} no longer resolves to ${to}: stored custom roles, tokens and SQL that still name it now deny`
|
|
221
246
|
});
|
|
247
|
+
const levels = diffLevels(a.catalog, b.catalog, aliasesB);
|
|
248
|
+
for (const item of levels.removed) breaking.push({
|
|
249
|
+
kind: "level-removed",
|
|
250
|
+
permission: item.permission,
|
|
251
|
+
detail: `level ${item.level} of ${item.permission} no longer exists: stored custom roles that pick it now deny the permission`
|
|
252
|
+
});
|
|
222
253
|
const scopes = setDiff((a.catalog.scopes ?? []).map((scope) => scope.name), (b.catalog.scopes ?? []).map((scope) => scope.name));
|
|
223
254
|
for (const name of scopes.removed) breaking.push({
|
|
224
255
|
kind: "scope-removed",
|
|
@@ -301,6 +332,7 @@ function diffCatalogs(original, b) {
|
|
|
301
332
|
a: sideRef(a),
|
|
302
333
|
b: sideRef(b),
|
|
303
334
|
permissions,
|
|
335
|
+
levels,
|
|
304
336
|
scopes,
|
|
305
337
|
roles: {
|
|
306
338
|
...roleNames,
|
|
@@ -353,6 +385,7 @@ function formatText(diff) {
|
|
|
353
385
|
for (const item of changed) lines.push(` ~ ${item}`);
|
|
354
386
|
};
|
|
355
387
|
section("permissions", diff.permissions.added, diff.permissions.removed, diff.permissions.renamed.map((rename) => `${rename.from} → ${rename.to} (renamed)`));
|
|
388
|
+
section("levels", diff.levels.added.map((item) => `${item.permission}@${item.level}`), diff.levels.removed.map((item) => `${item.permission}@${item.level}`));
|
|
356
389
|
section("scopes", diff.scopes.added, diff.scopes.removed);
|
|
357
390
|
section("roles", diff.roles.added, diff.roles.removed, diff.roles.changed.map((name) => `${name}: declaration changed`));
|
|
358
391
|
if (diff.grants === void 0) lines.push("grants: not compared (a catalog was built without its policy; run `permdock collect` with `policy` configured)");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as globalArgs, s as stringArg, t as COMMAND_DESCRIPTIONS } from "./commands-
|
|
1
|
+
import { i as globalArgs, s as stringArg, t as COMMAND_DESCRIPTIONS } from "./commands-DWOrSQic.js";
|
|
2
2
|
import { defineCommand } from "citty";
|
|
3
3
|
//#region src/cli/commands/diff.ts
|
|
4
4
|
function diff(ctx) {
|
|
@@ -30,7 +30,7 @@ function diff(ctx) {
|
|
|
30
30
|
}
|
|
31
31
|
},
|
|
32
32
|
async run({ args: parsed }) {
|
|
33
|
-
const result = await (await import("./diff-
|
|
33
|
+
const result = await (await import("./diff-B8Tunc3o.js")).runDiff({
|
|
34
34
|
cwd: ctx.cwd,
|
|
35
35
|
config: ctx.config,
|
|
36
36
|
sources: parsed._,
|