permdock 0.0.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (344) hide show
  1. package/README.md +327 -1
  2. package/dist/a2a/index.d.ts +169 -0
  3. package/dist/a2a/index.js +232 -0
  4. package/dist/adapter-context-mlWsVGGg.js +23 -0
  5. package/dist/ai-sdk/index.d.ts +95 -0
  6. package/dist/ai-sdk/index.js +154 -0
  7. package/dist/approval-required-TzNB9oQA.js +6 -0
  8. package/dist/approvals/index.d.ts +3 -0
  9. package/dist/approvals/index.js +5 -0
  10. package/dist/approvals-DbYAuNkG.js +224 -0
  11. package/dist/approvers-DT4AVyIg.js +52 -0
  12. package/dist/arazzo-BAgw9ap6.js +70 -0
  13. package/dist/arazzo-cmvX2jDe.js +54 -0
  14. package/dist/authzen/index.d.ts +39 -0
  15. package/dist/authzen/index.js +302 -0
  16. package/dist/better-auth/index.d.ts +109 -0
  17. package/dist/better-auth/index.js +344 -0
  18. package/dist/better-supabase/index.d.ts +206 -0
  19. package/dist/better-supabase/index.js +620 -0
  20. package/dist/bind-CVy3Espv.d.ts +25 -0
  21. package/dist/bind-VnYn2HKq.js +97 -0
  22. package/dist/boundary-BM8a_P6E.js +13 -0
  23. package/dist/boundary-BmHxVH1J.d.ts +15 -0
  24. package/dist/budget-JqcRqyhK.d.ts +11 -0
  25. package/dist/budget-NbEtbJC_.js +11 -0
  26. package/dist/canonical-json-DemiK4Vp.js +26 -0
  27. package/dist/capability-4qPdO9gk.js +173 -0
  28. package/dist/capability-Dq43tT1u.d.ts +99 -0
  29. package/dist/catalog/index.d.ts +12 -0
  30. package/dist/catalog/index.js +2 -0
  31. package/dist/catalog-BjZSovXQ.js +2 -0
  32. package/dist/catalog-doc-Dsc9y7sd.js +309 -0
  33. package/dist/catalog-h2tlKFkq.js +48 -0
  34. package/dist/catalog-path-CnI0XTFK.js +12 -0
  35. package/dist/catalog-z8q6bi_r.js +55 -0
  36. package/dist/claude-agent/index.d.ts +72 -0
  37. package/dist/claude-agent/index.js +77 -0
  38. package/dist/clerk/index.d.ts +65 -0
  39. package/dist/clerk/index.js +301 -0
  40. package/dist/cli/bin.d.ts +1 -0
  41. package/dist/cli/bin.js +20 -0
  42. package/dist/cli/index.d.ts +46 -0
  43. package/dist/cli/index.js +5 -0
  44. package/dist/clients-C7zLFuWT.d.ts +12 -0
  45. package/dist/clients-DjU5ABMy.js +23 -0
  46. package/dist/cloud/index.d.ts +90 -0
  47. package/dist/cloud/index.js +404 -0
  48. package/dist/cloud-BGhHS-lY.js +50 -0
  49. package/dist/cloud-Bo3e9Ak3.js +118 -0
  50. package/dist/collect-DDDv_ESs.js +502 -0
  51. package/dist/collect-DLlujdHC.js +83 -0
  52. package/dist/collect-rG2IQ3t0.js +2 -0
  53. package/dist/commands-DWOrSQic.js +97 -0
  54. package/dist/compact-y6vfu2_f.js +19 -0
  55. package/dist/compare-pfyVnBjE.js +12 -0
  56. package/dist/compile/index.d.ts +3 -0
  57. package/dist/compile/index.js +2 -0
  58. package/dist/compile-Ba4blROR.js +613 -0
  59. package/dist/compile-CNnl6uIt.d.ts +94 -0
  60. package/dist/config-BJiM-xAm.js +157 -0
  61. package/dist/config-Bn00Z3ks.js +36 -0
  62. package/dist/config-report-Dw_JcUqT.js +44 -0
  63. package/dist/connection-CU8MQxRi.js +194 -0
  64. package/dist/context-Ttp0ekMT.js +82 -0
  65. package/dist/convex/index.d.ts +45 -0
  66. package/dist/convex/index.js +65 -0
  67. package/dist/create-BWyx3jua.d.ts +245 -0
  68. package/dist/create-CPhDL6qx.js +253 -0
  69. package/dist/credential-8P81ff4u.js +306 -0
  70. package/dist/delegation-D8pUEuce.js +103 -0
  71. package/dist/describe-B_gVZEVi.js +94 -0
  72. package/dist/describe-PdoqESvg.d.ts +36 -0
  73. package/dist/diff-B8Tunc3o.js +451 -0
  74. package/dist/diff-CzqLxZ77.js +48 -0
  75. package/dist/digest-B3kc_PgQ.d.ts +19 -0
  76. package/dist/digest-BI-6aa6d.js +27 -0
  77. package/dist/doctor-WpvG6p4k.js +1194 -0
  78. package/dist/doctor-collect-ByfYlNv1.js +664 -0
  79. package/dist/doctor-rOr-4ZfS.js +53 -0
  80. package/dist/drizzle/index.d.ts +73 -0
  81. package/dist/drizzle/index.js +160 -0
  82. package/dist/duration-xK2jGFVc.js +25 -0
  83. package/dist/elysia/index.d.ts +49 -0
  84. package/dist/elysia/index.js +59 -0
  85. package/dist/errors-CWfoNg9N.js +47 -0
  86. package/dist/errors-Cz5zn0mW.js +123 -0
  87. package/dist/errors-DAqevpNk.d.ts +125 -0
  88. package/dist/errors-DRnGZHzF.js +30 -0
  89. package/dist/evaluation-items-CfCCejQd.js +40 -0
  90. package/dist/evaluations-tz6D9A2G.js +461 -0
  91. package/dist/eve/index.d.ts +86 -0
  92. package/dist/eve/index.js +176 -0
  93. package/dist/expiry-BoBJ8Tvc.js +7 -0
  94. package/dist/express/index.d.ts +23 -0
  95. package/dist/express/index.js +78 -0
  96. package/dist/fastify/index.d.ts +33 -0
  97. package/dist/fastify/index.js +92 -0
  98. package/dist/fields-BMl1RxoX.js +26 -0
  99. package/dist/files-DWUN9PzI.js +125 -0
  100. package/dist/fixtures-ht28Cplr.js +67 -0
  101. package/dist/freeze-CrU8nQeX.js +60 -0
  102. package/dist/from-snapshot-C3sHpZNS.js +569 -0
  103. package/dist/generate-CH7ThJ14.js +173 -0
  104. package/dist/grantee-Cv5Sogfv.js +602 -0
  105. package/dist/graph-sql-B-dsAT6j.d.ts +29 -0
  106. package/dist/headers-BZSDieNT.js +6 -0
  107. package/dist/headers-Cf-zWvsO.d.ts +6 -0
  108. package/dist/helpers-H_KARDVC.js +421 -0
  109. package/dist/hono/index.d.ts +48 -0
  110. package/dist/hono/index.js +99 -0
  111. package/dist/hosted-DJQw46hn.js +266 -0
  112. package/dist/http-BIhmLfCc.js +95 -0
  113. package/dist/http-DPuDaChb.d.ts +13 -0
  114. package/dist/http-SO7qGttf.js +44 -0
  115. package/dist/ids-DC4V4CFu.js +18 -0
  116. package/dist/index-A0YNL8jZ.d.ts +177 -0
  117. package/dist/index-CtE07CBF.d.ts +6 -0
  118. package/dist/index-D3vbkoSI.d.ts +483 -0
  119. package/dist/index-D6_cSa1z.d.ts +201 -0
  120. package/dist/index.d.ts +16 -0
  121. package/dist/index.js +26 -0
  122. package/dist/instance-options-BK_rNOSC.d.ts +11 -0
  123. package/dist/instance-options-Dhhcnm3y.js +22 -0
  124. package/dist/json-schema-BsAflUGW.js +106 -0
  125. package/dist/jwt/index.d.ts +91 -0
  126. package/dist/jwt/index.js +590 -0
  127. package/dist/kernel-GSQnMz3O.js +208 -0
  128. package/dist/kysely/index.d.ts +78 -0
  129. package/dist/kysely/index.js +129 -0
  130. package/dist/live-options-H2eG8dfJ.js +60 -0
  131. package/dist/load-DhWEB9P1.js +75 -0
  132. package/dist/load-DwJUafYN.js +2 -0
  133. package/dist/load-jose-BL6LH4bL.js +11 -0
  134. package/dist/lru-8q4WZjBV.js +28 -0
  135. package/dist/manifest-iaoBXHKc.js +783 -0
  136. package/dist/manifest-uDS9y5de.d.ts +206 -0
  137. package/dist/map-AcxK9o_D.js +147 -0
  138. package/dist/map-claims-Z4QZOiFF.js +369 -0
  139. package/dist/map-error-pgUWNNtG.js +23 -0
  140. package/dist/markers-B0hYLvMD.js +60 -0
  141. package/dist/may-use-DndQ5tQ-.js +77 -0
  142. package/dist/mcp/index.d.ts +159 -0
  143. package/dist/mcp/index.js +603 -0
  144. package/dist/nest/index.d.ts +75 -0
  145. package/dist/nest/index.js +261 -0
  146. package/dist/next/client.d.ts +23 -0
  147. package/dist/next/client.js +33 -0
  148. package/dist/next/index.d.ts +93 -0
  149. package/dist/next/index.js +180 -0
  150. package/dist/next/plugin.d.ts +14 -0
  151. package/dist/next/plugin.js +33 -0
  152. package/dist/node/index.d.ts +24 -0
  153. package/dist/node/index.js +34 -0
  154. package/dist/openai/index.d.ts +62 -0
  155. package/dist/openai/index.js +92 -0
  156. package/dist/openapi/index.d.ts +176 -0
  157. package/dist/openapi/index.js +3 -0
  158. package/dist/openapi-Bbg4wGVL.js +164 -0
  159. package/dist/openapi-BqRBvAng.js +538 -0
  160. package/dist/openapi-CqqEbHsL.js +250 -0
  161. package/dist/openapi-import-cmwetbzw.js +5959 -0
  162. package/dist/openapi-schema--ARjyfQr.js +6902 -0
  163. package/dist/orpc/index.d.ts +51 -0
  164. package/dist/orpc/index.js +145 -0
  165. package/dist/otel/index.d.ts +13 -0
  166. package/dist/otel/index.js +202 -0
  167. package/dist/package-root-zGkxO3oN.js +30 -0
  168. package/dist/parse-BuyjxhZV.js +53 -0
  169. package/dist/parse-local-manifest-BkGQNzAh.d.ts +10 -0
  170. package/dist/parse-local-manifest-BrMozJCo.js +36 -0
  171. package/dist/pdp/index.d.ts +22 -0
  172. package/dist/pdp/index.js +682 -0
  173. package/dist/peer-BOr_kJE1.js +31 -0
  174. package/dist/permdock-CzqXjCpU.js +3471 -0
  175. package/dist/permissions-CDgvKG5L.d.ts +52 -0
  176. package/dist/permissions-CpZrivYv.js +142 -0
  177. package/dist/permissions-DVoF6dMt.js +662 -0
  178. package/dist/permissions-DttnqqxC.d.ts +214 -0
  179. package/dist/pins-8ILTftC9.js +12 -0
  180. package/dist/policy-CFZAr_Al.d.ts +2252 -0
  181. package/dist/policy-D8UFyERw.d.ts +20 -0
  182. package/dist/policy-xyWg7QdR.js +1122 -0
  183. package/dist/powersync-A8x_Yyvh.js +2 -0
  184. package/dist/powersync-C7kLglqX.js +540 -0
  185. package/dist/powersync-yW1UUFzp.js +62 -0
  186. package/dist/prisma/index.d.ts +136 -0
  187. package/dist/prisma/index.js +455 -0
  188. package/dist/problem-B43ztKIm.js +191 -0
  189. package/dist/problem-details-CkL50EEf.d.ts +7 -0
  190. package/dist/problem-details-_AMOYz-w.js +144 -0
  191. package/dist/prompt-CXYhLfsS.js +32 -0
  192. package/dist/protected-CNsMzrVd.d.ts +27 -0
  193. package/dist/protected-Cs6kTaHo.js +100 -0
  194. package/dist/protected-bZs6rbT1.d.ts +40 -0
  195. package/dist/provider-Cjr62YMV.d.ts +6 -0
  196. package/dist/provider-DLzpb2Xz.js +52 -0
  197. package/dist/provider-store-DNyC1y48.js +43 -0
  198. package/dist/react/index.d.ts +8 -0
  199. package/dist/react/index.js +7 -0
  200. package/dist/react/provider-client.d.ts +2 -0
  201. package/dist/react/provider-client.js +3 -0
  202. package/dist/react-native/index.d.ts +198 -0
  203. package/dist/react-native/index.js +696 -0
  204. package/dist/refs-KYb4ntaz.js +91 -0
  205. package/dist/relations-cjOL01hZ.js +505 -0
  206. package/dist/replay-BsOyTrdV.js +28 -0
  207. package/dist/replay-sqBGMnNs.d.ts +5 -0
  208. package/dist/resource-ref-CaS9yVPi.js +20 -0
  209. package/dist/revocations-Bhr0aMIC.js +27 -0
  210. package/dist/revocations-Cy06JNx2.d.ts +21 -0
  211. package/dist/rls-BMNydpHk.js +2521 -0
  212. package/dist/rls-CEvs64Kj.js +238 -0
  213. package/dist/rls-fields-BMasREhR.js +3502 -0
  214. package/dist/rls-graph-pc9fuXYm.js +435 -0
  215. package/dist/rls-import-D8F7j35Q.js +943 -0
  216. package/dist/rls-migrate-7wikfrVI.js +367 -0
  217. package/dist/rls-ownership-B5Lkq62W.js +843 -0
  218. package/dist/rls-shared-aOQ4hGTO.js +493 -0
  219. package/dist/rls-verify-D8B7dOTh.js +745 -0
  220. package/dist/row-check-Dt35czLy.d.ts +40 -0
  221. package/dist/rpc-DOK54_CS.js +89 -0
  222. package/dist/run-YXCJDNYk.js +174 -0
  223. package/dist/runtime-CB8gQFvS.js +11 -0
  224. package/dist/saas-Bj_FFkjN.js +1203 -0
  225. package/dist/schema-D3MnDMxa.js +300 -0
  226. package/dist/scim/index.d.ts +2 -0
  227. package/dist/scim/index.js +2 -0
  228. package/dist/scim-BFGBBAqR.js +1445 -0
  229. package/dist/scopes-CVdPrWN-.js +239 -0
  230. package/dist/server/index.d.ts +134 -0
  231. package/dist/server/index.js +11 -0
  232. package/dist/server-DlZ28Oz5.js +268 -0
  233. package/dist/sha256-BO0swRXL.js +150 -0
  234. package/dist/shared-DRu8VFVM.js +123 -0
  235. package/dist/sink-Bd9PSyfq.js +141 -0
  236. package/dist/sink-Gs6TTVa-.d.ts +104 -0
  237. package/dist/skills-Biq5uup3.js +192 -0
  238. package/dist/skills-JaymNCdK.js +56 -0
  239. package/dist/snapshot-Enxd0n-s.js +975 -0
  240. package/dist/snapshot-cache-D6jLelln.js +44 -0
  241. package/dist/snapshot-cache-DwQH8ufx.d.ts +45 -0
  242. package/dist/solid/index.d.ts +93 -0
  243. package/dist/solid/index.js +188 -0
  244. package/dist/sources-B0UvrJ21.js +534 -0
  245. package/dist/sources-BcJgw0lt.d.ts +192 -0
  246. package/dist/sql-xdg5f4Fi.js +27 -0
  247. package/dist/src-CSbUiozF.js +568 -0
  248. package/dist/ssf/index.d.ts +4 -0
  249. package/dist/ssf/index.js +596 -0
  250. package/dist/store-DMAWwAJV.js +371 -0
  251. package/dist/store-D_pjn91-.d.ts +36 -0
  252. package/dist/store-options-yO0V6gRn.js +716 -0
  253. package/dist/stores-4_sqiOA1.js +87 -0
  254. package/dist/stores-DVR5NHLE.d.ts +52 -0
  255. package/dist/stream-DDpvynSB.js +66 -0
  256. package/dist/stream-DlvG2hs-.d.ts +12 -0
  257. package/dist/style-CTm1AXDT.js +22 -0
  258. package/dist/subject-C6dLxqHU.js +24 -0
  259. package/dist/subject-settings-BwBmCdTR.js +128 -0
  260. package/dist/supabase/index.d.ts +183 -0
  261. package/dist/supabase/index.js +5 -0
  262. package/dist/supabase/middleware.d.ts +82 -0
  263. package/dist/supabase/middleware.js +102 -0
  264. package/dist/supabase-CwafwxxF.js +83 -0
  265. package/dist/supabase-DTBaC20O.js +774 -0
  266. package/dist/supabase-config-Bs44dare.js +472 -0
  267. package/dist/supabase-hook-BuxLQLpU.js +1814 -0
  268. package/dist/supabase-hook-D5qVd_D8.js +2 -0
  269. package/dist/supautils-DYZnzRWV.js +91 -0
  270. package/dist/svelte/PermissionBoundary.svelte +37 -0
  271. package/dist/svelte/Protected.svelte +40 -0
  272. package/dist/svelte/index.d.ts +13 -0
  273. package/dist/svelte/index.js +107 -0
  274. package/dist/svelte/runtime.d.ts +7 -0
  275. package/dist/svelte/runtime.js +4 -0
  276. package/dist/svelte/source.d.ts +13 -0
  277. package/dist/svelte/source.js +11 -0
  278. package/dist/terminal/index.d.ts +163 -0
  279. package/dist/terminal/index.js +833 -0
  280. package/dist/testing/index.d.ts +745 -0
  281. package/dist/testing/index.js +3672 -0
  282. package/dist/testing/saas/index.d.ts +194 -0
  283. package/dist/testing/saas/index.js +3 -0
  284. package/dist/testing/saas/permissions.d.ts +2 -0
  285. package/dist/testing/saas/permissions.js +2 -0
  286. package/dist/text-diff-BdkkYSbi.js +15 -0
  287. package/dist/thenable-okc2xDsj.js +10 -0
  288. package/dist/timeout-D51niuQP.js +8 -0
  289. package/dist/token-CIWxJOCh.js +50 -0
  290. package/dist/trpc/index.d.ts +61 -0
  291. package/dist/trpc/index.js +122 -0
  292. package/dist/types-9AWO9EGt.d.ts +197 -0
  293. package/dist/types-BPxgszlT.d.ts +550 -0
  294. package/dist/types-BVyImy5I.d.ts +120 -0
  295. package/dist/types-Bvc4oWT6.d.ts +9 -0
  296. package/dist/types-C3s9xVJG.d.ts +48 -0
  297. package/dist/types-Dnemwd77.d.ts +183 -0
  298. package/dist/types-kxznc7cn.d.ts +52 -0
  299. package/dist/types-vKyAMtcX.d.ts +157 -0
  300. package/dist/types-vNSDF7Dq.d.ts +66 -0
  301. package/dist/types-yF5LmQVD.d.ts +306 -0
  302. package/dist/unplugin/index.d.ts +7 -0
  303. package/dist/unplugin/index.js +31 -0
  304. package/dist/usage-D07N9QJ3.js +42 -0
  305. package/dist/usage-D82l1CwK.js +2 -0
  306. package/dist/usage-DG1oeCca.js +693 -0
  307. package/dist/validation-error-CnjZ4t92.js +33 -0
  308. package/dist/validation-error-CtF23SrC.d.ts +26 -0
  309. package/dist/validity-uOp8UpYn.js +245 -0
  310. package/dist/verifier-BxBo6I44.js +466 -0
  311. package/dist/version-BvacVTZR.js +17 -0
  312. package/dist/views-Soe7bGSC.js +95 -0
  313. package/dist/vocabulary-DA8a8zif.d.ts +56 -0
  314. package/dist/vue/index.d.ts +79 -0
  315. package/dist/vue/index.js +196 -0
  316. package/dist/watch-Etoa_Mvr.js +2 -0
  317. package/dist/watch-UihESpsJ.js +128 -0
  318. package/dist/webmcp/index.d.ts +75 -0
  319. package/dist/webmcp/index.js +307 -0
  320. package/package.json +450 -5
  321. package/rulesets/permdock.yaml +29 -0
  322. package/schemas/approval-request-v1.json +175 -0
  323. package/schemas/catalog-v1.json +535 -0
  324. package/schemas/openapi/oas-3.1.json +1298 -0
  325. package/schemas/openapi/oas-3.2.json +1516 -0
  326. package/schemas/openapi/overlay-1.1.json +79 -0
  327. package/schemas/supabase-claims-v1.json +144 -0
  328. package/schemas/supabase-manifest-v1.json +361 -0
  329. package/skills/permdock/SKILL.md +66 -0
  330. package/skills/permdock-agents/SKILL.md +77 -0
  331. package/skills/permdock-agents/references/runtimes.md +213 -0
  332. package/skills/permdock-approvals/SKILL.md +80 -0
  333. package/skills/permdock-approvals/references/stores-and-resume.md +94 -0
  334. package/skills/permdock-audit/SKILL.md +67 -0
  335. package/skills/permdock-credentials/SKILL.md +55 -0
  336. package/skills/permdock-credentials/references/tokens-keys-links.md +132 -0
  337. package/skills/permdock-data/SKILL.md +57 -0
  338. package/skills/permdock-data/references/queries-and-rls.md +62 -0
  339. package/skills/permdock-data/references/relationships.md +67 -0
  340. package/skills/permdock-tenancy/SKILL.md +80 -0
  341. package/skills/permdock-tenancy/references/ownership-and-custom-roles.md +89 -0
  342. package/skills/permdock-wire/SKILL.md +116 -0
  343. package/skills/permdock-wire/references/adapters.md +492 -0
  344. package/skills/permdock-wire/references/policy-options.md +45 -0
@@ -0,0 +1,421 @@
1
+ import { t as compact } from "./compact-y6vfu2_f.js";
2
+ import { n as freezeDeep } from "./freeze-CrU8nQeX.js";
3
+ import { i as findPermission, s as getRegistry } from "./permissions-DVoF6dMt.js";
4
+ import { r as approverLeaves } from "./approvers-DT4AVyIg.js";
5
+ import { t as describe } from "./describe-B_gVZEVi.js";
6
+ import { t as parseDuration } from "./duration-xK2jGFVc.js";
7
+ import { i as relationReader, n as pendingRelations, o as resolveRelated } from "./relations-cjOL01hZ.js";
8
+ import { t as ApprovalError } from "./errors-DRnGZHzF.js";
9
+ import { f as approverRelationKey, l as APPROVAL_HEADER, n as assertApprover, s as listAllApprovals } from "./store-DMAWwAJV.js";
10
+ //#region src/approvals/relations.ts
11
+ const DEFAULT_PARENT_DEPTH = 16;
12
+ /** Every approver a request names: `by`, each stage and its escalation, and `escalation.to`, inside `anyOf` groups too. */
13
+ function requestApprovers(approvers) {
14
+ return [
15
+ ...approverLeaves(approvers.by),
16
+ ...(approvers.stages ?? []).flatMap((stage) => approverLeaves(stage.by).concat(approverLeaves(stage.escalation?.to))),
17
+ ...approverLeaves(approvers.escalation?.to)
18
+ ];
19
+ }
20
+ /** Reads until nothing is in flight: each round loads one more layer of facts. */
21
+ async function settled(read, unread, cache) {
22
+ for (;;) {
23
+ const value = read();
24
+ if (!unread(value)) return value;
25
+ const pending = pendingRelations(cache);
26
+ if (pending.length === 0) return value;
27
+ await Promise.all(pending);
28
+ }
29
+ }
30
+ /** The id of `item.resource` the walk starts from, after following `through` links. */
31
+ async function startOf(item, resource, id, reader, cache, registry) {
32
+ if (!Array.isArray(item.through)) return resource === item.resource ? id : void 0;
33
+ let current = resource;
34
+ let at = id;
35
+ for (const link of item.through) {
36
+ const node = registry.get(current);
37
+ const target = node !== void 0 && Object.hasOwn(node.links, link) ? node.links[link] : void 0;
38
+ if (target === void 0) return;
39
+ const query = {
40
+ resource: current,
41
+ id: at,
42
+ depth: 1,
43
+ through: link
44
+ };
45
+ const chain = await settled(() => reader.chain(query), (value) => value === "pending", cache);
46
+ const next = chain === "pending" || chain === "failed" ? void 0 : chain.ancestors[0]?.id;
47
+ if (next === void 0) return;
48
+ current = target.resource;
49
+ at = next;
50
+ }
51
+ return current === item.resource ? at : void 0;
52
+ }
53
+ function depthOf(item) {
54
+ if (item.through === "parent") return item.depth ?? DEFAULT_PARENT_DEPTH;
55
+ return item.depth ?? 0;
56
+ }
57
+ /**
58
+ * The relation approvers of `request` that `subject` holds on its resource,
59
+ * keyed by `approverRelationKey`, for `ApprovalVerdict.relations`. Reads go
60
+ * through `relations` by the request's resource id; a request without an id,
61
+ * a missing source or a read that fails holds nothing.
62
+ */
63
+ async function approverRelations(request, subject, options) {
64
+ const approvers = request.approvers;
65
+ const id = request.resource.id;
66
+ if (approvers === void 0 || id === void 0 || options.relations === void 0 || options.permissions === void 0 || subject.principal === null) return [];
67
+ const items = /* @__PURE__ */ new Map();
68
+ for (const item of requestApprovers(approvers)) if (item.kind === "relation") items.set(approverRelationKey(item), item);
69
+ if (items.size === 0) return [];
70
+ const registry = getRegistry(options.permissions);
71
+ const cache = /* @__PURE__ */ new Map();
72
+ const reader = relationReader(options.relations, cache, registry);
73
+ const now = (options.now ?? /* @__PURE__ */ new Date()).getTime() / 1e3;
74
+ const holds = async (item) => {
75
+ const start = await startOf(item, request.resource.type, id, reader, cache, registry);
76
+ if (start === void 0) return false;
77
+ const condition = {
78
+ op: "related",
79
+ resource: item.resource,
80
+ relation: item.relation,
81
+ field: "id",
82
+ depth: depthOf(item)
83
+ };
84
+ return await settled(() => resolveRelated(condition, { id: start }, subject, now, reader), (value) => value === "relation-unavailable", cache) === true;
85
+ };
86
+ const entries = [...items];
87
+ const verdicts = await Promise.all(entries.map(([, item]) => holds(item)));
88
+ return entries.flatMap(([key], index) => verdicts[index] === true ? [key] : []);
89
+ }
90
+ //#endregion
91
+ //#region src/approvals/permissions.ts
92
+ /**
93
+ * The `holder(permission)` approvers of `request` that `approver` holds, for
94
+ * `ApprovalVerdict.permissions`: each permission key the approver's own
95
+ * instance grants without a row. `approver` must be an instance for the
96
+ * approving principal in the request's tenant; for any other tenant, or an
97
+ * anonymous instance, it holds nothing. A check that throws holds nothing.
98
+ */
99
+ function approverPermissions(request, approver) {
100
+ const approvers = request.approvers;
101
+ const principal = approver.subject.principal;
102
+ const tenant = request.subject.principal?.tenant;
103
+ if (approvers === void 0 || principal === null || tenant !== void 0 && principal.tenant !== tenant) return [];
104
+ const keys = /* @__PURE__ */ new Set();
105
+ for (const item of requestApprovers(approvers)) if (item.kind === "permission") keys.add(item.permission);
106
+ return [...keys].filter((key) => {
107
+ const leaf = findPermission(approver.permissions, key);
108
+ if (leaf === void 0) return false;
109
+ try {
110
+ const decide = approver.decide;
111
+ return decide(leaf).outcome === "granted";
112
+ } catch {
113
+ return false;
114
+ }
115
+ });
116
+ }
117
+ /** The permission approvers `subject` holds on `request`, read through `permdockFor`. */
118
+ async function heldPermissions(request, subject, permdockFor) {
119
+ if (permdockFor === void 0 || request.approvers === void 0) return [];
120
+ try {
121
+ return approverPermissions(request, await permdockFor(subject, request));
122
+ } catch {
123
+ return [];
124
+ }
125
+ }
126
+ //#endregion
127
+ //#region src/approvals/helpers.ts
128
+ function permissionMeta(permission) {
129
+ return {
130
+ key: permission.key,
131
+ scope: permission.scope,
132
+ resource: permission.resource
133
+ };
134
+ }
135
+ function summariseSubject(subject) {
136
+ const principal = subject.principal;
137
+ return compact({
138
+ principal: principal === null ? null : compact({
139
+ id: principal.id,
140
+ roles: principal.roles ?? [],
141
+ tenant: principal.tenant
142
+ }),
143
+ actor: subject.actor === void 0 ? void 0 : {
144
+ id: subject.actor.id,
145
+ kind: subject.actor.kind
146
+ },
147
+ session: subject.session,
148
+ delegation: subject.delegation === void 0 ? void 0 : compact({
149
+ scopes: subject.delegation.scopes,
150
+ authorizationDetails: subject.delegation.authorizationDetails
151
+ })
152
+ });
153
+ }
154
+ /**
155
+ * The window (`meta.ttl`, else the store's `ttl`, else the default) capped by the grant's
156
+ * `approval.ttl`: a grant shortens how long a request stays open, never
157
+ * extends it.
158
+ */
159
+ function approvalTtl(storeTtl, approval) {
160
+ if (storeTtl !== void 0 && (!Number.isSafeInteger(storeTtl) || storeTtl <= 0)) throw new RangeError(`PermDock: approval ttl must be a positive whole number of milliseconds, got ${String(storeTtl)}`);
161
+ const base = storeTtl ?? 36e5;
162
+ const grant = approval === void 0 || approval === "human" ? void 0 : parseDuration(approval.ttl);
163
+ return grant === void 0 ? base : Math.min(base, grant * 1e3);
164
+ }
165
+ async function requestApproval(store, decision, meta) {
166
+ const now = meta.now ?? /* @__PURE__ */ new Date();
167
+ const leaf = permissionMeta(meta.permission);
168
+ const approval = decision.grant.approval;
169
+ const approvers = approval === void 0 || approval === "human" ? void 0 : compact({
170
+ by: approval.by,
171
+ mode: approval.mode,
172
+ stages: approval.stages,
173
+ distinct: approval.distinct,
174
+ staleOn: approval.staleOn,
175
+ quorum: approval.quorum,
176
+ escalation: approval.escalation
177
+ });
178
+ const ttl = approvalTtl(meta.ttl ?? store.ttl, approval);
179
+ const request = freezeDeep(compact({
180
+ v: 1,
181
+ token: decision.token,
182
+ permission: leaf.key,
183
+ scope: leaf.scope,
184
+ resource: meta.resource ?? { type: leaf.resource },
185
+ subject: summariseSubject(meta.subject),
186
+ membership: meta.membership,
187
+ approvers,
188
+ detail: meta.detail ?? describe(decision).detail,
189
+ adapter: meta.adapter,
190
+ createdAt: now.toISOString(),
191
+ expiresAt: new Date(now.getTime() + ttl).toISOString(),
192
+ status: "pending"
193
+ }));
194
+ await store.create(request);
195
+ return request;
196
+ }
197
+ /**
198
+ * Checks `verdict.by` and resolves the request. Relation approvers are read
199
+ * through `options.relations` unless `verdict.relations` is already set.
200
+ */
201
+ async function resolveApproval(store, token, verdict, options = {}) {
202
+ const current = await store.get(token);
203
+ if (current === null) throw new ApprovalError("approval-not-found", "approval was not found");
204
+ const relations = verdict.relations ?? await approverRelations(current, verdict.by, options);
205
+ const permissions = verdict.permissions ?? await heldPermissions(current, verdict.by, options.permdockFor);
206
+ assertApprover(current, verdict.by, options.requireDistinctApprover === true, options.now, relations, permissions);
207
+ return store.resolve(token, {
208
+ ...verdict,
209
+ relations,
210
+ permissions
211
+ });
212
+ }
213
+ async function vouchApproval(store, token, verdict) {
214
+ if (typeof verdict.rule !== "string" || verdict.rule === "") throw new TypeError("PermDock: vouchApproval needs the name of the rule that decided the verdict");
215
+ return await store.resolve(token, compact({
216
+ status: verdict.status,
217
+ by: verdict.by,
218
+ note: verdict.note,
219
+ vouched: verdict.rule
220
+ }));
221
+ }
222
+ async function inspectApproval(store, token, now = /* @__PURE__ */ new Date()) {
223
+ await store.expire(now);
224
+ const request = await store.get(token);
225
+ if (request === null) return {
226
+ ok: false,
227
+ detail: "approval-not-found"
228
+ };
229
+ if (request.status === "pending") return {
230
+ ok: false,
231
+ detail: "approval-pending"
232
+ };
233
+ if (request.status === "rejected") return {
234
+ ok: false,
235
+ detail: "approval-rejected"
236
+ };
237
+ if (request.consumedAt !== void 0) return {
238
+ ok: false,
239
+ detail: "approval-consumed"
240
+ };
241
+ if (request.status === "expired" || Date.parse(request.expiresAt) <= now.getTime()) return {
242
+ ok: false,
243
+ detail: "approval-expired"
244
+ };
245
+ return {
246
+ ok: true,
247
+ request
248
+ };
249
+ }
250
+ /** Inspects `token` and, when it is approved, consumes it so it resumes once. */
251
+ async function consumeApproval(store, token, now = /* @__PURE__ */ new Date()) {
252
+ const inspected = await inspectApproval(store, token, now);
253
+ if (!inspected.ok) return inspected;
254
+ if (typeof store.consume !== "function") return {
255
+ ok: false,
256
+ detail: "approval-not-found"
257
+ };
258
+ const consumed = await store.consume(token, now);
259
+ if (consumed === null) return {
260
+ ok: false,
261
+ detail: "approval-consumed"
262
+ };
263
+ return {
264
+ ok: true,
265
+ request: consumed
266
+ };
267
+ }
268
+ function approvalDenied(detail) {
269
+ return {
270
+ outcome: "denied",
271
+ denials: [{
272
+ role: null,
273
+ reason: "approval",
274
+ detail
275
+ }],
276
+ alternatives: []
277
+ };
278
+ }
279
+ function staleOnChange(decision) {
280
+ const approval = decision.grant.approval;
281
+ return approval !== void 0 && approval !== "human" && approval.staleOn === "resource-change";
282
+ }
283
+ /**
284
+ * True when `token` names a pending or approved request for this permission,
285
+ * resource and principal: the same request, issued while the row had another
286
+ * `version`.
287
+ */
288
+ async function isStaleToken(store, token, input) {
289
+ const principal = input.subject.principal;
290
+ if (principal === null) return false;
291
+ let request;
292
+ try {
293
+ request = await store.get(token);
294
+ } catch {
295
+ return false;
296
+ }
297
+ return request !== null && (request.status === "approved" || request.status === "pending") && request.permission === input.permission.key && request.resource.type === input.resource.type && request.resource.id === input.resource.id && request.subject.principal?.id === principal.id;
298
+ }
299
+ /**
300
+ * Applies a resume token to a decision. The token only matters when the
301
+ * decision is `approval-required` and the token is the one this call was
302
+ * issued; otherwise a new approval is requested. A matching token is consumed
303
+ * unless `consume` is `false`, so an approval resumes exactly one call. Under
304
+ * `staleOn: 'resource-change'`, a token issued for an earlier version of the
305
+ * same row denies with `stale-approval`; the next call without it asks again.
306
+ */
307
+ async function resumeDecision(input) {
308
+ const { decision, store, token } = input;
309
+ if (decision.outcome !== "approval-required") return decision;
310
+ if (token === void 0 || token !== decision.token) {
311
+ if (store !== void 0 && token !== void 0 && staleOnChange(decision) && await isStaleToken(store, token, input)) return {
312
+ outcome: "denied",
313
+ denials: [{
314
+ role: null,
315
+ reason: "stale-approval"
316
+ }],
317
+ alternatives: []
318
+ };
319
+ if (store !== void 0) await requestApproval(store, decision, compact({
320
+ permission: input.permission,
321
+ resource: input.resource,
322
+ subject: input.subject,
323
+ adapter: input.adapter,
324
+ ttl: input.ttl
325
+ }));
326
+ return decision;
327
+ }
328
+ if (store === void 0) return approvalDenied("approval-not-found");
329
+ let inspected;
330
+ try {
331
+ inspected = await inspectApproval(store, token, input.now);
332
+ if (inspected.ok) {
333
+ const { request } = inspected;
334
+ if (request.permission !== input.permission.key || request.resource.id !== void 0 && request.resource.id !== input.resource.id) return approvalDenied("approval-mismatch");
335
+ if (input.consume !== false) inspected = await consumeApproval(store, token, input.now);
336
+ }
337
+ } catch {
338
+ return approvalDenied("approval-not-found");
339
+ }
340
+ if (!inspected.ok) return approvalDenied(inspected.detail);
341
+ const principal = input.subject.principal;
342
+ if (principal === null) return approvalDenied("approval-mismatch");
343
+ return {
344
+ outcome: "granted",
345
+ subject: {
346
+ ...input.subject,
347
+ principal
348
+ },
349
+ matched: decision.grant,
350
+ token: decision.token
351
+ };
352
+ }
353
+ const SYSTEM_KIND = "system";
354
+ async function cancelApprovals(store, filter, meta) {
355
+ if (store.cancel !== void 0) return store.cancel(filter, meta);
356
+ const pending = await listAllApprovals(store, {
357
+ ...filter,
358
+ status: "pending"
359
+ });
360
+ const by = {
361
+ principal: {
362
+ id: `system:${meta.by}`,
363
+ kind: "service",
364
+ roles: []
365
+ },
366
+ actor: {
367
+ id: `system:${meta.by}`,
368
+ kind: SYSTEM_KIND
369
+ },
370
+ context: {}
371
+ };
372
+ return (await Promise.all(pending.map(async (request) => {
373
+ try {
374
+ await store.resolve(request.token, compact({
375
+ status: "rejected",
376
+ by,
377
+ note: meta.note
378
+ }));
379
+ return true;
380
+ } catch {
381
+ return false;
382
+ }
383
+ }))).filter(Boolean).length;
384
+ }
385
+ function readApprovalHeader(headers) {
386
+ const value = headers.get(APPROVAL_HEADER);
387
+ if (value === null || value.trim() === "") return;
388
+ return value.trim();
389
+ }
390
+ function resumeFromHeader(store, headers, now) {
391
+ const token = readApprovalHeader(headers);
392
+ if (token === void 0) return Promise.resolve({
393
+ ok: false,
394
+ detail: "approval-not-found"
395
+ });
396
+ return inspectApproval(store, token, now);
397
+ }
398
+ /**
399
+ * The token to resume `decision` with when the caller carries none: the
400
+ * decision's own token when the store holds an approved or rejected request
401
+ * for it, so `resumeDecision` resumes (or denies) the call without the
402
+ * caller passing the token back. The token already binds permission,
403
+ * resource (or the call's data when there is no row id), subject and actor.
404
+ * A pending request counts only with `denyPending: true`, which makes the
405
+ * call deny with `approval-pending` instead of asking again. `undefined` when
406
+ * the decision needs no approval, there is no store, or the store has no
407
+ * unexpired request for the token; a store that throws counts as none.
408
+ */
409
+ async function storedApprovalToken(store, decision, options = {}) {
410
+ if (store === void 0 || decision.outcome !== "approval-required") return;
411
+ const now = (options.now ?? /* @__PURE__ */ new Date()).getTime();
412
+ try {
413
+ const record = await store.get(decision.token);
414
+ if (record === null || record.status === "pending" && options.denyPending !== true || record.status === "expired" || Date.parse(record.expiresAt) <= now) return;
415
+ return decision.token;
416
+ } catch {
417
+ return;
418
+ }
419
+ }
420
+ //#endregion
421
+ export { requestApproval as a, resumeFromHeader as c, vouchApproval as d, approverPermissions as f, readApprovalHeader as i, storedApprovalToken as l, approverRelations as m, consumeApproval as n, resolveApproval as o, heldPermissions as p, inspectApproval as r, resumeDecision as s, cancelApprovals as t, summariseSubject as u };
@@ -0,0 +1,48 @@
1
+ import { C as Policy, D as PolicyVocabulary, Nr as Principal, ln as PermDock } from "../policy-CFZAr_Al.js";
2
+ import { f as Permission } from "../permissions-DttnqqxC.js";
3
+ import { n as RevocationFeed } from "../revocations-Cy06JNx2.js";
4
+ import { A as ConnectionOptions, O as Connection, h as InvalidSignatureError, i as ProtectOptions, n as OpenApiHooks, w as verifyWebBotAuth, x as discoverViaSignatureAgent } from "../create-BWyx3jua.js";
5
+ import { t as ServerAdapterOptions } from "../bind-CVy3Espv.js";
6
+ import { Context, Hono, MiddlewareHandler } from "hono";
7
+ import { SSEMessage, SSEStreamingApi } from "hono/streaming";
8
+ import { WSEvents } from "hono/ws";
9
+ //#region src/hono/create.d.ts
10
+ type HonoPermDockOptions<TUser = unknown> = ServerAdapterOptions<Context, TUser> & {
11
+ /** Ends or revalidates open sockets and streams. */
12
+ readonly revocations?: RevocationFeed;
13
+ };
14
+ /** The `Variables` both middlewares set; Hono merges them into the route's Env. */
15
+ type PermDockEnv<TData = unknown, V extends PolicyVocabulary = PolicyVocabulary> = {
16
+ readonly Variables: {
17
+ readonly permdock: PermDock<V>;
18
+ readonly permdockData: TData;
19
+ };
20
+ };
21
+ type HonoPermDock<V extends PolicyVocabulary = PolicyVocabulary> = {
22
+ readonly permdock: () => MiddlewareHandler<PermDockEnv<unknown, V>>;
23
+ readonly protect: <TData = unknown>(permission: Permission | null, loadData?: (c: Context) => TData | Promise<TData>, protectOptions?: ProtectOptions) => MiddlewareHandler<PermDockEnv<NonNullable<TData>, V>>;
24
+ /** A long-lived connection for the request behind `c`. */
25
+ readonly connection: (c: Context, connectionOptions?: ConnectionOptions) => Promise<Connection>;
26
+ /** `upgradeWebSocket` events that close with `1008` when the connection aborts. */
27
+ readonly socket: <T = unknown>(connection: Connection, events: WSEvents<T>) => WSEvents<T>;
28
+ /**
29
+ * Writes `source` to a `streamSSE` stream, dropping items the subscriber
30
+ * cannot read, and resolves when it ends: after an `event: permdock` frame
31
+ * when the connection aborts, when the client disconnects, or when the
32
+ * source is done. Await it as the last statement of the callback.
33
+ */
34
+ readonly sse: <T>(connection: Connection, stream: SSEStreamingApi, source: AsyncIterable<T>, options?: SseOptions<T>) => Promise<void>;
35
+ readonly permdockHandler: () => Hono;
36
+ readonly openapi: OpenApiHooks;
37
+ };
38
+ type SseOptions<T> = {
39
+ /** Items the subscriber cannot read under this permission are dropped. */
40
+ readonly items?: Permission<string, unknown, "instance">;
41
+ /** The row to check for an item, when the item wraps it. */
42
+ readonly unwrap?: (item: T) => unknown;
43
+ /** The frame for an item; defaults to `{ data: JSON.stringify(item) }`. */
44
+ readonly format?: (item: T) => SSEMessage;
45
+ };
46
+ export declare function createPermDock<TUser, TPrincipal extends Principal = Principal, V extends PolicyVocabulary = PolicyVocabulary>(policy: Policy<TUser, TPrincipal, V>, options: HonoPermDockOptions<TUser>): HonoPermDock<V>;
47
+ //#endregion
48
+ export { type HonoPermDock, type HonoPermDockOptions, InvalidSignatureError, type PermDockEnv, type SseOptions, discoverViaSignatureAgent, verifyWebBotAuth };
@@ -0,0 +1,99 @@
1
+ import { t as compact } from "../compact-y6vfu2_f.js";
2
+ import { r as PermDockRevokedError } from "../errors-Cz5zn0mW.js";
3
+ import { i as discoverViaSignatureAgent, r as InvalidSignatureError, s as verifyWebBotAuth } from "../evaluations-tz6D9A2G.js";
4
+ import { t as problemFromError } from "../map-error-pgUWNNtG.js";
5
+ import { r as bindKernel } from "../bind-VnYn2HKq.js";
6
+ import { i as onRevoked, n as guardIterable, t as POLICY_VIOLATION } from "../stream-DDpvynSB.js";
7
+ import { Hono } from "hono";
8
+ //#region src/hono/create.ts
9
+ function socket(connection, events) {
10
+ return {
11
+ ...events,
12
+ onOpen: (evt, ws) => {
13
+ onRevoked(connection, (problem) => {
14
+ ws.close(POLICY_VIOLATION, problem.type);
15
+ });
16
+ if (!connection.signal.aborted) events.onOpen?.(evt, ws);
17
+ },
18
+ onClose: (evt, ws) => {
19
+ connection.close();
20
+ events.onClose?.(evt, ws);
21
+ }
22
+ };
23
+ }
24
+ async function sse(connection, stream, source, options = {}) {
25
+ const disconnected = new Promise((resolve) => {
26
+ stream.onAbort(() => {
27
+ connection.close();
28
+ resolve({
29
+ done: true,
30
+ value: void 0
31
+ });
32
+ });
33
+ });
34
+ const iterator = guardIterable(source, connection, compact({
35
+ items: options.items,
36
+ unwrap: options.unwrap,
37
+ onRevoked: (error) => error
38
+ }))[Symbol.asyncIterator]();
39
+ try {
40
+ for (;;) {
41
+ const next = await Promise.race([iterator.next(), disconnected]);
42
+ if (next.done === true || stream.aborted) return;
43
+ const item = next.value;
44
+ await stream.writeSSE(options.format?.(item) ?? { data: JSON.stringify(item) });
45
+ }
46
+ } catch (error) {
47
+ if (!(error instanceof PermDockRevokedError)) throw error;
48
+ if (!stream.aborted) await stream.writeSSE({
49
+ event: "permdock",
50
+ data: JSON.stringify(error.toProblemDetails())
51
+ });
52
+ } finally {
53
+ Promise.resolve(iterator.return(void 0)).catch(() => void 0);
54
+ }
55
+ }
56
+ function mapDownstream(c) {
57
+ const mapped = c.error === void 0 ? void 0 : problemFromError(c.error, { credentials: c.req.header("authorization") !== void 0 });
58
+ if (mapped !== void 0) {
59
+ c.res = void 0;
60
+ c.res = mapped;
61
+ }
62
+ }
63
+ function createPermDock(policy, options) {
64
+ const { kernel, bind, scopeOf, handlerScope, attach } = bindKernel(policy, options, "hono", (c) => c.req.raw);
65
+ const permdock = () => async (c, next) => {
66
+ const attached = await attach(c);
67
+ if (!attached.ok) return attached.response;
68
+ c.set("permdock", attached.permdock);
69
+ await next();
70
+ mapDownstream(c);
71
+ };
72
+ const protect = (permission, loadData, protectOptions) => async (c, next) => {
73
+ const guard = await kernel.protect(permission, loadData === void 0 ? void 0 : () => loadData(c), protectOptions)(bind(c), await scopeOf(c));
74
+ if (!guard.ok) return guard.response;
75
+ c.set("permdock", guard.permdock);
76
+ c.set("permdockData", guard.data);
77
+ await next();
78
+ mapDownstream(c);
79
+ };
80
+ const connection = async (c, connectionOptions) => kernel.connection(bind(c), connectionOptions, await scopeOf(c));
81
+ const permdockHandler = () => {
82
+ const { POST, GET } = kernel.permdockHandler(handlerScope);
83
+ const app = new Hono();
84
+ app.post("/", (c) => POST(bind(c)));
85
+ app.get("/", (c) => GET(bind(c)));
86
+ return app;
87
+ };
88
+ return {
89
+ permdock,
90
+ protect,
91
+ connection,
92
+ socket,
93
+ sse,
94
+ permdockHandler,
95
+ openapi: kernel.openapi
96
+ };
97
+ }
98
+ //#endregion
99
+ export { InvalidSignatureError, createPermDock, discoverViaSignatureAgent, verifyWebBotAuth };