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,174 @@
1
+ "use client";
2
+ import { t as compact } from "../compact-y6vfu2_f.js";
3
+ import { n as requiredPlans, t as describe } from "../describe-Bt1YD5uS.js";
4
+ import { n as parseSnapshot } from "../snapshot-DE8dE_hz.js";
5
+ import { t as emptySnapshot } from "../from-snapshot-BMGnhmgv.js";
6
+ import { t as approvalHeaders } from "../headers-B5RRv3Xm.js";
7
+ import { n as PermDockStoreContext } from "../context-gtAwAILx.js";
8
+ import { a as useFilter, c as usePermission, d as useSubject, f as useTenant, i as useAssignableRoles, l as usePermissions, n as useApproval, o as useMemberships, r as useAssignablePermissions, s as usePermDock, t as Protected, u as useRoles } from "../protected-B4K3BKoX.js";
9
+ import { t as createClientStore } from "../store-C6hFW6ta.js";
10
+ import { useEffect, useMemo } from "react";
11
+ import { jsx } from "react/jsx-runtime";
12
+ //#region src/react-native/storage.ts
13
+ const SNAPSHOT_KEY = "permdock.snapshot";
14
+ const TENANT_KEY = "permdock.tenant";
15
+ function memoryStorage(initial = {}) {
16
+ const map = new Map(Object.entries(initial));
17
+ return {
18
+ getItem(key) {
19
+ return map.get(key) ?? null;
20
+ },
21
+ setItem(key, value) {
22
+ map.set(key, value);
23
+ },
24
+ removeItem(key) {
25
+ map.delete(key);
26
+ }
27
+ };
28
+ }
29
+ function isThenable(value) {
30
+ return typeof value === "object" && value !== null && "then" in value && typeof value.then === "function";
31
+ }
32
+ function acceptSnapshot(raw, subjectId) {
33
+ if (raw === null || raw.length === 0) return;
34
+ try {
35
+ const parsed = JSON.parse(raw);
36
+ const snapshot = parseSnapshot(parsed);
37
+ const id = snapshot.subject.principal?.id;
38
+ if (subjectId !== void 0 && id !== subjectId) return;
39
+ return snapshot;
40
+ } catch {
41
+ return;
42
+ }
43
+ }
44
+ async function readStored(storage, subjectId) {
45
+ const raw = await Promise.resolve(storage.getItem(SNAPSHOT_KEY));
46
+ const tenantRaw = await Promise.resolve(storage.getItem(TENANT_KEY));
47
+ return {
48
+ snapshot: acceptSnapshot(raw, subjectId),
49
+ tenant: tenantRaw === null || tenantRaw.length === 0 ? void 0 : tenantRaw
50
+ };
51
+ }
52
+ function readStoredSync(storage, subjectId) {
53
+ const raw = storage.getItem(SNAPSHOT_KEY);
54
+ const tenantRaw = storage.getItem(TENANT_KEY);
55
+ if (isThenable(raw) || isThenable(tenantRaw)) return;
56
+ return {
57
+ snapshot: acceptSnapshot(raw, subjectId),
58
+ tenant: tenantRaw === null || tenantRaw.length === 0 ? void 0 : tenantRaw
59
+ };
60
+ }
61
+ function persistSnapshot(storage, snapshot, tenant) {
62
+ const write = storage.setItem(SNAPSHOT_KEY, JSON.stringify(snapshot));
63
+ if (isThenable(write)) write.catch(() => void 0);
64
+ if (tenant === void 0) return;
65
+ const next = storage.setItem(TENANT_KEY, tenant);
66
+ if (isThenable(next)) next.catch(() => void 0);
67
+ }
68
+ function clearStorage(storage) {
69
+ const snap = storage.removeItem(SNAPSHOT_KEY);
70
+ if (isThenable(snap)) snap.catch(() => void 0);
71
+ const tenant = storage.removeItem(TENANT_KEY);
72
+ if (isThenable(tenant)) tenant.catch(() => void 0);
73
+ }
74
+ //#endregion
75
+ //#region src/react-native/store.ts
76
+ function isJws(value) {
77
+ const parts = value.split(".");
78
+ return parts.length === 3 && parts.every((part) => part.length > 0);
79
+ }
80
+ function createNativeStore(options) {
81
+ const signed = typeof options.snapshot === "string" && isJws(options.snapshot) ? options.snapshot : void 0;
82
+ const seeded = options.snapshot === void 0 || signed !== void 0 ? void 0 : typeof options.snapshot === "string" ? acceptSnapshot(options.snapshot, options.subjectId) : acceptSnapshot(JSON.stringify(options.snapshot), options.subjectId);
83
+ const sync = signed === void 0 ? readStoredSync(options.storage, options.subjectId) : void 0;
84
+ const snapshot = signed ?? seeded ?? sync?.snapshot ?? emptySnapshot();
85
+ const tenant = options.tenant ?? sync?.tenant;
86
+ let booted = false;
87
+ let touched = false;
88
+ const store = createClientStore(compact({
89
+ snapshot,
90
+ endpoint: options.endpoint,
91
+ snapshotUrl: options.snapshotUrl,
92
+ approvals: options.approvals,
93
+ tenant,
94
+ fetch: options.fetch,
95
+ headers: options.headers,
96
+ maxAge: options.maxAge,
97
+ verifier: options.verifier,
98
+ server: false,
99
+ onSnapshot: (next, nextTenant) => {
100
+ if (!booted) return;
101
+ touched = true;
102
+ persistSnapshot(options.storage, next, nextTenant);
103
+ },
104
+ onClear: () => {
105
+ touched = true;
106
+ clearStorage(options.storage);
107
+ }
108
+ }));
109
+ booted = true;
110
+ if (seeded !== void 0) persistSnapshot(options.storage, seeded, tenant);
111
+ if (sync === void 0 && seeded === void 0 && signed === void 0) readStored(options.storage, options.subjectId).then((stored) => {
112
+ if (!touched && stored.snapshot !== void 0) store.replace(stored.snapshot);
113
+ });
114
+ return store;
115
+ }
116
+ //#endregion
117
+ //#region src/react-native/provider.tsx
118
+ function PermDockProvider(props) {
119
+ const store = useMemo(() => createNativeStore(compact({
120
+ storage: props.storage,
121
+ snapshot: props.snapshot,
122
+ snapshotUrl: props.snapshotUrl,
123
+ endpoint: props.endpoint,
124
+ approvals: props.approvals,
125
+ tenant: props.tenant,
126
+ subjectId: props.subjectId,
127
+ revalidate: props.revalidate,
128
+ subscribeForeground: props.subscribeForeground,
129
+ fetch: props.fetch,
130
+ headers: props.headers,
131
+ maxAge: props.maxAge,
132
+ verifier: props.verifier
133
+ })), [
134
+ props.storage,
135
+ props.snapshot,
136
+ props.snapshotUrl,
137
+ props.endpoint,
138
+ props.approvals,
139
+ props.tenant,
140
+ props.subjectId,
141
+ props.revalidate,
142
+ props.subscribeForeground,
143
+ props.fetch,
144
+ props.headers,
145
+ props.maxAge,
146
+ props.verifier
147
+ ]);
148
+ useEffect(() => {
149
+ const mode = props.revalidate ?? "launch";
150
+ const refresh = () => {
151
+ if (props.snapshotUrl === void 0) return;
152
+ store.get().refresh().catch(() => void 0);
153
+ };
154
+ if (mode === "launch" || mode === "focus" || typeof mode === "number") refresh();
155
+ if (typeof mode === "number") {
156
+ const timer = setInterval(refresh, mode * 1e3);
157
+ return () => {
158
+ clearInterval(timer);
159
+ };
160
+ }
161
+ if (mode === "focus" && props.subscribeForeground !== void 0) return props.subscribeForeground(refresh);
162
+ }, [
163
+ store,
164
+ props.revalidate,
165
+ props.snapshotUrl,
166
+ props.subscribeForeground
167
+ ]);
168
+ return /* @__PURE__ */ jsx(PermDockStoreContext, {
169
+ value: store,
170
+ children: props.children
171
+ });
172
+ }
173
+ //#endregion
174
+ export { PermDockProvider, Protected, approvalHeaders, createNativeStore, describe, memoryStorage, requiredPlans, useApproval, useAssignablePermissions, useAssignableRoles, useFilter, useMemberships, usePermDock, usePermission, usePermissions, useRoles, useSubject, useTenant };
@@ -0,0 +1,90 @@
1
+ import { n as freezeDeep } from "./freeze-y1_jQL4v.js";
2
+ import { E as splitPath, T as readPath, x as assertSafeKey } from "./permissions-DC7GROPA.js";
3
+ //#region src/conditions/ast.ts
4
+ function parentHop(parent) {
5
+ return typeof parent === "string" ? { field: parent } : parent;
6
+ }
7
+ function isConditionRef(value) {
8
+ return value !== null && typeof value === "object" && "ref" in value && typeof value.ref === "string";
9
+ }
10
+ function isConditionDate(value) {
11
+ return value !== null && typeof value === "object" && "date" in value && typeof value.date === "string" && !("ref" in value);
12
+ }
13
+ function isCondition(value) {
14
+ return value !== null && typeof value === "object" && "op" in value && typeof value.op === "string";
15
+ }
16
+ function isSqlFunctionField(value) {
17
+ return value !== null && typeof value === "object" && "field" in value && typeof value.field === "string" && !("ref" in value) && !("date" in value) && !("op" in value);
18
+ }
19
+ function hasConditionOp(condition, op) {
20
+ if (condition === void 0) return false;
21
+ if (condition.op === op) return true;
22
+ switch (condition.op) {
23
+ case "and":
24
+ case "or": return condition.conditions.some((child) => hasConditionOp(child, op));
25
+ case "not": return hasConditionOp(condition.condition, op);
26
+ case "sqlFunction": return hasConditionOp(condition.twin, op);
27
+ case "eq":
28
+ case "ne":
29
+ case "gt":
30
+ case "gte":
31
+ case "lt":
32
+ case "lte":
33
+ case "contains":
34
+ case "in":
35
+ case "notIn":
36
+ case "isNull":
37
+ case "memberOf":
38
+ case "related":
39
+ case "opaque": return false;
40
+ default:
41
+ /* v8 ignore next */
42
+ return condition;
43
+ }
44
+ }
45
+ //#endregion
46
+ //#region src/conditions/refs.ts
47
+ const REF_BRAND = Symbol.for("permdock.ref");
48
+ function createRef(path) {
49
+ const segments = splitPath(path);
50
+ for (const segment of segments) assertSafeKey(segment, "subject path");
51
+ const target = freezeDeep({ ref: path });
52
+ return new Proxy(target, {
53
+ get(object, property, receiver) {
54
+ if (property === "ref" || property === REF_BRAND) return Reflect.get(object, property === REF_BRAND ? "ref" : property, receiver);
55
+ if (property === "toJSON" || property === "valueOf" || property === Symbol.toStringTag) return;
56
+ if (typeof property !== "string") return;
57
+ assertSafeKey(property, "subject path");
58
+ return createRef(`${path}.${property}`);
59
+ },
60
+ getOwnPropertyDescriptor(object, property) {
61
+ if (property === "ref") return Reflect.getOwnPropertyDescriptor(object, property);
62
+ },
63
+ ownKeys() {
64
+ return ["ref"];
65
+ }
66
+ });
67
+ }
68
+ const principal = createRef("principal");
69
+ const context = createRef("context");
70
+ function isSubjectRef(value) {
71
+ if (value === null || typeof value !== "object" || !("ref" in value) || typeof value.ref !== "string") return false;
72
+ const ref = value.ref;
73
+ return ref === "principal" || ref.startsWith("principal.") || ref === "context" || ref.startsWith("context.");
74
+ }
75
+ function resolveConditionRef(ref, resolved) {
76
+ if (resolved === void 0) return;
77
+ if (ref === "principal" || ref.startsWith("principal.")) {
78
+ const path = ref === "principal" ? "" : ref.slice(10);
79
+ if (path === "") return resolved.principal;
80
+ if (resolved.principal === null) return;
81
+ return readPath(resolved.principal, path);
82
+ }
83
+ if (ref === "context" || ref.startsWith("context.")) {
84
+ const path = ref === "context" ? "" : ref.slice(8);
85
+ if (path === "") return resolved.context;
86
+ return readPath(resolved.context, path);
87
+ }
88
+ }
89
+ //#endregion
90
+ export { hasConditionOp as a, isConditionRef as c, resolveConditionRef as i, isSqlFunctionField as l, isSubjectRef as n, isCondition as o, principal as r, isConditionDate as s, context as t, parentHop as u };
@@ -0,0 +1,426 @@
1
+ import { C as ownGet, l as isComputedRelation, p as isPrincipalRelation, r as expandRelation, s as getRegistry, u as isEdgeRelation } from "./permissions-DC7GROPA.js";
2
+ import { n as isThenable } from "./thenable-okc2xDsj.js";
3
+ function isRecord(value) {
4
+ return value !== null && typeof value === "object" && !Array.isArray(value);
5
+ }
6
+ function isInstant(value) {
7
+ return value === void 0 || typeof value === "number" && Number.isFinite(value);
8
+ }
9
+ function asChain(value) {
10
+ if (!isRecord(value) || !Array.isArray(value["ancestors"])) return;
11
+ const ancestors = [];
12
+ for (const item of value["ancestors"]) {
13
+ if (!isRecord(item) || typeof item["id"] !== "string" || item["id"] === "") return;
14
+ ancestors.push(item["restricted"] === true ? {
15
+ id: item["id"],
16
+ restricted: true
17
+ } : { id: item["id"] });
18
+ }
19
+ return {
20
+ ancestors,
21
+ ...value["restricted"] === true ? { restricted: true } : {},
22
+ ...value["truncated"] === true ? { truncated: true } : {}
23
+ };
24
+ }
25
+ function asGroup(value) {
26
+ if (!isRecord(value) || typeof value["resource"] !== "string" || typeof value["id"] !== "string" || typeof value["relation"] !== "string" || value["id"] === "") return;
27
+ return {
28
+ resource: value["resource"],
29
+ id: value["id"],
30
+ relation: value["relation"]
31
+ };
32
+ }
33
+ function asHolders(value) {
34
+ if (!Array.isArray(value)) return;
35
+ const holders = [];
36
+ for (const item of value) {
37
+ if (!isRecord(item) || !isInstant(item["startsAt"]) || !isInstant(item["expiresAt"])) return;
38
+ const period = {
39
+ ...item["startsAt"] === void 0 ? {} : { startsAt: item["startsAt"] },
40
+ ...item["expiresAt"] === void 0 ? {} : { expiresAt: item["expiresAt"] }
41
+ };
42
+ if (isRecord(item["principal"]) && typeof item["principal"]["id"] === "string") {
43
+ holders.push({
44
+ principal: { id: item["principal"]["id"] },
45
+ ...period
46
+ });
47
+ continue;
48
+ }
49
+ const group = asGroup(item["group"]);
50
+ if (group === void 0) return;
51
+ holders.push({
52
+ group,
53
+ ...period
54
+ });
55
+ }
56
+ return holders;
57
+ }
58
+ function read(cache, key, call, validate) {
59
+ const entry = cache.get(key);
60
+ if (entry !== void 0) return entry.state === "ready" ? entry.value : entry.state;
61
+ if (call === void 0) return "failed";
62
+ const settle = (value) => {
63
+ const valid = validate(value);
64
+ cache.set(key, valid === void 0 ? { state: "failed" } : {
65
+ state: "ready",
66
+ value: valid
67
+ });
68
+ };
69
+ let result;
70
+ try {
71
+ result = call();
72
+ } catch {
73
+ cache.set(key, { state: "failed" });
74
+ return "failed";
75
+ }
76
+ if (isThenable(result)) {
77
+ const promise = Promise.resolve(result).then(settle, () => {
78
+ cache.set(key, { state: "failed" });
79
+ });
80
+ cache.set(key, {
81
+ state: "pending",
82
+ promise
83
+ });
84
+ return "pending";
85
+ }
86
+ settle(result);
87
+ const settled = cache.get(key);
88
+ return settled?.state === "ready" ? settled.value : "failed";
89
+ }
90
+ function relationReader(source, cache, resources) {
91
+ const concrete = (resource, id, relation) => read(cache, JSON.stringify([
92
+ "holders",
93
+ resource,
94
+ id,
95
+ relation
96
+ ]), source === void 0 ? void 0 : () => source.related({
97
+ resource,
98
+ id,
99
+ relation
100
+ }), asHolders);
101
+ return {
102
+ available: source !== void 0,
103
+ chain(query) {
104
+ const through = query.through ?? "parent";
105
+ return read(cache, JSON.stringify([
106
+ "chain",
107
+ query.resource,
108
+ query.id,
109
+ query.depth,
110
+ through
111
+ ]), source === void 0 ? void 0 : () => source.ancestors({
112
+ resource: query.resource,
113
+ id: query.id,
114
+ depth: query.depth,
115
+ through
116
+ }), asChain);
117
+ },
118
+ holders(query) {
119
+ const node = resources?.get(query.resource);
120
+ const names = node === void 0 ? [query.relation] : expandRelation(node, query.relation);
121
+ const out = [];
122
+ let unread;
123
+ for (const name of names) {
124
+ const answer = concrete(query.resource, query.id, name);
125
+ if (answer === "pending" || answer === "failed") {
126
+ unread = answer === "failed" || unread === "failed" ? "failed" : "pending";
127
+ continue;
128
+ }
129
+ for (const holder of answer) out.push({
130
+ ...holder,
131
+ relation: name
132
+ });
133
+ }
134
+ return unread ?? out;
135
+ }
136
+ };
137
+ }
138
+ /** The loads still in flight, for an instance that awaits them before deciding. */
139
+ function pendingRelations(cache) {
140
+ const out = [];
141
+ for (const entry of cache.values()) if (entry.state === "pending") out.push(entry.promise);
142
+ return out;
143
+ }
144
+ function relationId(value) {
145
+ if (typeof value === "string") return value === "" ? void 0 : value;
146
+ if (typeof value === "number" && Number.isFinite(value)) return String(value);
147
+ if (typeof value === "bigint") return String(value);
148
+ }
149
+ /** Whether the holder's period covers `now`. */
150
+ function activeNow(holder, now) {
151
+ return (holder.startsAt === void 0 || holder.startsAt <= now) && (holder.expiresAt === void 0 || holder.expiresAt > now);
152
+ }
153
+ function holdsNow(holder, principalId, now) {
154
+ return "principal" in holder && holder.principal.id === principalId && activeNow(holder, now);
155
+ }
156
+ /** Where the walk starts after following `hops`, or why it cannot. */
157
+ function followHops(condition, first, reader) {
158
+ const hops = condition.hops ?? [];
159
+ let id = first;
160
+ for (let index = 1; index < hops.length; index += 1) {
161
+ const from = hops[index - 1];
162
+ const hop = hops[index];
163
+ if (from === void 0 || hop === void 0)
164
+ /* v8 ignore next */
165
+ return;
166
+ const chain = reader.chain({
167
+ resource: from.resource,
168
+ id,
169
+ depth: 1,
170
+ through: hop.link
171
+ });
172
+ if (chain === "pending" || chain === "failed") return "relation-unavailable";
173
+ const next = chain.ancestors[0]?.id;
174
+ if (next === void 0) return;
175
+ id = next;
176
+ }
177
+ return { id };
178
+ }
179
+ /** The instances a graph relation reads: the start, then ancestors until a restricted one or `depth`. */
180
+ function relationWalk(condition, row, reader) {
181
+ if (!isRecord(row)) return;
182
+ const first = relationId(ownGet(row, condition.field));
183
+ if (first === void 0) return;
184
+ const rowRestricted = condition.restricted !== void 0 && ownGet(row, condition.restricted) === true;
185
+ const hopped = condition.hops !== void 0 && condition.hops.length > 0;
186
+ if ((condition.parent === true || hopped) && rowRestricted) return;
187
+ const start = hopped ? followHops(condition, first, reader) : { id: first };
188
+ if (start === void 0 || start === "relation-unavailable") return start;
189
+ const id = start.id;
190
+ if (condition.depth === 0 || rowRestricted) return {
191
+ ids: [id],
192
+ truncated: false
193
+ };
194
+ const chain = reader.chain({
195
+ resource: condition.resource,
196
+ id,
197
+ depth: condition.depth
198
+ });
199
+ if (chain === "pending" || chain === "failed") return "relation-unavailable";
200
+ const ids = [id];
201
+ let stopped = chain.restricted === true;
202
+ if (!stopped) for (const ancestor of chain.ancestors.slice(0, condition.depth)) {
203
+ ids.push(ancestor.id);
204
+ if (ancestor.restricted === true) {
205
+ stopped = true;
206
+ break;
207
+ }
208
+ }
209
+ if (new Set(ids).size !== ids.length) return "relation-depth";
210
+ return {
211
+ ids,
212
+ truncated: !stopped && (chain.ancestors.length > condition.depth || chain.truncated === true)
213
+ };
214
+ }
215
+ /**
216
+ * Whether the subject holds the relation on the row's instance or an
217
+ * ancestor within `depth`. A cycle is `relation-depth`; so is a chain that
218
+ * goes on past `depth` with no holder below it. Any read the instance could
219
+ * not answer is `relation-unavailable` unless a holder was found elsewhere.
220
+ */
221
+ function resolveRelated(condition, row, subject, now, reader) {
222
+ const principal = subject.principal;
223
+ if (principal === null) return false;
224
+ const walk = relationWalk(condition, row, reader);
225
+ if (walk === void 0) return false;
226
+ if (walk === "relation-depth" || walk === "relation-unavailable") return walk;
227
+ if (condition.ids !== void 0) {
228
+ const held = new Set(condition.ids);
229
+ if (walk.ids.some((id) => held.has(id))) return true;
230
+ return walk.truncated ? "relation-depth" : false;
231
+ }
232
+ let unavailable = false;
233
+ let deep = false;
234
+ const explored = /* @__PURE__ */ new Map();
235
+ for (const id of walk.ids) {
236
+ const verdict = holdsRelation({
237
+ resource: condition.resource,
238
+ id,
239
+ relation: condition.relation
240
+ }, principal.id, now, reader, 16, /* @__PURE__ */ new Set(), explored);
241
+ if (verdict === true) return true;
242
+ if (verdict === "relation-unavailable") unavailable = true;
243
+ else if (verdict === "relation-depth") deep = true;
244
+ }
245
+ if (unavailable) return "relation-unavailable";
246
+ return walk.truncated || deep ? "relation-depth" : false;
247
+ }
248
+ function groupKey(group) {
249
+ return JSON.stringify([
250
+ group.resource,
251
+ group.id,
252
+ group.relation
253
+ ]);
254
+ }
255
+ /**
256
+ * Whether the principal holds `at.relation` on one instance, directly or
257
+ * through a group whose members hold it. Groups of `at`'s own resource nest
258
+ * at most `budget` deep; a group of another resource gets a fresh budget
259
+ * (declarations rule out cycles across resources). A group met twice on one
260
+ * path, or one past the budget, is `relation-depth`. `explored` holds the
261
+ * budget each group was walked with across the whole walk: a group already
262
+ * walked with as much budget adds nothing, since its verdict already reached
263
+ * the caller, so shared sub-groups cost one walk rather than one per path.
264
+ */
265
+ function holdsRelation(at, principalId, now, reader, budget, seen, explored) {
266
+ const key = groupKey(at);
267
+ const walked = explored.get(key);
268
+ if (walked !== void 0 && walked >= budget) return false;
269
+ explored.set(key, budget);
270
+ const holders = reader.holders(at);
271
+ if (holders === "pending" || holders === "failed") return "relation-unavailable";
272
+ if (holders.some((holder) => holdsNow(holder, principalId, now))) return true;
273
+ const path = new Set(seen).add(key);
274
+ let unavailable = false;
275
+ let deep = false;
276
+ for (const holder of holders) {
277
+ if (!("group" in holder) || !activeNow(holder, now)) continue;
278
+ const nested = holder.group.resource === at.resource;
279
+ if (nested && budget <= 0 || path.has(groupKey(holder.group))) {
280
+ deep = true;
281
+ continue;
282
+ }
283
+ const verdict = holdsRelation(holder.group, principalId, now, reader, nested ? budget - 1 : 16, path, explored);
284
+ if (verdict === true) return true;
285
+ if (verdict === "relation-unavailable") unavailable = true;
286
+ else if (verdict === "relation-depth") deep = true;
287
+ }
288
+ if (unavailable) return "relation-unavailable";
289
+ return deep ? "relation-depth" : false;
290
+ }
291
+ /** The holder one edge-table row names for `spec`, or `undefined` when the row does not belong to it. */
292
+ function tableHolder(resourceName, spec, row, id) {
293
+ if (relationId(ownGet(row, spec.object ?? `${resourceName}_id`)) !== id) return;
294
+ for (const [column, value] of Object.entries(spec.match ?? {})) if (ownGet(row, column) !== value) return;
295
+ const subject = relationId(ownGet(row, spec.subject ?? "user_id"));
296
+ if (subject === void 0) return;
297
+ const expiresAt = spec.expiresAt === void 0 ? void 0 : seconds(ownGet(row, spec.expiresAt));
298
+ const period = expiresAt === void 0 ? {} : { expiresAt };
299
+ const groups = spec.groups;
300
+ const kind = groups === void 0 ? null : ownGet(row, groups.column);
301
+ if (groups === void 0 || kind === null || kind === void 0 || kind === groups.direct) return {
302
+ principal: { id: subject },
303
+ ...period
304
+ };
305
+ const relation = typeof kind === "string" && Object.hasOwn(groups.resources, kind) ? groups.resources[kind] : void 0;
306
+ return relation === void 0 ? void 0 : {
307
+ group: {
308
+ resource: kind,
309
+ id: subject,
310
+ relation
311
+ },
312
+ ...period
313
+ };
314
+ }
315
+ function seconds(value) {
316
+ if (value instanceof Date) {
317
+ const time = value.getTime();
318
+ return Number.isNaN(time) ? void 0 : time / 1e3;
319
+ }
320
+ if (typeof value === "number" && Number.isFinite(value)) return value;
321
+ if (typeof value === "string") {
322
+ const parsed = Date.parse(value);
323
+ return Number.isNaN(parsed) ? void 0 : parsed / 1e3;
324
+ }
325
+ }
326
+ function restrictedOf(node, row) {
327
+ return node.restricted !== void 0 && row !== void 0 && ownGet(row, node.restricted) === true;
328
+ }
329
+ function edgeHolder(edge) {
330
+ const holder = { principal: { id: edge.principal } };
331
+ if (edge.startsAt !== void 0) holder.startsAt = edge.startsAt;
332
+ if (edge.expiresAt !== void 0) holder.expiresAt = edge.expiresAt;
333
+ return holder;
334
+ }
335
+ /**
336
+ * An in-process `RelationSource` over plain rows and edges, read against the
337
+ * resource definitions in `permissions`. For tests, fixtures and small apps.
338
+ */
339
+ function memoryRelations(permissions, data = {}) {
340
+ const registry = getRegistry(permissions);
341
+ const byId = /* @__PURE__ */ new Map();
342
+ for (const [name, rows] of Object.entries(data.rows ?? {})) {
343
+ const node = registry.get(name);
344
+ const index = /* @__PURE__ */ new Map();
345
+ for (const row of rows) {
346
+ const id = relationId(ownGet(row, node?.id ?? "id"));
347
+ if (id !== void 0) index.set(id, row);
348
+ }
349
+ byId.set(name, index);
350
+ }
351
+ const rowOf = (resource, id) => byId.get(resource)?.get(id);
352
+ return {
353
+ ancestors({ resource, id, depth, through }) {
354
+ const node = registry.get(resource);
355
+ const start = rowOf(resource, id);
356
+ if (node === void 0 || start === void 0) return { ancestors: [] };
357
+ if (through !== "parent") {
358
+ const link = Object.hasOwn(node.links, through) ? node.links[through] : void 0;
359
+ const next = link === void 0 ? void 0 : relationId(ownGet(start, link.field));
360
+ if (next === void 0 || depth < 1) return { ancestors: [] };
361
+ return { ancestors: [{ id: next }] };
362
+ }
363
+ const restricted = restrictedOf(node, start);
364
+ if (restricted || node.parent === void 0 || node.parent.resource !== resource) return restricted ? {
365
+ restricted: true,
366
+ ancestors: []
367
+ } : { ancestors: [] };
368
+ const field = node.parent.field;
369
+ const seen = /* @__PURE__ */ new Set([id]);
370
+ const ancestors = [];
371
+ let next = relationId(ownGet(start, field));
372
+ while (next !== void 0 && ancestors.length < depth) {
373
+ const row = rowOf(resource, next);
374
+ if (row === void 0) {
375
+ next = void 0;
376
+ break;
377
+ }
378
+ const hidden = restrictedOf(node, row);
379
+ ancestors.push(hidden ? {
380
+ id: next,
381
+ restricted: true
382
+ } : { id: next });
383
+ if (seen.has(next) || hidden) {
384
+ next = void 0;
385
+ break;
386
+ }
387
+ seen.add(next);
388
+ next = relationId(ownGet(row, field));
389
+ }
390
+ return next === void 0 ? { ancestors } : {
391
+ ancestors,
392
+ truncated: true
393
+ };
394
+ },
395
+ related({ resource, id, relation }) {
396
+ const spec = registry.get(resource)?.relations[relation];
397
+ if (spec === void 0 || isComputedRelation(spec)) return [];
398
+ if (isEdgeRelation(spec)) {
399
+ const table = data.tables?.[spec.edge];
400
+ if (table !== void 0) return table.flatMap((row) => {
401
+ const holder = tableHolder(resource, spec, row, id);
402
+ return holder === void 0 ? [] : [holder];
403
+ });
404
+ return (data.edges?.[resource]?.[relation] ?? []).filter((edge) => edge.id === id).map(edgeHolder);
405
+ }
406
+ const row = rowOf(resource, id);
407
+ if (row === void 0) return [];
408
+ if (isPrincipalRelation(spec)) {
409
+ const holder = relationId(ownGet(row, spec.principal));
410
+ if (holder === void 0) return [];
411
+ const startsAt = spec.period?.startsAt === void 0 ? void 0 : seconds(ownGet(row, spec.period.startsAt));
412
+ const expiresAt = spec.period?.expiresAt === void 0 ? void 0 : seconds(ownGet(row, spec.period.expiresAt));
413
+ return [{
414
+ principal: { id: holder },
415
+ ...startsAt === void 0 ? {} : { startsAt },
416
+ ...expiresAt === void 0 ? {} : { expiresAt }
417
+ }];
418
+ }
419
+ if (spec.memberOf !== void 0) return [];
420
+ const holder = relationId(ownGet(row, spec.field));
421
+ return holder === void 0 ? [] : [{ principal: { id: holder } }];
422
+ }
423
+ };
424
+ }
425
+ //#endregion
426
+ export { relationWalk as a, relationReader as i, pendingRelations as n, resolveRelated as o, relationId as r, memoryRelations as t };