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,212 @@
1
+ import { S as isForbiddenKey } from "./permissions-DC7GROPA.js";
2
+ //#region src/core/scopes.ts
3
+ const RESERVED = /* @__PURE__ */ new Set(["global", "resource"]);
4
+ const NAME = /^[a-z][a-z0-9_]*$/u;
5
+ /** A policy without `scopes` keeps the historical pair: `tenant`, and `team` inside it. */
6
+ const IMPLICIT = Object.freeze([Object.freeze({ name: "tenant" }), Object.freeze({
7
+ name: "team",
8
+ within: "tenant"
9
+ })]);
10
+ function fail(message) {
11
+ throw new Error(`PermDock: ${message}`);
12
+ }
13
+ /**
14
+ * Validates `definePolicy({ scopes })`. Declaration order is the scope order;
15
+ * every scope after the first names an earlier one in `within`, so the scopes
16
+ * form one tree rooted at the first and have no cycles.
17
+ * A scope named `tenant` is the first and `team` the second, so the aliases
18
+ * never point at two different scopes.
19
+ */
20
+ function defineScopes(input) {
21
+ if (input === void 0) return Object.freeze([]);
22
+ if (input === null || typeof input !== "object" || Array.isArray(input)) fail("definePolicy({ scopes }) must be an object");
23
+ const out = [];
24
+ const seen = /* @__PURE__ */ new Set();
25
+ for (const name of Object.keys(input)) {
26
+ if (isForbiddenKey(name) || RESERVED.has(name) || !NAME.test(name)) fail(`scope name '${name}' must be lower snake case and not global or resource`);
27
+ const declaration = input[name];
28
+ if (declaration === void 0 || declaration === null || typeof declaration !== "object" || typeof declaration.key !== "string" || declaration.key === "") fail(`scopes.${name} needs a key`);
29
+ const index = out.length;
30
+ if (name === "tenant" && index !== 0) fail("scope 'tenant' must be declared first");
31
+ if (name === "team" && index !== 1) fail("scope 'team' must be declared second");
32
+ const within = declaration.within;
33
+ if (within !== void 0 && !seen.has(within)) fail(`scopes.${name}.within names '${within}', which is not declared before it`);
34
+ if (name === "team" && within === void 0 && seen.has("tenant")) fail("scopes.team needs within: 'tenant'");
35
+ if (index > 0 && within === void 0) fail(`scopes.${name} needs within: every scope after the first sits inside an earlier one`);
36
+ seen.add(name);
37
+ out.push(Object.freeze(within === void 0 ? {
38
+ name,
39
+ key: declaration.key
40
+ } : {
41
+ name,
42
+ key: declaration.key,
43
+ within
44
+ }));
45
+ }
46
+ return Object.freeze(out);
47
+ }
48
+ /** The scopes a policy or snapshot evaluates with: the declared list, or the implicit pair. */
49
+ function scopeList(declared) {
50
+ return declared === void 0 || declared.length === 0 ? IMPLICIT : declared;
51
+ }
52
+ /** A declared name, or an alias: `tenant` is the first scope, `team` the second. */
53
+ function resolveScope(scopes, name) {
54
+ if (typeof name !== "string") return;
55
+ if (scopes.some((scope) => scope.name === name)) return name;
56
+ if (name === "tenant") return scopes[0]?.name;
57
+ if (name === "team") return scopes[1]?.name;
58
+ }
59
+ function findScope(scopes, name) {
60
+ return scopes.find((scope) => scope.name === name);
61
+ }
62
+ /** `name` and its ancestors, innermost first. */
63
+ function scopeChain(scopes, name) {
64
+ const chain = [];
65
+ let current = findScope(scopes, name);
66
+ while (current !== void 0 && !chain.includes(current.name)) {
67
+ chain.push(current.name);
68
+ current = current.within === void 0 ? void 0 : findScope(scopes, current.within);
69
+ }
70
+ return chain;
71
+ }
72
+ /** The scope the active tenant selects an instance of: the first declared one. */
73
+ function rootScope(scopes) {
74
+ return scopes[0]?.name;
75
+ }
76
+ /** The id a membership holds for `scope`: its own id, or the `within` entry of an ancestor. */
77
+ function scopeIdOf(membership, scope) {
78
+ if (membership.scope === scope) return membership.id;
79
+ const within = membership.within;
80
+ if (within === void 0 || !Object.hasOwn(within, scope)) return;
81
+ return within[scope];
82
+ }
83
+ /**
84
+ * A membership of the first scope itself (the only scope without a parent):
85
+ * its id is a tenant. Needs no scope list, for code that holds only a subject.
86
+ */
87
+ function rootMembershipId(membership) {
88
+ if (membership.scope !== void 0) return membership.within === void 0 ? membership.id : void 0;
89
+ return membership.team === void 0 ? membership.tenant : void 0;
90
+ }
91
+ /** The instance of the first scope a membership sits in; what the active tenant selects. */
92
+ function tenantOf(membership, scopes) {
93
+ const root = rootScope(scopes);
94
+ return root === void 0 ? void 0 : scopeIdOf(membership, root);
95
+ }
96
+ function isId(value) {
97
+ return typeof value === "string" && value !== "";
98
+ }
99
+ function roleList(value) {
100
+ if (!Array.isArray(value)) return;
101
+ return value.filter((item) => typeof item === "string");
102
+ }
103
+ /**
104
+ * The canonical form of one membership, or `undefined` when it is malformed
105
+ * (fail-closed: it grants nothing). A named membership is
106
+ * `{ scope, id, within }` with one `within` entry per ancestor of `scope`;
107
+ * the `tenant` / `team` input shape and alias names normalise to it. A
108
+ * resource membership keeps `on`. Shapes are exclusive.
109
+ */
110
+ function normalizeMembership(input, scopes) {
111
+ if (input === null || typeof input !== "object" || Array.isArray(input)) return;
112
+ const raw = input;
113
+ const roles = roleList(raw["roles"]);
114
+ if (roles === void 0) return;
115
+ const extra = {};
116
+ if (typeof raw["via"] === "string") extra.via = raw["via"];
117
+ if (typeof raw["expiresAt"] === "number") extra.expiresAt = raw["expiresAt"];
118
+ if (typeof raw["grantedBy"] === "string" && raw["grantedBy"] !== "") extra.grantedBy = raw["grantedBy"];
119
+ if (typeof raw["reason"] === "string" && raw["reason"] !== "") extra.reason = raw["reason"];
120
+ const eligible = roleList(raw["eligible"]);
121
+ if (eligible !== void 0 && eligible.length > 0) extra.eligible = Object.freeze([...eligible]);
122
+ const member = raw["member"] !== null && typeof raw["member"] === "object" && !Array.isArray(raw["member"]) ? raw["member"]["group"] : void 0;
123
+ if (typeof member === "string" && member !== "") extra.member = Object.freeze({ group: member });
124
+ if (raw["managedBy"] === "idp") extra.managedBy = "idp";
125
+ if (Array.isArray(raw["entitlements"])) {
126
+ const seats = raw["entitlements"].filter((item) => typeof item === "string" && item !== "");
127
+ if (seats.length > 0) extra.entitlements = Object.freeze(seats);
128
+ }
129
+ const named = raw["scope"] !== void 0 || raw["id"] !== void 0;
130
+ const legacy = raw["tenant"] !== void 0 || raw["team"] !== void 0;
131
+ const on = raw["on"];
132
+ if (on !== void 0) {
133
+ if (named || legacy || on === null || typeof on !== "object") return;
134
+ const target = on;
135
+ if (!isId(target["resource"]) || !isId(target["id"])) return;
136
+ return Object.freeze({
137
+ on: Object.freeze({
138
+ resource: target["resource"],
139
+ id: target["id"]
140
+ }),
141
+ roles: Object.freeze([...roles]),
142
+ ...extra
143
+ });
144
+ }
145
+ let scope;
146
+ let id;
147
+ let within = {};
148
+ if (named) {
149
+ if (legacy) return;
150
+ scope = resolveScope(scopes, raw["scope"]);
151
+ id = raw["id"];
152
+ if (raw["within"] !== void 0) {
153
+ if (raw["within"] === null || typeof raw["within"] !== "object" || Array.isArray(raw["within"])) return;
154
+ within = raw["within"];
155
+ }
156
+ } else if (raw["team"] !== void 0) {
157
+ scope = resolveScope(scopes, "team");
158
+ id = raw["team"];
159
+ const parent = resolveScope(scopes, "tenant");
160
+ if (raw["tenant"] !== void 0 && parent !== void 0) within = { [parent]: raw["tenant"] };
161
+ } else if (raw["tenant"] === void 0) return;
162
+ else {
163
+ scope = resolveScope(scopes, "tenant");
164
+ id = raw["tenant"];
165
+ }
166
+ if (scope === void 0 || !isId(id)) return;
167
+ const ancestors = scopeChain(scopes, scope).slice(1);
168
+ const resolved = {};
169
+ for (const key of Object.keys(within)) {
170
+ if (isForbiddenKey(key)) return;
171
+ const name = resolveScope(scopes, key);
172
+ const value = within[key];
173
+ if (name !== void 0 && ancestors.includes(name) && isId(value)) resolved[name] = value;
174
+ }
175
+ if (ancestors.some((name) => resolved[name] === void 0)) return;
176
+ return Object.freeze({
177
+ scope,
178
+ id,
179
+ ...ancestors.length === 0 ? {} : { within: Object.freeze(resolved) },
180
+ roles: Object.freeze([...roles]),
181
+ ...extra
182
+ });
183
+ }
184
+ function normalizeMemberships(input, scopes) {
185
+ if (!Array.isArray(input)) return [];
186
+ const out = [];
187
+ for (const item of input) {
188
+ const membership = normalizeMembership(item, scopes);
189
+ if (membership !== void 0) out.push(membership);
190
+ }
191
+ return out;
192
+ }
193
+ /**
194
+ * A subject's memberships in canonical form. Resolved subjects already are;
195
+ * this accepts a hand-built subject passed straight to a condition evaluator
196
+ * or compiler.
197
+ */
198
+ function subjectMemberships(memberships, scopes) {
199
+ const list = memberships ?? [];
200
+ return list.some((membership) => membership.tenant !== void 0 || membership.team !== void 0) ? normalizeMemberships(list, scopes) : list;
201
+ }
202
+ /**
203
+ * Whether a named membership applies under the active tenant: a membership
204
+ * whose chain includes the first scope counts only inside the active tenant.
205
+ */
206
+ function activeFor(membership, scopes, active) {
207
+ const root = rootScope(scopes);
208
+ if (root === void 0 || membership.scope === void 0 || !scopeChain(scopes, membership.scope).includes(root)) return true;
209
+ return active !== void 0 && scopeIdOf(membership, root) === active;
210
+ }
211
+ //#endregion
212
+ export { resolveScope as a, scopeChain as c, subjectMemberships as d, tenantOf as f, normalizeMemberships as i, scopeIdOf as l, defineScopes as n, rootMembershipId as o, findScope as r, rootScope as s, activeFor as t, scopeList as u };
@@ -0,0 +1,123 @@
1
+ import { $ as DecisionSink, Ft as Credential, Ht as CredentialPrincipal, J as AuthEvent, Mn as Decision, St as SubjectResolver, X as CredentialVerifier, hr as Subject, mr as Principal, mt as SettingsSource } from "../policy-CInmNGkM.js";
2
+ import { d as Permission, p as PermissionTree } from "../permissions-B4apnahQ.js";
3
+ import { a as PermDockValidationError, i as PermDockRevokedError, n as PermDockApprovalRequiredError, o as ProblemDetails, r as PermDockDeniedError, t as ApprovalHint } from "../errors-DbZ1YOnb.js";
4
+ import { i as memoryRevocationFeed, n as RevocationFeed, t as RevocationEvent } from "../revocations-Cy06JNx2.js";
5
+ import { S as ConnectionOptions, _ as invalidSignatureProblem, a as ServerPermDockOptions, b as Connection, c as createEvaluationsHandler, d as WebBotAuthJwk, f as WebBotAuthKeyLookup, g as discoverViaSignatureAgent, h as WebBotAuthVerifier, i as ServerPermDock, l as DiscoverViaSignatureAgentOptions, m as WebBotAuthOptions, n as OpenApiHooks, p as WebBotAuthKeys, r as ProtectOptions, s as createPermDock, t as Guard, u as InvalidSignatureError, v as invalidSignatureResponse, x as ConnectionData, y as verifyWebBotAuth } from "../create-BKF3dgFk.js";
6
+ //#region src/server/credentials.d.ts
7
+ /** `on('auth')` causes for an API key that resolves to the anonymous subject. */
8
+ type ApiKeyFailureCause = "malformed" | "unknown-credential" | "invalid-claims" | "expired" | "credential-policy" | "credential-revoked" | "owner-unavailable";
9
+ /** An opaque key split at its last `_`: `pdk_<id>_<secret><checksum>`. */
10
+ type ApiKeyParts = {
11
+ readonly id: string;
12
+ readonly secret: string;
13
+ };
14
+ /** What an application stores per key: the credential and the key's hash, never the key. */
15
+ type StoredCredential = {
16
+ readonly credential: Credential;
17
+ readonly hash: string;
18
+ };
19
+ /**
20
+ * Splits `pdk_<id>_<secret><checksum>`: `id` is 1 to 128 of `A-Z a-z 0-9 _ -`,
21
+ * the secret 43 base62 characters and the checksum the 6 base62 characters of
22
+ * the CRC-32 of everything before it. Anything else, including a checksum
23
+ * that does not match, is `undefined`.
24
+ */
25
+ export declare function parseApiKey(key: unknown): ApiKeyParts | undefined;
26
+ /**
27
+ * A fresh `pdk_<id>_<secret><checksum>`: a 43-character base62 secret (about
28
+ * 256 bits) and a 6-character CRC-32 checksum, so a secret scanner can tell a
29
+ * real key from a lookalike without calling the issuer.
30
+ */
31
+ export declare function generateApiKey(id: string): string;
32
+ /** base64url SHA-256 of the whole key, the value to store and compare. */
33
+ export declare function hashApiKey(key: string): Promise<string>;
34
+ /**
35
+ * A `CredentialVerifier` over the application's own table: `find` looks a
36
+ * key up by the id in it, and the key's hash is compared in constant time.
37
+ * A record that is not a valid v1 credential, or whose id is not the key's,
38
+ * verifies to `null`. A throwing `find` propagates, so the resolver denies
39
+ * with `source-threw`.
40
+ */
41
+ export declare function apiKeyVerifier(options: {
42
+ readonly find: (id: string) => StoredCredential | null | undefined | Promise<StoredCredential | null | undefined>;
43
+ /** Passed through as the verifier's `touch`, for a `lastUsedAt` column. */
44
+ readonly touch?: CredentialVerifier["touch"];
45
+ }): CredentialVerifier;
46
+ type MemoryCredentials = CredentialVerifier & {
47
+ /** Stores `credential` and returns its key; the key is never stored. */
48
+ issue(credential: Credential): Promise<string>;
49
+ /** A new secret for the same id; the old key stops verifying at once. */
50
+ rotate(id: string): Promise<string | undefined>;
51
+ /** `true` when a credential was removed. */
52
+ revoke(id: string): boolean;
53
+ list(): readonly Credential[];
54
+ /** When `touch` last recorded a use of `id`, in Unix seconds. */
55
+ lastUsedAt(id: string): number | undefined;
56
+ };
57
+ /**
58
+ * In-process credentials for tests and single-replica apps. `issue`, `rotate`
59
+ * and `revoke` write `credential` events to `sink` when one is given.
60
+ */
61
+ export declare function memoryCredentials(options?: {
62
+ readonly sink?: DecisionSink;
63
+ readonly source?: string;
64
+ }): MemoryCredentials;
65
+ type ApiKeySubjectOptions = {
66
+ readonly verifier: CredentialVerifier;
67
+ /** The definitions, to turn the credential's permission keys into its delegation. */
68
+ readonly permissions: PermissionTree;
69
+ /**
70
+ * The live owner of a user-bound key: roles and memberships as of this
71
+ * request. `null` (a deleted or suspended user) is anonymous. Without it
72
+ * the owner is `{ id, kind: 'user' }` and its rights come from the
73
+ * `memberships` source passed to `createPermDock`.
74
+ */
75
+ readonly owner?: (id: string) => Principal | null | undefined | Promise<Principal | null | undefined>;
76
+ /** `true` when the application revoked the credential id; a throw denies. */
77
+ readonly revoked?: (id: string) => boolean | Promise<boolean>;
78
+ /**
79
+ * The tenant `credentials` policy, checked on every use so a tightened
80
+ * policy reaches existing keys: a service key's own tenant, a user key's
81
+ * the `tenant` the resolver is called with. A throw denies.
82
+ */
83
+ readonly settings?: SettingsSource;
84
+ /** Receives a `credential` event with operation `used` for sampled uses. */
85
+ readonly sink?: DecisionSink;
86
+ /** Fraction of uses reported to `sink`, in `(0, 1]`; defaults to 1. */
87
+ readonly sample?: number;
88
+ /** The `source` of `used` events; defaults to `permdock`. */
89
+ readonly source?: string;
90
+ readonly onAuth?: (event: AuthEvent) => void;
91
+ readonly requestId?: string;
92
+ };
93
+ /**
94
+ * A `SubjectResolver` for opaque API keys (`pdk_<id>_<secret>`): each call
95
+ * resolves a key into the subject its credential acts as. Every failure (a
96
+ * malformed or unknown key, a record that is not a valid credential, expiry,
97
+ * a tenant policy the key breaks, a revoked id, a missing owner, a throwing
98
+ * verifier or callback) is the anonymous subject, never a throw.
99
+ */
100
+ export declare function subjectFromApiKey(options: ApiKeySubjectOptions): SubjectResolver<string | undefined | null, CredentialPrincipal>;
101
+ //#endregion
102
+ //#region src/server/map-error.d.ts
103
+ /**
104
+ * Turns a thrown PermDock error into its Problem Details response. Returns
105
+ * `undefined` for anything else so the framework's own error path takes over.
106
+ */
107
+ export declare function problemFromError(error: unknown): Response | undefined;
108
+ //#endregion
109
+ //#region src/server/problem.d.ts
110
+ export declare const PROBLEM_BASE = "https://permdock.dev/problems";
111
+ export declare function wwwAuthenticate(decision: Decision, permission: Permission | undefined, credentials?: boolean): string | undefined;
112
+ export declare function problemResponse(details: ProblemDetails, permission?: Permission, decision?: Decision, extra?: Readonly<Record<string, string>>, credentials?: boolean): Response;
113
+ export declare function validationProblem(detail: string): Response;
114
+ export declare function problemFromDecision(decision: Decision, permission: Permission, subject: Subject, options?: {
115
+ readonly instance?: string;
116
+ readonly approval?: ApprovalHint;
117
+ /** `'hide'` on a loaded row: a denial answers as `404` `/not-found`. */
118
+ readonly disclosure?: "hide" | "reveal";
119
+ /** Whether the request carried credentials, which picks the `401` challenge. */
120
+ readonly credentials?: boolean;
121
+ }): Response;
122
+ //#endregion
123
+ export { type ApiKeyFailureCause, type ApiKeyParts, type ApiKeySubjectOptions, type ApprovalHint, type Connection, type ConnectionData, type ConnectionOptions, type DiscoverViaSignatureAgentOptions, type Guard, InvalidSignatureError, type MemoryCredentials, type OpenApiHooks, PermDockApprovalRequiredError, PermDockDeniedError, PermDockRevokedError, PermDockValidationError, type ProtectOptions, type RevocationEvent, type RevocationFeed, type ServerPermDock, type ServerPermDockOptions, type StoredCredential, type WebBotAuthJwk, type WebBotAuthKeyLookup, type WebBotAuthKeys, type WebBotAuthOptions, type WebBotAuthVerifier, createEvaluationsHandler, createPermDock, discoverViaSignatureAgent, invalidSignatureProblem, invalidSignatureResponse, memoryRevocationFeed, verifyWebBotAuth };
@@ -0,0 +1,8 @@
1
+ import { i as PermDockValidationError, n as PermDockDeniedError, r as PermDockRevokedError, t as PermDockApprovalRequiredError } from "../errors-Iy71s7Oj.js";
2
+ import { s as memoryRevocationFeed } from "../credential-B_rkUNlY.js";
3
+ import { a as problemFromDecision, l as validationProblem, o as problemResponse, t as PROBLEM_BASE, u as wwwAuthenticate } from "../problem-Cgp9-KZA.js";
4
+ import { a as invalidSignatureProblem, i as discoverViaSignatureAgent, n as createEvaluationsHandler, o as invalidSignatureResponse, r as InvalidSignatureError, s as verifyWebBotAuth } from "../evaluations-DsAU9ppl.js";
5
+ import { n as createPermDock } from "../create-CSkhDU9T.js";
6
+ import { a as parseApiKey, i as memoryCredentials, n as generateApiKey, o as subjectFromApiKey, r as hashApiKey, t as apiKeyVerifier } from "../credentials-BgRX3WEg.js";
7
+ import { t as problemFromError } from "../map-error-RJ3ZsUyA.js";
8
+ export { InvalidSignatureError, PROBLEM_BASE, PermDockApprovalRequiredError, PermDockDeniedError, PermDockRevokedError, PermDockValidationError, apiKeyVerifier, createEvaluationsHandler, createPermDock, discoverViaSignatureAgent, generateApiKey, hashApiKey, invalidSignatureProblem, invalidSignatureResponse, memoryCredentials, memoryRevocationFeed, parseApiKey, problemFromDecision, problemFromError, problemResponse, subjectFromApiKey, validationProblem, verifyWebBotAuth, wwwAuthenticate };
@@ -0,0 +1,150 @@
1
+ //#region src/core/sha256.ts
2
+ const K = [
3
+ 1116352408,
4
+ 1899447441,
5
+ 3049323471,
6
+ 3921009573,
7
+ 961987163,
8
+ 1508970993,
9
+ 2453635748,
10
+ 2870763221,
11
+ 3624381080,
12
+ 310598401,
13
+ 607225278,
14
+ 1426881987,
15
+ 1925078388,
16
+ 2162078206,
17
+ 2614888103,
18
+ 3248222580,
19
+ 3835390401,
20
+ 4022224774,
21
+ 264347078,
22
+ 604807628,
23
+ 770255983,
24
+ 1249150122,
25
+ 1555081692,
26
+ 1996064986,
27
+ 2554220882,
28
+ 2821834349,
29
+ 2952996808,
30
+ 3210313671,
31
+ 3336571891,
32
+ 3584528711,
33
+ 113926993,
34
+ 338241895,
35
+ 666307205,
36
+ 773529912,
37
+ 1294757372,
38
+ 1396182291,
39
+ 1695183700,
40
+ 1986661051,
41
+ 2177026350,
42
+ 2456956037,
43
+ 2730485921,
44
+ 2820302411,
45
+ 3259730800,
46
+ 3345764771,
47
+ 3516065817,
48
+ 3600352804,
49
+ 4094571909,
50
+ 275423344,
51
+ 430227734,
52
+ 506948616,
53
+ 659060556,
54
+ 883997877,
55
+ 958139571,
56
+ 1322822218,
57
+ 1537002063,
58
+ 1747873779,
59
+ 1955562222,
60
+ 2024104815,
61
+ 2227730452,
62
+ 2361852424,
63
+ 2428436474,
64
+ 2756734187,
65
+ 3204031479,
66
+ 3329325298
67
+ ];
68
+ function rotr(value, bits) {
69
+ return value >>> bits | value << 32 - bits;
70
+ }
71
+ /**
72
+ * SHA-256 of UTF-8 text. Pure JS so `decide` stays synchronous and WinterTC-safe.
73
+ */
74
+ function sha256(message) {
75
+ const bytes = new TextEncoder().encode(message);
76
+ const bitLength = bytes.length * 8;
77
+ const paddedLength = bytes.length + 9 + 63 >> 6 << 6;
78
+ const padded = new Uint8Array(paddedLength);
79
+ padded.set(bytes);
80
+ padded[bytes.length] = 128;
81
+ const view = new DataView(padded.buffer);
82
+ view.setUint32(paddedLength - 4, bitLength, false);
83
+ let h0 = 1779033703;
84
+ let h1 = 3144134277;
85
+ let h2 = 1013904242;
86
+ let h3 = 2773480762;
87
+ let h4 = 1359893119;
88
+ let h5 = 2600822924;
89
+ let h6 = 528734635;
90
+ let h7 = 1541459225;
91
+ const w = /* @__PURE__ */ new Int32Array(64);
92
+ for (let offset = 0; offset < paddedLength; offset += 64) {
93
+ for (let i = 0; i < 16; i += 1) w[i] = view.getInt32(offset + i * 4, false);
94
+ for (let i = 16; i < 64; i += 1) {
95
+ const w15 = w[i - 15] ?? 0;
96
+ const w2 = w[i - 2] ?? 0;
97
+ const s0 = rotr(w15, 7) ^ rotr(w15, 18) ^ w15 >>> 3;
98
+ const s1 = rotr(w2, 17) ^ rotr(w2, 19) ^ w2 >>> 10;
99
+ w[i] = (w[i - 16] ?? 0) + s0 + (w[i - 7] ?? 0) + s1 | 0;
100
+ }
101
+ let a = h0;
102
+ let b = h1;
103
+ let c = h2;
104
+ let d = h3;
105
+ let e = h4;
106
+ let f = h5;
107
+ let g = h6;
108
+ let h = h7;
109
+ for (let i = 0; i < 64; i += 1) {
110
+ const S1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25);
111
+ const ch = e & f ^ ~e & g;
112
+ const temp1 = h + S1 + ch + (K[i] ?? 0) + (w[i] ?? 0) | 0;
113
+ const temp2 = (rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22)) + (a & b ^ a & c ^ b & c) | 0;
114
+ h = g;
115
+ g = f;
116
+ f = e;
117
+ e = d + temp1 | 0;
118
+ d = c;
119
+ c = b;
120
+ b = a;
121
+ a = temp1 + temp2 | 0;
122
+ }
123
+ h0 = h0 + a | 0;
124
+ h1 = h1 + b | 0;
125
+ h2 = h2 + c | 0;
126
+ h3 = h3 + d | 0;
127
+ h4 = h4 + e | 0;
128
+ h5 = h5 + f | 0;
129
+ h6 = h6 + g | 0;
130
+ h7 = h7 + h | 0;
131
+ }
132
+ const out = /* @__PURE__ */ new Uint8Array(32);
133
+ const outView = new DataView(out.buffer);
134
+ outView.setInt32(0, h0, false);
135
+ outView.setInt32(4, h1, false);
136
+ outView.setInt32(8, h2, false);
137
+ outView.setInt32(12, h3, false);
138
+ outView.setInt32(16, h4, false);
139
+ outView.setInt32(20, h5, false);
140
+ outView.setInt32(24, h6, false);
141
+ outView.setInt32(28, h7, false);
142
+ return out;
143
+ }
144
+ function bytesToBase64Url(bytes) {
145
+ let binary = "";
146
+ for (const byte of bytes) binary += String.fromCodePoint(byte);
147
+ return btoa(binary).replaceAll("+", "-").replaceAll("/", "_").replaceAll("=", "");
148
+ }
149
+ //#endregion
150
+ export { sha256 as n, bytesToBase64Url as t };
@@ -0,0 +1,141 @@
1
+ import { t as compact } from "./compact-y6vfu2_f.js";
2
+ //#region src/core/sink.ts
3
+ /** The closed list of CloudEvents `type` values PermDock emits. */
4
+ const CLOUD_EVENT_TYPES = Object.freeze({
5
+ decision: "dev.permdock.decision",
6
+ approval: "dev.permdock.approval",
7
+ directory: "dev.permdock.directory",
8
+ membership: "dev.permdock.membership",
9
+ catalog: "dev.permdock.catalog",
10
+ credential: "dev.permdock.credential",
11
+ accessStarted: "dev.permdock.access.started",
12
+ accessEnded: "dev.permdock.access.ended",
13
+ accessRevoked: "dev.permdock.access.revoked"
14
+ });
15
+ function cloudEventType(event) {
16
+ switch (event.type) {
17
+ case "directory": return CLOUD_EVENT_TYPES.directory;
18
+ case "membership": return CLOUD_EVENT_TYPES.membership;
19
+ case "credential": return CLOUD_EVENT_TYPES.credential;
20
+ case "access": return event.operation === "started" ? CLOUD_EVENT_TYPES.accessStarted : event.operation === "ended" ? CLOUD_EVENT_TYPES.accessEnded : CLOUD_EVENT_TYPES.accessRevoked;
21
+ case "decision":
22
+ if (event.phase === "requested" || event.phase === "resolved") return CLOUD_EVENT_TYPES.approval;
23
+ return CLOUD_EVENT_TYPES.decision;
24
+ default: return event;
25
+ }
26
+ }
27
+ function cloudEventSubject(event) {
28
+ if (event.type === "directory") return event.resource.id;
29
+ if (event.type === "membership" || event.type === "access") return event.principal.id;
30
+ if (event.type === "credential") return event.credential.id;
31
+ return event.permission;
32
+ }
33
+ /**
34
+ * A `credential` sink event for `credential`. `sample` belongs on `used`
35
+ * events only and must be in `(0, 1]`.
36
+ */
37
+ function credentialEvent(input) {
38
+ const sample = input.sample;
39
+ if (sample !== void 0 && (input.operation !== "used" || !Number.isFinite(sample) || sample <= 0 || sample > 1)) throw new RangeError("PermDock: sample is a number in (0, 1] on used events only");
40
+ const { credential } = input;
41
+ return compact({
42
+ type: "credential",
43
+ at: input.at ?? (/* @__PURE__ */ new Date()).toISOString(),
44
+ source: input.source ?? "permdock",
45
+ operation: input.operation,
46
+ credential: {
47
+ id: credential.id,
48
+ kind: credential.kind
49
+ },
50
+ principal: { id: credential.principal },
51
+ tenant: credential.tenant,
52
+ expiresAt: credential.expiresAt,
53
+ by: input.by,
54
+ sample
55
+ });
56
+ }
57
+ function membershipEvent(input) {
58
+ if (input.scope === void 0 !== (input.id === void 0)) throw new TypeError("PermDock: membershipEvent needs scope and id together");
59
+ if (input.scope === void 0 && input.within !== void 0) throw new TypeError("PermDock: membershipEvent within needs a scope");
60
+ return compact({
61
+ type: "membership",
62
+ at: input.at ?? (/* @__PURE__ */ new Date()).toISOString(),
63
+ source: input.source,
64
+ operation: input.operation,
65
+ principal: input.principal,
66
+ scope: input.scope,
67
+ id: input.id,
68
+ within: input.within,
69
+ via: input.via,
70
+ expiresAt: input.expiresAt,
71
+ roles: input.roles,
72
+ by: input.by
73
+ });
74
+ }
75
+ /**
76
+ * A support-access lifecycle event. `started` on consent, `ended` when the
77
+ * session lapses, `revoked` when the tenant pulls consent early. It never
78
+ * decides; the app writes and revokes the membership.
79
+ */
80
+ function accessEvent(input) {
81
+ return compact({
82
+ type: "access",
83
+ at: input.at ?? (/* @__PURE__ */ new Date()).toISOString(),
84
+ source: input.source,
85
+ operation: input.operation,
86
+ tenant: input.tenant,
87
+ principal: input.principal,
88
+ via: input.via ?? "support",
89
+ roles: input.roles,
90
+ member: input.member,
91
+ expiresAt: input.expiresAt,
92
+ grantedBy: input.grantedBy,
93
+ reason: input.reason,
94
+ actor: input.actor
95
+ });
96
+ }
97
+ function toCloudEvent(event, source = "permdock") {
98
+ return compact({
99
+ specversion: "1.0",
100
+ type: cloudEventType(event),
101
+ source,
102
+ subject: cloudEventSubject(event),
103
+ id: globalThis.crypto.randomUUID(),
104
+ time: event.at,
105
+ datacontenttype: "application/json",
106
+ data: event
107
+ });
108
+ }
109
+ function signDecisionBatch(events, signer, options = {}) {
110
+ const source = options.source ?? "permdock";
111
+ return signer.sign({ events: events.map((event) => toCloudEvent(event, source)) }, compact({
112
+ typ: "permdock-decisions+jwt",
113
+ audience: options.audience
114
+ }));
115
+ }
116
+ function memorySink(options = {}) {
117
+ const capacity = options.capacity ?? 1e4;
118
+ const buffer = [];
119
+ const signed = [];
120
+ return {
121
+ write(events) {
122
+ buffer.push(...events);
123
+ if (buffer.length > capacity) buffer.splice(0, buffer.length - capacity);
124
+ if (options.signer === void 0) return;
125
+ return signDecisionBatch(events, options.signer, compact({
126
+ audience: options.audience,
127
+ source: options.source
128
+ })).then((batch) => {
129
+ signed.push(batch);
130
+ }).catch(() => void 0);
131
+ },
132
+ events() {
133
+ return [...buffer];
134
+ },
135
+ batches() {
136
+ return [...signed];
137
+ }
138
+ };
139
+ }
140
+ //#endregion
141
+ export { memorySink as a, membershipEvent as i, accessEvent as n, signDecisionBatch as o, credentialEvent as r, toCloudEvent as s, CLOUD_EVENT_TYPES as t };