permdock 0.0.0 → 0.2.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 (344) hide show
  1. package/README.md +327 -1
  2. package/dist/a2a/index.d.ts +169 -0
  3. package/dist/a2a/index.js +232 -0
  4. package/dist/adapter-context-mlWsVGGg.js +23 -0
  5. package/dist/ai-sdk/index.d.ts +95 -0
  6. package/dist/ai-sdk/index.js +154 -0
  7. package/dist/approval-required-TzNB9oQA.js +6 -0
  8. package/dist/approvals/index.d.ts +3 -0
  9. package/dist/approvals/index.js +5 -0
  10. package/dist/approvals-DbYAuNkG.js +224 -0
  11. package/dist/approvers-DT4AVyIg.js +52 -0
  12. package/dist/arazzo-BAgw9ap6.js +70 -0
  13. package/dist/arazzo-cmvX2jDe.js +54 -0
  14. package/dist/authzen/index.d.ts +39 -0
  15. package/dist/authzen/index.js +302 -0
  16. package/dist/better-auth/index.d.ts +109 -0
  17. package/dist/better-auth/index.js +344 -0
  18. package/dist/better-supabase/index.d.ts +206 -0
  19. package/dist/better-supabase/index.js +620 -0
  20. package/dist/bind-CVy3Espv.d.ts +25 -0
  21. package/dist/bind-VnYn2HKq.js +97 -0
  22. package/dist/boundary-BM8a_P6E.js +13 -0
  23. package/dist/boundary-BmHxVH1J.d.ts +15 -0
  24. package/dist/budget-JqcRqyhK.d.ts +11 -0
  25. package/dist/budget-NbEtbJC_.js +11 -0
  26. package/dist/canonical-json-DemiK4Vp.js +26 -0
  27. package/dist/capability-4qPdO9gk.js +173 -0
  28. package/dist/capability-Dq43tT1u.d.ts +99 -0
  29. package/dist/catalog/index.d.ts +12 -0
  30. package/dist/catalog/index.js +2 -0
  31. package/dist/catalog-BjZSovXQ.js +2 -0
  32. package/dist/catalog-doc-Dsc9y7sd.js +309 -0
  33. package/dist/catalog-h2tlKFkq.js +48 -0
  34. package/dist/catalog-path-CnI0XTFK.js +12 -0
  35. package/dist/catalog-z8q6bi_r.js +55 -0
  36. package/dist/claude-agent/index.d.ts +72 -0
  37. package/dist/claude-agent/index.js +77 -0
  38. package/dist/clerk/index.d.ts +65 -0
  39. package/dist/clerk/index.js +301 -0
  40. package/dist/cli/bin.d.ts +1 -0
  41. package/dist/cli/bin.js +20 -0
  42. package/dist/cli/index.d.ts +46 -0
  43. package/dist/cli/index.js +5 -0
  44. package/dist/clients-C7zLFuWT.d.ts +12 -0
  45. package/dist/clients-DjU5ABMy.js +23 -0
  46. package/dist/cloud/index.d.ts +90 -0
  47. package/dist/cloud/index.js +404 -0
  48. package/dist/cloud-BGhHS-lY.js +50 -0
  49. package/dist/cloud-Bo3e9Ak3.js +118 -0
  50. package/dist/collect-DDDv_ESs.js +502 -0
  51. package/dist/collect-DLlujdHC.js +83 -0
  52. package/dist/collect-rG2IQ3t0.js +2 -0
  53. package/dist/commands-DWOrSQic.js +97 -0
  54. package/dist/compact-y6vfu2_f.js +19 -0
  55. package/dist/compare-pfyVnBjE.js +12 -0
  56. package/dist/compile/index.d.ts +3 -0
  57. package/dist/compile/index.js +2 -0
  58. package/dist/compile-Ba4blROR.js +613 -0
  59. package/dist/compile-CNnl6uIt.d.ts +94 -0
  60. package/dist/config-BJiM-xAm.js +157 -0
  61. package/dist/config-Bn00Z3ks.js +36 -0
  62. package/dist/config-report-Dw_JcUqT.js +44 -0
  63. package/dist/connection-CU8MQxRi.js +194 -0
  64. package/dist/context-Ttp0ekMT.js +82 -0
  65. package/dist/convex/index.d.ts +45 -0
  66. package/dist/convex/index.js +65 -0
  67. package/dist/create-BWyx3jua.d.ts +245 -0
  68. package/dist/create-CPhDL6qx.js +253 -0
  69. package/dist/credential-8P81ff4u.js +306 -0
  70. package/dist/delegation-D8pUEuce.js +103 -0
  71. package/dist/describe-B_gVZEVi.js +94 -0
  72. package/dist/describe-PdoqESvg.d.ts +36 -0
  73. package/dist/diff-B8Tunc3o.js +451 -0
  74. package/dist/diff-CzqLxZ77.js +48 -0
  75. package/dist/digest-B3kc_PgQ.d.ts +19 -0
  76. package/dist/digest-BI-6aa6d.js +27 -0
  77. package/dist/doctor-WpvG6p4k.js +1194 -0
  78. package/dist/doctor-collect-ByfYlNv1.js +664 -0
  79. package/dist/doctor-rOr-4ZfS.js +53 -0
  80. package/dist/drizzle/index.d.ts +73 -0
  81. package/dist/drizzle/index.js +160 -0
  82. package/dist/duration-xK2jGFVc.js +25 -0
  83. package/dist/elysia/index.d.ts +49 -0
  84. package/dist/elysia/index.js +59 -0
  85. package/dist/errors-CWfoNg9N.js +47 -0
  86. package/dist/errors-Cz5zn0mW.js +123 -0
  87. package/dist/errors-DAqevpNk.d.ts +125 -0
  88. package/dist/errors-DRnGZHzF.js +30 -0
  89. package/dist/evaluation-items-CfCCejQd.js +40 -0
  90. package/dist/evaluations-tz6D9A2G.js +461 -0
  91. package/dist/eve/index.d.ts +86 -0
  92. package/dist/eve/index.js +176 -0
  93. package/dist/expiry-BoBJ8Tvc.js +7 -0
  94. package/dist/express/index.d.ts +23 -0
  95. package/dist/express/index.js +78 -0
  96. package/dist/fastify/index.d.ts +33 -0
  97. package/dist/fastify/index.js +92 -0
  98. package/dist/fields-BMl1RxoX.js +26 -0
  99. package/dist/files-DWUN9PzI.js +125 -0
  100. package/dist/fixtures-ht28Cplr.js +67 -0
  101. package/dist/freeze-CrU8nQeX.js +60 -0
  102. package/dist/from-snapshot-C3sHpZNS.js +569 -0
  103. package/dist/generate-CH7ThJ14.js +173 -0
  104. package/dist/grantee-Cv5Sogfv.js +602 -0
  105. package/dist/graph-sql-B-dsAT6j.d.ts +29 -0
  106. package/dist/headers-BZSDieNT.js +6 -0
  107. package/dist/headers-Cf-zWvsO.d.ts +6 -0
  108. package/dist/helpers-H_KARDVC.js +421 -0
  109. package/dist/hono/index.d.ts +48 -0
  110. package/dist/hono/index.js +99 -0
  111. package/dist/hosted-DJQw46hn.js +266 -0
  112. package/dist/http-BIhmLfCc.js +95 -0
  113. package/dist/http-DPuDaChb.d.ts +13 -0
  114. package/dist/http-SO7qGttf.js +44 -0
  115. package/dist/ids-DC4V4CFu.js +18 -0
  116. package/dist/index-A0YNL8jZ.d.ts +177 -0
  117. package/dist/index-CtE07CBF.d.ts +6 -0
  118. package/dist/index-D3vbkoSI.d.ts +483 -0
  119. package/dist/index-D6_cSa1z.d.ts +201 -0
  120. package/dist/index.d.ts +16 -0
  121. package/dist/index.js +26 -0
  122. package/dist/instance-options-BK_rNOSC.d.ts +11 -0
  123. package/dist/instance-options-Dhhcnm3y.js +22 -0
  124. package/dist/json-schema-BsAflUGW.js +106 -0
  125. package/dist/jwt/index.d.ts +91 -0
  126. package/dist/jwt/index.js +590 -0
  127. package/dist/kernel-GSQnMz3O.js +208 -0
  128. package/dist/kysely/index.d.ts +78 -0
  129. package/dist/kysely/index.js +129 -0
  130. package/dist/live-options-H2eG8dfJ.js +60 -0
  131. package/dist/load-DhWEB9P1.js +75 -0
  132. package/dist/load-DwJUafYN.js +2 -0
  133. package/dist/load-jose-BL6LH4bL.js +11 -0
  134. package/dist/lru-8q4WZjBV.js +28 -0
  135. package/dist/manifest-iaoBXHKc.js +783 -0
  136. package/dist/manifest-uDS9y5de.d.ts +206 -0
  137. package/dist/map-AcxK9o_D.js +147 -0
  138. package/dist/map-claims-Z4QZOiFF.js +369 -0
  139. package/dist/map-error-pgUWNNtG.js +23 -0
  140. package/dist/markers-B0hYLvMD.js +60 -0
  141. package/dist/may-use-DndQ5tQ-.js +77 -0
  142. package/dist/mcp/index.d.ts +159 -0
  143. package/dist/mcp/index.js +603 -0
  144. package/dist/nest/index.d.ts +75 -0
  145. package/dist/nest/index.js +261 -0
  146. package/dist/next/client.d.ts +23 -0
  147. package/dist/next/client.js +33 -0
  148. package/dist/next/index.d.ts +93 -0
  149. package/dist/next/index.js +180 -0
  150. package/dist/next/plugin.d.ts +14 -0
  151. package/dist/next/plugin.js +33 -0
  152. package/dist/node/index.d.ts +24 -0
  153. package/dist/node/index.js +34 -0
  154. package/dist/openai/index.d.ts +62 -0
  155. package/dist/openai/index.js +92 -0
  156. package/dist/openapi/index.d.ts +176 -0
  157. package/dist/openapi/index.js +3 -0
  158. package/dist/openapi-Bbg4wGVL.js +164 -0
  159. package/dist/openapi-BqRBvAng.js +538 -0
  160. package/dist/openapi-CqqEbHsL.js +250 -0
  161. package/dist/openapi-import-cmwetbzw.js +5959 -0
  162. package/dist/openapi-schema--ARjyfQr.js +6902 -0
  163. package/dist/orpc/index.d.ts +51 -0
  164. package/dist/orpc/index.js +145 -0
  165. package/dist/otel/index.d.ts +13 -0
  166. package/dist/otel/index.js +202 -0
  167. package/dist/package-root-zGkxO3oN.js +30 -0
  168. package/dist/parse-BuyjxhZV.js +53 -0
  169. package/dist/parse-local-manifest-BkGQNzAh.d.ts +10 -0
  170. package/dist/parse-local-manifest-BrMozJCo.js +36 -0
  171. package/dist/pdp/index.d.ts +22 -0
  172. package/dist/pdp/index.js +682 -0
  173. package/dist/peer-BOr_kJE1.js +31 -0
  174. package/dist/permdock-CzqXjCpU.js +3471 -0
  175. package/dist/permissions-CDgvKG5L.d.ts +52 -0
  176. package/dist/permissions-CpZrivYv.js +142 -0
  177. package/dist/permissions-DVoF6dMt.js +662 -0
  178. package/dist/permissions-DttnqqxC.d.ts +214 -0
  179. package/dist/pins-8ILTftC9.js +12 -0
  180. package/dist/policy-CFZAr_Al.d.ts +2252 -0
  181. package/dist/policy-D8UFyERw.d.ts +20 -0
  182. package/dist/policy-xyWg7QdR.js +1122 -0
  183. package/dist/powersync-A8x_Yyvh.js +2 -0
  184. package/dist/powersync-C7kLglqX.js +540 -0
  185. package/dist/powersync-yW1UUFzp.js +62 -0
  186. package/dist/prisma/index.d.ts +136 -0
  187. package/dist/prisma/index.js +455 -0
  188. package/dist/problem-B43ztKIm.js +191 -0
  189. package/dist/problem-details-CkL50EEf.d.ts +7 -0
  190. package/dist/problem-details-_AMOYz-w.js +144 -0
  191. package/dist/prompt-CXYhLfsS.js +32 -0
  192. package/dist/protected-CNsMzrVd.d.ts +27 -0
  193. package/dist/protected-Cs6kTaHo.js +100 -0
  194. package/dist/protected-bZs6rbT1.d.ts +40 -0
  195. package/dist/provider-Cjr62YMV.d.ts +6 -0
  196. package/dist/provider-DLzpb2Xz.js +52 -0
  197. package/dist/provider-store-DNyC1y48.js +43 -0
  198. package/dist/react/index.d.ts +8 -0
  199. package/dist/react/index.js +7 -0
  200. package/dist/react/provider-client.d.ts +2 -0
  201. package/dist/react/provider-client.js +3 -0
  202. package/dist/react-native/index.d.ts +198 -0
  203. package/dist/react-native/index.js +696 -0
  204. package/dist/refs-KYb4ntaz.js +91 -0
  205. package/dist/relations-cjOL01hZ.js +505 -0
  206. package/dist/replay-BsOyTrdV.js +28 -0
  207. package/dist/replay-sqBGMnNs.d.ts +5 -0
  208. package/dist/resource-ref-CaS9yVPi.js +20 -0
  209. package/dist/revocations-Bhr0aMIC.js +27 -0
  210. package/dist/revocations-Cy06JNx2.d.ts +21 -0
  211. package/dist/rls-BMNydpHk.js +2521 -0
  212. package/dist/rls-CEvs64Kj.js +238 -0
  213. package/dist/rls-fields-BMasREhR.js +3502 -0
  214. package/dist/rls-graph-pc9fuXYm.js +435 -0
  215. package/dist/rls-import-D8F7j35Q.js +943 -0
  216. package/dist/rls-migrate-7wikfrVI.js +367 -0
  217. package/dist/rls-ownership-B5Lkq62W.js +843 -0
  218. package/dist/rls-shared-aOQ4hGTO.js +493 -0
  219. package/dist/rls-verify-D8B7dOTh.js +745 -0
  220. package/dist/row-check-Dt35czLy.d.ts +40 -0
  221. package/dist/rpc-DOK54_CS.js +89 -0
  222. package/dist/run-YXCJDNYk.js +174 -0
  223. package/dist/runtime-CB8gQFvS.js +11 -0
  224. package/dist/saas-Bj_FFkjN.js +1203 -0
  225. package/dist/schema-D3MnDMxa.js +300 -0
  226. package/dist/scim/index.d.ts +2 -0
  227. package/dist/scim/index.js +2 -0
  228. package/dist/scim-BFGBBAqR.js +1445 -0
  229. package/dist/scopes-CVdPrWN-.js +239 -0
  230. package/dist/server/index.d.ts +134 -0
  231. package/dist/server/index.js +11 -0
  232. package/dist/server-DlZ28Oz5.js +268 -0
  233. package/dist/sha256-BO0swRXL.js +150 -0
  234. package/dist/shared-DRu8VFVM.js +123 -0
  235. package/dist/sink-Bd9PSyfq.js +141 -0
  236. package/dist/sink-Gs6TTVa-.d.ts +104 -0
  237. package/dist/skills-Biq5uup3.js +192 -0
  238. package/dist/skills-JaymNCdK.js +56 -0
  239. package/dist/snapshot-Enxd0n-s.js +975 -0
  240. package/dist/snapshot-cache-D6jLelln.js +44 -0
  241. package/dist/snapshot-cache-DwQH8ufx.d.ts +45 -0
  242. package/dist/solid/index.d.ts +93 -0
  243. package/dist/solid/index.js +188 -0
  244. package/dist/sources-B0UvrJ21.js +534 -0
  245. package/dist/sources-BcJgw0lt.d.ts +192 -0
  246. package/dist/sql-xdg5f4Fi.js +27 -0
  247. package/dist/src-CSbUiozF.js +568 -0
  248. package/dist/ssf/index.d.ts +4 -0
  249. package/dist/ssf/index.js +596 -0
  250. package/dist/store-DMAWwAJV.js +371 -0
  251. package/dist/store-D_pjn91-.d.ts +36 -0
  252. package/dist/store-options-yO0V6gRn.js +716 -0
  253. package/dist/stores-4_sqiOA1.js +87 -0
  254. package/dist/stores-DVR5NHLE.d.ts +52 -0
  255. package/dist/stream-DDpvynSB.js +66 -0
  256. package/dist/stream-DlvG2hs-.d.ts +12 -0
  257. package/dist/style-CTm1AXDT.js +22 -0
  258. package/dist/subject-C6dLxqHU.js +24 -0
  259. package/dist/subject-settings-BwBmCdTR.js +128 -0
  260. package/dist/supabase/index.d.ts +183 -0
  261. package/dist/supabase/index.js +5 -0
  262. package/dist/supabase/middleware.d.ts +82 -0
  263. package/dist/supabase/middleware.js +102 -0
  264. package/dist/supabase-CwafwxxF.js +83 -0
  265. package/dist/supabase-DTBaC20O.js +774 -0
  266. package/dist/supabase-config-Bs44dare.js +472 -0
  267. package/dist/supabase-hook-BuxLQLpU.js +1814 -0
  268. package/dist/supabase-hook-D5qVd_D8.js +2 -0
  269. package/dist/supautils-DYZnzRWV.js +91 -0
  270. package/dist/svelte/PermissionBoundary.svelte +37 -0
  271. package/dist/svelte/Protected.svelte +40 -0
  272. package/dist/svelte/index.d.ts +13 -0
  273. package/dist/svelte/index.js +107 -0
  274. package/dist/svelte/runtime.d.ts +7 -0
  275. package/dist/svelte/runtime.js +4 -0
  276. package/dist/svelte/source.d.ts +13 -0
  277. package/dist/svelte/source.js +11 -0
  278. package/dist/terminal/index.d.ts +163 -0
  279. package/dist/terminal/index.js +833 -0
  280. package/dist/testing/index.d.ts +745 -0
  281. package/dist/testing/index.js +3672 -0
  282. package/dist/testing/saas/index.d.ts +194 -0
  283. package/dist/testing/saas/index.js +3 -0
  284. package/dist/testing/saas/permissions.d.ts +2 -0
  285. package/dist/testing/saas/permissions.js +2 -0
  286. package/dist/text-diff-BdkkYSbi.js +15 -0
  287. package/dist/thenable-okc2xDsj.js +10 -0
  288. package/dist/timeout-D51niuQP.js +8 -0
  289. package/dist/token-CIWxJOCh.js +50 -0
  290. package/dist/trpc/index.d.ts +61 -0
  291. package/dist/trpc/index.js +122 -0
  292. package/dist/types-9AWO9EGt.d.ts +197 -0
  293. package/dist/types-BPxgszlT.d.ts +550 -0
  294. package/dist/types-BVyImy5I.d.ts +120 -0
  295. package/dist/types-Bvc4oWT6.d.ts +9 -0
  296. package/dist/types-C3s9xVJG.d.ts +48 -0
  297. package/dist/types-Dnemwd77.d.ts +183 -0
  298. package/dist/types-kxznc7cn.d.ts +52 -0
  299. package/dist/types-vKyAMtcX.d.ts +157 -0
  300. package/dist/types-vNSDF7Dq.d.ts +66 -0
  301. package/dist/types-yF5LmQVD.d.ts +306 -0
  302. package/dist/unplugin/index.d.ts +7 -0
  303. package/dist/unplugin/index.js +31 -0
  304. package/dist/usage-D07N9QJ3.js +42 -0
  305. package/dist/usage-D82l1CwK.js +2 -0
  306. package/dist/usage-DG1oeCca.js +693 -0
  307. package/dist/validation-error-CnjZ4t92.js +33 -0
  308. package/dist/validation-error-CtF23SrC.d.ts +26 -0
  309. package/dist/validity-uOp8UpYn.js +245 -0
  310. package/dist/verifier-BxBo6I44.js +466 -0
  311. package/dist/version-BvacVTZR.js +17 -0
  312. package/dist/views-Soe7bGSC.js +95 -0
  313. package/dist/vocabulary-DA8a8zif.d.ts +56 -0
  314. package/dist/vue/index.d.ts +79 -0
  315. package/dist/vue/index.js +196 -0
  316. package/dist/watch-Etoa_Mvr.js +2 -0
  317. package/dist/watch-UihESpsJ.js +128 -0
  318. package/dist/webmcp/index.d.ts +75 -0
  319. package/dist/webmcp/index.js +307 -0
  320. package/package.json +450 -5
  321. package/rulesets/permdock.yaml +29 -0
  322. package/schemas/approval-request-v1.json +175 -0
  323. package/schemas/catalog-v1.json +535 -0
  324. package/schemas/openapi/oas-3.1.json +1298 -0
  325. package/schemas/openapi/oas-3.2.json +1516 -0
  326. package/schemas/openapi/overlay-1.1.json +79 -0
  327. package/schemas/supabase-claims-v1.json +144 -0
  328. package/schemas/supabase-manifest-v1.json +361 -0
  329. package/skills/permdock/SKILL.md +66 -0
  330. package/skills/permdock-agents/SKILL.md +77 -0
  331. package/skills/permdock-agents/references/runtimes.md +213 -0
  332. package/skills/permdock-approvals/SKILL.md +80 -0
  333. package/skills/permdock-approvals/references/stores-and-resume.md +94 -0
  334. package/skills/permdock-audit/SKILL.md +67 -0
  335. package/skills/permdock-credentials/SKILL.md +55 -0
  336. package/skills/permdock-credentials/references/tokens-keys-links.md +132 -0
  337. package/skills/permdock-data/SKILL.md +57 -0
  338. package/skills/permdock-data/references/queries-and-rls.md +62 -0
  339. package/skills/permdock-data/references/relationships.md +67 -0
  340. package/skills/permdock-tenancy/SKILL.md +80 -0
  341. package/skills/permdock-tenancy/references/ownership-and-custom-roles.md +89 -0
  342. package/skills/permdock-wire/SKILL.md +116 -0
  343. package/skills/permdock-wire/references/adapters.md +492 -0
  344. package/skills/permdock-wire/references/policy-options.md +45 -0
@@ -0,0 +1,502 @@
1
+ import { i as describeError } from "./errors-CWfoNg9N.js";
2
+ import { i as formatCatalogJson, n as catalogForCompare, t as buildCatalog } from "./catalog-doc-Dsc9y7sd.js";
3
+ import { t as catalogPath } from "./catalog-path-CnI0XTFK.js";
4
+ import { i as rel, r as listSourceFiles, t as defaultSrcPath } from "./files-DWUN9PzI.js";
5
+ import { a as loadModule, i as loadConfiguredPolicy, o as pickNamed, r as leavesOf, t as asPermissionTree } from "./load-DhWEB9P1.js";
6
+ import { t as shortDiff } from "./text-diff-BdkkYSbi.js";
7
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
8
+ import { dirname, relative, resolve } from "node:path";
9
+ import { Visitor, parseSync, visitorKeys } from "oxc-parser";
10
+ //#region src/cli/scan.ts
11
+ /** oxc reports recoverable problems as `Warning` or `Advice`; only `Error` leaves the program incomplete. */
12
+ const PARSE_ERRORS = /* @__PURE__ */ new Set(["Error"]);
13
+ const CHECK_CALLS = /* @__PURE__ */ new Set([
14
+ "can",
15
+ "decide",
16
+ "assert",
17
+ "filter",
18
+ "where",
19
+ "simulate",
20
+ "actions",
21
+ "usePermission",
22
+ "getPermission",
23
+ "protect",
24
+ "allow",
25
+ "deny",
26
+ "registerTool",
27
+ "anyone",
28
+ "authenticated",
29
+ "relation",
30
+ "plan",
31
+ "actor",
32
+ "assurance",
33
+ "inherit"
34
+ ]);
35
+ function scanSources(cwd, files, knownKeys) {
36
+ const roots = /* @__PURE__ */ new Set(["permissions"]);
37
+ const definitionFiles = {};
38
+ const usages = {};
39
+ const unknown = [];
40
+ const dynamic = [];
41
+ const roleNames = /* @__PURE__ */ new Set();
42
+ const planNames = /* @__PURE__ */ new Set();
43
+ const allowKeys = /* @__PURE__ */ new Set();
44
+ const snapshots = [];
45
+ const unparsed = [];
46
+ const parsed = [];
47
+ for (const file of files) {
48
+ const source = readFileSync(file, "utf8");
49
+ const fileRel = rel(cwd, file);
50
+ try {
51
+ const result = parseSync(file, source);
52
+ const error = result.errors.find((item) => PARSE_ERRORS.has(item.severity));
53
+ if (error !== void 0) unparsed.push({
54
+ file: fileRel,
55
+ line: lineIndex(source)(error.labels[0]?.start ?? 0),
56
+ message: error.message
57
+ });
58
+ parsed.push({
59
+ file,
60
+ source,
61
+ program: result.program
62
+ });
63
+ } catch (error) {
64
+ unparsed.push({
65
+ file: fileRel,
66
+ line: 1,
67
+ message: describeError(error)
68
+ });
69
+ }
70
+ }
71
+ const definitions = /* @__PURE__ */ new Set(["permissions"]);
72
+ for (const { program } of parsed) walk(program, (node) => {
73
+ if (node.type === "VariableDeclarator" && node.id?.type === "Identifier" && node.id.name !== void 0 && isDefinePermissions(node.init)) definitions.add(node.id.name);
74
+ });
75
+ for (const { file, source, program } of parsed) {
76
+ const fileRel = rel(cwd, file);
77
+ const lineAt = lineIndex(source);
78
+ const scopes = /* @__PURE__ */ new WeakMap();
79
+ walk(program, (node, parent, ancestors) => {
80
+ const isRoot = (name) => boundToRoot(name, ancestors, definitions, scopes);
81
+ if (node.type === "CallExpression") {
82
+ recordCall(node, parent, lineAt, fileRel, roots, definitionFiles, usages, unknown, dynamic, roleNames, planNames, allowKeys, knownKeys);
83
+ const callee = calleeName(node.callee);
84
+ if (callee === "snapshot" || callee === "snapshotFor") snapshots.push({
85
+ file: fileRel,
86
+ line: lineAt(node.start ?? 0),
87
+ include: includeOf(node.arguments?.[callee === "snapshot" ? 0 : 2], isRoot)
88
+ });
89
+ }
90
+ if (node.type === "MemberExpression" && parent?.type !== "MemberExpression") recordMember(node, parent, lineAt, fileRel, isRoot, usages, unknown, dynamic, allowKeys, knownKeys);
91
+ if (node.type === "ImportDeclaration") recordImport(node, roots, definitions);
92
+ });
93
+ }
94
+ return {
95
+ roots: [...roots].toSorted(),
96
+ definitionFiles,
97
+ usages,
98
+ unknown,
99
+ dynamic,
100
+ roleNames: [...roleNames].toSorted(),
101
+ planNames: [...planNames].toSorted(),
102
+ allowKeys: [...allowKeys].toSorted(),
103
+ snapshots,
104
+ unparsed
105
+ };
106
+ }
107
+ function includeOf(options, isRoot) {
108
+ if (options?.type !== "ObjectExpression") return options === void 0 ? void 0 : null;
109
+ const property = options.properties?.find((item) => item.key?.name === "include");
110
+ if (property === void 0) return options.properties?.some((item) => item.type === "SpreadElement") ? null : void 0;
111
+ const list = property.value;
112
+ if (list?.type !== "ArrayExpression") return null;
113
+ const keys = [];
114
+ for (const element of list.elements ?? []) {
115
+ const [root, ...rest] = (element?.type === "MemberExpression" ? memberPath(element) : void 0) ?? [];
116
+ if (root === void 0 || !isRoot(root) || rest.length === 0) return null;
117
+ keys.push(rest.join("."));
118
+ }
119
+ return keys;
120
+ }
121
+ function recordImport(node, roots, definitions) {
122
+ for (const spec of node.specifiers ?? []) {
123
+ const local = spec.local?.name;
124
+ if (local !== void 0 && importsRoot(spec, definitions)) roots.add(local);
125
+ }
126
+ }
127
+ function isDefinePermissions(node) {
128
+ return node?.type === "CallExpression" && calleeName(node.callee) === "definePermissions";
129
+ }
130
+ /** An import binding of a permission tree: by its imported name, or a default import named `permissions`. */
131
+ function importsRoot(spec, definitions) {
132
+ if (spec.type === "ImportSpecifier") {
133
+ const value = spec.imported?.value;
134
+ const imported = typeof value === "string" ? value : spec.imported?.name;
135
+ return imported !== void 0 && definitions.has(imported);
136
+ }
137
+ return spec.type === "ImportDefaultSpecifier" && spec.local?.name === "permissions";
138
+ }
139
+ function patternNames(pattern, into) {
140
+ if (pattern === null || pattern === void 0) return;
141
+ const type = pattern.type;
142
+ if (type === "Identifier" && pattern.name !== void 0) into.push(pattern.name);
143
+ else if (type === "ObjectPattern") for (const property of pattern.properties ?? []) {
144
+ const value = property.value;
145
+ patternNames(property.type === "RestElement" ? property.argument : value, into);
146
+ }
147
+ else if (type === "ArrayPattern") for (const element of pattern.elements ?? []) patternNames(element, into);
148
+ else patternNames(pattern.left ?? pattern.argument ?? pattern.parameter, into);
149
+ }
150
+ const NAMED_DECLARATIONS = /* @__PURE__ */ new Set([
151
+ "FunctionDeclaration",
152
+ "ClassDeclaration",
153
+ "TSEnumDeclaration"
154
+ ]);
155
+ function declareStatement(statement, bindings, definitions) {
156
+ const type = statement.type;
157
+ if (type === "VariableDeclaration") for (const declarator of statement.declarations ?? []) {
158
+ const names = [];
159
+ patternNames(declarator.id, names);
160
+ const root = declarator.id?.type === "Identifier" && isDefinePermissions(declarator.init);
161
+ for (const name of names) bindings.set(name, root);
162
+ }
163
+ else if (NAMED_DECLARATIONS.has(type)) {
164
+ if (statement.id?.name !== void 0) bindings.set(statement.id.name, false);
165
+ } else if (type === "ExportNamedDeclaration" || type === "ExportDefaultDeclaration") {
166
+ const declaration = statement.declaration;
167
+ if (declaration !== void 0 && declaration !== null) declareStatement(declaration, bindings, definitions);
168
+ } else if (type === "ImportDeclaration") {
169
+ for (const spec of statement.specifiers ?? []) if (spec.local?.name !== void 0) bindings.set(spec.local.name, importsRoot(spec, definitions));
170
+ }
171
+ }
172
+ function isNodeList(value) {
173
+ return Array.isArray(value);
174
+ }
175
+ const BLOCK_SCOPES = /* @__PURE__ */ new Set([
176
+ "Program",
177
+ "BlockStatement",
178
+ "StaticBlock"
179
+ ]);
180
+ const FUNCTION_SCOPES = /* @__PURE__ */ new Set([
181
+ "FunctionDeclaration",
182
+ "FunctionExpression",
183
+ "ArrowFunctionExpression"
184
+ ]);
185
+ /** The names a scope node declares, each with whether it is a permission tree; `undefined` for a node that opens no scope. */
186
+ function bindingsOf(node, definitions) {
187
+ const bindings = /* @__PURE__ */ new Map();
188
+ const type = node.type;
189
+ const declare = (statements) => {
190
+ for (const statement of isNodeList(statements) ? statements : []) declareStatement(statement, bindings, definitions);
191
+ };
192
+ const names = [];
193
+ if (BLOCK_SCOPES.has(type)) declare(node.body);
194
+ else if (FUNCTION_SCOPES.has(type)) {
195
+ for (const param of node.params ?? []) patternNames(param, names);
196
+ if (type === "FunctionExpression") patternNames(node.id, names);
197
+ } else if (type === "ForStatement") declare(node.init === null || node.init === void 0 ? [] : [node.init]);
198
+ else if (type === "ForInStatement" || type === "ForOfStatement") declare(node.left === void 0 ? [] : [node.left]);
199
+ else if (type === "CatchClause") patternNames(node.param, names);
200
+ else if (type === "SwitchStatement") for (const branch of node.cases ?? []) declare(branch.consequent);
201
+ else return;
202
+ for (const name of names) bindings.set(name, false);
203
+ return bindings;
204
+ }
205
+ /**
206
+ * Whether `name`, read inside `ancestors`, is bound to a permission tree: the
207
+ * innermost scope that declares it decides. A name no scope declares keeps
208
+ * matching by name, as a global or generated reference does.
209
+ */
210
+ function boundToRoot(name, ancestors, definitions, cache) {
211
+ for (const scope of ancestors.toReversed()) {
212
+ let bindings = cache.get(scope);
213
+ if (bindings === void 0) {
214
+ const found = bindingsOf(scope, definitions);
215
+ if (found === void 0) continue;
216
+ bindings = found;
217
+ cache.set(scope, bindings);
218
+ }
219
+ const bound = bindings.get(name);
220
+ if (bound !== void 0) return bound;
221
+ }
222
+ return definitions.has(name);
223
+ }
224
+ function recordCall(node, parent, lineAt, fileRel, roots, definitionFiles, usages, unknown, dynamic, roleNames, planNames, _allowKeys, knownKeys) {
225
+ const callee = calleeName(node.callee);
226
+ const line = lineAt(node.start ?? 0);
227
+ if (callee === "definePermissions" || callee === "defineRoles" || callee === "definePlans") {
228
+ const name = declaredName(parent);
229
+ if (name !== void 0) {
230
+ if (callee === "definePermissions") roots.add(name);
231
+ definitionFiles[name] = fileRel;
232
+ }
233
+ if (callee === "defineRoles") collectObjectKeys(node.arguments?.[0], roleNames);
234
+ if (callee === "definePlans") collectObjectKeys(node.arguments?.[0], planNames);
235
+ return;
236
+ }
237
+ if (callee === "role") {
238
+ const first = node.arguments?.[0];
239
+ if (typeof first?.value === "string") roleNames.add(first.value);
240
+ else if (first?.type === "MemberExpression" && typeof first.property?.name === "string") roleNames.add(first.property.name);
241
+ return;
242
+ }
243
+ if (callee === "findPermission") {
244
+ const second = node.arguments?.[1];
245
+ if (typeof second?.value === "string") {
246
+ pushUsage(second.value, {
247
+ file: fileRel,
248
+ line,
249
+ call: "findPermission"
250
+ }, knownKeys, usages, unknown);
251
+ return;
252
+ }
253
+ dynamic.push({
254
+ file: fileRel,
255
+ line,
256
+ call: "findPermission"
257
+ });
258
+ }
259
+ }
260
+ function recordMember(node, parent, lineAt, fileRel, isRoot, usages, unknown, dynamic, allowKeys, knownKeys) {
261
+ if (node.computed === true) {
262
+ const root = rootName(node);
263
+ if (root !== void 0 && isRoot(root)) dynamic.push({
264
+ file: fileRel,
265
+ line: lineAt(node.start ?? 0),
266
+ call: callName(parent)
267
+ });
268
+ return;
269
+ }
270
+ const path = memberPath(node);
271
+ if (path === void 0 || path.length < 2) return;
272
+ const [root, ...rest] = path;
273
+ if (root === void 0 || !isRoot(root)) return;
274
+ const key = rest.join(".");
275
+ if (!knownKeys.has(key) && isFieldOrSubtree(rest, knownKeys)) return;
276
+ const call = callName(parent);
277
+ const usage = {
278
+ file: fileRel,
279
+ line: lineAt(node.start ?? 0),
280
+ call
281
+ };
282
+ if (call === "allow") allowKeys.add(key);
283
+ pushUsage(key, usage, knownKeys, usages, unknown);
284
+ }
285
+ const LEAF_FIELDS = /* @__PURE__ */ new Set([
286
+ "key",
287
+ "resource",
288
+ "action",
289
+ "scope",
290
+ "meta"
291
+ ]);
292
+ function isFieldOrSubtree(path, knownKeys) {
293
+ const last = path.at(-1);
294
+ if (last !== void 0 && LEAF_FIELDS.has(last) && knownKeys.has(path.slice(0, -1).join("."))) return true;
295
+ const prefix = `${path.join(".")}.`;
296
+ return [...knownKeys].some((known) => known.startsWith(prefix));
297
+ }
298
+ function pushUsage(key, usage, knownKeys, usages, unknown) {
299
+ if (knownKeys.size > 0 && !knownKeys.has(key)) {
300
+ unknown.push({
301
+ ...usage,
302
+ call: `${usage.call}:${key}`
303
+ });
304
+ return;
305
+ }
306
+ const list = usages[key] ?? [];
307
+ list.push(usage);
308
+ usages[key] = list;
309
+ }
310
+ function calleeName(node) {
311
+ if (node === void 0) return;
312
+ if (node.type === "Identifier") return node.name;
313
+ if (node.type === "MemberExpression" && node.property?.type === "Identifier") return node.property.name;
314
+ }
315
+ function declaredName(parent) {
316
+ if (parent?.type === "VariableDeclarator" && parent.id?.type === "Identifier") return parent.id.name;
317
+ }
318
+ function callName(parent) {
319
+ if (parent?.type === "CallExpression") {
320
+ const name = calleeName(parent.callee);
321
+ if (name !== void 0 && CHECK_CALLS.has(name)) return name;
322
+ }
323
+ if (parent?.type === "Property" || parent?.type === "ObjectProperty") return "tools";
324
+ return "reference";
325
+ }
326
+ function memberPath(node) {
327
+ const parts = [];
328
+ let current = node;
329
+ while (current?.type === "MemberExpression") {
330
+ if (current.computed === true) return;
331
+ const name = current.property?.name;
332
+ if (name === void 0) return;
333
+ parts.unshift(name);
334
+ current = current.object;
335
+ }
336
+ if (current?.type !== "Identifier" || current.name === void 0) return;
337
+ parts.unshift(current.name);
338
+ return parts;
339
+ }
340
+ function rootName(node) {
341
+ let current = node;
342
+ while (current?.type === "MemberExpression") current = current.object;
343
+ return current?.type === "Identifier" ? current.name : void 0;
344
+ }
345
+ /** One pass over the file, then a binary search per node. */
346
+ function lineIndex(source) {
347
+ const starts = [0];
348
+ for (let i = 0; i < source.length; i += 1) if (source.charCodeAt(i) === 10) starts.push(i + 1);
349
+ return (index) => {
350
+ let low = 0;
351
+ let high = starts.length - 1;
352
+ while (low < high) {
353
+ const mid = low + high + 1 >> 1;
354
+ if ((starts[mid] ?? 0) <= index) low = mid;
355
+ else high = mid - 1;
356
+ }
357
+ return low + 1;
358
+ };
359
+ }
360
+ function collectObjectKeys(node, into) {
361
+ if (node?.type !== "ObjectExpression" || node.properties === void 0) return;
362
+ for (const property of node.properties) {
363
+ const key = property.key;
364
+ if (property.computed !== true && typeof key?.name === "string") {
365
+ into.add(key.name);
366
+ continue;
367
+ }
368
+ if (typeof key?.value === "string") into.add(key.value);
369
+ }
370
+ }
371
+ /** Every node in source order, with its parent: Oxc nodes carry none, so enter and exit keep a stack. */
372
+ function walk(program, visit) {
373
+ const stack = [];
374
+ const handlers = {};
375
+ for (const type of Object.keys(visitorKeys)) {
376
+ handlers[type] = (node) => {
377
+ visit(node, stack.at(-1), stack);
378
+ stack.push(node);
379
+ };
380
+ handlers[`${type}:exit`] = () => {
381
+ stack.pop();
382
+ };
383
+ }
384
+ new Visitor(handlers).visit(program);
385
+ }
386
+ //#endregion
387
+ //#region src/cli/collect.ts
388
+ async function runCollect(input) {
389
+ const load = { fresh: input.fresh === true };
390
+ const srcPath = input.collect.srcPath ?? input.config.collect?.srcPath ?? defaultSrcPath();
391
+ const outPath = catalogPath(input.config, input.cwd, input.collect.out);
392
+ const permissionsRel = input.config.permissions ?? guessPermissions(input.cwd, srcPath);
393
+ if (permissionsRel === void 0) return {
394
+ code: 2,
395
+ document: void 0,
396
+ scan: void 0,
397
+ outPath,
398
+ message: "usage: set permissions in permdock.config.ts or pass a definePermissions module"
399
+ };
400
+ const permissionsAbs = resolve(input.cwd, permissionsRel);
401
+ if (!existsSync(permissionsAbs)) return {
402
+ code: 2,
403
+ document: void 0,
404
+ scan: void 0,
405
+ outPath,
406
+ message: `PermDock CLI: permissions module not found: ${rel(input.cwd, permissionsAbs)}`
407
+ };
408
+ let tree;
409
+ try {
410
+ const mod = await loadModule(permissionsAbs, load);
411
+ tree = asPermissionTree(pickNamed(mod, ["permissions"]));
412
+ } catch (error) {
413
+ return {
414
+ code: 2,
415
+ document: void 0,
416
+ scan: void 0,
417
+ outPath,
418
+ message: describeError(error)
419
+ };
420
+ }
421
+ const files = listSourceFiles(input.cwd, input.scanPath ?? srcPath);
422
+ const knownKeys = new Set(leavesOf(tree).map((leaf) => leaf.key));
423
+ const scan = scanSources(input.cwd, files, knownKeys);
424
+ const policy = input.loadPolicy === void 0 ? await loadConfiguredPolicy(input.cwd, input.config.policy, load) : await input.loadPolicy();
425
+ const generatedAt = input.now.toISOString();
426
+ const document = buildCatalog(tree, scan, generatedAt, policy);
427
+ const next = formatCatalogJson(document);
428
+ if (input.check) {
429
+ if (!existsSync(outPath)) return {
430
+ code: 1,
431
+ document,
432
+ scan,
433
+ outPath,
434
+ message: `catalog missing: ${rel(input.cwd, outPath)}`
435
+ };
436
+ const current = readFileSync(outPath, "utf8");
437
+ const currentDoc = JSON.parse(current);
438
+ const onDisk = catalogForCompare(currentDoc);
439
+ const generated = catalogForCompare(input.scanPath === void 0 || samePaths(input.scanPath, srcPath) ? document : buildCatalog(tree, scanSources(input.cwd, listSourceFiles(input.cwd, srcPath), knownKeys), generatedAt, policy));
440
+ if (onDisk !== generated) {
441
+ const file = rel(input.cwd, outPath);
442
+ return {
443
+ code: 1,
444
+ document,
445
+ scan,
446
+ outPath,
447
+ message: `catalog drift: ${file}\n${shortDiff(file, onDisk, generated)}`
448
+ };
449
+ }
450
+ return {
451
+ code: 0,
452
+ document,
453
+ scan,
454
+ outPath,
455
+ message: `catalog up to date: ${rel(input.cwd, outPath)}`
456
+ };
457
+ }
458
+ mkdirSync(dirname(outPath), { recursive: true });
459
+ writeFileSync(outPath, next);
460
+ const written = [outPath];
461
+ const barrel = input.collect.barrel ?? input.config.collect?.barrel;
462
+ if (barrel !== void 0 && barrel !== false) {
463
+ const barrelPath = resolve(input.cwd, barrelFile(barrel));
464
+ writeBarrel(barrelPath, permissionsAbs);
465
+ written.push(barrelPath);
466
+ }
467
+ return {
468
+ code: 0,
469
+ document,
470
+ scan,
471
+ outPath,
472
+ message: `wrote ${rel(input.cwd, outPath)}`,
473
+ written
474
+ };
475
+ }
476
+ function samePaths(a, b) {
477
+ return a.length === b.length && a.every((entry, index) => entry === b[index]);
478
+ }
479
+ /** The permissions module `collect` reads when the config names none. */
480
+ function guessPermissions(cwd, srcPath) {
481
+ return [
482
+ "src/permissions.ts",
483
+ "permissions.ts",
484
+ ...srcPath.map((entry) => `${entry.replace(/\/$/, "")}/permissions.ts`)
485
+ ].find((file) => existsSync(resolve(cwd, file)));
486
+ }
487
+ function barrelFile(barrel) {
488
+ return barrel === true ? "src/permissions.generated.ts" : barrel;
489
+ }
490
+ function writeBarrel(abs, permissionsAbs) {
491
+ const specifier = relative(dirname(abs), permissionsAbs).replace(/\\/gu, "/").replace(/\.tsx?$/u, ".js");
492
+ const body = `// @generated by permdock — do not edit
493
+ import { mergePermissions } from 'permdock'
494
+ import { permissions as collected } from '${specifier.startsWith(".") ? specifier : `./${specifier}`}'
495
+
496
+ export const permissions = mergePermissions(collected)
497
+ `;
498
+ mkdirSync(dirname(abs), { recursive: true });
499
+ writeFileSync(abs, body);
500
+ }
501
+ //#endregion
502
+ export { scanSources as i, guessPermissions as n, runCollect as r, barrelFile as t };
@@ -0,0 +1,83 @@
1
+ import { i as describeError } from "./errors-CWfoNg9N.js";
2
+ import { a as listArg, i as globalArgs, s as stringArg, t as COMMAND_DESCRIPTIONS } from "./commands-DWOrSQic.js";
3
+ import { defineCommand } from "citty";
4
+ //#region src/cli/commands/collect.ts
5
+ function collect(ctx) {
6
+ return defineCommand({
7
+ meta: {
8
+ name: "collect",
9
+ description: COMMAND_DESCRIPTIONS.collect
10
+ },
11
+ args: {
12
+ ...globalArgs,
13
+ check: {
14
+ type: "boolean",
15
+ description: "Exit 1 when the catalog on disk is stale; write nothing"
16
+ },
17
+ src: {
18
+ type: "string",
19
+ description: "Source roots or globs, repeatable or comma-separated",
20
+ valueHint: "path"
21
+ },
22
+ out: {
23
+ type: "string",
24
+ description: "Catalog file to write",
25
+ valueHint: "file"
26
+ },
27
+ watch: {
28
+ type: "boolean",
29
+ description: "Collect again when a source, config or policy file changes"
30
+ }
31
+ },
32
+ async run({ args: parsed, rawArgs }) {
33
+ const src = listArg(rawArgs, "src");
34
+ const out = stringArg(parsed.out);
35
+ const overrides = {
36
+ ...src.length > 0 ? { srcPath: src } : {},
37
+ ...out === void 0 ? {} : { out }
38
+ };
39
+ if (parsed.watch === true) {
40
+ if (parsed.check === true) {
41
+ ctx.report({
42
+ code: 2,
43
+ output: "collect: --watch writes the catalog; drop --check"
44
+ });
45
+ return;
46
+ }
47
+ const { createCollectScheduler } = await import("./watch-Etoa_Mvr.js");
48
+ const scheduler = createCollectScheduler(ctx.cwd, { collect: overrides }, {
49
+ ...ctx.configFile === void 0 ? {} : { configFile: ctx.configFile },
50
+ report: (message) => {
51
+ ctx.io.stderr(message ?? "catalog updated");
52
+ }
53
+ });
54
+ let message;
55
+ try {
56
+ message = await scheduler.run(false);
57
+ } catch (error) {
58
+ message = describeError(error);
59
+ }
60
+ scheduler.watch();
61
+ ctx.report({
62
+ code: 0,
63
+ output: message ?? "watching for changes; Ctrl-C to stop"
64
+ });
65
+ return;
66
+ }
67
+ const result = await (await import("./collect-rG2IQ3t0.js")).runCollect({
68
+ cwd: ctx.cwd,
69
+ config: ctx.config,
70
+ collect: overrides,
71
+ check: parsed.check === true,
72
+ now: ctx.now,
73
+ io: ctx.io
74
+ });
75
+ ctx.report({
76
+ code: result.code,
77
+ output: result.message
78
+ });
79
+ }
80
+ });
81
+ }
82
+ //#endregion
83
+ export { collect };
@@ -0,0 +1,2 @@
1
+ import { r as runCollect } from "./collect-DDDv_ESs.js";
2
+ export { runCollect };
@@ -0,0 +1,97 @@
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
+ config: "Check permdock.config.ts for unknown keys, or print the effective config",
69
+ skills: "Install, update or list the PermDock Agent Skills",
70
+ openapi: "Emit security into an OpenAPI document, or import one into a generated definition",
71
+ rls: "Generate, import, verify or migrate Postgres RLS policies from the policy",
72
+ arazzo: "Resolve every Arazzo step to x-permdock-permissions",
73
+ cloud: "Publish the catalog, hostable flags and role assignability to a PermDock Cloud environment",
74
+ supabase: "Generate the Supabase Custom Access Token Hook, or inspect its manifest",
75
+ powersync: "Generate PowerSync Sync Streams from the policy, or verify them against the fixtures"
76
+ };
77
+ /** Every top-level command, loaded only when it runs or its own `--help` is asked for. */
78
+ const commands = {
79
+ collect: async () => (await import("./collect-DLlujdHC.js")).collect,
80
+ catalog: async () => (await import("./catalog-h2tlKFkq.js")).catalog,
81
+ diff: async () => (await import("./diff-CzqLxZ77.js")).diff,
82
+ usage: async () => (await import("./usage-D07N9QJ3.js")).usage,
83
+ doctor: async () => (await import("./doctor-rOr-4ZfS.js")).doctor,
84
+ config: async () => (await import("./config-Bn00Z3ks.js")).config,
85
+ skills: async () => (await import("./skills-JaymNCdK.js")).skills,
86
+ openapi: async () => (await import("./openapi-Bbg4wGVL.js")).openapi,
87
+ rls: async () => (await import("./rls-CEvs64Kj.js")).rls,
88
+ arazzo: async () => (await import("./arazzo-cmvX2jDe.js")).arazzo,
89
+ cloud: async () => (await import("./cloud-BGhHS-lY.js")).cloud,
90
+ supabase: async () => (await import("./supabase-CwafwxxF.js")).supabase,
91
+ powersync: async () => (await import("./powersync-yW1UUFzp.js")).powersync
92
+ };
93
+ function isCommand(name) {
94
+ return Object.hasOwn(commands, name);
95
+ }
96
+ //#endregion
97
+ export { listArg as a, globalArgs as i, commands as n, resolveArgs as o, isCommand as r, stringArg as s, COMMAND_DESCRIPTIONS as t };