permdock 0.0.0 → 0.1.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 (290) hide show
  1. package/README.md +268 -1
  2. package/dist/a2a/index.d.ts +178 -0
  3. package/dist/a2a/index.js +271 -0
  4. package/dist/ai-sdk/index.d.ts +74 -0
  5. package/dist/ai-sdk/index.js +137 -0
  6. package/dist/approval-required-TzNB9oQA.js +6 -0
  7. package/dist/approvals/index.d.ts +3 -0
  8. package/dist/approvals/index.js +4 -0
  9. package/dist/approvals-DaxY-Bdg.js +218 -0
  10. package/dist/approvers-aH0PJkmf.js +20 -0
  11. package/dist/arazzo-CTeVuXr5.js +70 -0
  12. package/dist/arazzo-aoTkqYsJ.js +54 -0
  13. package/dist/authzen/index.d.ts +48 -0
  14. package/dist/authzen/index.js +336 -0
  15. package/dist/better-auth/index.d.ts +92 -0
  16. package/dist/better-auth/index.js +324 -0
  17. package/dist/budget-JqcRqyhK.d.ts +11 -0
  18. package/dist/budget-NbEtbJC_.js +11 -0
  19. package/dist/capability-B68OFnZx.js +171 -0
  20. package/dist/capability-BDG_nkxt.d.ts +99 -0
  21. package/dist/catalog/index.d.ts +12 -0
  22. package/dist/catalog/index.js +2 -0
  23. package/dist/catalog-B0E6bggc.js +48 -0
  24. package/dist/catalog-H-vFGwWK.js +55 -0
  25. package/dist/catalog-doc-BSo_Q_-6.js +298 -0
  26. package/dist/catalog-idsHc0vo.js +2 -0
  27. package/dist/catalog-path-CnI0XTFK.js +12 -0
  28. package/dist/claude-agent/index.d.ts +81 -0
  29. package/dist/claude-agent/index.js +83 -0
  30. package/dist/clerk/index.d.ts +56 -0
  31. package/dist/clerk/index.js +280 -0
  32. package/dist/cli/bin.d.ts +1 -0
  33. package/dist/cli/bin.js +20 -0
  34. package/dist/cli/index.d.ts +46 -0
  35. package/dist/cli/index.js +5 -0
  36. package/dist/cloud/index.d.ts +91 -0
  37. package/dist/cloud/index.js +390 -0
  38. package/dist/cloud-BNQTrmrr.js +50 -0
  39. package/dist/cloud-Cuxr6Czw.js +117 -0
  40. package/dist/collect-B7_TIfmg.js +49 -0
  41. package/dist/collect-O-tOtbnk.js +350 -0
  42. package/dist/collect-fRPAQIWb.js +2 -0
  43. package/dist/commands-BMh_Etm2.js +93 -0
  44. package/dist/compact-y6vfu2_f.js +19 -0
  45. package/dist/compare-pfyVnBjE.js +12 -0
  46. package/dist/compile-CQbvyIBr.d.ts +30 -0
  47. package/dist/compile-D22iwvuV.js +558 -0
  48. package/dist/config-BPYmjTOp.js +26 -0
  49. package/dist/connection-JvqwHODC.js +194 -0
  50. package/dist/context-CKEAabd7.js +73 -0
  51. package/dist/context-gtAwAILx.js +6 -0
  52. package/dist/convex/index.d.ts +40 -0
  53. package/dist/convex/index.js +55 -0
  54. package/dist/create-BKF3dgFk.d.ts +162 -0
  55. package/dist/create-CSkhDU9T.js +222 -0
  56. package/dist/credential-B_rkUNlY.js +326 -0
  57. package/dist/credentials-BgRX3WEg.js +268 -0
  58. package/dist/describe-Bt1YD5uS.js +99 -0
  59. package/dist/describe-DernyItf.d.ts +37 -0
  60. package/dist/diff-BUzf5Poi.js +48 -0
  61. package/dist/diff-x5Il8LVa.js +418 -0
  62. package/dist/digest-B3kc_PgQ.d.ts +19 -0
  63. package/dist/digest-BI-6aa6d.js +27 -0
  64. package/dist/doctor-BGle8Gqi.js +1314 -0
  65. package/dist/doctor-Bqo6FwUa.js +53 -0
  66. package/dist/drizzle/index.d.ts +72 -0
  67. package/dist/drizzle/index.js +160 -0
  68. package/dist/duration-xK2jGFVc.js +25 -0
  69. package/dist/elysia/index.d.ts +71 -0
  70. package/dist/elysia/index.js +103 -0
  71. package/dist/errors-DSMnAVNa.js +43 -0
  72. package/dist/errors-DbZ1YOnb.d.ts +138 -0
  73. package/dist/errors-Iy71s7Oj.js +177 -0
  74. package/dist/errors-m3u9TmDu.js +27 -0
  75. package/dist/evaluations-DsAU9ppl.js +479 -0
  76. package/dist/eve/index.d.ts +95 -0
  77. package/dist/eve/index.js +181 -0
  78. package/dist/express/index.d.ts +46 -0
  79. package/dist/express/index.js +108 -0
  80. package/dist/fastify/index.d.ts +56 -0
  81. package/dist/fastify/index.js +141 -0
  82. package/dist/files-B_wAGYmt.js +121 -0
  83. package/dist/fixtures-Cvaw0gDG.js +64 -0
  84. package/dist/freeze-y1_jQL4v.js +31 -0
  85. package/dist/from-snapshot-BMGnhmgv.js +552 -0
  86. package/dist/generate-CH7ThJ14.js +173 -0
  87. package/dist/grantee-Bv04_Vzf.js +521 -0
  88. package/dist/headers-B5RRv3Xm.js +6 -0
  89. package/dist/headers-C8SHQccD.d.ts +6 -0
  90. package/dist/helpers-DnSOrhB9.js +682 -0
  91. package/dist/hono/index.d.ts +70 -0
  92. package/dist/hono/index.js +131 -0
  93. package/dist/hosted-BwKQ1BTA.js +265 -0
  94. package/dist/http-DPuDaChb.d.ts +13 -0
  95. package/dist/http-GgVApX1k.js +111 -0
  96. package/dist/index-CltcQ4Bf.d.ts +138 -0
  97. package/dist/index-LF_hS-yn.d.ts +177 -0
  98. package/dist/index-fG6NSXlc.d.ts +9 -0
  99. package/dist/index-xIxJLwOQ.d.ts +415 -0
  100. package/dist/index.d.ts +11 -0
  101. package/dist/index.js +21 -0
  102. package/dist/jwt/index.d.ts +87 -0
  103. package/dist/jwt/index.js +571 -0
  104. package/dist/kernel-YOGCWNLf.js +211 -0
  105. package/dist/kysely/index.d.ts +77 -0
  106. package/dist/kysely/index.js +129 -0
  107. package/dist/load-BZ24CpZP.js +69 -0
  108. package/dist/load-QOOm1z70.js +2 -0
  109. package/dist/load-jose-BL6LH4bL.js +11 -0
  110. package/dist/lru-8q4WZjBV.js +28 -0
  111. package/dist/manifest-DDQbC6K0.d.ts +118 -0
  112. package/dist/map-DowSO96j.js +158 -0
  113. package/dist/map-claims-B_6I1Rn-.js +360 -0
  114. package/dist/map-error-RJ3ZsUyA.js +16 -0
  115. package/dist/markers-B0hYLvMD.js +60 -0
  116. package/dist/may-use-CnFEjVEp.js +37 -0
  117. package/dist/mcp/index.d.ts +127 -0
  118. package/dist/mcp/index.js +563 -0
  119. package/dist/nest/index.d.ts +80 -0
  120. package/dist/nest/index.js +270 -0
  121. package/dist/next/client.d.ts +24 -0
  122. package/dist/next/client.js +31 -0
  123. package/dist/next/index.d.ts +110 -0
  124. package/dist/next/index.js +195 -0
  125. package/dist/next/plugin.d.ts +14 -0
  126. package/dist/next/plugin.js +2 -0
  127. package/dist/node/index.d.ts +43 -0
  128. package/dist/node/index.js +66 -0
  129. package/dist/openai/index.d.ts +71 -0
  130. package/dist/openai/index.js +105 -0
  131. package/dist/openapi/index.d.ts +93 -0
  132. package/dist/openapi/index.js +3 -0
  133. package/dist/openapi-CwePaF7C.js +164 -0
  134. package/dist/openapi-DWD0Uc_4.js +250 -0
  135. package/dist/openapi-DcqM8nU7.js +306 -0
  136. package/dist/openapi-import-BWRUNNeW.js +5959 -0
  137. package/dist/openapi-schema-D8j_T9tO.js +6902 -0
  138. package/dist/orpc/index.d.ts +64 -0
  139. package/dist/orpc/index.js +188 -0
  140. package/dist/otel/index.d.ts +13 -0
  141. package/dist/otel/index.js +202 -0
  142. package/dist/package-root-zGkxO3oN.js +30 -0
  143. package/dist/parse-DPfIvFMU.js +135 -0
  144. package/dist/pdp/index.d.ts +22 -0
  145. package/dist/pdp/index.js +795 -0
  146. package/dist/peer-BOr_kJE1.js +31 -0
  147. package/dist/permdock-yoZ7EjxX.js +2956 -0
  148. package/dist/permissions-B4apnahQ.d.ts +185 -0
  149. package/dist/permissions-B8vCg_bI.d.ts +52 -0
  150. package/dist/permissions-CofRqesP.js +142 -0
  151. package/dist/permissions-DC7GROPA.js +600 -0
  152. package/dist/pg-4GJWDUxG.js +953 -0
  153. package/dist/pins-CqE1jZuF.js +12 -0
  154. package/dist/plugin-4gr7IxFJ.js +65 -0
  155. package/dist/policy-ANp36PnI.js +971 -0
  156. package/dist/policy-CInmNGkM.d.ts +1959 -0
  157. package/dist/policy-Cq2fB8Q5.d.ts +20 -0
  158. package/dist/prisma/index.d.ts +135 -0
  159. package/dist/prisma/index.js +430 -0
  160. package/dist/problem-Cgp9-KZA.js +226 -0
  161. package/dist/prompt-CXYhLfsS.js +32 -0
  162. package/dist/protected-B4K3BKoX.js +138 -0
  163. package/dist/protected-BuPAycJT.d.ts +26 -0
  164. package/dist/protected-wY7nXhY9.d.ts +23 -0
  165. package/dist/provider-_wx46HpB.js +48 -0
  166. package/dist/provider-wTAUda2v.d.ts +6 -0
  167. package/dist/react/index.d.ts +6 -0
  168. package/dist/react/index.js +6 -0
  169. package/dist/react/provider-client.d.ts +2 -0
  170. package/dist/react/provider-client.js +3 -0
  171. package/dist/react-native/index.d.ts +42 -0
  172. package/dist/react-native/index.js +174 -0
  173. package/dist/refs-ChLSxbST.js +90 -0
  174. package/dist/relations-r4soIFZB.js +426 -0
  175. package/dist/revocations-Cy06JNx2.d.ts +21 -0
  176. package/dist/rls-BOFU3chG.js +233 -0
  177. package/dist/rls-CJVja9Ww.js +2119 -0
  178. package/dist/rls-graph-DxQ39PJj.js +371 -0
  179. package/dist/rls-helpers-BxRuif0l.js +1346 -0
  180. package/dist/rls-import-CXV6LBlS.js +942 -0
  181. package/dist/rls-migrate-DrFPbf8p.js +366 -0
  182. package/dist/row-check-BajTgQZ-.d.ts +43 -0
  183. package/dist/run-CJ6UvS3a.js +155 -0
  184. package/dist/runtime-DP9ttFh1.js +27 -0
  185. package/dist/saas-BRrZzJkM.js +1193 -0
  186. package/dist/schema-P8yoma__.js +296 -0
  187. package/dist/scim/index.d.ts +2 -0
  188. package/dist/scim/index.js +2 -0
  189. package/dist/scim-9NFa0XVZ.js +1445 -0
  190. package/dist/scopes-cKVp_WTw.js +212 -0
  191. package/dist/server/index.d.ts +123 -0
  192. package/dist/server/index.js +8 -0
  193. package/dist/sha256-BO0swRXL.js +150 -0
  194. package/dist/sink-Bd9PSyfq.js +141 -0
  195. package/dist/sink-Cfr9-7YC.d.ts +104 -0
  196. package/dist/skills-C_lpV4Jx.js +50 -0
  197. package/dist/skills-Dx3QLnMY.js +110 -0
  198. package/dist/snapshot-DE8dE_hz.js +1051 -0
  199. package/dist/solid/index.d.ts +63 -0
  200. package/dist/solid/index.js +197 -0
  201. package/dist/source-DoBBYJi2.js +6 -0
  202. package/dist/sources-DOpW5Ila.d.ts +347 -0
  203. package/dist/sources-DVHM3Mwq.js +284 -0
  204. package/dist/sql-Bll1d7y0.js +22 -0
  205. package/dist/src-CTNT-PBW.js +430 -0
  206. package/dist/ssf/index.d.ts +3 -0
  207. package/dist/ssf/index.js +622 -0
  208. package/dist/store-Bq90395i.d.ts +27 -0
  209. package/dist/store-C6hFW6ta.js +508 -0
  210. package/dist/stores-CkG2HrSg.js +140 -0
  211. package/dist/stores-CvOnu_2T.d.ts +41 -0
  212. package/dist/stream-BhMfZOwr.d.ts +12 -0
  213. package/dist/stream-Q_xlB6Ko.js +52 -0
  214. package/dist/style-CTm1AXDT.js +22 -0
  215. package/dist/subject-C6dLxqHU.js +24 -0
  216. package/dist/subject-settings-xt7V845g.js +82 -0
  217. package/dist/supabase/index.d.ts +67 -0
  218. package/dist/supabase/index.js +4 -0
  219. package/dist/supabase/middleware.d.ts +77 -0
  220. package/dist/supabase/middleware.js +68 -0
  221. package/dist/supabase-D8UlBA7Z.js +83 -0
  222. package/dist/supabase-DTxGtYdi.js +796 -0
  223. package/dist/supabase-hook-DW-xP4hU.js +2 -0
  224. package/dist/supabase-hook-D_OqGb_V.js +1528 -0
  225. package/dist/svelte/Protected.svelte +34 -0
  226. package/dist/svelte/index.d.ts +10 -0
  227. package/dist/svelte/index.js +53 -0
  228. package/dist/svelte/runtime.d.ts +6 -0
  229. package/dist/svelte/runtime.js +3 -0
  230. package/dist/svelte/source.d.ts +10 -0
  231. package/dist/svelte/source.js +8 -0
  232. package/dist/terminal/index.d.ts +171 -0
  233. package/dist/terminal/index.js +821 -0
  234. package/dist/testing/index.d.ts +656 -0
  235. package/dist/testing/index.js +3208 -0
  236. package/dist/testing/saas/index.d.ts +194 -0
  237. package/dist/testing/saas/index.js +3 -0
  238. package/dist/testing/saas/permissions.d.ts +2 -0
  239. package/dist/testing/saas/permissions.js +2 -0
  240. package/dist/text-diff-BdkkYSbi.js +15 -0
  241. package/dist/thenable-okc2xDsj.js +10 -0
  242. package/dist/timeout-D51niuQP.js +8 -0
  243. package/dist/trpc/index.d.ts +80 -0
  244. package/dist/trpc/index.js +205 -0
  245. package/dist/types-B8w5PFtS.d.ts +141 -0
  246. package/dist/types-B9dmiiab.d.ts +66 -0
  247. package/dist/types-BBK-exvJ.d.ts +177 -0
  248. package/dist/types-BvBk1wgn.d.ts +118 -0
  249. package/dist/types-CxquUByI.d.ts +9 -0
  250. package/dist/types-D6Z6-rKJ.d.ts +312 -0
  251. package/dist/types-DbWdEfcm.d.ts +87 -0
  252. package/dist/types-bva3i4Gf.d.ts +98 -0
  253. package/dist/types-i4BAOvdb.d.ts +97 -0
  254. package/dist/unplugin/index.d.ts +7 -0
  255. package/dist/unplugin/index.js +30 -0
  256. package/dist/usage-1ozMubLY.js +42 -0
  257. package/dist/usage-CUnK6Ou9.js +530 -0
  258. package/dist/usage-PyEor6GA.js +2 -0
  259. package/dist/validity-D0uRmJKJ.js +224 -0
  260. package/dist/verifier-B90agnhl.js +461 -0
  261. package/dist/version-CnSh33Fj.js +16 -0
  262. package/dist/vocabulary-Dk0fs-Jk.d.ts +56 -0
  263. package/dist/vue/index.d.ts +57 -0
  264. package/dist/vue/index.js +203 -0
  265. package/dist/webmcp/index.d.ts +75 -0
  266. package/dist/webmcp/index.js +313 -0
  267. package/package.json +423 -4
  268. package/rulesets/permdock.yaml +29 -0
  269. package/schemas/catalog-v1.json +507 -0
  270. package/schemas/openapi/oas-3.1.json +1298 -0
  271. package/schemas/openapi/oas-3.2.json +1516 -0
  272. package/schemas/openapi/overlay-1.1.json +79 -0
  273. package/schemas/supabase-claims-v1.json +139 -0
  274. package/schemas/supabase-manifest-v1.json +217 -0
  275. package/skills/permdock/SKILL.md +66 -0
  276. package/skills/permdock-agents/SKILL.md +77 -0
  277. package/skills/permdock-agents/references/runtimes.md +211 -0
  278. package/skills/permdock-approvals/SKILL.md +80 -0
  279. package/skills/permdock-approvals/references/stores-and-resume.md +83 -0
  280. package/skills/permdock-audit/SKILL.md +67 -0
  281. package/skills/permdock-credentials/SKILL.md +55 -0
  282. package/skills/permdock-credentials/references/tokens-keys-links.md +127 -0
  283. package/skills/permdock-data/SKILL.md +57 -0
  284. package/skills/permdock-data/references/queries-and-rls.md +54 -0
  285. package/skills/permdock-data/references/relationships.md +65 -0
  286. package/skills/permdock-tenancy/SKILL.md +77 -0
  287. package/skills/permdock-tenancy/references/ownership-and-custom-roles.md +83 -0
  288. package/skills/permdock-wire/SKILL.md +116 -0
  289. package/skills/permdock-wire/references/adapters.md +480 -0
  290. package/skills/permdock-wire/references/policy-options.md +43 -0
@@ -0,0 +1,622 @@
1
+ import { t as compact } from "../compact-y6vfu2_f.js";
2
+ import { t as cancelApprovals } from "../helpers-DnSOrhB9.js";
3
+ import { i as issuerFromDiscovery, t as joseTokenVerifier } from "../verifier-B90agnhl.js";
4
+ import { t as timeoutSignal } from "../timeout-D51niuQP.js";
5
+ //#region src/ssf/wire.ts
6
+ const SET_TYP = "secevent+jwt";
7
+ const LOGOUT_TYP = "logout+jwt";
8
+ function jsonResponse(status, body) {
9
+ return new Response(JSON.stringify(body), {
10
+ status,
11
+ headers: { "content-type": "application/json" }
12
+ });
13
+ }
14
+ function rfc8935(status, err, description) {
15
+ return jsonResponse(status, {
16
+ err,
17
+ description
18
+ });
19
+ }
20
+ function errForCause(cause) {
21
+ switch (cause) {
22
+ case "invalid-signature":
23
+ case "unknown-kid":
24
+ case "alg-not-allowed":
25
+ case "alg-none": return "invalid_key";
26
+ case "wrong-issuer": return "invalid_issuer";
27
+ case "wrong-audience": return "invalid_audience";
28
+ case "expired":
29
+ case "not-yet-valid":
30
+ case "wrong-token-type":
31
+ case "malformed":
32
+ case "encrypted-token":
33
+ case "dpop-proof-invalid":
34
+ case "mtls-binding-mismatch":
35
+ case "sender-constraint-required":
36
+ case "token-in-query":
37
+ case "invalid-claims":
38
+ case "invalid-chain":
39
+ case "jwks-unavailable":
40
+ case "discovery-unavailable":
41
+ case "discovery-mismatch": return "invalid_request";
42
+ default: return cause;
43
+ }
44
+ }
45
+ function isRecord(value) {
46
+ return value !== null && typeof value === "object" && !Array.isArray(value);
47
+ }
48
+ function contentType(request) {
49
+ return (request.headers.get("content-type") ?? "").split(";", 1)[0]?.trim().toLowerCase() ?? "";
50
+ }
51
+ function parseEvery(every) {
52
+ if (typeof every === "number") {
53
+ if (!Number.isFinite(every) || every <= 0) throw new TypeError("PermDock: poll every must be a positive interval.");
54
+ return every;
55
+ }
56
+ const match = /^(\d+)(ms|s|m)$/u.exec(every);
57
+ if (match?.[2] === void 0) throw new TypeError(`PermDock: invalid poll interval '${every}'.`);
58
+ const unit = match[2];
59
+ const scale = unit === "ms" ? 1 : unit === "s" ? 1e3 : 6e4;
60
+ return Number(match[1]) * scale;
61
+ }
62
+ //#endregion
63
+ //#region src/ssf/claims.ts
64
+ function asSubject(mapped, session, issuer) {
65
+ if (typeof mapped === "string") return compact({
66
+ id: mapped,
67
+ session,
68
+ issuer
69
+ });
70
+ return compact({
71
+ id: mapped.id,
72
+ session: mapped.session ?? session,
73
+ issuer: mapped.issuer ?? issuer
74
+ });
75
+ }
76
+ function setSubjectFromClaims(claims) {
77
+ const subId = claims["sub_id"];
78
+ if (isRecord(subId) && typeof subId["format"] === "string") return subId;
79
+ if (typeof claims.sub === "string" && claims.sub.length > 0) return compact({
80
+ format: "iss_sub",
81
+ iss: typeof claims.iss === "string" ? claims.iss : void 0,
82
+ sub: claims.sub
83
+ });
84
+ }
85
+ function eventTimestamp(payload) {
86
+ const value = payload["event_timestamp"];
87
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
88
+ }
89
+ function eventSession(payload) {
90
+ if (typeof payload["session"] === "string" && payload["session"].length > 0) return payload["session"];
91
+ if (typeof payload["sid"] === "string" && payload["sid"].length > 0) return payload["sid"];
92
+ }
93
+ /** CAEP drafts before SSF 1.0 put the subject in the event instead of `sub_id`. */
94
+ function eventSubject(payload) {
95
+ const subject = payload["subject"];
96
+ return isRecord(subject) && typeof subject["format"] === "string" ? subject : void 0;
97
+ }
98
+ function subjectSession(subject) {
99
+ if (subject.format !== "complex" || !isRecord(subject["session"])) return;
100
+ const { id } = subject["session"];
101
+ return typeof id === "string" && id.length > 0 ? id : void 0;
102
+ }
103
+ //#endregion
104
+ //#region src/ssf/events.ts
105
+ const BACKCHANNEL_LOGOUT_EVENT = "http://schemas.openid.net/event/backchannel-logout";
106
+ const CAEP_PREFIX = "https://schemas.openid.net/secevent/caep/event-type/";
107
+ const CAEP_NAMES = /* @__PURE__ */ new Set([
108
+ "session-revoked",
109
+ "credential-change",
110
+ "assurance-level-change",
111
+ "token-claims-change",
112
+ "device-compliance-change"
113
+ ]);
114
+ function caepName(uri) {
115
+ if (!uri.startsWith(CAEP_PREFIX)) return;
116
+ const name = uri.slice(52);
117
+ if (CAEP_NAMES.has(name)) return name;
118
+ }
119
+ //#endregion
120
+ //#region src/ssf/poll.ts
121
+ /** Milliseconds a poll or acknowledgement request may take. */
122
+ const POLL_TIMEOUT_MS = 3e4;
123
+ /**
124
+ * One RFC 8936 poll round: fetch the pending SETs, ingest them and acknowledge
125
+ * the ones that were accepted. Returns the acknowledged `jti` values.
126
+ */
127
+ async function pollOnce(input) {
128
+ const { options, acks, ingest, emit } = input;
129
+ const fetchFn = options.fetch ?? globalThis.fetch;
130
+ const headers = { "content-type": "application/json" };
131
+ if (options.token !== void 0) headers["authorization"] = `Bearer ${options.token}`;
132
+ const body = {
133
+ maxEvents: 100,
134
+ returnImmediately: true
135
+ };
136
+ if (acks.length > 0) body["acks"] = acks;
137
+ const requestInit = compact({
138
+ method: "POST",
139
+ headers,
140
+ body: JSON.stringify(body),
141
+ signal: timeoutSignal(POLL_TIMEOUT_MS, options.signal)
142
+ });
143
+ const response = await fetchFn(options.endpoint, requestInit);
144
+ if (!response.ok) {
145
+ emit({
146
+ type: "poll-failed",
147
+ err: "connection_failed"
148
+ });
149
+ return [];
150
+ }
151
+ const parsed = await response.json();
152
+ if (!isRecord(parsed) || !isRecord(parsed["sets"])) return [];
153
+ const tokens = Object.entries(parsed["sets"]).flatMap(([jti, jwt]) => typeof jwt === "string" ? [{
154
+ jti,
155
+ jwt
156
+ }] : []);
157
+ const outcomes = await Promise.all(tokens.map(async ({ jti, jwt }) => ({
158
+ jti,
159
+ result: await ingest(jwt)
160
+ })));
161
+ const processed = outcomes.flatMap((row) => row.result.ok ? [row.jti] : []);
162
+ const setErrs = {};
163
+ for (const { jti, result } of outcomes) if (!result.ok && result.cause !== void 0) setErrs[jti] = {
164
+ err: result.err,
165
+ description: result.description
166
+ };
167
+ const failed = Object.keys(setErrs).length;
168
+ if (processed.length > 0 || failed > 0) await fetchFn(options.endpoint, compact({
169
+ method: "POST",
170
+ headers,
171
+ body: JSON.stringify(compact({
172
+ acks: processed,
173
+ setErrs: failed > 0 ? setErrs : void 0,
174
+ maxEvents: 0,
175
+ returnImmediately: true
176
+ })),
177
+ signal: timeoutSignal(POLL_TIMEOUT_MS, options.signal)
178
+ }));
179
+ return processed;
180
+ }
181
+ //#endregion
182
+ //#region src/ssf/receiver.ts
183
+ const CHANGED_EVENTS = /* @__PURE__ */ new Set([
184
+ "credential-change",
185
+ "assurance-level-change",
186
+ "token-claims-change"
187
+ ]);
188
+ function replayExpiresAt(claims, clockTolerance = 0) {
189
+ if (typeof claims["exp"] === "number") return claims["exp"];
190
+ if (typeof claims["iat"] === "number") {
191
+ const until = claims["iat"] + clockTolerance;
192
+ return until > Date.now() / 1e3 ? until : void 0;
193
+ }
194
+ }
195
+ function replayKey(issuer, jti, event) {
196
+ return JSON.stringify(event === void 0 ? [issuer ?? null, jti] : [
197
+ issuer ?? null,
198
+ jti,
199
+ event
200
+ ]);
201
+ }
202
+ function createReceiver(config) {
203
+ const listeners = /* @__PURE__ */ new Set();
204
+ function emit(event) {
205
+ const next = compact(event);
206
+ for (const listener of listeners) listener(next);
207
+ }
208
+ async function verify(token, typ) {
209
+ const result = await config.verifier.verify(token, compact({
210
+ typ,
211
+ issuer: config.issuer,
212
+ audience: config.audience,
213
+ clockTolerance: config.clockTolerance
214
+ }));
215
+ if (!result.ok) return {
216
+ ok: false,
217
+ err: errForCause(result.cause),
218
+ description: result.cause,
219
+ cause: result.cause
220
+ };
221
+ if (typeof result.claims["jti"] !== "string" || result.claims["jti"].length === 0) return {
222
+ ok: false,
223
+ err: "invalid_request",
224
+ description: "missing jti",
225
+ cause: "invalid-claims"
226
+ };
227
+ if (typeof result.claims.iat !== "number") return {
228
+ ok: false,
229
+ err: "invalid_request",
230
+ description: "missing iat",
231
+ cause: "invalid-claims"
232
+ };
233
+ return result;
234
+ }
235
+ async function resolveSubject(setSubject, session, issuer) {
236
+ const mapped = await config.subject(setSubject, compact({
237
+ session,
238
+ issuer
239
+ }));
240
+ if (mapped === null || mapped === void 0) return;
241
+ if (typeof mapped === "string" && mapped.length === 0) return;
242
+ if (typeof mapped !== "string" && mapped.id.length === 0) return;
243
+ return asSubject(mapped, session, issuer);
244
+ }
245
+ const atomic = typeof config.replay.claim === "function" && typeof config.replay.release === "function";
246
+ /** `true` when this delivery owns the SET and should dispatch it. */
247
+ async function claimDelivery(key, expiresAt) {
248
+ if (atomic) return await config.replay.claim?.(key, expiresAt) === true;
249
+ return !await config.replay.seen(key);
250
+ }
251
+ async function settleDelivery(key, expiresAt, ok) {
252
+ if (atomic) {
253
+ if (!ok) await config.replay.release?.(key);
254
+ return;
255
+ }
256
+ if (ok) await config.replay.remember(key, expiresAt);
257
+ }
258
+ async function publishRevocation(input) {
259
+ const feed = config.revocations;
260
+ if (feed === void 0) return;
261
+ const kind = input.type === "session-revoked" ? "session-revoked" : CHANGED_EVENTS.has(input.type) ? "changed" : void 0;
262
+ if (kind === void 0) return;
263
+ try {
264
+ await feed.revoke(compact({
265
+ principal: input.subject.id,
266
+ session: kind === "session-revoked" ? input.subject.session : void 0,
267
+ kind
268
+ }));
269
+ } catch {}
270
+ }
271
+ async function cancelSessionApprovals(input) {
272
+ if (config.approvals === void 0 || input.type !== "session-revoked") return;
273
+ const count = await cancelApprovals(config.approvals, compact({
274
+ principalId: input.subject.id,
275
+ session: input.subject.session
276
+ }), {
277
+ by: "ssf",
278
+ note: input.jti
279
+ });
280
+ emit({
281
+ type: "approvals-cancelled",
282
+ subject: input.subject,
283
+ jti: input.jti,
284
+ cancelled: count
285
+ });
286
+ }
287
+ async function dispatch(type, input) {
288
+ const named = Object.hasOwn(config.onEvent, type) ? config.onEvent[type] : void 0;
289
+ const wildcard = config.onEvent["*"];
290
+ const handler = named ?? wildcard;
291
+ if (handler === void 0) {
292
+ emit({
293
+ type,
294
+ subject: input.subject,
295
+ transmitter: input.subject.issuer,
296
+ jti: input.jti,
297
+ unknown: "event"
298
+ });
299
+ await publishRevocation(input);
300
+ await cancelSessionApprovals(input);
301
+ return { ok: true };
302
+ }
303
+ try {
304
+ await handler(input);
305
+ } catch {
306
+ return {
307
+ ok: false,
308
+ err: "invalid_request",
309
+ description: "handler failed"
310
+ };
311
+ }
312
+ emit({
313
+ type,
314
+ subject: input.subject,
315
+ transmitter: input.subject.issuer,
316
+ jti: input.jti
317
+ });
318
+ await publishRevocation(input);
319
+ await cancelSessionApprovals(input);
320
+ return { ok: true };
321
+ }
322
+ async function dispatchEvents(entries, run) {
323
+ const [head, ...tail] = entries;
324
+ if (head === void 0) return { ok: true };
325
+ const { issuer, jti, baseSubject } = run;
326
+ const [uri, raw] = head;
327
+ const eventKey = replayKey(issuer, jti, uri);
328
+ if (run.perEvent && await config.replay.seen(eventKey)) return dispatchEvents(tail, run);
329
+ const payload = isRecord(raw) ? raw : {};
330
+ const type = caepName(uri) ?? uri;
331
+ if (caepName(uri) === void 0 && config.onEvent["*"] === void 0) {
332
+ emit({
333
+ type,
334
+ transmitter: issuer,
335
+ jti,
336
+ unknown: "event"
337
+ });
338
+ return dispatchEvents(tail, run);
339
+ }
340
+ const identifier = baseSubject ?? eventSubject(payload) ?? {
341
+ format: "opaque",
342
+ id: eventSession(payload) ?? jti
343
+ };
344
+ const subject = await resolveSubject(identifier, eventSession(payload) ?? subjectSession(identifier), issuer);
345
+ if (subject === void 0) {
346
+ emit({
347
+ type,
348
+ transmitter: issuer,
349
+ jti,
350
+ unknown: "subject"
351
+ });
352
+ return dispatchEvents(tail, run);
353
+ }
354
+ const result = await dispatch(type, compact({
355
+ subject,
356
+ event: payload,
357
+ event_timestamp: eventTimestamp(payload),
358
+ jti,
359
+ type
360
+ }));
361
+ if (!result.ok) return result;
362
+ if (run.perEvent) await config.replay.remember(eventKey, run.expiresAt);
363
+ return dispatchEvents(tail, run);
364
+ }
365
+ async function ingestSet(token) {
366
+ const verified = await verify(token, SET_TYP);
367
+ if (!verified.ok) {
368
+ emit({
369
+ type: "verification-failed",
370
+ err: verified.err,
371
+ cause: verified.cause
372
+ });
373
+ return verified;
374
+ }
375
+ const jti = verified.claims["jti"];
376
+ const issuer = typeof verified.claims.iss === "string" ? verified.claims.iss : void 0;
377
+ const events = verified.claims["events"];
378
+ if (!isRecord(events)) return {
379
+ ok: false,
380
+ err: "invalid_request",
381
+ description: "missing events",
382
+ cause: "invalid-claims"
383
+ };
384
+ const key = replayKey(issuer, jti);
385
+ const expiresAt = replayExpiresAt(verified.claims, config.clockTolerance);
386
+ if (!await claimDelivery(key, expiresAt)) {
387
+ emit({
388
+ type: "replay",
389
+ transmitter: issuer,
390
+ jti,
391
+ replayed: true
392
+ });
393
+ return { ok: true };
394
+ }
395
+ const entries = Object.entries(events);
396
+ let dispatched = {
397
+ ok: false,
398
+ err: "invalid_request",
399
+ description: "handler failed"
400
+ };
401
+ try {
402
+ dispatched = await dispatchEvents(entries, {
403
+ issuer,
404
+ jti,
405
+ baseSubject: setSubjectFromClaims(verified.claims),
406
+ expiresAt,
407
+ perEvent: entries.length > 1
408
+ });
409
+ } finally {
410
+ await settleDelivery(key, expiresAt, dispatched.ok);
411
+ }
412
+ return dispatched;
413
+ }
414
+ async function ingestLogout(token) {
415
+ const verified = await verify(token, LOGOUT_TYP);
416
+ if (!verified.ok) {
417
+ emit({
418
+ type: "verification-failed",
419
+ err: verified.err,
420
+ cause: verified.cause
421
+ });
422
+ return {
423
+ ok: false,
424
+ err: "invalid_request",
425
+ description: verified.description
426
+ };
427
+ }
428
+ if (verified.claims["nonce"] !== void 0) return {
429
+ ok: false,
430
+ err: "invalid_request",
431
+ description: "nonce must be absent",
432
+ cause: "invalid-claims"
433
+ };
434
+ const events = verified.claims["events"];
435
+ if (!isRecord(events) || !("http://schemas.openid.net/event/backchannel-logout" in events)) return {
436
+ ok: false,
437
+ err: "invalid_request",
438
+ description: "missing backchannel-logout event",
439
+ cause: "invalid-claims"
440
+ };
441
+ const sub = typeof verified.claims.sub === "string" ? verified.claims.sub : void 0;
442
+ const sid = typeof verified.claims["sid"] === "string" ? verified.claims["sid"] : void 0;
443
+ if ((sub === void 0 || sub.length === 0) && (sid === void 0 || sid.length === 0)) return {
444
+ ok: false,
445
+ err: "invalid_request",
446
+ description: "sub or sid required",
447
+ cause: "invalid-claims"
448
+ };
449
+ const jti = verified.claims["jti"];
450
+ const issuer = typeof verified.claims.iss === "string" ? verified.claims.iss : void 0;
451
+ const key = replayKey(issuer, jti);
452
+ const expiresAt = replayExpiresAt(verified.claims, config.clockTolerance);
453
+ if (!await claimDelivery(key, expiresAt)) {
454
+ emit({
455
+ type: "replay",
456
+ transmitter: issuer,
457
+ jti,
458
+ replayed: true
459
+ });
460
+ return { ok: true };
461
+ }
462
+ let dispatched = {
463
+ ok: false,
464
+ err: "invalid_request",
465
+ description: "handler failed"
466
+ };
467
+ try {
468
+ dispatched = await dispatchLogout(verified.claims, {
469
+ issuer,
470
+ jti,
471
+ sub,
472
+ sid
473
+ });
474
+ } finally {
475
+ await settleDelivery(key, expiresAt, dispatched.ok);
476
+ }
477
+ return dispatched;
478
+ }
479
+ async function dispatchLogout(claims, ids) {
480
+ const { issuer, jti, sub, sid } = ids;
481
+ const events = claims["events"];
482
+ const subject = await resolveSubject(sub === void 0 || sub.length === 0 ? compact({
483
+ format: "opaque",
484
+ id: sid
485
+ }) : compact({
486
+ format: "iss_sub",
487
+ iss: issuer,
488
+ sub
489
+ }), sid, issuer);
490
+ if (subject === void 0) {
491
+ emit({
492
+ type: "session-revoked",
493
+ transmitter: issuer,
494
+ jti,
495
+ unknown: "subject"
496
+ });
497
+ return { ok: true };
498
+ }
499
+ const payload = isRecord(events["http://schemas.openid.net/event/backchannel-logout"]) ? events[BACKCHANNEL_LOGOUT_EVENT] : {};
500
+ return dispatch("session-revoked", compact({
501
+ subject,
502
+ event: payload,
503
+ event_timestamp: eventTimestamp(payload),
504
+ jti,
505
+ type: "session-revoked"
506
+ }));
507
+ }
508
+ return {
509
+ async push(request) {
510
+ if (request.method !== "POST") return rfc8935(400, "invalid_request", "POST required");
511
+ if (contentType(request) !== "application/secevent+jwt") return rfc8935(400, "invalid_request", "application/secevent+jwt required");
512
+ const token = (await request.text()).trim();
513
+ if (token.length === 0) return rfc8935(400, "invalid_request", "empty body");
514
+ const result = await ingestSet(token);
515
+ if (!result.ok) return rfc8935(400, result.err, result.description);
516
+ return new Response(null, { status: 202 });
517
+ },
518
+ async logout(request) {
519
+ if (request.method !== "POST") return jsonResponse(400, { error: "invalid_request" });
520
+ if (contentType(request) !== "application/x-www-form-urlencoded") return jsonResponse(400, { error: "invalid_request" });
521
+ const token = new URLSearchParams(await request.text()).get("logout_token");
522
+ if (token === null || token.length === 0) return jsonResponse(400, { error: "invalid_request" });
523
+ if (!(await ingestLogout(token)).ok) return jsonResponse(400, { error: "invalid_request" });
524
+ return new Response(null, { status: 200 });
525
+ },
526
+ poll(options) {
527
+ if (options.every === void 0) return pollOnce({
528
+ options,
529
+ acks: [],
530
+ ingest: ingestSet,
531
+ emit
532
+ }).then((acked) => ({ acked }));
533
+ const ms = parseEvery(options.every);
534
+ let timer;
535
+ const tick = () => {
536
+ pollOnce({
537
+ options,
538
+ acks: [],
539
+ ingest: ingestSet,
540
+ emit
541
+ }).catch(() => {
542
+ emit({
543
+ type: "poll-failed",
544
+ err: "connection_failed"
545
+ });
546
+ });
547
+ };
548
+ tick();
549
+ timer = setInterval(tick, ms);
550
+ return { stop() {
551
+ if (timer !== void 0) {
552
+ clearInterval(timer);
553
+ timer = void 0;
554
+ }
555
+ } };
556
+ },
557
+ on(event, handler) {
558
+ if (event !== "event") return event;
559
+ listeners.add(handler);
560
+ return () => {
561
+ listeners.delete(handler);
562
+ };
563
+ }
564
+ };
565
+ }
566
+ //#endregion
567
+ //#region src/ssf/replay.ts
568
+ function memoryReplayStore() {
569
+ const seen = /* @__PURE__ */ new Map();
570
+ function evict(now = Date.now() / 1e3) {
571
+ for (const [jti, expiresAt] of seen) if (expiresAt !== void 0 && expiresAt <= now) seen.delete(jti);
572
+ }
573
+ return {
574
+ seen(jti) {
575
+ evict();
576
+ return seen.has(jti);
577
+ },
578
+ remember(jti, expiresAt) {
579
+ evict();
580
+ seen.set(jti, expiresAt);
581
+ },
582
+ claim(key, expiresAt) {
583
+ evict();
584
+ if (seen.has(key)) return false;
585
+ seen.set(key, expiresAt);
586
+ return true;
587
+ },
588
+ release(key) {
589
+ seen.delete(key);
590
+ }
591
+ };
592
+ }
593
+ //#endregion
594
+ //#region src/ssf/create.ts
595
+ function createPermDock(policy, options) {
596
+ if (typeof options.subject !== "function") throw new TypeError("PermDock: permdock/ssf requires subject.");
597
+ if (options.audience === void 0) throw new TypeError("PermDock: permdock/ssf requires audience.");
598
+ if (options.verifier === void 0 && options.jwks === void 0 && options.discovery === void 0) throw new TypeError("PermDock: permdock/ssf requires verifier, jwks, or discovery.");
599
+ if (options.issuer === void 0 && options.discovery === void 0) throw new TypeError("PermDock: permdock/ssf requires issuer or discovery.");
600
+ const issuer = options.issuer ?? (options.discovery === void 0 ? void 0 : issuerFromDiscovery(options.discovery));
601
+ const jwks = typeof options.jwks === "string" ? new URL(options.jwks) : options.jwks;
602
+ const verifier = options.verifier ?? joseTokenVerifier(compact({
603
+ jwks,
604
+ discovery: options.discovery,
605
+ issuer,
606
+ audience: options.audience,
607
+ clockTolerance: options.clockTolerance
608
+ }));
609
+ return { receiver: createReceiver(compact({
610
+ verifier,
611
+ issuer,
612
+ audience: options.audience,
613
+ subject: options.subject,
614
+ onEvent: options.onEvent ?? {},
615
+ replay: options.replay ?? memoryReplayStore(),
616
+ approvals: options.approvals,
617
+ revocations: options.revocations,
618
+ clockTolerance: options.clockTolerance
619
+ })) };
620
+ }
621
+ //#endregion
622
+ export { createPermDock, memoryReplayStore };
@@ -0,0 +1,27 @@
1
+ import { Mn as Decision, gt as Snapshot } from "./policy-CInmNGkM.js";
2
+ import { d as Permission } from "./permissions-B4apnahQ.js";
3
+ import { c as PermissionState, n as ApprovalState, r as ClientPermDock } from "./types-DbWdEfcm.js";
4
+ //#region src/react/store.d.ts
5
+ type ClientStore = {
6
+ get(): ClientPermDock;
7
+ subscribe(listener: () => void): () => void;
8
+ permissionState(permission: Permission, data?: unknown): PermissionState;
9
+ requestApproval(decision: Decision, note?: string): Promise<void>;
10
+ /** Hydrate from a pushed snapshot; a compact JWS goes through the verifier. */
11
+ replace(value: unknown): void;
12
+ /** Stay `pending` until `value` settles, then hydrate; a rejection fails closed. */
13
+ follow(value: PromiseLike<Snapshot | string>): void;
14
+ /**
15
+ * The approval state for a decision. While something subscribes, an
16
+ * `approval-required` decision is polled at `<approvals>/<token>`.
17
+ */
18
+ approvalState(decision: Decision): ApprovalState;
19
+ /**
20
+ * Hydrate from a resolved `snapshotPromise` during render. Idempotent per `source`;
21
+ * subscribers are notified in a microtask, never synchronously inside render.
22
+ */
23
+ adopt(value: Snapshot | string, source: object): void;
24
+ snapshot(): Snapshot;
25
+ };
26
+ //#endregion
27
+ export { ClientStore as t };