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,466 @@
1
+ import { n as isReadonlyArray, t as compact } from "./compact-y6vfu2_f.js";
2
+ import { T as isForbiddenKey, k as splitPath } from "./permissions-DVoF6dMt.js";
3
+ import { t as loadJose } from "./load-jose-BL6LH4bL.js";
4
+ //#region src/jwt/header.ts
5
+ function compactParts(token) {
6
+ return token.split(".");
7
+ }
8
+ function isJwe(token) {
9
+ return compactParts(token).length === 5;
10
+ }
11
+ function decodeHeader(token) {
12
+ const [encoded] = compactParts(token);
13
+ if (encoded === void 0 || encoded.length === 0) return;
14
+ try {
15
+ const padded = encoded.replaceAll("-", "+").replaceAll("_", "/");
16
+ const pad = padded.length % 4 === 0 ? "" : "=".repeat(4 - padded.length % 4);
17
+ const json = atob(`${padded}${pad}`);
18
+ const value = JSON.parse(json);
19
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return;
20
+ return value;
21
+ } catch {
22
+ return;
23
+ }
24
+ }
25
+ function unknownCrit(header) {
26
+ const crit = header.crit;
27
+ if (crit === void 0) return false;
28
+ if (!isReadonlyArray(crit)) return true;
29
+ const understood = /* @__PURE__ */ new Set([
30
+ "alg",
31
+ "kid",
32
+ "typ",
33
+ "cty",
34
+ "enc"
35
+ ]);
36
+ return crit.some((name) => typeof name !== "string" || !understood.has(name));
37
+ }
38
+ function normalizeTyp(typ) {
39
+ if (typ === void 0) return;
40
+ const lower = typ.toLowerCase();
41
+ return lower.startsWith("application/") ? lower.slice(12) : lower;
42
+ }
43
+ //#endregion
44
+ //#region src/jwt/config.ts
45
+ const DEFAULT_ALGORITHMS = [
46
+ "ES256",
47
+ "PS256",
48
+ "Ed25519",
49
+ "RS256"
50
+ ];
51
+ const FAPI2_ALGORITHMS = [
52
+ "ES256",
53
+ "PS256",
54
+ "Ed25519"
55
+ ];
56
+ const DEFAULT_DECRYPTION_ALGS = [
57
+ "RSA-OAEP-256",
58
+ "ECDH-ES",
59
+ "ECDH-ES+A256KW",
60
+ "dir"
61
+ ];
62
+ const DEFAULT_CLOCK_TOLERANCE = 5;
63
+ const FAPI2_CLOCK_TOLERANCE = 5;
64
+ function fail(cause) {
65
+ return {
66
+ ok: false,
67
+ reason: "invalid-token",
68
+ cause
69
+ };
70
+ }
71
+ function isSecretJwks(jwks) {
72
+ return typeof jwks === "object" && jwks !== null && !(jwks instanceof URL) && "secret" in jwks;
73
+ }
74
+ function issuerFromDiscovery(discovery) {
75
+ return typeof discovery === "string" ? discovery : discovery.issuer;
76
+ }
77
+ function resolveAlgorithms(options) {
78
+ if (options.algorithms !== void 0) return options.algorithms;
79
+ return options.profile === "fapi2" ? FAPI2_ALGORITHMS : DEFAULT_ALGORITHMS;
80
+ }
81
+ function resolveClockTolerance(options, override) {
82
+ const configured = override ?? options.clockTolerance ?? DEFAULT_CLOCK_TOLERANCE;
83
+ if (options.profile === "fapi2") return Math.min(configured, FAPI2_CLOCK_TOLERANCE);
84
+ return configured;
85
+ }
86
+ function assertSafeClaimPaths(claims) {
87
+ if (claims === void 0) return;
88
+ const paths = [
89
+ claims.id,
90
+ claims.roles,
91
+ claims.groups,
92
+ claims.entitlements,
93
+ claims.tenant,
94
+ claims.memberships,
95
+ claims.session
96
+ ].filter((path) => path !== void 0);
97
+ if (typeof claims.assurance === "string") paths.push(claims.assurance);
98
+ else if (claims.assurance !== void 0) paths.push(...[
99
+ claims.assurance.acr,
100
+ claims.assurance.amr,
101
+ claims.assurance.authTime,
102
+ claims.assurance.verified
103
+ ].filter((path) => path !== void 0));
104
+ if (claims.kind !== void 0 && claims.kind !== "workload" && claims.kind !== "user" && claims.kind !== "service") paths.push(claims.kind);
105
+ for (const path of paths) for (const segment of splitPath(path)) if (isForbiddenKey(segment)) throw new Error(`PermDock: forbidden claim path '${path}'.`);
106
+ }
107
+ function assertVerifierConfig(options) {
108
+ if (options.discovery !== void 0 && options.jwks !== void 0) throw new Error("PermDock: discovery and jwks are mutually exclusive.");
109
+ if (options.discovery === void 0 && options.jwks === void 0) throw new Error("PermDock: joseTokenVerifier requires jwks or discovery.");
110
+ if (typeof options.jwks === "string" && !URL.canParse(options.jwks)) throw new Error("PermDock: jwks must be an absolute URL.");
111
+ if (options.discovery !== void 0) {
112
+ const issuer = issuerFromDiscovery(options.discovery);
113
+ let url;
114
+ try {
115
+ url = new URL(issuer);
116
+ } catch {
117
+ throw new Error("PermDock: discovery issuer must be an absolute URL.");
118
+ }
119
+ if (url.protocol !== "https:") throw new Error("PermDock: discovery issuer must use https.");
120
+ if (options.issuer !== void 0 && options.issuer !== issuer) throw new Error("PermDock: issuer must match discovery or be omitted.");
121
+ const jwksUri = typeof options.discovery === "string" ? void 0 : options.discovery.metadata?.jwks_uri;
122
+ if (jwksUri !== void 0 && URL.parse(jwksUri)?.protocol !== "https:") throw new Error("PermDock: discovery jwks_uri must use https.");
123
+ }
124
+ if (options.jwks !== void 0 && isSecretJwks(options.jwks)) {
125
+ if (secretBits(options.jwks.secret) < 256) throw new Error("PermDock: HMAC secret must be at least 256 bits.");
126
+ }
127
+ if (resolveAlgorithms(options).includes("none")) throw new Error("PermDock: alg none is never accepted.");
128
+ }
129
+ function assertSubjectConfig(options) {
130
+ if (options.verifier === void 0) {
131
+ assertVerifierConfig(options);
132
+ if (options.jwks !== void 0 && !isSecretJwks(options.jwks) && options.issuer === void 0) throw new Error("PermDock: issuer is required with jwks.");
133
+ }
134
+ assertSafeClaimPaths(options.claims);
135
+ if (options.profile === "fapi2" && options.sender === "none") throw new Error("PermDock: profile 'fapi2' requires a sender constraint.");
136
+ }
137
+ function secretBits(secret) {
138
+ if (typeof secret === "string") return secret.length * 8;
139
+ return secret.byteLength * 8;
140
+ }
141
+ function secretBytes(secret) {
142
+ if (typeof secret === "string") return new TextEncoder().encode(secret);
143
+ return secret;
144
+ }
145
+ //#endregion
146
+ //#region src/jwt/cache.ts
147
+ function clampTtl(seconds, minTtl, maxTtl) {
148
+ return Math.min(maxTtl, Math.max(minTtl, seconds));
149
+ }
150
+ function cacheControlMaxAge(header) {
151
+ if (header === null) return;
152
+ const match = /max-age=(\d+)/iu.exec(header);
153
+ if (match?.[1] === void 0) return;
154
+ return Math.trunc(Number(match[1]));
155
+ }
156
+ function isHttpsUrl(value) {
157
+ return typeof value === "string" && URL.parse(value)?.protocol === "https:";
158
+ }
159
+ function discoveryUrls(issuer) {
160
+ const url = new URL(issuer);
161
+ const oidc = new URL("/.well-known/openid-configuration", url.origin);
162
+ if (url.pathname !== "/" && url.pathname !== "") oidc.pathname = `${url.pathname.replace(/\/$/u, "")}/.well-known/openid-configuration`;
163
+ const rfc8414 = new URL(url.href);
164
+ rfc8414.pathname = `/.well-known/oauth-authorization-server${url.pathname === "/" ? "" : url.pathname.replace(/\/$/u, "")}`;
165
+ return [oidc.href, rfc8414.href];
166
+ }
167
+ function createKeyCache(options) {
168
+ const minTtl = options.jwksCache?.minTtl ?? 60;
169
+ const maxTtl = options.jwksCache?.maxTtl ?? 3600;
170
+ const cooldown = options.jwksCache?.cooldown ?? 60;
171
+ const timeout = options.jwksCache?.timeout ?? 5e3;
172
+ const fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis);
173
+ const jwksInFlight = /* @__PURE__ */ new Map();
174
+ let discoveryInFlight;
175
+ let discoveryCache;
176
+ /** Keyed by `jwks_uri`: keys cached for one URI never answer for another. */
177
+ let jwksCache;
178
+ const cachedJwks = (href, now) => jwksCache?.href === href && jwksCache.expiresAt > now ? jwksCache.value : void 0;
179
+ let cooldownUntil = 0;
180
+ let discoveryCause;
181
+ const readDiscovery = async (href, issuer, now) => {
182
+ try {
183
+ const response = await fetchImpl(href, {
184
+ headers: { accept: "application/json" },
185
+ signal: AbortSignal.timeout(timeout)
186
+ });
187
+ if (!response.ok) return;
188
+ const body = await response.json();
189
+ if (body.issuer !== issuer) {
190
+ discoveryCause = "discovery-mismatch";
191
+ return {
192
+ ok: false,
193
+ cause: "discovery-mismatch"
194
+ };
195
+ }
196
+ if (!isHttpsUrl(body.jwks_uri)) return;
197
+ const ttl = clampTtl(cacheControlMaxAge(response.headers.get("cache-control")) ?? maxTtl, minTtl, maxTtl);
198
+ discoveryCache = {
199
+ value: {
200
+ issuer: body.issuer,
201
+ jwks_uri: body.jwks_uri
202
+ },
203
+ expiresAt: now + ttl
204
+ };
205
+ discoveryCause = void 0;
206
+ return {
207
+ ok: true,
208
+ ...discoveryCache.value
209
+ };
210
+ } catch {
211
+ return;
212
+ }
213
+ };
214
+ const loadDiscovery = (discovery, now) => {
215
+ if (typeof discovery !== "string" && discovery.metadata?.jwks_uri !== void 0) {
216
+ const issuer = issuerFromDiscovery(discovery);
217
+ if (discovery.metadata.issuer !== void 0 && discovery.metadata.issuer !== issuer) {
218
+ discoveryCause = "discovery-mismatch";
219
+ return Promise.resolve({
220
+ ok: false,
221
+ cause: "discovery-mismatch"
222
+ });
223
+ }
224
+ return Promise.resolve({
225
+ ok: true,
226
+ issuer,
227
+ jwks_uri: discovery.metadata.jwks_uri
228
+ });
229
+ }
230
+ if (discoveryCache !== void 0 && discoveryCache.expiresAt > now) return Promise.resolve({
231
+ ok: true,
232
+ ...discoveryCache.value
233
+ });
234
+ discoveryInFlight ??= fetchDiscovery(discovery, now).finally(() => {
235
+ discoveryInFlight = void 0;
236
+ });
237
+ return discoveryInFlight;
238
+ };
239
+ const fetchDiscovery = async (discovery, now) => {
240
+ const issuer = issuerFromDiscovery(discovery);
241
+ const [oidc, rfc8414] = discoveryUrls(issuer);
242
+ const fromOidc = oidc === void 0 ? void 0 : await readDiscovery(oidc, issuer, now);
243
+ if (fromOidc !== void 0) return fromOidc;
244
+ const fromRfc8414 = rfc8414 === void 0 ? void 0 : await readDiscovery(rfc8414, issuer, now);
245
+ if (fromRfc8414 !== void 0) return fromRfc8414;
246
+ if (discoveryCache !== void 0) return {
247
+ ok: true,
248
+ ...discoveryCache.value
249
+ };
250
+ return {
251
+ ok: false,
252
+ cause: discoveryCause ?? "discovery-unavailable"
253
+ };
254
+ };
255
+ const loadJwks = (href, now, force) => {
256
+ const cached = force ? void 0 : cachedJwks(href, now);
257
+ if (cached !== void 0) return Promise.resolve({
258
+ ok: true,
259
+ jwks: cached
260
+ });
261
+ const pending = jwksInFlight.get(href);
262
+ if (pending !== void 0) return pending;
263
+ const fetched = fetchJwks(href, now).finally(() => {
264
+ jwksInFlight.delete(href);
265
+ });
266
+ jwksInFlight.set(href, fetched);
267
+ return fetched;
268
+ };
269
+ const fetchJwks = async (href, now) => {
270
+ try {
271
+ const response = await fetchImpl(href, {
272
+ headers: { accept: "application/jwk-set+json, application/json" },
273
+ signal: AbortSignal.timeout(timeout)
274
+ });
275
+ if (!response.ok) throw new Error("jwks fetch failed");
276
+ const body = await response.json();
277
+ if (!Array.isArray(body.keys) || body.keys.length === 0) throw new Error("empty jwks");
278
+ jwksCache = {
279
+ href,
280
+ value: body,
281
+ expiresAt: now + clampTtl(cacheControlMaxAge(response.headers.get("cache-control")) ?? maxTtl, minTtl, maxTtl)
282
+ };
283
+ return {
284
+ ok: true,
285
+ jwks: body
286
+ };
287
+ } catch {
288
+ const stale = cachedJwks(href, now);
289
+ if (stale !== void 0) return {
290
+ ok: true,
291
+ jwks: stale
292
+ };
293
+ return {
294
+ ok: false,
295
+ cause: "jwks-unavailable"
296
+ };
297
+ }
298
+ };
299
+ const resolve = async (force, nowInput) => {
300
+ const now = nowInput ?? Math.floor(Date.now() / 1e3);
301
+ if (options.jwks instanceof URL) return loadJwks(options.jwks.href, now, force);
302
+ if (typeof options.jwks === "string") return loadJwks(options.jwks, now, force);
303
+ if (options.jwks !== void 0 && typeof options.jwks === "object" && "keys" in options.jwks) return {
304
+ ok: true,
305
+ jwks: options.jwks
306
+ };
307
+ if (options.discovery === void 0) return {
308
+ ok: false,
309
+ cause: "jwks-unavailable"
310
+ };
311
+ const discovered = await loadDiscovery(options.discovery, now);
312
+ if (!discovered.ok) return discovered;
313
+ return loadJwks(discovered.jwks_uri, now, force);
314
+ };
315
+ return {
316
+ resolveJwks(now) {
317
+ return resolve(false, now);
318
+ },
319
+ refetchJwks(now) {
320
+ const current = now ?? Math.floor(Date.now() / 1e3);
321
+ if (current < cooldownUntil) return resolve(false, current);
322
+ cooldownUntil = current + cooldown;
323
+ return resolve(true, current);
324
+ }
325
+ };
326
+ }
327
+ //#endregion
328
+ //#region src/jwt/verifier.ts
329
+ const ACCESS_TYPS = /* @__PURE__ */ new Set(["at+jwt", "jwt"]);
330
+ const FAPI2_TYPS = /* @__PURE__ */ new Set(["at+jwt"]);
331
+ function algorithmAllowed(alg, allowed, key) {
332
+ if (alg === "none") return false;
333
+ if (alg === "EdDSA") return allowed.includes("Ed25519") && key?.["kty"] === "OKP" && key["crv"] === "Ed25519";
334
+ return allowed.includes(alg);
335
+ }
336
+ function findKey(keys, kid, profile) {
337
+ const usable = keys.filter((key) => !skipUndersized(key, profile));
338
+ if (kid === void 0) return usable.length === 1 ? usable[0] : void 0;
339
+ return usable.find((key) => key["kid"] === kid);
340
+ }
341
+ function skipUndersized(key, profile) {
342
+ if (profile !== "fapi2") return false;
343
+ if (key["kty"] === "RSA" && typeof key["n"] === "string") return Math.floor(key["n"].length * 6 / 8) * 8 < 2048;
344
+ if (key["kty"] === "EC" && key["crv"] === "P-192") return true;
345
+ return false;
346
+ }
347
+ function typAccepted(headerTyp, expected, profile) {
348
+ const seen = normalizeTyp(headerTyp);
349
+ if (expected !== void 0) return (typeof expected === "string" ? [expected] : expected).some((item) => normalizeTyp(item) === seen);
350
+ if (profile === "fapi2") return seen !== void 0 && FAPI2_TYPS.has(seen.toLowerCase());
351
+ if (seen === void 0) return true;
352
+ return ACCESS_TYPS.has(seen.toLowerCase());
353
+ }
354
+ function mapJoseCause(error) {
355
+ if (typeof error !== "object" || error === null || !("code" in error)) return "invalid-signature";
356
+ const code = String(error.code);
357
+ if (code === "ERR_JWT_EXPIRED") return "expired";
358
+ if (code === "ERR_JWKS_NO_MATCHING_KEY") return "unknown-kid";
359
+ if (code === "ERR_JOSE_ALG_NOT_ALLOWED" || code === "ERR_JWS_ALG_NOT_ALLOWED") return "alg-not-allowed";
360
+ if (code === "ERR_JWE_INVALID" || code === "ERR_JWE_NOT_SUPPORTED") return "encrypted-token";
361
+ if (code === "ERR_JWT_CLAIM_VALIDATION_FAILED") {
362
+ const claim = error.claim;
363
+ if (claim === "aud") return "wrong-audience";
364
+ if (claim === "iss") return "wrong-issuer";
365
+ if (claim === "nbf" || claim === "iat") return "not-yet-valid";
366
+ if (claim === "typ") return "wrong-token-type";
367
+ return "malformed";
368
+ }
369
+ if (code === "ERR_JWS_INVALID" || code === "ERR_JWT_INVALID") return "malformed";
370
+ return "invalid-signature";
371
+ }
372
+ function joseTokenVerifier(options) {
373
+ assertVerifierConfig(options);
374
+ const algorithms = resolveAlgorithms(options);
375
+ const cache = options.jwks !== void 0 && isSecretJwks(options.jwks) ? void 0 : createKeyCache(options);
376
+ const issuer = options.issuer ?? (options.discovery === void 0 ? void 0 : issuerFromDiscovery(options.discovery));
377
+ const verifyInner = async (token, expectations, keys, header) => {
378
+ const jose = await loadJose();
379
+ const alg = header?.alg ?? "";
380
+ const key = keys instanceof Uint8Array ? void 0 : findKey(keys, header?.kid, options.profile);
381
+ if (!(keys instanceof Uint8Array) && key === void 0) return fail("unknown-kid");
382
+ if (!algorithmAllowed(alg, algorithms, key)) return fail(alg === "none" ? "alg-none" : "alg-not-allowed");
383
+ const expectedTyp = expectations.typ ?? options.typ;
384
+ if (!typAccepted(header?.typ, expectedTyp, options.profile)) return fail("wrong-token-type");
385
+ const securityEvent = normalizeTyp(header?.typ) === "secevent+jwt";
386
+ const verifyAlgs = algorithms.includes("Ed25519") ? [...algorithms, "EdDSA"] : [...algorithms];
387
+ try {
388
+ const getKey = keys instanceof Uint8Array ? keys : jose.createLocalJWKSet({ keys });
389
+ const result = await jose.jwtVerify(token, getKey, compact({
390
+ algorithms: verifyAlgs,
391
+ issuer: expectations.issuer ?? issuer,
392
+ audience: expectations.audience ?? options.audience,
393
+ clockTolerance: resolveClockTolerance(options, expectations.clockTolerance),
394
+ requiredClaims: securityEvent ? ["iat"] : ["exp"]
395
+ }));
396
+ const claims = result.payload;
397
+ if (!securityEvent && typeof claims.exp !== "number") return fail("expired");
398
+ return {
399
+ ok: true,
400
+ claims,
401
+ header: compact({
402
+ alg: String(result.protectedHeader.alg ?? alg),
403
+ kid: typeof result.protectedHeader.kid === "string" ? result.protectedHeader.kid : header?.kid,
404
+ typ: typeof result.protectedHeader.typ === "string" ? result.protectedHeader.typ : header?.typ
405
+ })
406
+ };
407
+ } catch (error) {
408
+ return fail(mapJoseCause(error));
409
+ }
410
+ };
411
+ const decryptNested = async (token) => {
412
+ if (options.decryptionKeys === void 0) return fail("encrypted-token");
413
+ const header = decodeHeader(token);
414
+ if (header?.zip !== void 0 || header?.alg === "RSA1_5" || header?.cty === void 0 || normalizeTyp(header.cty) !== "jwt") return fail("encrypted-token");
415
+ const jose = await loadJose();
416
+ try {
417
+ const listed = options.decryptionKeys;
418
+ const first = ("keys" in listed && Array.isArray(listed.keys) ? listed.keys : [listed])[0];
419
+ if (first === void 0 || first["kty"] !== "oct" || typeof first["k"] !== "string") return fail("encrypted-token");
420
+ const { plaintext } = await jose.compactDecrypt(token, jose.base64url.decode(first["k"]), { keyManagementAlgorithms: [...options.decryptionAlgorithms ?? DEFAULT_DECRYPTION_ALGS].filter((alg) => alg !== "RSA1_5") });
421
+ return {
422
+ ok: true,
423
+ jwt: new TextDecoder().decode(plaintext)
424
+ };
425
+ } catch {
426
+ return fail("encrypted-token");
427
+ }
428
+ };
429
+ return { verify(token, expectations = {}) {
430
+ return verifyToken(token, expectations);
431
+ } };
432
+ async function verifyToken(token, expectations) {
433
+ try {
434
+ if (typeof token !== "string" || token.length === 0) return fail("malformed");
435
+ let jwt = token;
436
+ if (isJwe(token)) {
437
+ const decrypted = await decryptNested(token);
438
+ if (!decrypted.ok) return decrypted;
439
+ jwt = decrypted.jwt;
440
+ }
441
+ const header = decodeHeader(jwt);
442
+ if (header === void 0) return fail("malformed");
443
+ if (header.alg === "none") return fail("alg-none");
444
+ if (unknownCrit(header)) return fail("malformed");
445
+ if (options.jwks !== void 0 && isSecretJwks(options.jwks)) {
446
+ if (!algorithms.includes("HS256") || header.alg !== "HS256") return fail(header.alg === "none" ? "alg-none" : "alg-not-allowed");
447
+ return await verifyInner(jwt, expectations, secretBytes(options.jwks.secret), header);
448
+ }
449
+ if (cache === void 0) return fail("jwks-unavailable");
450
+ let resolved = await cache.resolveJwks();
451
+ if (!resolved.ok) return fail(resolved.cause);
452
+ let key = findKey(resolved.jwks.keys, header.kid, options.profile);
453
+ if (key === void 0 && header.kid !== void 0) {
454
+ resolved = await cache.refetchJwks();
455
+ if (!resolved.ok) return fail(resolved.cause);
456
+ key = findKey(resolved.jwks.keys, header.kid, options.profile);
457
+ }
458
+ if (key === void 0) return fail("unknown-kid");
459
+ return await verifyInner(jwt, expectations, resolved.jwks.keys, header);
460
+ } catch {
461
+ return fail("malformed");
462
+ }
463
+ }
464
+ }
465
+ //#endregion
466
+ export { decodeHeader as a, issuerFromDiscovery as i, assertSubjectConfig as n, normalizeTyp as o, fail as r, joseTokenVerifier as t };
@@ -0,0 +1,17 @@
1
+ import { t as packageRoot } from "./package-root-zGkxO3oN.js";
2
+ import { readFileSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ //#region src/cli/version.ts
5
+ function cliVersion() {
6
+ return JSON.parse(readFileSync(join(packageRoot(), "package.json"), "utf8")).version;
7
+ }
8
+ function generatorBanner() {
9
+ return `permdock@${cliVersion()}`;
10
+ }
11
+ const CATALOG_SCHEMA = "https://permdock.com/schemas/catalog-v1.json";
12
+ const SUPABASE_MANIFEST_SCHEMA = "https://permdock.com/schemas/supabase-manifest-v1.json";
13
+ const USAGE_REPORT_SCHEMA = "https://permdock.com/schemas/usage-report-v1.json";
14
+ const DOCTOR_REPORT_SCHEMA = "https://permdock.com/schemas/doctor-report-v1.json";
15
+ const CONFIG_REPORT_SCHEMA = "https://permdock.com/schemas/config-report-v1.json";
16
+ //#endregion
17
+ export { USAGE_REPORT_SCHEMA as a, SUPABASE_MANIFEST_SCHEMA as i, CONFIG_REPORT_SCHEMA as n, cliVersion as o, DOCTOR_REPORT_SCHEMA as r, generatorBanner as s, CATALOG_SCHEMA as t };
@@ -0,0 +1,95 @@
1
+ //#region src/client/views.ts
2
+ function permissionSet(store, permissions, data) {
3
+ const granted = [];
4
+ const byKey = {};
5
+ for (const permission of permissions) {
6
+ const state = store.permissionState(permission, data);
7
+ byKey[permission.key] = state;
8
+ if (state.allowed) granted.push(permission);
9
+ }
10
+ return new Proxy({
11
+ granted,
12
+ get(permission) {
13
+ return byKey[permission.key];
14
+ }
15
+ }, { get(target, prop, receiver) {
16
+ if (typeof prop === "string" && Object.hasOwn(byKey, prop)) return byKey[prop];
17
+ return Reflect.get(target, prop, receiver);
18
+ } });
19
+ }
20
+ function filterResult(permdock, permission, rows) {
21
+ const result = permdock.filter(permission, rows);
22
+ result.partial = permdock.where(permission).partial;
23
+ return result;
24
+ }
25
+ function tenantView(permdock) {
26
+ return {
27
+ tenant: permdock.subject.principal?.tenant ?? null,
28
+ tenants: permdock.tenants(),
29
+ switchTo: (id) => permdock.refresh({ tenant: id }),
30
+ status: permdock.status()
31
+ };
32
+ }
33
+ function rolesView(permdock, options) {
34
+ return { roles: (options.team === void 0 ? permdock : permdock.team(options.team)).heldRoles(options.tenant === void 0 ? void 0 : { tenant: options.tenant }) };
35
+ }
36
+ function subjectView(permdock) {
37
+ const snapshot = permdock.snapshot();
38
+ return {
39
+ principal: permdock.subject.principal,
40
+ actor: permdock.subject.actor,
41
+ delegation: permdock.subject.delegation,
42
+ expiresAt: permdock.subject.expiresAt,
43
+ simulated: typeof snapshot === "object" && snapshot !== null && "simulated" in snapshot && snapshot.simulated === true
44
+ };
45
+ }
46
+ /** The root's view of another tenant for a `Protected` with a `tenant` prop; `undefined` answers the active one. */
47
+ function scopedTenant(root, tenant) {
48
+ return tenant === void 0 ? void 0 : root.tenant(tenant);
49
+ }
50
+ /** An instance whose every read answers from `current()`, so a held reference follows the store. */
51
+ function livePermDock(current) {
52
+ return new Proxy({}, { get(_target, prop, _receiver) {
53
+ return Reflect.get(current(), prop);
54
+ } });
55
+ }
56
+ /**
57
+ * `local` answers the active tenant; `scoped`, the root's view of another
58
+ * tenant, is decided on the spot and shares the root's `pending` and `stale`.
59
+ */
60
+ function protectedView(local, root, permission, data, scoped) {
61
+ const state = scoped === void 0 ? local : decideIn(root, scoped, permission, data);
62
+ if (state.status === "pending") return {
63
+ ...state,
64
+ slot: "pending"
65
+ };
66
+ const decision = state.decision;
67
+ if (!state.allowed || decision.outcome !== "granted") return {
68
+ ...state,
69
+ slot: "fallback"
70
+ };
71
+ return {
72
+ allowed: true,
73
+ status: state.status,
74
+ decision,
75
+ slot: "default"
76
+ };
77
+ }
78
+ function decideIn(root, scoped, permission, data) {
79
+ const decision = scoped.decide(permission, data);
80
+ const status = root.status();
81
+ return {
82
+ allowed: decision.outcome === "granted",
83
+ status: status === "pending" || status === "stale" ? status : "ready",
84
+ decision
85
+ };
86
+ }
87
+ function approvalHandle(store, decision) {
88
+ return {
89
+ state: store.approvalState(decision),
90
+ token: decision.outcome === "approval-required" ? decision.token : void 0,
91
+ request: (note) => store.requestApproval(decision, note)
92
+ };
93
+ }
94
+ //#endregion
95
+ export { protectedView as a, subjectView as c, permissionSet as i, tenantView as l, filterResult as n, rolesView as o, livePermDock as r, scopedTenant as s, approvalHandle as t };
@@ -0,0 +1,56 @@
1
+ import { n as ActionMeta } from "./permissions-DttnqqxC.js";
2
+ //#region src/core/vocabulary.d.ts
3
+ declare const ROLE_KIND: "role";
4
+ declare const PLAN_KIND: "plan";
5
+ /**
6
+ * A role's metadata. `audience` names the surface its holders use (`'staff'`,
7
+ * `'portal'`, `'platform'`); `permdock.audiences()` lists the distinct
8
+ * audiences of the roles held in the active scope.
9
+ */
10
+ type RoleMeta = ActionMeta & {
11
+ readonly audience?: string;
12
+ };
13
+ type Role<K extends string = string> = {
14
+ readonly key: K;
15
+ /** A declared scope name, or the `tenant` / `team` alias. */
16
+ readonly on?: string;
17
+ readonly assignable: boolean;
18
+ readonly meta: RoleMeta;
19
+ readonly kind: typeof ROLE_KIND;
20
+ };
21
+ type Plan<K extends string = string> = {
22
+ readonly key: K;
23
+ readonly meta: ActionMeta;
24
+ readonly kind: typeof PLAN_KIND;
25
+ };
26
+ type RoleInit = {
27
+ /** A declared scope name, or the `tenant` / `team` alias. */
28
+ readonly on?: string;
29
+ readonly assignable?: boolean;
30
+ readonly meta?: RoleMeta;
31
+ };
32
+ type PlanInit = {
33
+ readonly meta?: ActionMeta;
34
+ };
35
+ type RoleTree = {
36
+ readonly [key: string]: Role;
37
+ };
38
+ type PlanTree = {
39
+ readonly [key: string]: Plan;
40
+ };
41
+ type Vocabulary = {
42
+ readonly permissions?: unknown;
43
+ readonly roles?: RoleTree;
44
+ readonly plans?: PlanTree;
45
+ };
46
+ type InferRoleTree<Input> = { readonly [K in keyof Input & string]: Role<K>; };
47
+ type InferPlanTree<Input> = { readonly [K in keyof Input & string]: Plan<K>; };
48
+ declare function isRole(value: unknown): value is Role;
49
+ declare function isPlan(value: unknown): value is Plan;
50
+ declare function defineRoles<const Input extends Record<string, RoleInit>>(input: Input): InferRoleTree<Input>;
51
+ declare function definePlans<const Input extends Record<string, PlanInit>>(input: Input): InferPlanTree<Input>;
52
+ declare function listRoles(tree: RoleTree | undefined): readonly Role[];
53
+ declare function listPlans(tree: PlanTree | undefined): readonly Plan[];
54
+ declare function findRole(tree: RoleTree | undefined, key: string): Role | undefined;
55
+ //#endregion
56
+ export { RoleTree as a, defineRoles as c, isRole as d, listPlans as f, RoleMeta as i, findRole as l, PlanTree as n, Vocabulary as o, listRoles as p, Role as r, definePlans as s, Plan as t, isPlan as u };