permdock 0.4.0 → 0.5.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 +37 -35
- package/dist/{schema-Bol6gqXA.js → 2020-C9VN-x8c.js} +5 -130
- package/dist/a2a/index.d.ts +6 -6
- package/dist/a2a/index.js +14 -17
- package/dist/{adapter-context-mlWsVGGg.js → adapter-context-CRhqyzCk.js} +1 -1
- package/dist/adoption-scan-B4R5fnMU.js +107 -0
- package/dist/agent/index.d.ts +3 -0
- package/dist/agent/index.js +1 -0
- package/dist/ai-sdk/index.d.ts +18 -35
- package/dist/ai-sdk/index.js +37 -23
- package/dist/{app-data-CV8pqqMi.js → app-data-MuyzVqX8.js} +2 -1
- package/dist/approval-header-CJACtHkv.js +23 -0
- package/dist/approval-prompt-Dg5LeAcT.js +62 -0
- package/dist/approval-prompt-Djo_PyZc.d.ts +57 -0
- package/dist/approvals/index.d.ts +5 -3
- package/dist/approvals/index.js +8 -5
- package/dist/approvals-DJ6Yd5z1.js +995 -0
- package/dist/arazzo-B6lebmiQ.js +36 -0
- package/dist/{arazzo-C4BcskbX.js → arazzo-BWhNF-k0.js} +20 -14
- package/dist/args-IIolxxKA.js +197 -0
- package/dist/astro/index.d.ts +43 -0
- package/dist/astro/index.js +27 -0
- package/dist/audience-Dg8XsRaO.js +55 -0
- package/dist/auth-DRLEizbL.js +178 -0
- package/dist/authzen/index.d.ts +26 -6
- package/dist/authzen/index.js +94 -79
- package/dist/automation-BMZPIVUM.d.ts +114 -0
- package/dist/automation-DVjOckjV.js +157 -0
- package/dist/better-auth/index.d.ts +8 -6
- package/dist/better-auth/index.js +9 -8
- package/dist/better-supabase/index.d.ts +357 -30
- package/dist/better-supabase/index.js +936 -194
- package/dist/{bind-BzqG8SMb.d.ts → bind--9EFVYWF.d.ts} +12 -10
- package/dist/{bind-kk-uyCwH.js → bind-CZzhx-Vj.js} +14 -10
- package/dist/body-CH5of8Ne.js +10 -0
- package/dist/body-text-QcXok_SI.js +52 -0
- package/dist/{build-instance-DIIV9DbC.js → build-instance-BMnAudHn.js} +4 -3
- package/dist/{canonical-json-CFKyFOke.js → canonical-json-BC8_nMTw.js} +5 -3
- package/dist/{capability-CksyCWDH.d.ts → capability-BSslw1QV.d.ts} +44 -25
- package/dist/{capability-txATtKV4.js → capability-N1K9IpqS.js} +68 -42
- package/dist/casbin-Cr7RLtA3.js +30 -0
- package/dist/casbin-Dyu2gnUD.js +234 -0
- package/dist/casl-64gpT-8x.js +24 -0
- package/dist/casl-DjEDhTCP.js +299 -0
- package/dist/catalog/index.d.ts +74 -2
- package/dist/catalog/index.js +51 -2
- package/dist/{catalog-tZUyOfOv.js → catalog-BECMPrwc.js} +51 -6
- package/dist/catalog-DjhMYYCq.js +1 -0
- package/dist/catalog-R_A__RsH.js +52 -0
- package/dist/{catalog-doc-DWtg0gGR.js → catalog-doc-C9wjsfNY.js} +45 -23
- package/dist/catalog-fingerprint-CCP0-yQS.js +153 -0
- package/dist/chat/index.d.ts +2 -0
- package/dist/chat/index.js +224 -0
- package/dist/chat-sdk/index.d.ts +87 -0
- package/dist/chat-sdk/index.js +197 -0
- package/dist/claims-map-7oQ3ue4X.js +13 -0
- package/dist/claims-map-Ca-QX8C6.d.ts +32 -0
- package/dist/claude-agent/index.d.ts +7 -14
- package/dist/claude-agent/index.js +24 -27
- package/dist/clerk/index.d.ts +9 -8
- package/dist/clerk/index.js +9 -14
- package/dist/cli/bin.js +36 -17
- package/dist/cli/index.d.ts +19 -5
- package/dist/cli/index.js +164 -4
- package/dist/cloud/index.d.ts +102 -63
- package/dist/cloud/index.js +239 -340
- package/dist/cloud-CIoHNevm.js +87 -0
- package/dist/codemod-Bmj9dWMH.js +37 -0
- package/dist/codemod-Cxvvc70T.js +2084 -0
- package/dist/{collect-2SrB7lfk.js → collect-CrZJJnEF.js} +75 -11
- package/dist/collect-DloHbDVa.js +55 -0
- package/dist/collect-FlXJlhus.js +1 -0
- package/dist/command-L8EstFNm.js +6 -0
- package/dist/compile/index.d.ts +1 -1
- package/dist/compile/index.js +1 -2
- package/dist/{compile-CcEu2ZQ1.js → compile-CMqMx_IN.js} +11 -8
- package/dist/{compile-CtTP7eur.d.ts → compile-Ckm2HqBZ.d.ts} +5 -3
- package/dist/completion-BqhRBJD8.js +143 -0
- package/dist/config-B46rm9sc.js +26 -0
- package/dist/{config-BIjREpyE.js → config-bs_kZeYq.js} +12 -7
- package/dist/{config-report--Xb9APJS.js → config-report-DUgj62Ai.js} +15 -5
- package/dist/{connection-DUsczpB5.js → connection-DjhIJSs2.js} +6 -5
- package/dist/{context-DieZVJXu.js → context-bbFHR-0D.js} +2 -2
- package/dist/convex/index.d.ts +11 -10
- package/dist/convex/index.js +6 -4
- package/dist/create-0VZ7Pdiu.d.ts +107 -0
- package/dist/create-BDS7wc3y.d.ts +138 -0
- package/dist/create-BFfm17UA.d.ts +110 -0
- package/dist/create-BWRSXgOF.js +403 -0
- package/dist/create-C3b4B5eF.js +130 -0
- package/dist/{create-BBO24vj6.js → create-DnrmLnLW.js} +31 -32
- package/dist/{credential-kue0qpbm.js → credential-DM2um3ha.js} +152 -31
- package/dist/credentials-DPyHmYz5.js +74 -0
- package/dist/delegation-DaXVdDhM.js +286 -0
- package/dist/delivery/index.d.ts +5 -0
- package/dist/delivery/index.js +5 -0
- package/dist/delivery-DCAgNyCn.js +499 -0
- package/dist/delivery-event-xX4obB8F.js +40 -0
- package/dist/{denied-text-DfRk15uw.d.ts → denied-text-D8jDHgsl.d.ts} +5 -5
- package/dist/{describe-C3ldA9os.d.ts → describe-BZUsixiL.d.ts} +2 -2
- package/dist/{describe-Cgkp7eP0.js → describe-BybMRY7A.js} +6 -2
- package/dist/device-BARQ8eYG.js +193 -0
- package/dist/diff-CxZo9pTq.js +37 -0
- package/dist/{diff-rpqoe7Ag.js → diff-DCePiN6M.js} +60 -54
- package/dist/doctor-CxiwSfqH.js +44 -0
- package/dist/{doctor-owlv6ddh.js → doctor-DFjUxf2f.js} +245 -50
- package/dist/drizzle/index.d.ts +5 -3
- package/dist/drizzle/index.js +2 -2
- package/dist/elysia/index.d.ts +16 -13
- package/dist/elysia/index.js +13 -12
- package/dist/env-DJZrPjRi.js +8 -0
- package/dist/errors-BDUwg2qC.js +27 -0
- package/dist/{errors-drnfxYtm.js → errors-BKy0EfhN.js} +5 -9
- package/dist/errors-BWXBMaKK.d.ts +11 -0
- package/dist/{errors-OD_4c__H.d.ts → errors-C2PXIv4c.d.ts} +2 -2
- package/dist/errors-CWTY6uih.js +143 -0
- package/dist/evaluate-_R8QkWaf.js +1732 -0
- package/dist/evaluations-16UqqQ6W.d.ts +32 -0
- package/dist/{evaluations-C9YJsv3H.js → evaluations-DZ2CbV5k.js} +145 -34
- package/dist/eve/index.d.ts +12 -16
- package/dist/eve/index.js +22 -28
- package/dist/event-time-CsegxXxB.js +23 -0
- package/dist/expiry-D4_YKRKD.js +52 -0
- package/dist/express/index.d.ts +13 -10
- package/dist/express/index.js +12 -11
- package/dist/fastify/index.d.ts +25 -22
- package/dist/fastify/index.js +13 -12
- package/dist/fetch-adapter-g0ypLkID.js +120 -0
- package/dist/fetch-adapter-qKJBuRqy.d.ts +31 -0
- package/dist/fields-D9tPVUUS.js +203 -0
- package/dist/files-C5ZI27eV.js +124 -0
- package/dist/{fixtures-h2eG2OZV.js → fixtures-B7XrLeY7.js} +8 -7
- package/dist/flags-C3DktBDY.js +86 -0
- package/dist/{from-snapshot-7REQZe0H.js → from-snapshot-D2lZt4Dd.js} +55 -52
- package/dist/{grantee-CXY-0C87.js → grantee-Cn1HyUsI.js} +3 -3
- package/dist/{grantee-conditions-MQs5NIuX.js → grantee-conditions-CcXf8hMM.js} +4 -3
- package/dist/{grantee-match-fxYp9Nmt.js → grantee-match-DHArqY82.js} +5 -4
- package/dist/h3/index.d.ts +37 -0
- package/dist/h3/index.js +35 -0
- package/dist/headers-BIjfMaoC.js +8 -0
- package/dist/headers-CIbDTUTK.d.ts +7 -0
- package/dist/{helpers-C9YmyBIa.js → helpers-DTcZOzhF.js} +45 -38
- package/dist/hono/index.d.ts +12 -9
- package/dist/hono/index.js +13 -12
- package/dist/hosted-BZIAYvon.js +315 -0
- package/dist/hosted-DBDX0M-P.d.ts +78 -0
- package/dist/{http-DPuDaChb.d.ts → http-B_LphE5Y.d.ts} +1 -2
- package/dist/http-DXJ37RDA.js +46 -0
- package/dist/{http-BEbdMZ05.js → http-ujKm0JXE.js} +1 -2
- package/dist/{import-UHk1N7vH.js → import-CNV7I2Dw.js} +25 -20
- package/dist/{import-BFIlhetD.js → import-DMmOG27O.js} +190 -53
- package/dist/index-BcHcPyIo.d.ts +110 -0
- package/dist/index-CaxrMD1A.d.ts +1 -0
- package/dist/index-Chrs5fQ-.d.ts +210 -0
- package/dist/index-CxGUswIC.d.ts +431 -0
- package/dist/index-D8EovfsP.d.ts +91 -0
- package/dist/{index-UdVQgq48.d.ts → index-DOVf7RJv.d.ts} +431 -81
- package/dist/{index-BwMe94Xq.d.ts → index-SGdIQyzc.d.ts} +34 -16
- package/dist/index.d.ts +19 -15
- package/dist/index.js +31 -21
- package/dist/init-DeMYsnYJ.js +96 -0
- package/dist/init-GG6Jh8HD.js +95 -0
- package/dist/{instance-options-plkrsAog.d.ts → instance-options-Omfd793B.d.ts} +2 -2
- package/dist/instance-snapshot-Cxq4ygFc.js +600 -0
- package/dist/instant-BluqDvyS.js +19 -0
- package/dist/internals-Dk8A8fX3.js +17 -0
- package/dist/{json-schema-DBkdUuCO.js → json-schema-B-vAwlde.js} +45 -6
- package/dist/json-schema-CN_iLFH2.d.ts +40 -0
- package/dist/jwt/index.d.ts +18 -11
- package/dist/jwt/index.js +156 -135
- package/dist/{kernel-CB3LrIJM.js → kernel-5JatXyND.js} +52 -24
- package/dist/kysely/index.d.ts +5 -3
- package/dist/kysely/index.js +2 -2
- package/dist/load-BxEtwlBS.js +1 -0
- package/dist/{load-C3_oTHyO.js → load-DFS_ry0W.js} +22 -6
- package/dist/{load-jose-BL6LH4bL.js → load-jose-DZ4dnjri.js} +1 -4
- package/dist/login-Dfe5RlYk.js +68 -0
- package/dist/login-imhuwvn3.js +254 -0
- package/dist/manifest-C8IzW3Do.js +42 -0
- package/dist/manifest-CtKR3GXL.js +370 -0
- package/dist/manifest-json-CAGzls-C.js +9 -0
- package/dist/{manifest-uDS9y5de.d.ts → manifest-mx5ghSFM.d.ts} +9 -2
- package/dist/manifest-schema-C0kK_8V0.js +399 -0
- package/dist/{map-claims-AVlBaJoa.js → map-claims-D3oRmTk0.js} +13 -10
- package/dist/{map-error-BE27PYkE.js → map-error-TCAdw-eW.js} +3 -3
- package/dist/{markers-CiwAOZtO.js → markers-C6joDI3o.js} +2 -1
- package/dist/mcp/index.d.ts +22 -12
- package/dist/mcp/index.js +57 -39
- package/dist/{migrate-BwlB5-Wk.js → migrate-BShP7Vf4.js} +53 -14
- package/dist/nest/index.d.ts +12 -9
- package/dist/nest/index.js +15 -14
- package/dist/next/index.d.ts +18 -21
- package/dist/next/index.js +13 -11
- package/dist/next/plugin.d.ts +1 -1
- package/dist/next/plugin.js +2 -2
- package/dist/node/index.d.ts +10 -10
- package/dist/node/index.js +7 -9
- package/dist/{ocsf-uYFXGVw2.js → ocsf-BFp-PZZA.js} +22 -11
- package/dist/openai/index.d.ts +9 -16
- package/dist/openai/index.js +17 -24
- package/dist/openapi/index.d.ts +3 -3
- package/dist/openapi/index.js +1 -1
- package/dist/{openapi-DBzHQbov.js → openapi-B7HZ0f-r.js} +8 -8
- package/dist/{openapi-BJdBmYDG.js → openapi-DTaEmTSW.js} +10 -9
- package/dist/openapi-ahr8rHu3.js +138 -0
- package/dist/operation-findings-DgATDpvh.js +36 -0
- package/dist/operations-CxybZErY.d.ts +59 -0
- package/dist/orpc/index.d.ts +13 -10
- package/dist/orpc/index.js +20 -15
- package/dist/otel/index.d.ts +3 -2
- package/dist/otel/index.js +30 -7
- package/dist/output-Dyw8fyPF.js +88 -0
- package/dist/output-files-B3IZJksC.js +1 -0
- package/dist/{output-files-CgIsvdSa.js → output-files-DhRBBE4n.js} +24 -26
- package/dist/{permission-keys-B26jeyUv.js → ownership-BatFgAA4.js} +1698 -869
- package/dist/{package-root-DtNnpmUd.js → package-root-Dk_ETdkp.js} +1 -1
- package/dist/{parse-CVFQHk6c.js → parse-Cxq0WxrA.js} +2 -2
- package/dist/{parse-local-manifest-C-q02Pal.js → parse-local-manifest-CVSs6J9I.js} +1 -1
- package/dist/{parse-local-manifest-DvYUR0QL.d.ts → parse-local-manifest-DgqtruPn.d.ts} +1 -1
- package/dist/parse-request-D_tUXG6M.js +26 -0
- package/dist/paths-DXSHAMIa.js +42 -0
- package/dist/pdp/index.d.ts +7 -3
- package/dist/pdp/index.js +45 -26
- package/dist/{peer-BOr_kJE1.js → peer-C8swJ2GH.js} +23 -4
- package/dist/peer-CRvC7Hg1.js +1 -0
- package/dist/permdock-B9JxkBwC.js +868 -0
- package/dist/permdock-D7eeLJER.d.ts +502 -0
- package/dist/{permission-registry-BsblpB-z.js → permission-registry-Br4jSNVi.js} +3 -3
- package/dist/permissions-B-wCP5ZC.js +30 -0
- package/dist/{permissions-CCJ6lmxB.js → permissions-CZKiUfFM.js} +4 -3
- package/dist/{permissions-COH-KRgT.d.ts → permissions-oEWfl-kl.d.ts} +1 -2
- package/dist/policies-CO1oOymN.js +295 -0
- package/dist/{policy-ur0BBK_e.d.ts → policy-Czo4n3Hs.d.ts} +2 -2
- package/dist/{hosted-CBHgkzDl.js → policy-DLZJ5gAp.js} +17 -273
- package/dist/policy-from-catalog-DzhEc3Y9.js +450 -0
- package/dist/policy-module-CTlwMvLI.js +89 -0
- package/dist/{policy-types-sp9P1iIV.d.ts → policy-types-DzwivBgR.d.ts} +434 -631
- package/dist/postgrest-CW0IqC-U.js +566 -0
- package/dist/postgrest-NUqZT-RB.d.ts +100 -0
- package/dist/powersync-BHfuehf3.js +62 -0
- package/dist/powersync-CbzkqL_M.js +1 -0
- package/dist/{powersync-cZe4kzhL.js → powersync-bYUDLOAO.js} +23 -24
- package/dist/preset/index.d.ts +146 -0
- package/dist/preset/index.js +1 -0
- package/dist/preset-DZdU0tne.js +1768 -0
- package/dist/principal-source-pHneukrx.js +103 -0
- package/dist/prisma/index.d.ts +6 -3
- package/dist/prisma/index.js +2 -2
- package/dist/{problem-CnWraVhC.js → problem-CTviyH5L.js} +13 -23
- package/dist/{problem-details-rIIo8B2C.d.ts → problem-details-DXlt-vks.d.ts} +1 -1
- package/dist/{problem-details-DECUnXAn.js → problem-details-cn5X30gZ.js} +43 -40
- package/dist/problem-types-CJ2325SZ.js +5 -0
- package/dist/{prompt-CXYhLfsS.js → prompt-DfZLJLIn.js} +2 -2
- package/dist/{protected-B3_P7xuw.d.ts → protected-DEPHc2xV.d.ts} +16 -8
- package/dist/{protected-BN7BUdY1.js → protected-DfjY5mLA.js} +21 -4
- package/dist/{provider-Bi-0HNL3.js → provider-CC-u3bYP.js} +2 -2
- package/dist/{provider-kwHC9CZD.d.ts → provider-DMVt6yYn.d.ts} +1 -1
- package/dist/{provider-store-Ctt-81Ni.js → provider-store-B5Yrkhzr.js} +2 -2
- package/dist/pull-BgIfno6w.js +256 -0
- package/dist/pull-ByOks_Tg.js +1 -0
- package/dist/push-CmFVBOeI.js +116 -0
- package/dist/pushed-policy-BImMTTIM.d.ts +57 -0
- package/dist/pushed-policy-DobP7AHI.js +238 -0
- package/dist/react/index.d.ts +8 -8
- package/dist/react/index.js +6 -6
- package/dist/react/provider-client.d.ts +1 -1
- package/dist/react/provider-client.js +1 -2
- package/dist/react-native/index.d.ts +24 -72
- package/dist/react-native/index.js +24 -22
- package/dist/{refs-f3imMjNW.js → refs-K6eWUJ0H.js} +1 -1
- package/dist/{relation-walk-BXnlLtg2.js → relation-walk-3OyDBF0S.js} +2 -2
- package/dist/{relations-CvmSpG67.js → relations-BnCWnJGI.js} +3 -3
- package/dist/renames-CGj7YwcQ.js +175 -0
- package/dist/{replay-COpmZUfx.d.ts → replay-D7iKcLFe.d.ts} +1 -1
- package/dist/{replay-BsOyTrdV.js → replay-Du1tJjG7.js} +2 -1
- package/dist/{request-context-BVM7aWNs.js → request-context-BTRTG7OT.js} +3 -3
- package/dist/request-schema-CMreVuFM.js +148 -0
- package/dist/resend/index.d.ts +126 -0
- package/dist/resend/index.js +379 -0
- package/dist/{resource-relations-D1Un3pcz.js → resource-relations-D_jw0BFx.js} +1 -1
- package/dist/{retire-BFcxL6un.js → retire-CALjIQ7e.js} +2 -2
- package/dist/{revocations-Cy06JNx2.d.ts → revocations-R07lFBnX.d.ts} +2 -0
- package/dist/rls-BA8an5Ap.js +336 -0
- package/dist/{rls-BEktUaqg.js → rls-j6t43t7n.js} +287 -689
- package/dist/{role-builder-B4GbKM-i.js → role-builder-CXbis5-X.js} +14 -207
- package/dist/{rpc-nYC3cR_u.js → rpc-aPyNi6tA.js} +7 -7
- package/dist/run-CNsApDpd.js +1 -0
- package/dist/run-DOfMtc9V.js +723 -0
- package/dist/run-ticket-BjhTOi6u.d.ts +124 -0
- package/dist/run-ticket-sxFI6LAk.js +337 -0
- package/dist/{runtime-D_tMXnsq.js → runtime-D3VTAiCA.js} +1 -1
- package/dist/{saas-DtaA4JuW.js → saas-FO-Q8oj0.js} +16 -14
- package/dist/scan-BOI5tJ-6.js +29 -0
- package/dist/{schema-DjQBcAP9.js → schema-B4v0Qrac.js} +102 -8
- package/dist/schema-yLuBWWsh.js +130 -0
- package/dist/scim/index.d.ts +2 -2
- package/dist/scim/index.js +1 -2
- package/dist/{scim-vFR1O5oG.js → scim-ClHtpyV3.js} +208 -76
- package/dist/{scopes-tvpa34ep.js → scopes-CUPSjo9q.js} +12 -7
- package/dist/server/index.d.ts +12 -143
- package/dist/server/index.js +12 -9
- package/dist/server-DqCT4CgZ.js +453 -0
- package/dist/{server-types-DdqBwZN_.d.ts → server-types-BLd4MnBX.d.ts} +51 -68
- package/dist/{sha256-BO0swRXL.js → sha256-D9ihqmvd.js} +8 -1
- package/dist/{shared-1uhI-e-b.js → shared-CD11nBbC.js} +18 -8
- package/dist/{shared-JhMeOsDF.js → shared-DvvFzYXe.js} +8 -9
- package/dist/signals-D3NcTKUS.js +32 -0
- package/dist/sink-BEZSlMS_.js +957 -0
- package/dist/sink-Bj_lDUDq.d.ts +225 -0
- package/dist/{skills-BZdRQkxs.js → skills-B6lVdD_W.js} +13 -6
- package/dist/skills-CTYwkl44.js +51 -0
- package/dist/snapshot-CXUWfsNy.js +269 -0
- package/dist/{snapshot-cache-Cod40D-X.js → snapshot-cache-DZHQ0KF6.js} +11 -5
- package/dist/{snapshot-cache-J5T7t_vD.d.ts → snapshot-cache-DqK9eDmM.d.ts} +7 -5
- package/dist/solid/index.d.ts +11 -12
- package/dist/solid/index.js +7 -7
- package/dist/solid-start/index.d.ts +52 -0
- package/dist/solid-start/index.js +49 -0
- package/dist/{sources-Dljy06zL.d.ts → sources-BV9j0DeZ.d.ts} +7 -13
- package/dist/{sources-B1-b-R0t.js → sources-vs5dGOsS.js} +125 -119
- package/dist/{sql-t8teWOfo.js → sql-B5T1IL83.js} +13 -1
- package/dist/src-DLfUWFAI.js +1851 -0
- package/dist/ssf/index.d.ts +4 -4
- package/dist/ssf/index.js +384 -47
- package/dist/standard-webhooks-6lg8v_is.d.ts +88 -0
- package/dist/standard-webhooks-DgFFD-Ga.js +228 -0
- package/dist/storage-C2bWdvJH.js +132 -0
- package/dist/{store-ILkLUj_o.js → store-4u_hxjWa.js} +40 -53
- package/dist/{store-options-CbUHDoSe.js → store-options-BqEakYRa.js} +26 -21
- package/dist/{stores-BHXdSbw9.js → stores-BbsD4fAR.js} +2 -2
- package/dist/{stores-Cxz_80g-.d.ts → stores-ClZUgeoP.d.ts} +7 -8
- package/dist/{stream-Dwsg6WwE.d.ts → stream-7-xmnf3U.d.ts} +2 -2
- package/dist/{stream-BMui98KK.js → stream-CvdUS9V1.js} +9 -2
- package/dist/style-DiKWnAvn.js +1 -0
- package/dist/{style-CTm1AXDT.js → style-Uao76wO7.js} +3 -2
- package/dist/subject-BGoM5o8B.js +17 -0
- package/dist/supabase/index.d.ts +23 -106
- package/dist/supabase/index.js +5 -4
- package/dist/supabase/middleware.d.ts +7 -6
- package/dist/supabase/middleware.js +13 -11
- package/dist/supabase-9pqI57pW.js +92 -0
- package/dist/{supabase-C1TWlnYt.js → supabase-Dxlp8A94.js} +98 -205
- package/dist/supabase-hook-CXcGpHqq.js +1 -0
- package/dist/{supabase-hook-Cva3ikXz.js → supabase-hook-DdDQhMlw.js} +951 -60
- package/dist/support-session-C6xJQYut.js +158 -0
- package/dist/svelte/Protected.svelte +4 -4
- package/dist/svelte/index.d.ts +7 -7
- package/dist/svelte/index.js +10 -10
- package/dist/svelte/runtime.d.ts +3 -3
- package/dist/svelte/runtime.js +3 -3
- package/dist/svelte/source.d.ts +7 -7
- package/dist/svelte/source.js +4 -4
- package/dist/sveltekit/index.d.ts +51 -0
- package/dist/sveltekit/index.js +27 -0
- package/dist/tanstack-start/index.d.ts +51 -0
- package/dist/tanstack-start/index.js +40 -0
- package/dist/target-Bw37TFNA.js +51 -0
- package/dist/{tenancy-DshjqY0n.js → tenancy-DN2QAx9z.js} +5 -5
- package/dist/terminal/index.d.ts +11 -9
- package/dist/terminal/index.js +23 -287
- package/dist/testing/index.d.ts +311 -38
- package/dist/testing/index.js +3475 -201
- package/dist/testing/saas/index.d.ts +9 -8
- package/dist/testing/saas/index.js +2 -2
- package/dist/testing/saas/permissions.d.ts +1 -1
- package/dist/testing/saas/permissions.js +1 -2
- package/dist/text-BMFRfBqc.js +8 -0
- package/dist/{text-diff-BdkkYSbi.js → text-diff-BQcUapOb.js} +1 -1
- package/dist/thenable-yD7SabqG.js +31 -0
- package/dist/time-DkWjdL98.js +71 -0
- package/dist/{token-Bx9qy30p.js → token-BLZcjQgt.js} +15 -6
- package/dist/{tool-refusal-CQ7OEia9.js → tool-refusal-CMLN5xhn.js} +2 -2
- package/dist/trpc/index.d.ts +12 -9
- package/dist/trpc/index.js +16 -14
- package/dist/{types-7rJVLWe5.d.ts → types-5Ut_pbKy.d.ts} +61 -11
- package/dist/{store-9KO4BlkB.d.ts → types-BNORmDM8.d.ts} +100 -75
- package/dist/types-BjV-fqcA.d.ts +57 -0
- package/dist/{types-CUcFZfpU.d.ts → types-BqAKcRNW.d.ts} +2 -1
- package/dist/types-C8-KNsFf.d.ts +107 -0
- package/dist/{types-Br9IXUBG.d.ts → types-CCpc2Dcv.d.ts} +77 -17
- package/dist/{types-DpWfQdSh.d.ts → types-CZTnPFzM.d.ts} +46 -11
- package/dist/{types-CqrjB9o6.d.ts → types-CdlxsYQh.d.ts} +23 -11
- package/dist/{types-CIlTojhq.d.ts → types-ClZaWzfb.d.ts} +9 -6
- package/dist/types-DX0LaKTb.d.ts +157 -0
- package/dist/types-DiQjupG2.d.ts +332 -0
- package/dist/types-DqzsnlSA.js +67 -0
- package/dist/types-_sHy8BQf.d.ts +65 -0
- package/dist/{types-ByUo56un.d.ts → types-fbZ7JEXr.d.ts} +23 -22
- package/dist/{types-DHrmBJLH.d.ts → types-tIgIeIKJ.d.ts} +7 -7
- package/dist/unplugin/index.d.ts +1 -1
- package/dist/unplugin/index.js +2 -2
- package/dist/usage-CHOtwL19.js +1 -0
- package/dist/usage-DHtE8j4E.js +32 -0
- package/dist/{usage-CG9nOYZw.js → usage-T5mXq98v.js} +54 -11
- package/dist/{validation-error-BSSw0l_8.d.ts → validation-error-Bg5Tpluk.d.ts} +1 -1
- package/dist/{validity-dVrUEPJt.js → validity-CZ7-y0Cj.js} +32 -15
- package/dist/{verifier-DMr_Zmb_.js → verifier-DHuh-okk.js} +18 -7
- package/dist/{verify-BztUB3GX.js → verify-DbCL9bnB.js} +645 -50
- package/dist/{version-BEogC-rB.js → version-CEbQ5UeM.js} +4 -3
- package/dist/version-DXkYUISx.js +1 -0
- package/dist/{views-CJsrBS1f.js → views-DTIIO-oQ.js} +22 -5
- package/dist/{permission-types-Dg39z9Kv.d.ts → vocabulary-D6lPdb4Z.d.ts} +65 -2
- package/dist/vue/index.d.ts +9 -10
- package/dist/vue/index.js +8 -8
- package/dist/waiter-BGUtGYoU.js +67 -0
- package/dist/waiter-CKy4MQSY.d.ts +36 -0
- package/dist/watch-Cb-NcaUw.js +1 -0
- package/dist/{watch-zeucB7eF.js → watch-CszoTJMq.js} +44 -5
- package/dist/webmcp/index.d.ts +2 -2
- package/dist/webmcp/index.js +3 -3
- package/dist/where-scope-Dv-WTP-w.js +306 -0
- package/dist/who-can-D0QoYbEb.js +364 -0
- package/dist/wire-delegation-Cv3W2eaM.js +36 -0
- package/dist/wire-denial-C7PaVYEM.js +27 -0
- package/dist/workflow/index.d.ts +5 -0
- package/dist/workflow/index.js +223 -0
- package/dist/workflow-sdk/index.d.ts +56 -0
- package/dist/workflow-sdk/index.js +78 -0
- package/dist/{wrap-Cr93qqdP.d.ts → wrap-Bd1Tejur.d.ts} +2 -1
- package/dist/{wrap-DWsU_5Bd.js → wrap-gX61EtpB.js} +7 -6
- package/package.json +136 -37
- package/schemas/access-event-v1.json +118 -0
- package/schemas/approval-request-v1.json +34 -1
- package/schemas/approval-signature-v1.json +94 -0
- package/schemas/automation-event-v1.json +113 -0
- package/schemas/capability-v1.json +84 -0
- package/schemas/catalog-event-v1.json +87 -0
- package/schemas/catalog-v1.json +123 -12
- package/schemas/cli-commands-v1.json +164 -0
- package/schemas/cli-result-v1.json +96 -0
- package/schemas/cloud-api-v1.json +5407 -0
- package/schemas/connector-v1.json +408 -0
- package/schemas/credential-event-v1.json +81 -0
- package/schemas/credential-v1.json +134 -0
- package/schemas/decision-event-v1.json +288 -0
- package/schemas/delivery-event-v1.json +117 -0
- package/schemas/directory-event-v1.json +85 -0
- package/schemas/evidence-export-v1.json +54 -0
- package/schemas/membership-event-v1.json +93 -0
- package/schemas/policy-v1.json +68 -0
- package/schemas/pushed-policy-v1.json +236 -0
- package/schemas/run-v1.json +162 -0
- package/schemas/snapshot-v1.json +138 -0
- package/schemas/supabase-claims-v1.json +4 -4
- package/schemas/supabase-manifest-v1.json +5 -1
- package/schemas/support-session-v1.json +111 -0
- package/skills/permdock/SKILL.md +16 -12
- package/skills/permdock-agents/SKILL.md +40 -23
- package/skills/permdock-agents/references/operations-automations-chat.md +221 -0
- package/skills/permdock-agents/references/runtimes.md +22 -18
- package/skills/permdock-approvals/SKILL.md +29 -13
- package/skills/permdock-approvals/references/delivery-and-waiters.md +172 -0
- package/skills/permdock-approvals/references/stores-and-resume.md +21 -7
- package/skills/permdock-audit/SKILL.md +3 -3
- package/skills/permdock-credentials/SKILL.md +5 -5
- package/skills/permdock-credentials/references/tokens-keys-links.md +14 -10
- package/skills/permdock-data/SKILL.md +6 -6
- package/skills/permdock-data/references/queries-and-rls.md +9 -8
- package/skills/permdock-data/references/relationships.md +3 -3
- package/skills/permdock-tenancy/SKILL.md +20 -7
- package/skills/permdock-tenancy/references/contacts-and-support-sessions.md +122 -0
- package/skills/permdock-tenancy/references/ownership-and-custom-roles.md +5 -4
- package/skills/permdock-wire/SKILL.md +17 -11
- package/skills/permdock-wire/references/adapters.md +139 -51
- package/skills/permdock-wire/references/policy-options.md +5 -5
- package/skills/permdock-wire/references/presets-and-recipes.md +58 -0
- package/dist/approvals-DZL76lKW.js +0 -240
- package/dist/arazzo-CD8d0WLb.js +0 -54
- package/dist/catalog-6yWAX6Ps.js +0 -2
- package/dist/catalog-WHG4kBq7.js +0 -48
- package/dist/cloud-C7bSDgX4.js +0 -50
- package/dist/cloud-PeBN3IEn.js +0 -118
- package/dist/collect-Bw2Jdq1q.js +0 -2
- package/dist/collect-CQx4hX4N.js +0 -83
- package/dist/commands-Cpip4ULx.js +0 -97
- package/dist/config-DLt6BvV7.js +0 -36
- package/dist/diff-Cnghh_Ip.js +0 -48
- package/dist/doctor-CuVJvhV_.js +0 -53
- package/dist/duration-xK2jGFVc.js +0 -25
- package/dist/errors-CWfoNg9N.js +0 -47
- package/dist/errors-DRnGZHzF.js +0 -30
- package/dist/expiry-BoBJ8Tvc.js +0 -7
- package/dist/fields-fwfXN01n.js +0 -1016
- package/dist/headers-BZSDieNT.js +0 -6
- package/dist/headers-Cf-zWvsO.d.ts +0 -6
- package/dist/ids-DC4V4CFu.js +0 -18
- package/dist/index-DgM7w96K.d.ts +0 -6
- package/dist/index-Dz7didpC.d.ts +0 -201
- package/dist/load-B_shHrmd.js +0 -2
- package/dist/manifest-BngWKryL.js +0 -770
- package/dist/may-use-BOn_dR_w.js +0 -78
- package/dist/openapi-DcQ1Kg40.js +0 -164
- package/dist/ownership-BgnbOJFT.js +0 -851
- package/dist/permdock-L26udHSk.js +0 -3646
- package/dist/powersync-BFSbSElQ.js +0 -62
- package/dist/powersync-DCDgZgfZ.js +0 -2
- package/dist/rls-55DQTuf5.js +0 -250
- package/dist/run-DMcNW_8T.js +0 -174
- package/dist/server-ZYEHtNHS.js +0 -268
- package/dist/sink-BTtmfPnE.js +0 -141
- package/dist/sink-CPN4zLfs.d.ts +0 -104
- package/dist/skills-Dle4ZoLF.js +0 -56
- package/dist/snapshot-Dc9CHPME.js +0 -1078
- package/dist/src-Bb7no-hS.js +0 -639
- package/dist/subject-C6dLxqHU.js +0 -24
- package/dist/supabase-Dbqr141s.js +0 -83
- package/dist/supabase-hook-BULg7Ut_.js +0 -2
- package/dist/thenable-QSmvt-vZ.js +0 -65
- package/dist/types-C0dee0Qf.d.ts +0 -197
- package/dist/types-DvupZE0w.d.ts +0 -9
- package/dist/usage-4G6t643F.js +0 -42
- package/dist/usage-iFLJ0-rr.js +0 -2
- package/dist/vocabulary-hhEFLFoL.d.ts +0 -65
- package/dist/watch-C8TpsAl4.js +0 -2
|
@@ -1,1078 +0,0 @@
|
|
|
1
|
-
import { a as sole, n as isReadonlyArray, r as isRecord, t as compact } from "./compact-CAf557ZB.js";
|
|
2
|
-
import { n as freezeDeep } from "./freeze-CrU8nQeX.js";
|
|
3
|
-
import { o as isForbiddenKey, s as ownGet } from "./thenable-QSmvt-vZ.js";
|
|
4
|
-
import { c as isConditionRef, i as resolveConditionRef, s as isConditionDate, u as parentHop } from "./refs-f3imMjNW.js";
|
|
5
|
-
import { t as expiredAt } from "./expiry-BoBJ8Tvc.js";
|
|
6
|
-
import { n as sameId } from "./ids-DC4V4CFu.js";
|
|
7
|
-
import { d as scopeList, l as scopeChain, m as tenantOf, o as resolveScope, p as subjectMemberships, r as findScope, t as activeFor, u as scopeIdOf } from "./scopes-tvpa34ep.js";
|
|
8
|
-
import { g as formerScopes, m as annotationsFor, n as findPermission } from "./permission-registry-BsblpB-z.js";
|
|
9
|
-
import { _ as listPlans, o as flattenGrantee, v as listRoles } from "./grantee-CXY-0C87.js";
|
|
10
|
-
import { t as isActive } from "./validity-dVrUEPJt.js";
|
|
11
|
-
import { o as resourceRoleCondition } from "./grantee-conditions-MQs5NIuX.js";
|
|
12
|
-
import { m as tenantsOf, n as inTeam, o as membershipField, r as isMembershipExpired } from "./tenancy-DshjqY0n.js";
|
|
13
|
-
import { n as matchGrantee } from "./grantee-match-fxYp9Nmt.js";
|
|
14
|
-
//#region src/conditions/evaluate.ts
|
|
15
|
-
function resolveRef(ref, subject) {
|
|
16
|
-
return resolveConditionRef(ref, subject);
|
|
17
|
-
}
|
|
18
|
-
function unwrap(value, subject) {
|
|
19
|
-
if (isConditionRef(value)) return resolveRef(value.ref, subject);
|
|
20
|
-
if (isConditionDate(value)) return new Date(isoInstant(value.date) ?? NaN);
|
|
21
|
-
if (isReadonlyArray(value)) return value.map((item) => unwrap(item, subject));
|
|
22
|
-
return value;
|
|
23
|
-
}
|
|
24
|
-
const ISO_INSTANT = /^(\d{4}-\d{2}-\d{2})(?:[T ](\d{2}:\d{2}(?::\d{2}(?:\.\d{1,9})?)?)(Z|[+-]\d{2}(?::?\d{2})?)?)?$/u;
|
|
25
|
-
function isoInstant(value) {
|
|
26
|
-
const match = ISO_INSTANT.exec(value);
|
|
27
|
-
if (match === null) return;
|
|
28
|
-
const [, day, time, zone] = match;
|
|
29
|
-
let offset = zone ?? (time === void 0 ? "" : "Z");
|
|
30
|
-
if (/^[+-]\d{2}$/u.test(offset)) offset = `${offset}:00`;
|
|
31
|
-
else if (/^[+-]\d{4}$/u.test(offset)) offset = `${offset.slice(0, 3)}:${offset.slice(3)}`;
|
|
32
|
-
const parsed = Date.parse(time === void 0 ? `${day}` : `${day}T${time}${offset}`);
|
|
33
|
-
return Number.isNaN(parsed) ? void 0 : parsed;
|
|
34
|
-
}
|
|
35
|
-
function instantOf(value) {
|
|
36
|
-
if (value instanceof Date) {
|
|
37
|
-
const time = value.getTime();
|
|
38
|
-
return Number.isNaN(time) ? void 0 : time;
|
|
39
|
-
}
|
|
40
|
-
if (typeof value === "number") return Number.isFinite(value) ? value : void 0;
|
|
41
|
-
if (typeof value === "string") return isoInstant(value);
|
|
42
|
-
}
|
|
43
|
-
function comparablePair(left, right) {
|
|
44
|
-
if (left instanceof Date || right instanceof Date) {
|
|
45
|
-
const a = instantOf(left);
|
|
46
|
-
const b = instantOf(right);
|
|
47
|
-
return a === void 0 || b === void 0 ? void 0 : [a, b];
|
|
48
|
-
}
|
|
49
|
-
const kind = typeof left;
|
|
50
|
-
if (kind === typeof right && (kind === "string" || kind === "number" || kind === "boolean")) return [left, right];
|
|
51
|
-
}
|
|
52
|
-
function compare(op, left, right) {
|
|
53
|
-
if (left === void 0 || left === null || right === void 0 || right === null) return false;
|
|
54
|
-
const comparable = comparablePair(left, right);
|
|
55
|
-
if (comparable === void 0) return false;
|
|
56
|
-
const [a, b] = comparable;
|
|
57
|
-
switch (op) {
|
|
58
|
-
case "eq": return a === b;
|
|
59
|
-
case "ne": return a !== b;
|
|
60
|
-
case "gt": return a > b;
|
|
61
|
-
case "gte": return a >= b;
|
|
62
|
-
case "lt": return a < b;
|
|
63
|
-
case "lte": return a <= b;
|
|
64
|
-
default:
|
|
65
|
-
/* v8 ignore next */
|
|
66
|
-
return false;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
function contains(left, right) {
|
|
70
|
-
if (left === void 0 || left === null || right === void 0 || right === null) return false;
|
|
71
|
-
if (typeof left === "string" && typeof right === "string") return left.includes(right);
|
|
72
|
-
if (Array.isArray(left)) return left.includes(right);
|
|
73
|
-
return false;
|
|
74
|
-
}
|
|
75
|
-
function inList(left, right) {
|
|
76
|
-
if (left === void 0 || left === null || !Array.isArray(right)) return false;
|
|
77
|
-
return right.includes(left);
|
|
78
|
-
}
|
|
79
|
-
function matchesParentHop(data, parents, on) {
|
|
80
|
-
for (const parent of parents ?? []) {
|
|
81
|
-
const hop = parentHop(parent);
|
|
82
|
-
if (hop.resource !== void 0 && hop.resource !== on.resource) continue;
|
|
83
|
-
if (sameId(ownGet(data, hop.field), on.id)) return true;
|
|
84
|
-
}
|
|
85
|
-
return false;
|
|
86
|
-
}
|
|
87
|
-
function evaluateMemberOf(condition, data, subject, now, scopes) {
|
|
88
|
-
if (data === null || typeof data !== "object") return false;
|
|
89
|
-
const rowValue = ownGet(data, condition.field);
|
|
90
|
-
if (rowValue === void 0 || rowValue === null) return false;
|
|
91
|
-
const memberships = subjectMemberships(subject.principal?.memberships, scopes);
|
|
92
|
-
const wanted = new Set(condition.roles);
|
|
93
|
-
const active = subject.principal?.tenant === "" ? void 0 : subject.principal?.tenant;
|
|
94
|
-
const scope = condition.scope === "resource" ? void 0 : resolveScope(scopes, condition.scope);
|
|
95
|
-
if (condition.scope !== "resource" && scope === void 0) return false;
|
|
96
|
-
for (const membership of memberships) {
|
|
97
|
-
if (expiredAt(membership, now)) continue;
|
|
98
|
-
if (wanted.size > 0 && !membership.roles.some((role) => wanted.has(role))) continue;
|
|
99
|
-
if (scope !== void 0) {
|
|
100
|
-
if (membership.scope !== scope || !sameId(membership.id, rowValue)) continue;
|
|
101
|
-
const tenant = tenantOf(membership, scopes);
|
|
102
|
-
if (active !== void 0 && tenant !== void 0 && tenant !== active) continue;
|
|
103
|
-
return true;
|
|
104
|
-
}
|
|
105
|
-
if (membership.on === void 0) continue;
|
|
106
|
-
if (condition.resource !== void 0 && membership.on.resource !== condition.resource) {
|
|
107
|
-
if (matchesParentHop(data, condition.parents, membership.on)) return true;
|
|
108
|
-
continue;
|
|
109
|
-
}
|
|
110
|
-
if (sameId(membership.on.id, rowValue)) return true;
|
|
111
|
-
if (matchesParentHop(data, condition.parents, membership.on)) return true;
|
|
112
|
-
}
|
|
113
|
-
return false;
|
|
114
|
-
}
|
|
115
|
-
function evaluateCondition(condition, data, subject, now = Date.now() / 1e3, scopes = scopeList(void 0), related, onOpaque) {
|
|
116
|
-
switch (condition.op) {
|
|
117
|
-
case "and": return condition.conditions.every((child) => evaluateCondition(child, data, subject, now, scopes, related, onOpaque));
|
|
118
|
-
case "or": return condition.conditions.some((child) => evaluateCondition(child, data, subject, now, scopes, related, onOpaque));
|
|
119
|
-
case "not": return !evaluateCondition(condition.condition, data, subject, now, scopes, related, onOpaque);
|
|
120
|
-
case "isNull": {
|
|
121
|
-
if (data === null || typeof data !== "object") return false;
|
|
122
|
-
const value = ownGet(data, condition.field);
|
|
123
|
-
const isNull = value === null || value === void 0;
|
|
124
|
-
return condition.value ? isNull : !isNull;
|
|
125
|
-
}
|
|
126
|
-
case "in":
|
|
127
|
-
case "notIn": {
|
|
128
|
-
if (data === null || typeof data !== "object") return false;
|
|
129
|
-
const left = ownGet(data, condition.field);
|
|
130
|
-
const matched = inList(left, unwrap(condition.value, subject));
|
|
131
|
-
return condition.op === "in" ? matched : !matched && left !== void 0 && left !== null;
|
|
132
|
-
}
|
|
133
|
-
case "contains":
|
|
134
|
-
if (data === null || typeof data !== "object") return false;
|
|
135
|
-
return contains(ownGet(data, condition.field), unwrap(condition.value, subject));
|
|
136
|
-
case "eq":
|
|
137
|
-
case "ne":
|
|
138
|
-
case "gt":
|
|
139
|
-
case "gte":
|
|
140
|
-
case "lt":
|
|
141
|
-
case "lte":
|
|
142
|
-
if (condition.field === "_" && condition.op === "eq") return condition.value === true;
|
|
143
|
-
if (data === null || typeof data !== "object") return false;
|
|
144
|
-
return compare(condition.op, ownGet(data, condition.field), unwrap(condition.value, subject));
|
|
145
|
-
case "memberOf": return evaluateMemberOf(condition, data, subject, now, scopes);
|
|
146
|
-
case "related": return related?.(condition, data) === true;
|
|
147
|
-
case "sqlFunction": return evaluateCondition(condition.twin, data, subject, now, scopes, related, onOpaque);
|
|
148
|
-
case "opaque":
|
|
149
|
-
onOpaque?.();
|
|
150
|
-
return false;
|
|
151
|
-
case "liveSession": return subject.liveSession === true;
|
|
152
|
-
default:
|
|
153
|
-
/* v8 ignore next */
|
|
154
|
-
return condition;
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
//#endregion
|
|
158
|
-
//#region src/core/arazzo.ts
|
|
159
|
-
const VERSION = /^1\.[01]\.\d+(?:-.+)?$/u;
|
|
160
|
-
const STEP_TARGETS = [
|
|
161
|
-
"operationId",
|
|
162
|
-
"operationPath",
|
|
163
|
-
"workflowId",
|
|
164
|
-
"channelPath"
|
|
165
|
-
];
|
|
166
|
-
const denied = (reason) => freezeDeep({
|
|
167
|
-
outcome: "denied",
|
|
168
|
-
denials: [{
|
|
169
|
-
role: null,
|
|
170
|
-
reason
|
|
171
|
-
}],
|
|
172
|
-
alternatives: []
|
|
173
|
-
});
|
|
174
|
-
function asString(value) {
|
|
175
|
-
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
176
|
-
}
|
|
177
|
-
function parseParameters(raw, components, where) {
|
|
178
|
-
if (raw === void 0) return [];
|
|
179
|
-
if (!Array.isArray(raw)) return `${where}: parameters must be an array`;
|
|
180
|
-
const out = [];
|
|
181
|
-
for (const item of raw) {
|
|
182
|
-
if (!isRecord(item)) return `${where}: a parameter is not an object`;
|
|
183
|
-
const reference = asString(item["reference"]);
|
|
184
|
-
if (reference !== void 0) {
|
|
185
|
-
const match = /^\$components\.parameters\.(.+)$/u.exec(reference);
|
|
186
|
-
const target = match?.[1] === void 0 ? void 0 : components[match[1]];
|
|
187
|
-
const name = isRecord(target) ? asString(target["name"]) : void 0;
|
|
188
|
-
if (!isRecord(target) || name === void 0 || !("value" in target)) return `${where}: unresolved parameter reference ${reference}`;
|
|
189
|
-
out.push({
|
|
190
|
-
name,
|
|
191
|
-
value: "value" in item ? item["value"] : target["value"]
|
|
192
|
-
});
|
|
193
|
-
continue;
|
|
194
|
-
}
|
|
195
|
-
const name = asString(item["name"]);
|
|
196
|
-
if (name === void 0 || !("value" in item)) return `${where}: a parameter needs a name and a value`;
|
|
197
|
-
out.push({
|
|
198
|
-
name,
|
|
199
|
-
value: item["value"]
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
return out;
|
|
203
|
-
}
|
|
204
|
-
function parseDocument(arazzo) {
|
|
205
|
-
if (!isRecord(arazzo)) return "Arazzo document is not an object";
|
|
206
|
-
const version = arazzo["arazzo"];
|
|
207
|
-
if (typeof version !== "string" || !VERSION.test(version)) return "arazzo must be a 1.0.x or 1.1.x version";
|
|
208
|
-
if (!isRecord(arazzo["info"])) return "info is required";
|
|
209
|
-
const rawSources = arazzo["sourceDescriptions"];
|
|
210
|
-
if (!Array.isArray(rawSources) || rawSources.length === 0) return "sourceDescriptions needs at least one entry";
|
|
211
|
-
const sources = [];
|
|
212
|
-
for (const source of rawSources) {
|
|
213
|
-
const name = isRecord(source) ? asString(source["name"]) : void 0;
|
|
214
|
-
if (!isRecord(source) || name === void 0 || asString(source["url"]) === void 0) return "a sourceDescription needs a name and a url";
|
|
215
|
-
if (sources.some((item) => item.name === name)) return `duplicate sourceDescription ${name}`;
|
|
216
|
-
sources.push({
|
|
217
|
-
name,
|
|
218
|
-
type: asString(source["type"]) ?? "openapi"
|
|
219
|
-
});
|
|
220
|
-
}
|
|
221
|
-
const components = isRecord(arazzo["components"]) && isRecord(arazzo["components"]["parameters"]) ? arazzo["components"]["parameters"] : {};
|
|
222
|
-
const rawWorkflows = arazzo["workflows"];
|
|
223
|
-
if (!Array.isArray(rawWorkflows) || rawWorkflows.length === 0) return "workflows needs at least one entry";
|
|
224
|
-
const workflows = [];
|
|
225
|
-
for (const item of rawWorkflows) {
|
|
226
|
-
const workflowId = isRecord(item) ? asString(item["workflowId"]) : void 0;
|
|
227
|
-
if (!isRecord(item) || workflowId === void 0) return "a workflow needs a workflowId";
|
|
228
|
-
if (workflows.some((workflow) => workflow.workflowId === workflowId)) return `duplicate workflowId ${workflowId}`;
|
|
229
|
-
const parameters = parseParameters(item["parameters"], components, workflowId);
|
|
230
|
-
if (typeof parameters === "string") return parameters;
|
|
231
|
-
const rawSteps = item["steps"];
|
|
232
|
-
if (!Array.isArray(rawSteps) || rawSteps.length === 0) return `${workflowId}: steps needs at least one entry`;
|
|
233
|
-
const steps = [];
|
|
234
|
-
for (const step of rawSteps) {
|
|
235
|
-
const stepId = isRecord(step) ? asString(step["stepId"]) : void 0;
|
|
236
|
-
if (!isRecord(step) || stepId === void 0) return `${workflowId}: a step needs a stepId`;
|
|
237
|
-
if (steps.some((other) => other.stepId === stepId)) return `${workflowId}: duplicate stepId ${stepId}`;
|
|
238
|
-
const targets = STEP_TARGETS.filter((field) => asString(step[field]) !== void 0);
|
|
239
|
-
if (targets.length !== 1 && !(targets.length === 2 && targets.includes("operationId") && targets.includes("channelPath"))) return `${workflowId}.${stepId}: a step needs exactly one of operationId, operationPath or workflowId`;
|
|
240
|
-
const stepParameters = parseParameters(step["parameters"], components, `${workflowId}.${stepId}`);
|
|
241
|
-
if (typeof stepParameters === "string") return stepParameters;
|
|
242
|
-
steps.push(compact({
|
|
243
|
-
stepId,
|
|
244
|
-
operationId: asString(step["operationId"]),
|
|
245
|
-
operationPath: asString(step["operationPath"]),
|
|
246
|
-
workflowId: asString(step["workflowId"]),
|
|
247
|
-
channelPath: asString(step["channelPath"]),
|
|
248
|
-
parameters: stepParameters
|
|
249
|
-
}));
|
|
250
|
-
}
|
|
251
|
-
workflows.push({
|
|
252
|
-
workflowId,
|
|
253
|
-
parameters,
|
|
254
|
-
steps
|
|
255
|
-
});
|
|
256
|
-
}
|
|
257
|
-
return {
|
|
258
|
-
sources,
|
|
259
|
-
workflows
|
|
260
|
-
};
|
|
261
|
-
}
|
|
262
|
-
function unescapePointer(token) {
|
|
263
|
-
return token.replaceAll("~1", "/").replaceAll("~0", "~");
|
|
264
|
-
}
|
|
265
|
-
function readPointer(doc, pointer) {
|
|
266
|
-
if (!pointer.startsWith("#/")) return;
|
|
267
|
-
let current = doc;
|
|
268
|
-
for (const raw of pointer.slice(2).split("/")) {
|
|
269
|
-
if (!isRecord(current)) return;
|
|
270
|
-
let token;
|
|
271
|
-
try {
|
|
272
|
-
token = unescapePointer(decodeURIComponent(raw));
|
|
273
|
-
} catch {
|
|
274
|
-
return;
|
|
275
|
-
}
|
|
276
|
-
if (!Object.hasOwn(current, token)) return;
|
|
277
|
-
current = current[token];
|
|
278
|
-
}
|
|
279
|
-
return current;
|
|
280
|
-
}
|
|
281
|
-
function findOperation(openapi, operationId) {
|
|
282
|
-
if (!isRecord(openapi) || !isRecord(openapi["paths"])) return;
|
|
283
|
-
for (const pathItem of Object.values(openapi["paths"])) {
|
|
284
|
-
if (!isRecord(pathItem)) continue;
|
|
285
|
-
for (const [method, operation] of Object.entries(pathItem)) if (!method.startsWith("x-") && isRecord(operation) && operation["operationId"] === operationId) return operation;
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
/** One description, or a map of descriptions keyed by source `name`. */
|
|
289
|
-
function descriptionFor(openapi, name) {
|
|
290
|
-
if (isRecord(openapi) && !("openapi" in openapi) && !("paths" in openapi) && isRecord(openapi[name])) return openapi[name];
|
|
291
|
-
return openapi;
|
|
292
|
-
}
|
|
293
|
-
function permissionKeysOf(node) {
|
|
294
|
-
if (!isRecord(node)) return [];
|
|
295
|
-
const raw = node["x-permdock-permissions"];
|
|
296
|
-
if (!Array.isArray(raw)) return [];
|
|
297
|
-
return raw.filter((item) => typeof item === "string");
|
|
298
|
-
}
|
|
299
|
-
/** `$inputs.a.b` against the frame's inputs; anything else that is a runtime expression is unknown. */
|
|
300
|
-
function valueOf(value, inputs) {
|
|
301
|
-
if (typeof value !== "string" || !value.includes("$")) return {
|
|
302
|
-
known: true,
|
|
303
|
-
value
|
|
304
|
-
};
|
|
305
|
-
const match = /^\$inputs\.([^#{}]+)$/u.exec(value);
|
|
306
|
-
if (match?.[1] === void 0) return value.startsWith("$") || value.includes("{$") ? { known: false } : {
|
|
307
|
-
known: true,
|
|
308
|
-
value
|
|
309
|
-
};
|
|
310
|
-
let current = inputs;
|
|
311
|
-
for (const part of match[1].split(".")) {
|
|
312
|
-
if (!isRecord(current) || !Object.hasOwn(current, part)) return { known: false };
|
|
313
|
-
current = current[part];
|
|
314
|
-
}
|
|
315
|
-
return {
|
|
316
|
-
known: true,
|
|
317
|
-
value: current
|
|
318
|
-
};
|
|
319
|
-
}
|
|
320
|
-
function bind(parameters, inputs) {
|
|
321
|
-
const record = {};
|
|
322
|
-
let provisional = false;
|
|
323
|
-
for (const parameter of parameters) {
|
|
324
|
-
const bound = valueOf(parameter.value, inputs);
|
|
325
|
-
if (!bound.known) {
|
|
326
|
-
provisional = true;
|
|
327
|
-
continue;
|
|
328
|
-
}
|
|
329
|
-
Object.defineProperty(record, parameter.name, {
|
|
330
|
-
value: bound.value,
|
|
331
|
-
enumerable: true,
|
|
332
|
-
writable: true,
|
|
333
|
-
configurable: true
|
|
334
|
-
});
|
|
335
|
-
}
|
|
336
|
-
return {
|
|
337
|
-
record,
|
|
338
|
-
provisional
|
|
339
|
-
};
|
|
340
|
-
}
|
|
341
|
-
function flatten(doc, workflowId, inputs, seen, out) {
|
|
342
|
-
if (seen.has(workflowId)) return "workflowId cycle";
|
|
343
|
-
const workflow = doc.workflows.find((item) => item.workflowId === workflowId);
|
|
344
|
-
if (workflow === void 0) return `unknown workflowId ${workflowId}`;
|
|
345
|
-
seen.add(workflowId);
|
|
346
|
-
for (const step of workflow.steps) {
|
|
347
|
-
if (step.workflowId === void 0 || step.workflowId.startsWith("$sourceDescriptions.")) {
|
|
348
|
-
out.push({
|
|
349
|
-
step,
|
|
350
|
-
workflow,
|
|
351
|
-
inputs
|
|
352
|
-
});
|
|
353
|
-
continue;
|
|
354
|
-
}
|
|
355
|
-
const nested = flatten(doc, step.workflowId, bind(step.parameters, inputs).record, seen, out);
|
|
356
|
-
if (nested !== void 0) return nested;
|
|
357
|
-
}
|
|
358
|
-
seen.delete(workflowId);
|
|
359
|
-
}
|
|
360
|
-
function locate(doc, openapi, step) {
|
|
361
|
-
if (step.workflowId !== void 0) return {
|
|
362
|
-
reason: "unsupported",
|
|
363
|
-
detail: "workflows in another Arazzo document are not resolved"
|
|
364
|
-
};
|
|
365
|
-
let sourceName;
|
|
366
|
-
let operationId = step.operationId;
|
|
367
|
-
let pointer;
|
|
368
|
-
if (step.operationPath !== void 0) {
|
|
369
|
-
const match = /^\{?\$sourceDescriptions\.([^.}#]+)(?:\.url)?\}?(#.*)?$/u.exec(step.operationPath);
|
|
370
|
-
if (match?.[1] === void 0) return {
|
|
371
|
-
reason: "undocumented",
|
|
372
|
-
detail: "operationPath is not a $sourceDescriptions reference"
|
|
373
|
-
};
|
|
374
|
-
sourceName = match[1];
|
|
375
|
-
pointer = match[2] ?? "";
|
|
376
|
-
} else if (operationId !== void 0) {
|
|
377
|
-
const match = /^\$sourceDescriptions\.([^.]+)\.(.+)$/u.exec(operationId);
|
|
378
|
-
if (match?.[1] !== void 0 && match[2] !== void 0) {
|
|
379
|
-
sourceName = match[1];
|
|
380
|
-
operationId = match[2];
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
const candidates = sourceName === void 0 ? doc.sources.filter((source) => source.type !== "arazzo") : doc.sources.filter((source) => source.name === sourceName);
|
|
384
|
-
if (candidates.length === 0) return {
|
|
385
|
-
reason: "undocumented",
|
|
386
|
-
detail: sourceName === void 0 ? "no API sourceDescription" : `unknown sourceDescription ${sourceName}`
|
|
387
|
-
};
|
|
388
|
-
if (step.channelPath !== void 0) return {
|
|
389
|
-
reason: "unsupported",
|
|
390
|
-
detail: "AsyncAPI steps are not evaluated"
|
|
391
|
-
};
|
|
392
|
-
const found = [];
|
|
393
|
-
for (const source of candidates) {
|
|
394
|
-
const description = descriptionFor(openapi, source.name);
|
|
395
|
-
const node = pointer === void 0 ? operationId === void 0 ? void 0 : findOperation(description, operationId) : readPointer(description, pointer);
|
|
396
|
-
if (node !== void 0 || candidates.length === 1) found.push({
|
|
397
|
-
source,
|
|
398
|
-
node
|
|
399
|
-
});
|
|
400
|
-
}
|
|
401
|
-
if (found.length > 1) return {
|
|
402
|
-
reason: "undocumented",
|
|
403
|
-
detail: "operationId matches several sources; qualify it with $sourceDescriptions"
|
|
404
|
-
};
|
|
405
|
-
const [hit] = found;
|
|
406
|
-
if (hit?.source.type === "asyncapi") return {
|
|
407
|
-
reason: "unsupported",
|
|
408
|
-
detail: "AsyncAPI steps are not evaluated"
|
|
409
|
-
};
|
|
410
|
-
if (hit === void 0 || hit.source.type === "arazzo" || !isRecord(hit.node)) return {
|
|
411
|
-
reason: "undocumented",
|
|
412
|
-
detail: "operation not found"
|
|
413
|
-
};
|
|
414
|
-
return compact({
|
|
415
|
-
node: hit.node,
|
|
416
|
-
operationId: asString(hit.node["operationId"]) ?? operationId
|
|
417
|
-
});
|
|
418
|
-
}
|
|
419
|
-
function resolve(doc, openapi, tree, flat) {
|
|
420
|
-
const { step, workflow, inputs } = flat;
|
|
421
|
-
const base = {
|
|
422
|
-
stepId: step.stepId,
|
|
423
|
-
workflowId: workflow.workflowId
|
|
424
|
-
};
|
|
425
|
-
const located = locate(doc, openapi, step);
|
|
426
|
-
const { record, provisional } = bind([...workflow.parameters.filter((parameter) => !step.parameters.some((own) => own.name === parameter.name)), ...step.parameters], inputs);
|
|
427
|
-
const data = Object.keys(inputs).length + Object.keys(record).length === 0 ? void 0 : {
|
|
428
|
-
...inputs,
|
|
429
|
-
...record
|
|
430
|
-
};
|
|
431
|
-
if ("reason" in located) return {
|
|
432
|
-
...base,
|
|
433
|
-
...compact({ operationId: step.operationId }),
|
|
434
|
-
keys: [],
|
|
435
|
-
finding: located,
|
|
436
|
-
data,
|
|
437
|
-
provisional
|
|
438
|
-
};
|
|
439
|
-
const keys = permissionKeysOf(located.node);
|
|
440
|
-
const unknown = tree === void 0 ? void 0 : keys.find((key) => findPermission(tree, key) === void 0);
|
|
441
|
-
return {
|
|
442
|
-
...base,
|
|
443
|
-
...compact({ operationId: located.operationId }),
|
|
444
|
-
keys,
|
|
445
|
-
...keys.length === 0 ? { finding: {
|
|
446
|
-
reason: "undocumented",
|
|
447
|
-
detail: "operation has no x-permdock-permissions"
|
|
448
|
-
} } : unknown === void 0 ? {} : { finding: {
|
|
449
|
-
reason: "unknown-key",
|
|
450
|
-
detail: unknown
|
|
451
|
-
} },
|
|
452
|
-
data,
|
|
453
|
-
provisional
|
|
454
|
-
};
|
|
455
|
-
}
|
|
456
|
-
function resolveAll(input, tree) {
|
|
457
|
-
const doc = parseDocument(input.arazzo);
|
|
458
|
-
if (typeof doc === "string") return {
|
|
459
|
-
workflowId: input.workflowId ?? "",
|
|
460
|
-
error: doc
|
|
461
|
-
};
|
|
462
|
-
const workflowId = input.workflowId ?? doc.workflows[0]?.workflowId ?? "";
|
|
463
|
-
const flat = [];
|
|
464
|
-
const error = flatten(doc, workflowId, input.inputs ?? {}, /* @__PURE__ */ new Set(), flat);
|
|
465
|
-
if (error !== void 0) return {
|
|
466
|
-
workflowId,
|
|
467
|
-
error
|
|
468
|
-
};
|
|
469
|
-
return {
|
|
470
|
-
workflowId,
|
|
471
|
-
steps: flat.map((item) => resolve(doc, input.openapi, tree, item))
|
|
472
|
-
};
|
|
473
|
-
}
|
|
474
|
-
function arazzoFindings(input, tree) {
|
|
475
|
-
const resolved = resolveAll(input, tree);
|
|
476
|
-
if ("error" in resolved) return [{
|
|
477
|
-
stepId: "document",
|
|
478
|
-
workflowId: resolved.workflowId,
|
|
479
|
-
reason: "validation",
|
|
480
|
-
detail: resolved.error
|
|
481
|
-
}];
|
|
482
|
-
return resolved.steps.flatMap((step) => step.finding === void 0 ? [] : [{
|
|
483
|
-
stepId: step.stepId,
|
|
484
|
-
workflowId: step.workflowId,
|
|
485
|
-
reason: step.finding.reason,
|
|
486
|
-
detail: step.finding.detail
|
|
487
|
-
}]);
|
|
488
|
-
}
|
|
489
|
-
function worst(outcomes) {
|
|
490
|
-
if (outcomes.includes("denied")) return "denied";
|
|
491
|
-
if (outcomes.includes("approval-required")) return "approval-required";
|
|
492
|
-
return "granted";
|
|
493
|
-
}
|
|
494
|
-
function combine(decisions) {
|
|
495
|
-
const outcome = worst(decisions.map((item) => item.outcome));
|
|
496
|
-
return decisions.find((item) => item.outcome === outcome) ?? denied("undocumented");
|
|
497
|
-
}
|
|
498
|
-
function simulateArazzo(input, tree, decide) {
|
|
499
|
-
const resolved = resolveAll(input, tree);
|
|
500
|
-
if ("error" in resolved) return freezeDeep({
|
|
501
|
-
workflowId: resolved.workflowId === "" ? "unknown" : resolved.workflowId,
|
|
502
|
-
outcome: "denied",
|
|
503
|
-
steps: [{
|
|
504
|
-
stepId: "document",
|
|
505
|
-
permissions: [],
|
|
506
|
-
decision: denied("validation")
|
|
507
|
-
}]
|
|
508
|
-
});
|
|
509
|
-
const steps = resolved.steps.map((step) => {
|
|
510
|
-
const owner = step.workflowId === resolved.workflowId ? void 0 : step.workflowId;
|
|
511
|
-
if (step.finding !== void 0) return compact({
|
|
512
|
-
stepId: step.stepId,
|
|
513
|
-
workflowId: owner,
|
|
514
|
-
operationId: step.operationId,
|
|
515
|
-
permissions: [],
|
|
516
|
-
decision: denied(step.finding.reason === "unsupported" ? "unsupported" : "undocumented")
|
|
517
|
-
});
|
|
518
|
-
const permissions = step.keys.flatMap((key) => {
|
|
519
|
-
const leaf = tree === void 0 ? void 0 : findPermission(tree, key);
|
|
520
|
-
return leaf === void 0 ? [] : [leaf];
|
|
521
|
-
});
|
|
522
|
-
return compact({
|
|
523
|
-
stepId: step.stepId,
|
|
524
|
-
workflowId: owner,
|
|
525
|
-
operationId: step.operationId,
|
|
526
|
-
permissions,
|
|
527
|
-
decision: combine(permissions.map((permission) => decide(permission, step.data))),
|
|
528
|
-
provisional: step.provisional ? true : void 0
|
|
529
|
-
});
|
|
530
|
-
});
|
|
531
|
-
return freezeDeep({
|
|
532
|
-
workflowId: resolved.workflowId,
|
|
533
|
-
outcome: worst(steps.map((step) => step.decision.outcome)),
|
|
534
|
-
steps
|
|
535
|
-
});
|
|
536
|
-
}
|
|
537
|
-
function isArazzoSimulateInput(value) {
|
|
538
|
-
return isRecord(value) && "arazzo" in value;
|
|
539
|
-
}
|
|
540
|
-
//#endregion
|
|
541
|
-
//#region src/core/row-pair.ts
|
|
542
|
-
function isRowPair(value) {
|
|
543
|
-
return value !== null && typeof value === "object" && "current" in value && "next" in value;
|
|
544
|
-
}
|
|
545
|
-
/**
|
|
546
|
-
* The row a `where` reads and the row a `check` reads. An instance check
|
|
547
|
-
* takes a `{ current, next }` pair or one row for both; a collection check
|
|
548
|
-
* has no current row, only the input it creates.
|
|
549
|
-
*/
|
|
550
|
-
function rowValues(permission, data) {
|
|
551
|
-
if (permission.kind === "collection") return {
|
|
552
|
-
current: void 0,
|
|
553
|
-
next: data
|
|
554
|
-
};
|
|
555
|
-
if (permission.kind === "instance" && isRowPair(data)) return {
|
|
556
|
-
current: data.current,
|
|
557
|
-
next: data.next
|
|
558
|
-
};
|
|
559
|
-
return {
|
|
560
|
-
current: data,
|
|
561
|
-
next: data
|
|
562
|
-
};
|
|
563
|
-
}
|
|
564
|
-
/** The row's id under `field` as a string, or `*` when the row has no string or number there. */
|
|
565
|
-
function rowIdOf(row, field = "id") {
|
|
566
|
-
if (row === null || typeof row !== "object" || !Object.hasOwn(row, field)) return "*";
|
|
567
|
-
const id = Reflect.get(row, field);
|
|
568
|
-
return typeof id === "string" || typeof id === "number" ? String(id) : "*";
|
|
569
|
-
}
|
|
570
|
-
//#endregion
|
|
571
|
-
//#region src/core/delegation.ts
|
|
572
|
-
/** The permission's scope and any scope it was renamed from: tokens issued before a rename keep working. */
|
|
573
|
-
function scopeNames(permission) {
|
|
574
|
-
return [permission.scope, ...formerScopes(permission)];
|
|
575
|
-
}
|
|
576
|
-
/**
|
|
577
|
-
* Whether a delegated caller may use a permission its principal holds, through
|
|
578
|
-
* OAuth `scopes`, RFC 9396 `authorizationDetails` or GNAP `access`.
|
|
579
|
-
* `undefined` means covered; otherwise the denial reason `decide` would add.
|
|
580
|
-
*/
|
|
581
|
-
function coveredByDelegation(permission, delegation, resourceId, hasActor = false) {
|
|
582
|
-
const unscoped = hasActor ? "no-delegation" : void 0;
|
|
583
|
-
if (delegation === void 0) return unscoped;
|
|
584
|
-
const hasScopes = delegation.scopes !== void 0;
|
|
585
|
-
const hasDetails = delegation.authorizationDetails !== void 0;
|
|
586
|
-
const hasAccess = delegation.access !== void 0;
|
|
587
|
-
if (!hasScopes && !hasDetails && !hasAccess) return unscoped;
|
|
588
|
-
const emptyScopes = hasScopes && (delegation.scopes?.length ?? 0) === 0;
|
|
589
|
-
const emptyAccess = hasAccess && (delegation.access?.length ?? 0) === 0;
|
|
590
|
-
if (emptyScopes && !hasDetails && !hasAccess) return "no-delegation";
|
|
591
|
-
if (emptyAccess && !hasScopes && !hasDetails) return "no-delegation";
|
|
592
|
-
if (emptyScopes && emptyAccess && !hasDetails) return "no-delegation";
|
|
593
|
-
const scopes = scopeNames(permission);
|
|
594
|
-
const scopeOk = delegation.scopes?.some((scope) => scopes.includes(scope)) ?? false;
|
|
595
|
-
const detailOk = delegation.authorizationDetails?.some((detail) => {
|
|
596
|
-
if (detail.type !== permission.resource) return false;
|
|
597
|
-
const identifier = detail["identifier"];
|
|
598
|
-
if (identifier !== void 0 && (typeof identifier !== "string" || identifier !== resourceId)) return false;
|
|
599
|
-
const actions = detail.actions;
|
|
600
|
-
if (actions === void 0) return true;
|
|
601
|
-
return Array.isArray(actions) && actions.includes(permission.action);
|
|
602
|
-
}) ?? false;
|
|
603
|
-
const accessOk = accessCovers(permission, delegation.access, resourceId);
|
|
604
|
-
if (scopeOk || detailOk || accessOk) return;
|
|
605
|
-
return "not-delegated";
|
|
606
|
-
}
|
|
607
|
-
function coversRequirements(tree, requires, delegation, resourceId, hasActor = false) {
|
|
608
|
-
return (requires ?? []).every((key) => {
|
|
609
|
-
const leaf = findPermission(tree, key);
|
|
610
|
-
return leaf !== void 0 && coveredByDelegation(leaf, delegation, resourceId, hasActor) === void 0;
|
|
611
|
-
});
|
|
612
|
-
}
|
|
613
|
-
function requiresStandIn(grant) {
|
|
614
|
-
return (grant.requires ?? []).length > 0 && annotationsFor(grant.permission).readOnlyHint && !flattenGrantee(grant.to).some((item) => item.kind === "role");
|
|
615
|
-
}
|
|
616
|
-
function accessCovers(permission, access, resourceId) {
|
|
617
|
-
if (access === void 0) return false;
|
|
618
|
-
return access.some((entry) => {
|
|
619
|
-
if (typeof entry === "string") return scopeNames(permission).includes(entry);
|
|
620
|
-
if (entry === null || typeof entry !== "object") return false;
|
|
621
|
-
const type = entry["type"];
|
|
622
|
-
if (typeof type !== "string" || !typeMatches(type, permission.resource)) return false;
|
|
623
|
-
const actions = entry["actions"];
|
|
624
|
-
if (actions !== void 0 && (!Array.isArray(actions) || !actions.includes(permission.action))) return false;
|
|
625
|
-
const identifier = entry["identifier"];
|
|
626
|
-
if (identifier !== void 0 && (typeof identifier !== "string" || identifier !== resourceId)) return false;
|
|
627
|
-
return true;
|
|
628
|
-
});
|
|
629
|
-
}
|
|
630
|
-
function typeMatches(type, resource) {
|
|
631
|
-
if (type === resource) return true;
|
|
632
|
-
return type.endsWith(`/${resource}`);
|
|
633
|
-
}
|
|
634
|
-
/**
|
|
635
|
-
* Whether the subject's principal is a `from` of the delegation: every item
|
|
636
|
-
* matches, with roles checked against the roles the principal holds here
|
|
637
|
-
* (`matchGrantee` leaves role holding to the caller) and nothing that needs a
|
|
638
|
-
* row.
|
|
639
|
-
*/
|
|
640
|
-
function handsOver(delegation, subject, heldRoles, now) {
|
|
641
|
-
const items = flattenGrantee(delegation.from);
|
|
642
|
-
if (items.length === 0 || subject.principal === null) return false;
|
|
643
|
-
return items.every((item) => {
|
|
644
|
-
if (item.kind === "role") return heldRoles.has(item.role);
|
|
645
|
-
if (item.kind === "relation") return false;
|
|
646
|
-
const match = matchGrantee(item, subject, now, void 0);
|
|
647
|
-
return match.matched && match.where === void 0;
|
|
648
|
-
});
|
|
649
|
-
}
|
|
650
|
-
/**
|
|
651
|
-
* The permission keys the policy's delegations let `subject.actor` use for
|
|
652
|
-
* `subject.principal` right now: the union over every active delegation whose
|
|
653
|
-
* `to` matches the actor and whose `from` the principal holds. `undefined`
|
|
654
|
-
* when none applies, so the call falls back to the token delegation alone.
|
|
655
|
-
* An actor with `readOnly: true` gets only each delegation's read-only keys.
|
|
656
|
-
* Attenuation only: a key here still needs a matching allow and no deny.
|
|
657
|
-
*/
|
|
658
|
-
function delegatedPermissions(delegations, subject, heldRoles, now) {
|
|
659
|
-
const actor = subject.actor;
|
|
660
|
-
if (actor === void 0 || delegations === void 0) return;
|
|
661
|
-
let keys;
|
|
662
|
-
for (const delegation of delegations) {
|
|
663
|
-
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;
|
|
664
|
-
keys ??= /* @__PURE__ */ new Set();
|
|
665
|
-
for (const key of actor.readOnly === true ? delegation.readOnly : delegation.permissions) keys.add(key);
|
|
666
|
-
}
|
|
667
|
-
return keys;
|
|
668
|
-
}
|
|
669
|
-
//#endregion
|
|
670
|
-
//#region src/conditions/bind.ts
|
|
671
|
-
function isPrimitive(value) {
|
|
672
|
-
return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
673
|
-
}
|
|
674
|
-
const ALWAYS$1 = {
|
|
675
|
-
op: "eq",
|
|
676
|
-
field: "_",
|
|
677
|
-
value: true
|
|
678
|
-
};
|
|
679
|
-
const NEVER = {
|
|
680
|
-
op: "or",
|
|
681
|
-
conditions: []
|
|
682
|
-
};
|
|
683
|
-
function bindValue(value, subject, only) {
|
|
684
|
-
if (isConditionRef(value) && only !== void 0 && !only(value.ref)) return value;
|
|
685
|
-
if (isConditionRef(value)) {
|
|
686
|
-
const resolved = resolveConditionRef(value.ref, subject);
|
|
687
|
-
if (Array.isArray(resolved)) return resolved.filter((item) => isPrimitive(item));
|
|
688
|
-
return isPrimitive(resolved) ? resolved : null;
|
|
689
|
-
}
|
|
690
|
-
if (Array.isArray(value)) return value.map((item) => bindValue(item, subject, only));
|
|
691
|
-
return value;
|
|
692
|
-
}
|
|
693
|
-
function bindArg(arg, subject, only) {
|
|
694
|
-
return arg !== null && typeof arg === "object" && "field" in arg && !isConditionRef(arg) ? arg : bindValue(arg, subject, only);
|
|
695
|
-
}
|
|
696
|
-
/**
|
|
697
|
-
* Replaces every `principal.*` / `context.*` ref with the subject's value, and
|
|
698
|
-
* a `liveSession` node with a constant, so a `where()` result compiles the
|
|
699
|
-
* same without the subject. A ref the subject
|
|
700
|
-
* does not hold binds to `null` (or `[]` in a list), which never matches, as
|
|
701
|
-
* in `evaluateCondition`. With `only`, refs it rejects stay refs.
|
|
702
|
-
*/
|
|
703
|
-
function bindConditionRefs(condition, subject, only) {
|
|
704
|
-
switch (condition.op) {
|
|
705
|
-
case "and":
|
|
706
|
-
case "or": return {
|
|
707
|
-
op: condition.op,
|
|
708
|
-
conditions: condition.conditions.map((child) => bindConditionRefs(child, subject, only))
|
|
709
|
-
};
|
|
710
|
-
case "not": return {
|
|
711
|
-
op: "not",
|
|
712
|
-
condition: bindConditionRefs(condition.condition, subject, only)
|
|
713
|
-
};
|
|
714
|
-
case "in":
|
|
715
|
-
case "notIn": {
|
|
716
|
-
const value = condition.value;
|
|
717
|
-
if (isConditionRef(value) && only !== void 0 && !only(value.ref)) return condition;
|
|
718
|
-
const bound = bindValue(value, subject, only);
|
|
719
|
-
return {
|
|
720
|
-
...condition,
|
|
721
|
-
value: Array.isArray(bound) ? bound : []
|
|
722
|
-
};
|
|
723
|
-
}
|
|
724
|
-
case "eq":
|
|
725
|
-
case "ne":
|
|
726
|
-
case "gt":
|
|
727
|
-
case "gte":
|
|
728
|
-
case "lt":
|
|
729
|
-
case "lte":
|
|
730
|
-
case "contains": return {
|
|
731
|
-
...condition,
|
|
732
|
-
value: bindValue(condition.value, subject, only)
|
|
733
|
-
};
|
|
734
|
-
case "sqlFunction": return {
|
|
735
|
-
...condition,
|
|
736
|
-
args: condition.args.map((arg) => bindArg(arg, subject, only)),
|
|
737
|
-
twin: bindConditionRefs(condition.twin, subject, only)
|
|
738
|
-
};
|
|
739
|
-
case "liveSession": return subject.liveSession === true ? ALWAYS$1 : NEVER;
|
|
740
|
-
case "isNull":
|
|
741
|
-
case "memberOf":
|
|
742
|
-
case "related":
|
|
743
|
-
case "opaque": return condition;
|
|
744
|
-
default: return condition;
|
|
745
|
-
}
|
|
746
|
-
}
|
|
747
|
-
//#endregion
|
|
748
|
-
//#region src/core/where-scope.ts
|
|
749
|
-
const ALWAYS = freezeDeep({
|
|
750
|
-
op: "eq",
|
|
751
|
-
field: "_",
|
|
752
|
-
value: true
|
|
753
|
-
});
|
|
754
|
-
function eq(field, value) {
|
|
755
|
-
return value === void 0 ? {
|
|
756
|
-
op: "or",
|
|
757
|
-
conditions: []
|
|
758
|
-
} : {
|
|
759
|
-
op: "eq",
|
|
760
|
-
field,
|
|
761
|
-
value
|
|
762
|
-
};
|
|
763
|
-
}
|
|
764
|
-
/** One equality per partitioning scope key on the membership's chain, outermost first. */
|
|
765
|
-
function namedFilters(membership, scope) {
|
|
766
|
-
if (findScope(scope.scopes, membership.scope ?? "") === void 0 || !inTeam(membership, scope.scopes, scope.team) || !activeFor(membership, scope.scopes, scope.tenant) || membership.scope === void 0) return null;
|
|
767
|
-
const filters = [];
|
|
768
|
-
for (const name of scopeChain(scope.scopes, membership.scope).toReversed()) {
|
|
769
|
-
const key = scope.fieldOf?.(name) ?? findScope(scope.scopes, name)?.key;
|
|
770
|
-
if (key !== void 0 && scope.partitioned(name, key)) filters.push(eq(key, scopeIdOf(membership, name)));
|
|
771
|
-
}
|
|
772
|
-
return filters;
|
|
773
|
-
}
|
|
774
|
-
/**
|
|
775
|
-
* The row filters a grant's membership implies, or `null` when the grant
|
|
776
|
-
* reaches no row in this scope (another tenant, no active tenant, expired).
|
|
777
|
-
*/
|
|
778
|
-
function scopeFilters(grant, scope) {
|
|
779
|
-
if (grant.scope === void 0) return [];
|
|
780
|
-
const membership = grant.membership;
|
|
781
|
-
if (membership === void 0 || isMembershipExpired(membership, scope.now)) return null;
|
|
782
|
-
if (typeof grant.scope === "string") return membership.scope === grant.scope ? namedFilters(membership, scope) : null;
|
|
783
|
-
const on = membership.on;
|
|
784
|
-
if (on === void 0) return null;
|
|
785
|
-
if (scope.resources === void 0) return on.resource === grant.scope.resource && on.resource === scope.resource ? [eq("id", on.id)] : null;
|
|
786
|
-
const roleResource = scope.resources.get(grant.scope.resource);
|
|
787
|
-
if (on.resource !== grant.scope.resource && membershipField(roleResource, on.resource, scope.resources) === void 0) return null;
|
|
788
|
-
const walked = scope.graph === true ? resourceRoleCondition(scope.resources.get(scope.resource), on.resource, [on.id], scope.resources) : void 0;
|
|
789
|
-
if (walked !== void 0) return [walked];
|
|
790
|
-
const field = membershipField(scope.resources.get(scope.resource), on.resource, scope.resources);
|
|
791
|
-
return field === void 0 ? null : [eq(field, on.id)];
|
|
792
|
-
}
|
|
793
|
-
function all(conditions) {
|
|
794
|
-
if (conditions.length === 0) return ALWAYS;
|
|
795
|
-
return sole(conditions) ?? {
|
|
796
|
-
op: "and",
|
|
797
|
-
conditions: [...conditions]
|
|
798
|
-
};
|
|
799
|
-
}
|
|
800
|
-
function scopedCondition(grant, scope) {
|
|
801
|
-
const filters = scopeFilters(grant, scope);
|
|
802
|
-
if (filters === null) return null;
|
|
803
|
-
const parts = grant.where === void 0 ? filters : [...filters, grant.where];
|
|
804
|
-
return parts.length === 0 ? "always" : all(parts);
|
|
805
|
-
}
|
|
806
|
-
/** Whether an unconditional `deny` removes every row `allow` could reach. */
|
|
807
|
-
function covers(deny, allow, scopes) {
|
|
808
|
-
if (deny.where !== void 0) return false;
|
|
809
|
-
const denied = deny.membership;
|
|
810
|
-
if (deny.scope === void 0 || denied === void 0) return deny.scope === void 0;
|
|
811
|
-
const allowed = allow.membership;
|
|
812
|
-
if (allowed === void 0) return false;
|
|
813
|
-
if (typeof deny.scope === "object") return typeof allow.scope === "object" && denied.on?.resource === allowed.on?.resource && denied.on?.id === allowed.on?.id;
|
|
814
|
-
if (typeof allow.scope !== "string" || allowed.scope === void 0) return false;
|
|
815
|
-
const chain = scopeChain(scopes, deny.scope);
|
|
816
|
-
return scopeChain(scopes, allowed.scope).includes(deny.scope) && chain.every((name) => scopeIdOf(allowed, name) === scopeIdOf(denied, name));
|
|
817
|
-
}
|
|
818
|
-
/**
|
|
819
|
-
* The portable filter for one permission's grants: allows OR together, each
|
|
820
|
-
* narrowed to its membership's tenant, team or resource; any applicable
|
|
821
|
-
* portable deny is subtracted, and an unconditional one empties the result.
|
|
822
|
-
*/
|
|
823
|
-
function collect(grants, scope) {
|
|
824
|
-
const none = {
|
|
825
|
-
op: "or",
|
|
826
|
-
conditions: []
|
|
827
|
-
};
|
|
828
|
-
const partial = grants.some((grant) => grant.portable === false);
|
|
829
|
-
const denies = [];
|
|
830
|
-
for (const grant of grants) {
|
|
831
|
-
if (grant.effect !== "deny" || grant.portable === false || !isActive(grant.validity, scope.now)) continue;
|
|
832
|
-
const condition = scopedCondition(grant, scope);
|
|
833
|
-
if (condition === "always") return {
|
|
834
|
-
condition: none,
|
|
835
|
-
partial
|
|
836
|
-
};
|
|
837
|
-
if (condition !== null) denies.push({
|
|
838
|
-
grant,
|
|
839
|
-
condition
|
|
840
|
-
});
|
|
841
|
-
}
|
|
842
|
-
const parts = [];
|
|
843
|
-
for (const grant of grants) {
|
|
844
|
-
if (grant.effect !== "allow" || grant.portable === false || !isActive(grant.validity, scope.now)) continue;
|
|
845
|
-
const condition = scopedCondition(grant, scope);
|
|
846
|
-
if (condition === null || denies.some((deny) => covers(deny.grant, grant, scope.scopes))) continue;
|
|
847
|
-
parts.push(all([...condition === "always" ? [] : [condition], ...denies.map((deny) => ({
|
|
848
|
-
op: "not",
|
|
849
|
-
condition: deny.condition
|
|
850
|
-
}))]));
|
|
851
|
-
}
|
|
852
|
-
if (parts.length === 0) return {
|
|
853
|
-
condition: none,
|
|
854
|
-
partial
|
|
855
|
-
};
|
|
856
|
-
return {
|
|
857
|
-
condition: sole(parts) ?? {
|
|
858
|
-
op: "or",
|
|
859
|
-
conditions: parts
|
|
860
|
-
},
|
|
861
|
-
partial
|
|
862
|
-
};
|
|
863
|
-
}
|
|
864
|
-
/**
|
|
865
|
-
* `collect`, with every subject ref bound to `scope.subject` and the subject
|
|
866
|
-
* attached (not enumerable) for `memberOf`, which needs its memberships.
|
|
867
|
-
*/
|
|
868
|
-
function whereFromGrants(grants, scope) {
|
|
869
|
-
const { condition, partial } = collect(grants, scope);
|
|
870
|
-
const result = {
|
|
871
|
-
condition: bindConditionRefs(condition, scope.subject),
|
|
872
|
-
partial
|
|
873
|
-
};
|
|
874
|
-
Object.defineProperty(result, "subject", {
|
|
875
|
-
value: scope.subject,
|
|
876
|
-
enumerable: false
|
|
877
|
-
});
|
|
878
|
-
Object.defineProperty(result, "scopes", {
|
|
879
|
-
value: scope.scopes,
|
|
880
|
-
enumerable: false
|
|
881
|
-
});
|
|
882
|
-
if (scope.resources !== void 0) Object.defineProperty(result, "resources", {
|
|
883
|
-
value: scope.resources,
|
|
884
|
-
enumerable: false
|
|
885
|
-
});
|
|
886
|
-
return freezeDeep(result);
|
|
887
|
-
}
|
|
888
|
-
//#endregion
|
|
889
|
-
//#region src/core/snapshot-sign.ts
|
|
890
|
-
async function signSnapshot(snapshot, signer, audience) {
|
|
891
|
-
const payload = { snapshot };
|
|
892
|
-
if (snapshot.subject.principal !== null) payload["sub"] = snapshot.subject.principal.id;
|
|
893
|
-
return await signer.sign(payload, compact({
|
|
894
|
-
typ: "permdock-snapshot+jwt",
|
|
895
|
-
audience,
|
|
896
|
-
expiresAt: snapshot.expiresAt
|
|
897
|
-
}));
|
|
898
|
-
}
|
|
899
|
-
//#endregion
|
|
900
|
-
//#region src/core/snapshot.ts
|
|
901
|
-
function plainPermission(leaf) {
|
|
902
|
-
return {
|
|
903
|
-
key: leaf.key,
|
|
904
|
-
scope: leaf.scope,
|
|
905
|
-
resource: leaf.resource,
|
|
906
|
-
action: leaf.action,
|
|
907
|
-
meta: leaf.meta,
|
|
908
|
-
kind: leaf.kind
|
|
909
|
-
};
|
|
910
|
-
}
|
|
911
|
-
function plainRole(leaf) {
|
|
912
|
-
return compact({
|
|
913
|
-
key: leaf.key,
|
|
914
|
-
on: leaf.on,
|
|
915
|
-
assignable: leaf.assignable,
|
|
916
|
-
meta: leaf.meta,
|
|
917
|
-
kind: leaf.kind
|
|
918
|
-
});
|
|
919
|
-
}
|
|
920
|
-
function plainPlan(leaf) {
|
|
921
|
-
return {
|
|
922
|
-
key: leaf.key,
|
|
923
|
-
meta: leaf.meta,
|
|
924
|
-
kind: leaf.kind
|
|
925
|
-
};
|
|
926
|
-
}
|
|
927
|
-
function snapshotGrant(grant, membership) {
|
|
928
|
-
const scope = grant.scope === "global" ? void 0 : typeof grant.scope === "string" ? grant.scope : { resource: grant.scope.resource };
|
|
929
|
-
const entry = compact({
|
|
930
|
-
permission: grant.permission.key,
|
|
931
|
-
effect: grant.effect,
|
|
932
|
-
role: grant.role,
|
|
933
|
-
to: grant.to,
|
|
934
|
-
where: grant.portable ? grant.where : void 0,
|
|
935
|
-
check: grant.portable ? grant.check : void 0,
|
|
936
|
-
approval: grant.approval,
|
|
937
|
-
scope,
|
|
938
|
-
membership,
|
|
939
|
-
portable: grant.portable ? void 0 : false,
|
|
940
|
-
fields: grant.fields,
|
|
941
|
-
validity: grant.validity,
|
|
942
|
-
name: grant.name,
|
|
943
|
-
meta: grant.meta,
|
|
944
|
-
obligations: grant.obligations
|
|
945
|
-
});
|
|
946
|
-
return freezeDeep(entry);
|
|
947
|
-
}
|
|
948
|
-
const CARRIED = /* @__PURE__ */ new Set([
|
|
949
|
-
"id",
|
|
950
|
-
"roles",
|
|
951
|
-
"plans",
|
|
952
|
-
"tenant",
|
|
953
|
-
"memberships"
|
|
954
|
-
]);
|
|
955
|
-
/** Principal refs the snapshot principal does not carry (`claims`, `teamIds`, …) are bound to the subject's values. */
|
|
956
|
-
function isClaimRef(ref) {
|
|
957
|
-
const [root, head] = ref.split(".", 2);
|
|
958
|
-
return root === "principal" && !CARRIED.has(String(head));
|
|
959
|
-
}
|
|
960
|
-
function bindClaims(grant, subject) {
|
|
961
|
-
if (grant.where === void 0 && grant.check === void 0) return grant;
|
|
962
|
-
return freezeDeep(compact({
|
|
963
|
-
...grant,
|
|
964
|
-
where: grant.where === void 0 ? void 0 : bindConditionRefs(grant.where, subject, isClaimRef),
|
|
965
|
-
check: grant.check === void 0 ? void 0 : bindConditionRefs(grant.check, subject, isClaimRef)
|
|
966
|
-
}));
|
|
967
|
-
}
|
|
968
|
-
function notEntitledOf(items) {
|
|
969
|
-
const seen = /* @__PURE__ */ new Map();
|
|
970
|
-
for (const { grant } of items) {
|
|
971
|
-
const key = `${grant.permission.key}\u0000${grant.role ?? ""}`;
|
|
972
|
-
if (!seen.has(key)) seen.set(key, {
|
|
973
|
-
permission: grant.permission.key,
|
|
974
|
-
role: grant.role,
|
|
975
|
-
to: grant.to
|
|
976
|
-
});
|
|
977
|
-
}
|
|
978
|
-
return seen.size === 0 ? void 0 : [...seen.values()];
|
|
979
|
-
}
|
|
980
|
-
function buildSnapshot(input) {
|
|
981
|
-
const now = input.now ?? Math.floor(Date.now() / 1e3);
|
|
982
|
-
const principal = input.subject.principal;
|
|
983
|
-
const allTenants = tenantsOf(principal, scopeList(input.scopes));
|
|
984
|
-
const tenants = input.tenants === "all" ? allTenants : principal?.tenant === void 0 ? [] : [principal.tenant];
|
|
985
|
-
const include = input.include;
|
|
986
|
-
const included = (permission) => include === void 0 || include.length === 0 || include.some((prefix) => permission.key === prefix || permission.key.startsWith(`${prefix}.`) || permission.resource === prefix);
|
|
987
|
-
const grants = input.grants.filter((item) => included(item.grant.permission)).map((item) => bindClaims(snapshotGrant(item.grant, item.membership), input.subject));
|
|
988
|
-
const ids = {};
|
|
989
|
-
for (const item of input.grants) {
|
|
990
|
-
const name = item.grant.permission.resource;
|
|
991
|
-
const field = input.idOf?.(name);
|
|
992
|
-
if (field !== void 0 && field !== "id" && included(item.grant.permission)) ids[name] = field;
|
|
993
|
-
}
|
|
994
|
-
const assignableFor = input.assignable;
|
|
995
|
-
const assignable = assignableFor === void 0 ? [] : tenants.map((tenant) => {
|
|
996
|
-
const entry = assignableFor(tenant);
|
|
997
|
-
const permissions = entry.permissions.filter(included).map(plainPermission);
|
|
998
|
-
if (entry.levels === void 0) return {
|
|
999
|
-
...entry,
|
|
1000
|
-
permissions
|
|
1001
|
-
};
|
|
1002
|
-
const keys = new Set(permissions.map((leaf) => leaf.key));
|
|
1003
|
-
const levels = Object.fromEntries(Object.entries(entry.levels).filter(([key]) => keys.has(key)));
|
|
1004
|
-
return compact({
|
|
1005
|
-
...entry,
|
|
1006
|
-
permissions,
|
|
1007
|
-
levels: Object.keys(levels).length === 0 ? void 0 : levels
|
|
1008
|
-
});
|
|
1009
|
-
});
|
|
1010
|
-
return freezeDeep(compact({
|
|
1011
|
-
v: 1,
|
|
1012
|
-
issuedAt: now,
|
|
1013
|
-
subject: compact({
|
|
1014
|
-
principal: principal === null ? null : compact({
|
|
1015
|
-
id: principal.id,
|
|
1016
|
-
roles: principal.roles ?? [],
|
|
1017
|
-
plans: principal.plans,
|
|
1018
|
-
tenant: principal.tenant,
|
|
1019
|
-
memberships: principal.memberships
|
|
1020
|
-
}),
|
|
1021
|
-
delegation: snapshotDelegation(input.subject, input.delegated !== void 0),
|
|
1022
|
-
context: input.subject.context
|
|
1023
|
-
}),
|
|
1024
|
-
roles: input.roles,
|
|
1025
|
-
audiences: input.audiences,
|
|
1026
|
-
grants,
|
|
1027
|
-
tenants,
|
|
1028
|
-
include,
|
|
1029
|
-
simulated: input.simulated === true ? true : void 0,
|
|
1030
|
-
expiresAt: input.subject.expiresAt,
|
|
1031
|
-
scopes: input.scopes,
|
|
1032
|
-
ids: Object.keys(ids).length === 0 ? void 0 : ids,
|
|
1033
|
-
assignable: assignable.length > 0 ? assignable : void 0,
|
|
1034
|
-
delegated: input.delegated === void 0 ? void 0 : [...input.delegated].toSorted(),
|
|
1035
|
-
notEntitled: notEntitledOf((input.notEntitled ?? []).filter((item) => included(item.grant.permission))),
|
|
1036
|
-
vocabulary: input.vocabulary === void 0 ? void 0 : compact({
|
|
1037
|
-
roles: listRoles(input.vocabulary.roles).length === 0 ? void 0 : Object.fromEntries(listRoles(input.vocabulary.roles).map((leaf) => [leaf.key, plainRole(leaf)])),
|
|
1038
|
-
plans: listPlans(input.vocabulary.plans).length === 0 ? void 0 : Object.fromEntries(listPlans(input.vocabulary.plans).map((leaf) => [leaf.key, plainPlan(leaf)]))
|
|
1039
|
-
})
|
|
1040
|
-
}));
|
|
1041
|
-
}
|
|
1042
|
-
/**
|
|
1043
|
-
* The token delegation as the client sees it. An actor with no token
|
|
1044
|
-
* delegation gets an empty `scopes` list so the client ceiling agrees with
|
|
1045
|
-
* `no-delegation`, unless a policy delegation applies (`delegated`), which
|
|
1046
|
-
* then is the ceiling.
|
|
1047
|
-
*/
|
|
1048
|
-
function snapshotDelegation(subject, delegated) {
|
|
1049
|
-
const delegation = subject.delegation;
|
|
1050
|
-
if (subject.actor === void 0 || delegated) return delegation;
|
|
1051
|
-
if (delegation?.scopes === void 0 && delegation?.authorizationDetails === void 0 && delegation?.access === void 0) return {
|
|
1052
|
-
...delegation,
|
|
1053
|
-
scopes: []
|
|
1054
|
-
};
|
|
1055
|
-
return delegation;
|
|
1056
|
-
}
|
|
1057
|
-
function rejectUnsafe(value, path) {
|
|
1058
|
-
if (value === null || typeof value !== "object") return;
|
|
1059
|
-
if (Array.isArray(value)) {
|
|
1060
|
-
for (const [index, item] of value.entries()) rejectUnsafe(item, `${path}[${index}]`);
|
|
1061
|
-
return;
|
|
1062
|
-
}
|
|
1063
|
-
for (const key of Object.keys(value)) {
|
|
1064
|
-
if (isForbiddenKey(key)) throw new Error(`PermDock: unsafe snapshot key '${key}' at ${path}`);
|
|
1065
|
-
rejectUnsafe(value[key], `${path}.${key}`);
|
|
1066
|
-
}
|
|
1067
|
-
}
|
|
1068
|
-
function parseSnapshot(json) {
|
|
1069
|
-
const input = typeof json === "string" ? JSON.parse(json) : json;
|
|
1070
|
-
if (input === null || typeof input !== "object" || Array.isArray(input)) throw new Error("PermDock: snapshot must be an object");
|
|
1071
|
-
const value = typeof json === "string" || Object.isFrozen(input) ? input : JSON.parse(JSON.stringify(input));
|
|
1072
|
-
rejectUnsafe(value, "$");
|
|
1073
|
-
const version = value["v"];
|
|
1074
|
-
if (version !== 1) throw new Error(`PermDock: unsupported snapshot version '${String(version)}'`);
|
|
1075
|
-
return freezeDeep(value);
|
|
1076
|
-
}
|
|
1077
|
-
//#endregion
|
|
1078
|
-
export { evaluateCondition as _, whereFromGrants as a, coversRequirements as c, isRowPair as d, rowIdOf as f, simulateArazzo as g, isArazzoSimulateInput as h, signSnapshot as i, delegatedPermissions as l, arazzoFindings as m, parseSnapshot as n, bindConditionRefs as o, rowValues as p, snapshotGrant as r, coveredByDelegation as s, buildSnapshot as t, requiresStandIn as u };
|