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.
Files changed (552) hide show
  1. package/README.md +37 -35
  2. package/dist/{openapi-schema--ARjyfQr.js → 2020-C9VN-x8c.js} +5 -132
  3. package/dist/a2a/index.d.ts +8 -6
  4. package/dist/a2a/index.js +21 -31
  5. package/dist/{adapter-context-mlWsVGGg.js → adapter-context-CRhqyzCk.js} +1 -1
  6. package/dist/adoption-scan-B4R5fnMU.js +107 -0
  7. package/dist/agent/index.d.ts +3 -0
  8. package/dist/agent/index.js +1 -0
  9. package/dist/ai-sdk/index.d.ts +18 -23
  10. package/dist/ai-sdk/index.js +38 -21
  11. package/dist/app-data-MuyzVqX8.js +60 -0
  12. package/dist/approval-header-CJACtHkv.js +23 -0
  13. package/dist/approval-prompt-Dg5LeAcT.js +62 -0
  14. package/dist/approval-prompt-Djo_PyZc.d.ts +57 -0
  15. package/dist/approvals/index.d.ts +5 -3
  16. package/dist/approvals/index.js +8 -5
  17. package/dist/approvals-DJ6Yd5z1.js +995 -0
  18. package/dist/{approvers-DT4AVyIg.js → approvers-CqPOLD-o.js} +1 -1
  19. package/dist/arazzo-B6lebmiQ.js +36 -0
  20. package/dist/{arazzo-BAgw9ap6.js → arazzo-BWhNF-k0.js} +24 -17
  21. package/dist/args-IIolxxKA.js +197 -0
  22. package/dist/astro/index.d.ts +43 -0
  23. package/dist/astro/index.js +27 -0
  24. package/dist/audience-Dg8XsRaO.js +55 -0
  25. package/dist/auth-DRLEizbL.js +178 -0
  26. package/dist/authzen/index.d.ts +26 -6
  27. package/dist/authzen/index.js +228 -75
  28. package/dist/automation-BMZPIVUM.d.ts +114 -0
  29. package/dist/automation-DVjOckjV.js +157 -0
  30. package/dist/better-auth/index.d.ts +8 -6
  31. package/dist/better-auth/index.js +11 -23
  32. package/dist/better-supabase/index.d.ts +438 -86
  33. package/dist/better-supabase/index.js +1027 -184
  34. package/dist/bind--9EFVYWF.d.ts +38 -0
  35. package/dist/{bind-CuzGytRf.js → bind-CZzhx-Vj.js} +22 -10
  36. package/dist/body-CH5of8Ne.js +10 -0
  37. package/dist/body-text-QcXok_SI.js +52 -0
  38. package/dist/build-instance-BMnAudHn.js +52 -0
  39. package/dist/{canonical-json-DemiK4Vp.js → canonical-json-BC8_nMTw.js} +6 -6
  40. package/dist/{capability-2kYTMWDv.d.ts → capability-BSslw1QV.d.ts} +44 -25
  41. package/dist/{capability-4qPdO9gk.js → capability-N1K9IpqS.js} +69 -42
  42. package/dist/casbin-Cr7RLtA3.js +30 -0
  43. package/dist/casbin-Dyu2gnUD.js +234 -0
  44. package/dist/casl-64gpT-8x.js +24 -0
  45. package/dist/casl-DjEDhTCP.js +299 -0
  46. package/dist/catalog/index.d.ts +74 -2
  47. package/dist/catalog/index.js +51 -2
  48. package/dist/catalog-BECMPrwc.js +100 -0
  49. package/dist/catalog-DjhMYYCq.js +1 -0
  50. package/dist/catalog-R_A__RsH.js +52 -0
  51. package/dist/{catalog-doc-DdGm82XT.js → catalog-doc-C9wjsfNY.js} +54 -25
  52. package/dist/catalog-fingerprint-CCP0-yQS.js +153 -0
  53. package/dist/chat/index.d.ts +2 -0
  54. package/dist/chat/index.js +224 -0
  55. package/dist/chat-sdk/index.d.ts +87 -0
  56. package/dist/chat-sdk/index.js +197 -0
  57. package/dist/claims-map-7oQ3ue4X.js +13 -0
  58. package/dist/claims-map-Ca-QX8C6.d.ts +32 -0
  59. package/dist/claude-agent/index.d.ts +7 -14
  60. package/dist/claude-agent/index.js +26 -30
  61. package/dist/clerk/index.d.ts +9 -8
  62. package/dist/clerk/index.js +15 -45
  63. package/dist/cli/bin.js +36 -17
  64. package/dist/cli/index.d.ts +20 -6
  65. package/dist/cli/index.js +164 -4
  66. package/dist/cloud/index.d.ts +102 -63
  67. package/dist/cloud/index.js +240 -347
  68. package/dist/cloud-CIoHNevm.js +87 -0
  69. package/dist/codemod-Bmj9dWMH.js +37 -0
  70. package/dist/codemod-Cxvvc70T.js +2084 -0
  71. package/dist/{collect-DSTE3ml9.js → collect-CrZJJnEF.js} +79 -17
  72. package/dist/collect-DloHbDVa.js +55 -0
  73. package/dist/collect-FlXJlhus.js +1 -0
  74. package/dist/command-L8EstFNm.js +6 -0
  75. package/dist/{compact-y6vfu2_f.js → compact-CAf557ZB.js} +11 -1
  76. package/dist/compile/index.d.ts +1 -1
  77. package/dist/compile/index.js +1 -2
  78. package/dist/{compile-Ba4blROR.js → compile-CMqMx_IN.js} +13 -9
  79. package/dist/{compile-BkRyBDBw.d.ts → compile-Ckm2HqBZ.d.ts} +5 -3
  80. package/dist/completion-BqhRBJD8.js +143 -0
  81. package/dist/config-B46rm9sc.js +26 -0
  82. package/dist/{config-BJiM-xAm.js → config-bs_kZeYq.js} +15 -10
  83. package/dist/{config-report-CdCgbRnV.js → config-report-DUgj62Ai.js} +17 -8
  84. package/dist/{connection-CU8MQxRi.js → connection-DjhIJSs2.js} +8 -6
  85. package/dist/constants-DcJABbLW.js +20 -0
  86. package/dist/{context-Bcy85rGi.js → context-bbFHR-0D.js} +16 -5
  87. package/dist/convex/index.d.ts +11 -10
  88. package/dist/convex/index.js +18 -18
  89. package/dist/create-0VZ7Pdiu.d.ts +107 -0
  90. package/dist/create-BDS7wc3y.d.ts +138 -0
  91. package/dist/create-BFfm17UA.d.ts +110 -0
  92. package/dist/create-BWRSXgOF.js +403 -0
  93. package/dist/create-C3b4B5eF.js +130 -0
  94. package/dist/create-DnrmLnLW.js +323 -0
  95. package/dist/{credential-8P81ff4u.js → credential-DM2um3ha.js} +153 -32
  96. package/dist/credentials-DPyHmYz5.js +74 -0
  97. package/dist/deciding-columns-Sq12mEA6.js +123 -0
  98. package/dist/delegation-DaXVdDhM.js +286 -0
  99. package/dist/delegation-input-FTxMK3ji.js +19 -0
  100. package/dist/delivery/index.d.ts +5 -0
  101. package/dist/delivery/index.js +5 -0
  102. package/dist/delivery-DCAgNyCn.js +499 -0
  103. package/dist/delivery-event-xX4obB8F.js +40 -0
  104. package/dist/denied-text-D8jDHgsl.d.ts +19 -0
  105. package/dist/{describe-DMYiCjJV.d.ts → describe-BZUsixiL.d.ts} +11 -2
  106. package/dist/{describe-B_gVZEVi.js → describe-BybMRY7A.js} +10 -5
  107. package/dist/device-BARQ8eYG.js +193 -0
  108. package/dist/diff-CxZo9pTq.js +37 -0
  109. package/dist/{diff-2VaeChzX.js → diff-DCePiN6M.js} +61 -55
  110. package/dist/doctor-CxiwSfqH.js +44 -0
  111. package/dist/doctor-DFjUxf2f.js +2361 -0
  112. package/dist/drizzle/index.d.ts +5 -3
  113. package/dist/drizzle/index.js +6 -14
  114. package/dist/elysia/index.d.ts +16 -13
  115. package/dist/elysia/index.js +14 -13
  116. package/dist/env-DJZrPjRi.js +8 -0
  117. package/dist/errors-BDUwg2qC.js +27 -0
  118. package/dist/{errors-Cz5zn0mW.js → errors-BKy0EfhN.js} +6 -10
  119. package/dist/errors-BWXBMaKK.d.ts +11 -0
  120. package/dist/{errors-DPdqI50v.d.ts → errors-C2PXIv4c.d.ts} +2 -2
  121. package/dist/errors-CWTY6uih.js +143 -0
  122. package/dist/evaluate-_R8QkWaf.js +1732 -0
  123. package/dist/evaluations-16UqqQ6W.d.ts +32 -0
  124. package/dist/{evaluations-tz6D9A2G.js → evaluations-DZ2CbV5k.js} +181 -32
  125. package/dist/eve/index.d.ts +12 -16
  126. package/dist/eve/index.js +23 -29
  127. package/dist/event-time-CsegxXxB.js +23 -0
  128. package/dist/expiry-D4_YKRKD.js +52 -0
  129. package/dist/express/index.d.ts +13 -10
  130. package/dist/express/index.js +14 -12
  131. package/dist/fastify/index.d.ts +26 -13
  132. package/dist/fastify/index.js +17 -36
  133. package/dist/fetch-adapter-g0ypLkID.js +120 -0
  134. package/dist/fetch-adapter-qKJBuRqy.d.ts +31 -0
  135. package/dist/fields-D9tPVUUS.js +203 -0
  136. package/dist/files-C5ZI27eV.js +124 -0
  137. package/dist/{files-DWUN9PzI.js → files-D_JIzUrP.js} +12 -3
  138. package/dist/{fixtures-ht28Cplr.js → fixtures-B7XrLeY7.js} +12 -12
  139. package/dist/flags-C3DktBDY.js +86 -0
  140. package/dist/{from-snapshot-CTLijvdm.js → from-snapshot-D2lZt4Dd.js} +78 -65
  141. package/dist/{generate-CH7ThJ14.js → generate-CNU1pIOo.js} +1 -3
  142. package/dist/grantee-Cn1HyUsI.js +254 -0
  143. package/dist/grantee-conditions-CcXf8hMM.js +271 -0
  144. package/dist/grantee-match-DHArqY82.js +142 -0
  145. package/dist/h3/index.d.ts +37 -0
  146. package/dist/h3/index.js +35 -0
  147. package/dist/headers-BIjfMaoC.js +8 -0
  148. package/dist/headers-CIbDTUTK.d.ts +7 -0
  149. package/dist/{helpers-H_KARDVC.js → helpers-DTcZOzhF.js} +47 -39
  150. package/dist/hono/index.d.ts +12 -9
  151. package/dist/hono/index.js +14 -13
  152. package/dist/{hosted-DJQw46hn.js → hosted-BZIAYvon.js} +64 -15
  153. package/dist/hosted-DBDX0M-P.d.ts +78 -0
  154. package/dist/{http-SO7qGttf.js → http-BBoKefeS.js} +35 -2
  155. package/dist/{http-DPuDaChb.d.ts → http-B_LphE5Y.d.ts} +1 -2
  156. package/dist/http-DXJ37RDA.js +46 -0
  157. package/dist/{http-BIhmLfCc.js → http-ujKm0JXE.js} +3 -26
  158. package/dist/{openapi-import-cmwetbzw.js → import-CNV7I2Dw.js} +30 -26
  159. package/dist/{rls-import-4lLW_pbb.js → import-DMmOG27O.js} +271 -128
  160. package/dist/index-BcHcPyIo.d.ts +110 -0
  161. package/dist/index-CaxrMD1A.d.ts +1 -0
  162. package/dist/index-Chrs5fQ-.d.ts +210 -0
  163. package/dist/index-CxGUswIC.d.ts +431 -0
  164. package/dist/index-D8EovfsP.d.ts +91 -0
  165. package/dist/index-DOVf7RJv.d.ts +900 -0
  166. package/dist/{index-C8z4RjQV.d.ts → index-SGdIQyzc.d.ts} +34 -16
  167. package/dist/index.d.ts +20 -14
  168. package/dist/index.js +33 -23
  169. package/dist/init-DeMYsnYJ.js +96 -0
  170. package/dist/init-GG6Jh8HD.js +95 -0
  171. package/dist/{instance-options-jARdwfPN.d.ts → instance-options-Omfd793B.d.ts} +2 -2
  172. package/dist/instance-snapshot-Cxq4ygFc.js +600 -0
  173. package/dist/instant-BluqDvyS.js +19 -0
  174. package/dist/internals-Dk8A8fX3.js +17 -0
  175. package/dist/{json-schema-BsAflUGW.js → json-schema-B-vAwlde.js} +46 -9
  176. package/dist/json-schema-CN_iLFH2.d.ts +40 -0
  177. package/dist/jwt/index.d.ts +18 -11
  178. package/dist/jwt/index.js +166 -145
  179. package/dist/{kernel-_RRHmnMY.js → kernel-5JatXyND.js} +120 -43
  180. package/dist/kysely/index.d.ts +5 -3
  181. package/dist/kysely/index.js +6 -14
  182. package/dist/{live-options-H2eG8dfJ.js → live-options-BaAFCIiu.js} +16 -3
  183. package/dist/load-BxEtwlBS.js +1 -0
  184. package/dist/{load-DhWEB9P1.js → load-DFS_ry0W.js} +31 -7
  185. package/dist/{load-jose-BL6LH4bL.js → load-jose-DZ4dnjri.js} +1 -4
  186. package/dist/login-Dfe5RlYk.js +68 -0
  187. package/dist/login-imhuwvn3.js +254 -0
  188. package/dist/manifest-C8IzW3Do.js +42 -0
  189. package/dist/manifest-CtKR3GXL.js +370 -0
  190. package/dist/manifest-json-CAGzls-C.js +9 -0
  191. package/dist/{manifest-uDS9y5de.d.ts → manifest-mx5ghSFM.d.ts} +9 -2
  192. package/dist/manifest-schema-C0kK_8V0.js +399 -0
  193. package/dist/{map-claims-Z4QZOiFF.js → map-claims-D3oRmTk0.js} +19 -25
  194. package/dist/{map-error-pgUWNNtG.js → map-error-TCAdw-eW.js} +5 -5
  195. package/dist/{markers-B0hYLvMD.js → markers-C6joDI3o.js} +8 -3
  196. package/dist/mcp/index.d.ts +36 -9
  197. package/dist/mcp/index.js +476 -448
  198. package/dist/{rls-migrate-CN4TlJTO.js → migrate-BShP7Vf4.js} +119 -20
  199. package/dist/nest/index.d.ts +12 -9
  200. package/dist/nest/index.js +20 -20
  201. package/dist/next/index.d.ts +40 -20
  202. package/dist/next/index.js +37 -39
  203. package/dist/next/plugin.d.ts +1 -1
  204. package/dist/next/plugin.js +2 -2
  205. package/dist/node/index.d.ts +10 -10
  206. package/dist/node/index.js +7 -9
  207. package/dist/ocsf-BFp-PZZA.js +126 -0
  208. package/dist/openai/index.d.ts +9 -16
  209. package/dist/openai/index.js +18 -25
  210. package/dist/openapi/index.d.ts +3 -3
  211. package/dist/openapi/index.js +1 -1
  212. package/dist/{openapi-BqRBvAng.js → openapi-B7HZ0f-r.js} +9 -12
  213. package/dist/{openapi-CqqEbHsL.js → openapi-DTaEmTSW.js} +23 -26
  214. package/dist/openapi-ahr8rHu3.js +138 -0
  215. package/dist/operation-findings-DgATDpvh.js +36 -0
  216. package/dist/operations-CxybZErY.d.ts +59 -0
  217. package/dist/orpc/index.d.ts +13 -10
  218. package/dist/orpc/index.js +23 -20
  219. package/dist/otel/index.d.ts +3 -2
  220. package/dist/otel/index.js +53 -27
  221. package/dist/output-Dyw8fyPF.js +88 -0
  222. package/dist/output-files-B3IZJksC.js +1 -0
  223. package/dist/output-files-DhRBBE4n.js +138 -0
  224. package/dist/{rls-fields-CZOMlwHl.js → ownership-BatFgAA4.js} +2393 -2349
  225. package/dist/{package-root-zGkxO3oN.js → package-root-Dk_ETdkp.js} +4 -3
  226. package/dist/{parse-BuyjxhZV.js → parse-Cxq0WxrA.js} +3 -3
  227. package/dist/{parse-local-manifest-BrMozJCo.js → parse-local-manifest-CVSs6J9I.js} +2 -4
  228. package/dist/{parse-local-manifest-JLnaBH0S.d.ts → parse-local-manifest-DgqtruPn.d.ts} +1 -1
  229. package/dist/parse-request-D_tUXG6M.js +26 -0
  230. package/dist/paths-DXSHAMIa.js +42 -0
  231. package/dist/pdp/index.d.ts +7 -3
  232. package/dist/pdp/index.js +47 -29
  233. package/dist/{peer-BOr_kJE1.js → peer-C8swJ2GH.js} +23 -4
  234. package/dist/peer-CRvC7Hg1.js +1 -0
  235. package/dist/permdock-B9JxkBwC.js +868 -0
  236. package/dist/permdock-D7eeLJER.d.ts +502 -0
  237. package/dist/permission-registry-Br4jSNVi.js +385 -0
  238. package/dist/permissions-B-wCP5ZC.js +30 -0
  239. package/dist/{permissions-RJrovw98.js → permissions-CZKiUfFM.js} +4 -3
  240. package/dist/{permissions-CDgvKG5L.d.ts → permissions-oEWfl-kl.d.ts} +1 -2
  241. package/dist/policies-CO1oOymN.js +295 -0
  242. package/dist/{policy-D2W7uv19.d.ts → policy-Czo4n3Hs.d.ts} +2 -2
  243. package/dist/policy-DLZJ5gAp.js +399 -0
  244. package/dist/policy-from-catalog-DzhEc3Y9.js +450 -0
  245. package/dist/policy-module-CTlwMvLI.js +89 -0
  246. package/dist/{policy-IB6yxpC3.d.ts → policy-types-DzwivBgR.d.ts} +939 -1057
  247. package/dist/postgrest-CW0IqC-U.js +566 -0
  248. package/dist/postgrest-NUqZT-RB.d.ts +100 -0
  249. package/dist/powersync-BHfuehf3.js +62 -0
  250. package/dist/powersync-CbzkqL_M.js +1 -0
  251. package/dist/{powersync-Dv1_aWF7.js → powersync-bYUDLOAO.js} +30 -32
  252. package/dist/preset/index.d.ts +146 -0
  253. package/dist/preset/index.js +1 -0
  254. package/dist/preset-DZdU0tne.js +1768 -0
  255. package/dist/principal-source-pHneukrx.js +103 -0
  256. package/dist/prisma/index.d.ts +6 -3
  257. package/dist/prisma/index.js +6 -12
  258. package/dist/{problem-B43ztKIm.js → problem-CTviyH5L.js} +18 -27
  259. package/dist/{problem-details-DX075l9V.d.ts → problem-details-DXlt-vks.d.ts} +1 -1
  260. package/dist/{problem-details-_AMOYz-w.js → problem-details-cn5X30gZ.js} +45 -42
  261. package/dist/problem-types-CJ2325SZ.js +5 -0
  262. package/dist/{prompt-CXYhLfsS.js → prompt-DfZLJLIn.js} +2 -2
  263. package/dist/protected-DEPHc2xV.d.ts +38 -0
  264. package/dist/{protected-utU-SLuy.js → protected-DfjY5mLA.js} +37 -8
  265. package/dist/{provider-CSQd7m92.js → provider-CC-u3bYP.js} +23 -10
  266. package/dist/{provider-DZY281jO.d.ts → provider-DMVt6yYn.d.ts} +1 -1
  267. package/dist/{provider-store-Cfbvo4DE.js → provider-store-B5Yrkhzr.js} +6 -3
  268. package/dist/pull-BgIfno6w.js +256 -0
  269. package/dist/pull-ByOks_Tg.js +1 -0
  270. package/dist/push-CmFVBOeI.js +116 -0
  271. package/dist/pushed-policy-BImMTTIM.d.ts +57 -0
  272. package/dist/pushed-policy-DobP7AHI.js +238 -0
  273. package/dist/react/index.d.ts +8 -8
  274. package/dist/react/index.js +6 -6
  275. package/dist/react/provider-client.d.ts +1 -1
  276. package/dist/react/provider-client.js +1 -2
  277. package/dist/react-native/index.d.ts +24 -63
  278. package/dist/react-native/index.js +45 -27
  279. package/dist/{refs-KYb4ntaz.js → refs-K6eWUJ0H.js} +1 -1
  280. package/dist/relation-walk-3OyDBF0S.js +186 -0
  281. package/dist/relations-BnCWnJGI.js +163 -0
  282. package/dist/renames-CGj7YwcQ.js +175 -0
  283. package/dist/{replay-CYyiLiwO.d.ts → replay-D7iKcLFe.d.ts} +1 -1
  284. package/dist/{replay-BsOyTrdV.js → replay-Du1tJjG7.js} +2 -1
  285. package/dist/request-context-BTRTG7OT.js +71 -0
  286. package/dist/request-context-C2_1lchh.d.ts +5 -0
  287. package/dist/request-schema-CMreVuFM.js +148 -0
  288. package/dist/resend/index.d.ts +126 -0
  289. package/dist/resend/index.js +379 -0
  290. package/dist/resource-relations-D_jw0BFx.js +243 -0
  291. package/dist/retire-CALjIQ7e.js +240 -0
  292. package/dist/{revocations-Cy06JNx2.d.ts → revocations-R07lFBnX.d.ts} +2 -0
  293. package/dist/rls-BA8an5Ap.js +336 -0
  294. package/dist/{rls-DiinlRML.js → rls-j6t43t7n.js} +1066 -1068
  295. package/dist/role-builder-CXbis5-X.js +623 -0
  296. package/dist/{rpc-DL9Sqvb1.js → rpc-aPyNi6tA.js} +18 -8
  297. package/dist/run-CNsApDpd.js +1 -0
  298. package/dist/run-DOfMtc9V.js +723 -0
  299. package/dist/run-ticket-BjhTOi6u.d.ts +124 -0
  300. package/dist/run-ticket-sxFI6LAk.js +337 -0
  301. package/dist/{runtime-CB8gQFvS.js → runtime-D3VTAiCA.js} +1 -1
  302. package/dist/{saas-DhpJjnBA.js → saas-FO-Q8oj0.js} +18 -15
  303. package/dist/scan-BOI5tJ-6.js +29 -0
  304. package/dist/{schema-D3MnDMxa.js → schema-B4v0Qrac.js} +106 -10
  305. package/dist/schema-yLuBWWsh.js +130 -0
  306. package/dist/scim/index.d.ts +2 -2
  307. package/dist/scim/index.js +1 -2
  308. package/dist/{scim-BFGBBAqR.js → scim-ClHtpyV3.js} +213 -87
  309. package/dist/{scopes-CVdPrWN-.js → scopes-CUPSjo9q.js} +20 -7
  310. package/dist/server/index.d.ts +13 -134
  311. package/dist/server/index.js +13 -10
  312. package/dist/server-DqCT4CgZ.js +453 -0
  313. package/dist/{create-B1d519XK.d.ts → server-types-BLd4MnBX.d.ts} +89 -70
  314. package/dist/{sha256-BO0swRXL.js → sha256-D9ihqmvd.js} +8 -1
  315. package/dist/shared-CD11nBbC.js +304 -0
  316. package/dist/{shared-DRu8VFVM.js → shared-DvvFzYXe.js} +8 -9
  317. package/dist/signals-D3NcTKUS.js +32 -0
  318. package/dist/sink-BEZSlMS_.js +957 -0
  319. package/dist/sink-Bj_lDUDq.d.ts +225 -0
  320. package/dist/{skills-Biq5uup3.js → skills-B6lVdD_W.js} +16 -8
  321. package/dist/skills-CTYwkl44.js +51 -0
  322. package/dist/snapshot-CXUWfsNy.js +269 -0
  323. package/dist/{snapshot-cache-D6jLelln.js → snapshot-cache-DZHQ0KF6.js} +11 -5
  324. package/dist/{snapshot-cache-B-LxUahj.d.ts → snapshot-cache-DqK9eDmM.d.ts} +7 -5
  325. package/dist/solid/index.d.ts +24 -25
  326. package/dist/solid/index.js +41 -11
  327. package/dist/solid-start/index.d.ts +52 -0
  328. package/dist/solid-start/index.js +49 -0
  329. package/dist/{sources-BdOYLw9j.d.ts → sources-BV9j0DeZ.d.ts} +11 -13
  330. package/dist/{sources-4p0-4xQm.js → sources-vs5dGOsS.js} +147 -142
  331. package/dist/sql-B5T1IL83.js +55 -0
  332. package/dist/src-DLfUWFAI.js +1851 -0
  333. package/dist/ssf/index.d.ts +4 -4
  334. package/dist/ssf/index.js +440 -106
  335. package/dist/standard-webhooks-6lg8v_is.d.ts +88 -0
  336. package/dist/standard-webhooks-DgFFD-Ga.js +228 -0
  337. package/dist/storage-C2bWdvJH.js +132 -0
  338. package/dist/{store-DMAWwAJV.js → store-4u_hxjWa.js} +42 -55
  339. package/dist/{store-options-ByhZq1jV.js → store-options-BqEakYRa.js} +38 -24
  340. package/dist/{stores-BT2pSCub.js → stores-BbsD4fAR.js} +7 -3
  341. package/dist/stores-ClZUgeoP.d.ts +30 -0
  342. package/dist/{stream-D1RXubw2.d.ts → stream-7-xmnf3U.d.ts} +2 -2
  343. package/dist/{stream-DDpvynSB.js → stream-CvdUS9V1.js} +10 -2
  344. package/dist/style-DiKWnAvn.js +1 -0
  345. package/dist/{style-CTm1AXDT.js → style-Uao76wO7.js} +3 -2
  346. package/dist/subject-BGoM5o8B.js +17 -0
  347. package/dist/{subject-settings-BwBmCdTR.js → subject-settings-CkEwrw3W.js} +23 -5
  348. package/dist/supabase/index.d.ts +23 -106
  349. package/dist/supabase/index.js +5 -4
  350. package/dist/supabase/middleware.d.ts +13 -6
  351. package/dist/supabase/middleware.js +16 -11
  352. package/dist/supabase-9pqI57pW.js +92 -0
  353. package/dist/{supabase-C0qESOa-.js → supabase-Dxlp8A94.js} +124 -247
  354. package/dist/supabase-hook-CXcGpHqq.js +1 -0
  355. package/dist/{supabase-hook-ntETYCQu.js → supabase-hook-DdDQhMlw.js} +1659 -819
  356. package/dist/{supautils-u8jXTGrt.js → supautils-B6HYL9eL.js} +2 -2
  357. package/dist/support-session-C6xJQYut.js +158 -0
  358. package/dist/svelte/Protected.svelte +11 -4
  359. package/dist/svelte/index.d.ts +7 -7
  360. package/dist/svelte/index.js +26 -12
  361. package/dist/svelte/runtime.d.ts +10 -3
  362. package/dist/svelte/runtime.js +4 -3
  363. package/dist/svelte/source.d.ts +7 -7
  364. package/dist/svelte/source.js +5 -5
  365. package/dist/sveltekit/index.d.ts +51 -0
  366. package/dist/sveltekit/index.js +27 -0
  367. package/dist/tanstack-start/index.d.ts +51 -0
  368. package/dist/tanstack-start/index.js +40 -0
  369. package/dist/target-Bw37TFNA.js +51 -0
  370. package/dist/{validity-uOp8UpYn.js → tenancy-DN2QAx9z.js} +6 -42
  371. package/dist/terminal/index.d.ts +11 -9
  372. package/dist/terminal/index.js +36 -316
  373. package/dist/testing/index.d.ts +391 -106
  374. package/dist/testing/index.js +4574 -1286
  375. package/dist/testing/saas/index.d.ts +9 -8
  376. package/dist/testing/saas/index.js +2 -2
  377. package/dist/testing/saas/permissions.d.ts +1 -1
  378. package/dist/testing/saas/permissions.js +1 -2
  379. package/dist/text-BMFRfBqc.js +8 -0
  380. package/dist/{text-diff-BdkkYSbi.js → text-diff-BQcUapOb.js} +1 -1
  381. package/dist/thenable-yD7SabqG.js +31 -0
  382. package/dist/time-DkWjdL98.js +71 -0
  383. package/dist/{token-CIWxJOCh.js → token-BLZcjQgt.js} +15 -6
  384. package/dist/tool-refusal-CMLN5xhn.js +41 -0
  385. package/dist/trpc/index.d.ts +12 -9
  386. package/dist/trpc/index.js +18 -17
  387. package/dist/{types-DbjRN55U.d.ts → types-5Ut_pbKy.d.ts} +141 -13
  388. package/dist/types-BNORmDM8.d.ts +172 -0
  389. package/dist/types-BjV-fqcA.d.ts +57 -0
  390. package/dist/{types-QCuYJh4q.d.ts → types-BqAKcRNW.d.ts} +2 -1
  391. package/dist/types-C8-KNsFf.d.ts +107 -0
  392. package/dist/{types-aqOHTHcp.d.ts → types-CCpc2Dcv.d.ts} +77 -17
  393. package/dist/{types-Dnemwd77.d.ts → types-CZTnPFzM.d.ts} +50 -11
  394. package/dist/{types-C97IskBw.d.ts → types-CdlxsYQh.d.ts} +23 -11
  395. package/dist/{types-DxiCGmmd.d.ts → types-ClZaWzfb.d.ts} +9 -6
  396. package/dist/types-DX0LaKTb.d.ts +157 -0
  397. package/dist/types-DiQjupG2.d.ts +332 -0
  398. package/dist/types-DqzsnlSA.js +67 -0
  399. package/dist/types-_sHy8BQf.d.ts +65 -0
  400. package/dist/types-fbZ7JEXr.d.ts +89 -0
  401. package/dist/types-tIgIeIKJ.d.ts +66 -0
  402. package/dist/unplugin/index.d.ts +1 -1
  403. package/dist/unplugin/index.js +2 -2
  404. package/dist/usage-CHOtwL19.js +1 -0
  405. package/dist/usage-DHtE8j4E.js +32 -0
  406. package/dist/{usage-ItS7nLcl.js → usage-T5mXq98v.js} +56 -13
  407. package/dist/{validation-error-Ba264OaJ.d.ts → validation-error-Bg5Tpluk.d.ts} +1 -1
  408. package/dist/{validation-error-CnjZ4t92.js → validation-error-ZfUHbKvf.js} +1 -1
  409. package/dist/validity-CZ7-y0Cj.js +79 -0
  410. package/dist/{verifier-BxBo6I44.js → verifier-DHuh-okk.js} +68 -21
  411. package/dist/verify-DbCL9bnB.js +1770 -0
  412. package/dist/{version-BvacVTZR.js → version-CEbQ5UeM.js} +4 -3
  413. package/dist/version-DXkYUISx.js +1 -0
  414. package/dist/{views-Soe7bGSC.js → views-DTIIO-oQ.js} +41 -2
  415. package/dist/{permissions-DttnqqxC.d.ts → vocabulary-D6lPdb4Z.d.ts} +120 -29
  416. package/dist/vue/index.d.ts +25 -21
  417. package/dist/vue/index.js +25 -9
  418. package/dist/waiter-BGUtGYoU.js +67 -0
  419. package/dist/waiter-CKy4MQSY.d.ts +36 -0
  420. package/dist/watch-Cb-NcaUw.js +1 -0
  421. package/dist/{watch-DVBJ9cBq.js → watch-CszoTJMq.js} +47 -8
  422. package/dist/webmcp/index.d.ts +2 -2
  423. package/dist/webmcp/index.js +13 -37
  424. package/dist/where-scope-Dv-WTP-w.js +306 -0
  425. package/dist/who-can-D0QoYbEb.js +364 -0
  426. package/dist/wire-delegation-Cv3W2eaM.js +36 -0
  427. package/dist/wire-denial-C7PaVYEM.js +27 -0
  428. package/dist/workflow/index.d.ts +5 -0
  429. package/dist/workflow/index.js +223 -0
  430. package/dist/workflow-sdk/index.d.ts +56 -0
  431. package/dist/workflow-sdk/index.js +78 -0
  432. package/dist/wrap-Bd1Tejur.d.ts +15 -0
  433. package/dist/wrap-gX61EtpB.js +27 -0
  434. package/package.json +140 -41
  435. package/schemas/access-event-v1.json +118 -0
  436. package/schemas/approval-request-v1.json +34 -1
  437. package/schemas/approval-signature-v1.json +94 -0
  438. package/schemas/automation-event-v1.json +113 -0
  439. package/schemas/capability-v1.json +84 -0
  440. package/schemas/catalog-event-v1.json +87 -0
  441. package/schemas/catalog-v1.json +129 -12
  442. package/schemas/cli-commands-v1.json +164 -0
  443. package/schemas/cli-result-v1.json +96 -0
  444. package/schemas/cloud-api-v1.json +5407 -0
  445. package/schemas/connector-v1.json +408 -0
  446. package/schemas/credential-event-v1.json +81 -0
  447. package/schemas/credential-v1.json +134 -0
  448. package/schemas/decision-event-v1.json +288 -0
  449. package/schemas/delivery-event-v1.json +117 -0
  450. package/schemas/directory-event-v1.json +85 -0
  451. package/schemas/evidence-export-v1.json +54 -0
  452. package/schemas/membership-event-v1.json +93 -0
  453. package/schemas/policy-v1.json +68 -0
  454. package/schemas/pushed-policy-v1.json +236 -0
  455. package/schemas/run-v1.json +162 -0
  456. package/schemas/snapshot-v1.json +138 -0
  457. package/schemas/supabase-claims-v1.json +4 -4
  458. package/schemas/supabase-manifest-v1.json +5 -1
  459. package/schemas/support-session-v1.json +111 -0
  460. package/skills/permdock/SKILL.md +16 -12
  461. package/skills/permdock-agents/SKILL.md +40 -23
  462. package/skills/permdock-agents/references/operations-automations-chat.md +221 -0
  463. package/skills/permdock-agents/references/runtimes.md +22 -18
  464. package/skills/permdock-approvals/SKILL.md +29 -13
  465. package/skills/permdock-approvals/references/delivery-and-waiters.md +172 -0
  466. package/skills/permdock-approvals/references/stores-and-resume.md +21 -7
  467. package/skills/permdock-audit/SKILL.md +3 -3
  468. package/skills/permdock-credentials/SKILL.md +5 -5
  469. package/skills/permdock-credentials/references/tokens-keys-links.md +19 -10
  470. package/skills/permdock-data/SKILL.md +6 -6
  471. package/skills/permdock-data/references/queries-and-rls.md +13 -8
  472. package/skills/permdock-data/references/relationships.md +3 -3
  473. package/skills/permdock-tenancy/SKILL.md +20 -7
  474. package/skills/permdock-tenancy/references/contacts-and-support-sessions.md +122 -0
  475. package/skills/permdock-tenancy/references/ownership-and-custom-roles.md +6 -4
  476. package/skills/permdock-wire/SKILL.md +18 -12
  477. package/skills/permdock-wire/references/adapters.md +146 -50
  478. package/skills/permdock-wire/references/policy-options.md +15 -6
  479. package/skills/permdock-wire/references/presets-and-recipes.md +58 -0
  480. package/dist/approvals-DbYAuNkG.js +0 -224
  481. package/dist/arazzo-C9chp3ST.js +0 -54
  482. package/dist/bind-C_ob3LKa.d.ts +0 -25
  483. package/dist/catalog-CRW5Mx_B.js +0 -2
  484. package/dist/catalog-CYj-mX2O.js +0 -48
  485. package/dist/catalog-DWF5cYqB.js +0 -55
  486. package/dist/cloud-CfwZ39Rl.js +0 -50
  487. package/dist/cloud-DWLXO2af.js +0 -118
  488. package/dist/collect-CHB22Sx4.js +0 -83
  489. package/dist/collect-DSWOk19R.js +0 -2
  490. package/dist/commands-BeaGNj_o.js +0 -97
  491. package/dist/config-ir40y8m0.js +0 -36
  492. package/dist/create-CMwIl-w2.js +0 -253
  493. package/dist/delegation-D8pUEuce.js +0 -103
  494. package/dist/diff-C9RDjjhs.js +0 -48
  495. package/dist/doctor-Djh6JDEk.js +0 -53
  496. package/dist/doctor-DvH0IQff.js +0 -1194
  497. package/dist/doctor-collect-CjdO0wQX.js +0 -665
  498. package/dist/duration-xK2jGFVc.js +0 -25
  499. package/dist/errors-CWfoNg9N.js +0 -47
  500. package/dist/errors-DRnGZHzF.js +0 -30
  501. package/dist/evaluation-items-CfCCejQd.js +0 -40
  502. package/dist/expiry-BoBJ8Tvc.js +0 -7
  503. package/dist/fields-BMl1RxoX.js +0 -26
  504. package/dist/grantee-Cv5Sogfv.js +0 -602
  505. package/dist/headers-BZSDieNT.js +0 -6
  506. package/dist/headers-Cf-zWvsO.d.ts +0 -6
  507. package/dist/ids-DC4V4CFu.js +0 -18
  508. package/dist/index-0nNqHspG.d.ts +0 -6
  509. package/dist/index-BNc7Wer_.d.ts +0 -483
  510. package/dist/index-C7Tw7MaW.d.ts +0 -201
  511. package/dist/instance-options-Dhhcnm3y.js +0 -22
  512. package/dist/load-DwJUafYN.js +0 -2
  513. package/dist/manifest-iaoBXHKc.js +0 -783
  514. package/dist/map-AcxK9o_D.js +0 -147
  515. package/dist/may-use-DndQ5tQ-.js +0 -77
  516. package/dist/openapi-CQTsgKoB.js +0 -164
  517. package/dist/permdock-CbgvLnuo.js +0 -3479
  518. package/dist/permissions-DVoF6dMt.js +0 -662
  519. package/dist/policy-xyWg7QdR.js +0 -1122
  520. package/dist/powersync-CrBX8hY6.js +0 -2
  521. package/dist/powersync-DE19b9dT.js +0 -62
  522. package/dist/protected-BdnIEFkY.d.ts +0 -27
  523. package/dist/protected-xAr24FEC.d.ts +0 -40
  524. package/dist/relations-cjOL01hZ.js +0 -505
  525. package/dist/rls-P-BeBx0n.js +0 -238
  526. package/dist/rls-graph-CHwx0V8q.js +0 -435
  527. package/dist/rls-ownership-DcYlZ09B.js +0 -843
  528. package/dist/rls-shared-Cewd_-zI.js +0 -495
  529. package/dist/rls-verify-CMv9H3wV.js +0 -746
  530. package/dist/run-BWc9qqvE.js +0 -174
  531. package/dist/server-DlZ28Oz5.js +0 -268
  532. package/dist/sink-B1fZzIMf.d.ts +0 -104
  533. package/dist/sink-Bd9PSyfq.js +0 -141
  534. package/dist/skills-C5CbhhpG.js +0 -56
  535. package/dist/snapshot-Enxd0n-s.js +0 -975
  536. package/dist/sql-xdg5f4Fi.js +0 -27
  537. package/dist/src-BDwEZWrZ.js +0 -568
  538. package/dist/store-jOBYpiXC.d.ts +0 -36
  539. package/dist/stores-C0IMQrGI.d.ts +0 -52
  540. package/dist/subject-C6dLxqHU.js +0 -24
  541. package/dist/supabase-config-Bj3iDH2I.js +0 -472
  542. package/dist/supabase-hook-gd3s8bxB.js +0 -2
  543. package/dist/supabase-s4o9s1O1.js +0 -83
  544. package/dist/thenable-okc2xDsj.js +0 -10
  545. package/dist/types-BnIEz1sU.d.ts +0 -48
  546. package/dist/types-Bvc4oWT6.d.ts +0 -9
  547. package/dist/types-CKNSyIf_.d.ts +0 -52
  548. package/dist/types-Cq_H8N_X.d.ts +0 -197
  549. package/dist/usage-B0YuTQRO.js +0 -42
  550. package/dist/usage-DorAJiU_.js +0 -2
  551. package/dist/vocabulary-DA8a8zif.d.ts +0 -56
  552. package/dist/watch-BwxLTYMZ.js +0 -2
@@ -1,1122 +0,0 @@
1
- import { n as isReadonlyArray, r as sole, t as compact } from "./compact-y6vfu2_f.js";
2
- import { n as freezeDeep } from "./freeze-CrU8nQeX.js";
3
- import { D as ownKeys, T as isForbiddenKey, _ as listPermissions, f as isFieldRelation, g as isSelfParented, h as isRegistryTree, i as findPermission, p as isPermission, s as getRegistry, t as annotationsFor, w as assertSafeKey } from "./permissions-DVoF6dMt.js";
4
- import { c as isConditionRef, l as isSqlFunctionField, n as isSubjectRef, o as isCondition, s as isConditionDate } from "./refs-KYb4ntaz.js";
5
- import { c as isUserApprover, i as flattenApprovers, l as user, o as isAnyOfInput, r as approverLeaves, s as isPermissionApprover } from "./approvers-DT4AVyIg.js";
6
- import { n as defineScopes, o as resolveScope } from "./scopes-CVdPrWN-.js";
7
- import { t as parseDuration } from "./duration-xK2jGFVc.js";
8
- import { E as listRoles, a as authenticated, g as relationStart, h as relationHops, l as inheritCondition, r as asGrantee, s as flattenGrantee, u as isGraphRelation, v as roleNameOf, w as isRole, y as roleScopeOf } from "./grantee-Cv5Sogfv.js";
9
- import { t as canonicalJson } from "./canonical-json-DemiK4Vp.js";
10
- import { i as sanitizeFields } from "./fields-BMl1RxoX.js";
11
- import { n as sha256, t as bytesToBase64Url } from "./sha256-BO0swRXL.js";
12
- import { f as relatesTo, h as scopeField, n as normalizeValidity, s as memberOfFields } from "./validity-uOp8UpYn.js";
13
- //#region src/conditions/opaque.ts
14
- function opaque(input) {
15
- return freezeDeep({
16
- op: "opaque",
17
- sql: input.sql,
18
- fingerprint: input.fingerprint
19
- });
20
- }
21
- //#endregion
22
- //#region src/conditions/sql-function-assert.ts
23
- const IDENT = /^[A-Za-z_][A-Za-z0-9_]*$/u;
24
- function assertSqlFunctionName(name) {
25
- const parts = name.split(".");
26
- if (parts.length === 0 || parts.length > 2) throw new Error(`PermDock: sqlFunction name '${name}' is not a SQL identifier`);
27
- for (const part of parts) {
28
- if (!IDENT.test(part)) throw new Error(`PermDock: sqlFunction name '${name}' is not a SQL identifier`);
29
- assertSafeKey(part, "sqlFunction name");
30
- }
31
- }
32
- function assertSqlFunctionArg(arg) {
33
- if (isSqlFunctionField(arg)) assertSafeKey(arg.field, "sqlFunction argument field");
34
- }
35
- function assertPortableTwin(condition, depth = 0) {
36
- /* v8 ignore next 3 */
37
- if (depth > 32) throw new Error("PermDock: sqlFunction twin is nested too deeply");
38
- switch (condition.op) {
39
- case "opaque": throw new Error("PermDock: sqlFunction twin must not be opaque");
40
- case "sqlFunction": throw new Error("PermDock: sqlFunction twin must not nest sqlFunction");
41
- case "related": throw new Error("PermDock: sqlFunction twin must not read the relation graph");
42
- case "and":
43
- case "or":
44
- for (const child of condition.conditions) assertPortableTwin(child, depth + 1);
45
- break;
46
- case "not": assertPortableTwin(condition.condition, depth + 1);
47
- }
48
- }
49
- //#endregion
50
- //#region src/conditions/normalize.ts
51
- const FIELD_OPS = /* @__PURE__ */ new Set([
52
- "eq",
53
- "ne",
54
- "gt",
55
- "gte",
56
- "lt",
57
- "lte",
58
- "contains",
59
- "in",
60
- "notIn",
61
- "isNull"
62
- ]);
63
- function toValue(raw) {
64
- if (isSubjectRef(raw) || isConditionRef(raw)) return freezeDeep({ ref: raw.ref });
65
- if (raw instanceof Date) return freezeDeep({ date: raw.toISOString() });
66
- if (isConditionDate(raw)) return freezeDeep({ date: raw.date });
67
- if (Array.isArray(raw)) return raw.map((item) => toValue(item));
68
- if (raw === null || typeof raw === "string" || typeof raw === "number" || typeof raw === "boolean") return raw;
69
- throw new Error("PermDock: unsupported condition value");
70
- }
71
- function flatten(op, conditions) {
72
- const out = [];
73
- for (const condition of conditions) if (condition.op === op) out.push(...condition.conditions);
74
- else out.push(condition);
75
- return out;
76
- }
77
- function collapse(condition) {
78
- if (condition.op === "and" || condition.op === "or") {
79
- const flat = flatten(condition.op, condition.conditions).map(collapse);
80
- if (flat.length === 0) throw new Error(`PermDock: empty ${condition.op} condition`);
81
- const single = sole(flat);
82
- if (single !== void 0) return single;
83
- return freezeDeep({
84
- op: condition.op,
85
- conditions: flat
86
- });
87
- }
88
- if (condition.op === "not") return freezeDeep({
89
- op: "not",
90
- condition: collapse(condition.condition)
91
- });
92
- if (condition.op === "sqlFunction") return freezeDeep({
93
- op: "sqlFunction",
94
- name: condition.name,
95
- args: condition.args,
96
- twin: collapse(condition.twin)
97
- });
98
- return freezeDeep(condition);
99
- }
100
- function fieldCondition(field, raw) {
101
- assertSafeKey(field, "condition field");
102
- if (isCondition(raw) && (raw.op === "opaque" || raw.op === "sqlFunction")) return raw.op === "sqlFunction" ? normalizeSqlFunction(raw) : raw;
103
- if (raw !== null && typeof raw === "object" && !isSubjectRef(raw) && !isConditionRef(raw) && !isConditionDate(raw) && !Array.isArray(raw) && !(raw instanceof Date)) {
104
- const keys = ownKeys(raw);
105
- if (keys.length === 1 && keys[0] !== void 0 && FIELD_OPS.has(keys[0])) {
106
- const op = keys[0];
107
- const value = raw[op];
108
- if (op === "isNull") {
109
- if (typeof value !== "boolean") throw new TypeError("PermDock: isNull requires a boolean");
110
- return collapse({
111
- op: "isNull",
112
- field,
113
- value
114
- });
115
- }
116
- if (op === "in" || op === "notIn") {
117
- if (isSubjectRef(value) || isConditionRef(value)) return collapse({
118
- op,
119
- field,
120
- value: { ref: value.ref }
121
- });
122
- if (!Array.isArray(value)) throw new TypeError(`PermDock: ${op} requires an array or subject reference`);
123
- return collapse({
124
- op,
125
- field,
126
- value: value.map((item) => toValue(item))
127
- });
128
- }
129
- return collapse({
130
- op,
131
- field,
132
- value: toValue(value)
133
- });
134
- }
135
- }
136
- return collapse({
137
- op: "eq",
138
- field,
139
- value: toValue(raw)
140
- });
141
- }
142
- function normalizeSqlFunction(input) {
143
- assertSqlFunctionName(input.name);
144
- const args = input.args ?? [];
145
- for (const arg of args) assertSqlFunctionArg(arg);
146
- if (isCondition(input.twin) && input.twin.op === "sqlFunction") throw new Error("PermDock: sqlFunction twin must not nest sqlFunction");
147
- const twin = isCondition(input.twin) ? collapse(input.twin) : normalizeWhere(input.twin);
148
- assertPortableTwin(twin);
149
- return freezeDeep({
150
- op: "sqlFunction",
151
- name: input.name,
152
- args,
153
- twin
154
- });
155
- }
156
- /** `{ session: … }` under `subject`; any other value is a comparison on a `subject` field. */
157
- function isSubjectCondition(value) {
158
- return value !== null && typeof value === "object" && !Array.isArray(value) && Object.hasOwn(value, "session");
159
- }
160
- function subjectCondition(value) {
161
- const session = value["session"];
162
- if (ownKeys(value).length !== 1 || session === null || typeof session !== "object" || ownKeys(session).length !== 1 || Reflect.get(session, "live") !== true) throw new TypeError("PermDock: a subject condition is { subject: { session: { live: true } } }");
163
- return freezeDeep({ op: "liveSession" });
164
- }
165
- function normalizeWhere(input) {
166
- if (isCondition(input)) {
167
- if (input.op === "sqlFunction") return collapse(normalizeSqlFunction(input));
168
- return collapse(input);
169
- }
170
- if (input !== null && typeof input === "object" && "sql" in input && "fingerprint" in input && typeof input.sql === "string") return opaque({
171
- sql: input.sql,
172
- fingerprint: input.fingerprint
173
- });
174
- if (input === null || typeof input !== "object" || Array.isArray(input)) throw new Error("PermDock: condition must be an object");
175
- const parts = [];
176
- for (const key of Object.keys(input)) {
177
- const value = input[key];
178
- if (key === "and") {
179
- if (!Array.isArray(value)) throw new TypeError("PermDock: and requires an array");
180
- parts.push(collapse({
181
- op: "and",
182
- conditions: value.map(normalizeWhere)
183
- }));
184
- continue;
185
- }
186
- if (key === "or") {
187
- if (!Array.isArray(value)) throw new TypeError("PermDock: or requires an array");
188
- parts.push(collapse({
189
- op: "or",
190
- conditions: value.map(normalizeWhere)
191
- }));
192
- continue;
193
- }
194
- if (key === "not") {
195
- parts.push(collapse({
196
- op: "not",
197
- condition: normalizeWhere(value)
198
- }));
199
- continue;
200
- }
201
- if (key === "subject" && isSubjectCondition(value)) {
202
- parts.push(subjectCondition(value));
203
- continue;
204
- }
205
- parts.push(fieldCondition(key, value));
206
- }
207
- if (parts.length === 0) throw new Error("PermDock: empty condition");
208
- const single = sole(parts);
209
- if (single !== void 0) return single;
210
- return collapse({
211
- op: "and",
212
- conditions: parts
213
- });
214
- }
215
- //#endregion
216
- //#region src/core/limits.ts
217
- const UNIT_SECONDS = {
218
- s: 1,
219
- sec: 1,
220
- secs: 1,
221
- second: 1,
222
- seconds: 1,
223
- m: 60,
224
- min: 60,
225
- mins: 60,
226
- minute: 60,
227
- minutes: 60,
228
- h: 3600,
229
- hr: 3600,
230
- hrs: 3600,
231
- hour: 3600,
232
- hours: 3600,
233
- d: 86400,
234
- day: 86400,
235
- days: 86400
236
- };
237
- function isThenable(value) {
238
- return value !== null && typeof value === "object" && "then" in value && typeof value.then === "function";
239
- }
240
- const PER_PATTERN = /^(\d+)\s*(s|sec|secs|second|seconds|m|min|mins|minute|minutes|h|hr|hrs|hour|hours|d|day|days)$/u;
241
- /** The window length of `per` in seconds, or `undefined` when unrecognised. */
242
- function limitWindowSeconds(per) {
243
- const trimmed = per.trim().toLowerCase();
244
- const named = UNIT_SECONDS[trimmed];
245
- if (named !== void 0) return named;
246
- const match = PER_PATTERN.exec(trimmed);
247
- if (match === null) return;
248
- const amount = Number(match[1]);
249
- const unit = UNIT_SECONDS[match[2] ?? ""];
250
- return unit !== void 0 && Number.isSafeInteger(amount) && amount > 0 ? amount * unit : void 0;
251
- }
252
- /** Throws at definition time for a `limit` no store could count. */
253
- function assertLimit(limit, permissionKey) {
254
- if (limit === void 0) return;
255
- if (!Number.isSafeInteger(limit.count) || limit.count <= 0) throw new Error(`PermDock: limit count on '${permissionKey}' must be a positive integer`);
256
- if (limitWindowSeconds(limit.per) === void 0) throw new Error(`PermDock: limit per '${limit.per}' on '${permissionKey}' is not a duration such as 'hour' or '15 min'`);
257
- if (limit.mode !== void 0 && limit.mode !== "hard" && limit.mode !== "soft") throw new Error(`PermDock: limit mode on '${permissionKey}' must be 'hard' or 'soft'`);
258
- if (limit.alertAt !== void 0 && (typeof limit.alertAt !== "number" || !(limit.alertAt > 0 && limit.alertAt <= 1))) throw new Error(`PermDock: limit alertAt on '${permissionKey}' must be a fraction above 0 and at most 1`);
259
- }
260
- /** The declared fields of a validated `limit`, so extra keys never reach the grant. */
261
- function normalizeLimit(limit) {
262
- if (limit === void 0) return;
263
- return {
264
- count: limit.count,
265
- per: limit.per,
266
- ...limit.mode === void 0 ? {} : { mode: limit.mode },
267
- ...limit.alertAt === void 0 ? {} : { alertAt: limit.alertAt }
268
- };
269
- }
270
- function limitWindowId(per, now) {
271
- const seconds = limitWindowSeconds(per);
272
- return seconds === void 0 ? void 0 : String(Math.floor(now / seconds));
273
- }
274
- function limitCacheKey(input, now) {
275
- const window = limitWindowId(input.per, now);
276
- return window === void 0 ? void 0 : JSON.stringify([
277
- input.tenant ?? null,
278
- input.subjectId,
279
- input.key,
280
- input.per,
281
- window
282
- ]);
283
- }
284
- function locate(input) {
285
- const now = input.now ?? Date.now() / 1e3;
286
- const seconds = limitWindowSeconds(input.per);
287
- const id = limitCacheKey(input, now);
288
- if (seconds === void 0 || id === void 0) return;
289
- return {
290
- id,
291
- until: (Math.floor(now / seconds) + 1) * seconds,
292
- now
293
- };
294
- }
295
- function memoryLimitStore() {
296
- const used = /* @__PURE__ */ new Map();
297
- let earliest = Number.POSITIVE_INFINITY;
298
- const sweep = (now) => {
299
- if (now < earliest) return;
300
- earliest = Number.POSITIVE_INFINITY;
301
- for (const [id, entry] of used) if (entry.until <= now) used.delete(id);
302
- else earliest = Math.min(earliest, entry.until);
303
- };
304
- return {
305
- remaining(input) {
306
- const cap = input.count;
307
- const slot = locate(input);
308
- if (!Number.isFinite(cap) || cap <= 0 || slot === void 0) return { remaining: -1 };
309
- return { remaining: cap - (used.get(slot.id)?.count ?? 0) };
310
- },
311
- consume(input) {
312
- const cap = input.count;
313
- const slot = locate(input);
314
- if (!Number.isFinite(cap) || cap <= 0 || slot === void 0) return { remaining: -1 };
315
- sweep(slot.now);
316
- const seen = used.get(slot.id)?.count ?? 0;
317
- if (seen >= cap) return { remaining: -1 };
318
- used.set(slot.id, {
319
- count: seen + 1,
320
- until: slot.until
321
- });
322
- earliest = Math.min(earliest, slot.until);
323
- return { remaining: cap - seen - 1 };
324
- },
325
- size() {
326
- return used.size;
327
- }
328
- };
329
- }
330
- /**
331
- * `left` is what remains once this call counts: the store's answer after
332
- * `consume`, or one less than `remaining` when only peeking. Below zero the
333
- * call is past the count.
334
- */
335
- function verdictFor(limit, left, now) {
336
- const seconds = limitWindowSeconds(limit.per);
337
- if (seconds === void 0) return {
338
- ok: false,
339
- reason: "limit-unavailable"
340
- };
341
- const resetsAt = (Math.floor(now / seconds) + 1) * seconds;
342
- if (left < 0) return limit.mode === "soft" ? {
343
- ok: true,
344
- quota: {
345
- remaining: 0,
346
- resetsAt
347
- },
348
- obligations: [{ kind: "over-limit" }]
349
- } : {
350
- ok: false,
351
- reason: "limit",
352
- detail: {
353
- count: limit.count,
354
- window: seconds,
355
- resetsAt
356
- }
357
- };
358
- return limit.alertAt !== void 0 && (limit.count - left) / limit.count >= limit.alertAt ? {
359
- ok: true,
360
- quota: {
361
- remaining: left,
362
- resetsAt
363
- },
364
- obligations: [{ kind: "near-limit" }]
365
- } : {
366
- ok: true,
367
- quota: {
368
- remaining: left,
369
- resetsAt
370
- }
371
- };
372
- }
373
- function applyQuota(input) {
374
- const limit = input.grant.limit;
375
- if (limit === void 0) return { ok: true };
376
- if (input.store === void 0) return {
377
- ok: false,
378
- reason: "limit-unavailable"
379
- };
380
- const payload = {
381
- key: input.permissionKey,
382
- subjectId: input.subjectId,
383
- count: limit.count,
384
- per: limit.per,
385
- now: input.now,
386
- ...input.tenant === void 0 ? {} : { tenant: input.tenant }
387
- };
388
- const cacheKey = limitCacheKey(payload, input.now);
389
- if (cacheKey === void 0) return {
390
- ok: false,
391
- reason: "limit-unavailable"
392
- };
393
- if (!input.consume) {
394
- try {
395
- const peeked = input.store.remaining(payload);
396
- if (isThenable(peeked)) return {
397
- ok: false,
398
- reason: "limit-unavailable"
399
- };
400
- if (peeked !== void 0) return verdictFor(limit, peeked.remaining - 1, input.now);
401
- } catch {
402
- return {
403
- ok: false,
404
- reason: "limit-unavailable"
405
- };
406
- }
407
- const cached = input.cache.get(cacheKey);
408
- if (cached === void 0) return {
409
- ok: false,
410
- reason: "limit-unavailable"
411
- };
412
- return verdictFor(limit, cached - 1, input.now);
413
- }
414
- try {
415
- const consumed = input.store.consume(payload);
416
- if (isThenable(consumed)) return {
417
- ok: false,
418
- reason: "limit-unavailable"
419
- };
420
- input.cache.set(cacheKey, consumed.remaining);
421
- return verdictFor(limit, consumed.remaining, input.now);
422
- } catch {
423
- return {
424
- ok: false,
425
- reason: "limit-unavailable"
426
- };
427
- }
428
- }
429
- //#endregion
430
- //#region src/core/policy.ts
431
- /** Every approver a requirement names: `by`, each stage and its escalation, and `escalation.to`, inside `anyOf` groups too. */
432
- function approversOf(requirement) {
433
- return [
434
- ...approverLeaves(requirement.by),
435
- ...(requirement.stages ?? []).flatMap((stage) => approverLeaves(stage.by).concat(approverLeaves(stage.escalation?.to))),
436
- ...approverLeaves(requirement.escalation?.to)
437
- ];
438
- }
439
- function asApprover(input) {
440
- if (isPermissionApprover(input)) {
441
- if (typeof input.permission !== "string" || input.permission === "") throw new Error("PermDock: a permission approver needs a permission key");
442
- return Object.freeze({
443
- kind: "permission",
444
- permission: input.permission
445
- });
446
- }
447
- if (isAnyOfInput(input)) {
448
- if (!Array.isArray(input.of) || input.of.length === 0) throw new Error("PermDock: anyOf() needs at least one approver");
449
- const of = input.of.map((item) => {
450
- const normalized = asApprover(item);
451
- const items = flattenApprovers(normalized);
452
- if (items.length === 0) throw new Error("PermDock: an anyOf() item names no approver");
453
- const [first] = items;
454
- return isReadonlyArray(normalized) || first === void 0 ? items : first;
455
- });
456
- return Object.freeze({
457
- kind: "any-of",
458
- of: Object.freeze(of)
459
- });
460
- }
461
- if (isReadonlyArray(input)) {
462
- const items = [];
463
- for (const item of input) items.push(...flattenApprovers(asApprover(item)));
464
- return items;
465
- }
466
- if (isUserApprover(input)) return user(input.id);
467
- return asGrantee(input);
468
- }
469
- function indexPolicy(roles, grants, vocabulary) {
470
- const declaredRoles = new Set(roles.map((item) => item.name));
471
- for (const leaf of listRoles(vocabulary.roles)) declaredRoles.add(leaf.key);
472
- const supports = roles.flatMap((binding) => binding.support === void 0 ? [] : [binding.support]);
473
- const listed = grants.length > 0 ? grants : roles.flatMap((binding) => binding.grants);
474
- const byKey = /* @__PURE__ */ new Map();
475
- for (const grant of listed) {
476
- const bucket = byKey.get(grant.permission.key);
477
- if (bucket === void 0) byKey.set(grant.permission.key, [grant]);
478
- else bucket.push(grant);
479
- }
480
- for (const bucket of byKey.values()) Object.freeze(bucket);
481
- return freezeDeep({
482
- declaredRoles,
483
- supports,
484
- grantsByKey: byKey
485
- });
486
- }
487
- function normalizeApproval(approval, permission) {
488
- if (approval === void 0) return;
489
- if (approval === "human") return "human";
490
- if (approval.staleOn !== void 0 && approval.staleOn !== "resource-change") throw new Error(`PermDock: approval staleOn must be 'resource-change', got '${String(approval.staleOn)}'`);
491
- const label = permission ?? "a grant";
492
- assertQuorum(approval.quorum, "approval.quorum", label);
493
- if (approval.ttl !== void 0 && parseDuration(approval.ttl) === void 0) throw new Error(`PermDock: approval.ttl on '${label}' must be a duration such as '30m', got '${approval.ttl}'`);
494
- const escalation = normalizeEscalation(approval.escalation, label);
495
- const mode = approval.mode ?? "any";
496
- if (mode !== "any") return compact({
497
- mode,
498
- stages: normalizeStages(approval, mode, label),
499
- distinct: approval.distinct,
500
- staleOn: approval.staleOn,
501
- ttl: approval.ttl,
502
- escalation
503
- });
504
- if (approval.stages !== void 0) throw new Error(`PermDock: approval.stages on '${label}' needs mode: 'all' or 'sequential'`);
505
- const by = approval.by === void 0 ? void 0 : asApprover(approval.by);
506
- if (by === void 0 && approval.distinct === void 0 && approval.staleOn === void 0 && approval.quorum === void 0 && approval.ttl === void 0 && escalation === void 0) return "human";
507
- return compact({
508
- by: by ?? authenticated(),
509
- distinct: approval.distinct,
510
- staleOn: approval.staleOn,
511
- quorum: approval.quorum,
512
- ttl: approval.ttl,
513
- escalation
514
- });
515
- }
516
- function assertQuorum(quorum, name, label) {
517
- if (quorum !== void 0 && (!Number.isInteger(quorum) || quorum < 1)) throw new Error(`PermDock: ${name} on '${label}' must be an integer of at least 1, got ${String(quorum)}`);
518
- }
519
- function normalizeStages(approval, mode, label) {
520
- if (mode !== "all" && mode !== "sequential") throw new Error(`PermDock: approval.mode on '${label}' must be 'any', 'all' or 'sequential', got '${mode}'`);
521
- if (approval.by !== void 0 || approval.quorum !== void 0) throw new Error(`PermDock: approval on '${label}' sets mode '${mode}': put by and quorum on each stage`);
522
- const stages = approval.stages ?? [];
523
- if (stages.length === 0) throw new Error(`PermDock: approval mode '${mode}' on '${label}' needs at least one stage`);
524
- return stages.map((stage, index) => {
525
- assertQuorum(stage.quorum, `approval.stages[${index}].quorum`, label);
526
- const by = asApprover(stage.by);
527
- if (flattenApprovers(by).length === 0) throw new Error(`PermDock: approval.stages[${index}].by on '${label}' names no approver`);
528
- return compact({
529
- by,
530
- quorum: stage.quorum,
531
- escalation: normalizeEscalation(stage.escalation, label)
532
- });
533
- });
534
- }
535
- function normalizeEscalation(escalation, label) {
536
- if (escalation === void 0) return;
537
- if (parseDuration(escalation.after) === void 0) throw new Error(`PermDock: approval.escalation.after on '${label}' must be a duration such as '4h', got '${escalation.after}'`);
538
- return {
539
- after: escalation.after,
540
- to: asApprover(escalation.to)
541
- };
542
- }
543
- function isClosure(value) {
544
- return typeof value === "function";
545
- }
546
- function flattenPermissions(input) {
547
- if (isPermission(input)) return [input];
548
- if (isReadonlyArray(input)) return input.flatMap((item) => flattenPermissions(item));
549
- return [...listPermissions(input)];
550
- }
551
- function delegationTarget(to, index) {
552
- if (typeof to === "string") return { kind: to };
553
- if ("actor" in to) return { kind: to.actor };
554
- const target = compact({
555
- kind: to.kind,
556
- id: to.id,
557
- client: to.client
558
- });
559
- if (typeof target.kind !== "string" || target.kind === "") throw new Error(`PermDock: delegations[${index}].to needs an actor kind, such as actor('eve')`);
560
- if (target.id !== void 0 && (typeof target.id !== "string" || target.id === "")) throw new Error(`PermDock: delegations[${index}].to.id must be a non-empty string`);
561
- if (target.client !== void 0 && (typeof target.client !== "string" || target.client === "")) throw new Error(`PermDock: delegations[${index}].to.client must be a non-empty string`);
562
- if (target.id !== void 0 && target.client !== void 0) throw new Error(`PermDock: delegations[${index}].to names both an id and a client; name one`);
563
- return target;
564
- }
565
- function normalizeDelegation(input, index, tree) {
566
- const label = `delegations[${index}]`;
567
- const from = asGrantee(input.from);
568
- const items = flattenGrantee(from);
569
- if (items.length === 0) throw new Error(`PermDock: ${label}.from names nobody`);
570
- if (items.some((item) => item.kind === "relation" || item.kind === "inherit")) throw new Error(`PermDock: ${label}.from names a relation or inherit(); a delegation is matched without a row, so name a role or another subject-only grantee`);
571
- if (items.some((item) => item.kind === "actor")) throw new Error(`PermDock: ${label}.from names an actor; the principal hands over, the actor is \`to\``);
572
- const leaves = /* @__PURE__ */ new Map();
573
- for (const leaf of input.permissions.flatMap((item) => flattenPermissions(item))) {
574
- if (findPermission(tree, leaf.key) === void 0) throw new Error(`PermDock: ${label} names unknown permission '${leaf.key}'`);
575
- leaves.set(leaf.key, leaf);
576
- }
577
- const keys = [...leaves.keys()].toSorted();
578
- if (keys.length === 0) throw new Error(`PermDock: ${label}.permissions is empty`);
579
- return compact({
580
- from,
581
- to: delegationTarget(input.to, index),
582
- permissions: keys,
583
- readOnly: [...leaves.values()].filter((leaf) => annotationsFor(leaf).readOnlyHint).map((leaf) => leaf.key).toSorted(),
584
- validity: normalizeValidity(input, label)
585
- });
586
- }
587
- /** RFC 6749 section 3.3 `scope-token`: printable ASCII without space, `"` or `\`. */
588
- function isScopeToken(value) {
589
- return /^[!#-[\]-~]+$/u.test(value);
590
- }
591
- function normalizeOAuthScopes(input, tree) {
592
- if (input === void 0) return [];
593
- const own = new Set(listPermissions(tree).map((leaf) => leaf.scope));
594
- return Object.entries(input).map(([scope, items]) => {
595
- if (!isScopeToken(scope)) throw new Error(`PermDock: oauthScopes key '${scope}' is not an OAuth scope token`);
596
- if (own.has(scope)) throw new Error(`PermDock: oauthScopes key '${scope}' is a permission's own scope`);
597
- const leaves = /* @__PURE__ */ new Map();
598
- for (const leaf of (Array.isArray(items) ? items : []).flatMap((item) => flattenPermissions(item))) {
599
- if (findPermission(tree, leaf.key) === void 0) throw new Error(`PermDock: oauthScopes '${scope}' names unknown permission '${leaf.key}'`);
600
- leaves.set(leaf.key, leaf);
601
- }
602
- if (leaves.size === 0) throw new Error(`PermDock: oauthScopes '${scope}' covers no permission`);
603
- const sorted = [...leaves.values()].toSorted((a, b) => a.key.localeCompare(b.key));
604
- return {
605
- scope,
606
- permissions: sorted.map((leaf) => leaf.key),
607
- scopes: sorted.map((leaf) => leaf.scope)
608
- };
609
- });
610
- }
611
- function resolveRoleScope(on) {
612
- if (on === void 0) return "global";
613
- if (typeof on === "string") {
614
- if (on === "global" || on === "resource") throw new Error(`PermDock: role on: '${on}' is not a scope name`);
615
- return on;
616
- }
617
- const permissions = flattenPermissions(on);
618
- const names = new Set(permissions.map((permission) => permission.resource));
619
- const [resource] = names;
620
- if (names.size !== 1 || resource === void 0) throw new Error("PermDock: role on: resource must name exactly one resource");
621
- return { resource };
622
- }
623
- const GROUP = /^[a-z][a-z0-9_-]*$/u;
624
- function grantGroup(group, key) {
625
- if (group === void 0) return;
626
- if (typeof group !== "string" || !GROUP.test(group) || group === "break-glass") throw new Error(`PermDock: group '${String(group)}' on ${key} must be lower case letters, digits, _ or -, start with a letter, and not be break-glass`);
627
- return group;
628
- }
629
- function makeGrant(permission, effect, condition) {
630
- const toInput = isClosure(condition) ? void 0 : condition?.to;
631
- const to = toInput === void 0 ? {
632
- kind: "role",
633
- role: "",
634
- scope: "global"
635
- } : asGrantee(toInput);
636
- if (isClosure(condition)) return {
637
- permission,
638
- effect,
639
- to,
640
- portable: false,
641
- closure: condition
642
- };
643
- const whereInput = condition?.where;
644
- const checkInput = condition?.check;
645
- if (whereInput !== void 0 && permission.kind === "collection") throw new Error(`PermDock: where is not allowed on collection action '${permission.key}'`);
646
- const where = whereInput === void 0 ? void 0 : normalizeWhere(whereInput);
647
- const check = checkInput === void 0 ? void 0 : normalizeWhere(checkInput);
648
- assertLimit(condition?.limit, permission.key);
649
- const purpose = condition?.purpose === void 0 || condition.purpose.length === 0 ? void 0 : Object.freeze([...new Set(condition.purpose)]);
650
- const portable = condition?.limit === void 0 && purpose === void 0;
651
- const requires = requiredKey(condition?.requires, permission, effect);
652
- return compact({
653
- permission,
654
- effect,
655
- to,
656
- where,
657
- check,
658
- approval: normalizeApproval(condition?.approval, permission.key),
659
- portable,
660
- limit: normalizeLimit(condition?.limit),
661
- fields: sanitizeFields(condition?.fields),
662
- name: condition?.name,
663
- group: grantGroup(condition?.group, permission.key),
664
- purpose,
665
- validity: normalizeValidity(condition ?? {}, permission.key),
666
- requires
667
- });
668
- }
669
- function requiredKey(input, permission, effect) {
670
- if (input === void 0) return;
671
- if (effect !== "allow") throw new Error(`PermDock: requires is allowed on an allow only; '${permission.key}' is a deny`);
672
- if (permission.kind !== "instance") throw new Error(`PermDock: requires on '${permission.key}' needs an instance action; a collection action has no row whose scope it can check`);
673
- const list = Array.isArray(input) ? input : [input];
674
- if (list.length === 0 || !list.every(isPermission)) throw new TypeError(`PermDock: requires on '${permission.key}' must be a permission leaf or a non-empty list of them`);
675
- return Object.freeze([...new Set(list.map((leaf) => leaf.key))]);
676
- }
677
- function allow(permission, condition) {
678
- const grants = flattenPermissions(permission).map((leaf) => makeGrant(leaf, "allow", condition));
679
- return sole(grants) ?? grants;
680
- }
681
- function deny(permission, condition) {
682
- const grants = flattenPermissions(permission).map((leaf) => makeGrant(leaf, "deny", condition));
683
- return sole(grants) ?? grants;
684
- }
685
- function flattenGrants(grants) {
686
- const out = [];
687
- for (const grant of grants) if (Array.isArray(grant)) out.push(...grant);
688
- else out.push(grant);
689
- return out;
690
- }
691
- function role(name, grants, options) {
692
- if (options !== void 0 && Object.hasOwn(options, "restricted")) throw new Error(`PermDock: role option 'restricted' is reserved`);
693
- const leaf = isRole(name) ? name : void 0;
694
- const roleName = leaf?.key ?? name;
695
- const scope = resolveRoleScope(options?.on ?? leaf?.on);
696
- const assignable = options?.assignable ?? leaf?.assignable ?? scope !== "global";
697
- const rules = roleRules(roleName, scope, options);
698
- const activation = normalizeActivation(roleName, options?.activation);
699
- const roleGrantee = asGrantee(freezeDeep({
700
- kind: "role",
701
- role: roleName,
702
- scope
703
- }));
704
- const normalised = flattenGrants(grants).map((grant) => {
705
- const items = flattenGrantee(grant.to);
706
- const first = items[0];
707
- const to = items.length === 1 && first?.kind === "role" ? roleGrantee : grant.to;
708
- return freezeDeep({
709
- ...grant,
710
- to,
711
- role: roleName,
712
- scope: roleScopeOf(to, scope)
713
- });
714
- });
715
- return freezeDeep(compact({
716
- name: roleName,
717
- grants: normalised,
718
- on: options?.on ?? leaf?.on,
719
- assignable,
720
- exclusiveWith: options?.exclusiveWith,
721
- ...rules,
722
- meta: options?.meta ?? leaf?.meta,
723
- activation
724
- }));
725
- }
726
- /**
727
- * A role with `activation` is eligible-only: it needs a positive `maxDuration`
728
- * (Doctor PD033 warns without one). `justification` defaults to `'optional'`.
729
- */
730
- function activationApproval(option, roleName) {
731
- const label = `activation of '${roleName}'`;
732
- const approval = normalizeApproval(option, label);
733
- if (approval !== void 0 && approval !== "human" && approversOf(approval).some((item) => item.kind === "relation")) throw new Error(`PermDock: approval on ${label} names a relation; an activation has no row to read it on`);
734
- return approval;
735
- }
736
- function normalizeActivation(roleName, option) {
737
- if (option === void 0) return;
738
- const justification = option.justification ?? "optional";
739
- if (justification !== "required" && justification !== "optional") throw new Error(`PermDock: role '${roleName}' activation justification must be 'required' or 'optional'`);
740
- return compact({
741
- maxDuration: option.maxDuration,
742
- justification,
743
- approval: activationApproval(option.approval, roleName),
744
- assurance: normalizeAssurance(option.assurance)
745
- });
746
- }
747
- function normalizeAssurance(input) {
748
- if (input === void 0) return;
749
- const acr = input.acr === void 0 || input.acr.length === 0 ? void 0 : Object.freeze([...input.acr]);
750
- const amr = input.amr === void 0 || input.amr.length === 0 ? void 0 : Object.freeze([...input.amr]);
751
- const maxAge = typeof input.maxAge === "number" && input.maxAge >= 0 ? input.maxAge : void 0;
752
- if (acr === void 0 && amr === void 0 && maxAge === void 0) return;
753
- return compact({
754
- maxAge,
755
- acr,
756
- amr
757
- });
758
- }
759
- function nameList(roleName, option, value) {
760
- if (value === void 0) return;
761
- if (!Array.isArray(value) || value.some((item) => typeof item !== "string" || item === "" || isForbiddenKey(item))) throw new Error(`PermDock: role '${roleName}' ${option} must be a list of names`);
762
- return [...new Set(value)];
763
- }
764
- function holderCount(roleName, option, value) {
765
- if (value === void 0) return;
766
- if (typeof value !== "number" || !Number.isInteger(value) || value < 0) throw new Error(`PermDock: role '${roleName}' ${option} must be a whole number of holders`);
767
- return value;
768
- }
769
- /** Ownership rules count holders per scope instance, so they need a named-scope role. */
770
- function roleRules(roleName, scope, options) {
771
- const min = holderCount(roleName, "min", options?.min);
772
- const max = holderCount(roleName, "max", options?.max);
773
- const transferOnly = options?.transferOnly;
774
- if (transferOnly !== void 0 && typeof transferOnly !== "boolean") throw new Error(`PermDock: role '${roleName}' transferOnly must be a boolean`);
775
- if (max !== void 0 && max < 1) throw new Error(`PermDock: role '${roleName}' max must be at least 1`);
776
- if (min !== void 0 && max !== void 0 && min > max) throw new Error(`PermDock: role '${roleName}' min must not exceed max`);
777
- if ((min !== void 0 && min > 0 || max !== void 0 || transferOnly === true) && (typeof scope !== "string" || scope === "global")) throw new Error(`PermDock: role '${roleName}' min, max and transferOnly need on: '<scope>'`);
778
- return compact({
779
- min,
780
- max,
781
- transferOnly,
782
- assigns: nameList(roleName, "assigns", options?.assigns),
783
- for: nameList(roleName, "for", options?.for)
784
- });
785
- }
786
- function canonicalPolicy(grants, delegations, levels) {
787
- const payload = canonicalGrants(grants);
788
- const withDelegations = delegations.length === 0 ? payload : `${payload}\n${JSON.stringify(delegations)}`;
789
- return levels === void 0 ? withDelegations : `${withDelegations}\nlevels:${canonicalJson(levels)}`;
790
- }
791
- function normalizeLevels(resources) {
792
- const out = {};
793
- for (const node of resources.values()) {
794
- const entries = Object.entries({ ...node.levels });
795
- if (entries.length === 0) continue;
796
- const levels = {};
797
- for (const [name, input] of entries) try {
798
- levels[name] = Object.keys(input).length === 0 ? {
799
- op: "and",
800
- conditions: []
801
- } : normalizeWhere(input);
802
- } catch (error) {
803
- throw new Error(`PermDock: level '${name}' on '${node.name}' is not a valid condition`, { cause: error });
804
- }
805
- out[node.name] = levels;
806
- }
807
- return Object.keys(out).length === 0 ? void 0 : freezeDeep(out);
808
- }
809
- /** Declared levels of `resource` with their conditions, in declaration order. */
810
- function policyLevels(policy, resource) {
811
- const levels = policy.levels;
812
- return levels !== void 0 && Object.hasOwn(levels, resource) ? Object.entries({ ...levels[resource] }) : [];
813
- }
814
- /** The condition of `level` on `resource`, if the policy declares it. */
815
- function levelCondition(policy, resource, level) {
816
- return policyLevels(policy, resource).find(([name]) => name === level)?.[1];
817
- }
818
- /** Declared level names of `resource`, in declaration order. */
819
- function levelNames(policy, resource) {
820
- return policyLevels(policy, resource).map(([name]) => name);
821
- }
822
- function canonicalGrants(grants) {
823
- const payload = grants.map((grant) => ({
824
- permission: grant.permission.key,
825
- effect: grant.effect,
826
- to: grant.to,
827
- role: grant.role,
828
- where: grant.where,
829
- check: grant.check,
830
- approval: grant.approval,
831
- portable: grant.portable,
832
- fields: grant.fields,
833
- scope: grant.scope,
834
- name: grant.name,
835
- purpose: grant.purpose,
836
- breakGlass: grant.breakGlass,
837
- viaOnly: grant.viaOnly,
838
- validity: grant.validity,
839
- requires: grant.requires
840
- }));
841
- return JSON.stringify(payload);
842
- }
843
- function assertParentGraph(resources) {
844
- for (const node of resources.values()) {
845
- if (node.parent === void 0) continue;
846
- if (!resources.has(node.parent.resource)) throw new Error(`PermDock: resource '${node.name}' parents unknown resource '${node.parent.resource}'`);
847
- }
848
- }
849
- /**
850
- * Graph relation grantees must reach their resource: `through: 'parent'` from
851
- * the row to its parent resource or along its own self-parent, and never over
852
- * a `memberOf` relation, which is tenancy, not the object graph.
853
- */
854
- function assertRelationGrants(grants, resources) {
855
- for (const grant of grants) for (const item of flattenGrantee(grant.to)) {
856
- if (item.kind !== "relation" || !isGraphRelation(item, resources)) continue;
857
- const label = `grant ${grant.permission.key} relation '${item.relation}'`;
858
- const target = resources.get(item.resource);
859
- const spec = target?.relations[item.relation];
860
- if (target === void 0 || spec === void 0) throw new Error(`PermDock: ${label}: ${item.resource} does not declare it`);
861
- if (isFieldRelation(spec) && spec.memberOf !== void 0) throw new Error(`PermDock: ${label} is a memberOf relation; through walks the object graph, not scopes`);
862
- const row = resources.get(grant.permission.resource);
863
- if (Array.isArray(item.through)) {
864
- if (relationHops(item, row, resources) === void 0) throw new Error(`PermDock: ${label}: the links [${item.through.join(", ")}] from ${grant.permission.resource} do not end on ${target.name}${(item.depth ?? 0) > 0 ? ` (or ${target.name} does not parent itself for depth)` : ""}`);
865
- continue;
866
- }
867
- if (item.through === "parent" && target.name === row?.name && !isSelfParented(target)) throw new Error(`PermDock: ${label}: through: 'parent' needs ${target.name} to parent itself`);
868
- if (relationStart(item, row, target) === void 0) throw new Error(item.through === void 0 ? `PermDock: ${label} is on ${target.name}, not ${grant.permission.resource}; add through: 'parent'` : `PermDock: ${label}: ${grant.permission.resource} has no parent on ${target.name}`);
869
- }
870
- }
871
- function assertInheritGrants(grants, resources, tree) {
872
- const keys = new Set(listPermissions(tree).map((leaf) => leaf.key));
873
- const edges = /* @__PURE__ */ new Map();
874
- for (const grant of grants) for (const item of flattenGrantee(grant.to)) {
875
- if (item.kind !== "inherit") continue;
876
- const label = `grant ${grant.permission.key} inherit '${item.permission}'`;
877
- if (grant.effect !== "allow") throw new Error(`PermDock: ${label}: inherit() is allowed on an allow only`);
878
- if (grant.permission.kind !== "instance") throw new Error(`PermDock: ${label}: inherit() needs an instance action; a collection action has no row to follow`);
879
- if (!keys.has(item.permission)) throw new Error(`PermDock: ${label}: the policy does not declare it`);
880
- if (inheritCondition(item, resources.get(grant.permission.resource), resources) === void 0) throw new Error(item.through === "parent" ? `PermDock: ${label}: ${grant.permission.resource} has no parent on ${item.resource}` : `PermDock: ${label}: the links [${item.through.join(", ")}] from ${grant.permission.resource} do not end on ${item.resource}`);
881
- const next = edges.get(grant.permission.key) ?? /* @__PURE__ */ new Set();
882
- next.add(item.permission);
883
- edges.set(grant.permission.key, next);
884
- }
885
- const done = /* @__PURE__ */ new Set();
886
- const visit = (key, path) => {
887
- if (path.includes(key)) throw new Error(`PermDock: inherit() grants form a cycle: ${[...path.slice(path.indexOf(key)), key].join(" -> ")}`);
888
- if (done.has(key)) return;
889
- for (const target of edges.get(key) ?? []) visit(target, [...path, key]);
890
- done.add(key);
891
- };
892
- for (const key of edges.keys()) visit(key, []);
893
- }
894
- function scopeOfGrant(scope, declared) {
895
- if (typeof scope !== "string" || scope === "global") return scope;
896
- const resolved = resolveScope(declared, scope);
897
- if (resolved === void 0) throw new Error(`PermDock: definePolicy({ scopes }) must declare '${scope}' for on: '${scope}' roles`);
898
- return resolved;
899
- }
900
- function rescopeGrantee(to, declared) {
901
- const items = flattenGrantee(to);
902
- if (!items.some((item) => item.kind === "role")) return to;
903
- const mapped = items.map((item) => item.kind === "role" ? freezeDeep({
904
- ...item,
905
- scope: scopeOfGrant(item.scope, declared)
906
- }) : item);
907
- if (Array.isArray(to)) return freezeDeep(mapped);
908
- const [single] = mapped;
909
- return single ?? to;
910
- }
911
- /** Resolves `tenant` / `team` aliases to declared names; an undeclared scope throws. */
912
- function rescopeGrant(grant, declared) {
913
- const scope = scopeOfGrant(grant.scope, declared);
914
- const to = rescopeGrantee(grant.to, declared);
915
- if (scope === grant.scope && to === grant.to) return grant;
916
- return freezeDeep({
917
- ...grant,
918
- scope,
919
- to
920
- });
921
- }
922
- function rescopeBinding(binding, declared) {
923
- const grants = binding.grants.map((grant) => rescopeGrant(grant, declared));
924
- const on = typeof binding.on === "string" ? scopeOfGrant(binding.on, declared) : binding.on;
925
- return freezeDeep(compact({
926
- ...binding,
927
- grants,
928
- on
929
- }));
930
- }
931
- /**
932
- * No implicit cascade: a grant on scope S reaches a row only through the row's
933
- * own S key, so every resource an instance grant on S touches declares a
934
- * `memberOf: S` relation on that key. Without it `where()` and RLS could not
935
- * narrow the rows.
936
- */
937
- function assertScopeKeys(grants, scopes, resources) {
938
- for (const grant of grants) {
939
- if (typeof grant.scope !== "string" || grant.scope === "global" || grant.permission.kind !== "instance") continue;
940
- const key = scopes.find((scope) => scope.name === grant.scope)?.key;
941
- const node = resources.get(grant.permission.resource);
942
- if (key === void 0 || node === void 0) continue;
943
- const fields = memberOfFields(node, grant.scope, scopes);
944
- if (fields.length > 1 && !fields.includes(key)) throw new Error(`PermDock: resource '${node.name}' declares several memberOf relations to '${grant.scope}' (${fields.join(", ")}); name the one holding the instance with the scope's key '${key}'`);
945
- const field = scopeField(node, grant.scope, scopes);
946
- if (field !== void 0 && relatesTo(node, field, grant.scope, scopes)) continue;
947
- throw new Error(`PermDock: resource '${node.name}' needs relations: { <name>: { field: '${key}', memberOf: '${grant.scope}' } } for ${grant.permission.key} on '${grant.scope}' roles`);
948
- }
949
- }
950
- /** A `requires` names a permission the policy declares. */
951
- function assertRequires(grants, tree) {
952
- const keys = new Set(listPermissions(tree).map((leaf) => leaf.key));
953
- for (const grant of grants) for (const key of grant.requires ?? []) if (!keys.has(key)) throw new Error(`PermDock: '${grant.permission.key}' requires '${key}', which the policy does not declare`);
954
- }
955
- /**
956
- * A stale-on-change approval needs a row to version: an instance permission
957
- * whose resource declares `version`.
958
- */
959
- function assertApprovalVersions(grants, resources) {
960
- for (const grant of grants) {
961
- const approval = grant.approval;
962
- if (approval === void 0 || approval === "human" || approval.staleOn === void 0) continue;
963
- if (grant.permission.kind !== "instance") throw new Error(`PermDock: approval staleOn on '${grant.permission.key}' needs an instance action; a collection action has no row to version`);
964
- if (resources.get(grant.permission.resource)?.version === void 0) throw new Error(`PermDock: approval staleOn on '${grant.permission.key}' needs resource(..., { version: '<field>' }) on '${grant.permission.resource}'`);
965
- }
966
- }
967
- /**
968
- * A relation approver is checked by id, from the requested row: the
969
- * relation lives on the permission's own resource (optionally up its parent
970
- * chain), or at the end of a list of links from it.
971
- */
972
- function assertApprovalRelations(grants, resources) {
973
- for (const grant of grants) {
974
- const approval = grant.approval;
975
- if (approval === void 0 || approval === "human") continue;
976
- for (const item of approversOf(approval)) {
977
- if (item.kind !== "relation") continue;
978
- const label = `${grant.permission.key}: approver relation '${item.relation}'`;
979
- if (grant.permission.kind !== "instance") throw new Error(`PermDock: ${label} needs an instance action; a collection action has no row to read it on`);
980
- if (approverRelationResource(grant.permission.resource, item.through, resources) !== item.resource) throw new Error(`PermDock: ${label} must live on '${grant.permission.resource}' or at the end of its through links`);
981
- if (resources.get(item.resource)?.relations[item.relation] === void 0) throw new Error(`PermDock: ${label} is not declared on '${item.resource}'`);
982
- }
983
- }
984
- }
985
- /** The resource a relation approver's `through` reaches from `start`, or `undefined`. */
986
- function approverRelationResource(start, through, resources) {
987
- if (through === void 0) return start;
988
- if (through === "parent") return isSelfParented(resources.get(start)) ? start : void 0;
989
- let current = start;
990
- for (const name of through) {
991
- const node = current === void 0 ? void 0 : resources.get(current);
992
- current = node !== void 0 && Object.hasOwn(node.links, name) ? node.links[name]?.resource : void 0;
993
- }
994
- return current;
995
- }
996
- function isVocabularyInput(value) {
997
- return value !== null && typeof value === "object" && "permissions" in value && isRegistryTree(value.permissions);
998
- }
999
- function completeGrant(grant) {
1000
- const to = flattenGrantee(grant.to);
1001
- const first = to[0];
1002
- if (to.length === 1 && first?.kind === "role" && first.role === "") throw new Error("PermDock: grant is missing to");
1003
- return freezeDeep({
1004
- ...grant,
1005
- role: roleNameOf(grant.to),
1006
- scope: roleScopeOf(grant.to)
1007
- });
1008
- }
1009
- function mergeBindings(items) {
1010
- const merged = /* @__PURE__ */ new Map();
1011
- for (const item of items) {
1012
- const existing = merged.get(item.name);
1013
- if (existing === void 0) {
1014
- merged.set(item.name, item);
1015
- continue;
1016
- }
1017
- merged.set(item.name, freezeDeep(compact({
1018
- name: item.name,
1019
- grants: [...existing.grants, ...item.grants],
1020
- on: existing.on,
1021
- assignable: existing.assignable,
1022
- exclusiveWith: existing.exclusiveWith ?? item.exclusiveWith,
1023
- min: existing.min ?? item.min,
1024
- max: existing.max ?? item.max,
1025
- transferOnly: existing.transferOnly ?? item.transferOnly,
1026
- assigns: existing.assigns ?? item.assigns,
1027
- for: existing.for ?? item.for,
1028
- meta: existing.meta ?? item.meta,
1029
- activation: existing.activation ?? item.activation,
1030
- support: existing.support ?? item.support
1031
- })));
1032
- }
1033
- return {
1034
- roles: [...merged.values()],
1035
- rolesByName: merged
1036
- };
1037
- }
1038
- function definePolicy(permissions, options) {
1039
- const vocabulary = isVocabularyInput(permissions) ? permissions : { permissions };
1040
- const tree = vocabulary.permissions;
1041
- const mapper = options.principal ?? options.subject;
1042
- if (mapper === void 0) throw new Error("PermDock: definePolicy requires principal or subject");
1043
- const resources = getRegistry(tree);
1044
- assertParentGraph(resources);
1045
- const scopes = defineScopes(options.scopes);
1046
- const { roles, rolesByName } = mergeBindings((options.roles ?? []).map((binding) => rescopeBinding(binding, scopes)));
1047
- const declared = new Set(roles.map((item) => item.name));
1048
- for (const leaf of listRoles(vocabulary.roles)) declared.add(leaf.key);
1049
- for (const binding of roles) for (const name of binding.assigns ?? []) if (!declared.has(name)) throw new Error(`PermDock: role '${binding.name}' names undeclared role '${name}'`);
1050
- const fromBindings = roles.flatMap((item) => item.grants);
1051
- const fromGrants = flattenGrants(options.grants ?? []).map(completeGrant).map((grant) => rescopeGrant(grant, scopes));
1052
- const grants = [...fromBindings, ...fromGrants];
1053
- assertScopeKeys(grants, scopes, resources);
1054
- assertApprovalVersions(grants, resources);
1055
- assertApprovalRelations(grants, resources);
1056
- assertRelationGrants(grants, resources);
1057
- assertRequires(grants, tree);
1058
- assertInheritGrants(grants, resources, tree);
1059
- const delegations = (options.delegations ?? []).map((item, index) => normalizeDelegation(item, index, tree));
1060
- const levels = normalizeLevels(resources);
1061
- const oauthScopes = normalizeOAuthScopes(options.oauthScopes, tree);
1062
- const fingerprint = bytesToBase64Url(sha256(oauthScopes.length === 0 ? canonicalPolicy(grants, delegations, levels) : `${canonicalPolicy(grants, delegations, levels)}\noauthScopes:${canonicalJson(oauthScopes)}`));
1063
- const hostable = [...new Set((options.hostable ?? []).flatMap((item) => flattenPermissions(item).map((leaf) => leaf.key)))].toSorted();
1064
- const fresh = [...new Set((options.fresh ?? []).flatMap((item) => flattenPermissions(item).map((leaf) => leaf.key)))].toSorted();
1065
- return freezeDeep({
1066
- permissions: tree,
1067
- roles,
1068
- rolesByName,
1069
- grants,
1070
- vocabulary,
1071
- scopes,
1072
- principal: mapper,
1073
- subject: mapper,
1074
- context: options.context,
1075
- validate: options.validate ?? "boundary",
1076
- onDenied: options.onDenied,
1077
- fingerprint,
1078
- resources,
1079
- providers: options.providers,
1080
- hostable,
1081
- fresh,
1082
- delegations: delegations.length === 0 ? void 0 : delegations,
1083
- levels,
1084
- oauthScopes: oauthScopes.length === 0 ? void 0 : oauthScopes,
1085
- index: indexPolicy(roles, grants, vocabulary)
1086
- });
1087
- }
1088
- function exclusivePairs(policy) {
1089
- const pairs = /* @__PURE__ */ new Map();
1090
- for (const binding of policy.roles) if (binding.exclusiveWith !== void 0) pairs.set(binding.name, binding.exclusiveWith);
1091
- return pairs;
1092
- }
1093
- function grantList(policy) {
1094
- if (policy.grants !== void 0 && policy.grants.length > 0) return policy.grants;
1095
- return policy.roles.flatMap((binding) => binding.grants);
1096
- }
1097
- function declaredRoleNames(policy) {
1098
- return policy.index.declaredRoles;
1099
- }
1100
- function separationConflicts(policy, memberships) {
1101
- const exclusive = exclusivePairs(policy);
1102
- const seen = /* @__PURE__ */ new Set();
1103
- const conflicts = [];
1104
- for (const membership of memberships) {
1105
- const held = new Set(membership.roles);
1106
- for (const name of held) for (const other of exclusive.get(name) ?? []) {
1107
- if (!held.has(other)) continue;
1108
- const pair = [name, other].toSorted();
1109
- const key = `${membership.principal ?? ""}:${membership.tenant ?? ""}:${pair.join("+")}`;
1110
- if (seen.has(key)) continue;
1111
- seen.add(key);
1112
- conflicts.push(compact({
1113
- principal: membership.principal ?? "",
1114
- tenant: membership.tenant,
1115
- roles: pair
1116
- }));
1117
- }
1118
- }
1119
- return conflicts;
1120
- }
1121
- //#endregion
1122
- export { opaque as S, memoryLimitStore as _, definePolicy as a, assertSqlFunctionArg as b, indexPolicy as c, normalizeApproval as d, normalizeAssurance as f, applyQuota as g, separationConflicts as h, declaredRoleNames as i, levelCondition as l, role as m, assertApprovalRelations as n, deny as o, policyLevels as p, completeGrant as r, grantList as s, allow as t, levelNames as u, normalizeWhere as v, assertSqlFunctionName as x, assertPortableTwin as y };