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,367 @@
1
+ import { i as describeError } from "./errors-CWfoNg9N.js";
2
+ import { a as sqlFiles } from "./files-DWUN9PzI.js";
3
+ import { i as quoteSqlLiteral, n as escapeSqlIdent } from "./sql-xdg5f4Fi.js";
4
+ import "./sources-B0UvrJ21.js";
5
+ import { n as HELPERS } from "./rls-shared-aOQ4hGTO.js";
6
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
7
+ import { relative, resolve } from "node:path";
8
+ import { parse } from "pgsql-parser";
9
+ //#region src/cli/rls-migrate.ts
10
+ function migrateTarget(generated) {
11
+ const granted = /* @__PURE__ */ new Map();
12
+ for (const row of generated.seeds ?? []) {
13
+ if (row.effect !== "allow") continue;
14
+ let keys = granted.get(row.scope);
15
+ if (keys === void 0) {
16
+ keys = /* @__PURE__ */ new Set();
17
+ granted.set(row.scope, keys);
18
+ }
19
+ keys.add(row.grantKey);
20
+ }
21
+ return {
22
+ schema: generated.schema ?? "permdock",
23
+ sql: generated.text,
24
+ permissions: new Set(generated.keys?.permissions ?? []),
25
+ rowConditions: new Set(generated.keys?.rowConditions ?? []),
26
+ granted,
27
+ renamed: generated.keys?.renamed ?? {}
28
+ };
29
+ }
30
+ function isNode(value) {
31
+ return typeof value === "object" && value !== null && !Array.isArray(value);
32
+ }
33
+ function child(node, key) {
34
+ return isNode(node) ? node[key] : void 0;
35
+ }
36
+ function list(value) {
37
+ return Array.isArray(value) ? value : [];
38
+ }
39
+ /** libpg_query reports byte offsets; this maps them onto string indices. */
40
+ function charIndex(text) {
41
+ if (Buffer.byteLength(text) === text.length) return (byte) => byte;
42
+ const map = [];
43
+ for (let index = 0; index < text.length; index += 1) {
44
+ const code = text.codePointAt(index) ?? 0;
45
+ const size = Buffer.byteLength(String.fromCodePoint(code));
46
+ for (let byte = 0; byte < size; byte += 1) map.push(index);
47
+ if (code > 65535) index += 1;
48
+ }
49
+ return (byte) => map[byte] ?? text.length;
50
+ }
51
+ /** The index just past the `)` closing the call that starts at `start`. */
52
+ function callEnd(text, start) {
53
+ let depth = 0;
54
+ for (let index = start; index < text.length; index += 1) {
55
+ const char = text[index];
56
+ if (char === "'" || char === "\"") {
57
+ const close = text.indexOf(char, index + 1);
58
+ if (close === -1) return -1;
59
+ index = close;
60
+ continue;
61
+ }
62
+ if (char === "-" && text[index + 1] === "-") {
63
+ const close = text.indexOf("\n", index);
64
+ index = close === -1 ? text.length : close;
65
+ continue;
66
+ }
67
+ if (char === "/" && text[index + 1] === "*") {
68
+ const close = text.indexOf("*/", index + 2);
69
+ index = close === -1 ? text.length : close + 1;
70
+ continue;
71
+ }
72
+ if (char === "(") depth += 1;
73
+ else if (char === ")") {
74
+ depth -= 1;
75
+ if (depth === 0) return index + 1;
76
+ }
77
+ }
78
+ return -1;
79
+ }
80
+ const IDENTIFIER = String.raw`(?:"(?:[^"]|"")+"|[A-Za-z_][\w$]*)`;
81
+ const COLUMN = new RegExp(String.raw`${IDENTIFIER}(?:\s*\.\s*${IDENTIFIER})*`, "uy");
82
+ function columnText(text, start) {
83
+ COLUMN.lastIndex = start;
84
+ return COLUMN.exec(text)?.[0];
85
+ }
86
+ function lineOf(text, index) {
87
+ let line = 1;
88
+ for (let at = text.indexOf("\n"); at !== -1 && at < index;) {
89
+ line += 1;
90
+ at = text.indexOf("\n", at + 1);
91
+ }
92
+ return line;
93
+ }
94
+ function stringConst(node) {
95
+ const value = child(child(child(node, "A_Const"), "sval"), "sval");
96
+ return typeof value === "string" ? value : void 0;
97
+ }
98
+ function isNullConst(node) {
99
+ return child(child(node, "A_Const"), "isnull") === true;
100
+ }
101
+ const literal = quoteSqlLiteral;
102
+ /** The PermDock key for a legacy one: `keys` first, then `renamed`, then the longest matching prefix. */
103
+ function mapKey(config, key, renamed = {}) {
104
+ const exact = config.keys?.[key];
105
+ if (exact !== void 0) return exact;
106
+ if (Object.hasOwn(renamed, key)) return renamed[key] ?? key;
107
+ const prefix = Object.keys(config.prefixes ?? {}).filter((candidate) => key.startsWith(candidate)).toSorted((a, b) => b.length - a.length)[0];
108
+ return prefix === void 0 ? key : `${config.prefixes?.[prefix] ?? ""}${key.slice(prefix.length)}`;
109
+ }
110
+ function skip(reason, detail) {
111
+ return {
112
+ reason,
113
+ detail
114
+ };
115
+ }
116
+ var Rewriter = class {
117
+ #config;
118
+ #target;
119
+ #text;
120
+ #at;
121
+ constructor(config, target, text) {
122
+ this.#config = config;
123
+ this.#target = target;
124
+ this.#text = text;
125
+ this.#at = charIndex(text);
126
+ }
127
+ #helper(name) {
128
+ const { schema, sql } = this.#target;
129
+ const quoted = escapeSqlIdent(schema);
130
+ if (!sql.includes(`function ${quoted}.${name}(`)) return;
131
+ return /^[a-z_][a-z0-9_$]*$/u.test(schema) ? `${schema}.${name}` : `${quoted}.${name}`;
132
+ }
133
+ #key(arg, scope) {
134
+ const legacy = stringConst(arg);
135
+ if (legacy === void 0) return skip("dynamic-key", "the key is not a string literal; map it by hand");
136
+ const key = mapKey(this.#config, legacy, this.#target.renamed);
137
+ if (!this.#target.permissions.has(key)) return skip("unknown-key", `${legacy} maps to ${key}, which the policy does not declare; add it to rls.migrate.keys or the vocabulary`);
138
+ if (this.#target.rowConditions.has(key)) return skip("row-conditions", `${key} has row conditions the helper cannot apply; let rls generate write this table's policy`);
139
+ if (this.#target.granted.get(scope)?.has(key) !== true) return skip("not-granted-on-scope", [...this.#target.granted.values()].some((keys) => keys.has(key)) ? `no role grants ${key} on ${scope}, so the helper would always deny` : `${key} has no unconditional allow row in role_permissions: a conditional, time-bounded or deny-mixed grant splits its grant key, so the helper would always deny`);
140
+ return { to: literal(key) };
141
+ }
142
+ #column(arg) {
143
+ const location = child(child(arg, "ColumnRef"), "location");
144
+ if (typeof location !== "number") return skip("not-a-column", "the id is an expression, not a plain column; rewrite it by hand");
145
+ const text = columnText(this.#text, this.#at(location));
146
+ return text === void 0 ? skip("not-a-column", "the id could not be read as a column") : { to: text };
147
+ }
148
+ #ids(scope, keyArg) {
149
+ const helper = this.#helper(`permitted_${scope}_ids`);
150
+ if (helper === void 0) return skip("missing-helper", `rls generate writes no permitted_${scope}_ids for this policy`);
151
+ const key = this.#key(keyArg, scope);
152
+ return "to" in key ? { to: `${helper}(${key.to})` } : key;
153
+ }
154
+ #row(scope, idArg, keyArg) {
155
+ const column = this.#column(idArg);
156
+ if (!("to" in column)) return column;
157
+ const ids = this.#ids(scope, keyArg);
158
+ return "to" in ids ? { to: `(${column.to} in (select ${ids.to}))` } : ids;
159
+ }
160
+ #global(keyArg, selected) {
161
+ const helper = this.#helper(HELPERS.has);
162
+ if (helper === void 0) return skip("missing-helper", `rls generate writes no ${HELPERS.has}`);
163
+ const key = this.#key(keyArg, "global");
164
+ if (!("to" in key)) return key;
165
+ const call = `${helper}(${key.to})`;
166
+ return { to: selected ? call : `(select ${call})` };
167
+ }
168
+ #membership(scope, idArg) {
169
+ const helper = this.#helper(`member_${scope}_ids`);
170
+ if (helper === void 0) return skip("missing-helper", `rls generate writes no member_${scope}_ids: ${scope} has no membership source`);
171
+ const column = this.#column(idArg);
172
+ return "to" in column ? { to: `(${column.to} in (select ${helper}()))` } : column;
173
+ }
174
+ #scoped(args, selected) {
175
+ const [scopeArg, idArg, keyArg] = args;
176
+ const named = stringConst(scopeArg);
177
+ if (named === void 0) return skip("unknown-scope", "the scope is not a string literal; rewrite it by hand");
178
+ if (this.#config.globalScopes?.includes(named) === true || isNullConst(idArg)) return this.#global(keyArg, selected);
179
+ return this.#row(this.#config.scopes?.[named] ?? named, idArg, keyArg);
180
+ }
181
+ /** `selected`: the call is already a `select` target, so `permdock_has` needs no wrapping subquery. */
182
+ rewrite(call, selected) {
183
+ const { helper, args } = call;
184
+ switch (helper.form) {
185
+ case "ids": return this.#ids(helper.scope, args[0]);
186
+ case "row": return this.#row(helper.scope, args[0], args[1]);
187
+ case "membership": return this.#membership(helper.scope, args[0]);
188
+ case "scoped": return this.#scoped(args, selected);
189
+ case "global": return this.#global(args[0], selected);
190
+ default: return helper;
191
+ }
192
+ }
193
+ call(node) {
194
+ const name = list(node["funcname"]).map((part) => child(child(part, "String"), "sval")).at(-1);
195
+ const location = node["location"];
196
+ if (typeof name !== "string" || typeof location !== "number") return;
197
+ const helper = this.#config.helpers[name];
198
+ if (helper === void 0) return;
199
+ const start = this.#at(location);
200
+ return {
201
+ name,
202
+ helper,
203
+ args: list(node["args"]),
204
+ start,
205
+ end: callEnd(this.#text, start)
206
+ };
207
+ }
208
+ };
209
+ const POLICY_STATEMENTS = /* @__PURE__ */ new Set(["CreatePolicyStmt", "AlterPolicyStmt"]);
210
+ const BODY_STATEMENTS = /* @__PURE__ */ new Set(["CreateFunctionStmt", "DoStmt"]);
211
+ function bodyStrings(statement) {
212
+ const options = [...list(child(statement, "options")), ...list(child(statement, "args"))];
213
+ const found = [];
214
+ for (const option of options) {
215
+ const element = child(option, "DefElem");
216
+ if (child(element, "defname") !== "as") continue;
217
+ const arg = child(element, "arg");
218
+ const items = [child(arg, "String"), ...list(child(child(arg, "List"), "items")).map((item) => child(item, "String"))];
219
+ for (const item of items) {
220
+ const value = child(item, "sval");
221
+ if (typeof value === "string") found.push(value);
222
+ }
223
+ }
224
+ return found;
225
+ }
226
+ /** Rewrites the configured helper calls in one file's policies; everything else is reported. */
227
+ async function migrateSql(file, text, config, target) {
228
+ const rewrites = [];
229
+ const skipped = [];
230
+ const names = Object.keys(config.helpers);
231
+ if (!names.some((name) => text.includes(name))) return {
232
+ rewrites,
233
+ skipped,
234
+ text
235
+ };
236
+ let tree;
237
+ try {
238
+ tree = await parse(text);
239
+ } catch (cause) {
240
+ skipped.push({
241
+ file,
242
+ line: 1,
243
+ call: "",
244
+ reason: "unparsed",
245
+ detail: `the file does not parse: ${describeError(cause)}`
246
+ });
247
+ return {
248
+ rewrites,
249
+ skipped,
250
+ text
251
+ };
252
+ }
253
+ const rewriter = new Rewriter(config, target, text);
254
+ const at = charIndex(text);
255
+ const edits = [];
256
+ const called = new RegExp(String.raw`\b(${names.map((name) => name.replaceAll(/[$]/gu, String.raw`\$`)).join("|")})\s*\(`, "gu");
257
+ const visit = (node, inPolicy, selected = false) => {
258
+ if (Array.isArray(node)) {
259
+ for (const item of node) visit(item, inPolicy);
260
+ return;
261
+ }
262
+ if (!isNode(node)) return;
263
+ for (const [kind, value] of Object.entries(node)) {
264
+ if (kind === "FuncCall" && isNode(value)) {
265
+ const call = rewriter.call(value);
266
+ if (call !== void 0) {
267
+ const source = call.end === -1 ? call.name : text.slice(call.start, call.end);
268
+ const line = lineOf(text, call.start);
269
+ if (!inPolicy) {
270
+ skipped.push({
271
+ file,
272
+ line,
273
+ call: source,
274
+ reason: "not-in-policy",
275
+ detail: "the call is outside a create or alter policy; rewrite it by hand"
276
+ });
277
+ continue;
278
+ }
279
+ const outcome = call.end === -1 ? skip("not-a-column", "the call could not be delimited") : rewriter.rewrite(call, selected);
280
+ if ("to" in outcome) {
281
+ edits.push({
282
+ start: call.start,
283
+ end: call.end,
284
+ to: outcome.to
285
+ });
286
+ rewrites.push({
287
+ file,
288
+ line,
289
+ from: source,
290
+ to: outcome.to
291
+ });
292
+ } else skipped.push({
293
+ file,
294
+ line,
295
+ call: source,
296
+ ...outcome
297
+ });
298
+ continue;
299
+ }
300
+ }
301
+ visit(value, inPolicy || POLICY_STATEMENTS.has(kind), kind === "ResTarget" || selected && kind === "val");
302
+ }
303
+ };
304
+ for (const raw of list(child(tree, "stmts"))) {
305
+ const statement = child(raw, "stmt");
306
+ const offset = child(raw, "stmt_location");
307
+ const statementStart = at(typeof offset === "number" ? offset : 0);
308
+ const kind = isNode(statement) ? Object.keys(statement)[0] : void 0;
309
+ if (kind !== void 0 && BODY_STATEMENTS.has(kind)) {
310
+ for (const body of bodyStrings(child(statement, kind))) {
311
+ const bodyStart = text.indexOf(body, statementStart);
312
+ for (const match of body.matchAll(called)) skipped.push({
313
+ file,
314
+ line: lineOf(text, (bodyStart === -1 ? statementStart : bodyStart) + (match.index ?? 0)),
315
+ call: match[1] ?? "",
316
+ reason: "function-body",
317
+ detail: "the call is inside a function body, which runs with its own privileges; rewrite it by hand"
318
+ });
319
+ }
320
+ continue;
321
+ }
322
+ visit(statement, false);
323
+ }
324
+ let out = text;
325
+ for (const edit of edits.toSorted((a, b) => b.start - a.start)) out = `${out.slice(0, edit.start)}${edit.to}${out.slice(edit.end)}`;
326
+ return {
327
+ rewrites,
328
+ skipped,
329
+ text: out
330
+ };
331
+ }
332
+ function describe(report, write) {
333
+ const lines = [...report.rewrites.map((item) => `${item.file}:${String(item.line)} ${item.from} -> ${item.to}`), ...report.skipped.map((item) => `skipped ${item.file}:${String(item.line)} ${item.call}: ${item.detail}`)];
334
+ const files = new Set(report.rewrites.map((item) => item.file)).size;
335
+ const unknown = report.skipped.filter((item) => item.reason === "unknown-key").length;
336
+ lines.push(`rls migrate: ${write ? "rewrote" : "would rewrite"} ${String(report.rewrites.length)} call(s) in ${String(files)} file(s), skipped ${String(report.skipped.length)}${unknown === 0 ? "" : `, ${String(unknown)} with an unknown key`}${write ? "" : "; --write applies them"}`);
337
+ return lines.join("\n");
338
+ }
339
+ /** `permdock rls migrate`: a dry run unless `write`; exits 1 while a key is unknown. */
340
+ async function runRlsMigrate(input) {
341
+ const root = resolve(input.cwd, input.sql);
342
+ if (!existsSync(root)) return {
343
+ code: 2,
344
+ output: `rls migrate --sql: ${input.sql} does not exist`
345
+ };
346
+ const files = sqlFiles(root, ["."]);
347
+ const rewrites = [];
348
+ const skipped = [];
349
+ for (const path of files) {
350
+ const file = relative(input.cwd, path);
351
+ const text = readFileSync(path, "utf8");
352
+ const result = await migrateSql(file, text, input.config, input.target);
353
+ rewrites.push(...result.rewrites);
354
+ skipped.push(...result.skipped);
355
+ if (input.write && result.text !== text) writeFileSync(path, result.text);
356
+ }
357
+ const report = {
358
+ rewrites,
359
+ skipped
360
+ };
361
+ return {
362
+ code: skipped.some((item) => item.reason === "unknown-key") ? 1 : 0,
363
+ output: input.json ? JSON.stringify(report, void 0, 2) : describe(report, input.write)
364
+ };
365
+ }
366
+ //#endregion
367
+ export { migrateTarget, runRlsMigrate };