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,350 @@
1
+ import { i as formatCatalogJson, n as catalogForCompare, t as buildCatalog } from "./catalog-doc-BSo_Q_-6.js";
2
+ import { t as catalogPath } from "./catalog-path-CnI0XTFK.js";
3
+ import { n as listSourceFiles, r as rel, t as defaultSrcPath } from "./files-B_wAGYmt.js";
4
+ import { a as loadModule, i as loadConfiguredPolicy, o as pickNamed, r as leavesOf, t as asPermissionTree } from "./load-BZ24CpZP.js";
5
+ import { t as shortDiff } from "./text-diff-BdkkYSbi.js";
6
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
7
+ import { dirname, relative, resolve } from "node:path";
8
+ import { Visitor, parseSync, visitorKeys } from "oxc-parser";
9
+ //#region src/cli/scan.ts
10
+ const CHECK_CALLS = /* @__PURE__ */ new Set([
11
+ "can",
12
+ "decide",
13
+ "assert",
14
+ "filter",
15
+ "where",
16
+ "simulate",
17
+ "actions",
18
+ "usePermission",
19
+ "getPermission",
20
+ "protect",
21
+ "allow",
22
+ "deny",
23
+ "registerTool",
24
+ "anyone",
25
+ "authenticated",
26
+ "relation",
27
+ "plan",
28
+ "actor",
29
+ "assurance"
30
+ ]);
31
+ function scanSources(cwd, files, knownKeys) {
32
+ const roots = /* @__PURE__ */ new Set(["permissions"]);
33
+ const definitionFiles = {};
34
+ const usages = {};
35
+ const unknown = [];
36
+ const dynamic = [];
37
+ const roleNames = /* @__PURE__ */ new Set();
38
+ const planNames = /* @__PURE__ */ new Set();
39
+ const allowKeys = /* @__PURE__ */ new Set();
40
+ const snapshots = [];
41
+ for (const file of files) {
42
+ const source = readFileSync(file, "utf8");
43
+ let program;
44
+ try {
45
+ program = parseSync(file, source).program;
46
+ } catch {
47
+ continue;
48
+ }
49
+ const fileRel = rel(cwd, file);
50
+ walk(program, (node, parent) => {
51
+ if (node.type === "CallExpression") {
52
+ recordCall(node, parent, source, fileRel, roots, definitionFiles, usages, unknown, dynamic, roleNames, planNames, allowKeys, knownKeys);
53
+ const callee = calleeName(node.callee);
54
+ if (callee === "snapshot" || callee === "snapshotFor") snapshots.push({
55
+ file: fileRel,
56
+ line: lineAt(source, node.start ?? 0),
57
+ include: includeOf(node.arguments?.[callee === "snapshot" ? 0 : 2], roots)
58
+ });
59
+ }
60
+ if (node.type === "MemberExpression" && parent?.type !== "MemberExpression") recordMember(node, parent, source, fileRel, roots, usages, unknown, dynamic, allowKeys, knownKeys);
61
+ if (node.type === "ImportDeclaration") recordImport(node, roots);
62
+ });
63
+ }
64
+ return {
65
+ roots: [...roots].toSorted(),
66
+ definitionFiles,
67
+ usages,
68
+ unknown,
69
+ dynamic,
70
+ roleNames: [...roleNames].toSorted(),
71
+ planNames: [...planNames].toSorted(),
72
+ allowKeys: [...allowKeys].toSorted(),
73
+ snapshots
74
+ };
75
+ }
76
+ function includeOf(options, roots) {
77
+ if (options?.type !== "ObjectExpression") return options === void 0 ? void 0 : null;
78
+ const property = options.properties?.find((item) => item.key?.name === "include");
79
+ if (property === void 0) return options.properties?.some((item) => item.type === "SpreadElement") ? null : void 0;
80
+ const list = property.value;
81
+ if (list?.type !== "ArrayExpression") return null;
82
+ const keys = [];
83
+ for (const element of list.elements ?? []) {
84
+ const [root, ...rest] = (element.type === "MemberExpression" ? memberPath(element) : void 0) ?? [];
85
+ if (root === void 0 || !roots.has(root) || rest.length === 0) return null;
86
+ keys.push(rest.join("."));
87
+ }
88
+ return keys;
89
+ }
90
+ function recordImport(node, roots) {
91
+ for (const spec of node.specifiers ?? []) {
92
+ const imported = spec.imported?.name ?? spec.local?.name;
93
+ const local = spec.local?.name;
94
+ if (imported === "permissions" && local !== void 0) roots.add(local);
95
+ }
96
+ }
97
+ function recordCall(node, parent, source, fileRel, roots, definitionFiles, usages, unknown, dynamic, roleNames, planNames, _allowKeys, knownKeys) {
98
+ const callee = calleeName(node.callee);
99
+ const line = lineAt(source, node.start ?? 0);
100
+ if (callee === "definePermissions" || callee === "defineRoles" || callee === "definePlans") {
101
+ const name = declaredName(parent);
102
+ if (name !== void 0) {
103
+ if (callee === "definePermissions") roots.add(name);
104
+ definitionFiles[name] = fileRel;
105
+ }
106
+ if (callee === "defineRoles") collectObjectKeys(node.arguments?.[0], roleNames);
107
+ if (callee === "definePlans") collectObjectKeys(node.arguments?.[0], planNames);
108
+ return;
109
+ }
110
+ if (callee === "role") {
111
+ const first = node.arguments?.[0];
112
+ if (typeof first?.value === "string") roleNames.add(first.value);
113
+ else if (first?.type === "MemberExpression" && typeof first.property?.name === "string") roleNames.add(first.property.name);
114
+ return;
115
+ }
116
+ if (callee === "findPermission") {
117
+ const second = node.arguments?.[1];
118
+ if (typeof second?.value === "string") {
119
+ pushUsage(second.value, {
120
+ file: fileRel,
121
+ line,
122
+ call: "findPermission"
123
+ }, knownKeys, usages, unknown);
124
+ return;
125
+ }
126
+ dynamic.push({
127
+ file: fileRel,
128
+ line,
129
+ call: "findPermission"
130
+ });
131
+ }
132
+ }
133
+ function recordMember(node, parent, source, fileRel, roots, usages, unknown, dynamic, allowKeys, knownKeys) {
134
+ if (node.computed === true) {
135
+ const root = rootName(node);
136
+ if (root !== void 0 && roots.has(root)) dynamic.push({
137
+ file: fileRel,
138
+ line: lineAt(source, node.start ?? 0),
139
+ call: callName(parent)
140
+ });
141
+ return;
142
+ }
143
+ const path = memberPath(node);
144
+ if (path === void 0 || path.length < 2) return;
145
+ const [root, ...rest] = path;
146
+ if (root === void 0 || !roots.has(root)) return;
147
+ const key = rest.join(".");
148
+ if (!knownKeys.has(key) && isFieldOrSubtree(rest, knownKeys)) return;
149
+ const call = callName(parent);
150
+ const usage = {
151
+ file: fileRel,
152
+ line: lineAt(source, node.start ?? 0),
153
+ call
154
+ };
155
+ if (call === "allow") allowKeys.add(key);
156
+ pushUsage(key, usage, knownKeys, usages, unknown);
157
+ }
158
+ const LEAF_FIELDS = /* @__PURE__ */ new Set([
159
+ "key",
160
+ "resource",
161
+ "action",
162
+ "scope",
163
+ "meta"
164
+ ]);
165
+ function isFieldOrSubtree(path, knownKeys) {
166
+ const last = path.at(-1);
167
+ if (last !== void 0 && LEAF_FIELDS.has(last) && knownKeys.has(path.slice(0, -1).join("."))) return true;
168
+ const prefix = `${path.join(".")}.`;
169
+ return [...knownKeys].some((known) => known.startsWith(prefix));
170
+ }
171
+ function pushUsage(key, usage, knownKeys, usages, unknown) {
172
+ if (knownKeys.size > 0 && !knownKeys.has(key)) {
173
+ unknown.push({
174
+ ...usage,
175
+ call: `${usage.call}:${key}`
176
+ });
177
+ return;
178
+ }
179
+ const list = usages[key] ?? [];
180
+ list.push(usage);
181
+ usages[key] = list;
182
+ }
183
+ function calleeName(node) {
184
+ if (node === void 0) return;
185
+ if (node.type === "Identifier") return node.name;
186
+ if (node.type === "MemberExpression" && node.property?.type === "Identifier") return node.property.name;
187
+ }
188
+ function declaredName(parent) {
189
+ if (parent?.type === "VariableDeclarator" && parent.id?.type === "Identifier") return parent.id.name;
190
+ }
191
+ function callName(parent) {
192
+ if (parent?.type === "CallExpression") {
193
+ const name = calleeName(parent.callee);
194
+ if (name !== void 0 && CHECK_CALLS.has(name)) return name;
195
+ }
196
+ if (parent?.type === "Property" || parent?.type === "ObjectProperty") return "tools";
197
+ return "reference";
198
+ }
199
+ function memberPath(node) {
200
+ const parts = [];
201
+ let current = node;
202
+ while (current?.type === "MemberExpression") {
203
+ if (current.computed === true) return;
204
+ const name = current.property?.name;
205
+ if (name === void 0) return;
206
+ parts.unshift(name);
207
+ current = current.object;
208
+ }
209
+ if (current?.type !== "Identifier" || current.name === void 0) return;
210
+ parts.unshift(current.name);
211
+ return parts;
212
+ }
213
+ function rootName(node) {
214
+ let current = node;
215
+ while (current?.type === "MemberExpression") current = current.object;
216
+ return current?.type === "Identifier" ? current.name : void 0;
217
+ }
218
+ function lineAt(source, index) {
219
+ let line = 1;
220
+ const end = Math.min(index, source.length);
221
+ for (let i = 0; i < end; i += 1) if (source.charCodeAt(i) === 10) line += 1;
222
+ return line;
223
+ }
224
+ function collectObjectKeys(node, into) {
225
+ if (node?.type !== "ObjectExpression" || node.properties === void 0) return;
226
+ for (const property of node.properties) {
227
+ const key = property.key;
228
+ if (property.computed !== true && typeof key?.name === "string") {
229
+ into.add(key.name);
230
+ continue;
231
+ }
232
+ if (typeof key?.value === "string") into.add(key.value);
233
+ }
234
+ }
235
+ /** Every node in source order, with its parent: Oxc nodes carry none, so enter and exit keep a stack. */
236
+ function walk(program, visit) {
237
+ const stack = [];
238
+ const handlers = {};
239
+ for (const type of Object.keys(visitorKeys)) {
240
+ handlers[type] = (node) => {
241
+ visit(node, stack.at(-1));
242
+ stack.push(node);
243
+ };
244
+ handlers[`${type}:exit`] = () => {
245
+ stack.pop();
246
+ };
247
+ }
248
+ new Visitor(handlers).visit(program);
249
+ }
250
+ //#endregion
251
+ //#region src/cli/collect.ts
252
+ async function runCollect(input) {
253
+ const srcPath = input.collect.srcPath ?? input.config.collect?.srcPath ?? defaultSrcPath();
254
+ const outPath = catalogPath(input.config, input.cwd, input.collect.out);
255
+ const permissionsRel = input.config.permissions ?? guessPermissions(input.cwd, srcPath);
256
+ if (permissionsRel === void 0) return {
257
+ code: 2,
258
+ document: void 0,
259
+ scan: void 0,
260
+ outPath,
261
+ message: "usage: set permissions in permdock.config.ts or pass a definePermissions module"
262
+ };
263
+ const permissionsAbs = resolve(input.cwd, permissionsRel);
264
+ if (!existsSync(permissionsAbs)) return {
265
+ code: 2,
266
+ document: void 0,
267
+ scan: void 0,
268
+ outPath,
269
+ message: `PermDock CLI: permissions module not found: ${rel(input.cwd, permissionsAbs)}`
270
+ };
271
+ let tree;
272
+ try {
273
+ const mod = await loadModule(permissionsAbs);
274
+ tree = asPermissionTree(pickNamed(mod, ["permissions"]));
275
+ } catch (error) {
276
+ return {
277
+ code: 2,
278
+ document: void 0,
279
+ scan: void 0,
280
+ outPath,
281
+ message: error instanceof Error ? error.message : String(error)
282
+ };
283
+ }
284
+ const files = listSourceFiles(input.cwd, srcPath);
285
+ const knownKeys = new Set(leavesOf(tree).map((leaf) => leaf.key));
286
+ const scan = scanSources(input.cwd, files, knownKeys);
287
+ const document = buildCatalog(tree, scan, input.now.toISOString(), await loadConfiguredPolicy(input.cwd, input.config.policy));
288
+ const next = formatCatalogJson(document);
289
+ if (input.check) {
290
+ if (!existsSync(outPath)) return {
291
+ code: 1,
292
+ document,
293
+ scan,
294
+ outPath,
295
+ message: `catalog missing: ${rel(input.cwd, outPath)}`
296
+ };
297
+ const current = readFileSync(outPath, "utf8");
298
+ const currentDoc = JSON.parse(current);
299
+ const onDisk = catalogForCompare(currentDoc);
300
+ const generated = catalogForCompare(document);
301
+ if (onDisk !== generated) {
302
+ const file = rel(input.cwd, outPath);
303
+ return {
304
+ code: 1,
305
+ document,
306
+ scan,
307
+ outPath,
308
+ message: `catalog drift: ${file}\n${shortDiff(file, onDisk, generated)}`
309
+ };
310
+ }
311
+ return {
312
+ code: 0,
313
+ document,
314
+ scan,
315
+ outPath,
316
+ message: `catalog up to date: ${rel(input.cwd, outPath)}`
317
+ };
318
+ }
319
+ mkdirSync(dirname(outPath), { recursive: true });
320
+ writeFileSync(outPath, next);
321
+ const barrel = input.collect.barrel ?? input.config.collect?.barrel;
322
+ if (barrel !== void 0 && barrel !== false) writeBarrel(resolve(input.cwd, barrel === true ? "src/permissions.generated.ts" : barrel), permissionsAbs);
323
+ return {
324
+ code: 0,
325
+ document,
326
+ scan,
327
+ outPath,
328
+ message: `wrote ${rel(input.cwd, outPath)}`
329
+ };
330
+ }
331
+ function guessPermissions(cwd, srcPath) {
332
+ return [
333
+ "src/permissions.ts",
334
+ "permissions.ts",
335
+ ...srcPath.map((entry) => `${entry.replace(/\/$/, "")}/permissions.ts`)
336
+ ].find((file) => existsSync(resolve(cwd, file)));
337
+ }
338
+ function writeBarrel(abs, permissionsAbs) {
339
+ const specifier = relative(dirname(abs), permissionsAbs).replace(/\\/gu, "/").replace(/\.tsx?$/u, ".js");
340
+ const body = `// @generated by permdock — do not edit
341
+ import { mergePermissions } from 'permdock'
342
+ import { permissions as collected } from '${specifier.startsWith(".") ? specifier : `./${specifier}`}'
343
+
344
+ export const permissions = mergePermissions(collected)
345
+ `;
346
+ mkdirSync(dirname(abs), { recursive: true });
347
+ writeFileSync(abs, body);
348
+ }
349
+ //#endregion
350
+ export { scanSources as n, runCollect as t };
@@ -0,0 +1,2 @@
1
+ import { t as runCollect } from "./collect-O-tOtbnk.js";
2
+ export { runCollect };
@@ -0,0 +1,93 @@
1
+ //#region src/cli/commands/context.ts
2
+ /** Flags every command accepts. `run()` reads them from anywhere in argv. */
3
+ const globalArgs = {
4
+ cwd: {
5
+ type: "string",
6
+ description: "Run as if started in this directory",
7
+ valueHint: "dir"
8
+ },
9
+ config: {
10
+ type: "string",
11
+ description: "Config file (default permdock.config.{ts,mts,js,mjs})",
12
+ valueHint: "file"
13
+ },
14
+ json: {
15
+ type: "boolean",
16
+ description: "Machine-readable output"
17
+ },
18
+ yes: {
19
+ type: "boolean",
20
+ alias: "y",
21
+ description: "Never prompt; take the answer the flags give"
22
+ },
23
+ color: {
24
+ type: "boolean",
25
+ description: "Styled output on a colour terminal",
26
+ default: true,
27
+ negativeDescription: "Plain output"
28
+ }
29
+ };
30
+ /**
31
+ * A list flag: every `--name a,b` and `--name=c` occurrence, comma-split and
32
+ * trimmed, in order. citty keeps only the last occurrence of a string flag.
33
+ */
34
+ function listArg(rawArgs, name) {
35
+ const values = [];
36
+ const flag = `--${name}`;
37
+ for (const [i, token] of rawArgs.entries()) {
38
+ if (token === "--") break;
39
+ let value;
40
+ if (token.startsWith(`${flag}=`)) value = token.slice(flag.length + 1);
41
+ else if (token === flag) {
42
+ const next = rawArgs[i + 1];
43
+ if (next !== void 0 && (next === "-" || !next.startsWith("-"))) value = next;
44
+ }
45
+ if (value !== void 0) values.push(...value.split(",").map((item) => item.trim()));
46
+ }
47
+ return values;
48
+ }
49
+ /** A command's flag and positional definitions, whatever form it declared them in. */
50
+ function resolveArgs(command) {
51
+ const args = command.args;
52
+ if (args === void 0) return {};
53
+ return typeof args === "function" ? args() : args;
54
+ }
55
+ /** A string flag, `undefined` when absent or given without a value. */
56
+ function stringArg(value) {
57
+ return typeof value === "string" && value !== "" ? value : void 0;
58
+ }
59
+ //#endregion
60
+ //#region src/cli/commands/index.ts
61
+ /** What `permdock --help` lists, without loading any command module. */
62
+ const COMMAND_DESCRIPTIONS = {
63
+ collect: "Scan the sources for definePermissions() and permission references; write the catalog and barrel",
64
+ catalog: "Export the catalog as JSON, JSON Schema or Markdown",
65
+ diff: "Compare two policies or catalogs; exit 1 on a breaking change",
66
+ usage: "Report unused, ungranted and role-less permissions and conditions on undeclared fields",
67
+ doctor: "Check a PermDock installation and print a fix for each finding",
68
+ skills: "Install, update or list the PermDock Agent Skills",
69
+ openapi: "Emit security into an OpenAPI document, or import one into a generated definition",
70
+ rls: "Generate, import, verify or migrate Postgres RLS policies from the policy",
71
+ arazzo: "Resolve every Arazzo step to x-permdock-permissions",
72
+ cloud: "Publish the catalog, hostable flags and role assignability to a PermDock Cloud environment",
73
+ supabase: "Generate the Supabase Custom Access Token Hook, or inspect its manifest"
74
+ };
75
+ /** Every top-level command, loaded only when it runs or its own `--help` is asked for. */
76
+ const commands = {
77
+ collect: async () => (await import("./collect-B7_TIfmg.js")).collect,
78
+ catalog: async () => (await import("./catalog-B0E6bggc.js")).catalog,
79
+ diff: async () => (await import("./diff-BUzf5Poi.js")).diff,
80
+ usage: async () => (await import("./usage-1ozMubLY.js")).usage,
81
+ doctor: async () => (await import("./doctor-Bqo6FwUa.js")).doctor,
82
+ skills: async () => (await import("./skills-C_lpV4Jx.js")).skills,
83
+ openapi: async () => (await import("./openapi-CwePaF7C.js")).openapi,
84
+ rls: async () => (await import("./rls-BOFU3chG.js")).rls,
85
+ arazzo: async () => (await import("./arazzo-aoTkqYsJ.js")).arazzo,
86
+ cloud: async () => (await import("./cloud-BNQTrmrr.js")).cloud,
87
+ supabase: async () => (await import("./supabase-D8UlBA7Z.js")).supabase
88
+ };
89
+ function isCommand(name) {
90
+ return Object.hasOwn(commands, name);
91
+ }
92
+ //#endregion
93
+ export { listArg as a, globalArgs as i, commands as n, resolveArgs as o, isCommand as r, stringArg as s, COMMAND_DESCRIPTIONS as t };
@@ -0,0 +1,19 @@
1
+ //#region src/core/compact.ts
2
+ function compact(value) {
3
+ const result = {};
4
+ for (const key of Object.keys(value)) {
5
+ const next = value[key];
6
+ if (next !== void 0) result[key] = next;
7
+ }
8
+ return result;
9
+ }
10
+ /** `Array.isArray` that keeps `readonly T[]` instead of widening to `any[]`. */
11
+ function isReadonlyArray(value) {
12
+ return Array.isArray(value);
13
+ }
14
+ /** The element of a one-element list, else `undefined`. */
15
+ function sole(items) {
16
+ return items.length === 1 ? items[0] : void 0;
17
+ }
18
+ //#endregion
19
+ export { isReadonlyArray as n, sole as r, compact as t };
@@ -0,0 +1,12 @@
1
+ //#region src/core/compare.ts
2
+ /**
3
+ * Orders strings by UTF-16 code unit, the same in every locale and runtime,
4
+ * so sorted output is byte-stable where `localeCompare` would follow the ICU
5
+ * build.
6
+ */
7
+ function byCodePoint(a, b) {
8
+ if (a === b) return 0;
9
+ return a < b ? -1 : 1;
10
+ }
11
+ //#endregion
12
+ export { byCodePoint as t };
@@ -0,0 +1,30 @@
1
+ //#region src/conditions/compile.d.ts
2
+ type MembershipTable = {
3
+ readonly table: string;
4
+ readonly user: string;
5
+ readonly role: string;
6
+ /** Per scope name, the column holding that scope's id (the row's own scope and its ancestors). */
7
+ readonly columns?: Readonly<Record<string, string>>;
8
+ /** Column of the first scope's id; shorthand for `columns[<first scope>]`. */
9
+ readonly tenant?: string;
10
+ /** Column of the second scope's id; shorthand for `columns[<second scope>]`. */
11
+ readonly team?: string;
12
+ readonly id?: string;
13
+ /** Column naming the membership's resource, when one table holds several kinds. */
14
+ readonly resource?: string;
15
+ /** Column holding the membership kind (`Membership.via`); roles with `for` need it. */
16
+ readonly via?: string;
17
+ /** Unix seconds, like `Membership.expiresAt`; `null` never expires. */
18
+ readonly expiresAt?: string;
19
+ };
20
+ type MembershipsMapping = {
21
+ /** The membership table of each named scope. */
22
+ readonly scopes?: Readonly<Record<string, MembershipTable>>;
23
+ /** The first scope's table; shorthand for `scopes[<first scope>]`. */
24
+ readonly tenant?: MembershipTable;
25
+ /** The second scope's table; shorthand for `scopes[<second scope>]`. */
26
+ readonly team?: MembershipTable;
27
+ readonly resource?: Readonly<Record<string, MembershipTable>>;
28
+ };
29
+ //#endregion
30
+ export { MembershipsMapping as t };