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,53 @@
1
+ import { a as listArg, i as globalArgs, t as COMMAND_DESCRIPTIONS } from "./commands-DWOrSQic.js";
2
+ import { n as ask, t as CANCELLED } from "./prompt-CXYhLfsS.js";
3
+ import { defineCommand } from "citty";
4
+ //#region src/cli/commands/doctor.ts
5
+ function doctor(ctx) {
6
+ return defineCommand({
7
+ meta: {
8
+ name: "doctor",
9
+ description: COMMAND_DESCRIPTIONS.doctor
10
+ },
11
+ args: {
12
+ ...globalArgs,
13
+ only: {
14
+ type: "string",
15
+ description: "Check codes or groups to run, repeatable",
16
+ valueHint: "codes"
17
+ },
18
+ fix: {
19
+ type: "boolean",
20
+ description: "Apply safe fixes: install skills, regenerate the catalog"
21
+ },
22
+ strict: {
23
+ type: "boolean",
24
+ description: "Exit 1 on warnings too"
25
+ }
26
+ },
27
+ async run({ args: parsed, rawArgs }) {
28
+ let fix = parsed.fix === true;
29
+ if (fix && ctx.interactive) {
30
+ const answer = await ask(`Install the Agent Skills and regenerate the catalog in ${ctx.cwd}?`);
31
+ if (answer === void 0) {
32
+ ctx.report(CANCELLED);
33
+ return;
34
+ }
35
+ fix = answer;
36
+ }
37
+ const result = await (await import("./doctor-WpvG6p4k.js")).runDoctor({
38
+ cwd: ctx.cwd,
39
+ config: ctx.config,
40
+ only: listArg(rawArgs, "only"),
41
+ json: ctx.json,
42
+ fix,
43
+ strict: parsed.strict === true,
44
+ color: ctx.color,
45
+ now: ctx.now,
46
+ io: ctx.io
47
+ });
48
+ ctx.report(result);
49
+ }
50
+ });
51
+ }
52
+ //#endregion
53
+ export { doctor };
@@ -0,0 +1,73 @@
1
+ import { Ir as Condition, Pr as Subject, mn as WhereResult } from "../policy-CFZAr_Al.js";
2
+ import { r as RelationsMapping } from "../graph-sql-B-dsAT6j.js";
3
+ import { s as MembershipsMapping } from "../compile-CNnl6uIt.js";
4
+ import { n as WithSubjectOptions, t as RowCheck } from "../row-check-Dt35czLy.js";
5
+ import { SQL, Table } from "drizzle-orm";
6
+ //#region src/drizzle/types.d.ts
7
+ /** A column of the Drizzle table `T` or an `SQL` expression; anything for a structural stand-in. */
8
+ type DrizzleColumnOf<T> = T extends Table ? T["_"]["columns"][keyof T["_"]["columns"]] | SQL : unknown;
9
+ type DrizzleWhereOptions<T = unknown> = {
10
+ /** Condition field to column of the table passed to `toWhere`. */
11
+ readonly columns?: Readonly<Record<string, DrizzleColumnOf<T>>>;
12
+ readonly subject?: Subject;
13
+ readonly memberships?: MembershipsMapping;
14
+ /** Where the relation graph lives; graph grants compile to Postgres subqueries with it and are refused without. */
15
+ readonly relations?: RelationsMapping;
16
+ readonly now?: number;
17
+ readonly operators?: DrizzleOperators;
18
+ };
19
+ type DrizzleOperators = {
20
+ readonly and: (...args: unknown[]) => unknown;
21
+ readonly or: (...args: unknown[]) => unknown;
22
+ readonly not: (value: unknown) => unknown;
23
+ readonly eq: (column: unknown, value: unknown) => unknown;
24
+ readonly ne: (column: unknown, value: unknown) => unknown;
25
+ readonly gt: (column: unknown, value: unknown) => unknown;
26
+ readonly gte: (column: unknown, value: unknown) => unknown;
27
+ readonly lt: (column: unknown, value: unknown) => unknown;
28
+ readonly lte: (column: unknown, value: unknown) => unknown;
29
+ readonly inArray: (column: unknown, values: readonly unknown[]) => unknown;
30
+ readonly notInArray: (column: unknown, values: readonly unknown[]) => unknown;
31
+ readonly isNull: (column: unknown) => unknown;
32
+ readonly isNotNull: (column: unknown) => unknown;
33
+ readonly like: (column: unknown, value: unknown) => unknown;
34
+ readonly sql: (strings: TemplateStringsArray, ...values: unknown[]) => unknown;
35
+ };
36
+ type DrizzleWithSubjectOptions = WithSubjectOptions & {
37
+ /** `import * as operators from 'drizzle-orm'`, on runtimes without `require`. */
38
+ readonly operators?: DrizzleOperators;
39
+ };
40
+ //#endregion
41
+ //#region src/drizzle/to-where.d.ts
42
+ /** Compiles a condition into a Drizzle `SQL` filter over `table`; no grant compiles to `false`. */
43
+ export declare function toWhere<T extends object>(input: Condition | WhereResult, table: T, options?: DrizzleWhereOptions<T>): SQL;
44
+ type DrizzleDatabase<Tx> = {
45
+ transaction<T>(fn: (tx: Tx) => Promise<T>): Promise<T>;
46
+ };
47
+ /**
48
+ * Runs `fn` in a transaction whose role and claims are `permdock.subject`'s, so the generated
49
+ * RLS policies decide for the same subject as the in-process checks.
50
+ */
51
+ export declare function withSubject<Tx extends {
52
+ execute(query: never): unknown;
53
+ }, T>(db: DrizzleDatabase<Tx>, permdock: {
54
+ readonly subject: Subject;
55
+ }, fn: (tx: Tx) => Promise<T>, options?: DrizzleWithSubjectOptions): Promise<T>;
56
+ type DrizzleSelectable = {
57
+ select(fields: Record<string, unknown>): {
58
+ from(table: never): {
59
+ where(where: unknown): {
60
+ limit(count: number): PromiseLike<readonly {
61
+ readonly granted?: unknown;
62
+ }[]>;
63
+ };
64
+ };
65
+ };
66
+ };
67
+ /**
68
+ * One query for one row: `{ found: false }` when `key` matches nothing, otherwise whether the
69
+ * permission filter keeps the row. Throws when `key` matches more than one row.
70
+ */
71
+ export declare function checkRow<T extends object>(db: DrizzleSelectable, table: T, input: Condition | WhereResult, key: SQL, options?: DrizzleWhereOptions<T>): Promise<RowCheck>;
72
+ //#endregion
73
+ export type { DrizzleOperators, DrizzleWhereOptions, DrizzleWithSubjectOptions, MembershipsMapping, RelationsMapping, RowCheck, WithSubjectOptions };
@@ -0,0 +1,160 @@
1
+ import { t as compact } from "../compact-y6vfu2_f.js";
2
+ import { w as assertSafeKey } from "../permissions-DVoF6dMt.js";
3
+ import { n as escapeLike, t as compileWhere } from "../compile-Ba4blROR.js";
4
+ import { i as rowCheckFrom, r as subjectStatements, t as statementTemplate } from "../subject-settings-BwBmCdTR.js";
5
+ //#region src/drizzle/to-where.ts
6
+ function loadOperators(injected) {
7
+ if (injected !== void 0) return injected;
8
+ const loader = globalThis.process?.getBuiltinModule?.("node:module");
9
+ try {
10
+ if (loader === void 0) throw new Error("no module loader");
11
+ return loader.createRequire(import.meta.url)("drizzle-orm");
12
+ } catch {
13
+ throw new Error("PermDock: permdock/drizzle requires the drizzle-orm peer; pass `operators` on runtimes without require");
14
+ }
15
+ }
16
+ function ident(name) {
17
+ assertSafeKey(name, "sql identifier");
18
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/u.test(name)) throw new Error(`PermDock: unsafe SQL identifier '${name}'`);
19
+ return name;
20
+ }
21
+ function column(table, field, columns) {
22
+ assertSafeKey(field, "condition field");
23
+ const mapped = (columns !== void 0 && Object.hasOwn(columns, field) ? columns[field] : void 0) ?? (Object.hasOwn(table, field) ? table[field] : void 0);
24
+ if (mapped === void 0 || typeof mapped === "function") throw new Error(`PermDock: unknown column '${field}'`);
25
+ return mapped;
26
+ }
27
+ /** Drizzle's Postgres array columns (`text().array()`) report `dataType: 'array'`. */
28
+ function isArrayColumn(col) {
29
+ if (col === null || typeof col !== "object") return false;
30
+ const { dataType, dimensions } = col;
31
+ return dataType === "array" || typeof dimensions === "number" && dimensions > 0;
32
+ }
33
+ function tagged(parts, ops) {
34
+ const strings = [""];
35
+ const values = [];
36
+ for (const part of parts) if ("text" in part) strings[strings.length - 1] += part.text;
37
+ else {
38
+ values.push(part.value);
39
+ strings.push("");
40
+ }
41
+ const template = strings;
42
+ Object.defineProperty(template, "raw", { value: strings });
43
+ return ops.sql(template, ...values);
44
+ }
45
+ function existsSql(node, table, options, ops) {
46
+ const m = (name) => `m.${ident(name)}`;
47
+ const parts = [
48
+ { text: `exists (select 1 from ${ident(node.table)} m where ${m(node.rowColumn)} = ` },
49
+ { value: column(table, node.rowField, options.columns) },
50
+ { text: ` and ${m(node.user)} = ` },
51
+ { value: node.userValue }
52
+ ];
53
+ if (node.roles.length > 0) {
54
+ parts.push({ text: ` and ${m(node.role)} in (` });
55
+ for (const [index, role] of node.roles.entries()) {
56
+ if (index > 0) parts.push({ text: ", " });
57
+ parts.push({ value: role });
58
+ }
59
+ parts.push({ text: ")" });
60
+ }
61
+ if (node.expiresAt !== void 0) {
62
+ const expires = m(node.expiresAt);
63
+ parts.push({ text: ` and (${expires} is null or ${expires} > ` }, { value: node.now }, { text: ")" });
64
+ }
65
+ if (node.tenantColumn !== void 0 && node.tenantValue !== void 0) {
66
+ const tenant = m(node.tenantColumn);
67
+ parts.push({ text: ` and (${tenant} is null or ${tenant} = ` }, { value: node.tenantValue }, { text: ")" });
68
+ }
69
+ if (node.resourceColumn !== void 0 && node.resourceValue !== void 0) parts.push({ text: ` and ${m(node.resourceColumn)} = ` }, { value: node.resourceValue });
70
+ parts.push({ text: ")" });
71
+ return tagged(parts, ops);
72
+ }
73
+ function containsSql(col, value, ops) {
74
+ if (isArrayColumn(col)) return tagged([
75
+ { value },
76
+ { text: " = any(" },
77
+ { value: col },
78
+ { text: ")" }
79
+ ], ops);
80
+ if (typeof value === "string") return ops.like(col, `%${escapeLike(value)}%`);
81
+ return tagged([
82
+ { value: col },
83
+ { text: " @> " },
84
+ { value }
85
+ ], ops);
86
+ }
87
+ function render(node, table, options, ops) {
88
+ switch (node.kind) {
89
+ case "never": return ops.sql`false`;
90
+ case "always": return ops.sql`true`;
91
+ case "isNull": {
92
+ const col = column(table, node.field, options.columns);
93
+ return node.negated ? ops.isNotNull(col) : ops.isNull(col);
94
+ }
95
+ case "and": return ops.and(...node.items.map((item) => render(item, table, options, ops)));
96
+ case "or": return ops.or(...node.items.map((item) => render(item, table, options, ops)));
97
+ case "not": return ops.not(render(node.item, table, options, ops));
98
+ case "exists": return existsSql(node, table, options, ops);
99
+ case "sql": return tagged(node.parts.map((part) => {
100
+ if ("text" in part) return part;
101
+ if ("column" in part) return { value: column(table, part.column, options.columns) };
102
+ return { value: "subject" in part ? node.subject : part.value };
103
+ }), ops);
104
+ case "compare": {
105
+ const col = column(table, node.field, options.columns);
106
+ switch (node.op) {
107
+ case "eq": return ops.eq(col, node.value);
108
+ case "ne": return ops.ne(col, node.value);
109
+ case "gt": return ops.gt(col, node.value);
110
+ case "gte": return ops.gte(col, node.value);
111
+ case "lt": return ops.lt(col, node.value);
112
+ case "lte": return ops.lte(col, node.value);
113
+ case "in": return ops.inArray(col, node.value);
114
+ case "notIn": return ops.notInArray(col, node.value);
115
+ case "contains": return containsSql(col, node.value, ops);
116
+ /* v8 ignore next 4 */
117
+ default: {
118
+ const exhaustive = node.op;
119
+ throw new Error(`PermDock: unknown compare '${String(exhaustive)}'`);
120
+ }
121
+ }
122
+ }
123
+ /* v8 ignore next 6 */
124
+ default: throw new Error(`PermDock: unknown compiled node '${String(node)}'`);
125
+ }
126
+ }
127
+ /** Compiles a condition into a Drizzle `SQL` filter over `table`; no grant compiles to `false`. */
128
+ function toWhere(input, table, options = {}) {
129
+ return render(compileWhere(input, compact({
130
+ subject: options.subject,
131
+ memberships: options.memberships,
132
+ now: options.now,
133
+ relations: options.relations
134
+ })), table, options, loadOperators(options.operators));
135
+ }
136
+ /**
137
+ * Runs `fn` in a transaction whose role and claims are `permdock.subject`'s, so the generated
138
+ * RLS policies decide for the same subject as the in-process checks.
139
+ */
140
+ function withSubject(db, permdock, fn, options = {}) {
141
+ const statements = subjectStatements(permdock, options);
142
+ const { sql } = loadOperators(options.operators);
143
+ return db.transaction(async (tx) => {
144
+ const execute = tx.execute.bind(tx);
145
+ for (const statement of statements) await execute(sql(statementTemplate(statement), ...statement.values));
146
+ return fn(tx);
147
+ });
148
+ }
149
+ /**
150
+ * One query for one row: `{ found: false }` when `key` matches nothing, otherwise whether the
151
+ * permission filter keeps the row. Throws when `key` matches more than one row.
152
+ */
153
+ async function checkRow(db, table, input, key, options = {}) {
154
+ const { sql } = loadOperators(options.operators);
155
+ const filter = toWhere(input, table, options);
156
+ const rows = await db.select({ granted: sql`coalesce((${filter}), false)` }).from(table).where(key).limit(2);
157
+ return rowCheckFrom(rows);
158
+ }
159
+ //#endregion
160
+ export { checkRow, toWhere, withSubject };
@@ -0,0 +1,25 @@
1
+ //#region src/core/duration.ts
2
+ /**
3
+ * Parses a duration string (`'30s'`, `'15m'`, `'4h'`, `'7d'`, `'2w'`) into
4
+ * whole seconds. Fail-closed: a malformed or non-positive duration is
5
+ * `undefined`, and every caller treats that as "no bound", never a default.
6
+ */
7
+ const UNITS = {
8
+ s: 1,
9
+ m: 60,
10
+ h: 3600,
11
+ d: 86400,
12
+ w: 604800
13
+ };
14
+ function parseDuration(input) {
15
+ if (typeof input === "number") return Number.isFinite(input) && input > 0 ? Math.floor(input) : void 0;
16
+ if (typeof input !== "string") return;
17
+ const match = /^(\d+)(s|m|h|d|w)$/u.exec(input.trim());
18
+ if (match === null) return;
19
+ const amount = Number(match[1]);
20
+ const unit = UNITS[match[2] ?? ""];
21
+ if (unit === void 0 || !Number.isFinite(amount) || amount <= 0) return;
22
+ return amount * unit;
23
+ }
24
+ //#endregion
25
+ export { parseDuration as t };
@@ -0,0 +1,49 @@
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 { Elysia } from "elysia";
7
+ //#region src/elysia/create.d.ts
8
+ type ElysiaCtx = {
9
+ readonly request: Request;
10
+ readonly body?: unknown;
11
+ readonly params?: Readonly<Record<string, string | undefined>>;
12
+ };
13
+ type ElysiaPermDockOptions<TUser = unknown> = ServerAdapterOptions<ElysiaCtx, TUser> & {
14
+ /** Ends or revalidates open sockets. */
15
+ readonly revocations?: RevocationFeed;
16
+ };
17
+ /** The `ws` Elysia passes to `.ws` handlers; `data` is the upgrade context. */
18
+ type ElysiaSocket = {
19
+ readonly data: ElysiaCtx;
20
+ close(code?: number, reason?: string): unknown;
21
+ };
22
+ type ElysiaContext<V extends PolicyVocabulary = PolicyVocabulary> = ElysiaCtx & {
23
+ permdock: PermDock<V>;
24
+ permdockData?: unknown;
25
+ };
26
+ type ElysiaProtect = (permission: Permission | null, loadData?: (ctx: ElysiaCtx) => unknown, protectOptions?: ProtectOptions) => (ctx: ElysiaCtx) => Promise<Response | undefined>;
27
+ /** The `permdock()` plugin: its global derive types `permdock` in every later handler. */
28
+ type ElysiaPermDockPlugin<V extends PolicyVocabulary = PolicyVocabulary> = Elysia<"", {
29
+ decorator: Record<never, never>;
30
+ store: Record<never, never>;
31
+ derive: {
32
+ readonly permdock: PermDock<V>;
33
+ };
34
+ resolve: Record<never, never>;
35
+ }>;
36
+ type ElysiaPermDock<V extends PolicyVocabulary = PolicyVocabulary> = {
37
+ readonly permdock: () => ElysiaPermDockPlugin<V>;
38
+ readonly protect: ElysiaProtect;
39
+ /**
40
+ * One connection per socket: the same promise for every handler
41
+ * of that socket; closes it with `1008` when the connection aborts.
42
+ */
43
+ readonly connection: (ws: ElysiaSocket, connectionOptions?: ConnectionOptions) => Promise<Connection>;
44
+ readonly permdockHandler: () => Elysia;
45
+ readonly openapi: OpenApiHooks;
46
+ };
47
+ export declare function createPermDock<TUser, TPrincipal extends Principal = Principal, V extends PolicyVocabulary = PolicyVocabulary>(policy: Policy<TUser, TPrincipal, V>, options: ElysiaPermDockOptions<TUser>): ElysiaPermDock<V>;
48
+ //#endregion
49
+ export { type ElysiaContext, type ElysiaCtx, type ElysiaPermDock, type ElysiaPermDockOptions, type ElysiaProtect, type ElysiaSocket, InvalidSignatureError, discoverViaSignatureAgent, verifyWebBotAuth };
@@ -0,0 +1,59 @@
1
+ import { i as parsedBody, n as hasCredentials } from "../http-SO7qGttf.js";
2
+ import { i as discoverViaSignatureAgent, r as InvalidSignatureError, s as verifyWebBotAuth } from "../evaluations-tz6D9A2G.js";
3
+ import { t as problemFromError } from "../map-error-pgUWNNtG.js";
4
+ import { a as socketConnection, i as decorate, r as bindKernel } from "../bind-VnYn2HKq.js";
5
+ import { i as onRevoked, t as POLICY_VIOLATION } from "../stream-DDpvynSB.js";
6
+ import { Elysia } from "elysia";
7
+ //#region src/elysia/create.ts
8
+ function createPermDock(policy, options) {
9
+ const seed = globalThis.crypto.randomUUID();
10
+ const { kernel, bind, scopeOf, handlerScope } = bindKernel(policy, options, "elysia", toRequest);
11
+ const permdock = () => new Elysia({
12
+ name: "permdock",
13
+ seed
14
+ }).derive({ as: "global" }, async (ctx) => {
15
+ const instance = await kernel.permdock(bind(ctx), await scopeOf(ctx));
16
+ decorate(ctx, instance);
17
+ return { permdock: instance };
18
+ }).onError({ as: "global" }, ({ error, request }) => problemFromError(error, { credentials: hasCredentials(request) }));
19
+ const protect = (permission, loadData, protectOptions) => async (ctx) => {
20
+ const guard = await kernel.protect(permission, loadData === void 0 ? void 0 : () => loadData(ctx), protectOptions)(bind(ctx), await scopeOf(ctx));
21
+ if (!guard.ok) return guard.response;
22
+ decorate(ctx, guard.permdock, guard.data);
23
+ };
24
+ const sockets = /* @__PURE__ */ new WeakMap();
25
+ const connection = (ws, connectionOptions) => socketConnection(sockets, ws.data, async () => {
26
+ const conn = await kernel.connection(bind(ws.data), connectionOptions, await scopeOf(ws.data));
27
+ onRevoked(conn, (problem) => {
28
+ ws.close(POLICY_VIOLATION, problem.type);
29
+ });
30
+ return conn;
31
+ });
32
+ const permdockHandler = () => {
33
+ const { POST, GET } = kernel.permdockHandler(handlerScope);
34
+ return new Elysia({
35
+ name: "permdock-handler",
36
+ seed
37
+ }).post("/", (ctx) => POST(bind(ctx))).get("/", (ctx) => GET(bind(ctx)));
38
+ };
39
+ return {
40
+ permdock,
41
+ protect,
42
+ connection,
43
+ permdockHandler,
44
+ openapi: kernel.openapi
45
+ };
46
+ }
47
+ function toRequest(ctx) {
48
+ const method = ctx.request.method;
49
+ if (method === "GET" || method === "HEAD" || ctx.body === void 0) return ctx.request;
50
+ const headers = new Headers(ctx.request.headers);
51
+ const body = parsedBody(ctx.body, headers) ?? null;
52
+ return new Request(ctx.request.url, {
53
+ method,
54
+ headers,
55
+ body
56
+ });
57
+ }
58
+ //#endregion
59
+ export { InvalidSignatureError, createPermDock, discoverViaSignatureAgent, verifyWebBotAuth };
@@ -0,0 +1,47 @@
1
+ import { stripVTControlCharacters } from "node:util";
2
+ //#region src/cli/errors.ts
3
+ var CliError = class extends Error {
4
+ kind;
5
+ constructor(kind, message, options) {
6
+ super(message, options);
7
+ this.name = "CliError";
8
+ this.kind = kind;
9
+ }
10
+ };
11
+ const TITLES = {
12
+ usage: "Usage or configuration error",
13
+ unavailable: "A database or service the command needs did not answer",
14
+ failed: "The check the command ran found a problem"
15
+ };
16
+ function describeError(error) {
17
+ return error instanceof Error ? error.message : String(error);
18
+ }
19
+ /** An unclassified error is a usage error: a module that throws while loading is the project's to fix. */
20
+ function cliErrorKind(error) {
21
+ return error instanceof CliError ? error.kind : "usage";
22
+ }
23
+ function exitCodeOf(kind) {
24
+ return kind === "usage" ? 2 : 1;
25
+ }
26
+ function cliProblem(kind, message, command) {
27
+ return {
28
+ type: `https://permdock.com/problems/cli-${kind}`,
29
+ title: TITLES[kind],
30
+ detail: stripVTControlCharacters(message),
31
+ ...command === void 0 ? {} : { command },
32
+ exitCode: exitCodeOf(kind)
33
+ };
34
+ }
35
+ /**
36
+ * The result a command reports for a usage error it caught. A `CliError`
37
+ * propagates instead, so `run()` prints it, as Problem Details under `--json`.
38
+ */
39
+ function usageResult(error) {
40
+ if (error instanceof CliError) throw error;
41
+ return {
42
+ code: 2,
43
+ output: describeError(error)
44
+ };
45
+ }
46
+ //#endregion
47
+ export { exitCodeOf as a, describeError as i, cliErrorKind as n, usageResult as o, cliProblem as r, CliError as t };
@@ -0,0 +1,123 @@
1
+ import { t as compact } from "./compact-y6vfu2_f.js";
2
+ import { t as PROBLEM_BASE } from "./validation-error-CnjZ4t92.js";
3
+ import { a as wireDenials, n as problemDetails } from "./problem-details-_AMOYz-w.js";
4
+ import { n as deniedDigest, t as approvalDigest } from "./digest-BI-6aa6d.js";
5
+ //#region src/core/errors.ts
6
+ var PermDockDeniedError = class extends Error {
7
+ name = "PermDockDeniedError";
8
+ decision;
9
+ permission;
10
+ scope;
11
+ resource;
12
+ subject;
13
+ /** The resource's `disclosure` when the denied check carried a row; `'hide'` answers as `404`. */
14
+ disclosure;
15
+ /** `PERMDOCK_DENIED;<permission>`; survives the Server Component boundary (`parsePermDockDigest`). */
16
+ digest;
17
+ constructor(input) {
18
+ super(input.message);
19
+ this.decision = input.decision;
20
+ this.permission = input.permission;
21
+ this.scope = input.scope;
22
+ this.resource = input.resource;
23
+ this.subject = input.subject;
24
+ if (input.disclosure !== void 0) this.disclosure = input.disclosure;
25
+ this.digest = deniedDigest(input.permission);
26
+ }
27
+ /** The same status matrix as `protect`: `401`, `404`, `429`, `503` or `403`. */
28
+ toProblemDetails(options) {
29
+ return problemDetails(compact({
30
+ decision: this.decision,
31
+ detail: this.message,
32
+ instance: options?.instance,
33
+ permission: this.permission,
34
+ scope: this.scope,
35
+ resource: this.resource,
36
+ disclosure: options?.disclosure ?? this.disclosure
37
+ }));
38
+ }
39
+ };
40
+ var PermDockApprovalRequiredError = class extends Error {
41
+ name = "PermDockApprovalRequiredError";
42
+ decision;
43
+ permission;
44
+ scope;
45
+ resource;
46
+ token;
47
+ reason;
48
+ /** `PERMDOCK_APPROVAL_REQUIRED;<permission>;<token>`; the token is already bound to this subject. */
49
+ digest;
50
+ constructor(input) {
51
+ super(input.message);
52
+ this.decision = input.decision;
53
+ this.permission = input.permission;
54
+ this.scope = input.scope;
55
+ this.resource = input.resource;
56
+ this.token = input.decision.token;
57
+ this.reason = input.decision.reason;
58
+ this.digest = approvalDigest(input.permission, input.decision.token);
59
+ }
60
+ toProblemDetails(options) {
61
+ return problemDetails(compact({
62
+ decision: this.decision,
63
+ detail: this.message,
64
+ instance: options?.instance,
65
+ permission: this.permission,
66
+ scope: this.scope,
67
+ resource: this.resource
68
+ }));
69
+ }
70
+ };
71
+ /** The `name` of the deny grant a `deny` denial carries in `detail`, if any. */
72
+ function denyName(detail) {
73
+ if (detail === null || typeof detail !== "object" || !("name" in detail)) return;
74
+ return typeof detail.name === "string" ? detail.name : void 0;
75
+ }
76
+ function deniedMessage(permission, subjectId, denials, alternatives, named = true) {
77
+ const clauses = denials.map((denial) => {
78
+ const name = denial.reason === "deny" ? denyName(denial.detail) : void 0;
79
+ return name === void 0 ? `${denial.role ?? "none"} (${denial.reason})` : `${denial.role ?? "none"} (${denial.reason} '${name}')`;
80
+ }).join(", ");
81
+ const alt = alternatives.length === 0 ? "" : ` Alternatives: ${alternatives.join(", ")}.`;
82
+ return `${permission} denied${named ? ` for subject ${subjectId ?? "anonymous"}` : ""}: ${clauses}.${alt}`;
83
+ }
84
+ function approvalMessage(permission, reason, token) {
85
+ return `${permission} requires human approval (${reason}). Token: ${token}.`;
86
+ }
87
+ /**
88
+ * The `reason` of a long-lived connection's aborted `signal`. `denied` carries
89
+ * the decision that re-denied the permission the connection was opened for.
90
+ */
91
+ var PermDockRevokedError = class extends Error {
92
+ name = "PermDockRevokedError";
93
+ code;
94
+ permission;
95
+ decision;
96
+ constructor(input) {
97
+ super(`PermDock: connection ended (${input.code}).`);
98
+ this.code = input.code;
99
+ if (input.permission !== void 0) this.permission = input.permission;
100
+ if (input.decision !== void 0) this.decision = input.decision;
101
+ }
102
+ toProblemDetails(options) {
103
+ if (this.code === "denied") return compact({
104
+ type: `${PROBLEM_BASE}/denied`,
105
+ title: "Permission denied",
106
+ status: 403,
107
+ detail: this.code,
108
+ instance: options?.instance,
109
+ permission: this.permission,
110
+ denials: this.decision?.outcome === "denied" ? wireDenials(this.decision.denials) : void 0
111
+ });
112
+ return compact({
113
+ type: `${PROBLEM_BASE}/unauthenticated`,
114
+ title: "Authorization ended",
115
+ status: 401,
116
+ detail: this.code,
117
+ instance: options?.instance,
118
+ permission: this.permission
119
+ });
120
+ }
121
+ };
122
+ //#endregion
123
+ export { deniedMessage as a, approvalMessage as i, PermDockDeniedError as n, PermDockRevokedError as r, PermDockApprovalRequiredError as t };