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,324 @@
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 { g as listPermissions } from "../permissions-DC7GROPA.js";
4
+ import { d as role, t as allow } from "../policy-ANp36PnI.js";
5
+ import { t as ignoreRejection } from "../thenable-okc2xDsj.js";
6
+ import { t as anonymousSubject } from "../subject-C6dLxqHU.js";
7
+ import { i as membershipEvent } from "../sink-Bd9PSyfq.js";
8
+ //#region src/better-auth/parse.ts
9
+ function isRecord(value) {
10
+ return value !== null && typeof value === "object" && !Array.isArray(value);
11
+ }
12
+ function asRoles(value) {
13
+ if (typeof value === "string") return value === "" ? [] : value.split(",").map((item) => item.trim()).filter((item) => item !== "");
14
+ if (!Array.isArray(value)) return [];
15
+ return value.filter((item) => typeof item === "string");
16
+ }
17
+ function asStatements(value) {
18
+ if (!isRecord(value)) return {};
19
+ const out = {};
20
+ for (const [resource, actions] of Object.entries(value)) {
21
+ if (!Array.isArray(actions)) continue;
22
+ out[resource] = actions.filter((action) => typeof action === "string");
23
+ }
24
+ return out;
25
+ }
26
+ function expiresAtSeconds(value) {
27
+ if (typeof value === "number" && Number.isFinite(value)) return value > 0xe8d4a51000 ? Math.floor(value / 1e3) : Math.floor(value);
28
+ if (value instanceof Date) {
29
+ const ms = value.getTime();
30
+ return Number.isFinite(ms) ? Math.floor(ms / 1e3) : void 0;
31
+ }
32
+ if (typeof value === "string") {
33
+ const parsed = Date.parse(value);
34
+ return Number.isNaN(parsed) ? void 0 : Math.floor(parsed / 1e3);
35
+ }
36
+ }
37
+ function unwrapList(value) {
38
+ if (Array.isArray(value)) return value;
39
+ if (!isRecord(value)) return [];
40
+ for (const key of [
41
+ "members",
42
+ "teams",
43
+ "organizations",
44
+ "roles",
45
+ "data",
46
+ "items"
47
+ ]) {
48
+ const inner = value[key];
49
+ if (Array.isArray(inner)) return inner;
50
+ }
51
+ return [];
52
+ }
53
+ /**
54
+ * Member rows for `userId` only. `listMembers` returns every member of an
55
+ * organization, so a row without the caller's `userId` is never theirs.
56
+ */
57
+ function parseMemberRows(value, userId, requireUserId = true) {
58
+ const out = [];
59
+ const rows = isRecord(value) && typeof value["organizationId"] === "string" ? [value] : unwrapList(value);
60
+ for (const item of rows) {
61
+ if (!isRecord(item)) continue;
62
+ const owner = typeof item["userId"] === "string" ? item["userId"] : void 0;
63
+ if (owner === void 0 ? requireUserId : owner !== userId) continue;
64
+ const tenant = typeof item["organizationId"] === "string" ? item["organizationId"] : void 0;
65
+ const roles = asRoles(item["role"] ?? item["roles"]);
66
+ if (tenant === void 0 || roles.length === 0) continue;
67
+ out.push(compact({
68
+ tenant,
69
+ roles
70
+ }));
71
+ }
72
+ return out;
73
+ }
74
+ function parseTeamRows(value, userId) {
75
+ const out = [];
76
+ for (const item of unwrapList(value)) {
77
+ if (!isRecord(item)) continue;
78
+ if (typeof item["userId"] === "string" && item["userId"] !== userId) continue;
79
+ const teamRecord = isRecord(item["team"]) ? item["team"] : void 0;
80
+ const team = typeof item["teamId"] === "string" ? item["teamId"] : typeof teamRecord?.["id"] === "string" ? teamRecord["id"] : void 0;
81
+ const tenant = typeof item["organizationId"] === "string" ? item["organizationId"] : typeof teamRecord?.["organizationId"] === "string" ? teamRecord["organizationId"] : void 0;
82
+ const roles = asRoles(item["role"] ?? item["roles"]);
83
+ if (team === void 0 || roles.length === 0) continue;
84
+ out.push(compact({
85
+ tenant,
86
+ team,
87
+ roles,
88
+ via: `team:${team}`
89
+ }));
90
+ }
91
+ return out;
92
+ }
93
+ function parseOrganizationRoles(value) {
94
+ const out = [];
95
+ for (const item of unwrapList(value)) {
96
+ if (!isRecord(item)) continue;
97
+ const name = typeof item["role"] === "string" ? item["role"] : typeof item["name"] === "string" ? item["name"] : void 0;
98
+ if (name === void 0 || name === "") continue;
99
+ out.push({
100
+ name,
101
+ statements: asStatements(item["permission"] ?? item["permissions"] ?? item["statements"])
102
+ });
103
+ }
104
+ return out;
105
+ }
106
+ function statementsCover(candidate, required) {
107
+ for (const [resource, actions] of Object.entries(required)) {
108
+ const held = candidate[resource];
109
+ if (held === void 0) return false;
110
+ const set = new Set(held);
111
+ for (const action of actions) if (!set.has(action)) return false;
112
+ }
113
+ return true;
114
+ }
115
+ //#endregion
116
+ //#region src/better-auth/roles.ts
117
+ function statementsOf(accessRole) {
118
+ return asStatements(accessRole.statements ?? accessRole.permissions);
119
+ }
120
+ function rolesFromAccessControl(access, permissions, options = {}) {
121
+ const leaves = listPermissions(permissions);
122
+ const unmatched = [];
123
+ const roles = [];
124
+ for (const [name, accessRole] of Object.entries(access.roles)) {
125
+ const statements = statementsOf(accessRole);
126
+ const grants = [];
127
+ for (const [resource, actions] of Object.entries(statements)) for (const action of actions) {
128
+ const leaf = leaves.find((item) => item.resource === resource && item.action === action);
129
+ if (leaf === void 0) {
130
+ unmatched.push({
131
+ role: name,
132
+ resource,
133
+ action
134
+ });
135
+ continue;
136
+ }
137
+ grants.push(allow(leaf));
138
+ }
139
+ roles.push(options.on === "tenant" ? role(name, grants, { on: "tenant" }) : role(name, grants));
140
+ }
141
+ return Object.assign(roles, { unmatched });
142
+ }
143
+ function betterAuthRoleSource(auth, options = {}) {
144
+ const assignableRoles = options.assignable ?? [];
145
+ return {
146
+ async rolesFor(tenant) {
147
+ try {
148
+ return parseOrganizationRoles(await auth.api?.listOrganizationRoles?.({
149
+ query: { organizationId: tenant },
150
+ headers: options.headers
151
+ })).map((item) => freezeDeep(compact({
152
+ tenant,
153
+ name: item.name,
154
+ includes: assignableRoles.filter((declared) => statementsCover(item.statements, declared.statements)).map((declared) => declared.name)
155
+ })));
156
+ } catch {
157
+ return [];
158
+ }
159
+ },
160
+ assignable() {
161
+ return assignableRoles.map((item) => item.name);
162
+ }
163
+ };
164
+ }
165
+ /** A team role sits in the second scope inside its organization; an organization role in the first. */
166
+ function scopeOfChange(event) {
167
+ const tenant = event.organizationId;
168
+ if (tenant === void 0) return {};
169
+ return event.teamId === void 0 ? {
170
+ scope: "tenant",
171
+ id: tenant
172
+ } : {
173
+ scope: "team",
174
+ id: event.teamId,
175
+ within: { tenant }
176
+ };
177
+ }
178
+ function onRoleChange(refresh, options = {}) {
179
+ return async (event) => {
180
+ await refresh(event);
181
+ const sink = options.sink;
182
+ if (sink === void 0 || event.userId === void 0) return;
183
+ const added = event.role !== void 0 && event.role !== event.previousRole ? [event.role] : [];
184
+ const removed = event.previousRole !== void 0 && event.previousRole !== event.role ? [event.previousRole] : [];
185
+ const operation = event.previousRole === void 0 ? "added" : event.role === void 0 ? "removed" : "changed";
186
+ try {
187
+ await sink.write([membershipEvent(compact({
188
+ source: "better-auth",
189
+ operation,
190
+ principal: { id: event.userId },
191
+ ...scopeOfChange(event),
192
+ roles: {
193
+ added,
194
+ removed
195
+ },
196
+ by: event.by
197
+ }))]);
198
+ } catch {}
199
+ };
200
+ }
201
+ //#endregion
202
+ //#region src/better-auth/subject.ts
203
+ const PROFILE_FIELDS = /* @__PURE__ */ new Set([
204
+ "name",
205
+ "image",
206
+ "displayName"
207
+ ]);
208
+ function validateClaims(extra, schema) {
209
+ const result = schema["~standard"].validate(extra);
210
+ if (result instanceof Promise) {
211
+ ignoreRejection(result);
212
+ return;
213
+ }
214
+ if ("issues" in result && result.issues !== void 0) return;
215
+ const value = result.value;
216
+ return isRecord(value) ? value : void 0;
217
+ }
218
+ function extraFields(user) {
219
+ const reserved = /* @__PURE__ */ new Set([
220
+ "id",
221
+ "role",
222
+ "roles",
223
+ "email",
224
+ "emailVerified",
225
+ "createdAt",
226
+ "updatedAt",
227
+ "banned",
228
+ "banReason",
229
+ "banExpires"
230
+ ]);
231
+ const extra = {};
232
+ for (const [key, value] of Object.entries(user)) {
233
+ if (reserved.has(key) || PROFILE_FIELDS.has(key)) continue;
234
+ extra[key] = value;
235
+ }
236
+ return extra;
237
+ }
238
+ function isTrustedSession(session) {
239
+ if (!isRecord(session)) return false;
240
+ return isRecord(session["user"]) || isRecord(session["session"]);
241
+ }
242
+ async function settle(load, fallback) {
243
+ try {
244
+ return await load();
245
+ } catch {
246
+ return fallback;
247
+ }
248
+ }
249
+ async function organizationIds(auth, tenant, options) {
250
+ const list = auth.api?.listOrganizations;
251
+ if (options.memberships === "active" || list === void 0) return tenant === void 0 ? [] : [tenant];
252
+ const ids = (await settle(async () => {
253
+ const value = await list({ headers: options.headers });
254
+ return isReadonlyArray(value) ? value : [];
255
+ }, [])).map((row) => isRecord(row) && typeof row["id"] === "string" ? row["id"] : void 0).filter((id) => id !== void 0 && id !== "");
256
+ return [...new Set(ids)];
257
+ }
258
+ function memberIn(auth, userId, organizationId, tenant, headers) {
259
+ const active = auth.api?.getActiveMember;
260
+ if (organizationId === tenant && active !== void 0) return settle(async () => parseMemberRows(await active({ headers }), userId), []);
261
+ const list = auth.api?.listMembers;
262
+ if (list === void 0) return Promise.resolve([]);
263
+ return settle(async () => parseMemberRows(await list({
264
+ query: {
265
+ organizationId,
266
+ filterField: "userId",
267
+ filterOperator: "eq",
268
+ filterValue: userId
269
+ },
270
+ headers
271
+ }), userId).filter((item) => item.tenant === organizationId), []);
272
+ }
273
+ async function loadMemberships(auth, session, user, userId, tenant, options) {
274
+ let members = parseMemberRows(session["members"] ?? session["member"] ?? user["members"], userId, false);
275
+ let teams = parseTeamRows(session["teamMembers"] ?? session["teams"] ?? user["teamMembers"], userId);
276
+ const headers = options.headers;
277
+ if (members.length === 0) {
278
+ const ids = await organizationIds(auth, tenant, options);
279
+ members = (await Promise.all(ids.map((id) => memberIn(auth, userId, id, tenant, headers)))).flat();
280
+ }
281
+ const listUserTeams = auth.api?.listUserTeams;
282
+ if (teams.length === 0 && listUserTeams !== void 0) teams = await settle(async () => parseTeamRows(await listUserTeams({ headers }), userId), []);
283
+ if (options.memberships === "active" && tenant !== void 0) {
284
+ members = members.filter((item) => item.tenant === tenant);
285
+ teams = teams.filter((item) => item.tenant === tenant);
286
+ }
287
+ return [...members, ...teams];
288
+ }
289
+ async function subjectFromBetterAuth(auth, session, options = {}) {
290
+ try {
291
+ if (session === null || session === void 0 || !isTrustedSession(session)) return anonymousSubject();
292
+ if (!isRecord(session["user"])) return anonymousSubject();
293
+ const user = session["user"];
294
+ const record = isRecord(session["session"]) ? session["session"] : void 0;
295
+ const id = typeof user["id"] === "string" ? user["id"] : void 0;
296
+ if (id === void 0 || id === "") return anonymousSubject();
297
+ const tenant = typeof record?.["activeOrganizationId"] === "string" ? record["activeOrganizationId"] : void 0;
298
+ const roles = asRoles(user["role"] ?? user["roles"]);
299
+ const declared = options.declared;
300
+ const globalRoles = declared === void 0 ? roles : roles.filter((role) => declared.includes(role));
301
+ let extra = extraFields(user);
302
+ if (options.schema !== void 0) extra = validateClaims(extra, options.schema) ?? {};
303
+ const memberships = await loadMemberships(auth, session, user, id, tenant, options);
304
+ const principal = compact({
305
+ id,
306
+ kind: "user",
307
+ roles: globalRoles,
308
+ tenant,
309
+ memberships,
310
+ email: typeof user["email"] === "string" ? user["email"] : void 0,
311
+ claims: Object.keys(extra).length === 0 ? void 0 : extra
312
+ });
313
+ return freezeDeep(compact({
314
+ principal,
315
+ context: {},
316
+ session: typeof record?.["id"] === "string" ? record["id"] : void 0,
317
+ expiresAt: expiresAtSeconds(record?.["expiresAt"])
318
+ }));
319
+ } catch {
320
+ return anonymousSubject();
321
+ }
322
+ }
323
+ //#endregion
324
+ export { betterAuthRoleSource, onRoleChange, rolesFromAccessControl, subjectFromBetterAuth };
@@ -0,0 +1,11 @@
1
+ //#region src/supabase/budget.d.ts
2
+ /** The default size budget, in bytes of JSON, for the hook's `memberships` claim: about 15 UUID-keyed single-role memberships. */
3
+ declare const supabaseMembershipsBudget = 1024;
4
+ /**
5
+ * The default claim that carries the active first-scope id: the hook writes
6
+ * it, `subjectFromSupabase` reads it, and the RLS helpers compare with it.
7
+ * `rls.tenantClaim` and the `tenant` option change it.
8
+ */
9
+ declare const supabaseTenantClaim = "tenant_id";
10
+ //#endregion
11
+ export { supabaseTenantClaim as n, supabaseMembershipsBudget as t };
@@ -0,0 +1,11 @@
1
+ //#region src/supabase/budget.ts
2
+ /** The default size budget, in bytes of JSON, for the hook's `memberships` claim: about 15 UUID-keyed single-role memberships. */
3
+ const supabaseMembershipsBudget = 1024;
4
+ /**
5
+ * The default claim that carries the active first-scope id: the hook writes
6
+ * it, `subjectFromSupabase` reads it, and the RLS helpers compare with it.
7
+ * `rls.tenantClaim` and the `tenant` option change it.
8
+ */
9
+ const supabaseTenantClaim = "tenant_id";
10
+ //#endregion
11
+ export { supabaseTenantClaim as n, supabaseMembershipsBudget as t };
@@ -0,0 +1,171 @@
1
+ import { t as compact } from "./compact-y6vfu2_f.js";
2
+ import { n as freezeDeep } from "./freeze-y1_jQL4v.js";
3
+ import { S as isForbiddenKey, g as listPermissions } from "./permissions-DC7GROPA.js";
4
+ import { t as anonymousSubject } from "./subject-C6dLxqHU.js";
5
+ //#region src/core/capability.ts
6
+ function redeemerKind(redeemer) {
7
+ if (redeemer === void 0 || typeof redeemer === "string") return redeemer ?? "anyone";
8
+ return "user" in redeemer ? "user" : "scope";
9
+ }
10
+ /**
11
+ * The first rule of `policy` the capability breaks, or `undefined`. A
12
+ * lifetime rule without a known `issuedAt`, or one that is not a finite
13
+ * non-negative number, is broken: the check fails closed.
14
+ */
15
+ function linkPolicyViolation(capability, policy, issuedAt) {
16
+ const policies = Array.isArray(policy) ? policy : [policy];
17
+ for (const item of policies) {
18
+ const max = item.maxLifetime;
19
+ if (max !== void 0 && (typeof max !== "number" || !Number.isFinite(max) || max < 0 || issuedAt === void 0 || capability.expiresAt - issuedAt > max)) return "lifetime";
20
+ if (item.redeemers !== void 0 && !item.redeemers.includes(redeemerKind(capability.redeemer))) return "redeemer";
21
+ if (item.once === true && capability.once !== true) return "once";
22
+ }
23
+ }
24
+ const MAX_ID = 256;
25
+ const MAX_ENTRIES = 64;
26
+ /** A copy holding only own enumerable properties, so a prototype never supplies a field. */
27
+ function ownRecord(value) {
28
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return;
29
+ const record = {};
30
+ for (const [key, item] of Object.entries(value)) if (!isForbiddenKey(key)) record[key] = item;
31
+ return record;
32
+ }
33
+ function isId(value) {
34
+ return typeof value === "string" && value.length > 0 && value.length <= MAX_ID;
35
+ }
36
+ function idList(value) {
37
+ if (!Array.isArray(value) || value.length === 0 || value.length > MAX_ENTRIES || !value.every(isId)) return;
38
+ return [...new Set(value)];
39
+ }
40
+ function parseRedeemer(input) {
41
+ if (input === "anyone" || input === "signed-in") return input;
42
+ const value = ownRecord(input);
43
+ if (value === void 0) return;
44
+ const keys = Object.keys(value);
45
+ if (keys.length === 1 && isId(value["user"])) return { user: value["user"] };
46
+ if (keys.length === 2 && isId(value["scope"]) && isId(value["id"])) return {
47
+ scope: value["scope"],
48
+ id: value["id"]
49
+ };
50
+ }
51
+ /**
52
+ * Validates an untrusted `capability` claim and returns a frozen copy with
53
+ * only the v1 fields, or `undefined`. Unknown fields are dropped; a wrong
54
+ * type in a known field rejects the whole claim.
55
+ */
56
+ function parseCapability(input) {
57
+ const value = ownRecord(input);
58
+ if (value === void 0 || value["v"] !== 1 || !isId(value["id"])) return;
59
+ if (value["holder"] !== "link" && value["holder"] !== "key") return;
60
+ const on = ownRecord(value["on"]);
61
+ if (on === void 0 || !isId(on["resource"]) || !isId(on["id"])) return;
62
+ const roles = idList(value["roles"]);
63
+ if (roles === void 0) return;
64
+ const permissions = value["permissions"] === void 0 ? void 0 : idList(value["permissions"]);
65
+ if (value["permissions"] !== void 0 && permissions === void 0) return;
66
+ const redeemer = value["redeemer"] === void 0 ? void 0 : parseRedeemer(value["redeemer"]);
67
+ if (value["redeemer"] !== void 0 && redeemer === void 0) return;
68
+ if (value["once"] !== void 0 && value["once"] !== true) return;
69
+ const expiresAt = value["expiresAt"];
70
+ if (typeof expiresAt !== "number" || !Number.isFinite(expiresAt)) return;
71
+ return freezeDeep(compact({
72
+ v: 1,
73
+ id: value["id"],
74
+ holder: value["holder"],
75
+ on: {
76
+ resource: on["resource"],
77
+ id: on["id"]
78
+ },
79
+ roles,
80
+ permissions,
81
+ redeemer,
82
+ once: value["once"],
83
+ expiresAt
84
+ }));
85
+ }
86
+ function resourceName(resource) {
87
+ const names = new Set(listPermissions(resource).map((leaf) => leaf.resource));
88
+ const [name] = names;
89
+ if (names.size !== 1 || name === void 0) throw new Error("PermDock: capability on.resource must name exactly one resource");
90
+ return name;
91
+ }
92
+ /** Builds the v1 `Capability` for `input`; throws on an input no resolver would accept. */
93
+ function capabilityOf(input) {
94
+ const capability = parseCapability(compact({
95
+ v: 1,
96
+ id: input.id,
97
+ holder: "link",
98
+ on: {
99
+ resource: resourceName(input.on.resource),
100
+ id: input.on.id
101
+ },
102
+ roles: input.roles,
103
+ permissions: input.permissions?.map((permission) => permission.key),
104
+ redeemer: input.redeemer,
105
+ once: input.once === true ? true : void 0,
106
+ expiresAt: Math.floor(input.expiresAt)
107
+ }));
108
+ if (capability === void 0) throw new Error("PermDock: invalid capability (id, on.id and roles are required; roles and permissions hold at most 64 entries)");
109
+ return capability;
110
+ }
111
+ /**
112
+ * Signs a capability as a `permdock-capability+jwt`: `sub` is the link id,
113
+ * `exp` is `expiresAt`, and the signer sets `iss`, `iat` and a fresh `jti`.
114
+ */
115
+ function signCapability(input, signer, options = {}) {
116
+ const capability = capabilityOf(input);
117
+ const violation = options.linkPolicy === void 0 ? void 0 : linkPolicyViolation(capability, options.linkPolicy, Math.floor(Date.now() / 1e3));
118
+ if (violation !== void 0) return Promise.reject(/* @__PURE__ */ new Error(`PermDock: capability breaks the link policy (${violation})`));
119
+ return signer.sign({
120
+ capability,
121
+ sub: capability.id
122
+ }, compact({
123
+ typ: "permdock-capability+jwt",
124
+ audience: options.audience,
125
+ expiresAt: capability.expiresAt
126
+ }));
127
+ }
128
+ function holdsScope(membership, scope, id, now) {
129
+ if (membership.expiresAt !== void 0 && membership.expiresAt <= now) return false;
130
+ if (membership.scope === scope && membership.id === id) return true;
131
+ return scope === "tenant" && membership.tenant === id || scope === "team" && membership.team === id;
132
+ }
133
+ /** Whether `viewer`, the request's own verified subject, may redeem a capability. */
134
+ function redeemerAllows(redeemer, viewer, now = Date.now() / 1e3) {
135
+ if (redeemer === void 0 || redeemer === "anyone") return true;
136
+ const principal = viewer?.principal ?? null;
137
+ if (principal === null || principal.kind === "link") return false;
138
+ if (redeemer === "signed-in") return true;
139
+ if ("user" in redeemer) return principal.id === redeemer.user;
140
+ return (principal.memberships ?? []).some((membership) => holdsScope(membership, redeemer.scope, redeemer.id, now));
141
+ }
142
+ /**
143
+ * The subject a verified capability acts as: a `link` principal holding
144
+ * `roles` on `on` and nothing else, with `delegation.scopes` narrowing it to
145
+ * `permissions` when the capability lists them. A `key` holder resolves to
146
+ * the anonymous subject until user-bound credentials ship.
147
+ */
148
+ function capabilitySubject(capability, options = {}) {
149
+ if (capability.holder !== "link") return anonymousSubject();
150
+ const membership = {
151
+ on: capability.on,
152
+ roles: capability.roles,
153
+ via: "link",
154
+ expiresAt: capability.expiresAt
155
+ };
156
+ const principal = compact({
157
+ id: capability.id,
158
+ kind: "link",
159
+ issuer: options.issuer,
160
+ memberships: [membership],
161
+ capability
162
+ });
163
+ return freezeDeep(compact({
164
+ principal,
165
+ delegation: capability.permissions === void 0 ? void 0 : { scopes: capability.permissions.map((key) => key.replaceAll(".", ":")) },
166
+ context: {},
167
+ expiresAt: capability.expiresAt
168
+ }));
169
+ }
170
+ //#endregion
171
+ export { ownRecord as a, signCapability as c, linkPolicyViolation as i, idList as n, parseCapability as o, isId as r, redeemerAllows as s, capabilitySubject as t };
@@ -0,0 +1,99 @@
1
+ import { Tt as TokenSigner, hr as Subject, mr as Principal } from "./policy-CInmNGkM.js";
2
+ import { d as Permission, p as PermissionTree } from "./permissions-B4apnahQ.js";
3
+ //#region src/core/capability.d.ts
4
+ /**
5
+ * Who may redeem a capability: anyone holding it, any signed-in principal,
6
+ * one user, or a member of one scope instance. The viewer is the request's
7
+ * own verified subject, never a claim of the capability.
8
+ */
9
+ type CapabilityRedeemer = "anyone" | "signed-in" | {
10
+ readonly user: string;
11
+ } | {
12
+ readonly scope: string;
13
+ readonly id: string;
14
+ };
15
+ /**
16
+ * Capability v1: the `capability` claim of a `permdock-capability+jwt`. It
17
+ * holds `roles` on one resource instance (`on`, the `Membership.on` shape),
18
+ * optionally narrowed to `permissions` (keys). `id` is the link id: the
19
+ * token's `sub` and the handle an application revokes.
20
+ */
21
+ type Capability = {
22
+ readonly v: 1;
23
+ readonly id: string;
24
+ /** `key` is reserved for user-bound credentials and resolves to no subject. */
25
+ readonly holder: "link" | "key";
26
+ readonly on: {
27
+ readonly resource: string;
28
+ readonly id: string;
29
+ };
30
+ readonly roles: readonly string[];
31
+ readonly permissions?: readonly string[];
32
+ readonly redeemer?: CapabilityRedeemer;
33
+ /** One request per token: the resolver claims the token's `jti` in a `ReplayStore`. */
34
+ readonly once?: true;
35
+ /** Seconds since the epoch; also the token's `exp` and the membership's `expiresAt`. */
36
+ readonly expiresAt: number;
37
+ };
38
+ type LinkPrincipal = Principal & {
39
+ readonly kind: "link";
40
+ readonly capability: Capability;
41
+ };
42
+ type CapabilityInput = {
43
+ readonly id: string;
44
+ readonly on: {
45
+ readonly resource: Permission | PermissionTree;
46
+ readonly id: string;
47
+ };
48
+ readonly roles: readonly string[];
49
+ readonly permissions?: readonly Permission[];
50
+ readonly redeemer?: CapabilityRedeemer;
51
+ readonly once?: boolean;
52
+ readonly expiresAt: number;
53
+ };
54
+ /**
55
+ * What one scope instance (a tenant, a customer) allows for links on its
56
+ * resources. Every field only tightens; several policies must all hold.
57
+ */
58
+ type LinkPolicy = {
59
+ /** Longest a link may live, in seconds from when it was issued. */
60
+ readonly maxLifetime?: number;
61
+ /** Redeemer kinds allowed; `anyone` also covers a capability without `redeemer`. */
62
+ readonly redeemers?: readonly ("anyone" | "signed-in" | "user" | "scope")[];
63
+ /** Every link must be one-time. */
64
+ readonly once?: boolean;
65
+ };
66
+ type LinkPolicyViolation = "lifetime" | "redeemer" | "once";
67
+ type SignCapabilityOptions = {
68
+ readonly audience?: string | readonly string[];
69
+ /** Refuse to sign a link these policies would refuse at resolution. */
70
+ readonly linkPolicy?: LinkPolicy | readonly LinkPolicy[];
71
+ };
72
+ /**
73
+ * The first rule of `policy` the capability breaks, or `undefined`. A
74
+ * lifetime rule without a known `issuedAt`, or one that is not a finite
75
+ * non-negative number, is broken: the check fails closed.
76
+ */
77
+ declare function linkPolicyViolation(capability: Capability, policy: LinkPolicy | readonly LinkPolicy[], issuedAt: number | undefined): LinkPolicyViolation | undefined;
78
+ /**
79
+ * Validates an untrusted `capability` claim and returns a frozen copy with
80
+ * only the v1 fields, or `undefined`. Unknown fields are dropped; a wrong
81
+ * type in a known field rejects the whole claim.
82
+ */
83
+ declare function parseCapability(input: unknown): Capability | undefined;
84
+ /**
85
+ * Signs a capability as a `permdock-capability+jwt`: `sub` is the link id,
86
+ * `exp` is `expiresAt`, and the signer sets `iss`, `iat` and a fresh `jti`.
87
+ */
88
+ declare function signCapability(input: CapabilityInput, signer: TokenSigner, options?: SignCapabilityOptions): Promise<string>;
89
+ /**
90
+ * The subject a verified capability acts as: a `link` principal holding
91
+ * `roles` on `on` and nothing else, with `delegation.scopes` narrowing it to
92
+ * `permissions` when the capability lists them. A `key` holder resolves to
93
+ * the anonymous subject until user-bound credentials ship.
94
+ */
95
+ declare function capabilitySubject(capability: Capability, options?: {
96
+ readonly issuer?: string;
97
+ }): Subject<LinkPrincipal> | Subject;
98
+ //#endregion
99
+ export { LinkPolicyViolation as a, capabilitySubject as c, signCapability as d, LinkPolicy as i, linkPolicyViolation as l, CapabilityInput as n, LinkPrincipal as o, CapabilityRedeemer as r, SignCapabilityOptions as s, Capability as t, parseCapability as u };
@@ -0,0 +1,12 @@
1
+ import { a as CatalogDocument, c as CatalogResource, d as CatalogSupportAccess, f as CatalogUsage, i as CatalogDelegation, l as CatalogRole, n as CatalogApproval, o as CatalogGrant, p as CatalogValidity, r as CatalogBreakGlass, s as CatalogPermission, t as CatalogActivation, u as CatalogScope } from "../types-BBK-exvJ.js";
2
+ //#region src/catalog/parse.d.ts
3
+ /**
4
+ * Reads a `permissions.catalog.json` document (parsed, or the JSON text) and
5
+ * validates it against `schemas/catalog-v1.json`. Returns a deep-frozen copy
6
+ * built from own keys; throws `PermDockValidationError` with every issue.
7
+ */
8
+ export declare function parseCatalog(json: unknown): CatalogDocument;
9
+ /** Keys of the permissions the catalog marks `rowConditions: true`: the SQL helpers alone cannot enforce them. */
10
+ export declare function rowConditionKeys(catalog: CatalogDocument): ReadonlySet<string>;
11
+ //#endregion
12
+ export type { CatalogActivation, CatalogApproval, CatalogBreakGlass, CatalogDelegation, CatalogDocument, CatalogGrant, CatalogPermission, CatalogResource, CatalogRole, CatalogScope, CatalogSupportAccess, CatalogUsage, CatalogValidity };
@@ -0,0 +1,2 @@
1
+ import { n as rowConditionKeys, t as parseCatalog } from "../parse-DPfIvFMU.js";
2
+ export { parseCatalog, rowConditionKeys };
@@ -0,0 +1,48 @@
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/catalog.ts
4
+ function catalog(ctx) {
5
+ return defineCommand({
6
+ meta: {
7
+ name: "catalog",
8
+ description: COMMAND_DESCRIPTIONS.catalog
9
+ },
10
+ args: {
11
+ ...globalArgs,
12
+ format: {
13
+ type: "enum",
14
+ options: [
15
+ "json",
16
+ "schema",
17
+ "markdown"
18
+ ],
19
+ default: "json",
20
+ description: "Output format"
21
+ },
22
+ from: {
23
+ type: "string",
24
+ description: "Module exporting the permissions, instead of the config",
25
+ valueHint: "module"
26
+ },
27
+ include: {
28
+ type: "string",
29
+ description: "Permission keys or prefixes to keep, repeatable",
30
+ valueHint: "key"
31
+ }
32
+ },
33
+ async run({ args: parsed, rawArgs }) {
34
+ const result = await (await import("./catalog-idsHc0vo.js")).runCatalog({
35
+ cwd: ctx.cwd,
36
+ config: ctx.config,
37
+ format: parsed.format,
38
+ from: stringArg(parsed.from),
39
+ include: listArg(rawArgs, "include"),
40
+ now: ctx.now,
41
+ io: ctx.io
42
+ });
43
+ ctx.report(result);
44
+ }
45
+ });
46
+ }
47
+ //#endregion
48
+ export { catalog };