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,795 @@
1
+ import { n as isReadonlyArray, t as compact } from "../compact-y6vfu2_f.js";
2
+ import { n as freezeDeep } from "../freeze-y1_jQL4v.js";
3
+ import { c as getResource, g as listPermissions } from "../permissions-DC7GROPA.js";
4
+ import { a as approvalMessage, i as PermDockValidationError, n as PermDockDeniedError, o as deniedMessage, t as PermDockApprovalRequiredError } from "../errors-Iy71s7Oj.js";
5
+ import { m as isArazzoSimulateInput, o as decisionToken } from "../snapshot-DE8dE_hz.js";
6
+ import { t as createPermDock$1 } from "../permdock-yoZ7EjxX.js";
7
+ import { s as isRecord } from "../map-DowSO96j.js";
8
+ //#region src/pdp/shared.ts
9
+ const MAX_CACHE_TTL_MS = 3e4;
10
+ const CACHE_MAX = 1e3;
11
+ /** Milliseconds, clamped to `[0, 30s]`; anything unparseable disables the cache. */
12
+ function ttlMs(cache) {
13
+ if (cache === void 0) return 0;
14
+ const raw = typeof cache.ttl === "number" ? cache.ttl : cache.ttl.endsWith("ms") ? Number(cache.ttl.slice(0, -2)) : Number(cache.ttl.slice(0, -1)) * 1e3;
15
+ if (!Number.isFinite(raw) || raw <= 0) return 0;
16
+ return Math.min(raw, MAX_CACHE_TTL_MS);
17
+ }
18
+ function denied(reason) {
19
+ return {
20
+ outcome: "denied",
21
+ denials: [{
22
+ role: null,
23
+ reason
24
+ }],
25
+ alternatives: []
26
+ };
27
+ }
28
+ function resourceIdOf(data, field = "id") {
29
+ if (data === null || typeof data !== "object") return "*";
30
+ const id = Object.hasOwn(data, field) ? data[field] : void 0;
31
+ if (typeof id === "string" || typeof id === "number") return String(id);
32
+ return "*";
33
+ }
34
+ function granted(provider, permission, subject, data) {
35
+ const principal = subject.principal;
36
+ if (principal === null) return denied("anonymous");
37
+ return {
38
+ outcome: "granted",
39
+ subject: {
40
+ ...subject,
41
+ principal
42
+ },
43
+ matched: {
44
+ role: provider,
45
+ permission: permission.key,
46
+ provider
47
+ },
48
+ token: decisionToken({
49
+ key: permission.key,
50
+ resourceId: resourceIdOf(data),
51
+ principal,
52
+ actor: subject.actor,
53
+ fingerprint: provider
54
+ })
55
+ };
56
+ }
57
+ /**
58
+ * The request that would be sent, plus what a custom mapping may drop
59
+ * (issuer, tenant, actor): a tenant switch or a changed row never reuses a
60
+ * cached answer.
61
+ */
62
+ function cacheKey(subject, permission, body) {
63
+ return JSON.stringify([
64
+ permission.key,
65
+ subject.principal?.issuer ?? null,
66
+ subject.principal?.tenant ?? null,
67
+ subject.actor === void 0 ? null : [subject.actor.id, subject.actor.kind],
68
+ body
69
+ ]);
70
+ }
71
+ function ttlCache(ttl) {
72
+ const entries = /* @__PURE__ */ new Map();
73
+ return {
74
+ get(key) {
75
+ if (ttl <= 0) return;
76
+ const hit = entries.get(key);
77
+ if (hit !== void 0 && Date.now() - hit.at < ttl) return hit.value;
78
+ entries.delete(key);
79
+ },
80
+ set(key, value) {
81
+ if (ttl <= 0) return;
82
+ entries.set(key, {
83
+ at: Date.now(),
84
+ value
85
+ });
86
+ if (entries.size > CACHE_MAX) {
87
+ const oldest = entries.keys().next();
88
+ if (oldest.done !== true) entries.delete(oldest.value);
89
+ }
90
+ }
91
+ };
92
+ }
93
+ async function bearerOf(auth) {
94
+ if (auth === void 0) return null;
95
+ try {
96
+ const token = typeof auth.bearer === "function" ? await auth.bearer() : auth.bearer;
97
+ return token === "" ? null : token;
98
+ } catch {
99
+ return null;
100
+ }
101
+ }
102
+ async function postJson(fetcher, url, body, options) {
103
+ const token = await bearerOf(options.auth);
104
+ const headers = {
105
+ "content-type": "application/json",
106
+ accept: "application/json"
107
+ };
108
+ if (token !== null) headers["authorization"] = `Bearer ${token}`;
109
+ try {
110
+ const response = await fetcher(url, {
111
+ method: "POST",
112
+ headers,
113
+ body: JSON.stringify(body),
114
+ signal: AbortSignal.timeout(options.timeout)
115
+ });
116
+ return response.ok ? {
117
+ ok: true,
118
+ response
119
+ } : { ok: false };
120
+ } catch {
121
+ return { ok: false };
122
+ }
123
+ }
124
+ function joinUrl(base, path) {
125
+ if (path.startsWith("http://") || path.startsWith("https://")) return path;
126
+ return `${base.endsWith("/") ? base.slice(0, -1) : base}${path.startsWith("/") ? path : `/${path}`}`;
127
+ }
128
+ //#endregion
129
+ //#region src/pdp/create.ts
130
+ function withoutProviders(policy) {
131
+ if (policy.providers === void 0 || policy.providers.length === 0) return policy;
132
+ return freezeDeep(compact({
133
+ permissions: policy.permissions,
134
+ roles: policy.roles,
135
+ rolesByName: policy.rolesByName,
136
+ grants: policy.grants,
137
+ vocabulary: policy.vocabulary,
138
+ scopes: policy.scopes,
139
+ principal(user) {
140
+ return policy.principal(user);
141
+ },
142
+ subject(user) {
143
+ return policy.subject(user);
144
+ },
145
+ context(user) {
146
+ return policy.context?.(user);
147
+ },
148
+ validate: policy.validate,
149
+ onDenied: policy.onDenied,
150
+ fingerprint: policy.fingerprint,
151
+ resources: policy.resources,
152
+ index: policy.index
153
+ }));
154
+ }
155
+ function providerFor(providers, permission) {
156
+ for (const provider of providers) if (provider.handles(permission)) return provider;
157
+ }
158
+ function idFieldOf(policy, permission) {
159
+ return getResource(policy.permissions, permission.resource)?.id ?? "id";
160
+ }
161
+ function isExplicitDeny(decision) {
162
+ return decision.outcome === "denied" && decision.denials.some((denial) => denial.reason === "deny");
163
+ }
164
+ function isLocalShortCircuit(decision) {
165
+ if (decision.outcome !== "denied") return false;
166
+ if (isExplicitDeny(decision)) return true;
167
+ return decision.denials.some((denial) => {
168
+ switch (denial.reason) {
169
+ case "no-grant":
170
+ case "inactive-grant": return false;
171
+ case "pdp-denied":
172
+ case "pdp-unavailable":
173
+ case "pdp-invalid-response": return false;
174
+ case "anonymous":
175
+ case "validation":
176
+ case "not-delegated":
177
+ case "no-delegation":
178
+ case "condition":
179
+ case "deny":
180
+ case "closure-error":
181
+ case "opaque-condition":
182
+ case "server-only":
183
+ case "insufficient-user-authentication":
184
+ case "not-entitled":
185
+ case "purpose":
186
+ case "reason-required":
187
+ case "actor-required":
188
+ case "limit":
189
+ case "limit-unavailable":
190
+ case "relation-depth":
191
+ case "relation-unavailable":
192
+ case "tenant-mismatch":
193
+ case "no-membership":
194
+ case "scope":
195
+ case "expired-membership":
196
+ case "stale-credentials":
197
+ case "unknown-role":
198
+ case "last-holder":
199
+ case "max-holders":
200
+ case "transfer-only":
201
+ case "not-assignable-by":
202
+ case "self-demotion":
203
+ case "externally-managed":
204
+ case "not-allowed-for-membership":
205
+ case "conflicting-role":
206
+ case "approval":
207
+ case "stale-approval":
208
+ case "undocumented":
209
+ case "unsupported":
210
+ case "exceeds-creator":
211
+ case "credential-policy": return true;
212
+ default: return denial.reason;
213
+ }
214
+ });
215
+ }
216
+ function wrap(permdock, policy, subject, providers) {
217
+ const decideLocal = permdock.decide;
218
+ const decide = async (permission, data, options) => {
219
+ const local = decideLocal(permission, data, options);
220
+ const provider = providerFor(providers, permission);
221
+ if (provider === void 0 || isLocalShortCircuit(local)) return local;
222
+ try {
223
+ return await provider.decide({
224
+ permission,
225
+ data,
226
+ subject,
227
+ local
228
+ });
229
+ } catch {
230
+ return denied("pdp-unavailable");
231
+ }
232
+ };
233
+ /** The local trace; a remote decision evaluated no local grant, so its trace is empty. */
234
+ const explain = async (permission, data, options) => {
235
+ const decision = await decide(permission, data, {
236
+ ...options,
237
+ source: options?.source ?? "explain",
238
+ explain: true
239
+ });
240
+ if (decision.trace !== void 0) return decision;
241
+ return freezeDeep({
242
+ ...decision,
243
+ trace: {
244
+ evaluated: 0,
245
+ allows: [],
246
+ denies: [],
247
+ skipped: []
248
+ }
249
+ });
250
+ };
251
+ const permittedIds = async (provider, permission) => {
252
+ if (provider?.permitted === void 0 || subject.principal === null) return;
253
+ try {
254
+ return await provider.permitted({
255
+ permission,
256
+ subject
257
+ });
258
+ } catch {
259
+ return null;
260
+ }
261
+ };
262
+ const can = async (permission, data, options) => {
263
+ try {
264
+ return (await decide(permission, data, options)).outcome === "granted";
265
+ } catch {
266
+ return false;
267
+ }
268
+ };
269
+ const assert = async (permission, data, options) => {
270
+ const decision = await decide(permission, data, {
271
+ ...options,
272
+ source: options?.source ?? "assert"
273
+ });
274
+ if (decision.outcome === "granted") return decision;
275
+ const onDenied = options?.onDenied ?? policy.onDenied;
276
+ if (onDenied !== void 0) onDenied(decision);
277
+ const resource = getResource(policy.permissions, permission.resource);
278
+ const resourceId = data !== null && typeof data === "object" ? data[resource?.id ?? "id"] : void 0;
279
+ const resourceRef = compact({
280
+ type: permission.resource,
281
+ id: resourceId === void 0 ? void 0 : String(resourceId)
282
+ });
283
+ if (decision.outcome === "approval-required") throw new PermDockApprovalRequiredError({
284
+ decision,
285
+ permission: permission.key,
286
+ scope: permission.scope,
287
+ resource: resourceRef,
288
+ message: approvalMessage(permission.key, decision.reason, decision.token)
289
+ });
290
+ if (decision.denials.some((denial) => denial.reason === "validation")) {
291
+ const detail = decision.denials[0]?.detail;
292
+ if (detail instanceof PermDockValidationError) throw detail;
293
+ }
294
+ throw new PermDockDeniedError({
295
+ decision,
296
+ permission: permission.key,
297
+ scope: permission.scope,
298
+ resource: resourceRef,
299
+ subject,
300
+ message: deniedMessage(permission.key, subject.principal?.id, decision.denials, decision.alternatives.map((leaf) => leaf.key))
301
+ });
302
+ };
303
+ const simulate = ((input, options) => {
304
+ if (isReadonlyArray(input)) return Promise.all(input.map(([permission, data]) => decide(permission, data, compact({
305
+ source: "simulate",
306
+ now: options?.now
307
+ }))));
308
+ if (isArazzoSimulateInput(input)) return permdock.simulate(input);
309
+ return wrap(permdock.simulate(input), policy, subject, providers);
310
+ });
311
+ return {
312
+ can,
313
+ decide,
314
+ assert,
315
+ explain,
316
+ async filter(permission, rows, options) {
317
+ const next = {
318
+ ...options,
319
+ source: "filter"
320
+ };
321
+ const provider = providerFor(providers, permission);
322
+ const ids = await permittedIds(provider, permission);
323
+ if (ids === void 0) {
324
+ const decisions = await Promise.all(rows.map((row) => decide(permission, row, next)));
325
+ return rows.filter((_, index) => decisions[index]?.outcome === "granted");
326
+ }
327
+ const allowed = new Set(ids ?? []);
328
+ const field = idFieldOf(policy, permission);
329
+ return rows.filter((row) => {
330
+ const id = resourceIdOf(row, field);
331
+ return allowed.has(id) && !isLocalShortCircuit(decideLocal(permission, row, next));
332
+ });
333
+ },
334
+ pick: permdock.pick.bind(permdock),
335
+ async where(permission) {
336
+ const provider = providerFor(providers, permission);
337
+ if (provider === void 0) return permdock.where(permission);
338
+ const ids = await permittedIds(provider, permission);
339
+ if (ids === void 0) return {
340
+ condition: {
341
+ op: "or",
342
+ conditions: []
343
+ },
344
+ partial: true
345
+ };
346
+ if (ids === null || ids.length === 0) return {
347
+ condition: {
348
+ op: "or",
349
+ conditions: []
350
+ },
351
+ partial: false
352
+ };
353
+ const remote = {
354
+ op: "in",
355
+ field: idFieldOf(policy, permission),
356
+ value: [...ids]
357
+ };
358
+ const local = permdock.where(permission);
359
+ return local.condition.op !== "or" || local.condition.conditions.length > 0 ? {
360
+ condition: {
361
+ op: "and",
362
+ conditions: [local.condition, remote]
363
+ },
364
+ partial: local.partial
365
+ } : {
366
+ condition: remote,
367
+ partial: true
368
+ };
369
+ },
370
+ actions: permdock.actions.bind(permdock),
371
+ simulate,
372
+ snapshot: permdock.snapshot.bind(permdock),
373
+ on: permdock.on.bind(permdock),
374
+ tenant: (id) => {
375
+ const next = permdock.tenant(id);
376
+ return wrap(next, policy, next.subject, providers);
377
+ },
378
+ team: (id) => {
379
+ const next = permdock.team(id);
380
+ return wrap(next, policy, next.subject, providers);
381
+ },
382
+ memberships: permdock.memberships.bind(permdock),
383
+ tenants: permdock.tenants.bind(permdock),
384
+ heldRoles: permdock.heldRoles.bind(permdock),
385
+ audiences: permdock.audiences.bind(permdock),
386
+ assignableRoles: permdock.assignableRoles.bind(permdock),
387
+ assignablePermissions: permdock.assignablePermissions.bind(permdock),
388
+ decideRoleChange: permdock.decideRoleChange.bind(permdock),
389
+ loadRelations: permdock.loadRelations.bind(permdock),
390
+ whoCan: permdock.whoCan.bind(permdock),
391
+ activate: permdock.activate.bind(permdock),
392
+ permissions: permdock.permissions,
393
+ roles: permdock.roles,
394
+ plans: permdock.plans,
395
+ subject
396
+ };
397
+ }
398
+ async function createPermDock(policy, user, options = {}) {
399
+ const localPolicy = withoutProviders(policy);
400
+ const permdock = await createPermDock$1(localPolicy, user, options);
401
+ return wrap(permdock, localPolicy, permdock.subject, policy.providers ?? []);
402
+ }
403
+ //#endregion
404
+ //#region src/pdp/relations.ts
405
+ function relationProvider(backend) {
406
+ const callbacks = /* @__PURE__ */ new Map();
407
+ for (const [permission, callback] of backend.map) callbacks.set(permission.key, callback);
408
+ const timeout = backend.timeout ?? 300;
409
+ const decisions = ttlCache(ttlMs(backend.cache));
410
+ const lists = ttlCache(ttlMs(backend.cache));
411
+ const fetcher = backend.fetch ?? fetch;
412
+ const post = async (url, body) => {
413
+ const posted = await postJson(fetcher, url, body, {
414
+ auth: backend.auth,
415
+ timeout
416
+ });
417
+ return posted.ok ? posted.response : null;
418
+ };
419
+ function tupleFor(permission, subject, data) {
420
+ const callback = callbacks.get(permission.key);
421
+ if (callback === void 0) return null;
422
+ try {
423
+ return callback(subject, data);
424
+ } catch {
425
+ return "invalid";
426
+ }
427
+ }
428
+ return {
429
+ name: backend.name,
430
+ handles(permission) {
431
+ return callbacks.has(permission.key);
432
+ },
433
+ async decide(request) {
434
+ if (request.subject.principal === null) return denied("anonymous");
435
+ const tuple = tupleFor(request.permission, request.subject, request.data);
436
+ if (tuple === "invalid") return denied("pdp-invalid-response");
437
+ if (tuple === null) return denied("pdp-denied");
438
+ const key = cacheKey(request.subject, request.permission, tuple);
439
+ const hit = decisions.get(key);
440
+ if (hit !== void 0) return hit;
441
+ const result = await backend.check(tuple, post);
442
+ if (result === "unavailable") return denied("pdp-unavailable");
443
+ if (result === "invalid") return denied("pdp-invalid-response");
444
+ const decision = result ? granted(backend.name, request.permission, request.subject, request.data) : denied("pdp-denied");
445
+ decisions.set(key, decision);
446
+ return decision;
447
+ },
448
+ async permitted(request) {
449
+ if (request.subject.principal === null) return [];
450
+ const tuple = tupleFor(request.permission, request.subject, void 0);
451
+ if (tuple === "invalid") return null;
452
+ if (tuple === null) return [];
453
+ const key = cacheKey(request.subject, request.permission, tuple);
454
+ const hit = lists.get(key);
455
+ if (hit !== void 0) return hit;
456
+ const ids = await backend.list(tuple, post);
457
+ if (ids !== null) lists.set(key, ids);
458
+ return ids;
459
+ }
460
+ };
461
+ }
462
+ async function jsonOf(response) {
463
+ if (response === null) return;
464
+ try {
465
+ return await response.json();
466
+ } catch {
467
+ return null;
468
+ }
469
+ }
470
+ /**
471
+ * An OpenFGA store as a decision provider: `check` decides one row and
472
+ * `list-objects` lists the ids `filter` and `where` use.
473
+ */
474
+ function openfga(options) {
475
+ const store = joinUrl(options.url, `/stores/${encodeURIComponent(options.storeId)}`);
476
+ const model = compact({ authorization_model_id: options.authorizationModelId });
477
+ return relationProvider(compact({
478
+ name: "openfga",
479
+ map: options.map,
480
+ auth: options.auth,
481
+ timeout: options.timeout,
482
+ cache: options.cache,
483
+ fetch: options.fetch,
484
+ async check(tuple, post) {
485
+ if (tuple.id === void 0) return "invalid";
486
+ const body = await jsonOf(await post(`${store}/check`, {
487
+ ...model,
488
+ tuple_key: {
489
+ user: tuple.user,
490
+ relation: tuple.relation,
491
+ object: `${tuple.type}:${tuple.id}`
492
+ }
493
+ }));
494
+ if (body === void 0) return "unavailable";
495
+ return isRecord(body) && typeof body["allowed"] === "boolean" ? body["allowed"] : "invalid";
496
+ },
497
+ async list(tuple, post) {
498
+ const body = await jsonOf(await post(`${store}/list-objects`, {
499
+ ...model,
500
+ type: tuple.type,
501
+ relation: tuple.relation,
502
+ user: tuple.user
503
+ }));
504
+ if (!isRecord(body) || !Array.isArray(body["objects"])) return null;
505
+ const prefix = `${tuple.type}:`;
506
+ const ids = [];
507
+ for (const object of body["objects"]) {
508
+ if (typeof object !== "string" || !object.startsWith(prefix)) return null;
509
+ ids.push(object.slice(prefix.length));
510
+ }
511
+ return Object.freeze(ids);
512
+ }
513
+ }));
514
+ }
515
+ function subjectReference(check) {
516
+ return compact({
517
+ object: {
518
+ objectType: check.subject.type,
519
+ objectId: check.subject.id
520
+ },
521
+ optionalRelation: check.subject.relation
522
+ });
523
+ }
524
+ /**
525
+ * A SpiceDB HTTP gateway as a decision provider: `CheckPermission` decides
526
+ * one row and `LookupResources` lists the ids `filter` and `where` use. A
527
+ * conditional permissionship (a caveat missing context) is a denial.
528
+ */
529
+ function spicedb(options) {
530
+ const consistency = options.consistency === "fully-consistent" ? { fullyConsistent: true } : { minimizeLatency: true };
531
+ return relationProvider(compact({
532
+ name: "spicedb",
533
+ map: options.map,
534
+ auth: { bearer: options.token },
535
+ timeout: options.timeout,
536
+ cache: options.cache,
537
+ fetch: options.fetch,
538
+ async check(check, post) {
539
+ if (check.resource.id === void 0) return "invalid";
540
+ const body = await jsonOf(await post(joinUrl(options.url, "/v1/permissions/check"), {
541
+ consistency,
542
+ resource: {
543
+ objectType: check.resource.type,
544
+ objectId: check.resource.id
545
+ },
546
+ permission: check.permission,
547
+ subject: subjectReference(check)
548
+ }));
549
+ if (body === void 0) return "unavailable";
550
+ if (!isRecord(body)) return "invalid";
551
+ switch (body["permissionship"]) {
552
+ case "PERMISSIONSHIP_HAS_PERMISSION": return true;
553
+ case "PERMISSIONSHIP_NO_PERMISSION":
554
+ case "PERMISSIONSHIP_CONDITIONAL_PERMISSION": return false;
555
+ default: return "invalid";
556
+ }
557
+ },
558
+ async list(check, post) {
559
+ const response = await post(joinUrl(options.url, "/v1/permissions/resources"), {
560
+ consistency,
561
+ resourceObjectType: check.resource.type,
562
+ permission: check.permission,
563
+ subject: subjectReference(check)
564
+ });
565
+ if (response === null) return null;
566
+ let text;
567
+ try {
568
+ text = await response.text();
569
+ } catch {
570
+ return null;
571
+ }
572
+ const ids = [];
573
+ for (const line of text.split("\n")) {
574
+ if (line.trim() === "") continue;
575
+ let parsed;
576
+ try {
577
+ parsed = JSON.parse(line);
578
+ } catch {
579
+ return null;
580
+ }
581
+ const result = isRecord(parsed) ? parsed["result"] : void 0;
582
+ if (!isRecord(result) || typeof result["resourceObjectId"] !== "string") return null;
583
+ if (result["permissionship"] === "LOOKUP_PERMISSIONSHIP_HAS_PERMISSION") ids.push(result["resourceObjectId"]);
584
+ }
585
+ return Object.freeze(ids);
586
+ }
587
+ }));
588
+ }
589
+ //#endregion
590
+ //#region src/pdp/remote.ts
591
+ const DEFAULT_EVALUATION = "/access/v1/evaluation";
592
+ const DEFAULT_EVALUATIONS = "/access/v1/evaluations";
593
+ const MAX_SEARCH_PAGES = 100;
594
+ function delegatedKeys(listed) {
595
+ if (listed === void 0) return null;
596
+ const keys = /* @__PURE__ */ new Set();
597
+ for (const item of listed) for (const leaf of listPermissions(item)) keys.add(leaf.key);
598
+ return keys;
599
+ }
600
+ function parseDiscovery(url, body) {
601
+ if (!isRecord(body)) return null;
602
+ const evaluation = typeof body["access_evaluation_endpoint"] === "string" ? body["access_evaluation_endpoint"] : typeof body["policy_decision_point"] === "string" ? joinUrl(body["policy_decision_point"], DEFAULT_EVALUATION) : joinUrl(url, DEFAULT_EVALUATION);
603
+ return compact({
604
+ evaluation,
605
+ evaluations: typeof body["access_evaluations_endpoint"] === "string" ? body["access_evaluations_endpoint"] : joinUrl(url, DEFAULT_EVALUATIONS),
606
+ searchResource: typeof body["search_resource_endpoint"] === "string" ? body["search_resource_endpoint"] : void 0
607
+ });
608
+ }
609
+ function mapEvaluationBody(permission, data, subject, mapping) {
610
+ const defaultId = data !== null && typeof data === "object" ? data["id"] : void 0;
611
+ const mappedSubject = mapping?.subject?.(subject) ?? compact({
612
+ type: "user",
613
+ id: subject.principal?.id,
614
+ properties: compact({
615
+ orgId: subject.principal?.tenant,
616
+ roles: subject.principal?.roles,
617
+ actor: subject.actor,
618
+ delegation: subject.delegation
619
+ })
620
+ });
621
+ const mappedResource = mapping?.resource?.(permission, data) ?? compact({
622
+ type: permission.resource,
623
+ id: typeof defaultId === "string" || typeof defaultId === "number" ? String(defaultId) : resourceIdOf(data),
624
+ properties: data
625
+ });
626
+ return {
627
+ subject: mappedSubject,
628
+ action: mapping?.action?.(permission) ?? { name: permission.action },
629
+ resource: mappedResource,
630
+ context: compact({
631
+ tenant: subject.principal?.tenant,
632
+ actor: subject.actor,
633
+ delegation: subject.delegation
634
+ })
635
+ };
636
+ }
637
+ function parseRemoteDecision(body, permission, subject, data) {
638
+ if (!isRecord(body) || typeof body["decision"] !== "boolean") return denied("pdp-invalid-response");
639
+ if (body["decision"]) return granted("pdp", permission, subject, data);
640
+ const context = isRecord(body["context"]) && isRecord(body["context"]["permdock"]) ? body["context"]["permdock"] : {};
641
+ if (context["outcome"] === "approval-required") {
642
+ const token = typeof context["token"] === "string" ? context["token"] : "";
643
+ return {
644
+ outcome: "approval-required",
645
+ grant: {
646
+ role: "pdp",
647
+ permission: permission.key,
648
+ provider: "pdp",
649
+ approval: "human"
650
+ },
651
+ reason: "human",
652
+ token
653
+ };
654
+ }
655
+ if (Array.isArray(context["denials"])) {
656
+ const denials = context["denials"].flatMap((item) => {
657
+ if (!isRecord(item) || typeof item["reason"] !== "string") return [];
658
+ return [compact({
659
+ role: typeof item["role"] === "string" ? item["role"] : null,
660
+ reason: item["reason"],
661
+ detail: item["detail"]
662
+ })];
663
+ });
664
+ if (denials.length > 0) return {
665
+ outcome: "denied",
666
+ denials,
667
+ alternatives: []
668
+ };
669
+ }
670
+ return denied("pdp-denied");
671
+ }
672
+ function mapSearchBody(permission, subject, mapping) {
673
+ const body = mapEvaluationBody(permission, void 0, subject, mapping);
674
+ const resource = isRecord(body["resource"]) ? body["resource"] : {};
675
+ return {
676
+ ...body,
677
+ resource: { type: resource["type"] ?? permission.resource }
678
+ };
679
+ }
680
+ function searchIds(body, type) {
681
+ if (!isRecord(body) || !Array.isArray(body["results"])) return null;
682
+ const ids = [];
683
+ for (const entity of body["results"]) {
684
+ if (!isRecord(entity) || entity["type"] !== type || typeof entity["id"] !== "string") return null;
685
+ ids.push(entity["id"]);
686
+ }
687
+ return ids;
688
+ }
689
+ function nextToken(body) {
690
+ if (!isRecord(body) || !isRecord(body["page"])) return;
691
+ const token = body["page"]["next_token"];
692
+ return typeof token === "string" && token !== "" ? token : void 0;
693
+ }
694
+ function remotePdp(options) {
695
+ const keys = delegatedKeys(options.permissions);
696
+ const timeout = options.timeout ?? 300;
697
+ const decisions = ttlCache(ttlMs(options.cache));
698
+ const lists = ttlCache(ttlMs(options.cache));
699
+ const fetcher = options.fetch ?? fetch;
700
+ const post = {
701
+ auth: options.auth,
702
+ timeout
703
+ };
704
+ let discovery = options.endpoints?.evaluation === void 0 ? null : compact({
705
+ evaluation: options.endpoints.evaluation,
706
+ evaluations: options.endpoints.evaluations,
707
+ searchResource: options.endpoints.searchResource
708
+ });
709
+ async function discover() {
710
+ if (discovery !== null) return discovery;
711
+ try {
712
+ const signal = AbortSignal.timeout(timeout);
713
+ const response = await fetcher(joinUrl(options.url, "/.well-known/authzen-configuration"), { signal });
714
+ if (!response.ok) return null;
715
+ const parsed = parseDiscovery(options.url, await response.json());
716
+ if (parsed === null) return null;
717
+ discovery = parsed;
718
+ return parsed;
719
+ } catch {
720
+ return null;
721
+ }
722
+ }
723
+ async function readJson(url, body) {
724
+ const posted = await postJson(fetcher, url, body, post);
725
+ if (!posted.ok) return posted;
726
+ try {
727
+ return {
728
+ ok: true,
729
+ body: await posted.response.json()
730
+ };
731
+ } catch {
732
+ return { ok: false };
733
+ }
734
+ }
735
+ return {
736
+ name: "pdp",
737
+ handles(permission) {
738
+ return keys === null || keys.has(permission.key);
739
+ },
740
+ async decide(request) {
741
+ if (request.subject.principal === null) return denied("anonymous");
742
+ let body;
743
+ try {
744
+ body = mapEvaluationBody(request.permission, request.data, request.subject, options.mapping);
745
+ } catch {
746
+ return denied("pdp-invalid-response");
747
+ }
748
+ const key = cacheKey(request.subject, request.permission, body);
749
+ const hit = decisions.get(key);
750
+ if (hit !== void 0) return hit;
751
+ const endpoints = await discover();
752
+ if (endpoints === null) return denied("pdp-unavailable");
753
+ const posted = await readJson(endpoints.evaluation, body);
754
+ if (!posted.ok) return denied("pdp-unavailable");
755
+ const decision = parseRemoteDecision(posted.body, request.permission, request.subject, request.data);
756
+ if (decision.outcome === "granted" || decision.outcome === "approval-required" || decision.outcome === "denied" && decision.denials[0]?.reason === "pdp-denied") decisions.set(key, decision);
757
+ return decision;
758
+ },
759
+ async permitted(request) {
760
+ if (request.subject.principal === null) return [];
761
+ const endpoints = await discover();
762
+ if (endpoints === null) return null;
763
+ if (endpoints.searchResource === void 0) return;
764
+ let body;
765
+ try {
766
+ body = mapSearchBody(request.permission, request.subject, options.mapping);
767
+ } catch {
768
+ return null;
769
+ }
770
+ const key = cacheKey(request.subject, request.permission, body);
771
+ const hit = lists.get(key);
772
+ if (hit !== void 0) return hit;
773
+ const type = isRecord(body["resource"]) ? body["resource"]["type"] : void 0;
774
+ const url = endpoints.searchResource;
775
+ const collect = async (token, page, ids) => {
776
+ if (page >= MAX_SEARCH_PAGES) return null;
777
+ const posted = await readJson(url, token === void 0 ? body : {
778
+ ...body,
779
+ page: { token }
780
+ });
781
+ const found = posted.ok ? searchIds(posted.body, type) : null;
782
+ if (!posted.ok || found === null) return null;
783
+ const next = nextToken(posted.body);
784
+ return next === void 0 ? [...ids, ...found] : collect(next, page + 1, [...ids, ...found]);
785
+ };
786
+ const ids = await collect(void 0, 0, []);
787
+ if (ids === null) return null;
788
+ const frozen = Object.freeze([...ids]);
789
+ lists.set(key, frozen);
790
+ return frozen;
791
+ }
792
+ };
793
+ }
794
+ //#endregion
795
+ export { createPermDock, openfga, remotePdp, spicedb };