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,538 @@
1
+ import { t as compact } from "./compact-y6vfu2_f.js";
2
+ import { _ as listPermissions, i as findPermission, p as isPermission } from "./permissions-DVoF6dMt.js";
3
+ import { n as sha256 } from "./sha256-BO0swRXL.js";
4
+ import { t as requiresApproval } from "./approval-required-TzNB9oQA.js";
5
+ import { i as PROFILE_PARAMETERS, n as GNAP_RESERVED, r as PROFILE_NAMES, t as DRAFT_PINS } from "./pins-8ILTftC9.js";
6
+ //#region src/openapi/emit.ts
7
+ function assertScheme(options) {
8
+ if (options.scheme.type === "gnap") throw new TypeError(GNAP_RESERVED);
9
+ }
10
+ function asList(permission) {
11
+ return isPermission(permission) ? [permission] : permission;
12
+ }
13
+ function grantsOf(policy, permissions) {
14
+ const keys = new Set(permissions.map((leaf) => leaf.key));
15
+ return policy.grants.filter((grant) => keys.has(grant.permission.key));
16
+ }
17
+ function grantsAnyone(grant) {
18
+ return (Array.isArray(grant.to) ? grant.to : [grant.to]).some((grantee) => grantee.kind === "anyone");
19
+ }
20
+ /** Every subject is granted it: an unconditional allow to `anyone()` and no deny. */
21
+ function isPublic(policy, permission) {
22
+ const grants = grantsOf(policy, [permission]);
23
+ return grants.every((grant) => grant.effect === "allow") && grants.some((grant) => grantsAnyone(grant) && grant.where === void 0 && grant.check === void 0 && grant.approval === void 0 && grant.closure === void 0 && grant.limit === void 0 && grant.purpose === void 0 && grant.viaOnly === void 0);
24
+ }
25
+ function mergeRecord(base, extra) {
26
+ const result = {};
27
+ for (const [key, value] of Object.entries(base)) result[key] = value;
28
+ for (const [key, value] of Object.entries(extra)) result[key] = value;
29
+ return result;
30
+ }
31
+ function scopesOf$1(policy) {
32
+ const scopes = {};
33
+ for (const leaf of listPermissions(policy.permissions)) scopes[leaf.scope] = leaf.meta.description ?? leaf.meta.title ?? leaf.key;
34
+ return scopes;
35
+ }
36
+ function flowWithScopes(flow, scopes) {
37
+ return mergeRecord(flow ?? {}, { scopes });
38
+ }
39
+ function securitySchemesOf(policy, options) {
40
+ assertScheme(options);
41
+ const target = options.target ?? "3.2";
42
+ const scopes = scopesOf$1(policy);
43
+ const name = options.scheme.name;
44
+ if (options.scheme.ref !== void 0 && target !== "3.1") return { [name]: { $ref: options.scheme.ref } };
45
+ const flowsIn = options.scheme.flows ?? { authorizationCode: {} };
46
+ const flows = {};
47
+ if (flowsIn.authorizationCode !== void 0) flows["authorizationCode"] = flowWithScopes(flowsIn.authorizationCode, scopes);
48
+ if (flowsIn.clientCredentials !== void 0) flows["clientCredentials"] = flowWithScopes(flowsIn.clientCredentials, scopes);
49
+ if (flowsIn.deviceAuthorization !== void 0) {
50
+ if (target === "3.1") {
51
+ const { deviceAuthorizationUrl, ...rest } = flowsIn.deviceAuthorization;
52
+ flows["x-oai-deviceAuthorization"] = flowWithScopes(compact({
53
+ ...rest,
54
+ "x-oai-deviceAuthorizationUrl": deviceAuthorizationUrl
55
+ }), scopes);
56
+ } else flows["deviceAuthorization"] = flowWithScopes(flowsIn.deviceAuthorization, scopes);
57
+ }
58
+ const scheme = compact({
59
+ type: options.scheme.type,
60
+ flows: options.scheme.type === "oauth2" ? flows : void 0,
61
+ openIdConnectUrl: options.scheme.type === "openIdConnect" ? options.scheme.openIdConnectUrl : void 0,
62
+ oauth2MetadataUrl: target === "3.2" || target === "3.3" ? options.scheme.oauth2MetadataUrl : void 0,
63
+ "x-permdock-oauth2MetadataUrl": target === "3.1" ? options.scheme.oauth2MetadataUrl : void 0,
64
+ deprecated: target !== "3.1" && options.scheme.deprecated === true ? true : void 0,
65
+ "x-oai-deprecated": target === "3.1" && options.scheme.deprecated === true ? true : void 0,
66
+ "x-permdock-securityProfile": options.securityProfile
67
+ });
68
+ const schemes = { [name]: scheme };
69
+ if (target === "3.3" && options.securityProfile !== void 0) {
70
+ const profileName = options.profileScheme ?? "permdockFapi2";
71
+ schemes[profileName] = compact({
72
+ type: "profile",
73
+ profileMetadata: compact({
74
+ name: PROFILE_NAMES[options.securityProfile],
75
+ supportedParametersSchema: PROFILE_PARAMETERS[options.securityProfile],
76
+ servers: options.scheme.oauth2MetadataUrl === void 0 ? void 0 : [{
77
+ name: "default",
78
+ url: options.scheme.oauth2MetadataUrl
79
+ }]
80
+ }),
81
+ "x-permdock-securityProfile": options.securityProfile
82
+ });
83
+ }
84
+ return schemes;
85
+ }
86
+ function securityOf(policy, options, permissions, anyOf) {
87
+ assertScheme(options);
88
+ const name = options.scheme.name;
89
+ if (anyOf === true ? permissions.some((leaf) => isPublic(policy, leaf)) : permissions.length > 0 && permissions.every((leaf) => isPublic(policy, leaf))) return [];
90
+ if (anyOf === true) return permissions.map((leaf) => ({ [name]: [leaf.scope] }));
91
+ return [{ [name]: permissions.map((leaf) => leaf.scope) }];
92
+ }
93
+ function describeOf(policy, options, permissions, anyOf) {
94
+ const conditions = {};
95
+ const approvals = {};
96
+ for (const leaf of permissions) {
97
+ const grants = grantsOf(policy, [leaf]).filter((grant) => grant.effect === "allow");
98
+ const wheres = grants.filter((grant) => grant.portable).map((grant) => grant.where).filter((where) => where !== void 0);
99
+ const [only] = wheres;
100
+ if (only !== void 0) conditions[leaf.key] = wheres.length === 1 ? only : {
101
+ op: "or",
102
+ conditions: wheres
103
+ };
104
+ if (grants.some((grant) => requiresApproval(grant.approval))) approvals[leaf.key] = { reason: "human" };
105
+ }
106
+ const approval = Object.keys(approvals).length > 0;
107
+ return compact({
108
+ security: securityOf(policy, options, permissions, anyOf),
109
+ "x-permdock-permissions": permissions.map((leaf) => leaf.key),
110
+ "x-permdock-conditions": Object.keys(conditions).length > 0 ? conditions : void 0,
111
+ "x-permdock-approval": approval ? approvals : void 0,
112
+ "x-permdock-securityProfile": options.securityProfile,
113
+ "x-badges": options.docsHints?.badges === true && approval ? [{ name: "Approval required" }] : void 0
114
+ });
115
+ }
116
+ function catalogOf(options, extraDrafts) {
117
+ const target = options.target ?? "3.2";
118
+ const drafts = {};
119
+ if (target === "3.3") {
120
+ drafts["oas"] = DRAFT_PINS.oas;
121
+ drafts["securityProfiles"] = DRAFT_PINS.securityProfiles;
122
+ }
123
+ if (extraDrafts !== void 0) for (const [key, value] of Object.entries(extraDrafts)) drafts[key] = value;
124
+ return compact({
125
+ v: 1,
126
+ generator: "permdock/openapi",
127
+ drafts: Object.keys(drafts).length > 0 ? drafts : void 0
128
+ });
129
+ }
130
+ const GRANT_TYPES = {
131
+ authorizationCode: "authorization_code",
132
+ clientCredentials: "client_credentials",
133
+ deviceAuthorization: "urn:ietf:params:oauth:grant-type:device_code"
134
+ };
135
+ const FLOWS = [
136
+ "authorizationCode",
137
+ "clientCredentials",
138
+ "deviceAuthorization"
139
+ ];
140
+ /** The client authentication methods FAPI 2.0 section 5.3.2.1 allows: sender-constrained, no shared secret. */
141
+ const FAPI2_AUTH_METHODS = ["private_key_jwt", "tls_client_auth"];
142
+ function pascal(value) {
143
+ return value.split(/[^A-Za-z0-9]+/u).filter((part) => part.length > 0).map((part) => `${part.charAt(0).toUpperCase()}${part.slice(1)}`).join("");
144
+ }
145
+ /**
146
+ * One Security Profile Requirement per distinct scope set: `scopeSets` from
147
+ * the operations, else one per permission.
148
+ */
149
+ function securityProfileRequirementsOf(policy, options, scopeSets) {
150
+ if ((options.target ?? "3.2") !== "3.3" || options.securityProfile === void 0) return;
151
+ const profileName = options.profileScheme ?? "permdockFapi2";
152
+ const flows = options.scheme.flows ?? { authorizationCode: {} };
153
+ const grantTypes = FLOWS.filter((flow) => flows[flow] !== void 0).map((flow) => GRANT_TYPES[flow]);
154
+ const sets = scopeSets ?? listPermissions(policy.permissions).map((leaf) => [leaf.scope]);
155
+ const requirements = {};
156
+ for (const set of sets) {
157
+ const scopes = [...new Set(set)].toSorted();
158
+ if (scopes.length === 0) continue;
159
+ requirements[`${profileName}${pascal(scopes.join(" "))}`] = {
160
+ securityScheme: { $ref: `#/components/securitySchemes/${profileName}` },
161
+ token_endpoint_auth_methods: [...FAPI2_AUTH_METHODS],
162
+ grant_types: grantTypes,
163
+ scopes
164
+ };
165
+ }
166
+ return requirements;
167
+ }
168
+ function openapiVersion(target) {
169
+ switch (target) {
170
+ case "3.1": return "3.1.0";
171
+ case "3.2": return "3.2.0";
172
+ case "3.3": return "3.3.0";
173
+ default: return target;
174
+ }
175
+ }
176
+ //#endregion
177
+ //#region src/openapi/overlay.ts
178
+ function pointerEscape(value) {
179
+ return value.replaceAll("~", "~0").replaceAll("/", "~1");
180
+ }
181
+ function actionKey(keys) {
182
+ return keys.toSorted().join(",");
183
+ }
184
+ /** An RFC 9535 single-quoted string literal. */
185
+ function jsonPathString(value) {
186
+ return `'${value.replaceAll("\\", "\\\\").replaceAll("'", "\\'")}'`;
187
+ }
188
+ function operationTarget(operationId) {
189
+ return `$.paths.*[?@.operationId == ${jsonPathString(operationId)}]`;
190
+ }
191
+ function hex(bytes) {
192
+ return Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
193
+ }
194
+ /** `sha256:` over the sorted permission keys and scopes, so the same catalog gives the same Overlay. */
195
+ function fingerprint(policy) {
196
+ const lines = listPermissions(policy.permissions).map((leaf) => `${leaf.key} ${leaf.scope}`).toSorted();
197
+ return `sha256:${hex(sha256(lines.join("\n")))}`;
198
+ }
199
+ function overlayOf(policy, options, overlayOptions = {}) {
200
+ const version = overlayOptions.version ?? "1.1";
201
+ const operations = (overlayOptions.operations ?? listPermissions(policy.permissions).map((leaf) => ({
202
+ operationId: leaf.key,
203
+ permissions: [leaf]
204
+ }))).toSorted((a, b) => a.operationId < b.operationId ? -1 : a.operationId > b.operationId ? 1 : 0);
205
+ const schemes = securitySchemesOf(policy, options);
206
+ const requirements = securityProfileRequirementsOf(policy, options, overlayOptions.operations?.map((operation) => operation.permissions.map((leaf) => leaf.scope)));
207
+ const catalogPin = fingerprint(policy);
208
+ const drafts = version === "1.2" ? { overlay: DRAFT_PINS.overlay } : void 0;
209
+ const info = {
210
+ title: "PermDock authorization metadata",
211
+ version: catalogPin
212
+ };
213
+ const head = [{
214
+ target: "$.components.securitySchemes",
215
+ description: "PermDock security schemes",
216
+ update: schemes
217
+ }];
218
+ if (requirements !== void 0) head.push({
219
+ target: "$.components.securityProfileRequirements",
220
+ description: "PermDock security profile requirements",
221
+ update: requirements
222
+ });
223
+ const catalogAction = {
224
+ target: "$",
225
+ description: "PermDock catalog pin",
226
+ update: { "x-permdock-catalog": catalogOf(options, drafts) }
227
+ };
228
+ const bodies = operations.map((operation) => {
229
+ const keys = operation.permissions.map((leaf) => leaf.key);
230
+ return {
231
+ operationId: operation.operationId,
232
+ key: actionKey(keys),
233
+ target: operationTarget(operation.operationId),
234
+ fields: describeOf(policy, options, operation.permissions)
235
+ };
236
+ });
237
+ if (version === "1.1") return compact({
238
+ overlay: "1.1.0",
239
+ info,
240
+ extends: overlayOptions.extends,
241
+ actions: [
242
+ ...head,
243
+ ...bodies.map((body) => ({
244
+ target: body.target,
245
+ description: body.key,
246
+ update: body.fields
247
+ })),
248
+ catalogAction
249
+ ]
250
+ });
251
+ const reusable = {};
252
+ for (const body of bodies.toSorted((a, b) => a.key < b.key ? -1 : a.key > b.key ? 1 : 0)) reusable[body.key] ??= {
253
+ description: body.key,
254
+ fields: { update: body.fields }
255
+ };
256
+ return compact({
257
+ overlay: "1.2.0",
258
+ info,
259
+ extends: overlayOptions.extends,
260
+ components: { actions: reusable },
261
+ actions: [
262
+ ...head,
263
+ ...bodies.map((body) => ({
264
+ $ref: `#/components/actions/${pointerEscape(body.key)}`,
265
+ target: body.target,
266
+ description: body.operationId
267
+ })),
268
+ catalogAction
269
+ ]
270
+ });
271
+ }
272
+ //#endregion
273
+ //#region src/openapi/create.ts
274
+ function extendOperation(operation, extra) {
275
+ const result = {};
276
+ for (const [key, value] of Object.entries(operation)) result[key] = value;
277
+ for (const [key, value] of Object.entries(extra)) result[key] = value;
278
+ return result;
279
+ }
280
+ const createPermDock = (policy, options) => {
281
+ return {
282
+ securitySchemes() {
283
+ return securitySchemesOf(policy, options);
284
+ },
285
+ security(permission, extra) {
286
+ return securityOf(policy, options, asList(permission), extra?.anyOf);
287
+ },
288
+ describe(permission, extra) {
289
+ return describeOf(policy, options, asList(permission), extra?.anyOf);
290
+ },
291
+ spec(permission) {
292
+ return (operation) => extendOperation(operation, describeOf(policy, options, asList(permission)));
293
+ },
294
+ overlay(overlayOptions) {
295
+ return overlayOf(policy, options, overlayOptions ?? {});
296
+ },
297
+ securityProfileRequirements(scopeSets) {
298
+ return securityProfileRequirementsOf(policy, options, scopeSets);
299
+ },
300
+ catalog() {
301
+ return catalogOf(options);
302
+ }
303
+ };
304
+ };
305
+ //#endregion
306
+ //#region src/openapi/operations.ts
307
+ const METHODS = /* @__PURE__ */ new Set([
308
+ "GET",
309
+ "PUT",
310
+ "POST",
311
+ "DELETE",
312
+ "OPTIONS",
313
+ "HEAD",
314
+ "PATCH",
315
+ "TRACE",
316
+ "QUERY"
317
+ ]);
318
+ function segmentsOf(path) {
319
+ return path.split("/").filter((segment) => segment !== "");
320
+ }
321
+ function isParam(segment) {
322
+ return segment.startsWith("{") && segment.endsWith("}");
323
+ }
324
+ /** The number of literal segments that match, or -1 when the template does not match. */
325
+ function score(route, segments) {
326
+ if (route.segments.length !== segments.length) return -1;
327
+ let literal = 0;
328
+ for (const [index, segment] of route.segments.entries()) {
329
+ if (isParam(segment)) continue;
330
+ if (segment !== segments[index]) return -1;
331
+ literal += 1;
332
+ }
333
+ return literal;
334
+ }
335
+ function isEntryObject(entry) {
336
+ return !isPermission(entry);
337
+ }
338
+ function scopesOf(key, entry) {
339
+ if (!isEntryObject(entry) || entry.oauthScopes === void 0) return;
340
+ const scopes = entry.oauthScopes;
341
+ if (scopes.length === 0 || !scopes.every((scope) => typeof scope === "string" && scope !== "")) throw new TypeError(`PermDock: operation '${key}' sets oauthScopes, which must be a non-empty list of scope names`);
342
+ return Object.freeze([...entry.oauthScopes]);
343
+ }
344
+ /**
345
+ * Operations as `"METHOD /path/{param}"` keys, the OpenAPI path template, to
346
+ * a permission. `base` is a prefix requests carry and the keys do not
347
+ * (`/api/v1`). A key that is not a method and a path throws.
348
+ */
349
+ function operationPermissions(operations, options = {}) {
350
+ const routes = [];
351
+ const byId = /* @__PURE__ */ new Map();
352
+ for (const [key, entry] of Object.entries(operations)) {
353
+ const space = key.indexOf(" ");
354
+ const method = key.slice(0, space).toUpperCase();
355
+ const path = key.slice(space + 1).trim();
356
+ if (space <= 0 || !METHODS.has(method) || !path.startsWith("/")) throw new TypeError(`PermDock: operation '${key}' must be a method and a path, such as 'GET /customers/{id}'`);
357
+ const oauthScopes = scopesOf(key, entry);
358
+ if (isEntryObject(entry) && (entry.permission === void 0 ? oauthScopes === void 0 : !isPermission(entry.permission))) throw new TypeError(`PermDock: operation '${key}' needs a permission, oauthScopes or both`);
359
+ const route = {
360
+ method,
361
+ segments: segmentsOf(path),
362
+ permission: isEntryObject(entry) ? entry.permission : entry,
363
+ ...oauthScopes === void 0 ? {} : { oauthScopes }
364
+ };
365
+ routes.push(route);
366
+ if (isEntryObject(entry) && entry.operationId !== void 0) byId.set(entry.operationId, route);
367
+ }
368
+ const base = segmentsOf(options.base ?? "");
369
+ const matchMethod = (upper, path) => {
370
+ const full = segmentsOf(path.split("?")[0] ?? "");
371
+ if (base.some((segment, index) => full[index] !== segment)) return;
372
+ const segments = full.slice(base.length);
373
+ let best;
374
+ let bestScore = -1;
375
+ for (const route of routes) {
376
+ if (route.method !== upper) continue;
377
+ const value = score(route, segments);
378
+ if (value > bestScore) {
379
+ best = route;
380
+ bestScore = value;
381
+ }
382
+ }
383
+ return best;
384
+ };
385
+ const match = (method, path) => {
386
+ const upper = method.toUpperCase();
387
+ const route = matchMethod(upper, path);
388
+ return route === void 0 && upper === "HEAD" ? matchMethod("GET", path) : route;
389
+ };
390
+ return {
391
+ forRequest(method, path) {
392
+ return match(method, path)?.permission;
393
+ },
394
+ forOperation(id) {
395
+ return byId.get(id)?.permission;
396
+ },
397
+ oauthScopesForRequest(method, path) {
398
+ return match(method, path)?.oauthScopes;
399
+ },
400
+ oauthScopesForOperation(id) {
401
+ return byId.get(id)?.oauthScopes;
402
+ }
403
+ };
404
+ }
405
+ function isRecord(value) {
406
+ return value !== null && typeof value === "object" && !Array.isArray(value);
407
+ }
408
+ /**
409
+ * The operation permissions an OpenAPI document declares: every operation
410
+ * whose `x-permdock-permissions` names exactly one permission of `tree`, keyed
411
+ * by its method, path and `operationId`. An operation naming none, several or
412
+ * an unknown key is left out, so a gate denies it.
413
+ */
414
+ function operationPermissionsFromOpenApi(document, tree, options = {}) {
415
+ const operations = {};
416
+ const paths = isRecord(document) && isRecord(document["paths"]) ? document["paths"] : {};
417
+ for (const [path, item] of Object.entries(paths)) {
418
+ if (!isRecord(item)) continue;
419
+ for (const [method, operation] of Object.entries(item)) {
420
+ if (!METHODS.has(method.toUpperCase()) || !isRecord(operation)) continue;
421
+ const keys = operation["x-permdock-permissions"];
422
+ if (!Array.isArray(keys) || keys.length !== 1 || typeof keys[0] !== "string") continue;
423
+ const permission = findPermission(tree, keys[0]);
424
+ if (permission === void 0) continue;
425
+ const operationId = operation["operationId"];
426
+ operations[`${method.toUpperCase()} ${path}`] = typeof operationId === "string" ? {
427
+ permission,
428
+ operationId
429
+ } : permission;
430
+ }
431
+ }
432
+ return operationPermissions(operations, options);
433
+ }
434
+ //#endregion
435
+ //#region src/openapi/problem-details.ts
436
+ const TARGETS = /* @__PURE__ */ new Set([
437
+ "draft-2020-12",
438
+ "draft-07",
439
+ "openapi-3.0"
440
+ ]);
441
+ const JSON_SCHEMA = Object.freeze({
442
+ type: "object",
443
+ description: "RFC 9457 Problem Details for a PermDock denial",
444
+ required: [
445
+ "type",
446
+ "title",
447
+ "status",
448
+ "detail"
449
+ ],
450
+ properties: {
451
+ type: {
452
+ type: "string",
453
+ format: "uri-reference"
454
+ },
455
+ title: { type: "string" },
456
+ status: {
457
+ type: "integer",
458
+ minimum: 400,
459
+ maximum: 599
460
+ },
461
+ detail: { type: "string" },
462
+ instance: { type: "string" },
463
+ permission: { type: "string" },
464
+ scope: { type: "string" },
465
+ reason: { type: "string" }
466
+ },
467
+ additionalProperties: true
468
+ });
469
+ const REQUIRED_STRINGS = [
470
+ "type",
471
+ "title",
472
+ "detail"
473
+ ];
474
+ function issuesOf(value) {
475
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return [{ message: "Expected a Problem Details object" }];
476
+ const issues = [];
477
+ const fields = new Map(Object.entries(value));
478
+ for (const key of REQUIRED_STRINGS) if (typeof fields.get(key) !== "string") issues.push({
479
+ message: `Expected a string`,
480
+ path: [key]
481
+ });
482
+ const status = fields.get("status");
483
+ if (typeof status !== "number" || !Number.isInteger(status) || status < 400 || status > 599) issues.push({
484
+ message: "Expected an HTTP error status",
485
+ path: ["status"]
486
+ });
487
+ return issues;
488
+ }
489
+ function isProblem(value) {
490
+ return issuesOf(value).length === 0;
491
+ }
492
+ function jsonSchema(options) {
493
+ if (!TARGETS.has(options.target)) throw new TypeError(`PermDock: problemDetails has no JSON Schema for target ${options.target}`);
494
+ return structuredClone(JSON_SCHEMA);
495
+ }
496
+ /**
497
+ * The Problem Details body the adapters send on a denial, as a Standard
498
+ * Schema with a JSON Schema, for `oc.errors({ FORBIDDEN: { data: problemDetails } })`.
499
+ * Extension members pass through: RFC 9457 lets a problem type add them.
500
+ */
501
+ const problemDetails = Object.freeze({ "~standard": Object.freeze({
502
+ version: 1,
503
+ vendor: "permdock",
504
+ validate: (value) => isProblem(value) ? { value } : { issues: issuesOf(value) },
505
+ jsonSchema: Object.freeze({
506
+ input: jsonSchema,
507
+ output: jsonSchema
508
+ })
509
+ }) });
510
+ //#endregion
511
+ //#region src/openapi/security.ts
512
+ function isList(permission) {
513
+ return Array.isArray(permission);
514
+ }
515
+ function listOf(permission) {
516
+ return isList(permission) ? permission : [permission];
517
+ }
518
+ /** The `x-permdock-permissions` value: the permission keys an operation enforces. */
519
+ function permissionsExtension(permissions) {
520
+ return Object.freeze(listOf(permissions).map((leaf) => leaf.key));
521
+ }
522
+ /**
523
+ * An operation's `security` and `x-permdock-permissions`, from permission
524
+ * references alone. Needs no policy, so a contract package can import it.
525
+ * Unlike `permdock openapi emit`, it never drops `security` for a public
526
+ * permission: that needs the policy.
527
+ */
528
+ function securityFor(permission, options = {}) {
529
+ const leaves = listOf(permission);
530
+ const scheme = options.scheme ?? "oauth2";
531
+ const security = options.anyOf === true && leaves.length > 0 ? leaves.map((leaf) => ({ [scheme]: [leaf.scope] })) : [{ [scheme]: leaves.map((leaf) => leaf.scope) }];
532
+ return Object.freeze({
533
+ security,
534
+ "x-permdock-permissions": permissionsExtension(leaves)
535
+ });
536
+ }
537
+ //#endregion
538
+ export { operationPermissionsFromOpenApi as a, openapiVersion as c, operationPermissions as i, securitySchemesOf as l, securityFor as n, createPermDock as o, problemDetails as r, catalogOf as s, permissionsExtension as t };