permdock 0.7.0 → 0.9.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 (483) hide show
  1. package/README.md +1 -3
  2. package/dist/a2a/index.d.ts +7 -7
  3. package/dist/a2a/index.js +8 -8
  4. package/dist/action-result-BcudBQOF.d.ts +19 -0
  5. package/dist/{adapter-context-CRhqyzCk.js → adapter-context-CIQpQxbE.js} +8 -2
  6. package/dist/{adoption-scan-D-feE7BE.js → adoption-scan-Ch07MdxN.js} +5 -5
  7. package/dist/agent/index.d.ts +2 -2
  8. package/dist/agent/index.js +1 -1
  9. package/dist/ai-sdk/index.d.ts +19 -13
  10. package/dist/ai-sdk/index.js +6 -6
  11. package/dist/{app-data-MuyzVqX8.js → app-data-UNNm07jV.js} +10 -7
  12. package/dist/{approval-header-CJACtHkv.js → approval-header-8QV6MU4H.js} +6 -3
  13. package/dist/{approval-prompt-K0faOLFp.d.ts → approval-prompt-3BqWczTt.d.ts} +13 -11
  14. package/dist/{approval-prompt-Dg5LeAcT.js → approval-prompt-B8hQY69x.js} +5 -6
  15. package/dist/approvals/index.d.ts +4 -4
  16. package/dist/approvals/index.js +6 -6
  17. package/dist/{approvals-CMRfsbBh.js → approvals-DnIBTuXE.js} +66 -42
  18. package/dist/{approvers-CqPOLD-o.js → approvers-B4r0N_Uz.js} +8 -2
  19. package/dist/{arazzo-ClrF3PVb.js → arazzo-BpS7LnV0.js} +2 -2
  20. package/dist/{arazzo-rdeJ8n1J.js → arazzo-CmQaGPkM.js} +6 -6
  21. package/dist/{args-CC3OwyHW.js → args-0FrVs5EH.js} +14 -7
  22. package/dist/astro/index.d.ts +30 -12
  23. package/dist/astro/index.js +2 -2
  24. package/dist/{audience-BrMs8c4o.js → audience-DTjR8xet.js} +8 -8
  25. package/dist/{auth-CscUX8Sy.js → auth--yPyZNgr.js} +19 -7
  26. package/dist/authzen/index.d.ts +34 -28
  27. package/dist/authzen/index.js +23 -20
  28. package/dist/{automation-DOtAFWdy.d.ts → automation-C6Jg75xq.d.ts} +42 -32
  29. package/dist/{automation-ySsxp_Yp.js → automation-x3KEUusw.js} +22 -21
  30. package/dist/better-auth/index.d.ts +2 -2
  31. package/dist/better-auth/index.js +13 -7
  32. package/dist/better-supabase/index.d.ts +357 -227
  33. package/dist/better-supabase/index.js +219 -140
  34. package/dist/{bind-D1nO6fiC.js → bind-BNQA9JK9.js} +26 -10
  35. package/dist/{bind-JDuvxjuW.d.ts → bind-YYjvfpB9.d.ts} +32 -12
  36. package/dist/{body-CH5of8Ne.js → body-CJQwYVa8.js} +3 -3
  37. package/dist/{body-text-QcXok_SI.js → body-text-DQhcmqdY.js} +8 -4
  38. package/dist/{boundary-BM8a_P6E.js → boundary-BV3O1eud.js} +8 -2
  39. package/dist/{boundary-BmHxVH1J.d.ts → boundary-C9ck-3uK.d.ts} +13 -4
  40. package/dist/{budget-NbEtbJC_.js → budget-BELja5A9.js} +6 -3
  41. package/dist/{budget-JqcRqyhK.d.ts → budget-hYsPz_yE.d.ts} +6 -3
  42. package/dist/{build-instance-DxE7czo9.js → build-instance-BWXqwQYU.js} +3 -3
  43. package/dist/{capability-L7NnfhiE.js → capability-BqX94r07.js} +31 -25
  44. package/dist/{capability-D4UC9TTW.d.ts → capability-Di9tiUvi.d.ts} +41 -29
  45. package/dist/{casbin-BHijLuHY.js → casbin-B7_yS-oo.js} +2 -2
  46. package/dist/{casbin-BW9pS47J.js → casbin-bHyIxTNQ.js} +16 -8
  47. package/dist/{casl-CmJlgziS.js → casl-C4OINZHI.js} +2 -2
  48. package/dist/{casl-UbI8v-Wq.js → casl-CHHoCldP.js} +19 -10
  49. package/dist/catalog/index.d.ts +51 -30
  50. package/dist/catalog/index.js +18 -15
  51. package/dist/{catalog-D69WhFii.js → catalog-CGlSwU6j.js} +20 -19
  52. package/dist/catalog-D3oS2GH3.js +1 -0
  53. package/dist/{catalog-BaMQfQ6Y.js → catalog-amPDr0JQ.js} +3 -3
  54. package/dist/{catalog-doc-CV9s6B1S.js → catalog-doc-DjMKzJp9.js} +28 -14
  55. package/dist/{catalog-fingerprint-C144oW4M.js → catalog-fingerprint-e6aCWosn.js} +18 -14
  56. package/dist/catalog-operations-DeHTrJSV.js +60 -0
  57. package/dist/{challenge-nGWma08S.js → challenge-DImNcR7B.js} +48 -27
  58. package/dist/chat/index.d.ts +1 -1
  59. package/dist/chat/index.js +13 -10
  60. package/dist/chat-sdk/index.d.ts +44 -26
  61. package/dist/chat-sdk/index.js +17 -17
  62. package/dist/{checks-BC_0mPIq.js → checks-CGkP3Z7A.js} +4 -1
  63. package/dist/{claims-map-7oQ3ue4X.js → claims-map-CKkoAAYF.js} +5 -2
  64. package/dist/{claims-map-Ca-QX8C6.d.ts → claims-map-D1Pb5oRq.d.ts} +8 -5
  65. package/dist/claude-agent/index.d.ts +6 -6
  66. package/dist/claude-agent/index.js +6 -3
  67. package/dist/clerk/index.d.ts +11 -7
  68. package/dist/clerk/index.js +6 -6
  69. package/dist/cli/bin.js +4 -4
  70. package/dist/cli/index.d.ts +82 -7
  71. package/dist/cli/index.js +6 -6
  72. package/dist/{clients-C7zLFuWT.d.ts → clients-C_NOET3z.d.ts} +5 -5
  73. package/dist/{clients-DjU5ABMy.js → clients-DYr3U86j.js} +3 -3
  74. package/dist/cloud/index.d.ts +84 -52
  75. package/dist/cloud/index.js +53 -39
  76. package/dist/{cloud-CO8pYtwr.js → cloud-3kWfjnYy.js} +4 -5
  77. package/dist/{codemod-BP6n8N9L.js → codemod-Bv5i-Mzo.js} +523 -201
  78. package/dist/{codemod-i4N2BhDc.js → codemod-D9Aiii1r.js} +3 -4
  79. package/dist/{collect-DNm3oKOk.js → collect-B80GYEot.js} +4 -5
  80. package/dist/collect-D-eroIfV.js +1 -0
  81. package/dist/{collect-BaWeMjwV.js → collect-WCl8cJQV.js} +26 -63
  82. package/dist/{compare-pfyVnBjE.js → compare-DTfyUunF.js} +2 -2
  83. package/dist/compile/index.d.ts +2 -2
  84. package/dist/compile/index.js +1 -1
  85. package/dist/{compile-COM2VKuN.d.ts → compile-BEklRUYo.d.ts} +36 -12
  86. package/dist/{compile-BAEO5bOk.js → compile-EzEMB-7v.js} +77 -33
  87. package/dist/{completion-BNdVf7X2.js → completion-_bc0OUQ-.js} +17 -8
  88. package/dist/config-BwPBfN0t.js +108 -0
  89. package/dist/{config-DGZzMV1B.js → config-D5XrLWpk.js} +2 -2
  90. package/dist/{config-report-Cm7UITNA.js → config-report-BmWIskD7.js} +9 -6
  91. package/dist/config-shape-ykV0Vm2n.js +134 -0
  92. package/dist/{connection-DjhIJSs2.js → connection-B72dg5Q2.js} +23 -22
  93. package/dist/{connector-schema-_VCSsdtD.js → connector-schema-CYLQNMYq.js} +3 -2
  94. package/dist/{context--uM9V3Ui.js → context-BnIzxTNE.js} +4 -3
  95. package/dist/convex/index.d.ts +13 -7
  96. package/dist/convex/index.js +9 -6
  97. package/dist/{core-CQkE8Esr.d.ts → core-CFepFiDP.d.ts} +49 -22
  98. package/dist/{core-B5-w6Kw9.js → core-DzVINFbU.js} +26 -20
  99. package/dist/{create-Cb86Z8Im.js → create-6EwRQlig.js} +10 -7
  100. package/dist/{create-DJrlhEp9.js → create-BLPKnJKa.js} +35 -25
  101. package/dist/{create-UTnUVETj.d.ts → create-BPUopdfL.d.ts} +70 -37
  102. package/dist/{create-QHuuPw3q.d.ts → create-BamXmeob.d.ts} +37 -29
  103. package/dist/{create-B2-CQqCI.d.ts → create-DBvUsgzK.d.ts} +49 -28
  104. package/dist/{credential-CIM7wHwA.js → credential-CyyyvCsL.js} +41 -38
  105. package/dist/{credentials-BpuTwd7a.js → credentials-CdDxp7jN.js} +6 -6
  106. package/dist/{deciding-columns-DRo2QM6E.js → deciding-columns-NB4wcyBf.js} +2 -2
  107. package/dist/{delegation-C5rOdTp5.js → delegation-CDB6_keF.js} +31 -22
  108. package/dist/delivery/index.d.ts +4 -4
  109. package/dist/delivery/index.js +5 -5
  110. package/dist/{delivery-rwOKLWRm.js → delivery-BupfvJIV.js} +34 -22
  111. package/dist/{delivery-event-xX4obB8F.js → delivery-event-JioK5YbS.js} +6 -6
  112. package/dist/denied-text-DHldhVUv.d.ts +22 -0
  113. package/dist/{describe-DZlnEtLy.js → describe-Bb4hGK5d.js} +5 -5
  114. package/dist/{describe-O0SwYIK8.d.ts → describe-BbFPBSms.d.ts} +5 -5
  115. package/dist/{device-BARQ8eYG.js → device-BwbJNmb2.js} +11 -8
  116. package/dist/{diff-Btr1c1Ow.js → diff-BwR1JdP2.js} +2 -2
  117. package/dist/{diff-DzT-xD13.js → diff-CQegtBAo.js} +22 -13
  118. package/dist/{digest-B3kc_PgQ.d.ts → digest-8Yx2CchM.d.ts} +3 -3
  119. package/dist/{doctor-BU1szn63.js → doctor-ClRVAtXQ.js} +287 -135
  120. package/dist/{doctor-BoK_y0KO.js → doctor-LPMYjSqO.js} +4 -4
  121. package/dist/drizzle/index.d.ts +33 -19
  122. package/dist/drizzle/index.js +17 -9
  123. package/dist/elysia/index.d.ts +17 -11
  124. package/dist/elysia/index.js +5 -5
  125. package/dist/{errors-BKy0EfhN.js → errors-B6R_lg2a.js} +13 -4
  126. package/dist/{errors-B_Qg9D3e.d.ts → errors-BIM4MFsJ.d.ts} +22 -6
  127. package/dist/{errors-BWXBMaKK.d.ts → errors-CHwoRRpB.d.ts} +4 -1
  128. package/dist/{errors-DpP_U6Bf.js → errors-Vpu6rKHl.js} +13 -10
  129. package/dist/{evaluate-B_oqFbWC.js → evaluate-BAmf_AQd.js} +153 -82
  130. package/dist/{evaluations-BCddEOfO.d.ts → evaluations-DOWuBpWv.d.ts} +11 -5
  131. package/dist/{evaluations-DReoiVBw.js → evaluations-IBceAeKT.js} +40 -19
  132. package/dist/eve/index.d.ts +9 -6
  133. package/dist/eve/index.js +4 -4
  134. package/dist/{event-time-CsegxXxB.js → event-time-BGy48400.js} +8 -4
  135. package/dist/{expiry-D4_YKRKD.js → expiry-6XByK0dm.js} +8 -5
  136. package/dist/express/index.d.ts +9 -6
  137. package/dist/express/index.js +9 -6
  138. package/dist/fastify/index.d.ts +16 -10
  139. package/dist/fastify/index.js +8 -5
  140. package/dist/{fetch-adapter-CuhyYwC1.d.ts → fetch-adapter-BIbBAtPZ.d.ts} +9 -6
  141. package/dist/{fetch-adapter-De-u6vhJ.js → fetch-adapter-dPTgJVHd.js} +14 -11
  142. package/dist/fields-D0vUI6dq.js +498 -0
  143. package/dist/{files-acUbNwWt.js → files-B3AA05f1.js} +8 -5
  144. package/dist/{files-D_JIzUrP.js → files-BSjrtIHw.js} +11 -4
  145. package/dist/{fixtures-BTMW6zgU.js → fixtures-A1_sp_tR.js} +15 -6
  146. package/dist/{flags-aaeRAdiD.js → flags-DXjoTVbS.js} +2 -2
  147. package/dist/{freeze-CrU8nQeX.js → freeze-jjan0lCv.js} +4 -1
  148. package/dist/{from-snapshot-Bz469dIh.js → from-snapshot-DCakWRsr.js} +18 -15
  149. package/dist/gen-BFfzZSLH.js +58 -0
  150. package/dist/gen-BtfFWGbz.js +827 -0
  151. package/dist/{generate-3FNO5P5Q.js → generate-CRVV5V7l.js} +14 -8
  152. package/dist/generate-CezbCaTI.js +275 -0
  153. package/dist/{grantee-BrRANrpT.js → grantee-Dke-9rd1.js} +4 -4
  154. package/dist/{grantee-conditions-C6P1Tvol.js → grantee-conditions-BrYPe-w0.js} +12 -12
  155. package/dist/{grantee-match-0RtHWQDx.js → grantee-match-7RZZvoT_.js} +12 -6
  156. package/dist/{graph-sql-B-dsAT6j.d.ts → graph-sql-BwFC4Qjs.d.ts} +3 -3
  157. package/dist/h3/index.d.ts +10 -7
  158. package/dist/h3/index.js +3 -3
  159. package/dist/headers-B9jQxjtW.d.ts +10 -0
  160. package/dist/{helpers-DY3vXuGs.js → helpers-DJicaG6f.js} +40 -28
  161. package/dist/hono/index.d.ts +16 -10
  162. package/dist/hono/index.js +5 -5
  163. package/dist/{hosted-XBgU6RGT.js → hosted-D0IzESu_.js} +42 -21
  164. package/dist/{hosted-BmjzxQhp.d.ts → hosted-DVxlLZMe.d.ts} +33 -21
  165. package/dist/{http-ujKm0JXE.js → http-DH94eh6f.js} +4 -4
  166. package/dist/{http-BBoKefeS.js → http-DKLXrFGk.js} +13 -7
  167. package/dist/{http-Ca3Sr5x1.js → http-DOL33cO0.js} +11 -8
  168. package/dist/{import-DB2EG_iy.js → import-ACkOrv6g.js} +6 -6
  169. package/dist/{import-Bz0GefWg.js → import-CST57XLp.js} +64 -51
  170. package/dist/{index-CMiPH2Tv.d.ts → index-BinlXeU-.d.ts} +64 -37
  171. package/dist/{index-BSfRl0hZ.d.ts → index-CV-7DWeD.d.ts} +64 -52
  172. package/dist/{index-BE8y3moU.d.ts → index-DJwEgYzA.d.ts} +127 -82
  173. package/dist/{index-DH9DUDEM.d.ts → index-Dj2qF9VC.d.ts} +54 -30
  174. package/dist/{index-BTkwrK7v.d.ts → index-vYjMrXyK.d.ts} +336 -173
  175. package/dist/{index-DLwcuCN_.d.ts → index-ymept53A.d.ts} +51 -30
  176. package/dist/index.d.ts +22 -22
  177. package/dist/index.js +34 -34
  178. package/dist/{init-B-4t1NzC.js → init-BjuFDYT1.js} +10 -10
  179. package/dist/{init-5TXNji88.js → init-txYTuW9u.js} +5 -5
  180. package/dist/{instance-options-CU0YQCLH.d.ts → instance-options-CoHn-0e8.d.ts} +4 -4
  181. package/dist/{instance-snapshot-CjcwnEiV.js → instance-snapshot-DuWf1cT3.js} +86 -61
  182. package/dist/{instant-BluqDvyS.js → instant-DK3Iz83e.js} +2 -2
  183. package/dist/{internals-Dk8A8fX3.js → internals-B3IgHrvo.js} +6 -3
  184. package/dist/{json-schema-B-vAwlde.js → json-schema-BPGa-RjQ.js} +9 -3
  185. package/dist/{json-schema-CN_iLFH2.d.ts → json-schema-BfXgnRNT.d.ts} +4 -4
  186. package/dist/jwt/index.d.ts +57 -27
  187. package/dist/jwt/index.js +24 -21
  188. package/dist/{kernel-DVExUwkp.js → kernel-qv4cr9w8.js} +32 -23
  189. package/dist/kysely/index.d.ts +49 -33
  190. package/dist/kysely/index.js +9 -7
  191. package/dist/{live-options-BaAFCIiu.js → live-options-BBIT68le.js} +2 -2
  192. package/dist/{load-DxroEzH1.js → load-DjSU5KXO.js} +6 -6
  193. package/dist/load-Dm0pSYH3.js +1 -0
  194. package/dist/{login-ClSJh5t5.js → login-CfImTJGb.js} +4 -4
  195. package/dist/{login-WC9HPJpU.js → login-CgfCTO3F.js} +16 -9
  196. package/dist/{manifest-Dv6q4i5s.js → manifest-B2QPh19C.js} +49 -38
  197. package/dist/{manifest-BVhExYhw.d.ts → manifest-CzzWtnAb.d.ts} +126 -31
  198. package/dist/{manifest-schema-Cv492Qev.js → manifest-schema-2r37XRhD.js} +44 -3
  199. package/dist/{manifest-B79YuF2T.js → manifest-wg8WkkpD.js} +6 -6
  200. package/dist/{map-claims-etGIS_Dv.js → map-claims-C-nv08_n.js} +16 -9
  201. package/dist/{map-error-BQGyDm_M.js → map-error-pasIGqMT.js} +7 -7
  202. package/dist/{markers-C6joDI3o.js → markers-BeHZ4x9Q.js} +20 -5
  203. package/dist/mcp/index.d.ts +114 -61
  204. package/dist/mcp/index.js +70 -40
  205. package/dist/{migrate-Dodel0IJ.js → migrate-B7oP_sQU.js} +35 -17
  206. package/dist/module-values-BJTBdo6y.js +107 -0
  207. package/dist/nest/index.d.ts +23 -13
  208. package/dist/nest/index.js +18 -11
  209. package/dist/next/client.d.ts +5 -2
  210. package/dist/next/client.js +1 -1
  211. package/dist/next/index.d.ts +79 -26
  212. package/dist/next/index.js +121 -10
  213. package/dist/next/plugin.d.ts +1 -1
  214. package/dist/next/plugin.js +4 -3
  215. package/dist/node/index.d.ts +5 -5
  216. package/dist/node/index.js +3 -3
  217. package/dist/{ocsf-BFp-PZZA.js → ocsf-TcjRBgIs.js} +15 -5
  218. package/dist/openai/index.d.ts +13 -7
  219. package/dist/openai/index.js +3 -3
  220. package/dist/openapi/index.d.ts +51 -30
  221. package/dist/openapi/index.js +2 -2
  222. package/dist/{openapi-ztVaux6j.js → openapi-BGeuunWC.js} +23 -14
  223. package/dist/{openapi-DMocl1bh.js → openapi-BIpw3Mb7.js} +4 -5
  224. package/dist/{openapi-Ddb4628T.js → openapi-BOsx0xn9.js} +33 -18
  225. package/dist/{operation-findings-kRcEp8lE.js → operation-findings-CXtFzlKJ.js} +3 -3
  226. package/dist/{operations-BNLes61x.d.ts → operations-Ci_rT6Uo.d.ts} +10 -7
  227. package/dist/orpc/index.d.ts +68 -14
  228. package/dist/orpc/index.js +62 -13
  229. package/dist/otel/index.d.ts +7 -4
  230. package/dist/otel/index.js +8 -5
  231. package/dist/{output-DgSDLrta.js → output-DV5dwOTs.js} +9 -5
  232. package/dist/output-files-BHOIlrfD.js +1 -0
  233. package/dist/{output-files-CCMdcFWb.js → output-files-BIQ_9pIs.js} +29 -17
  234. package/dist/ownership-DA5YdYTm.js +1059 -0
  235. package/dist/{parse-Ddhz2xf4.js → parse-1_ZheTW5.js} +16 -13
  236. package/dist/parse-local-manifest-CCmbhnxP.d.ts +10 -0
  237. package/dist/{parse-local-manifest-T1Q8X3A2.js → parse-local-manifest-DEiCF4ah.js} +19 -7
  238. package/dist/{parse-request-D_tUXG6M.js → parse-request-CwCZpyjV.js} +7 -8
  239. package/dist/{paths-DXSHAMIa.js → paths-CUvURzHp.js} +4 -1
  240. package/dist/pdp/index.d.ts +9 -6
  241. package/dist/pdp/index.js +20 -13
  242. package/dist/{peer-DOzzMfZL.js → peer-C9LvBCcb.js} +1 -1
  243. package/dist/{peer-12Q5I_RH.js → peer-Q0fuZ6hx.js} +9 -3
  244. package/dist/{permdock-BfWEeMqk.js → permdock-BvjivVb9.js} +200 -140
  245. package/dist/{permdock-Dco6dyCK.d.ts → permdock-CprAPN3w.d.ts} +260 -129
  246. package/dist/{permission-registry-DpPtSKNZ.js → permission-registry-B8tYxPIt.js} +23 -10
  247. package/dist/{permission-types-DhNEmoRG.d.ts → permission-types-CAY-GU7e.d.ts} +127 -41
  248. package/dist/{permissions-CoqCOfJ3.d.ts → permissions-Bx6UI8n1.d.ts} +6 -3
  249. package/dist/{permissions-CyH2MV_B.js → permissions-CVXmRILq.js} +3 -3
  250. package/dist/{permissions-DArULThq.js → permissions-CYcHj_w7.js} +8 -5
  251. package/dist/pg-DQTqRrou.js +60 -0
  252. package/dist/{pins-8ILTftC9.js → pins-nqarl3oE.js} +4 -1
  253. package/dist/{pkce-5h8NgMQJ.js → pkce-CnmmYqUZ.js} +1 -1
  254. package/dist/{policy-B7dg_yzu.d.ts → policy-BycVKnXv.d.ts} +5 -5
  255. package/dist/{policy-DaJy4nK4.js → policy-CLQ8__GF.js} +43 -23
  256. package/dist/{policy-from-catalog-DFWYkNdu.js → policy-from-catalog-CU3An8uP.js} +28 -25
  257. package/dist/{policy-module-CTlwMvLI.js → policy-module-xym9fnSq.js} +12 -6
  258. package/dist/{policy-types-B-F-qAZk.d.ts → policy-types-DGIO_gxq.d.ts} +782 -357
  259. package/dist/{postgres-store-BL9M_CA1.js → postgres-store-DcyrPS-r.js} +43 -16
  260. package/dist/{postgrest-r5faDIzD.js → postgrest-5Dr3W64L.js} +84 -86
  261. package/dist/{postgrest-CYacM_u7.d.ts → postgrest-D5nUGm-c.d.ts} +55 -35
  262. package/dist/powersync-B701tvhE.js +1 -0
  263. package/dist/{powersync-13odBwiM.js → powersync-Bg8u-JcR.js} +3 -3
  264. package/dist/{powersync-53ryOZip.js → powersync-CJrT1DSc.js} +127 -69
  265. package/dist/preset/index.d.ts +38 -28
  266. package/dist/preset/index.js +1 -1
  267. package/dist/{preset-CHTbd-DQ.js → preset-BjLzeFpp.js} +56 -32
  268. package/dist/{principal-source-pHneukrx.js → principal-source-C6N60GtM.js} +10 -10
  269. package/dist/prisma/index.d.ts +69 -41
  270. package/dist/prisma/index.js +21 -17
  271. package/dist/{problem-CTviyH5L.js → problem-BVLHFK33.js} +41 -21
  272. package/dist/{problem-details-cn5X30gZ.js → problem-details-CLDgX1KV.js} +13 -4
  273. package/dist/{problem-types-CJ2325SZ.js → problem-types-DSsRfONQ.js} +4 -1
  274. package/dist/{prompt-DwtVemER.js → prompt-BYc6drYW.js} +4 -1
  275. package/dist/protected-action-D8x73IGm.d.ts +58 -0
  276. package/dist/protected-action-DUYqb-Ma.js +80 -0
  277. package/dist/{protected-DXE3cQYg.js → protected-action-QEA8arRB.js} +48 -14
  278. package/dist/{provider-BQsTYYy0.js → provider-C55OGXJ7.js} +5 -4
  279. package/dist/{provider-Csk-THAn.d.ts → provider-DfLeek9O.d.ts} +1 -1
  280. package/dist/{provider-store-IgqQipCO.js → provider-store-CaTv00tr.js} +13 -9
  281. package/dist/{pull-CN5OLxrF.js → pull-2nJr0qg_.js} +12 -11
  282. package/dist/pull-C3EEGzSw.js +1 -0
  283. package/dist/{push-tVdG8dUL.js → push-Bn-lMEmI.js} +19 -13
  284. package/dist/{pushed-policy-CmYeSQqq.js → pushed-policy-CDuOL2de.js} +10 -7
  285. package/dist/{pushed-policy-BbcY9r_4.d.ts → pushed-policy-CryQheKq.d.ts} +12 -6
  286. package/dist/react/index.d.ts +9 -8
  287. package/dist/react/index.js +7 -6
  288. package/dist/react/provider-client.d.ts +1 -1
  289. package/dist/react/provider-client.js +1 -1
  290. package/dist/react-native/index.d.ts +94 -55
  291. package/dist/react-native/index.js +200 -61
  292. package/dist/{refs-CNJBiTFo.js → refs-C8BKxc_e.js} +2 -2
  293. package/dist/{relation-walk-3OyDBF0S.js → relation-walk-DK_gkgL7.js} +12 -9
  294. package/dist/{relations-BnCWnJGI.js → relations-BxvRvDHK.js} +3 -3
  295. package/dist/{replay-Du1tJjG7.js → replay-BU09ad4L.js} +1 -1
  296. package/dist/{replay-DCDD_ZfL.d.ts → replay-Bs9Df2fQ.d.ts} +1 -1
  297. package/dist/{request-context-BykKLmyE.js → request-context-Duzdf0cd.js} +8 -8
  298. package/dist/{request-schema-CMreVuFM.js → request-schema-DhX7UbfQ.js} +4 -1
  299. package/dist/resend/index.d.ts +34 -28
  300. package/dist/resend/index.js +29 -29
  301. package/dist/resolve-names-ConCSj1y.js +201 -0
  302. package/dist/{resource-relations-D_jw0BFx.js → resource-relations-8-pCScBO.js} +18 -9
  303. package/dist/{retire-Wj6dkyDE.js → retire-B2xffQgY.js} +15 -6
  304. package/dist/{revocations-R07lFBnX.d.ts → revocations-BaUXHM1N.d.ts} +6 -3
  305. package/dist/{rls-Ck_PocSp.js → rls-Ba9wN0SP.js} +13 -6
  306. package/dist/{rls-CxBZb4rZ.js → rls-Cx0dtsB7.js} +310 -128
  307. package/dist/{role-builder-C1VJzvcr.js → role-builder-BK2-T6oD.js} +41 -20
  308. package/dist/{row-conditions-h2HythXQ.js → row-conditions-BAGHOmVq.js} +4 -3
  309. package/dist/{rpc-Bk1bE-ch.js → rpc-vHIwyXCp.js} +8 -5
  310. package/dist/run-Ck22anC2.js +1 -0
  311. package/dist/{run-uLD2aWuO.js → run-PbRlXTfh.js} +26 -23
  312. package/dist/{run-ticket-BpNi7BCi.d.ts → run-ticket-B2o2Kxz8.d.ts} +29 -14
  313. package/dist/{run-ticket-B5d_63Ma.js → run-ticket-Dv7aF7Dk.js} +9 -9
  314. package/dist/{runtime-Vif3_-zf.js → runtime-BGnrOkVH.js} +5 -2
  315. package/dist/{saas-Az_Kz-4D.js → saas-DK4V-3Is.js} +42 -29
  316. package/dist/{scan-DSljDE1Y.js → scan-CRTj6fke.js} +1 -1
  317. package/dist/{schema-B4v0Qrac.js → schema-BOJjqlWL.js} +3 -2
  318. package/dist/{schema-gIcCx7zM.js → schema-BTsE1WRT.js} +8 -4
  319. package/dist/scim/index.d.ts +2 -2
  320. package/dist/scim/index.js +2 -2
  321. package/dist/{scim-C7JYhySg.js → scim-D8YupzX1.js} +2 -2
  322. package/dist/{scim-YNieBO1U.js → scim-jJBJ7g1Z.js} +33 -15
  323. package/dist/{scopes-BHsc-wp-.js → scopes-0Up_UA2t.js} +41 -23
  324. package/dist/server/index.d.ts +11 -11
  325. package/dist/server/index.js +12 -12
  326. package/dist/{server-Bnga6I50.js → server-3cVlTLde.js} +31 -31
  327. package/dist/{server-types-C4gZUEZy.d.ts → server-types-CyRN0-Cd.d.ts} +88 -46
  328. package/dist/{sha256-D9ihqmvd.js → sha256-C-4WXKIu.js} +4 -3
  329. package/dist/{shared-fMKOv8hP.js → shared-Afctg7B0.js} +65 -32
  330. package/dist/{shared-C8LjUdVU.js → shared-l0oGGetg.js} +9 -6
  331. package/dist/{signals-D3NcTKUS.js → signals-B1vHR3fN.js} +2 -2
  332. package/dist/{sink-Cp_Eot9W.d.ts → sink-B5zoUW_O.d.ts} +44 -20
  333. package/dist/{sink-BEZSlMS_.js → sink-D9_vh372.js} +32 -21
  334. package/dist/{skills-g_3BS9NC.js → skills-C9uKfSF5.js} +3 -3
  335. package/dist/{skills-Dcjw9_1C.js → skills-CQQcuGBi.js} +12 -8
  336. package/dist/{snapshot-CbGmYiJx.js → snapshot-CXlzi69u.js} +21 -18
  337. package/dist/{snapshot-cache-Pahd3IYJ.d.ts → snapshot-cache-BjAWkchD.d.ts} +21 -12
  338. package/dist/{snapshot-cache-DT2Kx1F8.js → snapshot-cache-Bx_4xC_6.js} +14 -11
  339. package/dist/solid/index.d.ts +55 -16
  340. package/dist/solid/index.js +46 -12
  341. package/dist/solid-start/index.d.ts +30 -12
  342. package/dist/solid-start/index.js +3 -3
  343. package/dist/{sources-B-zYB4GS.js → sources-CMAM-2A3.js} +46 -27
  344. package/dist/{sources-DEEuGb8S.d.ts → sources-CWG32C0G.d.ts} +126 -53
  345. package/dist/{sql-B96movIM.js → sql-0WjxIp9g.js} +28 -7
  346. package/dist/{sql-CDEPCA0g.d.ts → sql-B80DFdpG.d.ts} +2 -2
  347. package/dist/{src-DLFrtrrC.js → src-C_pi2Rnh.js} +292 -101
  348. package/dist/ssf/index.d.ts +3 -3
  349. package/dist/ssf/index.js +47 -35
  350. package/dist/{standard-webhooks-DgFFD-Ga.js → standard-webhooks-D67a3nzk.js} +5 -5
  351. package/dist/{standard-webhooks-B_qRg0ws.d.ts → standard-webhooks-DOYEuOLx.d.ts} +7 -7
  352. package/dist/{store-DSP9oGvh.js → store-RNFvaJJv.js} +32 -26
  353. package/dist/{store-options-B_poyYvg.js → store-options-Dil3lraY.js} +105 -15
  354. package/dist/stores-DZJvxFIZ.d.ts +59 -0
  355. package/dist/{stores-BqEuHC05.js → stores-DxZWDXCs.js} +42 -5
  356. package/dist/{stream-2Vwhl7Er.d.ts → stream-9y9qw51m.d.ts} +4 -3
  357. package/dist/{stream-CvdUS9V1.js → stream-CDvF0sJm.js} +5 -5
  358. package/dist/{style-Ds1gNm77.js → style-DblOtSga.js} +1 -1
  359. package/dist/{style-Cqo7-73x.js → style-Ds11Hmk4.js} +2 -1
  360. package/dist/{subject-settings-CkEwrw3W.js → subject-settings-8sH5HlII.js} +8 -4
  361. package/dist/{row-check-Dt35czLy.d.ts → subject-settings-vNW8qmUH.d.ts} +30 -18
  362. package/dist/supabase/index.d.ts +48 -38
  363. package/dist/supabase/index.js +5 -5
  364. package/dist/supabase/middleware.d.ts +19 -13
  365. package/dist/supabase/middleware.js +7 -7
  366. package/dist/{supabase--0aJdLEd.js → supabase-DnMMg5Fn.js} +79 -35
  367. package/dist/{supabase-Bqp7iIY2.js → supabase-SBs3MYUE.js} +3 -3
  368. package/dist/supabase-hook-C0FyEACZ.js +1 -0
  369. package/dist/{supabase-hook-Dg0SrQWR.js → supabase-hook-CrgU06WH.js} +175 -196
  370. package/dist/{supautils-MESd81bF.js → supautils-ByezN3b8.js} +385 -219
  371. package/dist/{support-session-Cna49-3f.js → support-session-BsmPCbz8.js} +21 -21
  372. package/dist/svelte/PermissionBoundary.svelte +2 -6
  373. package/dist/svelte/Protected.svelte +2 -8
  374. package/dist/svelte/index.d.ts +9 -8
  375. package/dist/svelte/index.js +10 -9
  376. package/dist/svelte/runtime.d.ts +4 -4
  377. package/dist/svelte/runtime.js +4 -4
  378. package/dist/svelte/source.d.ts +9 -8
  379. package/dist/svelte/source.js +6 -5
  380. package/dist/sveltekit/index.d.ts +30 -12
  381. package/dist/sveltekit/index.js +2 -2
  382. package/dist/{ownership-Z2LpxsGa.js → tables-BqrxBCir.js} +641 -1104
  383. package/dist/tanstack-start/index.d.ts +22 -10
  384. package/dist/tanstack-start/index.js +2 -2
  385. package/dist/{target-Bw37TFNA.js → target-qdEAnnhU.js} +6 -6
  386. package/dist/{tenancy-CmeBQ6Nv.js → tenancy-5d1zVBvK.js} +25 -19
  387. package/dist/terminal/index.d.ts +23 -14
  388. package/dist/terminal/index.js +17 -20
  389. package/dist/testing/core.d.ts +1 -1
  390. package/dist/testing/core.js +1 -1
  391. package/dist/testing/fixtures/index.d.ts +8 -5
  392. package/dist/testing/fixtures/index.js +78 -17
  393. package/dist/testing/index.d.ts +225 -141
  394. package/dist/testing/index.js +352 -234
  395. package/dist/testing/saas/index.d.ts +43 -27
  396. package/dist/testing/saas/index.js +2 -2
  397. package/dist/testing/saas/permissions.d.ts +1 -1
  398. package/dist/testing/saas/permissions.js +1 -1
  399. package/dist/{text-diff-DhITNCnD.js → text-diff-BtfSmdUo.js} +2 -2
  400. package/dist/{thenable-yD7SabqG.js → thenable-BNSM1U2R.js} +12 -3
  401. package/dist/{time-DkWjdL98.js → time-nR1JesoH.js} +32 -8
  402. package/dist/{token-2qYDvXz2.js → token-DC9EQiet.js} +14 -12
  403. package/dist/{tool-refusal-reAhIzdl.js → tool-refusal-Qpjs_W6M.js} +5 -2
  404. package/dist/trpc/index.d.ts +11 -8
  405. package/dist/trpc/index.js +15 -9
  406. package/dist/type-helpers-c7Xo_2Cu.d.ts +50 -0
  407. package/dist/{types-CfiKC5aN.d.ts → types-B2efzoSX.d.ts} +14 -11
  408. package/dist/{types-CIeZcG8v.d.ts → types-B6ExllNo.d.ts} +2 -2
  409. package/dist/{types-DBHftjgS.d.ts → types-BB-zWDcR.d.ts} +45 -33
  410. package/dist/{types-BfVmNJO5.d.ts → types-BMVDHvI0.d.ts} +128 -50
  411. package/dist/{types-DXmwu78Z.d.ts → types-CEinc15V.d.ts} +31 -14
  412. package/dist/{types-g7Oy6Zg4.d.ts → types-CN0LsqbK.d.ts} +47 -24
  413. package/dist/{types-CeIscIKp.d.ts → types-CWBsAwqn.d.ts} +23 -12
  414. package/dist/{types-DqzsnlSA.js → types-CcUXciSj.js} +17 -5
  415. package/dist/{types-BWZybqs9.d.ts → types-CzOeVvcC.d.ts} +384 -203
  416. package/dist/{types-DC44-hqb.d.ts → types-DLvhVm1r.d.ts} +59 -32
  417. package/dist/{types-D3A19w4A.d.ts → types-DlelvQk4.d.ts} +22 -13
  418. package/dist/{types-cTos-H7p.d.ts → types-DsHGPtkR.d.ts} +68 -32
  419. package/dist/{types-BXMYB7BY.d.ts → types-ZzRGoViD.d.ts} +77 -24
  420. package/dist/{types-CQVEQawv.d.ts → types-rCRV4Ge-.d.ts} +24 -14
  421. package/dist/types-tQB2CEnY.d.ts +262 -0
  422. package/dist/unplugin/index.d.ts +1 -1
  423. package/dist/unplugin/index.js +2 -2
  424. package/dist/usage-0hjZPIRX.js +1 -0
  425. package/dist/{usage-Bybmck7f.js → usage-B9EtHWLa.js} +50 -26
  426. package/dist/{usage-CDaLXCfL.js → usage-CBzgwfIs.js} +2 -2
  427. package/dist/{validation-error-ZfUHbKvf.js → validation-error-CYg2kJEw.js} +4 -1
  428. package/dist/{validation-error-CQpoquwj.d.ts → validation-error-uvp-kyfO.d.ts} +5 -2
  429. package/dist/{validity-CZ7-y0Cj.js → validity-Buc7w8E9.js} +13 -10
  430. package/dist/{verifier-DHuh-okk.js → verifier-DUV6pLqZ.js} +10 -4
  431. package/dist/{verify-pe8rL_Qw.js → verify-DlUcTDBz.js} +148 -487
  432. package/dist/version-DMQ0dnN5.js +48 -0
  433. package/dist/version-DizhmD72.js +1 -0
  434. package/dist/{views-BB8E9dTP.js → views-CD8wuL4Z.js} +19 -6
  435. package/dist/{vocabulary-Bg3eeT2H.d.ts → vocabulary-DEJ5j4mR.d.ts} +7 -4
  436. package/dist/vue/index.d.ts +71 -22
  437. package/dist/vue/index.js +50 -13
  438. package/dist/{waiter-DwEyouan.d.ts → waiter-CqUKX6CY.d.ts} +13 -10
  439. package/dist/{waiter-BGUtGYoU.js → waiter-aBLM63_f.js} +1 -1
  440. package/dist/{watch-C-4VmFlL.js → watch-BFDKqmUa.js} +8 -8
  441. package/dist/watch-ClLuO2TL.js +1 -0
  442. package/dist/webmcp/index.d.ts +11 -11
  443. package/dist/webmcp/index.js +8 -5
  444. package/dist/{where-scope-wq2coopv.js → where-scope-DlCdCM_8.js} +24 -18
  445. package/dist/{who-can-BwNsI_Js.js → who-can-BoDJm0Nc.js} +23 -20
  446. package/dist/workflow/index.d.ts +3 -3
  447. package/dist/workflow/index.js +13 -13
  448. package/dist/workflow-sdk/index.d.ts +19 -13
  449. package/dist/workflow-sdk/index.js +6 -6
  450. package/dist/{wrap-CiSc_KCq.js → wrap-B2wziJI_.js} +4 -4
  451. package/dist/{wrap-B6R0cMRL.d.ts → wrap-DxXB54Wu.d.ts} +8 -5
  452. package/package.json +8 -8
  453. package/schemas/catalog-v1.json +3 -0
  454. package/schemas/supabase-manifest-v1.json +33 -1
  455. package/skills/permdock-credentials/references/tokens-keys-links.md +8 -6
  456. package/skills/permdock-data/references/queries-and-rls.md +2 -1
  457. package/skills/permdock-tenancy/references/ownership-and-custom-roles.md +2 -2
  458. package/skills/permdock-wire/references/adapters.md +16 -23
  459. package/dist/catalog-BCCjSAdH.js +0 -1
  460. package/dist/collect-k_Dulxr5.js +0 -1
  461. package/dist/config-CoQHDrDi.js +0 -166
  462. package/dist/denied-text-D4qkEtFz.d.ts +0 -19
  463. package/dist/fields-ClcQLrVc.js +0 -238
  464. package/dist/generate-CNU1pIOo.js +0 -171
  465. package/dist/headers-BIjfMaoC.js +0 -8
  466. package/dist/headers-CIbDTUTK.d.ts +0 -7
  467. package/dist/load-DrMHXzgN.js +0 -1
  468. package/dist/output-files-DPAY7-GX.js +0 -1
  469. package/dist/package-root-Dk_ETdkp.js +0 -31
  470. package/dist/parse-local-manifest-e4mdwAKd.d.ts +0 -10
  471. package/dist/policies-B2lZIurj.js +0 -295
  472. package/dist/powersync-CExtTLyA.js +0 -1
  473. package/dist/problem-details-Tcfmj3bV.d.ts +0 -7
  474. package/dist/protected-BwZYL1X_.d.ts +0 -39
  475. package/dist/pull-Cty6Ovyu.js +0 -1
  476. package/dist/run-Bz7DXGEv.js +0 -1
  477. package/dist/stores-BAZwSYZA.d.ts +0 -31
  478. package/dist/supabase-hook-DJxC4PoP.js +0 -1
  479. package/dist/types-CKV71kKh.d.ts +0 -172
  480. package/dist/usage-y-kBNdqs.js +0 -1
  481. package/dist/version-CEbQ5UeM.js +0 -18
  482. package/dist/version-DXkYUISx.js +0 -1
  483. package/dist/watch-Bd9mx3rd.js +0 -1
@@ -1,20 +1,22 @@
1
- import { c as listPermissions, u as renamedKeys } from "./permission-registry-DpPtSKNZ.js";
2
- import { f as scopeList, s as resolveScope } from "./scopes-BHsc-wp-.js";
3
- import { o as flattenGrantee } from "./grantee-BrRANrpT.js";
4
- import { c as policyLevels } from "./policy-DaJy4nK4.js";
5
- import { a as describeError, i as configError } from "./errors-DpP_U6Bf.js";
6
- import { d as sqlTextArray, i as qualifySqlTable } from "./sql-B96movIM.js";
7
- import "./budget-NbEtbJC_.js";
8
- import { l as roleColumn } from "./sources-B-zYB4GS.js";
1
+ import { c as listPermissions, u as renamedKeys } from "./permission-registry-B8tYxPIt.js";
2
+ import { f as scopeList, s as resolveScope } from "./scopes-0Up_UA2t.js";
3
+ import { o as flattenGrantee } from "./grantee-Dke-9rd1.js";
4
+ import { l as policyLevels } from "./policy-CLQ8__GF.js";
5
+ import { a as describeError, i as configError } from "./errors-Vpu6rKHl.js";
6
+ import { d as sqlTextArray, i as qualifySqlTable } from "./sql-0WjxIp9g.js";
7
+ import "./budget-BELja5A9.js";
8
+ import { l as roleColumn } from "./sources-CMAM-2A3.js";
9
9
  import { t as beforeFirst } from "./text-BMFRfBqc.js";
10
- import { c as parseSplit } from "./output-files-CCMdcFWb.js";
11
- import { x as resolveAuthorize } from "./supabase-hook-Dg0SrQWR.js";
12
- import { A as quoteQualified, C as parseMembershipsFlag, D as qualified, L as tenantTypeOf, O as quoteIdent, a as customRolesOn, j as quoteTable, k as quoteLiteral, t as CUSTOM_ROLES } from "./shared-fMKOv8hP.js";
13
- import { D as byKey, E as byCodeUnit, I as roleNames, M as assignableRoles, T as rolesTableScope, U as graphSqlName, b as tokenScopesPlan, j as apiKeysPlan, ot as checkSuspension, r as unsatisfiedKinds, t as ownershipRules, w as currentKeyExpr } from "./ownership-Z2LpxsGa.js";
10
+ import { c as parseSplit } from "./output-files-BIQ_9pIs.js";
11
+ import { b as resolveAuthorize } from "./supabase-hook-CrgU06WH.js";
12
+ import { A as quoteQualified, C as parseMembershipsFlag, D as qualified, F as firstScopeType, O as quoteIdent, R as tenantTypeOf, a as customRolesOn, j as quoteTable, k as quoteLiteral, s as signedIn, t as CUSTOM_ROLES } from "./shared-Afctg7B0.js";
13
+ import { G as byKey, H as rolesTableScope, O as tokenScopesPlan, Q as graphSqlName, V as raiseSql, W as byCodeUnit, Y as apiKeysPlan, a as closureDepths, bt as checkSuspension, i as tablelessResources, o as graphPlan, r as tableNames, t as resolveVias, z as currentKeyExpr } from "./tables-BqrxBCir.js";
14
+ import { o as assignableRoles, r as unsatisfiedKinds, t as ownershipRules, u as roleNames } from "./ownership-DA5YdYTm.js";
14
15
  import { t as membershipSourcesOf } from "./sources-qoIJQrJv.js";
15
- import { i as group, o as sqlStatements } from "./deciding-columns-DRo2QM6E.js";
16
- import { c as branchClauses, i as orSql } from "./policies-B2lZIurj.js";
17
- import { d as tableNames, f as tablelessResources, i as graphPlan, l as resolveVias, r as closureDepths, x as tableFor } from "./verify-pe8rL_Qw.js";
16
+ import { i as group, o as sqlStatements } from "./deciding-columns-NB4wcyBf.js";
17
+ import { t as resolveNames } from "./resolve-names-ConCSj1y.js";
18
+ import { d as orSql, h as branchClauses } from "./fields-D0vUI6dq.js";
19
+ import { m as tableFor } from "./verify-DlUcTDBz.js";
18
20
  //#region src/cli/rls/custom-role-rebuild.ts
19
21
  const PREFIX = "PermDock CLI";
20
22
  /** A column of the roles-table row `r`. */
@@ -24,7 +26,10 @@ function col(name) {
24
26
  function schemaOf(table) {
25
27
  return table.includes(".") ? beforeFirst(table, ".") : "public";
26
28
  }
27
- /** The roles-table column a reference joins on, after checking it points at `roles`. */
29
+ /**
30
+ * The roles-table column a reference joins on, after checking it points at
31
+ * `roles`.
32
+ */
28
33
  function roleRef(role, table, roles, label) {
29
34
  const pairs = Object.entries(role.on);
30
35
  const [pair] = pairs;
@@ -104,9 +109,9 @@ function rebuildPlan(ctx, from, migrate) {
104
109
  const iRef = i === void 0 || iTable === void 0 ? void 0 : roleRef(i.role, i.table, roles, "rls.customRoles.from.includes.role");
105
110
  const included = i === void 0 || iTable === void 0 ? void 0 : sourceSql(i.include, iTable, "rls.customRoles.from.includes.include");
106
111
  const refs = [`${col(pRef.id)} as permissions_ref`, ...iRef === void 0 ? [] : [`${col(iRef.id)} as includes_ref`]].join(", ");
107
- const includeBlock = i === void 0 || iTable === void 0 || iRef === void 0 || included === void 0 ? " v_include := null;" : ` with raw as (
112
+ const includeBlock = (rows) => i === void 0 || iTable === void 0 || iRef === void 0 || included === void 0 || rows === void 0 ? " v_include := null;" : ` with raw as (
108
113
  select ${included} as role
109
- from ${quoteTable(iTable)} x
114
+ from ${rows}
110
115
  where x.${quoteIdent(iRef.ref)} = v.includes_ref
111
116
  ),
112
117
  judged as (
@@ -125,9 +130,9 @@ function rebuildPlan(ctx, from, migrate) {
125
130
  into v_include, v_lost
126
131
  from judged j;
127
132
  v_dropped := v_dropped || coalesce(v_lost, '{}'::text[]);`;
128
- const collect = ` with raw as (
133
+ const permissionsBlock = (rows) => ` with raw as (
129
134
  select ${legacy} as legacy, ${effect} as effect, ${level} as level
130
- from ${quoteTable(pTable)} x
135
+ from ${rows}
131
136
  where x.${quoteIdent(pRef.ref)} = v.permissions_ref
132
137
  ),
133
138
  mapped as (
@@ -147,8 +152,9 @@ function rebuildPlan(ctx, from, migrate) {
147
152
  array_agg(v.role || ': ' || coalesce(j.legacy, 'null') || ', ' || j.dropped) filter (where j.dropped is not null)
148
153
  into v_allow, v_deny, v_lost
149
154
  from judged j;
150
- v_dropped := v_dropped || coalesce(v_lost, '{}'::text[]);
151
- ${includeBlock}`;
155
+ v_dropped := v_dropped || coalesce(v_lost, '{}'::text[]);`;
156
+ const legacyRows = iTable === void 0 ? void 0 : `${quoteTable(iTable)} x`;
157
+ const newRow = "(select new.*) x";
152
158
  return {
153
159
  rolesTable,
154
160
  identity: `select ${tenant} as tenant_id, ${scope} as scope, ${scopeId} as scope_id, ${col(roles.key)}::text as role, ${refs}`,
@@ -156,7 +162,15 @@ ${includeBlock}`;
156
162
  permsRef: pRef,
157
163
  includesRef: iRef,
158
164
  scopes,
159
- collect,
165
+ collect: `${permissionsBlock(`${quoteTable(pTable)} x`)}
166
+ ${includeBlock(legacyRows)}`,
167
+ collectNew: {
168
+ permissions: `${permissionsBlock(newRow)}
169
+ v_include := null;`,
170
+ includes: ` v_allow := null;
171
+ v_deny := null;
172
+ ${includeBlock(newRow)}`
173
+ },
160
174
  replace,
161
175
  perms,
162
176
  includes,
@@ -164,7 +178,10 @@ ${includeBlock}`;
164
178
  roles
165
179
  };
166
180
  }
167
- /** `v_dropped` grouped per legacy role (`role: a, b; other: c`), capped at 50 entries. */
181
+ /**
182
+ * `v_dropped` grouped per legacy role (`role: a, b; other: c`), capped at 50
183
+ * entries.
184
+ */
168
185
  const DROPPED_LIST = `(select string_agg(g.role || ': ' || g.items, '; ' order by g.role)
169
186
  from (
170
187
  select split_part(l.d, ': ', 1) as role, string_agg(substr(l.d, strpos(l.d, ': ') + 2), ', ' order by l.d) as items
@@ -176,14 +193,20 @@ const DROPPED_LIST = `(select string_agg(g.role || ': ' || g.items, '; ' order b
176
193
  /**
177
194
  * `rls.customRoles.from.sync: 'trigger'`: after-row triggers on the legacy
178
195
  * permissions table, and on the includes table when mapped, rebuild each
179
- * affected role through `permdock_trusted_replace_custom_role_grants`, with
180
- * the same reads the backfill uses. An entry outside the ceiling is dropped
181
- * with a warning rather than aborting the legacy write, and a tenant role
182
- * whose name a shared role holds is skipped with a warning (`name-taken`).
196
+ * affected role through `permdock_trusted_replace_custom_role_grants`, with the
197
+ * same reads the backfill uses. An entry outside the ceiling is dropped with a
198
+ * warning rather than aborting the legacy write, and a tenant role whose name a
199
+ * shared role holds is skipped with a warning (`name-taken`). Before-row
200
+ * triggers hold a signed-in caller at trigger depth 1 to the checks of
201
+ * `permdock_replace_custom_role_grants`: `permdock_custom_role_guard` on each
202
+ * role the row names, then `permdock_custom_role_beyond` on the entry it adds;
203
+ * a refusal aborts the write.
183
204
  */
184
205
  function customRoleSyncSql(ctx, from, migrate) {
185
206
  const plan = rebuildPlan(ctx, from, migrate);
186
207
  const shared = qualified(ctx, CUSTOM_ROLES.shared);
208
+ const guard = qualified(ctx, CUSTOM_ROLES.guard);
209
+ const beyond = qualified(ctx, CUSTOM_ROLES.beyond);
187
210
  const keepIncludes = plan.includesRef === void 0 ? `
188
211
  v_include := array(select c.include_role from ${plan.includes} c where c.tenant_id is not distinct from v.tenant_id and c.scope = v.scope and c.scope_id is not distinct from v.scope_id and c.role = v.role);` : "";
189
212
  const one = (name, table, ref) => {
@@ -238,13 +261,317 @@ create trigger ${quoteIdent(trigger)}
238
261
  after insert or update or delete on ${target}
239
262
  for each row execute function ${fn}();`;
240
263
  };
241
- const chunks = [`-- rls.customRoles.from.sync: a write to the application's role tables rebuilds the role's PermDock grants`, one("permissions", from.permissions.table, plan.permsRef)];
242
- if (from.includes !== void 0 && plan.includesRef !== void 0) chunks.push(one("includes", from.includes.table, plan.includesRef));
264
+ const guardOne = (name, table, ref) => {
265
+ const fn = qualified(ctx, `${CUSTOM_ROLES.syncGuard}_${name}`);
266
+ const target = quoteTable(qualifySqlTable(table));
267
+ const trigger = `${CUSTOM_ROLES.syncGuard}_${name}`;
268
+ return `create or replace function ${fn}()
269
+ returns trigger
270
+ language plpgsql
271
+ volatile
272
+ security definer
273
+ set search_path = ''
274
+ as $$
275
+ declare
276
+ v record;
277
+ v_allow text[];
278
+ v_deny text[];
279
+ v_include text[];
280
+ v_lost text[];
281
+ v_dropped text[];
282
+ v_beyond text;
283
+ v_refs text[] := array[
284
+ case when tg_op <> 'INSERT' then old.${quoteIdent(ref.ref)}::text end,
285
+ case when tg_op <> 'DELETE' then new.${quoteIdent(ref.ref)}::text end
286
+ ];
287
+ begin
288
+ if not (${signedIn(ctx)} and pg_trigger_depth() = 1) then
289
+ return coalesce(new, old);
290
+ end if;
291
+ for v in
292
+ ${plan.identity}
293
+ from ${plan.rolesTable} r
294
+ where ${plan.eligible} and r.${quoteIdent(ref.id)}::text = any(v_refs)
295
+ loop
296
+ if v.role is null or not (v.scope = 'global' or v.scope = any(${plan.scopes})) then
297
+ continue;
298
+ end if;
299
+ if v.tenant_id is not null and ${shared}(v.scope, v.role) then
300
+ continue;
301
+ end if;
302
+ perform ${guard}(v.tenant_id, v.scope, v.scope_id, v.role);
303
+ if tg_op = 'DELETE' then
304
+ continue;
305
+ end if;
306
+ v_dropped := '{}'::text[];
307
+ ${plan.collectNew[name]}
308
+ select string_agg(b, ', ' order by b) into v_beyond
309
+ from ${beyond}(v.tenant_id, v.scope, v.scope_id, v_allow, v_deny, v_include) b;
310
+ if v_beyond is not null then
311
+ ${raiseSql(" ", "42501", `'permdock: ' || v.role || ' would allow ' || v_beyond || ', which the caller may not hand out'`, "not-assignable-by")}
312
+ end if;
313
+ end loop;
314
+ return coalesce(new, old);
315
+ end;
316
+ $$;
317
+ revoke execute on function ${fn}() from public, anon, authenticated;
318
+ drop trigger if exists ${quoteIdent(trigger)} on ${target};
319
+ create trigger ${quoteIdent(trigger)}
320
+ before insert or update or delete on ${target}
321
+ for each row execute function ${fn}();`;
322
+ };
323
+ const chunks = [
324
+ `-- rls.customRoles.from.sync: a write to the application's role tables rebuilds the role's PermDock grants`,
325
+ one("permissions", from.permissions.table, plan.permsRef),
326
+ `-- a signed-in caller writes only what the guarded replace would accept`,
327
+ guardOne("permissions", from.permissions.table, plan.permsRef)
328
+ ];
329
+ if (from.includes !== void 0 && plan.includesRef !== void 0) chunks.push(one("includes", from.includes.table, plan.includesRef), guardOne("includes", from.includes.table, plan.includesRef));
243
330
  return `${chunks.join("\n\n")}\n`;
244
331
  }
245
332
  //#endregion
333
+ //#region src/cli/rls/rows.ts
334
+ /**
335
+ * `permitted_<resource>_rows(p_permission)`: the resource's row ids the subject
336
+ * may act on with one permission.
337
+ */
338
+ function rowsHelper(resource) {
339
+ const name = graphSqlName(resource);
340
+ const helper = `permitted_${name ?? resource}_rows`;
341
+ if (name === void 0 || new TextEncoder().encode(`${helper}_for`).length > 63) throw configError(`PermDock CLI: rls.rowHelpers cannot name a helper for resource '${resource}'; use a SQL name of at most 45 bytes`);
342
+ return helper;
343
+ }
344
+ /**
345
+ * Every declared `<permission>@<level>` of an instance permission on a resource
346
+ * with levels.
347
+ */
348
+ function levelKeys(policy) {
349
+ const out = [];
350
+ for (const leaf of listPermissions(policy.vocabulary.permissions)) {
351
+ if (leaf.kind !== "instance") continue;
352
+ for (const [level, condition] of policyLevels(policy, leaf.resource)) out.push({
353
+ key: `${leaf.key}@${level}`,
354
+ permission: leaf.key,
355
+ conditioned: !(condition.op === "and" && condition.conditions.length === 0),
356
+ rowHelper: `permitted_${graphSqlName(leaf.resource) ?? leaf.resource}_row`
357
+ });
358
+ }
359
+ return out;
360
+ }
361
+ /**
362
+ * The branches a row check of a permission reads: its allows and denies,
363
+ * inserts included, for signed-in callers.
364
+ */
365
+ function rowBranchesOf(branches, resource) {
366
+ const out = /* @__PURE__ */ new Map();
367
+ for (const branch of branches) {
368
+ if (branch.resource !== resource || branch.coverage === true || !branch.roles.includes("authenticated")) continue;
369
+ out.set(branch.permissionKey, [...out.get(branch.permissionKey) ?? [], branch]);
370
+ }
371
+ return out;
372
+ }
373
+ /**
374
+ * What a branch asks of a row: the `with check` of an insert, which sees the
375
+ * new row, the `using` of every other command.
376
+ */
377
+ function clauseOf(branch) {
378
+ const clauses = branchClauses(branch);
379
+ return (branch.command === "insert" ? clauses.check : clauses.using) ?? "true";
380
+ }
381
+ function usingOf(branches) {
382
+ const parts = branches.map(clauseOf);
383
+ return parts.length === 0 ? void 0 : orSql(parts);
384
+ }
385
+ function permissionCase(key, branches) {
386
+ const allow = usingOf(branches.filter((branch) => branch.effect === "allow"));
387
+ if (allow === void 0) return;
388
+ const deny = usingOf(branches.filter((branch) => branch.effect === "deny"));
389
+ const granted = `coalesce((${allow}), false)`;
390
+ return ` when ${quoteLiteral(key)} then ${deny === void 0 ? granted : `${granted} and (${deny}) is not true`}`;
391
+ }
392
+ function forUserSql(ctx, fn, helper) {
393
+ const user = ctx.dialect === "supabase" ? "uuid" : "text";
394
+ const signature = `${user}, text, jsonb`;
395
+ const head = `create or replace function ${fn}(p_user ${user}, p_permission text, p_claims jsonb default '{}')
396
+ returns setof text
397
+ language plpgsql
398
+ volatile
399
+ security definer
400
+ set search_path = ''
401
+ as $$`;
402
+ const tail = `revoke execute on function ${fn}(${signature}) from public, anon, authenticated;`;
403
+ if (ctx.dialect === "supabase") return `${head}
404
+ declare
405
+ v_claims text := pg_catalog.current_setting('request.jwt.claims', true);
406
+ begin
407
+ perform pg_catalog.set_config(
408
+ 'request.jwt.claims',
409
+ (coalesce(p_claims, '{}'::jsonb) || pg_catalog.jsonb_build_object('sub', p_user::text, 'role', 'authenticated'))::text,
410
+ true
411
+ );
412
+ return query select r.id from ${helper}(p_permission) r(id);
413
+ perform pg_catalog.set_config('request.jwt.claims', coalesce(v_claims, ''), true);
414
+ end
415
+ $$;
416
+ ${tail}`;
417
+ const prefix = ctx.gucPrefix;
418
+ return `${head}
419
+ declare
420
+ v_saved jsonb := '{}'::jsonb;
421
+ v_key text;
422
+ v_value text;
423
+ begin
424
+ for v_key, v_value in
425
+ select 'user_id', p_user
426
+ union all
427
+ select c.key, c.value from pg_catalog.jsonb_each_text(coalesce(p_claims, '{}'::jsonb)) c where c.key <> 'user_id'
428
+ loop
429
+ v_saved := v_saved || pg_catalog.jsonb_build_object(v_key, coalesce(pg_catalog.current_setting(${quoteLiteral(`${prefix}.`)} || v_key, true), ''));
430
+ perform pg_catalog.set_config(${quoteLiteral(`${prefix}.`)} || v_key, v_value, true);
431
+ end loop;
432
+ return query select r.id from ${helper}(p_permission) r(id);
433
+ for v_key, v_value in select s.key, s.value from pg_catalog.jsonb_each_text(v_saved) s loop
434
+ perform pg_catalog.set_config(${quoteLiteral(`${prefix}.`)} || v_key, v_value, true);
435
+ end loop;
436
+ end
437
+ $$;
438
+ ${tail}`;
439
+ }
440
+ function inheritTargets(policy) {
441
+ const out = /* @__PURE__ */ new Set();
442
+ for (const grant of policy.grants) for (const item of flattenGrantee(grant.to)) if (item.kind === "inherit") out.add(item.resource);
443
+ return [...out].toSorted();
444
+ }
445
+ const CANDIDATES = "permdock_candidates";
446
+ function stubSql(ctx, resource) {
447
+ const fn = qualified(ctx, rowsHelper(resource));
448
+ return ["p_permission text", "p_permission text, p_ids text[]"].map((parameters) => `create or replace function ${fn}(${parameters})
449
+ returns setof text
450
+ language sql
451
+ stable
452
+ security definer
453
+ set search_path = ''
454
+ as $$
455
+ select null::text where false
456
+ $$;`).join("\n");
457
+ }
458
+ function rowSql(ctx, rows, table, where) {
459
+ const fn = qualified(ctx, rows.replace(/_rows$/u, "_row"));
460
+ return `create or replace function ${fn}(p_row ${table}, p_permission text)
461
+ returns boolean
462
+ language sql
463
+ stable
464
+ security definer
465
+ set search_path = ''
466
+ as $$
467
+ with ${CANDIDATES} as (select (p_row).*)
468
+ select exists (select 1 from ${CANDIDATES} where ${where})
469
+ $$;
470
+ revoke execute on function ${fn}(${table}, text) from public, anon;
471
+ grant execute on function ${fn}(${table}, text) to authenticated;`;
472
+ }
473
+ function whereOf(branches) {
474
+ const cases = [...branches.keys()].toSorted().flatMap((key) => {
475
+ const sql = permissionCase(key, branches.get(key) ?? []);
476
+ return sql === void 0 ? [] : [sql];
477
+ });
478
+ return cases.length === 0 ? "false" : `case p_permission\n${cases.join("\n")}\n else false\n end`;
479
+ }
480
+ function candidatesSql(fn, table, id, where) {
481
+ const assign = (indent) => `${indent}v_row.${id} := v_id;\n${indent}v_rows := pg_catalog.array_append(v_rows, v_row);`;
482
+ return `create or replace function ${fn}(p_permission text, p_ids text[])
483
+ returns setof text
484
+ language plpgsql
485
+ stable
486
+ security definer
487
+ set search_path = ''
488
+ as $$
489
+ declare
490
+ v_row ${table};
491
+ v_rows ${table}[] := '{}';
492
+ v_id text;
493
+ begin
494
+ begin
495
+ foreach v_id in array coalesce(p_ids, '{}') loop
496
+ ${assign(" ")}
497
+ end loop;
498
+ exception when data_exception then
499
+ v_rows := '{}';
500
+ foreach v_id in array p_ids loop
501
+ begin
502
+ ${assign(" ")}
503
+ exception when data_exception then
504
+ null;
505
+ end;
506
+ end loop;
507
+ end;
508
+ return query
509
+ with ${CANDIDATES} as materialized (
510
+ select * from ${table} where ${id} = any (array(select (r).${id} from pg_catalog.unnest(v_rows) r))
511
+ )
512
+ select ${id}::text from ${CANDIDATES}
513
+ where ${where};
514
+ end
515
+ $$;
516
+ revoke execute on function ${fn}(text, text[]) from public, anon;
517
+ grant execute on function ${fn}(text, text[]) to authenticated;`;
518
+ }
519
+ function resourceSql(ctx, node, branches, narrowed, tables) {
520
+ const name = rowsHelper(node.name);
521
+ const fn = qualified(ctx, name);
522
+ const table = quoteQualified(tableFor(node.name, tables));
523
+ const where = whereOf(branches);
524
+ const near = whereOf(narrowed);
525
+ const rows = `-- ${node.name}: ids of the rows the caller may act on with p_permission, as the table's policies decide it
526
+ create or replace function ${fn}(p_permission text)
527
+ returns setof text
528
+ language sql
529
+ stable
530
+ security definer
531
+ set search_path = ''
532
+ as $$
533
+ select ${quoteIdent(node.id)}::text from ${table}
534
+ where ${where}
535
+ $$;
536
+ revoke execute on function ${fn}(text) from public, anon;
537
+ grant execute on function ${fn}(text) to authenticated;
538
+ ${candidatesSql(fn, table, quoteIdent(node.id), near)}
539
+ ${rowSql(ctx, name, table, near)}`;
540
+ if (ctx.dialect === "neon") return rows;
541
+ return `${rows}
542
+ -- the same rows for a user the caller names, with claims it supplies; no client role may execute it
543
+ ${forUserSql(ctx, qualified(ctx, `${name}_for`), fn)}`;
544
+ }
545
+ /**
546
+ * `permitted_<resource>_rows(p_permission)` for each resource `select` names
547
+ * (or every resource a grant reaches with `true`): the ids of its rows the
548
+ * caller may read, update or delete with that permission, from the same
549
+ * compiled allows and denies the table policies use, so closure walks, link
550
+ * hops, the restricted stop, `includes`, groups and `requires` all apply. A
551
+ * `security definer` helper, so hand-written policies and functions call it
552
+ * without restating the graph. Outside the `neon` dialect a
553
+ * `permitted_<resource>_rows_for(p_user, p_permission, p_claims)` form runs it
554
+ * as the named user, with the claims the caller supplies, for trusted SQL.
555
+ */
556
+ function rowHelpersSql(ctx, policy, branches, select, tables, warnings, narrowed = branches) {
557
+ const names = select === true ? [...new Set(branches.flatMap((branch) => branch.resource === void 0 ? [] : [branch.resource]))].toSorted() : [...new Set(select)];
558
+ const called = inheritTargets(policy);
559
+ for (const name of called) if (!names.includes(name)) names.push(name);
560
+ const chunks = called.map((name) => stubSql(ctx, name));
561
+ for (const name of names) {
562
+ const node = policy.resources.get(name);
563
+ if (node === void 0) throw configError(`PermDock CLI: rls.rowHelpers names '${name}', which the policy does not declare`);
564
+ chunks.push(resourceSql(ctx, node, rowBranchesOf(branches, name), rowBranchesOf(narrowed, name), tables));
565
+ }
566
+ if (chunks.length > 0 && ctx.dialect === "neon") warnings.push("rls.rowHelpers: the neon dialect reads the subject from auth.session(), which SQL cannot set, so no permitted_<resource>_rows_for is written");
567
+ return chunks.length === 0 ? "" : `${chunks.join("\n\n")}\n`;
568
+ }
569
+ //#endregion
246
570
  //#region src/cli/rls/generate-context.ts
247
- /** The scopes an `rls.migrate` `role` helper names, so `rls generate` writes their role-filtered member helper. */
571
+ /**
572
+ * The scopes an `rls.migrate` `role` helper names, so `rls generate` writes
573
+ * their role-filtered member helper.
574
+ */
248
575
  function roleMemberScopesOf(migrate) {
249
576
  const scopes = [...new Set(Object.values(migrate?.helpers ?? {}).flatMap((helper) => helper.form === "role" ? [helper.scope] : []))].toSorted();
250
577
  return scopes.length === 0 ? {} : { roleMemberScopes: scopes };
@@ -285,7 +612,10 @@ function skippedOwnershipTriggers(triggers, scopes) {
285
612
  return name;
286
613
  });
287
614
  }
288
- /** The SQL context every emitter reads, from the flags, `rls` config and the policy. */
615
+ /**
616
+ * The SQL context every emitter reads, from the flags, `rls` config and the
617
+ * policy.
618
+ */
289
619
  function buildContext(input, policy, options) {
290
620
  const rls = input.config.rls;
291
621
  const memberships = parseMembershipsFlag(input.memberships) ?? rls?.memberships;
@@ -342,8 +672,7 @@ function buildContext(input, policy, options) {
342
672
  schema,
343
673
  authorize,
344
674
  roleClaim: rls?.roleClaim ?? "user_role",
345
- tenantType: input.tenantType ?? rls?.tenantType ?? "uuid",
346
- ...rls?.teamType === void 0 ? {} : { teamType: rls.teamType },
675
+ tenantType: input.tenantType ?? firstScopeType(rls?.scopeTypes, scopes),
347
676
  ...rls?.scopeTypes === void 0 ? {} : { scopeTypes: rls.scopeTypes },
348
677
  ...memberships === void 0 ? {} : { memberships },
349
678
  ...sources === void 0 || sources.length === 0 ? {} : { sources },
@@ -368,7 +697,7 @@ function buildContext(input, policy, options) {
368
697
  } },
369
698
  ...options.fieldsMode === void 0 ? {} : { fields: options.fieldsMode },
370
699
  ...vias === void 0 ? {} : { vias },
371
- ...graph.size === 0 ? {} : { graph: {
700
+ ...graph.size === 0 && inheritTargets(policy).length === 0 ? {} : { graph: {
372
701
  closures: closureDepths(graph),
373
702
  resources: policy.resources,
374
703
  ...rls?.tables === void 0 ? {} : { tables: tableNames(rls.tables) ?? {} }
@@ -388,8 +717,14 @@ function buildContext(input, policy, options) {
388
717
  }
389
718
  const [unsatisfied] = unsatisfiedKinds(ctx, policy);
390
719
  if (unsatisfied !== void 0) return { refusal: `role ${unsatisfied.role} is for ${unsatisfied.for.join(", ")}, but its membership sources hold ${unsatisfied.sources.join(", ")}: no membership can hold it; set via on a source to one of those kinds` };
720
+ const names = resolveNames(policy, input.config, {
721
+ schema,
722
+ gucPrefix: ctx.gucPrefix,
723
+ tenantClaim: ctx.tenantClaim
724
+ });
391
725
  return {
392
726
  ctx,
727
+ names,
393
728
  graph,
394
729
  ownership,
395
730
  schema,
@@ -413,192 +748,20 @@ function generateOptions(input) {
413
748
  revokeColumns
414
749
  };
415
750
  }
416
- /** Whether `--split` names `part`, which then leaves the helpers or the warnings. */
751
+ /**
752
+ * Whether `--split` names `part`, which then leaves the helpers or the
753
+ * warnings.
754
+ */
417
755
  function splitsPart(raw, part) {
418
756
  const split = parseSplit(raw);
419
757
  return typeof split !== "string" && split?.includes(part) === true;
420
758
  }
421
759
  //#endregion
422
- //#region src/cli/rls/rows.ts
423
- /** `permitted_<resource>_rows(p_permission)`: the resource's row ids the subject may act on with one permission. */
424
- function rowsHelper(resource) {
425
- const name = graphSqlName(resource);
426
- const helper = `permitted_${name ?? resource}_rows`;
427
- if (name === void 0 || new TextEncoder().encode(`${helper}_for`).length > 63) throw configError(`PermDock CLI: rls.rowHelpers cannot name a helper for resource '${resource}'; use a SQL name of at most 45 bytes`);
428
- return helper;
429
- }
430
- /** Every declared `<permission>@<level>` of an instance permission on a resource with levels. */
431
- function levelKeys(policy) {
432
- const out = [];
433
- for (const leaf of listPermissions(policy.vocabulary.permissions)) {
434
- if (leaf.kind !== "instance") continue;
435
- for (const [level, condition] of policyLevels(policy, leaf.resource)) out.push({
436
- key: `${leaf.key}@${level}`,
437
- permission: leaf.key,
438
- conditioned: !(condition.op === "and" && condition.conditions.length === 0),
439
- rowHelper: `permitted_${graphSqlName(leaf.resource) ?? leaf.resource}_row`
440
- });
441
- }
442
- return out;
443
- }
444
- /** The branches a row check of a permission reads: its allows and denies, inserts included, for signed-in callers. */
445
- function rowBranchesOf(branches, resource) {
446
- const out = /* @__PURE__ */ new Map();
447
- for (const branch of branches) {
448
- if (branch.resource !== resource || branch.coverage === true || !branch.roles.includes("authenticated")) continue;
449
- out.set(branch.permissionKey, [...out.get(branch.permissionKey) ?? [], branch]);
450
- }
451
- return out;
452
- }
453
- /** What a branch asks of a row: the `with check` of an insert, which sees the new row, the `using` of every other command. */
454
- function clauseOf(branch) {
455
- const clauses = branchClauses(branch);
456
- return (branch.command === "insert" ? clauses.check : clauses.using) ?? "true";
457
- }
458
- function usingOf(branches) {
459
- const parts = branches.map(clauseOf);
460
- return parts.length === 0 ? void 0 : orSql(parts);
461
- }
462
- function permissionCase(key, branches) {
463
- const allow = usingOf(branches.filter((branch) => branch.effect === "allow"));
464
- if (allow === void 0) return;
465
- const deny = usingOf(branches.filter((branch) => branch.effect === "deny"));
466
- const granted = `coalesce((${allow}), false)`;
467
- return ` when ${quoteLiteral(key)} then ${deny === void 0 ? granted : `${granted} and (${deny}) is not true`}`;
468
- }
469
- function forUserSql(ctx, fn, helper) {
470
- const user = ctx.dialect === "supabase" ? "uuid" : "text";
471
- const signature = `${user}, text, jsonb`;
472
- const head = `create or replace function ${fn}(p_user ${user}, p_permission text, p_claims jsonb default '{}')
473
- returns setof text
474
- language plpgsql
475
- volatile
476
- security definer
477
- set search_path = ''
478
- as $$`;
479
- const tail = `revoke execute on function ${fn}(${signature}) from public, anon, authenticated;`;
480
- if (ctx.dialect === "supabase") return `${head}
481
- declare
482
- v_claims text := pg_catalog.current_setting('request.jwt.claims', true);
483
- begin
484
- perform pg_catalog.set_config(
485
- 'request.jwt.claims',
486
- (coalesce(p_claims, '{}'::jsonb) || pg_catalog.jsonb_build_object('sub', p_user::text, 'role', 'authenticated'))::text,
487
- true
488
- );
489
- return query select r.id from ${helper}(p_permission) r(id);
490
- perform pg_catalog.set_config('request.jwt.claims', coalesce(v_claims, ''), true);
491
- end
492
- $$;
493
- ${tail}`;
494
- const prefix = ctx.gucPrefix;
495
- return `${head}
496
- declare
497
- v_saved jsonb := '{}'::jsonb;
498
- v_key text;
499
- v_value text;
500
- begin
501
- for v_key, v_value in
502
- select 'user_id', p_user
503
- union all
504
- select c.key, c.value from pg_catalog.jsonb_each_text(coalesce(p_claims, '{}'::jsonb)) c where c.key <> 'user_id'
505
- loop
506
- v_saved := v_saved || pg_catalog.jsonb_build_object(v_key, coalesce(pg_catalog.current_setting(${quoteLiteral(`${prefix}.`)} || v_key, true), ''));
507
- perform pg_catalog.set_config(${quoteLiteral(`${prefix}.`)} || v_key, v_value, true);
508
- end loop;
509
- return query select r.id from ${helper}(p_permission) r(id);
510
- for v_key, v_value in select s.key, s.value from pg_catalog.jsonb_each_text(v_saved) s loop
511
- perform pg_catalog.set_config(${quoteLiteral(`${prefix}.`)} || v_key, v_value, true);
512
- end loop;
513
- end
514
- $$;
515
- ${tail}`;
516
- }
517
- function inheritTargets(policy) {
518
- const out = /* @__PURE__ */ new Set();
519
- for (const grant of policy.grants) for (const item of flattenGrantee(grant.to)) if (item.kind === "inherit") out.add(item.resource);
520
- return [...out].toSorted();
521
- }
522
- function stubSql(ctx, resource) {
523
- return `create or replace function ${qualified(ctx, rowsHelper(resource))}(p_permission text)
524
- returns setof text
525
- language sql
526
- stable
527
- security definer
528
- set search_path = ''
529
- as $$
530
- select null::text where false
531
- $$;`;
532
- }
533
- function rowSql(ctx, rows, table, where) {
534
- const fn = qualified(ctx, rows.replace(/_rows$/u, "_row"));
535
- return `create or replace function ${fn}(p_row ${table}, p_permission text)
536
- returns boolean
537
- language sql
538
- stable
539
- security definer
540
- set search_path = ''
541
- as $$
542
- select exists (select 1 from (select (p_row).*) r where ${where})
543
- $$;
544
- revoke execute on function ${fn}(${table}, text) from public, anon;
545
- grant execute on function ${fn}(${table}, text) to authenticated;`;
546
- }
547
- function resourceSql(ctx, node, branches, tables) {
548
- const name = rowsHelper(node.name);
549
- const fn = qualified(ctx, name);
550
- const table = quoteQualified(tableFor(node.name, tables));
551
- const cases = [...branches.keys()].toSorted().flatMap((key) => {
552
- const sql = permissionCase(key, branches.get(key) ?? []);
553
- return sql === void 0 ? [] : [sql];
554
- });
555
- const where = cases.length === 0 ? "false" : `case p_permission\n${cases.join("\n")}\n else false\n end`;
556
- const rows = `-- ${node.name}: ids of the rows the caller may act on with p_permission, as the table's policies decide it
557
- create or replace function ${fn}(p_permission text)
558
- returns setof text
559
- language sql
560
- stable
561
- security definer
562
- set search_path = ''
563
- as $$
564
- select ${quoteIdent(node.id)}::text from ${table}
565
- where ${where}
566
- $$;
567
- revoke execute on function ${fn}(text) from public, anon;
568
- grant execute on function ${fn}(text) to authenticated;
569
- ${rowSql(ctx, name, table, where)}`;
570
- if (ctx.dialect === "neon") return rows;
571
- return `${rows}
572
- -- the same rows for a user the caller names, with claims it supplies; no client role may execute it
573
- ${forUserSql(ctx, qualified(ctx, `${name}_for`), fn)}`;
574
- }
760
+ //#region src/cli/sql/supautils.ts
575
761
  /**
576
- * `permitted_<resource>_rows(p_permission)` for each resource `select`
577
- * names (or every resource a grant reaches with `true`): the ids of its rows
578
- * the caller may read, update or delete with that permission, from the same
579
- * compiled allows and denies the table policies use, so closure walks, link
580
- * hops, the restricted stop, `includes`, groups and `requires` all apply. A
581
- * `security definer` helper, so hand-written policies and functions call it
582
- * without restating the graph. Outside the `neon` dialect a
583
- * `permitted_<resource>_rows_for(p_user, p_permission, p_claims)` form runs it
584
- * as the named user, with the claims the caller supplies, for trusted SQL.
762
+ * `supautils.reserved_roles` of supabase/postgres 17.11.0.002 (supautils
763
+ * 3.4.4).
585
764
  */
586
- function rowHelpersSql(ctx, policy, branches, select, tables, warnings) {
587
- const names = select === true ? [...new Set(branches.flatMap((branch) => branch.resource === void 0 ? [] : [branch.resource]))].toSorted() : [...new Set(select)];
588
- const called = inheritTargets(policy);
589
- for (const name of called) if (!names.includes(name)) names.push(name);
590
- const chunks = called.map((name) => stubSql(ctx, name));
591
- for (const name of names) {
592
- const node = policy.resources.get(name);
593
- if (node === void 0) throw configError(`PermDock CLI: rls.rowHelpers names '${name}', which the policy does not declare`);
594
- chunks.push(resourceSql(ctx, node, rowBranchesOf(branches, name), tables));
595
- }
596
- if (chunks.length > 0 && ctx.dialect === "neon") warnings.push("rls.rowHelpers: the neon dialect reads the subject from auth.session(), which SQL cannot set, so no permitted_<resource>_rows_for is written");
597
- return chunks.length === 0 ? "" : `${chunks.join("\n\n")}\n`;
598
- }
599
- //#endregion
600
- //#region src/cli/sql/supautils.ts
601
- /** `supautils.reserved_roles` of supabase/postgres 17.11.0.002 (supautils 3.4.4). */
602
765
  const RESERVED_ROLES = /* @__PURE__ */ new Set([
603
766
  "supabase_admin",
604
767
  "supabase_auth_admin",
@@ -615,7 +778,10 @@ const RESERVED_ROLES = /* @__PURE__ */ new Set([
615
778
  "authenticated",
616
779
  "anon"
617
780
  ]);
618
- /** The `*` entries of `reserved_roles`: `postgres` may still `set` or `reset` their settings. */
781
+ /**
782
+ * The `*` entries of `reserved_roles`: `postgres` may still `set` or `reset`
783
+ * their settings.
784
+ */
619
785
  const CONFIGURABLE_ROLES = /* @__PURE__ */ new Set([
620
786
  "service_role",
621
787
  "authenticator",
@@ -672,9 +838,9 @@ function rejection(text) {
672
838
  return role === void 0 ? void 0 : `grants membership in the reserved role ${role}`;
673
839
  }
674
840
  /**
675
- * The statements of `sql` that supautils rejects for a non-superuser:
676
- * changing or dropping a reserved role, other than `set` or `reset` on the
677
- * four API roles, and granting a reserved membership.
841
+ * The statements of `sql` that supautils rejects for a non-superuser: changing
842
+ * or dropping a reserved role, other than `set` or `reset` on the four API
843
+ * roles, and granting a reserved membership.
678
844
  */
679
845
  function supautilsRejections(sql) {
680
846
  return sqlStatements(sql).flatMap(({ line, text }) => {
@@ -686,4 +852,4 @@ function supautilsRejections(sql) {
686
852
  });
687
853
  }
688
854
  //#endregion
689
- export { generateOptions as a, buildContext as c, rowHelpersSql as i, DROPPED_LIST as l, inheritTargets as n, isRefusal as o, levelKeys as r, splitsPart as s, supautilsRejections as t, rebuildPlan as u };
855
+ export { buildContext as a, levelKeys as c, rebuildPlan as d, splitsPart as i, rowHelpersSql as l, generateOptions as n, CANDIDATES as o, isRefusal as r, inheritTargets as s, supautilsRejections as t, DROPPED_LIST as u };