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,218 @@
1
+ import { t as compact } from "./compact-y6vfu2_f.js";
2
+ import { o as rootMembershipId } from "./scopes-cKVp_WTw.js";
3
+ import { n as isApprovalError } from "./errors-m3u9TmDu.js";
4
+ import { f as assertApprover, m as approverRelations } from "./helpers-DnSOrhB9.js";
5
+ //#region src/approvals/handler.ts
6
+ const PROBLEM_BASE = "https://permdock.dev/problems";
7
+ function problem(status, title, detail, slug) {
8
+ const body = {
9
+ type: `${PROBLEM_BASE}/${slug}`,
10
+ title,
11
+ status,
12
+ detail
13
+ };
14
+ return new Response(JSON.stringify(body), {
15
+ status,
16
+ headers: { "content-type": "application/problem+json" }
17
+ });
18
+ }
19
+ function json(status, body) {
20
+ return new Response(JSON.stringify(body), {
21
+ status,
22
+ headers: { "content-type": "application/json" }
23
+ });
24
+ }
25
+ function parseRoute(url, method) {
26
+ const parts = url.pathname.replace(/\/+$/u, "").split("/").filter(Boolean);
27
+ const last = parts.at(-1);
28
+ const prev = parts.at(-2);
29
+ if (last === void 0) return;
30
+ if (method === "GET" && last === "pending") return { kind: "pending" };
31
+ if (method === "GET" && last === "mine") return { kind: "mine" };
32
+ if (method === "POST" && last === "approve" && prev !== void 0) return {
33
+ kind: "approve",
34
+ token: decodeURIComponent(prev)
35
+ };
36
+ if (method === "POST" && last === "reject" && prev !== void 0) return {
37
+ kind: "reject",
38
+ token: decodeURIComponent(prev)
39
+ };
40
+ if (method === "GET" && last !== "pending" && last !== "mine") return {
41
+ kind: "get",
42
+ token: decodeURIComponent(last)
43
+ };
44
+ }
45
+ async function resolveSubject(request, resolve) {
46
+ try {
47
+ const subject = await resolve(request);
48
+ if (subject === null || subject === void 0) return null;
49
+ return subject;
50
+ } catch {
51
+ return null;
52
+ }
53
+ }
54
+ function membershipTenants(subject) {
55
+ const principal = subject.principal;
56
+ if (principal === null) return [];
57
+ const tenants = /* @__PURE__ */ new Set();
58
+ if (principal.tenant !== void 0) tenants.add(principal.tenant);
59
+ for (const membership of principal.memberships ?? []) {
60
+ const tenant = rootMembershipId(membership);
61
+ if (tenant !== void 0) tenants.add(tenant);
62
+ }
63
+ return [...tenants];
64
+ }
65
+ function belongsToTenant(subject, tenant) {
66
+ return membershipTenants(subject).includes(tenant);
67
+ }
68
+ async function mayResolve(request, subject, requireDistinct, options) {
69
+ try {
70
+ const relations = await approverRelations(request, subject, options);
71
+ assertApprover(request, subject, requireDistinct, /* @__PURE__ */ new Date(), relations);
72
+ return true;
73
+ } catch {
74
+ return false;
75
+ }
76
+ }
77
+ function canView(request, subject) {
78
+ const principal = subject.principal;
79
+ if (principal === null) return false;
80
+ if (request.subject.principal?.id === principal.id) return true;
81
+ const tenant = request.subject.principal?.tenant;
82
+ if (tenant !== void 0) return belongsToTenant(subject, tenant);
83
+ return true;
84
+ }
85
+ /**
86
+ * The tenants whose pending requests the approver may list: the requested one,
87
+ * else the active one, else every membership tenant. Requests without a tenant
88
+ * are listed only when no tenant was requested or active.
89
+ */
90
+ function pageQuery(url) {
91
+ const limit = url.searchParams.get("limit");
92
+ const cursor = url.searchParams.get("cursor");
93
+ return compact({
94
+ limit: limit === null ? void 0 : Number(limit),
95
+ cursor: cursor ?? void 0
96
+ });
97
+ }
98
+ function inboxScope(url, subject) {
99
+ const requested = url.searchParams.get("tenant");
100
+ if (requested !== null && requested !== "") {
101
+ if (!belongsToTenant(subject, requested)) return { ok: false };
102
+ return {
103
+ ok: true,
104
+ tenants: [requested],
105
+ tenantless: false
106
+ };
107
+ }
108
+ const active = subject.principal?.tenant;
109
+ if (active !== void 0) return {
110
+ ok: true,
111
+ tenants: [active],
112
+ tenantless: false
113
+ };
114
+ return {
115
+ ok: true,
116
+ tenants: membershipTenants(subject),
117
+ tenantless: true
118
+ };
119
+ }
120
+ function signedApproval(request, signer, audience) {
121
+ if (signer === void 0 || request.status !== "approved") return Promise.resolve(void 0);
122
+ const payload = { approval: {
123
+ token: request.token,
124
+ permission: request.permission,
125
+ resource: request.resource,
126
+ status: request.status
127
+ } };
128
+ if (request.subject.principal !== null) payload["sub"] = request.subject.principal.id;
129
+ return signer.sign(payload, compact({
130
+ typ: "permdock-approval+jwt",
131
+ audience,
132
+ expiresAt: Math.floor(Date.parse(request.expiresAt) / 1e3)
133
+ }));
134
+ }
135
+ async function readNote(request) {
136
+ const contentType = request.headers.get("content-type") ?? "";
137
+ if (request.method !== "POST" || contentType === "") return;
138
+ if (!contentType.includes("application/json")) return;
139
+ try {
140
+ const body = await request.json();
141
+ if (body !== null && typeof body === "object" && "note" in body && typeof body.note === "string") return body.note;
142
+ } catch {
143
+ return;
144
+ }
145
+ }
146
+ function mapError(error) {
147
+ if (!isApprovalError(error)) return problem(500, "Internal error", "approval store failed", "internal");
148
+ if (error.code === "approval-not-found") return problem(404, "Not found", error.message, "not-found");
149
+ if (error.code === "approval-not-pending" || error.code === "approval-expired" || error.code === "approver-repeated") return problem(409, "Conflict", error.message, "conflict");
150
+ if (error.code === "approver-unauthenticated") return problem(401, "Unauthenticated", error.message, "unauthenticated");
151
+ return problem(403, "Permission denied", error.message, "denied");
152
+ }
153
+ function approvalsHandler(store, options) {
154
+ const requireDistinct = options.requireDistinctApprover === true;
155
+ return async (request) => {
156
+ const url = new URL(request.url);
157
+ const route = parseRoute(url, request.method);
158
+ if (route === void 0) return problem(405, "Method not allowed", "unknown approvals route", "method-not-allowed");
159
+ await store.expire();
160
+ const subject = await resolveSubject(request, options.subject);
161
+ const principal = subject?.principal ?? null;
162
+ if (subject === null || principal === null) return problem(401, "Unauthenticated", "approver must be authenticated", "unauthenticated");
163
+ try {
164
+ if (route.kind === "pending") {
165
+ const scoped = inboxScope(url, subject);
166
+ if (!scoped.ok) return problem(403, "Permission denied", "approver does not belong to that tenant", "denied");
167
+ const page = await store.list({
168
+ ...pageQuery(url),
169
+ status: "pending"
170
+ });
171
+ const tenants = new Set(scoped.tenants);
172
+ const eligible = await Promise.all(page.items.map(async (item) => {
173
+ const tenant = item.subject.principal?.tenant;
174
+ return (tenant === void 0 ? scoped.tenantless : tenants.has(tenant)) && await mayResolve(item, subject, requireDistinct, options);
175
+ }));
176
+ return json(200, compact({
177
+ items: page.items.filter((_, index) => eligible[index] === true),
178
+ next: page.next
179
+ }));
180
+ }
181
+ if (route.kind === "mine") {
182
+ const page = await store.list({
183
+ ...pageQuery(url),
184
+ principalId: principal.id
185
+ });
186
+ return json(200, compact({
187
+ items: page.items,
188
+ next: page.next
189
+ }));
190
+ }
191
+ if (route.kind === "get") {
192
+ const current = await store.get(route.token);
193
+ if (current === null || !canView(current, subject)) return problem(404, "Not found", "approval was not found", "not-found");
194
+ return json(200, current);
195
+ }
196
+ const current = await store.get(route.token);
197
+ if (current === null) return problem(404, "Not found", "approval was not found", "not-found");
198
+ const relations = await approverRelations(current, subject, options);
199
+ assertApprover(current, subject, requireDistinct, /* @__PURE__ */ new Date(), relations);
200
+ const note = await readNote(request);
201
+ const resolved = await store.resolve(route.token, compact({
202
+ status: route.kind === "approve" ? "approved" : "rejected",
203
+ by: subject,
204
+ note,
205
+ relations
206
+ }));
207
+ const signed = await signedApproval(resolved, options.signer, options.audience);
208
+ return json(200, compact({
209
+ ...resolved,
210
+ signed
211
+ }));
212
+ } catch (error) {
213
+ return mapError(error);
214
+ }
215
+ };
216
+ }
217
+ //#endregion
218
+ export { approvalsHandler as t };
@@ -0,0 +1,20 @@
1
+ import { n as isReadonlyArray } from "./compact-y6vfu2_f.js";
2
+ //#region src/core/approvers.ts
3
+ /** A named approver for `approval.by`, matched on the approver's principal id. */
4
+ function user(id) {
5
+ if (typeof id !== "string" || id === "") throw new Error("PermDock: user() needs a non-empty principal id");
6
+ return Object.freeze({
7
+ kind: "user",
8
+ id
9
+ });
10
+ }
11
+ function isUserApprover(value) {
12
+ return value !== null && typeof value === "object" && "kind" in value && value.kind === "user";
13
+ }
14
+ function flattenApprovers(input) {
15
+ if (input === void 0) return [];
16
+ if (isReadonlyArray(input)) return input;
17
+ return [input];
18
+ }
19
+ //#endregion
20
+ export { isUserApprover as n, user as r, flattenApprovers as t };
@@ -0,0 +1,70 @@
1
+ import { p as arazzoFindings } from "./snapshot-DE8dE_hz.js";
2
+ import { a as loadModule, o as pickNamed, t as asPermissionTree } from "./load-BZ24CpZP.js";
3
+ import { existsSync, readFileSync } from "node:fs";
4
+ import { resolve } from "node:path";
5
+ //#region src/cli/arazzo.ts
6
+ async function runArazzo(input) {
7
+ if (input.rest[0] !== "check") return {
8
+ code: 2,
9
+ output: "permdock arazzo check --doc <arazzo> --openapi <doc>"
10
+ };
11
+ const docPath = input.doc;
12
+ const openapiPath = input.openapi;
13
+ if (docPath === void 0 || openapiPath === void 0) return {
14
+ code: 2,
15
+ output: "arazzo check requires --doc and --openapi"
16
+ };
17
+ const arazzoFile = resolve(input.cwd, docPath);
18
+ const openapiFile = resolve(input.cwd, openapiPath);
19
+ if (!existsSync(arazzoFile) || !existsSync(openapiFile)) return {
20
+ code: 2,
21
+ output: "arazzo check: document not found"
22
+ };
23
+ let arazzo;
24
+ let openapi;
25
+ try {
26
+ arazzo = JSON.parse(readFileSync(arazzoFile, "utf8"));
27
+ openapi = JSON.parse(readFileSync(openapiFile, "utf8"));
28
+ } catch {
29
+ return {
30
+ code: 2,
31
+ output: "arazzo check: unreadable JSON"
32
+ };
33
+ }
34
+ const from = input.from ?? input.config.permissions;
35
+ let tree;
36
+ if (from !== void 0) {
37
+ const abs = resolve(input.cwd, from);
38
+ if (!existsSync(abs)) return {
39
+ code: 2,
40
+ output: `arazzo check: permissions not found: ${from}`
41
+ };
42
+ const mod = await loadModule(abs);
43
+ tree = asPermissionTree(pickNamed(mod, ["permissions"]));
44
+ }
45
+ const findings = arazzoFindings(input.workflow === void 0 ? {
46
+ arazzo,
47
+ openapi
48
+ } : {
49
+ arazzo,
50
+ openapi,
51
+ workflowId: input.workflow
52
+ }, tree);
53
+ if (input.json) return {
54
+ code: findings.length === 0 ? 0 : 1,
55
+ output: JSON.stringify({
56
+ $schema: "permdock-arazzo-check",
57
+ findings
58
+ })
59
+ };
60
+ if (findings.length === 0) return {
61
+ code: 0,
62
+ output: "arazzo check: all steps documented"
63
+ };
64
+ return {
65
+ code: 1,
66
+ output: findings.map((finding) => `${finding.workflowId} ${finding.stepId}: ${finding.reason} (${finding.detail})`).join("\n")
67
+ };
68
+ }
69
+ //#endregion
70
+ export { runArazzo };
@@ -0,0 +1,54 @@
1
+ import { a as listArg, i as globalArgs, s as stringArg, t as COMMAND_DESCRIPTIONS } from "./commands-BMh_Etm2.js";
2
+ import { defineCommand } from "citty";
3
+ //#region src/cli/commands/arazzo.ts
4
+ function arazzo(ctx) {
5
+ return defineCommand({
6
+ meta: {
7
+ name: "arazzo",
8
+ description: COMMAND_DESCRIPTIONS.arazzo
9
+ },
10
+ args: {
11
+ ...globalArgs,
12
+ action: {
13
+ type: "positional",
14
+ required: false,
15
+ description: "check"
16
+ },
17
+ doc: {
18
+ type: "string",
19
+ description: "Arazzo document",
20
+ valueHint: "arazzo.json"
21
+ },
22
+ openapi: {
23
+ type: "string",
24
+ description: "OpenAPI document the workflows call",
25
+ valueHint: "doc.json"
26
+ },
27
+ workflow: {
28
+ type: "string",
29
+ description: "Check one workflow",
30
+ valueHint: "id"
31
+ },
32
+ from: {
33
+ type: "string",
34
+ description: "Module exporting the policy, instead of the config",
35
+ valueHint: "module"
36
+ }
37
+ },
38
+ async run({ args: parsed, rawArgs }) {
39
+ const result = await (await import("./arazzo-CTeVuXr5.js")).runArazzo({
40
+ cwd: ctx.cwd,
41
+ config: ctx.config,
42
+ rest: parsed._,
43
+ doc: listArg(rawArgs, "doc")[0],
44
+ openapi: stringArg(parsed.openapi),
45
+ workflow: stringArg(parsed.workflow),
46
+ from: stringArg(parsed.from),
47
+ json: ctx.json
48
+ });
49
+ ctx.report(result);
50
+ }
51
+ });
52
+ }
53
+ //#endregion
54
+ export { arazzo };
@@ -0,0 +1,48 @@
1
+ import { $ as DecisionSink, C as Policy, at as LimitStore, ct as MembershipSource, ft as RelationSource, mr as Principal, pt as RoleSource, sn as PolicySource, tt as EntitlementSource, xt as SnapshotSource } from "../policy-CInmNGkM.js";
2
+ import { f as ApprovalStore } from "../types-B8w5PFtS.js";
3
+ //#region src/authzen/types.d.ts
4
+ type AuthzenResourceAdapter = {
5
+ readonly load?: (id: string) => unknown;
6
+ readonly list?: (query: {
7
+ readonly where?: unknown;
8
+ }) => readonly unknown[] | Promise<readonly unknown[]>;
9
+ };
10
+ type AuthzenSubjectRecord = {
11
+ readonly id: string;
12
+ readonly [key: string]: unknown;
13
+ };
14
+ type AuthzenPermDockOptions<TUser = unknown> = {
15
+ readonly subject: (request: Request) => TUser | Promise<TUser>;
16
+ readonly anonymous?: boolean;
17
+ /**
18
+ * Allow-list over the authenticated PEP. Only a PEP it returns `true` for
19
+ * may evaluate the body's `subject`, `actor` and `delegation`; every other
20
+ * caller is evaluated as itself. Off by default.
21
+ */
22
+ readonly trustedPep?: (pep: unknown) => boolean;
23
+ readonly resources?: Readonly<Record<string, AuthzenResourceAdapter>>;
24
+ readonly subjects?: {
25
+ readonly list?: () => readonly AuthzenSubjectRecord[] | Promise<readonly AuthzenSubjectRecord[]>;
26
+ };
27
+ readonly memberships?: MembershipSource | readonly MembershipSource[];
28
+ /** The object graph for relation grants that walk a parent chain; without it they deny. */
29
+ readonly relations?: RelationSource;
30
+ readonly entitlements?: EntitlementSource;
31
+ readonly customRoles?: RoleSource;
32
+ /** Hosted grants, read once per instance; see `PolicySource`. */
33
+ readonly policies?: PolicySource;
34
+ readonly store?: ApprovalStore;
35
+ readonly sink?: DecisionSink;
36
+ readonly limits?: LimitStore;
37
+ readonly snapshots?: SnapshotSource;
38
+ readonly maxEvaluations?: number;
39
+ };
40
+ type AuthzenPermDock = {
41
+ readonly permdockHandler: (request: Request) => Promise<Response>;
42
+ };
43
+ type AuthzenFactory = <TUser, TPrincipal extends Principal = Principal>(policy: Policy<TUser, TPrincipal>, options: AuthzenPermDockOptions<TUser>) => AuthzenPermDock;
44
+ //#endregion
45
+ //#region src/authzen/create.d.ts
46
+ export declare const createPermDock: AuthzenFactory;
47
+ //#endregion
48
+ export type { AuthzenFactory, AuthzenPermDock, AuthzenPermDockOptions, AuthzenResourceAdapter, AuthzenSubjectRecord };