permdock 0.3.1 → 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/{openapi-schema--ARjyfQr.js → 2020-C9VN-x8c.js} +5 -132
- package/dist/a2a/index.d.ts +8 -6
- package/dist/a2a/index.js +21 -31
- 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 -23
- package/dist/ai-sdk/index.js +38 -21
- package/dist/app-data-MuyzVqX8.js +60 -0
- 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/{approvers-DT4AVyIg.js → approvers-CqPOLD-o.js} +1 -1
- package/dist/arazzo-B6lebmiQ.js +36 -0
- package/dist/{arazzo-BAgw9ap6.js → arazzo-BWhNF-k0.js} +24 -17
- 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 +228 -75
- 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 +11 -23
- package/dist/better-supabase/index.d.ts +438 -86
- package/dist/better-supabase/index.js +1027 -184
- package/dist/bind--9EFVYWF.d.ts +38 -0
- package/dist/{bind-CuzGytRf.js → bind-CZzhx-Vj.js} +22 -10
- package/dist/body-CH5of8Ne.js +10 -0
- package/dist/body-text-QcXok_SI.js +52 -0
- package/dist/build-instance-BMnAudHn.js +52 -0
- package/dist/{canonical-json-DemiK4Vp.js → canonical-json-BC8_nMTw.js} +6 -6
- package/dist/{capability-2kYTMWDv.d.ts → capability-BSslw1QV.d.ts} +44 -25
- package/dist/{capability-4qPdO9gk.js → capability-N1K9IpqS.js} +69 -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-BECMPrwc.js +100 -0
- package/dist/catalog-DjhMYYCq.js +1 -0
- package/dist/catalog-R_A__RsH.js +52 -0
- package/dist/{catalog-doc-DdGm82XT.js → catalog-doc-C9wjsfNY.js} +54 -25
- 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 +26 -30
- package/dist/clerk/index.d.ts +9 -8
- package/dist/clerk/index.js +15 -45
- package/dist/cli/bin.js +36 -17
- package/dist/cli/index.d.ts +20 -6
- package/dist/cli/index.js +164 -4
- package/dist/cloud/index.d.ts +102 -63
- package/dist/cloud/index.js +240 -347
- package/dist/cloud-CIoHNevm.js +87 -0
- package/dist/codemod-Bmj9dWMH.js +37 -0
- package/dist/codemod-Cxvvc70T.js +2084 -0
- package/dist/{collect-DSTE3ml9.js → collect-CrZJJnEF.js} +79 -17
- package/dist/collect-DloHbDVa.js +55 -0
- package/dist/collect-FlXJlhus.js +1 -0
- package/dist/command-L8EstFNm.js +6 -0
- package/dist/{compact-y6vfu2_f.js → compact-CAf557ZB.js} +11 -1
- package/dist/compile/index.d.ts +1 -1
- package/dist/compile/index.js +1 -2
- package/dist/{compile-Ba4blROR.js → compile-CMqMx_IN.js} +13 -9
- package/dist/{compile-BkRyBDBw.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-BJiM-xAm.js → config-bs_kZeYq.js} +15 -10
- package/dist/{config-report-CdCgbRnV.js → config-report-DUgj62Ai.js} +17 -8
- package/dist/{connection-CU8MQxRi.js → connection-DjhIJSs2.js} +8 -6
- package/dist/constants-DcJABbLW.js +20 -0
- package/dist/{context-Bcy85rGi.js → context-bbFHR-0D.js} +16 -5
- package/dist/convex/index.d.ts +11 -10
- package/dist/convex/index.js +18 -18
- 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-DnrmLnLW.js +323 -0
- package/dist/{credential-8P81ff4u.js → credential-DM2um3ha.js} +153 -32
- package/dist/credentials-DPyHmYz5.js +74 -0
- package/dist/deciding-columns-Sq12mEA6.js +123 -0
- package/dist/delegation-DaXVdDhM.js +286 -0
- package/dist/delegation-input-FTxMK3ji.js +19 -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-D8jDHgsl.d.ts +19 -0
- package/dist/{describe-DMYiCjJV.d.ts → describe-BZUsixiL.d.ts} +11 -2
- package/dist/{describe-B_gVZEVi.js → describe-BybMRY7A.js} +10 -5
- package/dist/device-BARQ8eYG.js +193 -0
- package/dist/diff-CxZo9pTq.js +37 -0
- package/dist/{diff-2VaeChzX.js → diff-DCePiN6M.js} +61 -55
- package/dist/doctor-CxiwSfqH.js +44 -0
- package/dist/doctor-DFjUxf2f.js +2361 -0
- package/dist/drizzle/index.d.ts +5 -3
- package/dist/drizzle/index.js +6 -14
- package/dist/elysia/index.d.ts +16 -13
- package/dist/elysia/index.js +14 -13
- package/dist/env-DJZrPjRi.js +8 -0
- package/dist/errors-BDUwg2qC.js +27 -0
- package/dist/{errors-Cz5zn0mW.js → errors-BKy0EfhN.js} +6 -10
- package/dist/errors-BWXBMaKK.d.ts +11 -0
- package/dist/{errors-DPdqI50v.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-tz6D9A2G.js → evaluations-DZ2CbV5k.js} +181 -32
- package/dist/eve/index.d.ts +12 -16
- package/dist/eve/index.js +23 -29
- 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 +14 -12
- package/dist/fastify/index.d.ts +26 -13
- package/dist/fastify/index.js +17 -36
- 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/{files-DWUN9PzI.js → files-D_JIzUrP.js} +12 -3
- package/dist/{fixtures-ht28Cplr.js → fixtures-B7XrLeY7.js} +12 -12
- package/dist/flags-C3DktBDY.js +86 -0
- package/dist/{from-snapshot-CTLijvdm.js → from-snapshot-D2lZt4Dd.js} +78 -65
- package/dist/{generate-CH7ThJ14.js → generate-CNU1pIOo.js} +1 -3
- package/dist/grantee-Cn1HyUsI.js +254 -0
- package/dist/grantee-conditions-CcXf8hMM.js +271 -0
- package/dist/grantee-match-DHArqY82.js +142 -0
- 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-H_KARDVC.js → helpers-DTcZOzhF.js} +47 -39
- package/dist/hono/index.d.ts +12 -9
- package/dist/hono/index.js +14 -13
- package/dist/{hosted-DJQw46hn.js → hosted-BZIAYvon.js} +64 -15
- package/dist/hosted-DBDX0M-P.d.ts +78 -0
- package/dist/{http-SO7qGttf.js → http-BBoKefeS.js} +35 -2
- package/dist/{http-DPuDaChb.d.ts → http-B_LphE5Y.d.ts} +1 -2
- package/dist/http-DXJ37RDA.js +46 -0
- package/dist/{http-BIhmLfCc.js → http-ujKm0JXE.js} +3 -26
- package/dist/{openapi-import-cmwetbzw.js → import-CNV7I2Dw.js} +30 -26
- package/dist/{rls-import-4lLW_pbb.js → import-DMmOG27O.js} +271 -128
- 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-DOVf7RJv.d.ts +900 -0
- package/dist/{index-C8z4RjQV.d.ts → index-SGdIQyzc.d.ts} +34 -16
- package/dist/index.d.ts +20 -14
- package/dist/index.js +33 -23
- package/dist/init-DeMYsnYJ.js +96 -0
- package/dist/init-GG6Jh8HD.js +95 -0
- package/dist/{instance-options-jARdwfPN.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-BsAflUGW.js → json-schema-B-vAwlde.js} +46 -9
- package/dist/json-schema-CN_iLFH2.d.ts +40 -0
- package/dist/jwt/index.d.ts +18 -11
- package/dist/jwt/index.js +166 -145
- package/dist/{kernel-_RRHmnMY.js → kernel-5JatXyND.js} +120 -43
- package/dist/kysely/index.d.ts +5 -3
- package/dist/kysely/index.js +6 -14
- package/dist/{live-options-H2eG8dfJ.js → live-options-BaAFCIiu.js} +16 -3
- package/dist/load-BxEtwlBS.js +1 -0
- package/dist/{load-DhWEB9P1.js → load-DFS_ry0W.js} +31 -7
- 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-Z4QZOiFF.js → map-claims-D3oRmTk0.js} +19 -25
- package/dist/{map-error-pgUWNNtG.js → map-error-TCAdw-eW.js} +5 -5
- package/dist/{markers-B0hYLvMD.js → markers-C6joDI3o.js} +8 -3
- package/dist/mcp/index.d.ts +36 -9
- package/dist/mcp/index.js +476 -448
- package/dist/{rls-migrate-CN4TlJTO.js → migrate-BShP7Vf4.js} +119 -20
- package/dist/nest/index.d.ts +12 -9
- package/dist/nest/index.js +20 -20
- package/dist/next/index.d.ts +40 -20
- package/dist/next/index.js +37 -39
- 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-BFp-PZZA.js +126 -0
- package/dist/openai/index.d.ts +9 -16
- package/dist/openai/index.js +18 -25
- package/dist/openapi/index.d.ts +3 -3
- package/dist/openapi/index.js +1 -1
- package/dist/{openapi-BqRBvAng.js → openapi-B7HZ0f-r.js} +9 -12
- package/dist/{openapi-CqqEbHsL.js → openapi-DTaEmTSW.js} +23 -26
- 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 +23 -20
- package/dist/otel/index.d.ts +3 -2
- package/dist/otel/index.js +53 -27
- package/dist/output-Dyw8fyPF.js +88 -0
- package/dist/output-files-B3IZJksC.js +1 -0
- package/dist/output-files-DhRBBE4n.js +138 -0
- package/dist/{rls-fields-CZOMlwHl.js → ownership-BatFgAA4.js} +2393 -2349
- package/dist/{package-root-zGkxO3oN.js → package-root-Dk_ETdkp.js} +4 -3
- package/dist/{parse-BuyjxhZV.js → parse-Cxq0WxrA.js} +3 -3
- package/dist/{parse-local-manifest-BrMozJCo.js → parse-local-manifest-CVSs6J9I.js} +2 -4
- package/dist/{parse-local-manifest-JLnaBH0S.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 +47 -29
- 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-Br4jSNVi.js +385 -0
- package/dist/permissions-B-wCP5ZC.js +30 -0
- package/dist/{permissions-RJrovw98.js → permissions-CZKiUfFM.js} +4 -3
- package/dist/{permissions-CDgvKG5L.d.ts → permissions-oEWfl-kl.d.ts} +1 -2
- package/dist/policies-CO1oOymN.js +295 -0
- package/dist/{policy-D2W7uv19.d.ts → policy-Czo4n3Hs.d.ts} +2 -2
- package/dist/policy-DLZJ5gAp.js +399 -0
- package/dist/policy-from-catalog-DzhEc3Y9.js +450 -0
- package/dist/policy-module-CTlwMvLI.js +89 -0
- package/dist/{policy-IB6yxpC3.d.ts → policy-types-DzwivBgR.d.ts} +939 -1057
- 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-Dv1_aWF7.js → powersync-bYUDLOAO.js} +30 -32
- 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 +6 -12
- package/dist/{problem-B43ztKIm.js → problem-CTviyH5L.js} +18 -27
- package/dist/{problem-details-DX075l9V.d.ts → problem-details-DXlt-vks.d.ts} +1 -1
- package/dist/{problem-details-_AMOYz-w.js → problem-details-cn5X30gZ.js} +45 -42
- package/dist/problem-types-CJ2325SZ.js +5 -0
- package/dist/{prompt-CXYhLfsS.js → prompt-DfZLJLIn.js} +2 -2
- package/dist/protected-DEPHc2xV.d.ts +38 -0
- package/dist/{protected-utU-SLuy.js → protected-DfjY5mLA.js} +37 -8
- package/dist/{provider-CSQd7m92.js → provider-CC-u3bYP.js} +23 -10
- package/dist/{provider-DZY281jO.d.ts → provider-DMVt6yYn.d.ts} +1 -1
- package/dist/{provider-store-Cfbvo4DE.js → provider-store-B5Yrkhzr.js} +6 -3
- 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 -63
- package/dist/react-native/index.js +45 -27
- package/dist/{refs-KYb4ntaz.js → refs-K6eWUJ0H.js} +1 -1
- package/dist/relation-walk-3OyDBF0S.js +186 -0
- package/dist/relations-BnCWnJGI.js +163 -0
- package/dist/renames-CGj7YwcQ.js +175 -0
- package/dist/{replay-CYyiLiwO.d.ts → replay-D7iKcLFe.d.ts} +1 -1
- package/dist/{replay-BsOyTrdV.js → replay-Du1tJjG7.js} +2 -1
- package/dist/request-context-BTRTG7OT.js +71 -0
- package/dist/request-context-C2_1lchh.d.ts +5 -0
- 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-D_jw0BFx.js +243 -0
- package/dist/retire-CALjIQ7e.js +240 -0
- package/dist/{revocations-Cy06JNx2.d.ts → revocations-R07lFBnX.d.ts} +2 -0
- package/dist/rls-BA8an5Ap.js +336 -0
- package/dist/{rls-DiinlRML.js → rls-j6t43t7n.js} +1066 -1068
- package/dist/role-builder-CXbis5-X.js +623 -0
- package/dist/{rpc-DL9Sqvb1.js → rpc-aPyNi6tA.js} +18 -8
- 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-CB8gQFvS.js → runtime-D3VTAiCA.js} +1 -1
- package/dist/{saas-DhpJjnBA.js → saas-FO-Q8oj0.js} +18 -15
- package/dist/scan-BOI5tJ-6.js +29 -0
- package/dist/{schema-D3MnDMxa.js → schema-B4v0Qrac.js} +106 -10
- 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-BFGBBAqR.js → scim-ClHtpyV3.js} +213 -87
- package/dist/{scopes-CVdPrWN-.js → scopes-CUPSjo9q.js} +20 -7
- package/dist/server/index.d.ts +13 -134
- package/dist/server/index.js +13 -10
- package/dist/server-DqCT4CgZ.js +453 -0
- package/dist/{create-B1d519XK.d.ts → server-types-BLd4MnBX.d.ts} +89 -70
- package/dist/{sha256-BO0swRXL.js → sha256-D9ihqmvd.js} +8 -1
- package/dist/shared-CD11nBbC.js +304 -0
- package/dist/{shared-DRu8VFVM.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-Biq5uup3.js → skills-B6lVdD_W.js} +16 -8
- package/dist/skills-CTYwkl44.js +51 -0
- package/dist/snapshot-CXUWfsNy.js +269 -0
- package/dist/{snapshot-cache-D6jLelln.js → snapshot-cache-DZHQ0KF6.js} +11 -5
- package/dist/{snapshot-cache-B-LxUahj.d.ts → snapshot-cache-DqK9eDmM.d.ts} +7 -5
- package/dist/solid/index.d.ts +24 -25
- package/dist/solid/index.js +41 -11
- package/dist/solid-start/index.d.ts +52 -0
- package/dist/solid-start/index.js +49 -0
- package/dist/{sources-BdOYLw9j.d.ts → sources-BV9j0DeZ.d.ts} +11 -13
- package/dist/{sources-4p0-4xQm.js → sources-vs5dGOsS.js} +147 -142
- package/dist/sql-B5T1IL83.js +55 -0
- package/dist/src-DLfUWFAI.js +1851 -0
- package/dist/ssf/index.d.ts +4 -4
- package/dist/ssf/index.js +440 -106
- 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-DMAWwAJV.js → store-4u_hxjWa.js} +42 -55
- package/dist/{store-options-ByhZq1jV.js → store-options-BqEakYRa.js} +38 -24
- package/dist/{stores-BT2pSCub.js → stores-BbsD4fAR.js} +7 -3
- package/dist/stores-ClZUgeoP.d.ts +30 -0
- package/dist/{stream-D1RXubw2.d.ts → stream-7-xmnf3U.d.ts} +2 -2
- package/dist/{stream-DDpvynSB.js → stream-CvdUS9V1.js} +10 -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/{subject-settings-BwBmCdTR.js → subject-settings-CkEwrw3W.js} +23 -5
- package/dist/supabase/index.d.ts +23 -106
- package/dist/supabase/index.js +5 -4
- package/dist/supabase/middleware.d.ts +13 -6
- package/dist/supabase/middleware.js +16 -11
- package/dist/supabase-9pqI57pW.js +92 -0
- package/dist/{supabase-C0qESOa-.js → supabase-Dxlp8A94.js} +124 -247
- package/dist/supabase-hook-CXcGpHqq.js +1 -0
- package/dist/{supabase-hook-ntETYCQu.js → supabase-hook-DdDQhMlw.js} +1659 -819
- package/dist/{supautils-u8jXTGrt.js → supautils-B6HYL9eL.js} +2 -2
- package/dist/support-session-C6xJQYut.js +158 -0
- package/dist/svelte/Protected.svelte +11 -4
- package/dist/svelte/index.d.ts +7 -7
- package/dist/svelte/index.js +26 -12
- package/dist/svelte/runtime.d.ts +10 -3
- package/dist/svelte/runtime.js +4 -3
- package/dist/svelte/source.d.ts +7 -7
- package/dist/svelte/source.js +5 -5
- 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/{validity-uOp8UpYn.js → tenancy-DN2QAx9z.js} +6 -42
- package/dist/terminal/index.d.ts +11 -9
- package/dist/terminal/index.js +36 -316
- package/dist/testing/index.d.ts +391 -106
- package/dist/testing/index.js +4574 -1286
- 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-CIWxJOCh.js → token-BLZcjQgt.js} +15 -6
- package/dist/tool-refusal-CMLN5xhn.js +41 -0
- package/dist/trpc/index.d.ts +12 -9
- package/dist/trpc/index.js +18 -17
- package/dist/{types-DbjRN55U.d.ts → types-5Ut_pbKy.d.ts} +141 -13
- package/dist/types-BNORmDM8.d.ts +172 -0
- package/dist/types-BjV-fqcA.d.ts +57 -0
- package/dist/{types-QCuYJh4q.d.ts → types-BqAKcRNW.d.ts} +2 -1
- package/dist/types-C8-KNsFf.d.ts +107 -0
- package/dist/{types-aqOHTHcp.d.ts → types-CCpc2Dcv.d.ts} +77 -17
- package/dist/{types-Dnemwd77.d.ts → types-CZTnPFzM.d.ts} +50 -11
- package/dist/{types-C97IskBw.d.ts → types-CdlxsYQh.d.ts} +23 -11
- package/dist/{types-DxiCGmmd.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-fbZ7JEXr.d.ts +89 -0
- package/dist/types-tIgIeIKJ.d.ts +66 -0
- 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-ItS7nLcl.js → usage-T5mXq98v.js} +56 -13
- package/dist/{validation-error-Ba264OaJ.d.ts → validation-error-Bg5Tpluk.d.ts} +1 -1
- package/dist/{validation-error-CnjZ4t92.js → validation-error-ZfUHbKvf.js} +1 -1
- package/dist/validity-CZ7-y0Cj.js +79 -0
- package/dist/{verifier-BxBo6I44.js → verifier-DHuh-okk.js} +68 -21
- package/dist/verify-DbCL9bnB.js +1770 -0
- package/dist/{version-BvacVTZR.js → version-CEbQ5UeM.js} +4 -3
- package/dist/version-DXkYUISx.js +1 -0
- package/dist/{views-Soe7bGSC.js → views-DTIIO-oQ.js} +41 -2
- package/dist/{permissions-DttnqqxC.d.ts → vocabulary-D6lPdb4Z.d.ts} +120 -29
- package/dist/vue/index.d.ts +25 -21
- package/dist/vue/index.js +25 -9
- 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-DVBJ9cBq.js → watch-CszoTJMq.js} +47 -8
- package/dist/webmcp/index.d.ts +2 -2
- package/dist/webmcp/index.js +13 -37
- 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-Bd1Tejur.d.ts +15 -0
- package/dist/wrap-gX61EtpB.js +27 -0
- package/package.json +140 -41
- 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 +129 -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 +19 -10
- package/skills/permdock-data/SKILL.md +6 -6
- package/skills/permdock-data/references/queries-and-rls.md +13 -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 +6 -4
- package/skills/permdock-wire/SKILL.md +18 -12
- package/skills/permdock-wire/references/adapters.md +146 -50
- package/skills/permdock-wire/references/policy-options.md +15 -6
- package/skills/permdock-wire/references/presets-and-recipes.md +58 -0
- package/dist/approvals-DbYAuNkG.js +0 -224
- package/dist/arazzo-C9chp3ST.js +0 -54
- package/dist/bind-C_ob3LKa.d.ts +0 -25
- package/dist/catalog-CRW5Mx_B.js +0 -2
- package/dist/catalog-CYj-mX2O.js +0 -48
- package/dist/catalog-DWF5cYqB.js +0 -55
- package/dist/cloud-CfwZ39Rl.js +0 -50
- package/dist/cloud-DWLXO2af.js +0 -118
- package/dist/collect-CHB22Sx4.js +0 -83
- package/dist/collect-DSWOk19R.js +0 -2
- package/dist/commands-BeaGNj_o.js +0 -97
- package/dist/config-ir40y8m0.js +0 -36
- package/dist/create-CMwIl-w2.js +0 -253
- package/dist/delegation-D8pUEuce.js +0 -103
- package/dist/diff-C9RDjjhs.js +0 -48
- package/dist/doctor-Djh6JDEk.js +0 -53
- package/dist/doctor-DvH0IQff.js +0 -1194
- package/dist/doctor-collect-CjdO0wQX.js +0 -665
- package/dist/duration-xK2jGFVc.js +0 -25
- package/dist/errors-CWfoNg9N.js +0 -47
- package/dist/errors-DRnGZHzF.js +0 -30
- package/dist/evaluation-items-CfCCejQd.js +0 -40
- package/dist/expiry-BoBJ8Tvc.js +0 -7
- package/dist/fields-BMl1RxoX.js +0 -26
- package/dist/grantee-Cv5Sogfv.js +0 -602
- 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-0nNqHspG.d.ts +0 -6
- package/dist/index-BNc7Wer_.d.ts +0 -483
- package/dist/index-C7Tw7MaW.d.ts +0 -201
- package/dist/instance-options-Dhhcnm3y.js +0 -22
- package/dist/load-DwJUafYN.js +0 -2
- package/dist/manifest-iaoBXHKc.js +0 -783
- package/dist/map-AcxK9o_D.js +0 -147
- package/dist/may-use-DndQ5tQ-.js +0 -77
- package/dist/openapi-CQTsgKoB.js +0 -164
- package/dist/permdock-CbgvLnuo.js +0 -3479
- package/dist/permissions-DVoF6dMt.js +0 -662
- package/dist/policy-xyWg7QdR.js +0 -1122
- package/dist/powersync-CrBX8hY6.js +0 -2
- package/dist/powersync-DE19b9dT.js +0 -62
- package/dist/protected-BdnIEFkY.d.ts +0 -27
- package/dist/protected-xAr24FEC.d.ts +0 -40
- package/dist/relations-cjOL01hZ.js +0 -505
- package/dist/rls-P-BeBx0n.js +0 -238
- package/dist/rls-graph-CHwx0V8q.js +0 -435
- package/dist/rls-ownership-DcYlZ09B.js +0 -843
- package/dist/rls-shared-Cewd_-zI.js +0 -495
- package/dist/rls-verify-CMv9H3wV.js +0 -746
- package/dist/run-BWc9qqvE.js +0 -174
- package/dist/server-DlZ28Oz5.js +0 -268
- package/dist/sink-B1fZzIMf.d.ts +0 -104
- package/dist/sink-Bd9PSyfq.js +0 -141
- package/dist/skills-C5CbhhpG.js +0 -56
- package/dist/snapshot-Enxd0n-s.js +0 -975
- package/dist/sql-xdg5f4Fi.js +0 -27
- package/dist/src-BDwEZWrZ.js +0 -568
- package/dist/store-jOBYpiXC.d.ts +0 -36
- package/dist/stores-C0IMQrGI.d.ts +0 -52
- package/dist/subject-C6dLxqHU.js +0 -24
- package/dist/supabase-config-Bj3iDH2I.js +0 -472
- package/dist/supabase-hook-gd3s8bxB.js +0 -2
- package/dist/supabase-s4o9s1O1.js +0 -83
- package/dist/thenable-okc2xDsj.js +0 -10
- package/dist/types-BnIEz1sU.d.ts +0 -48
- package/dist/types-Bvc4oWT6.d.ts +0 -9
- package/dist/types-CKNSyIf_.d.ts +0 -52
- package/dist/types-Cq_H8N_X.d.ts +0 -197
- package/dist/usage-B0YuTQRO.js +0 -42
- package/dist/usage-DorAJiU_.js +0 -2
- package/dist/vocabulary-DA8a8zif.d.ts +0 -56
- package/dist/watch-BwxLTYMZ.js +0 -2
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
import { t as compact } from "../compact-CAf557ZB.js";
|
|
2
|
+
import { a as ownRecord } from "../paths-DXSHAMIa.js";
|
|
3
|
+
import { o as statusProblem } from "../problem-details-cn5X30gZ.js";
|
|
4
|
+
import { l as isRfc3339, p as nowSeconds } from "../time-DkWjdL98.js";
|
|
5
|
+
import { n as sha256, t as bytesToBase64Url } from "../sha256-D9ihqmvd.js";
|
|
6
|
+
import { t as deliveryEvent } from "../delivery-event-xX4obB8F.js";
|
|
7
|
+
import { n as readBodyText } from "../body-text-QcXok_SI.js";
|
|
8
|
+
import { a as methodNotAllowed, c as problemResponse } from "../problem-CTviyH5L.js";
|
|
9
|
+
import { t as bodyTooLarge } from "../body-CH5of8Ne.js";
|
|
10
|
+
import { n as approvalUrlFor } from "../approval-prompt-Dg5LeAcT.js";
|
|
11
|
+
import { i as isDeliveryTarget } from "../target-Bw37TFNA.js";
|
|
12
|
+
//#region src/resend/approval-email.ts
|
|
13
|
+
const HTML_ESCAPES = {
|
|
14
|
+
"&": "&",
|
|
15
|
+
"<": "<",
|
|
16
|
+
">": ">",
|
|
17
|
+
"\"": """,
|
|
18
|
+
"'": "'"
|
|
19
|
+
};
|
|
20
|
+
function escapeHtml(value) {
|
|
21
|
+
return value.replaceAll(/[&<>"']/gu, (char) => HTML_ESCAPES[char] ?? char);
|
|
22
|
+
}
|
|
23
|
+
function oneLine(value) {
|
|
24
|
+
return value.replaceAll(/\s+/gu, " ").trim();
|
|
25
|
+
}
|
|
26
|
+
function requesterLine(prompt) {
|
|
27
|
+
const principal = prompt.requester.principal?.id ?? "an anonymous caller";
|
|
28
|
+
const actor = prompt.requester.actor;
|
|
29
|
+
return actor === void 0 ? `Requested by ${principal}` : `Requested by ${principal} through ${actor.kind} ${actor.id}`;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* The default approval prompt email: an `approval`-category message whose
|
|
33
|
+
* one link opens the app's approval page for the request. It carries no
|
|
34
|
+
* approve or reject link; the signed-in approver decides on that page.
|
|
35
|
+
* Throws a `TypeError` for an approval page that is not https. Replace it
|
|
36
|
+
* with a React Email template by building the same `EmailMessage`.
|
|
37
|
+
*/
|
|
38
|
+
function approvalEmail(prompt, options) {
|
|
39
|
+
const url = approvalUrlFor(prompt, options.approvalUrl);
|
|
40
|
+
const title = oneLine(prompt.operation?.title ?? prompt.detail);
|
|
41
|
+
const resource = prompt.resource.id === void 0 ? prompt.resource.type : `${prompt.resource.type} ${prompt.resource.id}`;
|
|
42
|
+
const lines = [
|
|
43
|
+
prompt.detail,
|
|
44
|
+
"",
|
|
45
|
+
`${requesterLine(prompt)}.`,
|
|
46
|
+
`Permission: ${prompt.permission} on ${resource}`,
|
|
47
|
+
...prompt.operation?.risk === void 0 ? [] : [`Risk: ${prompt.operation.risk}`],
|
|
48
|
+
`Expires ${prompt.expiresAt}`,
|
|
49
|
+
"",
|
|
50
|
+
`Review the request: ${url}`,
|
|
51
|
+
"",
|
|
52
|
+
`This link opens the approval page. Nothing is approved until you decide there${options.product === void 0 ? "" : ` in ${options.product}`}.`
|
|
53
|
+
];
|
|
54
|
+
const facts = lines.slice(2, lines.indexOf("", 2)).map((line) => `<li>${escapeHtml(line)}</li>`).join("");
|
|
55
|
+
const html = [
|
|
56
|
+
`<p>${escapeHtml(prompt.detail)}</p>`,
|
|
57
|
+
`<ul>${facts}</ul>`,
|
|
58
|
+
`<p><a href="${escapeHtml(url)}">Review the request</a></p>`,
|
|
59
|
+
`<p>${escapeHtml(lines.at(-1) ?? "")}</p>`
|
|
60
|
+
].join("\n");
|
|
61
|
+
return Object.freeze({
|
|
62
|
+
subject: `Approval needed: ${title}`,
|
|
63
|
+
text: lines.join("\n"),
|
|
64
|
+
html,
|
|
65
|
+
category: "approval"
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
//#endregion
|
|
69
|
+
//#region src/resend/transport.ts
|
|
70
|
+
/** Resend's tag charset, at most 256 characters. */
|
|
71
|
+
const TAG = /^[A-Za-z0-9_-]{1,256}$/u;
|
|
72
|
+
const DELIVERY_TAG = "permdock_delivery";
|
|
73
|
+
const KEY_TAG = "permdock_key";
|
|
74
|
+
const CATEGORY_TAG = "permdock_category";
|
|
75
|
+
const RESERVED_TAGS = /* @__PURE__ */ new Set([
|
|
76
|
+
DELIVERY_TAG,
|
|
77
|
+
KEY_TAG,
|
|
78
|
+
CATEGORY_TAG
|
|
79
|
+
]);
|
|
80
|
+
const RETRYABLE = {
|
|
81
|
+
rate_limit_exceeded: "rate-limited",
|
|
82
|
+
daily_quota_exceeded: "quota-exceeded",
|
|
83
|
+
monthly_quota_exceeded: "quota-exceeded",
|
|
84
|
+
concurrent_idempotent_requests: "unavailable",
|
|
85
|
+
internal_server_error: "unavailable",
|
|
86
|
+
application_error: "unavailable"
|
|
87
|
+
};
|
|
88
|
+
const FINAL = {
|
|
89
|
+
invalid_api_key: "unauthorized",
|
|
90
|
+
missing_api_key: "unauthorized",
|
|
91
|
+
restricted_api_key: "unauthorized",
|
|
92
|
+
invalid_access: "unauthorized",
|
|
93
|
+
invalid_from_address: "invalid-message",
|
|
94
|
+
invalid_attachment: "invalid-message",
|
|
95
|
+
validation_error: "rejected"
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* The failure a Resend error name means. Rate limits, quotas and server
|
|
99
|
+
* errors are retryable with the same idempotency key; a key, sender or
|
|
100
|
+
* validation error is final. An unknown name is retryable only for a 5xx or
|
|
101
|
+
* a missing status.
|
|
102
|
+
*/
|
|
103
|
+
function resendFailure(error) {
|
|
104
|
+
const name = error.name;
|
|
105
|
+
const retryable = Object.hasOwn(RETRYABLE, name) ? RETRYABLE[name] : void 0;
|
|
106
|
+
if (retryable !== void 0) return {
|
|
107
|
+
status: "failed",
|
|
108
|
+
cause: retryable,
|
|
109
|
+
retryable: true,
|
|
110
|
+
reason: name
|
|
111
|
+
};
|
|
112
|
+
const final = Object.hasOwn(FINAL, name) ? FINAL[name] : void 0;
|
|
113
|
+
if (final !== void 0) return {
|
|
114
|
+
status: "failed",
|
|
115
|
+
cause: final,
|
|
116
|
+
retryable: false,
|
|
117
|
+
reason: name
|
|
118
|
+
};
|
|
119
|
+
const status = error.statusCode;
|
|
120
|
+
return status === null || status >= 500 ? {
|
|
121
|
+
status: "failed",
|
|
122
|
+
cause: "unavailable",
|
|
123
|
+
retryable: true,
|
|
124
|
+
reason: name
|
|
125
|
+
} : {
|
|
126
|
+
status: "failed",
|
|
127
|
+
cause: "rejected",
|
|
128
|
+
retryable: false,
|
|
129
|
+
reason: name
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
const UNAVAILABLE = Object.freeze({
|
|
133
|
+
status: "failed",
|
|
134
|
+
cause: "unavailable",
|
|
135
|
+
retryable: true,
|
|
136
|
+
reason: "request failed"
|
|
137
|
+
});
|
|
138
|
+
function checkTags(tags) {
|
|
139
|
+
return Object.entries(tags).map(([name, value]) => {
|
|
140
|
+
if (!TAG.test(name) || !TAG.test(value) || RESERVED_TAGS.has(name)) throw new TypeError(`PermDock: Resend tag ${JSON.stringify(name)} is reserved or outside [A-Za-z0-9_-]`);
|
|
141
|
+
return {
|
|
142
|
+
name,
|
|
143
|
+
value
|
|
144
|
+
};
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
const REFUSED = Object.freeze({
|
|
148
|
+
status: "failed",
|
|
149
|
+
cause: "invalid-recipient",
|
|
150
|
+
retryable: false
|
|
151
|
+
});
|
|
152
|
+
async function sendBatch(resend, items, payloadOf) {
|
|
153
|
+
const results = items.map(() => REFUSED);
|
|
154
|
+
const valid = items.flatMap((item, index) => isDeliveryTarget(item.target, "email") ? [index] : []);
|
|
155
|
+
if (valid.length === 0 || resend.batch === void 0) return results;
|
|
156
|
+
const key = `pdb_${bytesToBase64Url(sha256(JSON.stringify(valid.map((index) => items[index]?.options.idempotencyKey))))}`;
|
|
157
|
+
let answer;
|
|
158
|
+
try {
|
|
159
|
+
answer = await resend.batch.send(valid.flatMap((index) => {
|
|
160
|
+
const item = items[index];
|
|
161
|
+
return item === void 0 ? [] : [payloadOf(item.target, item.message, item.options)];
|
|
162
|
+
}), { idempotencyKey: key });
|
|
163
|
+
} catch {
|
|
164
|
+
answer = void 0;
|
|
165
|
+
}
|
|
166
|
+
for (const [offset, index] of valid.entries()) {
|
|
167
|
+
if (answer === void 0) {
|
|
168
|
+
results[index] = UNAVAILABLE;
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
if (answer.error !== null) {
|
|
172
|
+
results[index] = resendFailure(answer.error);
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
const id = answer.data.data[offset]?.id;
|
|
176
|
+
results[index] = id === void 0 ? UNAVAILABLE : {
|
|
177
|
+
status: "sent",
|
|
178
|
+
providerId: id
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
return results;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Sends the email channel of `permdock/delivery` through Resend. The
|
|
185
|
+
* idempotency key is Resend's `idempotencyKey`. The delivery id, key and
|
|
186
|
+
* category travel as tags, so `resendWebhook` can join provider events to
|
|
187
|
+
* the delivery. Two or more recipients go out through `batch.send`, up to
|
|
188
|
+
* 100 per call. Throws a `TypeError` for a tag outside Resend's charset.
|
|
189
|
+
*/
|
|
190
|
+
function resendTransport(resend, options = {}) {
|
|
191
|
+
const tags = checkTags(options.tags ?? {});
|
|
192
|
+
const payloadOf = (target, email, transportOptions) => compact({
|
|
193
|
+
from: email.from,
|
|
194
|
+
to: [target.address],
|
|
195
|
+
replyTo: email.replyTo ?? options.replyTo,
|
|
196
|
+
subject: email.subject,
|
|
197
|
+
text: email.text,
|
|
198
|
+
html: email.html,
|
|
199
|
+
headers: { ...email.headers },
|
|
200
|
+
tags: [
|
|
201
|
+
...tags,
|
|
202
|
+
...TAG.test(transportOptions.delivery) ? [{
|
|
203
|
+
name: DELIVERY_TAG,
|
|
204
|
+
value: transportOptions.delivery
|
|
205
|
+
}] : [],
|
|
206
|
+
{
|
|
207
|
+
name: KEY_TAG,
|
|
208
|
+
value: transportOptions.idempotencyKey
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
name: CATEGORY_TAG,
|
|
212
|
+
value: email.category
|
|
213
|
+
}
|
|
214
|
+
]
|
|
215
|
+
});
|
|
216
|
+
return Object.freeze(compact({
|
|
217
|
+
channel: "email",
|
|
218
|
+
name: "resend",
|
|
219
|
+
from: options.from,
|
|
220
|
+
batchSize: 100,
|
|
221
|
+
async deliver(target, email, transportOptions) {
|
|
222
|
+
if (!isDeliveryTarget(target, "email")) return REFUSED;
|
|
223
|
+
try {
|
|
224
|
+
const { data, error } = await resend.emails.send(payloadOf(target, email, transportOptions), { idempotencyKey: transportOptions.idempotencyKey });
|
|
225
|
+
if (error !== null) return resendFailure(error);
|
|
226
|
+
return {
|
|
227
|
+
status: "sent",
|
|
228
|
+
providerId: data.id
|
|
229
|
+
};
|
|
230
|
+
} catch {
|
|
231
|
+
return UNAVAILABLE;
|
|
232
|
+
}
|
|
233
|
+
},
|
|
234
|
+
deliverBatch: resend.batch === void 0 ? void 0 : (items) => sendBatch(resend, items, payloadOf)
|
|
235
|
+
}));
|
|
236
|
+
}
|
|
237
|
+
//#endregion
|
|
238
|
+
//#region src/resend/webhook.ts
|
|
239
|
+
/** Resend allows 5 minutes of clock skew either way; a claim outlives both. */
|
|
240
|
+
const CLAIM_SECONDS = 600;
|
|
241
|
+
const MAX_BODY = 1e6;
|
|
242
|
+
const CATEGORIES = /* @__PURE__ */ new Set([
|
|
243
|
+
"transactional",
|
|
244
|
+
"notification",
|
|
245
|
+
"security",
|
|
246
|
+
"approval"
|
|
247
|
+
]);
|
|
248
|
+
function header(request, name) {
|
|
249
|
+
return request.headers.get(`svix-${name}`) ?? request.headers.get(`webhook-${name}`);
|
|
250
|
+
}
|
|
251
|
+
function text(value) {
|
|
252
|
+
return typeof value === "string" && value !== "" ? value : void 0;
|
|
253
|
+
}
|
|
254
|
+
function joined(...parts) {
|
|
255
|
+
const found = parts.map(text).filter((part) => part !== void 0);
|
|
256
|
+
return found.length === 0 ? void 0 : found.join(": ");
|
|
257
|
+
}
|
|
258
|
+
function outcomeOf(type, data) {
|
|
259
|
+
switch (type) {
|
|
260
|
+
case "email.delivered": return { operation: "delivered" };
|
|
261
|
+
case "email.complained": return { operation: "complained" };
|
|
262
|
+
case "email.bounced": {
|
|
263
|
+
const bounce = ownRecord(data["bounce"]);
|
|
264
|
+
return compact({
|
|
265
|
+
operation: "bounced",
|
|
266
|
+
reason: joined(bounce?.["type"], bounce?.["message"])
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
case "email.failed": return compact({
|
|
270
|
+
operation: "failed",
|
|
271
|
+
cause: "rejected",
|
|
272
|
+
retryable: false,
|
|
273
|
+
reason: text(ownRecord(data["failed"])?.["reason"])
|
|
274
|
+
});
|
|
275
|
+
case "email.suppressed": {
|
|
276
|
+
const suppressed = ownRecord(data["suppressed"]);
|
|
277
|
+
return compact({
|
|
278
|
+
operation: "failed",
|
|
279
|
+
cause: "suppressed",
|
|
280
|
+
retryable: false,
|
|
281
|
+
reason: joined(suppressed?.["type"], suppressed?.["message"])
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
default: return;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* The delivery event a verified Resend payload stands for, or `null` for
|
|
289
|
+
* one that is not about a PermDock delivery: opens and clicks (tracking,
|
|
290
|
+
* not delivery), sends, contact and domain events, and mail without the
|
|
291
|
+
* `permdock_delivery` and `permdock_key` tags.
|
|
292
|
+
*/
|
|
293
|
+
function eventOf(payload, source) {
|
|
294
|
+
const record = ownRecord(payload);
|
|
295
|
+
const data = ownRecord(record?.["data"]);
|
|
296
|
+
if (record === void 0 || data === void 0) return null;
|
|
297
|
+
const outcome = outcomeOf(record["type"], data);
|
|
298
|
+
const tags = ownRecord(data["tags"]);
|
|
299
|
+
const id = text(tags?.[DELIVERY_TAG]);
|
|
300
|
+
const key = text(tags?.[KEY_TAG]);
|
|
301
|
+
if (outcome === void 0 || id === void 0 || key === void 0) return null;
|
|
302
|
+
const category = tags?.[CATEGORY_TAG];
|
|
303
|
+
const at = record["created_at"];
|
|
304
|
+
return deliveryEvent(compact({
|
|
305
|
+
at: isRfc3339(at) ? at : void 0,
|
|
306
|
+
source,
|
|
307
|
+
channel: "email",
|
|
308
|
+
delivery: {
|
|
309
|
+
id,
|
|
310
|
+
key
|
|
311
|
+
},
|
|
312
|
+
category: typeof category === "string" && CATEGORIES.has(category) ? category : void 0,
|
|
313
|
+
provider: compact({
|
|
314
|
+
name: "resend",
|
|
315
|
+
id: text(data["email_id"])
|
|
316
|
+
}),
|
|
317
|
+
...outcome
|
|
318
|
+
}));
|
|
319
|
+
}
|
|
320
|
+
function unsigned() {
|
|
321
|
+
return problemResponse(statusProblem(400, "webhook signature headers are missing"));
|
|
322
|
+
}
|
|
323
|
+
function unverified() {
|
|
324
|
+
return problemResponse(statusProblem(403, "webhook signature did not verify"));
|
|
325
|
+
}
|
|
326
|
+
async function claim(replay, key) {
|
|
327
|
+
const expiresAt = nowSeconds() + CLAIM_SECONDS;
|
|
328
|
+
if (replay.claim !== void 0) return replay.claim(key, expiresAt);
|
|
329
|
+
if (await replay.seen(key)) return false;
|
|
330
|
+
await replay.remember(key, expiresAt);
|
|
331
|
+
return true;
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* A fetch handler for Resend webhooks. It verifies the Standard Webhooks
|
|
335
|
+
* signature through `resend.webhooks.verify` (the `svix-*` and `webhook-*`
|
|
336
|
+
* header names both work), claims the message id, and writes one delivery
|
|
337
|
+
* event for `email.delivered`, `email.bounced`, `email.complained`,
|
|
338
|
+
* `email.failed` and `email.suppressed`. A bad signature is a `401`; a sink
|
|
339
|
+
* failure releases the claim and answers `503`, so Resend retries.
|
|
340
|
+
*/
|
|
341
|
+
function resendWebhook(options) {
|
|
342
|
+
const source = options.source ?? "permdock";
|
|
343
|
+
return async (request) => {
|
|
344
|
+
if (request.method !== "POST") return methodNotAllowed("POST");
|
|
345
|
+
const id = header(request, "id");
|
|
346
|
+
const timestamp = header(request, "timestamp");
|
|
347
|
+
const signature = header(request, "signature");
|
|
348
|
+
if (id === null || timestamp === null || signature === null) return unsigned();
|
|
349
|
+
const read = await readBodyText(request, MAX_BODY);
|
|
350
|
+
if (!read.ok) return read.cause === "too-large" ? bodyTooLarge(MAX_BODY) : problemResponse(statusProblem(400, "webhook body was unreadable"));
|
|
351
|
+
const body = read.text;
|
|
352
|
+
let payload;
|
|
353
|
+
try {
|
|
354
|
+
payload = options.resend.webhooks.verify({
|
|
355
|
+
payload: body,
|
|
356
|
+
headers: {
|
|
357
|
+
id,
|
|
358
|
+
timestamp,
|
|
359
|
+
signature
|
|
360
|
+
},
|
|
361
|
+
webhookSecret: options.secret
|
|
362
|
+
});
|
|
363
|
+
} catch {
|
|
364
|
+
return unverified();
|
|
365
|
+
}
|
|
366
|
+
const replayKey = `resend:${id}`;
|
|
367
|
+
if (!await claim(options.replay, replayKey)) return new Response(null, { status: 200 });
|
|
368
|
+
const event = eventOf(payload, source);
|
|
369
|
+
if (event !== null) try {
|
|
370
|
+
await options.sink.write([event]);
|
|
371
|
+
} catch {
|
|
372
|
+
await options.replay.release?.(replayKey);
|
|
373
|
+
return problemResponse(statusProblem(503, "the event sink is unavailable"));
|
|
374
|
+
}
|
|
375
|
+
return new Response(null, { status: 200 });
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
//#endregion
|
|
379
|
+
export { approvalEmail, resendFailure, resendTransport, resendWebhook };
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import { t as assertSafeKey } from "./paths-DXSHAMIa.js";
|
|
2
|
+
//#region src/core/resource-relations.ts
|
|
3
|
+
/** The edge's group resources with their relation and id column. */
|
|
4
|
+
function groupEntries(spec) {
|
|
5
|
+
const groups = spec.groups;
|
|
6
|
+
if (groups === void 0) return [];
|
|
7
|
+
return Object.entries(groups.resources).map(([resource, group]) => typeof group === "string" ? {
|
|
8
|
+
resource,
|
|
9
|
+
relation: group,
|
|
10
|
+
subject: spec.subject ?? "user_id",
|
|
11
|
+
typed: false
|
|
12
|
+
} : {
|
|
13
|
+
resource,
|
|
14
|
+
relation: group.relation,
|
|
15
|
+
subject: group.subject ?? spec.subject ?? "user_id",
|
|
16
|
+
typed: group.subject !== void 0
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
function restrictedStops(node, path) {
|
|
20
|
+
return node?.restricted !== void 0 && (node.restrictedStops === void 0 || node.restrictedStops.includes(path));
|
|
21
|
+
}
|
|
22
|
+
function restrictedFor(node, path) {
|
|
23
|
+
return restrictedStops(node, path) ? node?.restricted : void 0;
|
|
24
|
+
}
|
|
25
|
+
function isFieldRelation(relation) {
|
|
26
|
+
return relation !== void 0 && "field" in relation;
|
|
27
|
+
}
|
|
28
|
+
function isEdgeRelation(relation) {
|
|
29
|
+
return relation !== void 0 && "edge" in relation;
|
|
30
|
+
}
|
|
31
|
+
function isPrincipalRelation(relation) {
|
|
32
|
+
return relation !== void 0 && "principal" in relation;
|
|
33
|
+
}
|
|
34
|
+
function isComputedRelation(relation) {
|
|
35
|
+
return relation !== void 0 && !("field" in relation) && !("edge" in relation) && !("principal" in relation);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The relations whose holders hold `name` on `node`: `name` itself when it
|
|
39
|
+
* has a source, then everything it includes, transitively, each once.
|
|
40
|
+
* `definePermissions` rejects cycles and unknown names, so this terminates.
|
|
41
|
+
*/
|
|
42
|
+
function expandRelation(node, name) {
|
|
43
|
+
const out = [];
|
|
44
|
+
const seen = /* @__PURE__ */ new Set();
|
|
45
|
+
const visit = (current) => {
|
|
46
|
+
if (seen.has(current)) return;
|
|
47
|
+
seen.add(current);
|
|
48
|
+
const spec = node?.relations[current];
|
|
49
|
+
if (spec === void 0) return;
|
|
50
|
+
if (!isComputedRelation(spec)) out.push(current);
|
|
51
|
+
for (const included of spec.includes ?? []) visit(included);
|
|
52
|
+
};
|
|
53
|
+
visit(name);
|
|
54
|
+
return out;
|
|
55
|
+
}
|
|
56
|
+
/** Whether `node` names itself as its parent (nested folders, sub-teams, reporting lines). */
|
|
57
|
+
function isSelfParented(node) {
|
|
58
|
+
return node?.parent !== void 0 && node.parent.resource === node.name;
|
|
59
|
+
}
|
|
60
|
+
const RESOURCE_NAME = /^[A-Za-z][A-Za-z0-9_-]*$/u;
|
|
61
|
+
/** Level names ride claims and grant keys (`key@level`), so they stay SQL- and claim-safe. */
|
|
62
|
+
const LEVEL_NAME = /^[a-z][a-z0-9_]*$/u;
|
|
63
|
+
const EDGE_TABLE = /^[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)?$/u;
|
|
64
|
+
function restrictedStopsOf(name, option, parent, links) {
|
|
65
|
+
if (option.stops === void 0) return;
|
|
66
|
+
if (!Array.isArray(option.stops) || option.stops.length === 0) throw new Error(`PermDock: resource "${name}" restricted.stops must list 'parent' or link names`);
|
|
67
|
+
const stops = /* @__PURE__ */ new Set();
|
|
68
|
+
for (const path of option.stops) {
|
|
69
|
+
if (typeof path !== "string") throw new TypeError(`PermDock: resource "${name}" restricted.stops must list 'parent' or link names`);
|
|
70
|
+
if (path === "parent" ? parent === void 0 : !Object.hasOwn(links, path)) throw new Error(`PermDock: resource "${name}" restricted.stops names '${path}', which it does not declare`);
|
|
71
|
+
stops.add(path);
|
|
72
|
+
}
|
|
73
|
+
return Object.freeze([...stops].toSorted());
|
|
74
|
+
}
|
|
75
|
+
function normaliseRelation(resourceName, relationName, spec) {
|
|
76
|
+
if (typeof spec === "string") {
|
|
77
|
+
assertSafeKey(spec, "relation field");
|
|
78
|
+
return { field: spec };
|
|
79
|
+
}
|
|
80
|
+
const label = `relation '${relationName}' on '${resourceName}'`;
|
|
81
|
+
const includes = normaliseIncludes(label, spec.includes);
|
|
82
|
+
const kinds = [
|
|
83
|
+
"field",
|
|
84
|
+
"edge",
|
|
85
|
+
"principal"
|
|
86
|
+
].filter((kind) => kind in spec);
|
|
87
|
+
if (kinds.length === 0 && includes !== void 0) return { includes };
|
|
88
|
+
if (kinds.length !== 1) throw new Error(`PermDock: ${label} needs exactly one of field, edge, principal or includes`);
|
|
89
|
+
const withIncludes = includes === void 0 ? {} : { includes };
|
|
90
|
+
if (isEdgeRelation(spec)) {
|
|
91
|
+
if (!EDGE_TABLE.test(spec.edge)) throw new Error(`PermDock: ${label} has an unsafe edge table '${spec.edge}'`);
|
|
92
|
+
for (const column of [
|
|
93
|
+
spec.object,
|
|
94
|
+
spec.subject,
|
|
95
|
+
spec.expiresAt
|
|
96
|
+
]) if (column !== void 0) assertSafeKey(column, "edge column");
|
|
97
|
+
return {
|
|
98
|
+
edge: spec.edge,
|
|
99
|
+
...spec.object === void 0 ? {} : { object: spec.object },
|
|
100
|
+
...spec.subject === void 0 ? {} : { subject: spec.subject },
|
|
101
|
+
...spec.expiresAt === void 0 ? {} : { expiresAt: spec.expiresAt },
|
|
102
|
+
...spec.match === void 0 ? {} : { match: normaliseMatch(label, spec.match) },
|
|
103
|
+
...spec.groups === void 0 ? {} : { groups: normaliseGroups(label, spec.groups) },
|
|
104
|
+
...withIncludes
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
if (isPrincipalRelation(spec)) {
|
|
108
|
+
assertSafeKey(spec.principal, "relation principal");
|
|
109
|
+
for (const column of [spec.period?.startsAt, spec.period?.expiresAt]) if (column !== void 0) assertSafeKey(column, "relation period");
|
|
110
|
+
return spec.period === void 0 ? {
|
|
111
|
+
principal: spec.principal,
|
|
112
|
+
...withIncludes
|
|
113
|
+
} : {
|
|
114
|
+
principal: spec.principal,
|
|
115
|
+
period: { ...spec.period },
|
|
116
|
+
...withIncludes
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
const field = spec;
|
|
120
|
+
assertSafeKey(field.field, "relation field");
|
|
121
|
+
if (field.memberOf !== void 0 && includes !== void 0) throw new Error(`PermDock: ${label} is a memberOf relation and cannot include others`);
|
|
122
|
+
return field.memberOf === void 0 ? {
|
|
123
|
+
field: field.field,
|
|
124
|
+
...withIncludes
|
|
125
|
+
} : {
|
|
126
|
+
field: field.field,
|
|
127
|
+
memberOf: field.memberOf
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
function normaliseIncludes(label, includes) {
|
|
131
|
+
if (includes === void 0) return;
|
|
132
|
+
if (!Array.isArray(includes) || includes.length === 0) throw new Error(`PermDock: ${label} includes must be a non-empty list of relation names`);
|
|
133
|
+
for (const name of includes) {
|
|
134
|
+
if (typeof name !== "string") throw new TypeError(`PermDock: ${label} includes a non-string name`);
|
|
135
|
+
assertSafeKey(name, "included relation");
|
|
136
|
+
}
|
|
137
|
+
return [...new Set(includes)];
|
|
138
|
+
}
|
|
139
|
+
function normaliseMatch(label, match) {
|
|
140
|
+
const out = {};
|
|
141
|
+
const columns = Object.keys(match);
|
|
142
|
+
if (columns.length === 0) throw new Error(`PermDock: ${label} match needs at least one column`);
|
|
143
|
+
for (const column of columns) {
|
|
144
|
+
assertSafeKey(column, "edge match column");
|
|
145
|
+
const value = match[column];
|
|
146
|
+
if (typeof value !== "string" && typeof value !== "boolean" && !(typeof value === "number" && Number.isFinite(value))) throw new Error(`PermDock: ${label} match '${column}' must be a string, a finite number or a boolean`);
|
|
147
|
+
out[column] = value;
|
|
148
|
+
}
|
|
149
|
+
return out;
|
|
150
|
+
}
|
|
151
|
+
function normaliseGroups(label, groups) {
|
|
152
|
+
if (groups.column !== void 0) assertSafeKey(groups.column, "edge groups column");
|
|
153
|
+
const resources = {};
|
|
154
|
+
const names = Object.keys(groups.resources);
|
|
155
|
+
if (names.length === 0) throw new Error(`PermDock: ${label} groups needs at least one resource`);
|
|
156
|
+
for (const name of names) {
|
|
157
|
+
assertSafeKey(name, "group resource");
|
|
158
|
+
const group = groups.resources[name];
|
|
159
|
+
if (typeof group === "string") {
|
|
160
|
+
assertSafeKey(group, "group relation");
|
|
161
|
+
if (groups.column === void 0) throw new Error(`PermDock: ${label} groups '${name}' needs its own subject column, or groups needs a column naming the resource`);
|
|
162
|
+
resources[name] = group;
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
if (group === null || typeof group !== "object") throw new TypeError(`PermDock: ${label} groups '${name}' must name a relation`);
|
|
166
|
+
const relationName = "relation" in group ? group.relation : void 0;
|
|
167
|
+
if (typeof relationName !== "string") throw new TypeError(`PermDock: ${label} groups '${name}' must name a relation`);
|
|
168
|
+
assertSafeKey(relationName, "group relation");
|
|
169
|
+
const subject = "subject" in group ? group.subject : void 0;
|
|
170
|
+
if (subject !== void 0 && typeof subject !== "string") throw new TypeError(`PermDock: ${label} groups '${name}' subject must be a column name`);
|
|
171
|
+
if (subject !== void 0) assertSafeKey(subject, "group subject column");
|
|
172
|
+
else if (groups.column === void 0) throw new Error(`PermDock: ${label} groups '${name}' needs its own subject column, or groups needs a column naming the resource`);
|
|
173
|
+
resources[name] = subject === void 0 ? { relation: relationName } : {
|
|
174
|
+
relation: relationName,
|
|
175
|
+
subject
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
if (groups.direct !== void 0 && groups.column === void 0) throw new Error(`PermDock: ${label} groups direct needs a column to compare it with`);
|
|
179
|
+
if (groups.direct !== void 0 && groups.direct in resources) throw new Error(`PermDock: ${label} groups direct '${groups.direct}' is also a group resource`);
|
|
180
|
+
return {
|
|
181
|
+
...groups.column === void 0 ? {} : { column: groups.column },
|
|
182
|
+
resources,
|
|
183
|
+
...groups.direct === void 0 ? {} : { direct: groups.direct }
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
/** An included relation must exist on the same resource, be tenancy-free and never include itself back. */
|
|
187
|
+
function assertIncludes(node) {
|
|
188
|
+
const state = /* @__PURE__ */ new Map();
|
|
189
|
+
const visit = (name, path) => {
|
|
190
|
+
if (state.get(name) === "done") return;
|
|
191
|
+
if (state.get(name) === "visiting") throw new Error(`PermDock: relation includes on '${node.name}' form a cycle: ${[...path, name].join(" -> ")}`);
|
|
192
|
+
state.set(name, "visiting");
|
|
193
|
+
for (const included of node.relations[name]?.includes ?? []) {
|
|
194
|
+
const target = node.relations[included];
|
|
195
|
+
if (target === void 0) throw new Error(`PermDock: relation '${name}' on '${node.name}' includes '${included}', which '${node.name}' does not declare`);
|
|
196
|
+
if (isFieldRelation(target) && target.memberOf !== void 0) throw new Error(`PermDock: relation '${name}' on '${node.name}' includes the memberOf relation '${included}'; scopes are tenancy, not the object graph`);
|
|
197
|
+
visit(included, [...path, name]);
|
|
198
|
+
}
|
|
199
|
+
state.set(name, "done");
|
|
200
|
+
};
|
|
201
|
+
for (const name of Object.keys(node.relations)) visit(name, []);
|
|
202
|
+
}
|
|
203
|
+
function assertGroupTarget(registry, node, relationName, spec, target, targetRelation) {
|
|
204
|
+
const label = `relation '${relationName}' on '${node.name}' groups '${target}'`;
|
|
205
|
+
const targetSpec = registry.get(target)?.relations[targetRelation];
|
|
206
|
+
if (targetSpec === void 0) throw new Error(`PermDock: ${label} names '${target}#${targetRelation}', which is not declared`);
|
|
207
|
+
if (isFieldRelation(targetSpec) && targetSpec.memberOf !== void 0) throw new Error(`PermDock: ${label} names a memberOf relation; scopes are tenancy, not the object graph`);
|
|
208
|
+
if (target === node.name && (targetRelation !== relationName || spec.includes !== void 0)) throw new Error(`PermDock: ${label}: a group on its own resource must name the same relation, which includes nothing`);
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Links and group targets name declared resources and relations. Groups may
|
|
212
|
+
* nest within one resource (teams in teams) through the same relation, which
|
|
213
|
+
* then includes nothing, so SQL can walk it with one bounded recursive query;
|
|
214
|
+
* a group cycle across resources is rejected.
|
|
215
|
+
*/
|
|
216
|
+
function assertGraphTargets(registry) {
|
|
217
|
+
const edges = /* @__PURE__ */ new Map();
|
|
218
|
+
for (const node of registry.values()) {
|
|
219
|
+
for (const [linkName, link] of Object.entries(node.links)) if (!registry.has(link.resource)) throw new Error(`PermDock: link '${linkName}' on '${node.name}' names the undeclared resource '${link.resource}'`);
|
|
220
|
+
for (const [relationName, spec] of Object.entries(node.relations)) {
|
|
221
|
+
if (!isEdgeRelation(spec) || spec.groups === void 0) continue;
|
|
222
|
+
for (const { resource: target, relation: targetRelation } of groupEntries(spec)) {
|
|
223
|
+
assertGroupTarget(registry, node, relationName, spec, target, targetRelation);
|
|
224
|
+
if (target !== node.name) {
|
|
225
|
+
const out = edges.get(node.name) ?? /* @__PURE__ */ new Set();
|
|
226
|
+
out.add(target);
|
|
227
|
+
edges.set(node.name, out);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
const state = /* @__PURE__ */ new Map();
|
|
233
|
+
const visit = (name) => {
|
|
234
|
+
if (state.get(name) === "done") return;
|
|
235
|
+
if (state.get(name) === "visiting") throw new Error(`PermDock: edge groups form a cycle across resources through '${name}'`);
|
|
236
|
+
state.set(name, "visiting");
|
|
237
|
+
for (const next of edges.get(name) ?? []) visit(next);
|
|
238
|
+
state.set(name, "done");
|
|
239
|
+
};
|
|
240
|
+
for (const name of edges.keys()) visit(name);
|
|
241
|
+
}
|
|
242
|
+
//#endregion
|
|
243
|
+
export { expandRelation as a, isEdgeRelation as c, isSelfParented as d, normaliseRelation as f, restrictedStopsOf as h, assertIncludes as i, isFieldRelation as l, restrictedStops as m, RESOURCE_NAME as n, groupEntries as o, restrictedFor as p, assertGraphTargets as r, isComputedRelation as s, LEVEL_NAME as t, isPrincipalRelation as u };
|