permdock 0.16.0 → 0.18.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 (384) hide show
  1. package/dist/a2a/index.d.ts +4 -4
  2. package/dist/a2a/index.js +3 -3
  3. package/dist/{adapter-context-CIQpQxbE.js → adapter-context-OHikyRqV.js} +1 -1
  4. package/dist/{adoption-scan-C2BCiUEG.js → adoption-scan-CxExBYSJ.js} +1 -1
  5. package/dist/agent/index.d.ts +2 -2
  6. package/dist/agent/index.js +1 -1
  7. package/dist/ai-sdk/index.d.ts +3 -3
  8. package/dist/ai-sdk/index.js +3 -3
  9. package/dist/approval-normalize-CUjgSsOl.js +189 -0
  10. package/dist/approval-policies-oNnckT12.d.ts +138 -0
  11. package/dist/{approval-prompt-3BqWczTt.d.ts → approval-prompt-Bg7gDSqd.d.ts} +1 -1
  12. package/dist/approvals/index.d.ts +5 -4
  13. package/dist/approvals/index.js +7 -6
  14. package/dist/{approvals-DnIBTuXE.js → approvals-DGId_hgJ.js} +3 -3
  15. package/dist/{approvers-B4r0N_Uz.js → approvers-BaNwKYgd.js} +20 -1
  16. package/dist/{arazzo-ClYz2Z0W.js → arazzo--riLuGY0.js} +4 -4
  17. package/dist/{arazzo-CHoYnQXO.js → arazzo-CEDbb-uM.js} +2 -2
  18. package/dist/{args-0FrVs5EH.js → args-iafbHiXn.js} +2 -5
  19. package/dist/astro/index.d.ts +4 -4
  20. package/dist/astro/index.js +2 -2
  21. package/dist/{audience-DTjR8xet.js → audience-B4YR9UpV.js} +1 -1
  22. package/dist/{auth--yPyZNgr.js → auth-j3Eu-j4h.js} +1 -1
  23. package/dist/authz-topic-Dbc-HDOS.js +15 -0
  24. package/dist/authzen/index.d.ts +5 -5
  25. package/dist/authzen/index.js +2 -2
  26. package/dist/{automation-C6Jg75xq.d.ts → automation-Bfa_wD1h.d.ts} +1 -1
  27. package/dist/better-auth/index.d.ts +1 -1
  28. package/dist/better-auth/index.js +10 -8
  29. package/dist/better-supabase/index.d.ts +335 -38
  30. package/dist/better-supabase/index.js +778 -117
  31. package/dist/{better-supabase-Dirf_8Ec.js → better-supabase-BJtQ-kNf.js} +26 -10
  32. package/dist/{bind-BNQA9JK9.js → bind-B4pMH9bm.js} +6 -6
  33. package/dist/{bind-YYjvfpB9.d.ts → bind-DR6ku3A9.d.ts} +7 -7
  34. package/dist/{budget-BELja5A9.js → budget-BBCPDOGP.js} +1 -1
  35. package/dist/{budget-hYsPz_yE.d.ts → budget-CNLsV2SL.d.ts} +1 -1
  36. package/dist/{build-instance-BWXqwQYU.js → build-instance-BFMFQdE_.js} +3 -2
  37. package/dist/{capability-Di9tiUvi.d.ts → capability-BZ_veK9o.d.ts} +1 -1
  38. package/dist/{capability-BqX94r07.js → capability-zN6T9fxe.js} +2 -3
  39. package/dist/{casbin-D_rVQ31U.js → casbin-DCQHkkyj.js} +2 -2
  40. package/dist/{casbin-C9EvElBb.js → casbin-bKC1FpEx.js} +2 -2
  41. package/dist/{casl-C4OINZHI.js → casl-CjBVJj8R.js} +2 -2
  42. package/dist/{casl-CHHoCldP.js → casl-CkBssiB1.js} +1 -1
  43. package/dist/catalog/index.d.ts +5 -5
  44. package/dist/catalog/index.js +7 -7
  45. package/dist/catalog-Caqhbdix.js +1 -0
  46. package/dist/{catalog-CGlSwU6j.js → catalog-D1fw8qif.js} +5 -5
  47. package/dist/{catalog-doc-DjMKzJp9.js → catalog-doc-C4DGfJCO.js} +3 -3
  48. package/dist/{catalog-operations-DeHTrJSV.js → catalog-operations-BD22drQf.js} +4 -4
  49. package/dist/{catalog-amPDr0JQ.js → catalog-zzNuR3sY.js} +3 -3
  50. package/dist/{challenge-DImNcR7B.js → challenge-B2O2OLEk.js} +2 -2
  51. package/dist/chat/index.d.ts +1 -1
  52. package/dist/chat/index.js +2 -2
  53. package/dist/chat-sdk/index.d.ts +3 -3
  54. package/dist/{checks-CGkP3Z7A.js → checks-fyDOhcz0.js} +33 -1
  55. package/dist/claude-agent/index.d.ts +3 -3
  56. package/dist/claude-agent/index.js +2 -2
  57. package/dist/clerk/index.d.ts +2 -2
  58. package/dist/clerk/index.js +10 -7
  59. package/dist/cli/bin.js +1 -1
  60. package/dist/cli/index.d.ts +5 -5
  61. package/dist/cli/index.js +3 -3
  62. package/dist/client-CH7vzSAY.d.ts +32 -0
  63. package/dist/cloud/index.d.ts +8 -8
  64. package/dist/cloud/index.js +1 -1
  65. package/dist/{cloud-DdaJ7ILM.js → cloud-C0vXBmLG.js} +4 -4
  66. package/dist/{codemod-B1USJS7a.js → codemod-C-L0w-u7.js} +3 -3
  67. package/dist/{codemod-ammy6wv4.js → codemod-eYI1FbeJ.js} +395 -8
  68. package/dist/{collect-DnXL4B8c.js → collect-CU85z6Ta.js} +4 -4
  69. package/dist/{collect-WCl8cJQV.js → collect-D878zLDP.js} +4 -4
  70. package/dist/collect-KCtOigxx.js +1 -0
  71. package/dist/compile/index.d.ts +1 -1
  72. package/dist/compile/index.js +1 -1
  73. package/dist/{compile-EzEMB-7v.js → compile-B_oJqmIg.js} +4 -4
  74. package/dist/{compile-BEklRUYo.d.ts → compile-DBm0ub4p.d.ts} +2 -2
  75. package/dist/{completion--Y4YItFZ.js → completion-Dauc6pVT.js} +3 -3
  76. package/dist/{config-CcLlvEYW.js → config-COHmivz9.js} +4 -4
  77. package/dist/{config-BQ77xMZk.js → config-DWp2PucY.js} +2 -2
  78. package/dist/{config-report-DVMOLJ7F.js → config-report-DKpFm5ID.js} +2 -2
  79. package/dist/{context-BnIzxTNE.js → context-DeammvFl.js} +2 -2
  80. package/dist/convex/index.d.ts +4 -4
  81. package/dist/convex/index.js +3 -3
  82. package/dist/{core-lxoANyai.js → core-B8sLve3z.js} +7 -7
  83. package/dist/{core-CFepFiDP.d.ts → core-D87h2kpR.d.ts} +2 -2
  84. package/dist/{create-BLPKnJKa.js → create-3A7J9KRR.js} +6 -5
  85. package/dist/{create-CDd9c22W.d.ts → create-BrQXL-Wt.d.ts} +6 -6
  86. package/dist/{create-BPUopdfL.d.ts → create-BzwjZuRS.d.ts} +7 -7
  87. package/dist/{create-Coq5fIrq.js → create-C-tm3KIF.js} +5 -5
  88. package/dist/{create-DBvUsgzK.d.ts → create-CtoT1lIQ.d.ts} +4 -4
  89. package/dist/{credential-CyyyvCsL.js → credential-B3Hj4puZ.js} +4 -3
  90. package/dist/{credentials-CdDxp7jN.js → credentials-dkycUsY3.js} +1 -1
  91. package/dist/decision-CaG5_eNJ.js +21 -0
  92. package/dist/{delegation-CDB6_keF.js → delegation-aK4T_5WU.js} +3 -3
  93. package/dist/delivery/index.d.ts +4 -4
  94. package/dist/delivery/index.js +1 -1
  95. package/dist/{denied-text-DHldhVUv.d.ts → denied-text-DlIxt8fh.d.ts} +1 -1
  96. package/dist/{describe-BbFPBSms.d.ts → describe-BKtC_8PG.d.ts} +1 -1
  97. package/dist/{describe-Bb4hGK5d.js → describe-BZAlPHxT.js} +2 -1
  98. package/dist/{diff-DfmYaIhB.js → diff-BnNHqtHj.js} +8 -8
  99. package/dist/{diff-CxtbOi2l.js → diff-CBCzOTWM.js} +2 -2
  100. package/dist/{doctor-D1Xnmy6u.js → doctor-CkYKCuX7.js} +233 -30
  101. package/dist/{doctor-CwYc2lJb.js → doctor-xUpR5rXg.js} +3 -3
  102. package/dist/drizzle/index.d.ts +3 -3
  103. package/dist/drizzle/index.js +1 -1
  104. package/dist/elysia/index.d.ts +4 -4
  105. package/dist/elysia/index.js +3 -3
  106. package/dist/{errors-Vpu6rKHl.js → errors-BhRkoNS7.js} +0 -2
  107. package/dist/{errors-BIM4MFsJ.d.ts → errors-TpzkEKgJ.d.ts} +1 -1
  108. package/dist/{evaluate-BAmf_AQd.js → evaluate-Czbj7thS.js} +18 -15
  109. package/dist/{evaluations-DOWuBpWv.d.ts → evaluations-CisTTURl.d.ts} +3 -3
  110. package/dist/{evaluations-IBceAeKT.js → evaluations-h3KoJAPa.js} +3 -22
  111. package/dist/eve/index.d.ts +4 -4
  112. package/dist/eve/index.js +3 -3
  113. package/dist/express/index.d.ts +4 -4
  114. package/dist/express/index.js +3 -3
  115. package/dist/fastify/index.d.ts +4 -4
  116. package/dist/fastify/index.js +3 -3
  117. package/dist/{fetch-adapter-BIbBAtPZ.d.ts → fetch-adapter-BdmfnbJM.d.ts} +2 -2
  118. package/dist/{fetch-adapter-dPTgJVHd.js → fetch-adapter-DH-NJPbL.js} +2 -2
  119. package/dist/{fields-DI8s3cPl.js → fields-CrjL6A49.js} +3 -3
  120. package/dist/{files-B3AA05f1.js → files-CfiRtQ-m.js} +1 -1
  121. package/dist/{fixtures-Bm4_K1ke.js → fixtures-Cemqurt8.js} +10 -4
  122. package/dist/{flags-DXjoTVbS.js → flags-BlmpmXoY.js} +2 -2
  123. package/dist/{from-snapshot-DCakWRsr.js → from-snapshot-DMlSSo9b.js} +14 -12
  124. package/dist/{gen-DwgCSC6V.js → gen-BEIN-DRM.js} +2 -2
  125. package/dist/{gen-DuAhghDw.js → gen-mf-MRwVr.js} +9 -9
  126. package/dist/{generate-CRVV5V7l.js → generate-BqkZq8Dr.js} +2 -2
  127. package/dist/{grantee-conditions-BrYPe-w0.js → grantee-conditions-DX4K_gGI.js} +1 -1
  128. package/dist/{grantee-match-7RZZvoT_.js → grantee-match-BP-k4vRJ.js} +2 -2
  129. package/dist/h3/index.d.ts +4 -4
  130. package/dist/h3/index.js +3 -3
  131. package/dist/{helpers-DJicaG6f.js → helpers-DmqGy63f.js} +85 -13
  132. package/dist/hono/index.d.ts +4 -4
  133. package/dist/hono/index.js +3 -3
  134. package/dist/{hosted-DVxlLZMe.d.ts → hosted-BFNXwcjd.d.ts} +1 -1
  135. package/dist/{hosted-D0IzESu_.js → hosted-waouw2V-.js} +12 -10
  136. package/dist/{http-DOL33cO0.js → http-DhMWeB_h.js} +1 -1
  137. package/dist/{import-CNBF96hB.js → import-C1XXpG_m.js} +4 -4
  138. package/dist/{import-Dfe2unKO.js → import-DObwEota.js} +3 -3
  139. package/dist/{index-BinlXeU-.d.ts → index-BhnOOnp9.d.ts} +2 -2
  140. package/dist/{index-ymept53A.d.ts → index-CVGio3cH.d.ts} +4 -4
  141. package/dist/{index-DJwEgYzA.d.ts → index-CdMOd-GY.d.ts} +17 -11
  142. package/dist/{index-Cay5-Kvx.d.ts → index-CdUTE6qd.d.ts} +11 -10
  143. package/dist/{index-Dj2qF9VC.d.ts → index-Dfv9Toct.d.ts} +1 -1
  144. package/dist/{index-CV-7DWeD.d.ts → index-rFp6X_QP.d.ts} +4 -4
  145. package/dist/index.d.ts +18 -16
  146. package/dist/index.js +24 -20
  147. package/dist/{init-BUo2G-FI.js → init-CNJ8lLjo.js} +5 -5
  148. package/dist/{init-C6cWP3xW.js → init-DS3PEsCG.js} +5 -5
  149. package/dist/{instance-options-CoHn-0e8.d.ts → instance-options-2sFGSdsf.d.ts} +2 -2
  150. package/dist/{instance-snapshot-DuWf1cT3.js → instance-snapshot-BWa71my8.js} +15 -12
  151. package/dist/jwt/index.d.ts +4 -4
  152. package/dist/jwt/index.js +3 -3
  153. package/dist/{kernel-BD8QuMnv.js → kernel-30Z2zM_d.js} +10 -10
  154. package/dist/kysely/index.d.ts +3 -3
  155. package/dist/kysely/index.js +1 -1
  156. package/dist/{load-DjSU5KXO.js → load-BaEamml-.js} +1 -1
  157. package/dist/load-CjnlPxpL.js +1 -0
  158. package/dist/{login-D1MHOomI.js → login-BgK5Jloo.js} +4 -4
  159. package/dist/{login-DCKE5pVy.js → login-DUVzBLh7.js} +4 -4
  160. package/dist/{manifest-BXTbHNIV.js → manifest-BdzBobNK.js} +1 -1
  161. package/dist/{manifest-schema-DQkBK2Mr.js → manifest-schema-CsFsYLF-.js} +1 -1
  162. package/dist/{manifest-Cft51TLK.js → manifest-wclLWBVH.js} +37 -37
  163. package/dist/{map-claims-C-nv08_n.js → map-claims-PQwHynxV.js} +25 -11
  164. package/dist/{map-error-pasIGqMT.js → map-error-BH16Ah8P.js} +1 -1
  165. package/dist/mcp/index.d.ts +8 -8
  166. package/dist/mcp/index.js +9 -9
  167. package/dist/{migrate-BJHxQqT5.js → migrate-BbY5-Khy.js} +4 -4
  168. package/dist/{module-values-B1EVTkHP.js → module-values-B8tNIxdd.js} +2 -2
  169. package/dist/nest/index.d.ts +4 -4
  170. package/dist/nest/index.js +3 -3
  171. package/dist/next/index.d.ts +45 -13
  172. package/dist/next/index.js +68 -30
  173. package/dist/next/plugin.d.ts +1 -1
  174. package/dist/next/plugin.js +2 -2
  175. package/dist/node/index.d.ts +4 -4
  176. package/dist/node/index.js +2 -2
  177. package/dist/openai/index.d.ts +4 -4
  178. package/dist/openai/index.js +3 -3
  179. package/dist/openapi/index.d.ts +2 -2
  180. package/dist/{openapi-BwWkHxvW.js → openapi-C4gFqeRz.js} +4 -4
  181. package/dist/{openapi-DSzQN7Zu.js → openapi-zMEB9qxn.js} +5 -5
  182. package/dist/{operation-findings-CXtFzlKJ.js → operation-findings-CVwJHEu_.js} +1 -1
  183. package/dist/operation-risks-BKOcTv8J.js +13 -0
  184. package/dist/operations-Bm9HFecz.js +89 -0
  185. package/dist/orpc/index.d.ts +5 -5
  186. package/dist/orpc/index.js +3 -3
  187. package/dist/otel/index.d.ts +3 -3
  188. package/dist/otel/index.js +1 -1
  189. package/dist/{output-DlICTjBh.js → output-BFWLER4r.js} +1 -1
  190. package/dist/output-files-BYscrQl-.js +1 -0
  191. package/dist/{output-files-BIQ_9pIs.js → output-files-CM0BnH05.js} +1 -1
  192. package/dist/{ownership-qqBuGJXr.js → ownership-D-mIt-w0.js} +6 -6
  193. package/dist/{parse-1_ZheTW5.js → parse-UTC-sDrt.js} +2 -2
  194. package/dist/{parse-local-manifest-DEiCF4ah.js → parse-local-manifest-CxcSMQgl.js} +2 -2
  195. package/dist/{parse-local-manifest-CCmbhnxP.d.ts → parse-local-manifest-DvjTQNuO.d.ts} +1 -1
  196. package/dist/{parse-request-CwCZpyjV.js → parse-request-DOBVaeiQ.js} +1 -1
  197. package/dist/pdp/index.d.ts +3 -3
  198. package/dist/pdp/index.js +3 -3
  199. package/dist/{peer-Q0fuZ6hx.js → peer-BuK9F53f.js} +1 -1
  200. package/dist/{peer-C9LvBCcb.js → peer-n-swIV4H.js} +1 -1
  201. package/dist/{permdock-BvjivVb9.js → permdock-D-_WrdKu.js} +205 -102
  202. package/dist/{permdock-CprAPN3w.d.ts → permdock-ffY4CMd9.d.ts} +101 -131
  203. package/dist/{permissions-CYcHj_w7.js → permissions-B3ggI88M.js} +2 -2
  204. package/dist/{permissions-CVXmRILq.js → permissions-BaoLxy66.js} +1 -13
  205. package/dist/{pg-DQTqRrou.js → pg-Ddxsd5ZB.js} +2 -2
  206. package/dist/{policy-BycVKnXv.d.ts → policy-BtKSApSt.d.ts} +1 -1
  207. package/dist/{policy-CLQ8__GF.js → policy-cV_wwPb8.js} +5 -4
  208. package/dist/{policy-from-catalog-CU3An8uP.js → policy-from-catalog-B68hGC0S.js} +9 -8
  209. package/dist/{policy-types-DGIO_gxq.d.ts → policy-types-D-GwfQTc.d.ts} +72 -19
  210. package/dist/{postgrest-DAxFltvO.js → postgrest-BrjrckDG.js} +74 -19
  211. package/dist/{postgrest-D5nUGm-c.d.ts → postgrest-D84p5dbA.d.ts} +12 -7
  212. package/dist/{powersync-CBhTBhG2.js → powersync-9PYOE1wt.js} +158 -21
  213. package/dist/{powersync-DAfo0EL5.js → powersync-DStC_g0B.js} +3 -3
  214. package/dist/powersync-xNRlC4jN.js +1 -0
  215. package/dist/preset/index.js +1 -1
  216. package/dist/{preset-BjLzeFpp.js → preset-pPrVyGU5.js} +74 -7
  217. package/dist/prisma/index.d.ts +2 -2
  218. package/dist/prisma/index.js +1 -1
  219. package/dist/{protected-action-QEA8arRB.js → protected-action-B40tU3yP.js} +15 -5
  220. package/dist/{protected-action-D8x73IGm.d.ts → protected-action-Ds_EUY8B.d.ts} +14 -7
  221. package/dist/{protected-action-DUYqb-Ma.js → protected-action-OpOxtTsN.js} +1 -1
  222. package/dist/{provider-C55OGXJ7.js → provider-CY4TSSJo.js} +2 -2
  223. package/dist/{provider-DfLeek9O.d.ts → provider-OtnIiFWm.d.ts} +1 -1
  224. package/dist/{provider-store-CaTv00tr.js → provider-store-BQP_pp8s.js} +2 -2
  225. package/dist/{pull-CQCGy1gv.js → pull-DLP4I1Kl.js} +7 -7
  226. package/dist/pull-UBjDnf4b.js +1 -0
  227. package/dist/{push-Dq_ca4-j.js → push-BSb8j1EW.js} +8 -8
  228. package/dist/{pushed-policy-CDuOL2de.js → pushed-policy-BecMsTtM.js} +1 -1
  229. package/dist/{pushed-policy-CryQheKq.d.ts → pushed-policy-Ck3FZcoy.d.ts} +1 -1
  230. package/dist/react/index.d.ts +8 -8
  231. package/dist/react/index.js +6 -6
  232. package/dist/react/provider-client.d.ts +1 -1
  233. package/dist/react/provider-client.js +1 -1
  234. package/dist/react-native/index.d.ts +104 -39
  235. package/dist/react-native/index.js +199 -40
  236. package/dist/refresh-on-L9UOwATg.d.ts +49 -0
  237. package/dist/{replay-Bs9Df2fQ.d.ts → replay-E5X9E1lC.d.ts} +1 -1
  238. package/dist/{request-context-Duzdf0cd.js → request-context-DM6_jY1n.js} +2 -2
  239. package/dist/{request-schema-DhX7UbfQ.js → request-schema-CMP8Cmxd.js} +5 -0
  240. package/dist/resend/index.d.ts +4 -4
  241. package/dist/{resolve-names-Y1Cb22cp.js → resolve-names-CBl4r4_r.js} +6 -6
  242. package/dist/{rls-tHu7N_Pe.js → rls-DGBL-jDY.js} +20 -20
  243. package/dist/{rls-C5ZGzR_B.js → rls-pAHGYgTb.js} +4 -4
  244. package/dist/{role-builder-BK2-T6oD.js → role-builder-CMW4wWzn.js} +3 -157
  245. package/dist/{rpc-vHIwyXCp.js → rpc-KwX_Jcxz.js} +2 -2
  246. package/dist/{run-DUq1xU4K.js → run-B7lv3NuK.js} +8 -40
  247. package/dist/run-UPbacxPg.js +1 -0
  248. package/dist/{run-ticket-DfnZCh-u.js → run-ticket-CjvXr6wj.js} +1 -1
  249. package/dist/{run-ticket-ylovhyFQ.d.ts → run-ticket-DPaD27_r.d.ts} +2 -2
  250. package/dist/{runtime-BGnrOkVH.js → runtime-rf0ZuyF3.js} +1 -1
  251. package/dist/{saas-DK4V-3Is.js → saas-B8H1MsQ3.js} +13 -10
  252. package/dist/{scan-C3HRH9Fs.js → scan-0r3OZqqK.js} +1 -1
  253. package/dist/{schema-DvXvxPhQ.js → schema-B_9tXrbG.js} +1 -1
  254. package/dist/{schema-BOJjqlWL.js → schema-CuX70xgH.js} +15 -2
  255. package/dist/scim/index.d.ts +1 -1
  256. package/dist/scim/index.js +1 -1
  257. package/dist/{scim-jJBJ7g1Z.js → scim-C30QBBoF.js} +2 -1
  258. package/dist/{scim-D8YupzX1.js → scim-CovliQUg.js} +2 -2
  259. package/dist/{scopes-0Up_UA2t.js → scopes-BSdYaGHs.js} +9 -40
  260. package/dist/server/index.d.ts +11 -11
  261. package/dist/server/index.js +8 -8
  262. package/dist/{server-3cVlTLde.js → server-D0PW6ZCw.js} +2 -2
  263. package/dist/{server-types-CyRN0-Cd.d.ts → server-types-3OnXjZ2D.d.ts} +8 -8
  264. package/dist/{shared-l0oGGetg.js → shared-BRmCJxDK.js} +2 -2
  265. package/dist/{shared-DrGLwM3s.js → shared-DyYVEjKC.js} +2 -2
  266. package/dist/{sink-B5zoUW_O.d.ts → sink-ogbVkyeo.d.ts} +2 -2
  267. package/dist/{skills-Celu2W6v.js → skills-B4MPRxQd.js} +2 -2
  268. package/dist/{skills-B2qTbaQa.js → skills-C9sTD70r.js} +2 -2
  269. package/dist/{snapshot-CXlzi69u.js → snapshot-DN_8J27z.js} +6 -2
  270. package/dist/{snapshot-cache-BjAWkchD.d.ts → snapshot-cache-B4YvlGG_.d.ts} +20 -6
  271. package/dist/{snapshot-cache-Bx_4xC_6.js → snapshot-cache-B66h7FBK.js} +25 -8
  272. package/dist/solid/index.d.ts +7 -7
  273. package/dist/solid/index.js +6 -6
  274. package/dist/solid-start/index.d.ts +4 -4
  275. package/dist/solid-start/index.js +3 -3
  276. package/dist/{sources-oB1Hg1Fm.d.ts → sources-xdQShLDU.d.ts} +1 -1
  277. package/dist/{src-C_pi2Rnh.js → src-Brzq_0in.js} +193 -128
  278. package/dist/ssf/index.d.ts +3 -3
  279. package/dist/ssf/index.js +1 -1
  280. package/dist/{standard-webhooks-DOYEuOLx.d.ts → standard-webhooks-BfPaZ6T1.d.ts} +2 -2
  281. package/dist/{types-tQB2CEnY.d.ts → store-DYeB-_U3.d.ts} +114 -113
  282. package/dist/{store-RNFvaJJv.js → store-DmVqy74I.js} +13 -7
  283. package/dist/{store-options-Dil3lraY.js → store-options--zWn48PK.js} +76 -7
  284. package/dist/{stores-DxZWDXCs.js → stores-BYFopOm1.js} +3 -3
  285. package/dist/{stores-DZJvxFIZ.d.ts → stores-EPul_8MN.d.ts} +5 -6
  286. package/dist/{stream-9y9qw51m.d.ts → stream-W2RuUYly.d.ts} +1 -1
  287. package/dist/{subject-BGoM5o8B.js → subject-C7RddW0G.js} +8 -1
  288. package/dist/supabase/client.d.ts +2 -0
  289. package/dist/supabase/client.js +21 -0
  290. package/dist/supabase/index.d.ts +37 -6
  291. package/dist/supabase/index.js +6 -5
  292. package/dist/supabase/middleware.d.ts +8 -7
  293. package/dist/supabase/middleware.js +6 -6
  294. package/dist/{supabase-CDHMsDD0.js → supabase-BiViJpQ4.js} +31 -8
  295. package/dist/{supabase-DYWnT800.js → supabase-CogTyJH2.js} +3 -3
  296. package/dist/supabase-hook-BN46IrVI.js +1 -0
  297. package/dist/{supabase-hook-HPgwYb9V.js → supabase-hook-DX38Hj8h.js} +393 -32
  298. package/dist/{supautils-SwE642N1.js → supautils-BGf6zRvM.js} +12 -12
  299. package/dist/svelte/index.d.ts +7 -7
  300. package/dist/svelte/index.js +8 -8
  301. package/dist/svelte/runtime.d.ts +3 -3
  302. package/dist/svelte/runtime.js +3 -3
  303. package/dist/svelte/source.d.ts +7 -7
  304. package/dist/svelte/source.js +5 -5
  305. package/dist/sveltekit/index.d.ts +4 -4
  306. package/dist/sveltekit/index.js +2 -2
  307. package/dist/{tables-DimBcVWY.js → tables-BfOk0ymL.js} +7 -7
  308. package/dist/tanstack-start/index.d.ts +4 -4
  309. package/dist/tanstack-start/index.js +2 -2
  310. package/dist/{tenancy-5d1zVBvK.js → tenancy-DvOHHk3-.js} +1 -1
  311. package/dist/terminal/index.d.ts +5 -5
  312. package/dist/terminal/index.js +6 -6
  313. package/dist/testing/core.d.ts +1 -1
  314. package/dist/testing/core.js +1 -1
  315. package/dist/testing/fixtures/index.d.ts +1 -1
  316. package/dist/testing/fixtures/index.js +2 -2
  317. package/dist/testing/index.d.ts +29 -22
  318. package/dist/testing/index.js +120 -48
  319. package/dist/testing/saas/index.d.ts +3 -3
  320. package/dist/testing/saas/index.js +2 -2
  321. package/dist/testing/saas/permissions.js +1 -1
  322. package/dist/token-D6pWn8Uj.d.ts +11 -0
  323. package/dist/{token-DC9EQiet.js → token-DaMnIU9O.js} +24 -8
  324. package/dist/{tool-refusal-Qpjs_W6M.js → tool-refusal-D4spOJ7I.js} +1 -1
  325. package/dist/trpc/index.d.ts +5 -5
  326. package/dist/trpc/index.js +3 -3
  327. package/dist/{type-helpers-c7Xo_2Cu.d.ts → type-helpers-i1EJ3Eb1.d.ts} +1 -1
  328. package/dist/{types-Cklw5hJo.d.ts → types-3Y8UpFkF.d.ts} +40 -1
  329. package/dist/{types-DlelvQk4.d.ts → types-B8qUkGja.d.ts} +2 -2
  330. package/dist/{types-CN0LsqbK.d.ts → types-CCEeSCMB.d.ts} +3 -3
  331. package/dist/{types-B2efzoSX.d.ts → types-CDVXR6YD.d.ts} +1 -1
  332. package/dist/{types-DsHGPtkR.d.ts → types-Ck1KOfug.d.ts} +2 -2
  333. package/dist/{types-DLvhVm1r.d.ts → types-CqcsNCaN.d.ts} +16 -7
  334. package/dist/{types-BB-zWDcR.d.ts → types-D-JO7lh8.d.ts} +5 -5
  335. package/dist/{types-CEinc15V.d.ts → types-D19MK4t-.d.ts} +3 -4
  336. package/dist/{types-B6ExllNo.d.ts → types-DGf_cpKF.d.ts} +2 -2
  337. package/dist/{types-rCRV4Ge-.d.ts → types-DmbfLu2p.d.ts} +4 -4
  338. package/dist/{types-ZzRGoViD.d.ts → types-NYoj8JBm.d.ts} +2 -2
  339. package/dist/{types-CWBsAwqn.d.ts → types-o1vu6Ks3.d.ts} +4 -4
  340. package/dist/unplugin/index.d.ts +1 -1
  341. package/dist/unplugin/index.js +2 -2
  342. package/dist/usage-Cl5eb-e1.js +1 -0
  343. package/dist/{usage-CPXeuAdT.js → usage-DC0UKe6C.js} +6 -6
  344. package/dist/{usage-CfZCQd0F.js → usage-DYtRVkcN.js} +2 -2
  345. package/dist/{validation-error-uvp-kyfO.d.ts → validation-error-Dx8PipbO.d.ts} +1 -1
  346. package/dist/{verify-DfT0QYNh.js → verify-Bpj0hauG.js} +19 -19
  347. package/dist/{version-cache-Df11C2Qp.d.ts → version-cache-DzNKWiI6.d.ts} +9 -3
  348. package/dist/{views-CD8wuL4Z.js → views-MWmJ6Y4P.js} +1 -1
  349. package/dist/vue/index.d.ts +7 -7
  350. package/dist/vue/index.js +6 -6
  351. package/dist/{waiter-CqUKX6CY.d.ts → waiter-NK_UuZbb.d.ts} +2 -2
  352. package/dist/{watch-DAkjm75Y.js → watch-CBHADqBH.js} +3 -3
  353. package/dist/watch-OYwAPCzx.js +1 -0
  354. package/dist/webmcp/index.d.ts +1 -1
  355. package/dist/webmcp/index.js +1 -1
  356. package/dist/{where-scope-DlCdCM_8.js → where-scope-BKrqUDVk.js} +5 -5
  357. package/dist/{who-can-BoDJm0Nc.js → who-can-KhVWMxtf.js} +4 -4
  358. package/dist/workflow/index.d.ts +3 -3
  359. package/dist/workflow/index.js +5 -4
  360. package/dist/workflow-sdk/index.d.ts +4 -4
  361. package/dist/{wrap-DxXB54Wu.d.ts → wrap-BHGA-SMM.d.ts} +2 -2
  362. package/dist/{wrap-B2wziJI_.js → wrap-C5PWzgkq.js} +1 -1
  363. package/package.json +8 -5
  364. package/schemas/approval-request-v1.json +5 -0
  365. package/schemas/catalog-v1.json +18 -2
  366. package/schemas/cli-result-v1.json +0 -2
  367. package/schemas/snapshot-v1.json +9 -0
  368. package/schemas/supabase-manifest-v1.json +1 -1
  369. package/skills/permdock-approvals/SKILL.md +8 -8
  370. package/skills/permdock-approvals/references/stores-and-resume.md +7 -3
  371. package/skills/permdock-audit/SKILL.md +1 -1
  372. package/skills/permdock-wire/references/adapters.md +3 -1
  373. package/dist/action-result-BcudBQOF.d.ts +0 -19
  374. package/dist/catalog-D3oS2GH3.js +0 -1
  375. package/dist/collect-D-eroIfV.js +0 -1
  376. package/dist/load-Dm0pSYH3.js +0 -1
  377. package/dist/output-files-BHOIlrfD.js +0 -1
  378. package/dist/powersync-0QVP_DuR.js +0 -1
  379. package/dist/pull-CCAChKuy.js +0 -1
  380. package/dist/renames-CGj7YwcQ.js +0 -175
  381. package/dist/run-C5P3x1EI.js +0 -1
  382. package/dist/supabase-hook-qsewAVZY.js +0 -1
  383. package/dist/usage-DmmO_xjJ.js +0 -1
  384. package/dist/watch-CuPz0D2M.js +0 -1
@@ -2,13 +2,13 @@ import { r as isRecord, t as compact } from "./compact-CAf557ZB.js";
2
2
  import { d as isoNow, i as dateAt, p as nowSeconds, u as isoAt } from "./time-nR1JesoH.js";
3
3
  import { t as canonicalJson } from "./canonical-json-DwilZ1iB.js";
4
4
  import { s as ApprovalError } from "./types-CcUXciSj.js";
5
- import { c as decodeApprovalCursor, l as encodeApprovalCursor, s as approvalPageSize, t as applyApprovalVerdict } from "./store-RNFvaJJv.js";
6
- import { a as parseCapability } from "./capability-BqX94r07.js";
5
+ import { c as decodeApprovalCursor, l as encodeApprovalCursor, s as approvalPageSize, t as applyApprovalVerdict } from "./store-DmVqy74I.js";
6
+ import { a as parseCapability } from "./capability-zN6T9fxe.js";
7
7
  import { t as loadJose } from "./load-jose-DZ4dnjri.js";
8
- import "./budget-BELja5A9.js";
8
+ import "./budget-BBCPDOGP.js";
9
9
  import { a as quoteQualifiedTable, c as quoteSqlTable, d as sqlTextArray, i as qualifySqlTable, o as quoteSqlIdent, s as quoteSqlLiteral } from "./sql-0WjxIp9g.js";
10
10
  import { d as keptKeys, l as roleColumn } from "./sources-C4vkzZJV.js";
11
- import { t as callRpc } from "./postgrest-DAxFltvO.js";
11
+ import { t as callRpc } from "./postgrest-BrjrckDG.js";
12
12
  //#region src/supabase/capability.ts
13
13
  const DEFAULT_TTL = 300;
14
14
  const MAX_TTL = 3600;
@@ -96,8 +96,6 @@ function checkMembership(item, path, issues) {
96
96
  for (const key of [
97
97
  "scope",
98
98
  "id",
99
- "tenant",
100
- "team",
101
99
  "via",
102
100
  "granted_by",
103
101
  "reason"
@@ -110,7 +108,7 @@ function checkMembership(item, path, issues) {
110
108
  optional(item, "entitlements", path, issues, isStrings, "an array of strings");
111
109
  optional(item, "keep", path, issues, isStrings, "an array of strings");
112
110
  optional(item, "grants", path, issues, isRecord, "an object");
113
- if (!(own(item, "scope") !== void 0 && own(item, "id") !== void 0 || own(item, "tenant") !== void 0 || own(item, "team") !== void 0 || own(item, "on") !== void 0)) issue(issues, path, "Expected scope and id, tenant, team or on");
111
+ if (!(own(item, "scope") !== void 0 && own(item, "id") !== void 0 || own(item, "on") !== void 0)) issue(issues, path, "Expected scope and id, or on");
114
112
  }
115
113
  function checkPermDockClaims(record, tenantClaim, path, issues) {
116
114
  optional(record, "user_role", path, issues, (value) => value === null || typeof value === "string" || isStrings(value), "a string, an array of strings or null");
@@ -341,6 +339,31 @@ function supabaseApprovalStore(client, options = {}) {
341
339
  };
342
340
  }
343
341
  //#endregion
342
+ //#region src/supabase/approval-policies.ts
343
+ function rowsOf$1(result) {
344
+ return Array.isArray(result) ? result : result.rows;
345
+ }
346
+ /**
347
+ * Approval policies from the table `rls.approvals.tenantPolicies` generates:
348
+ * the subject's tenants' enabled rows and every platform floor. A row whose
349
+ * body is not an object throws, and the evaluator checks every entry with
350
+ * `validateApprovalPolicy`, so a bad row denies every call an allow would grant
351
+ * until it is fixed.
352
+ */
353
+ function tableApprovalPolicySource(options) {
354
+ const fn = quoteQualifiedTable(`${options.schema ?? "permdock"}.permdock_approval_policies_for`);
355
+ return {
356
+ name: "table",
357
+ async approvalPoliciesFor(query) {
358
+ return rowsOf$1(await options.query(`select p.body from ${fn}($1::text[]) p(body)`, [[...query.tenants]])).map((row) => {
359
+ const body = row["body"];
360
+ if (!isRecord(body)) throw new TypeError("PermDock: an approval_policies row has a body that is not an object");
361
+ return body;
362
+ });
363
+ }
364
+ };
365
+ }
366
+ //#endregion
344
367
  //#region src/supabase/approval-delegations.ts
345
368
  function rowsOf(result) {
346
369
  return Array.isArray(result) ? result : result.rows;
@@ -697,4 +720,4 @@ grant execute on function ${signature} to authenticated;
697
720
  `;
698
721
  }
699
722
  //#endregion
700
- export { supabaseClaims as a, supabaseApprovalStore as i, supabaseRls as n, exchangeCapability as o, tableApprovalDelegationSource as r, authorizeSql as t };
723
+ export { supabaseApprovalStore as a, tableApprovalPolicySource as i, supabaseRls as n, supabaseClaims as o, tableApprovalDelegationSource as r, exchangeCapability as s, authorizeSql as t };
@@ -1,5 +1,5 @@
1
1
  import { t as defineLeaf } from "./command-L8EstFNm.js";
2
- import { c as given, n as dbUrl, o as fileOut, r as dbUrlFlags, t as checkFlag } from "./flags-DXjoTVbS.js";
2
+ import { c as given, n as dbUrl, o as fileOut, r as dbUrlFlags, t as checkFlag } from "./flags-BlmpmXoY.js";
3
3
  //#region src/cli/commands/supabase.ts
4
4
  const hookGenerate = defineLeaf({
5
5
  flags: {
@@ -47,7 +47,7 @@ const hookGenerate = defineLeaf({
47
47
  const budget = given(flags.budget);
48
48
  const schema = given(flags.schema);
49
49
  const grantsOut = given(flags["grants-out"]);
50
- const { runSupabase } = await import("./supabase-hook-qsewAVZY.js");
50
+ const { runSupabase } = await import("./supabase-hook-BN46IrVI.js");
51
51
  return runSupabase({
52
52
  cwd: ctx.cwd,
53
53
  config: ctx.config,
@@ -76,7 +76,7 @@ const inspect = defineLeaf({
76
76
  },
77
77
  async run(ctx, { flags }) {
78
78
  const out = flags.out === "" ? true : flags.out === "-" ? void 0 : flags.out;
79
- const { runSupabase } = await import("./supabase-hook-qsewAVZY.js");
79
+ const { runSupabase } = await import("./supabase-hook-BN46IrVI.js");
80
80
  return runSupabase({
81
81
  cwd: ctx.cwd,
82
82
  config: ctx.config,
@@ -0,0 +1 @@
1
+ export { i as runSupabase } from "./supabase-hook-DX38Hj8h.js";
@@ -1,30 +1,31 @@
1
1
  import { r as isRecord } from "./compact-CAf557ZB.js";
2
2
  import { o as hasConditionOp } from "./refs-C8BKxc_e.js";
3
- import { f as scopeList, l as rootScope, s as resolveScope, u as scopeChain } from "./scopes-0Up_UA2t.js";
4
- import { t as APPROVAL_REQUEST_SCHEMA } from "./request-schema-DhX7UbfQ.js";
5
- import { a as describeError, i as configError } from "./errors-Vpu6rKHl.js";
3
+ import { c as rootScope, d as scopeList, l as scopeChain, s as resolveScope } from "./scopes-BSdYaGHs.js";
4
+ import { t as APPROVAL_REQUEST_SCHEMA } from "./request-schema-CMP8Cmxd.js";
5
+ import { t as AUTHZ_EVENT } from "./authz-topic-Dbc-HDOS.js";
6
+ import { a as describeError, i as configError } from "./errors-BhRkoNS7.js";
6
7
  import { i as readJsonFile, o as sqlFiles, s as writeFileEnsuringDir } from "./files-BSjrtIHw.js";
7
8
  import { a as SUPABASE_MANIFEST_SCHEMA } from "./version-DMQ0dnN5.js";
8
- import { c as requirePolicy } from "./load-DjSU5KXO.js";
9
- import "./budget-BELja5A9.js";
9
+ import { c as requirePolicy } from "./load-BaEamml-.js";
10
+ import "./budget-BBCPDOGP.js";
10
11
  import { i as qualifySqlTable } from "./sql-0WjxIp9g.js";
11
- import { i as scopeColumn } from "./compile-EzEMB-7v.js";
12
- import { t as authorizeSql } from "./supabase-CDHMsDD0.js";
12
+ import { i as scopeColumn } from "./compile-B_oJqmIg.js";
13
+ import { t as authorizeSql } from "./supabase-BiViJpQ4.js";
13
14
  import { a as hookApiNames, d as keptKeys, t as AUTHZ_VERSION_TABLE, u as roleManifest } from "./sources-C4vkzZJV.js";
14
- import { o as readMemberships } from "./postgrest-DAxFltvO.js";
15
+ import { o as readMemberships } from "./postgrest-BrjrckDG.js";
15
16
  import { t as beforeFirst } from "./text-BMFRfBqc.js";
16
17
  import { n as GRANTS_MARKER, r as HOOK_MARKER, s as hookMarkerFields } from "./markers-BeHZ4x9Q.js";
17
18
  import { n as formatManifestJson, t as MANIFEST_FILE } from "./manifest-json-CAGzls-C.js";
18
19
  import { n as MIGRATION_DIRS } from "./constants-DcJABbLW.js";
19
- import { f as writeOutputFiles, l as partPath, r as driftOf, u as pgDeltaPath } from "./output-files-BIQ_9pIs.js";
20
- import { A as quoteQualified, D as qualified, F as firstScopeType, I as scopeTypeOf, O as quoteIdent, R as tenantTypeOf, a as customRolesOn, j as quoteTable, k as quoteLiteral, l as USER_ID_HELPER, r as HELPERS, y as subjectIdSql } from "./shared-DrGLwM3s.js";
21
- import { E as TOKEN_SCOPE_ALLOWS, J as apiKeyFields, K as API_KEY_ALLOWS, R as globalRoleSource, _ as PERMISSION_HELPERS, at as memberForHelper, b as permissionKeysForHelper, bt as checkSuspension, ct as memberIdsHelper, dt as permittedForHelper, et as hasMemberFor, ft as permittedIdsHelper, g as OWNERSHIP, h as ASSIGNMENTS, lt as memberOfHelper, ot as memberForSources, rt as isTeamScope, st as memberForTable, tt as hasPermittedUsers, ut as memberRoleOf, v as checkName, vt as activeRowSql, x as permittedByPermissionHelper } from "./tables-DimBcVWY.js";
22
- import { a as guardedTables, t as ownershipRules, u as roleNames } from "./ownership-qqBuGJXr.js";
20
+ import { f as writeOutputFiles, l as partPath, r as driftOf, u as pgDeltaPath } from "./output-files-CM0BnH05.js";
21
+ import { A as quoteQualified, D as qualified, F as firstScopeType, I as scopeTypeOf, O as quoteIdent, R as tenantTypeOf, a as customRolesOn, j as quoteTable, k as quoteLiteral, l as USER_ID_HELPER, r as HELPERS, y as subjectIdSql } from "./shared-DyYVEjKC.js";
22
+ import { E as TOKEN_SCOPE_ALLOWS, J as apiKeyFields, K as API_KEY_ALLOWS, R as globalRoleSource, _ as PERMISSION_HELPERS, at as memberForHelper, b as permissionKeysForHelper, bt as checkSuspension, ct as memberIdsHelper, dt as permittedForHelper, et as hasMemberFor, ft as permittedIdsHelper, g as OWNERSHIP, h as ASSIGNMENTS, lt as memberOfHelper, ot as memberForSources, rt as isTeamScope, st as memberForTable, tt as hasPermittedUsers, ut as memberRoleOf, v as checkName, vt as activeRowSql, x as permittedByPermissionHelper } from "./tables-BfOk0ymL.js";
23
+ import { a as guardedTables, t as ownershipRules, u as roleNames } from "./ownership-D-mIt-w0.js";
23
24
  import { t as membershipSourcesOf } from "./sources-qoIJQrJv.js";
24
25
  import { a as splitUndiffed, r as tableKey, t as decidingColumns } from "./deciding-columns-NB4wcyBf.js";
25
- import { n as pgConnector } from "./pg-DQTqRrou.js";
26
- import { c as ACTOR_MAY_WRITE, f as readOnlyActorKinds } from "./fields-DI8s3cPl.js";
27
- import { r as permittedUsersHelper, t as resolveNames } from "./resolve-names-Y1Cb22cp.js";
26
+ import { n as pgConnector } from "./pg-Ddxsd5ZB.js";
27
+ import { c as ACTOR_MAY_WRITE, f as readOnlyActorKinds } from "./fields-CrjL6A49.js";
28
+ import { r as permittedUsersHelper, t as resolveNames } from "./resolve-names-CBl4r4_r.js";
28
29
  import { existsSync, readFileSync, readdirSync } from "node:fs";
29
30
  import { dirname, join, posix, resolve } from "node:path";
30
31
  //#region ../../node_modules/.pnpm/smol-toml@1.9.1/node_modules/smol-toml/dist/error.js
@@ -1885,6 +1886,246 @@ function customRolesOfSql(parts) {
1885
1886
  );`;
1886
1887
  }
1887
1888
  //#endregion
1889
+ //#region src/cli/rls/approval-managers.ts
1890
+ /** Whether the signed-in user manages a requester; better-supabase reads it. */
1891
+ const MANAGES = "permdock_manages";
1892
+ /**
1893
+ * The approver check with `manager` leaves; only `permdock_is_approver` calls
1894
+ * it.
1895
+ */
1896
+ const APPROVES = "permdock_approves";
1897
+ const MANAGES_FOR = "permdock_manages_for";
1898
+ function named(value) {
1899
+ return typeof value === "string" && value !== "";
1900
+ }
1901
+ function checked(managers) {
1902
+ if (typeof managers !== "object" || managers === null || !("table" in managers && named(managers.table)) || !("user" in managers && named(managers.user)) || !("manager" in managers && named(managers.manager))) throw configError("PermDock CLI: rls.approvals.managers needs { table, user, manager }: the table that names each user's manager, its user column and its manager column");
1903
+ return {
1904
+ table: managers.table,
1905
+ user: managers.user,
1906
+ manager: managers.manager
1907
+ };
1908
+ }
1909
+ /**
1910
+ * `rls.approvals.managers`: `permdock_manages(p_requester, p_levels)` walks the
1911
+ * app's manager table up to `levels` steps (at most `MAX_MANAGER_LEVELS`) with
1912
+ * a cycle guard, and `permdock_approves` decides `manager` leaves with it and
1913
+ * every other leaf through the two-argument `permdock_is_approver`. The
1914
+ * requester never manages themselves into an approval. Without `delegations`,
1915
+ * the four-argument `permdock_is_approver` is written here; with them,
1916
+ * `approvalDelegationsSql` writes it and calls `permdock_approves` first.
1917
+ */
1918
+ function approvalManagersSql(ctx, given, isApprover, delegations) {
1919
+ const managers = checked(given);
1920
+ const table = quoteQualified(managers.table);
1921
+ const user = quoteIdent(managers.user);
1922
+ const boss = quoteIdent(managers.manager);
1923
+ const manages = qualified(ctx, MANAGES);
1924
+ const managesFor = qualified(ctx, MANAGES_FOR);
1925
+ const approves = qualified(ctx, APPROVES);
1926
+ const me = `${subjectIdSql(ctx)}::text`;
1927
+ const entry = delegations ? "" : `
1928
+ -- approvers with managers: permdock_approves for the signed-in user
1929
+ create or replace function ${isApprover}(p_approvers jsonb, p_tenant text, p_requester text, p_resource text)
1930
+ returns boolean
1931
+ language sql
1932
+ stable
1933
+ security definer
1934
+ set search_path = ''
1935
+ as $$
1936
+ select ${approves}(p_approvers, p_tenant, p_requester)
1937
+ $$;
1938
+ revoke execute on function ${isApprover}(jsonb, text, text, text) from public, anon;
1939
+ grant execute on function ${isApprover}(jsonb, text, text, text) to authenticated;
1940
+ `;
1941
+ return `
1942
+ -- approval managers: whether p_user manages p_requester within p_levels steps of ${managers.table}
1943
+ create or replace function ${managesFor}(p_user text, p_requester text, p_levels integer)
1944
+ returns boolean
1945
+ language sql
1946
+ stable
1947
+ security definer
1948
+ set search_path = ''
1949
+ as $$
1950
+ with recursive chain (id, depth, path) as (
1951
+ select m.${boss}::text, 1, array[p_requester, m.${boss}::text]
1952
+ from ${table} m
1953
+ where m.${user}::text = p_requester
1954
+ and m.${boss} is not null
1955
+ union all
1956
+ select m.${boss}::text, c.depth + 1, c.path || m.${boss}::text
1957
+ from chain c
1958
+ join ${table} m on m.${user}::text = c.id
1959
+ where c.depth < least(p_levels, ${String(8)})
1960
+ and m.${boss} is not null
1961
+ and not (m.${boss}::text = any (c.path))
1962
+ )
1963
+ select coalesce(
1964
+ p_requester <> ''
1965
+ and p_user <> ''
1966
+ and p_levels between 1 and ${String(8)}
1967
+ and p_user <> p_requester
1968
+ and exists (select 1 from chain c where c.id = p_user),
1969
+ false
1970
+ )
1971
+ $$;
1972
+ revoke execute on function ${managesFor}(text, text, integer) from public, anon, authenticated;
1973
+
1974
+ -- approval managers: whether the signed-in user manages p_requester within p_levels steps of ${managers.table}
1975
+ create or replace function ${manages}(p_requester text, p_levels integer)
1976
+ returns boolean
1977
+ language sql
1978
+ stable
1979
+ security definer
1980
+ set search_path = ''
1981
+ as $$
1982
+ select ${managesFor}(${me}, p_requester, p_levels)
1983
+ $$;
1984
+ revoke execute on function ${manages}(text, integer) from public, anon, authenticated;
1985
+
1986
+ -- approval managers: approvers.by with manager leaves; only permdock_is_approver calls it
1987
+ create or replace function ${approves}(p_approvers jsonb, p_tenant text, p_requester text)
1988
+ returns boolean
1989
+ language plpgsql
1990
+ stable
1991
+ security definer
1992
+ set search_path = ''
1993
+ as $$
1994
+ declare
1995
+ v_item jsonb;
1996
+ v_levels jsonb;
1997
+ begin
1998
+ if p_approvers is null then
1999
+ return false;
2000
+ end if;
2001
+ if jsonb_typeof(p_approvers) = 'array' then
2002
+ if jsonb_array_length(p_approvers) = 0 then
2003
+ return false;
2004
+ end if;
2005
+ for v_item in select value from jsonb_array_elements(p_approvers) loop
2006
+ if not ${approves}(v_item, p_tenant, p_requester) then
2007
+ return false;
2008
+ end if;
2009
+ end loop;
2010
+ return true;
2011
+ end if;
2012
+ if jsonb_typeof(p_approvers) <> 'object' then
2013
+ return false;
2014
+ end if;
2015
+ case p_approvers ->> 'kind'
2016
+ when 'manager' then
2017
+ v_levels := coalesce(p_approvers -> 'levels', '1'::jsonb);
2018
+ if jsonb_typeof(v_levels) <> 'number' or v_levels::text !~ '^[0-9]{1,2}$' then
2019
+ return false;
2020
+ end if;
2021
+ return coalesce(${manages}(p_requester, v_levels::text::integer), false);
2022
+ when 'any-of' then
2023
+ if jsonb_typeof(p_approvers -> 'of') <> 'array' then
2024
+ return false;
2025
+ end if;
2026
+ for v_item in select value from jsonb_array_elements(p_approvers -> 'of') loop
2027
+ if ${approves}(v_item, p_tenant, p_requester) then
2028
+ return true;
2029
+ end if;
2030
+ end loop;
2031
+ return false;
2032
+ else
2033
+ return ${isApprover}(p_approvers, p_tenant);
2034
+ end case;
2035
+ end;
2036
+ $$;
2037
+ revoke execute on function ${approves}(jsonb, text, text) from public, anon, authenticated;
2038
+ ${entry}`;
2039
+ }
2040
+ //#endregion
2041
+ //#region src/cli/rls/approval-policies.ts
2042
+ /**
2043
+ * The objects `rls.approvals.tenantPolicies` adds; `tableApprovalPolicySource`
2044
+ * calls the function.
2045
+ */
2046
+ const APPROVAL_POLICIES = {
2047
+ table: "approval_policies",
2048
+ read: "permdock_approval_policies_for"
2049
+ };
2050
+ const KEY = /^[A-Za-z][\w-]*(?:\.[A-Za-z][\w-]*)+$/u;
2051
+ /**
2052
+ * `rls.approvals.tenantPolicies`: one table of `ApprovalPolicy` bodies, a
2053
+ * tenant row per requirement a tenant adds and platform floors with `tenant`
2054
+ * null. Members read their tenants' rows and the floors; a holder of `manage`
2055
+ * in a tenant writes that tenant's rows; nobody but the owner writes a floor.
2056
+ * `permdock_approval_policies_for(p_tenants)` answers the enabled bodies with
2057
+ * the row's tenant set, floors first, and only the owner may execute it, since
2058
+ * it reads every tenant.
2059
+ */
2060
+ function approvalPoliciesSql(ctx, options, actorMayWrite = false) {
2061
+ if (options === null || typeof options !== "object" || !("manage" in options) || typeof options.manage !== "string" || !KEY.test(options.manage)) throw configError("PermDock CLI: rls.approvals.tenantPolicies needs { manage: '<permission key>' }, the permission whose holders in a tenant edit its approval policies");
2062
+ const root = ctx.scopes[0]?.name;
2063
+ if (root === void 0) throw configError("PermDock CLI: rls.approvals.tenantPolicies needs a tenant scope; declare one in the policy's scopes");
2064
+ const table = qualified(ctx, APPROVAL_POLICIES.table);
2065
+ const fn = qualified(ctx, APPROVAL_POLICIES.read);
2066
+ const member = `tenant in (select m.id::text from ${qualified(ctx, memberIdsHelper(root))}() m(id))`;
2067
+ const manages = `exists (
2068
+ select 1
2069
+ from ${qualified(ctx, checkName(permittedByPermissionHelper(root)))}(${quoteLiteral(options.manage)}) i(id)
2070
+ where i.id::text = tenant
2071
+ )`;
2072
+ const writable = actorMayWrite ? ` and (select ${qualified(ctx, ACTOR_MAY_WRITE)}())` : "";
2073
+ const own = `tenant is not null and ${subjectIdSql(ctx)} is not null and ${manages}${writable}`;
2074
+ const policy = (name) => quoteIdent(`${APPROVAL_POLICIES.table}_${name}`);
2075
+ return `
2076
+ -- approval policies: requirements a tenant keeps as data, plus platform floors (tenant null); tableApprovalPolicySource reads them
2077
+ create table if not exists ${table} (
2078
+ id text primary key default gen_random_uuid()::text,
2079
+ tenant text,
2080
+ name text not null,
2081
+ body jsonb not null,
2082
+ enabled boolean not null default true,
2083
+ created_at timestamptz not null default now(),
2084
+ updated_at timestamptz not null default now(),
2085
+ constraint ${quoteIdent(`${APPROVAL_POLICIES.table}_body`)} check (jsonb_typeof(body) = 'object' and body ? 'approval')
2086
+ );
2087
+ create index if not exists ${quoteIdent(`${APPROVAL_POLICIES.table}_tenant`)} on ${table} (tenant);
2088
+ alter table ${table} enable row level security;
2089
+ revoke all on table ${table} from anon, public;
2090
+ grant select, insert, update, delete on table ${table} to authenticated;
2091
+ drop policy if exists ${policy("read")} on ${table};
2092
+ create policy ${policy("read")} on ${table}
2093
+ for select to authenticated
2094
+ using (tenant is null or ${member});
2095
+ drop policy if exists ${policy("insert")} on ${table};
2096
+ create policy ${policy("insert")} on ${table}
2097
+ for insert to authenticated
2098
+ with check (${own});
2099
+ drop policy if exists ${policy("update")} on ${table};
2100
+ create policy ${policy("update")} on ${table}
2101
+ for update to authenticated
2102
+ using (${own})
2103
+ with check (${own});
2104
+ drop policy if exists ${policy("delete")} on ${table};
2105
+ create policy ${policy("delete")} on ${table}
2106
+ for delete to authenticated
2107
+ using (${own});
2108
+
2109
+ -- approval policies: the enabled bodies for p_tenants and every floor, with the row's tenant; only the owner executes it
2110
+ create or replace function ${fn}(p_tenants text[])
2111
+ returns setof jsonb
2112
+ language sql
2113
+ stable
2114
+ set search_path = ''
2115
+ as $$
2116
+ select case
2117
+ when p.tenant is null then p.body - 'tenant'
2118
+ else p.body || jsonb_build_object('tenant', p.tenant)
2119
+ end
2120
+ from ${table} p
2121
+ where p.enabled
2122
+ and (p.tenant is null or p.tenant = any(coalesce(p_tenants, '{}')))
2123
+ order by p.tenant nulls first, p.created_at, p.id;
2124
+ $$;
2125
+ revoke execute on function ${fn}(text[]) from public, anon, authenticated;
2126
+ `;
2127
+ }
2128
+ //#endregion
1888
2129
  //#region src/cli/rls/approvals.ts
1889
2130
  /**
1890
2131
  * `rls.approvals`' approver check; better-supabase's `isApprover` template
@@ -2188,17 +2429,30 @@ grant execute on function ${fn}(jsonb, text) to authenticated;
2188
2429
  }
2189
2430
  /**
2190
2431
  * Everything `rls.approvals` writes: the generated or adopted store, the
2191
- * approver check and, with `delegations: true`, the covers. With
2432
+ * approver check, with `managers` the manager walk, with `delegations: true`
2433
+ * the covers, and with `tenantPolicies` the tenant approval policies. With
2192
2434
  * `actorMayWrite`, the covers' write policies call
2193
2435
  * `permdock_actor_may_write()`.
2194
2436
  */
2195
2437
  function approvalsSql(ctx, approvals, jsonSchema, actorMayWrite = false) {
2196
2438
  if (approvals === void 0 || approvals === false) return;
2197
2439
  if (approvals === true) return approvalStoreSql(ctx, jsonSchema) + isApproverSql(ctx);
2198
- const { table, delegations } = approvals;
2440
+ const { table, delegations, tenantPolicies, managers } = approvals;
2199
2441
  if (delegations !== void 0 && typeof delegations !== "boolean") throw new TypeError("PermDock CLI: rls.approvals.delegations must be a boolean");
2442
+ if (approvals.store !== void 0 && typeof approvals.store !== "boolean") throw new TypeError("PermDock CLI: rls.approvals.store must be a boolean");
2200
2443
  let store;
2201
- if (table === void 0) {
2444
+ if (approvals.store === false) {
2445
+ const adopted = [
2446
+ "table",
2447
+ "token",
2448
+ "body",
2449
+ "open",
2450
+ "schema",
2451
+ "mirror"
2452
+ ].find((key) => approvals[key] !== void 0);
2453
+ if (adopted !== void 0) throw configError(`PermDock CLI: rls.approvals.${adopted} configures the approval store, which rls.approvals.store: false leaves out`);
2454
+ store = "";
2455
+ } else if (table === void 0) {
2202
2456
  const adoptOnly = [
2203
2457
  "token",
2204
2458
  "body",
@@ -2212,7 +2466,7 @@ function approvalsSql(ctx, approvals, jsonSchema, actorMayWrite = false) {
2212
2466
  ...approvals,
2213
2467
  table
2214
2468
  }, jsonSchema);
2215
- return store + isApproverSql(ctx) + (delegations === true ? approvalDelegationsSql(ctx, actorMayWrite) : "");
2469
+ return store + isApproverSql(ctx) + (managers === void 0 ? "" : approvalManagersSql(ctx, managers, qualified(ctx, APPROVAL_STORE.isApprover), delegations === true)) + (delegations === true ? approvalDelegationsSql(ctx, actorMayWrite, managers !== void 0) : "") + (delegations === true || managers !== void 0 ? requestApproversSql(ctx) : "") + (tenantPolicies === void 0 ? "" : approvalPoliciesSql(ctx, tenantPolicies, actorMayWrite));
2216
2470
  }
2217
2471
  /**
2218
2472
  * The objects `rls.approvals.delegations` adds; `tableApprovalDelegationSource`
@@ -2225,13 +2479,15 @@ const DELEGATIONS = {
2225
2479
  /**
2226
2480
  * `rls.approvals.delegations`: one table of out-of-office covers that a user
2227
2481
  * writes for themselves, and a four-argument `permdock_is_approver` that also
2228
- * answers for a delegate inside an active cover. One hop: a cover is checked
2482
+ * answers for a delegate inside an active cover. With `managers`, the signed-in
2483
+ * user's own check is `permdock_approves`, and a cover passes on a `manager`
2484
+ * leaf when the delegator manages the requester. One hop: a cover is checked
2229
2485
  * against the delegator's own approver rights, never the delegator's covers. A
2230
2486
  * delegator who is the requester never counts. A `holder()` approver through a
2231
2487
  * cover needs `rls.mode: "database"`, where the `_for` helpers exist; in `jwt`
2232
2488
  * mode only `user()` approvers pass.
2233
2489
  */
2234
- function approvalDelegationsSql(ctx, actorMayWrite = false) {
2490
+ function approvalDelegationsSql(ctx, actorMayWrite = false, managers = false) {
2235
2491
  const table = qualified(ctx, DELEGATIONS.table);
2236
2492
  const fn = qualified(ctx, APPROVAL_STORE.isApprover);
2237
2493
  const covers = qualified(ctx, DELEGATIONS.covers);
@@ -2248,7 +2504,15 @@ function approvalDelegationsSql(ctx, actorMayWrite = false) {
2248
2504
  where i.id::text = p_tenant
2249
2505
  )` : "false";
2250
2506
  const policy = (name) => quoteIdent(`${DELEGATIONS.table}_${name}`);
2251
- const mine = `delegator::text = ${me}${actorMayWrite ? ` and (select ${qualified(ctx, ACTOR_MAY_WRITE)}())` : ""}`;
2507
+ const writable = actorMayWrite ? ` and (select ${qualified(ctx, ACTOR_MAY_WRITE)}())` : "";
2508
+ const managerCase = managers ? `
2509
+ when 'manager' then
2510
+ v_levels := coalesce(p_approvers -> 'levels', '1'::jsonb);
2511
+ if jsonb_typeof(v_levels) <> 'number' or v_levels::text !~ '^[0-9]{1,2}$' then
2512
+ return false;
2513
+ end if;
2514
+ return coalesce(${qualified(ctx, MANAGES_FOR)}(p_delegator::text, p_requester, v_levels::text::integer), false);` : "";
2515
+ const mine = `delegator::text = ${me}${writable}`;
2252
2516
  const own = `${mine} and (tenant is null or ${member("tenant")})`;
2253
2517
  return `
2254
2518
  -- approval delegations: out-of-office covers a user writes for themselves; tableApprovalDelegationSource and permdock_is_approver read them
@@ -2288,7 +2552,7 @@ create policy ${policy("delete")} on ${table}
2288
2552
  using (${mine});
2289
2553
 
2290
2554
  -- approval delegations: whether a delegator's own rights match approvers.by; only permdock_is_approver calls it
2291
- create or replace function ${covers}(p_delegator ${user}, p_approvers jsonb, p_tenant text)
2555
+ create or replace function ${covers}(p_delegator ${user}, p_approvers jsonb, p_tenant text, p_requester text)
2292
2556
  returns boolean
2293
2557
  language plpgsql
2294
2558
  stable
@@ -2296,7 +2560,7 @@ security definer
2296
2560
  set search_path = ''
2297
2561
  as $$
2298
2562
  declare
2299
- v_item jsonb;
2563
+ v_item jsonb;${managers ? "\n v_levels jsonb;" : ""}
2300
2564
  begin
2301
2565
  if p_delegator is null or p_approvers is null then
2302
2566
  return false;
@@ -2306,7 +2570,7 @@ begin
2306
2570
  return false;
2307
2571
  end if;
2308
2572
  for v_item in select value from jsonb_array_elements(p_approvers) loop
2309
- if not ${covers}(p_delegator, v_item, p_tenant) then
2573
+ if not ${covers}(p_delegator, v_item, p_tenant, p_requester) then
2310
2574
  return false;
2311
2575
  end if;
2312
2576
  end loop;
@@ -2322,13 +2586,13 @@ begin
2322
2586
  if p_tenant is null then
2323
2587
  return ${holderGlobal};
2324
2588
  end if;
2325
- return ${holderTenant};
2589
+ return ${holderTenant};${managerCase}
2326
2590
  when 'any-of' then
2327
2591
  if jsonb_typeof(p_approvers -> 'of') <> 'array' then
2328
2592
  return false;
2329
2593
  end if;
2330
2594
  for v_item in select value from jsonb_array_elements(p_approvers -> 'of') loop
2331
- if ${covers}(p_delegator, v_item, p_tenant) then
2595
+ if ${covers}(p_delegator, v_item, p_tenant, p_requester) then
2332
2596
  return true;
2333
2597
  end if;
2334
2598
  end loop;
@@ -2338,7 +2602,7 @@ begin
2338
2602
  end case;
2339
2603
  end;
2340
2604
  $$;
2341
- revoke execute on function ${covers}(${user}, jsonb, text) from public, anon, authenticated;
2605
+ revoke execute on function ${covers}(${user}, jsonb, text, text) from public, anon, authenticated;
2342
2606
 
2343
2607
  -- approvers with covers: the signed-in user, or a delegate inside an active cover of a delegator who is not the requester
2344
2608
  create or replace function ${fn}(p_approvers jsonb, p_tenant text, p_requester text, p_resource text)
@@ -2352,7 +2616,7 @@ declare
2352
2616
  v_delegator ${user};
2353
2617
  v_user text := ${me};
2354
2618
  begin
2355
- if ${fn}(p_approvers, p_tenant) then
2619
+ if ${managers ? `${qualified(ctx, APPROVES)}(p_approvers, p_tenant, p_requester)` : `${fn}(p_approvers, p_tenant)`} then
2356
2620
  return true;
2357
2621
  end if;
2358
2622
  if coalesce(v_user, '') = '' or coalesce(p_requester, '') = '' then
@@ -2373,7 +2637,7 @@ begin
2373
2637
  and d.permissions is null
2374
2638
  and (d.resources is null or p_resource = any (d.resources))
2375
2639
  loop
2376
- if ${covers}(v_delegator, p_approvers, p_tenant) then
2640
+ if ${covers}(v_delegator, p_approvers, p_tenant, p_requester) then
2377
2641
  return true;
2378
2642
  end if;
2379
2643
  end loop;
@@ -2384,6 +2648,45 @@ revoke execute on function ${fn}(jsonb, text, text, text) from public, anon;
2384
2648
  grant execute on function ${fn}(jsonb, text, text, text) to authenticated;
2385
2649
  `;
2386
2650
  }
2651
+ function requestApproversSql(ctx) {
2652
+ const fn = qualified(ctx, APPROVAL_STORE.isApprover);
2653
+ return `
2654
+ -- approvers with the current step: the four-argument check over p_approvers and the step's users, manager and permission
2655
+ create or replace function ${fn}(p_approvers jsonb, p_tenant text, p_requester text, p_resource text, p_request_approvers jsonb)
2656
+ returns boolean
2657
+ language sql
2658
+ stable
2659
+ security definer
2660
+ set search_path = ''
2661
+ as $$
2662
+ select ${fn}(
2663
+ jsonb_build_object(
2664
+ 'kind', 'any-of',
2665
+ 'of',
2666
+ case when p_approvers is null then '[]'::jsonb else jsonb_build_array(p_approvers) end
2667
+ || case
2668
+ when jsonb_typeof(p_request_approvers -> 'users') = 'array' then coalesce(
2669
+ (select jsonb_agg(jsonb_build_object('kind', 'user', 'id', u.id)) from jsonb_array_elements_text(p_request_approvers -> 'users') u(id)),
2670
+ '[]'::jsonb
2671
+ )
2672
+ else '[]'::jsonb
2673
+ end
2674
+ || case when p_request_approvers -> 'manager' = 'true'::jsonb then '[{"kind": "manager"}]'::jsonb else '[]'::jsonb end
2675
+ || case
2676
+ when jsonb_typeof(p_request_approvers -> 'permission') = 'string'
2677
+ then jsonb_build_array(jsonb_build_object('kind', 'permission', 'permission', p_request_approvers ->> 'permission'))
2678
+ else '[]'::jsonb
2679
+ end
2680
+ ),
2681
+ p_tenant,
2682
+ p_requester,
2683
+ p_resource
2684
+ )
2685
+ $$;
2686
+ revoke execute on function ${fn}(jsonb, text, text, text, jsonb) from public, anon;
2687
+ grant execute on function ${fn}(jsonb, text, text, text, jsonb) to authenticated;
2688
+ `;
2689
+ }
2387
2690
  /**
2388
2691
  * The request fields an adopted table may mirror into its own columns, as SQL
2389
2692
  * over a body.
@@ -2847,6 +3150,10 @@ function hookParts(scopes, config, overrides) {
2847
3150
  sources: hook.memberships,
2848
3151
  budget: positiveInteger(overrides.budget ?? hook.budget ?? 1024, "budget"),
2849
3152
  version: hook.version !== false,
3153
+ broadcast: hook.version === false || hook.broadcast === false ? void 0 : {
3154
+ topic: hook.broadcast?.topic ?? "permdock:authz",
3155
+ receivePolicy: hook.broadcast?.receivePolicy ?? true
3156
+ },
2850
3157
  jwtExpiry: positiveInteger(hook.jwtExpiry ?? 900, "jwtExpiry"),
2851
3158
  tenantClaim,
2852
3159
  users: suspension?.users,
@@ -2964,7 +3271,60 @@ revoke execute on function ${bump}() from public, anon, authenticated;
2964
3271
  ${tables.map(([name, user]) => `drop trigger if exists ${quoteIdent(VERSION_TRIGGER)} on ${quoteQualified(name)};
2965
3272
  create trigger ${quoteIdent(VERSION_TRIGGER)}
2966
3273
  after insert or update or delete on ${quoteQualified(name)}
2967
- for each row execute function ${bump}(${quoteLiteral(user)});`).join("\n")}${memberUsersVersionSql(parts, bumpFor)}${roleKeysVersionSql(parts, versionTable)}`;
3274
+ for each row execute function ${bump}(${quoteLiteral(user)});`).join("\n")}${broadcastSql(parts, versionTable)}${memberUsersVersionSql(parts, bumpFor)}${roleKeysVersionSql(parts, versionTable)}`;
3275
+ }
3276
+ /**
3277
+ * Every version row written is sent as `{ user_id, version }` on the server
3278
+ * topic and on the user's `authz:<uid>`, in the shape better-supabase's
3279
+ * `subscribeAuthzVersions` and `SessionProvider` read.
3280
+ */
3281
+ function broadcastSql(parts, versionTable) {
3282
+ const broadcast = parts.broadcast;
3283
+ if (broadcast === void 0) return "";
3284
+ const send = `${quoteIdent(parts.schema)}.permdock_broadcast_authz_version`;
3285
+ const payload = "jsonb_build_object('user_id', new.user_id, 'version', new.version)";
3286
+ const event = quoteLiteral(AUTHZ_EVENT);
3287
+ const receive = broadcast.receivePolicy ? `
3288
+
3289
+ -- each user receives their own authz:<uid> topic, and no user may join the server topic
3290
+ do $$
3291
+ begin
3292
+ if to_regclass('realtime.messages') is not null and not exists (
3293
+ select 1 from pg_policies
3294
+ where schemaname = 'realtime' and tablename = 'messages'
3295
+ and policyname = 'permdock_authz_version_receive'
3296
+ ) then
3297
+ create policy permdock_authz_version_receive on realtime.messages
3298
+ for select to authenticated
3299
+ using (
3300
+ realtime.messages.extension = 'broadcast'
3301
+ and (select realtime.topic()) = 'authz:' || (select auth.uid())::text
3302
+ );
3303
+ end if;
3304
+ end;
3305
+ $$;` : "";
3306
+ return `
3307
+
3308
+ -- sends every version bump on the server topic and on the user's authz:<uid>
3309
+ create or replace function ${send}()
3310
+ returns trigger
3311
+ language plpgsql
3312
+ security definer
3313
+ set search_path = ''
3314
+ as $$
3315
+ begin
3316
+ if to_regprocedure('realtime.send(jsonb, text, text, boolean)') is not null then
3317
+ perform realtime.send(${payload}, ${event}, ${quoteLiteral(broadcast.topic)}, true);
3318
+ perform realtime.send(${payload}, ${event}, 'authz:' || new.user_id::text, true);
3319
+ end if;
3320
+ return null;
3321
+ end;
3322
+ $$;
3323
+ revoke execute on function ${send}() from public, anon, authenticated;
3324
+ drop trigger if exists permdock_authz_version_broadcast on ${versionTable};
3325
+ create trigger permdock_authz_version_broadcast
3326
+ after insert or update on ${versionTable}
3327
+ for each row execute function ${send}();${receive}`;
2968
3328
  }
2969
3329
  function signedUp(user) {
2970
3330
  return `exists (select 1 from auth.users a where a.id = ${user})`;
@@ -3240,7 +3600,8 @@ function trustedHelpers(parts, config, types, tenantType, policy) {
3240
3600
  ...config.rls?.apiKeys === void 0 ? [] : [helperEntry(API_KEY_ALLOWS, "p_grant text", "boolean", client)],
3241
3601
  ...config.rls?.tokenScopes === true ? [helperEntry(TOKEN_SCOPE_ALLOWS, "p_grant text", "boolean", client)] : [],
3242
3602
  ...readOnlyActorKinds(config.rls?.readOnlyActors) === void 0 ? [] : [helperEntry(ACTOR_MAY_WRITE, "", "boolean", client)],
3243
- ...config.rls?.approvals === true || typeof config.rls?.approvals === "object" ? [helperEntry(IS_APPROVER, typeof config.rls.approvals === "object" && config.rls.approvals.delegations === true ? "p_approvers jsonb, p_tenant text, p_requester text, p_resource text" : "p_approvers jsonb, p_tenant text", "boolean", client)] : [],
3603
+ ...config.rls?.approvals === true || typeof config.rls?.approvals === "object" ? [helperEntry(IS_APPROVER, typeof config.rls.approvals === "object" && (config.rls.approvals.delegations === true || config.rls.approvals.managers !== void 0) ? "p_approvers jsonb, p_tenant text, p_requester text, p_resource text" : "p_approvers jsonb, p_tenant text", "boolean", client)] : [],
3604
+ ...typeof config.rls?.approvals === "object" && config.rls.approvals.managers !== void 0 ? [helperEntry(MANAGES, "p_requester text, p_levels integer", "boolean", [])] : [],
3244
3605
  ...forUser
3245
3606
  ];
3246
3607
  if (!(policy !== void 0 && (ownershipRules(policy, parts.scopes)?.assigns.length ?? 0) > 0)) return keyed;