permdock 0.6.0 → 0.8.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 (507) hide show
  1. package/README.md +2 -3
  2. package/dist/{2020-C9VN-x8c.js → 2020-CJbO8Bvz.js} +1 -3
  3. package/dist/a2a/index.d.ts +7 -7
  4. package/dist/a2a/index.js +9 -9
  5. package/dist/action-result-CL-QCITA.d.ts +19 -0
  6. package/dist/{adapter-context-CRhqyzCk.js → adapter-context-CIQpQxbE.js} +8 -2
  7. package/dist/{adoption-scan-DCYe60Pi.js → adoption-scan-BLs67P1l.js} +5 -5
  8. package/dist/agent/index.d.ts +3 -3
  9. package/dist/agent/index.js +1 -1
  10. package/dist/ai-sdk/index.d.ts +31 -10
  11. package/dist/ai-sdk/index.js +22 -12
  12. package/dist/{app-data-MuyzVqX8.js → app-data-UNNm07jV.js} +10 -7
  13. package/dist/{approval-header-CJACtHkv.js → approval-header-8QV6MU4H.js} +6 -3
  14. package/dist/{approval-prompt-Dg5LeAcT.js → approval-prompt-B8hQY69x.js} +5 -6
  15. package/dist/{approval-prompt-DvSSPQJX.d.ts → approval-prompt-PYagyQUj.d.ts} +13 -11
  16. package/dist/approvals/index.d.ts +5 -5
  17. package/dist/approvals/index.js +7 -7
  18. package/dist/{approvals-p1PGoVjb.js → approvals-DnIBTuXE.js} +128 -78
  19. package/dist/{approvers-CqPOLD-o.js → approvers-B4r0N_Uz.js} +8 -2
  20. package/dist/{arazzo-41WuzHou.js → arazzo-3RhGfkAK.js} +2 -2
  21. package/dist/{arazzo-CaUVBn7D.js → arazzo-B5-ulWif.js} +6 -6
  22. package/dist/{args-IIolxxKA.js → args-0FrVs5EH.js} +125 -8
  23. package/dist/astro/index.d.ts +30 -12
  24. package/dist/astro/index.js +2 -2
  25. package/dist/{audience-DabClFLQ.js → audience-BAkBDMqn.js} +8 -8
  26. package/dist/{auth-DRLEizbL.js → auth--yPyZNgr.js} +21 -10
  27. package/dist/authzen/index.d.ts +171 -25
  28. package/dist/authzen/index.js +321 -149
  29. package/dist/{automation-BNM3TtDo.d.ts → automation-DqEoWHBc.d.ts} +42 -32
  30. package/dist/{automation-DVjOckjV.js → automation-x3KEUusw.js} +22 -21
  31. package/dist/base-url-BQbddZO5.js +9 -0
  32. package/dist/better-auth/index.d.ts +2 -2
  33. package/dist/better-auth/index.js +13 -7
  34. package/dist/better-supabase/index.d.ts +392 -220
  35. package/dist/better-supabase/index.js +293 -152
  36. package/dist/{bind-DOyrv6zi.d.ts → bind-Cp2hBHzP.d.ts} +27 -12
  37. package/dist/{bind-CAvgUuKs.js → bind-D_sZSVA3.js} +22 -10
  38. package/dist/{body-CH5of8Ne.js → body-CJQwYVa8.js} +3 -3
  39. package/dist/{body-text-QcXok_SI.js → body-text-DQhcmqdY.js} +8 -4
  40. package/dist/{boundary-BM8a_P6E.js → boundary-BV3O1eud.js} +8 -2
  41. package/dist/{boundary-BmHxVH1J.d.ts → boundary-C9ck-3uK.d.ts} +13 -4
  42. package/dist/{budget-NbEtbJC_.js → budget-BELja5A9.js} +6 -3
  43. package/dist/{budget-JqcRqyhK.d.ts → budget-hYsPz_yE.d.ts} +6 -3
  44. package/dist/{build-instance-Bu_eDqYw.js → build-instance-CNWaYJyr.js} +3 -3
  45. package/dist/{canonical-json-BC8_nMTw.js → canonical-json-DwilZ1iB.js} +6 -3
  46. package/dist/{capability-N1K9IpqS.js → capability-BqX94r07.js} +31 -25
  47. package/dist/{capability-Drg-1YhL.d.ts → capability-ChuiONQU.d.ts} +41 -29
  48. package/dist/{casbin-Dyu2gnUD.js → casbin-H0rKxBx2.js} +16 -8
  49. package/dist/{casbin-Cr7RLtA3.js → casbin-cbSbhT_k.js} +2 -2
  50. package/dist/{casl-64gpT-8x.js → casl-C4OINZHI.js} +2 -2
  51. package/dist/{casl-DjEDhTCP.js → casl-CHHoCldP.js} +19 -10
  52. package/dist/catalog/index.d.ts +104 -23
  53. package/dist/catalog/index.js +117 -8
  54. package/dist/{catalog-HD2gf5mY.js → catalog-BFpz2EmT.js} +57 -26
  55. package/dist/{catalog-DZVbrF-z.js → catalog-DCspHDc8.js} +3 -3
  56. package/dist/{catalog-doc-Cdn7-0pQ.js → catalog-doc-DjMKzJp9.js} +53 -16
  57. package/dist/{catalog-fingerprint-CCP0-yQS.js → catalog-fingerprint-e6aCWosn.js} +19 -15
  58. package/dist/catalog-mRQQQhNK.js +1 -0
  59. package/dist/catalog-operations-Dadrl7Z-.js +60 -0
  60. package/dist/{create-CQWIpUG-.js → challenge-DImNcR7B.js} +157 -39
  61. package/dist/chat/index.d.ts +1 -1
  62. package/dist/chat/index.js +13 -10
  63. package/dist/chat-sdk/index.d.ts +44 -26
  64. package/dist/chat-sdk/index.js +17 -17
  65. package/dist/checks-CGkP3Z7A.js +40 -0
  66. package/dist/{claims-map-7oQ3ue4X.js → claims-map-CKkoAAYF.js} +5 -2
  67. package/dist/{claims-map-Ca-QX8C6.d.ts → claims-map-D1Pb5oRq.d.ts} +8 -5
  68. package/dist/claude-agent/index.d.ts +6 -6
  69. package/dist/claude-agent/index.js +6 -3
  70. package/dist/clerk/index.d.ts +11 -7
  71. package/dist/clerk/index.js +6 -6
  72. package/dist/cli/bin.js +4 -4
  73. package/dist/cli/index.d.ts +82 -7
  74. package/dist/cli/index.js +6 -6
  75. package/dist/{clients-C7zLFuWT.d.ts → clients-C_NOET3z.d.ts} +5 -5
  76. package/dist/{clients-DjU5ABMy.js → clients-DYr3U86j.js} +3 -3
  77. package/dist/cloud/index.d.ts +186 -38
  78. package/dist/cloud/index.js +293 -31
  79. package/dist/{cloud-ytQ3uviA.js → cloud-BFlGMaak.js} +5 -6
  80. package/dist/{codemod-5mpSpnUY.js → codemod-DLQ9Zpo4.js} +3 -4
  81. package/dist/{codemod-ua2hHy7w.js → codemod-DWSN2erG.js} +523 -201
  82. package/dist/collect-B5BL3klN.js +1 -0
  83. package/dist/{collect-mLTY4nwb.js → collect-B7ZFAJU3.js} +36 -64
  84. package/dist/{collect-Ci6akVwH.js → collect-Bzv3le0A.js} +6 -6
  85. package/dist/{compare-pfyVnBjE.js → compare-DTfyUunF.js} +2 -2
  86. package/dist/compile/index.d.ts +2 -2
  87. package/dist/compile/index.js +1 -1
  88. package/dist/{compile-1bsAezL0.d.ts → compile-BFzysW3o.d.ts} +36 -12
  89. package/dist/{compile-CMqMx_IN.js → compile-EzEMB-7v.js} +77 -33
  90. package/dist/{completion-BTFrHZhX.js → completion-saoYiRFO.js} +17 -8
  91. package/dist/config-BwPBfN0t.js +108 -0
  92. package/dist/{config-Bj2Ixq3d.js → config-DBeXXmBF.js} +2 -2
  93. package/dist/{config-report-DSpsLpCE.js → config-report-BipSWA6V.js} +9 -6
  94. package/dist/config-shape-ykV0Vm2n.js +134 -0
  95. package/dist/{connection-DjhIJSs2.js → connection-B72dg5Q2.js} +23 -22
  96. package/dist/connector-schema-CYLQNMYq.js +434 -0
  97. package/dist/{context-B_u3_bDJ.js → context-BnIzxTNE.js} +4 -3
  98. package/dist/convex/index.d.ts +13 -7
  99. package/dist/convex/index.js +9 -6
  100. package/dist/core-H-mbhpZc.js +341 -0
  101. package/dist/core-hWIARPDz.d.ts +206 -0
  102. package/dist/{create-CBMmFie-.d.ts → create-BSNrVuxh.d.ts} +87 -34
  103. package/dist/{create-B30OMUOJ.d.ts → create-BVq1lNQE.d.ts} +49 -28
  104. package/dist/{create-D_NmPOdH.d.ts → create-CM1FciYG.d.ts} +37 -29
  105. package/dist/{create-CGm28gyI.js → create-Cq4Uox0f.js} +13 -9
  106. package/dist/{create-DCF2SvoT.js → create-_noSrY1T.js} +15 -21
  107. package/dist/{credential-BcoiejpY.js → credential-CyyyvCsL.js} +42 -39
  108. package/dist/{credentials-DPyHmYz5.js → credentials-CdDxp7jN.js} +6 -6
  109. package/dist/{deciding-columns-Sq12mEA6.js → deciding-columns-NB4wcyBf.js} +13 -2
  110. package/dist/{delegation-j6-rc37o.js → delegation-CDB6_keF.js} +31 -22
  111. package/dist/delivery/index.d.ts +5 -5
  112. package/dist/delivery/index.js +6 -5
  113. package/dist/{delivery-DCAgNyCn.js → delivery-BupfvJIV.js} +81 -20
  114. package/dist/{delivery-event-xX4obB8F.js → delivery-event-JioK5YbS.js} +6 -6
  115. package/dist/denied-text-CHNlVInN.d.ts +22 -0
  116. package/dist/{describe-BybMRY7A.js → describe-Bb4hGK5d.js} +6 -5
  117. package/dist/{describe-B5qgDvEW.d.ts → describe-ByS9LgHK.d.ts} +5 -5
  118. package/dist/{device-BARQ8eYG.js → device-BwbJNmb2.js} +11 -8
  119. package/dist/{diff-CmuSD3vc.js → diff-CN8IYhC_.js} +2 -2
  120. package/dist/{diff-3jbx6Rm4.js → diff-iZWV65nC.js} +23 -14
  121. package/dist/{digest-B3kc_PgQ.d.ts → digest-8Yx2CchM.d.ts} +3 -3
  122. package/dist/{doctor-BdZw53-k.js → doctor-CHD1M9R5.js} +485 -141
  123. package/dist/{doctor-3ZqNHX_G.js → doctor-D3wo-yuz.js} +4 -4
  124. package/dist/drizzle/index.d.ts +33 -19
  125. package/dist/drizzle/index.js +17 -9
  126. package/dist/elysia/index.d.ts +17 -11
  127. package/dist/elysia/index.js +5 -5
  128. package/dist/{errors-BKy0EfhN.js → errors-B6R_lg2a.js} +13 -4
  129. package/dist/{errors-BWXBMaKK.d.ts → errors-CHwoRRpB.d.ts} +4 -1
  130. package/dist/{errors-CWTY6uih.js → errors-Vpu6rKHl.js} +14 -10
  131. package/dist/{errors-DH5QEGXh.d.ts → errors-zi_4T-rx.d.ts} +22 -6
  132. package/dist/{evaluate-CNClBvcj.js → evaluate-Dd8Ta0Ie.js} +185 -80
  133. package/dist/{evaluations-beAooV0n.js → evaluations-IBceAeKT.js} +41 -20
  134. package/dist/{evaluations-C_1vdSZc.d.ts → evaluations-z8dQFDaN.d.ts} +12 -6
  135. package/dist/eve/index.d.ts +9 -6
  136. package/dist/eve/index.js +4 -4
  137. package/dist/{event-time-CsegxXxB.js → event-time-BGy48400.js} +8 -4
  138. package/dist/{expiry-D4_YKRKD.js → expiry-6XByK0dm.js} +8 -5
  139. package/dist/express/index.d.ts +9 -6
  140. package/dist/express/index.js +9 -6
  141. package/dist/fastify/index.d.ts +16 -10
  142. package/dist/fastify/index.js +8 -5
  143. package/dist/{fetch-adapter-Dw0MTS3D.d.ts → fetch-adapter-C1DCvpqV.d.ts} +9 -6
  144. package/dist/{fetch-adapter-DD_gfmrC.js → fetch-adapter-JL43jD3E.js} +14 -11
  145. package/dist/fields-D0vUI6dq.js +498 -0
  146. package/dist/{files-C5ZI27eV.js → files-B3AA05f1.js} +21 -5
  147. package/dist/{files-D_JIzUrP.js → files-BSjrtIHw.js} +11 -4
  148. package/dist/{fixtures-B7XrLeY7.js → fixtures-A1_sp_tR.js} +15 -6
  149. package/dist/{flags-C3DktBDY.js → flags-DXjoTVbS.js} +2 -2
  150. package/dist/{freeze-CrU8nQeX.js → freeze-jjan0lCv.js} +4 -1
  151. package/dist/{from-snapshot-CTCMsFZk.js → from-snapshot-DCakWRsr.js} +26 -16
  152. package/dist/gen-B5kvbAoZ.js +58 -0
  153. package/dist/gen-DWCYcMQM.js +827 -0
  154. package/dist/generate-CRVV5V7l.js +165 -0
  155. package/dist/generate-CezbCaTI.js +275 -0
  156. package/dist/{grantee-hxrUsbpM.js → grantee-Dke-9rd1.js} +4 -4
  157. package/dist/{grantee-conditions-CcXf8hMM.js → grantee-conditions-BrYPe-w0.js} +12 -12
  158. package/dist/{grantee-match-DbENBHLB.js → grantee-match-7RZZvoT_.js} +12 -6
  159. package/dist/{graph-sql-B-dsAT6j.d.ts → graph-sql-BwFC4Qjs.d.ts} +3 -3
  160. package/dist/h3/index.d.ts +10 -7
  161. package/dist/h3/index.js +3 -3
  162. package/dist/headers-B9jQxjtW.d.ts +10 -0
  163. package/dist/{helpers-CBYVMjwh.js → helpers-DJicaG6f.js} +40 -28
  164. package/dist/hono/index.d.ts +16 -10
  165. package/dist/hono/index.js +5 -5
  166. package/dist/{hosted-BPk51-kX.d.ts → hosted-Cmtxogd0.d.ts} +44 -20
  167. package/dist/{hosted-B46-5LYE.js → hosted-D0IzESu_.js} +68 -25
  168. package/dist/{http-ujKm0JXE.js → http-DH94eh6f.js} +4 -4
  169. package/dist/{http-BBoKefeS.js → http-DKLXrFGk.js} +13 -7
  170. package/dist/{http-DXJ37RDA.js → http-DOL33cO0.js} +11 -8
  171. package/dist/{import-wyqXUyjm.js → import-CST57XLp.js} +64 -51
  172. package/dist/{import-CNV7I2Dw.js → import-_YqhhwvX.js} +6 -6
  173. package/dist/{index-B8YjkEZ4.d.ts → index-B8s204GL.d.ts} +64 -52
  174. package/dist/{index-Ch8LpNDp.d.ts → index-BT5-1VsX.d.ts} +64 -25
  175. package/dist/{index-DuWxc5dt.d.ts → index-BW_0MZOS.d.ts} +388 -149
  176. package/dist/index-BhxEUY9J.d.ts +233 -0
  177. package/dist/index-Bv5iXPqU.d.ts +210 -0
  178. package/dist/{index-C-6Letxg.d.ts → index-_9UiQIkt.d.ts} +164 -77
  179. package/dist/index.d.ts +22 -21
  180. package/dist/index.js +35 -33
  181. package/dist/{init-GG6Jh8HD.js → init-Dz_PsHdv.js} +5 -5
  182. package/dist/{init-DeMYsnYJ.js → init-cE3A8aXq.js} +10 -10
  183. package/dist/{instance-options-BsVpyGIk.d.ts → instance-options-B0KXqTrJ.d.ts} +4 -4
  184. package/dist/{instance-snapshot-BOEhcqIF.js → instance-snapshot--JWiTrvO.js} +81 -56
  185. package/dist/{instant-BluqDvyS.js → instant-DK3Iz83e.js} +2 -2
  186. package/dist/{internals-Dk8A8fX3.js → internals-B3IgHrvo.js} +6 -3
  187. package/dist/{json-schema-B-vAwlde.js → json-schema-BPGa-RjQ.js} +9 -3
  188. package/dist/{json-schema-CN_iLFH2.d.ts → json-schema-BfXgnRNT.d.ts} +4 -4
  189. package/dist/jwt/index.d.ts +125 -17
  190. package/dist/jwt/index.js +157 -16
  191. package/dist/{kernel-D0NVb1cK.js → kernel-C-fYydV2.js} +151 -16
  192. package/dist/kysely/index.d.ts +49 -33
  193. package/dist/kysely/index.js +9 -7
  194. package/dist/{live-options-BaAFCIiu.js → live-options-BBIT68le.js} +2 -2
  195. package/dist/{load-DFS_ry0W.js → load-DjSU5KXO.js} +6 -6
  196. package/dist/load-Dm0pSYH3.js +1 -0
  197. package/dist/{login-Dfe5RlYk.js → login-D-8tMqzo.js} +4 -4
  198. package/dist/{login-imhuwvn3.js → login-DplQ0s84.js} +18 -15
  199. package/dist/{manifest-dvL2XEe1.js → manifest-Cgiq5oqc.js} +67 -37
  200. package/dist/{manifest-mx5ghSFM.d.ts → manifest-CzzWtnAb.d.ts} +144 -28
  201. package/dist/{manifest-schema-C0kK_8V0.js → manifest-schema-2r37XRhD.js} +80 -9
  202. package/dist/{manifest-C8IzW3Do.js → manifest-wg8WkkpD.js} +11 -7
  203. package/dist/{map-claims-D3oRmTk0.js → map-claims-BNWCJtmP.js} +27 -18
  204. package/dist/{map-error-Dr70oA_3.js → map-error-pasIGqMT.js} +7 -7
  205. package/dist/{markers-C6joDI3o.js → markers-BeHZ4x9Q.js} +20 -5
  206. package/dist/mcp/index.d.ts +154 -47
  207. package/dist/mcp/index.js +200 -41
  208. package/dist/{migrate-CIq4-E9F.js → migrate-B7oP_sQU.js} +102 -31
  209. package/dist/module-values-BJTBdo6y.js +107 -0
  210. package/dist/nest/index.d.ts +23 -13
  211. package/dist/nest/index.js +18 -11
  212. package/dist/next/client.d.ts +5 -2
  213. package/dist/next/client.js +1 -1
  214. package/dist/next/index.d.ts +72 -26
  215. package/dist/next/index.js +110 -6
  216. package/dist/next/plugin.d.ts +1 -1
  217. package/dist/next/plugin.js +4 -3
  218. package/dist/node/index.d.ts +5 -5
  219. package/dist/node/index.js +3 -3
  220. package/dist/{ocsf-BFp-PZZA.js → ocsf-TcjRBgIs.js} +15 -5
  221. package/dist/openai/index.d.ts +13 -7
  222. package/dist/openai/index.js +3 -3
  223. package/dist/openapi/index.d.ts +61 -30
  224. package/dist/openapi/index.js +2 -2
  225. package/dist/{openapi-B7HZ0f-r.js → openapi-BOsx0xn9.js} +34 -24
  226. package/dist/{openapi-C4dDTVEd.js → openapi-CBZUhA3l.js} +4 -5
  227. package/dist/{openapi-DD1SV-5-.js → openapi-VeHHU2l9.js} +23 -14
  228. package/dist/{operation-findings-DgATDpvh.js → operation-findings-CXtFzlKJ.js} +3 -3
  229. package/dist/{operations-X0VM7F3m.d.ts → operations-Ci_rT6Uo.d.ts} +10 -7
  230. package/dist/orpc/index.d.ts +68 -14
  231. package/dist/orpc/index.js +62 -13
  232. package/dist/otel/index.d.ts +7 -4
  233. package/dist/otel/index.js +8 -5
  234. package/dist/output-files-BHOIlrfD.js +1 -0
  235. package/dist/{output-files-DhRBBE4n.js → output-files-BIQ_9pIs.js} +29 -17
  236. package/dist/{output-1im__-08.js → output-tkju6U7R.js} +15 -7
  237. package/dist/ownership-B4L59T9u.js +1054 -0
  238. package/dist/parse-1_ZheTW5.js +151 -0
  239. package/dist/parse-local-manifest-BQhTlLQS.d.ts +10 -0
  240. package/dist/parse-local-manifest-DEiCF4ah.js +69 -0
  241. package/dist/{parse-request-D_tUXG6M.js → parse-request-CwCZpyjV.js} +7 -8
  242. package/dist/{paths-DXSHAMIa.js → paths-CUvURzHp.js} +4 -1
  243. package/dist/pdp/index.d.ts +9 -6
  244. package/dist/pdp/index.js +23 -12
  245. package/dist/{peer-CRvC7Hg1.js → peer-C9LvBCcb.js} +1 -1
  246. package/dist/peer-Q0fuZ6hx.js +982 -0
  247. package/dist/{permdock-SV8ZINYT.d.ts → permdock-B6Sf4T_S.d.ts} +270 -117
  248. package/dist/{permdock-BrAscV28.js → permdock-L-_I_3zP.js} +226 -74
  249. package/dist/{permission-registry-Br4jSNVi.js → permission-registry-B8tYxPIt.js} +24 -11
  250. package/dist/{vocabulary-CN8H_9UF.d.ts → permission-types-CAY-GU7e.d.ts} +130 -104
  251. package/dist/{permissions-u_KHg-sN.d.ts → permissions-Bx6UI8n1.d.ts} +6 -2
  252. package/dist/{permissions-B-wCP5ZC.js → permissions-CVXmRILq.js} +3 -3
  253. package/dist/{permissions-BPxlwVhN.js → permissions-mDcTWoBs.js} +8 -5
  254. package/dist/pg-DQTqRrou.js +60 -0
  255. package/dist/{pins-8ILTftC9.js → pins-nqarl3oE.js} +4 -1
  256. package/dist/pkce-CnmmYqUZ.js +21 -0
  257. package/dist/{policy-77FSAq_V.d.ts → policy-Ba4bDhaj.d.ts} +5 -5
  258. package/dist/{policy-DbM5YYtV.js → policy-CLQ8__GF.js} +49 -20
  259. package/dist/{policy-from-catalog-C2gMa2Dj.js → policy-from-catalog-CJgOm6aq.js} +28 -25
  260. package/dist/{policy-module-CTlwMvLI.js → policy-module-xym9fnSq.js} +12 -6
  261. package/dist/{policy-types-n0uRTsW8.d.ts → policy-types-CCiDRZBH.d.ts} +802 -334
  262. package/dist/postgres-store-DcyrPS-r.js +1028 -0
  263. package/dist/{postgrest-DAjUkF9w.js → postgrest-D4nuPXIQ.js} +88 -36
  264. package/dist/{postgrest-CEgRbefE.d.ts → postgrest-DicQyqm-.d.ts} +60 -30
  265. package/dist/powersync-DHNQX06W.js +1117 -0
  266. package/dist/{powersync-DISt6SUe.js → powersync-DXqGuq9A.js} +3 -3
  267. package/dist/powersync-Djf-zCpB.js +1 -0
  268. package/dist/preset/index.d.ts +38 -28
  269. package/dist/preset/index.js +1 -1
  270. package/dist/{preset-DZdU0tne.js → preset-BjLzeFpp.js} +58 -34
  271. package/dist/{principal-source-pHneukrx.js → principal-source-C6N60GtM.js} +10 -10
  272. package/dist/prisma/index.d.ts +69 -41
  273. package/dist/prisma/index.js +21 -17
  274. package/dist/{problem-CTviyH5L.js → problem-BVLHFK33.js} +41 -21
  275. package/dist/{problem-details-cn5X30gZ.js → problem-details-CLDgX1KV.js} +13 -4
  276. package/dist/{problem-types-CJ2325SZ.js → problem-types-DSsRfONQ.js} +4 -1
  277. package/dist/prompt-BYc6drYW.js +938 -0
  278. package/dist/protected-action-BE7N_Luo.d.ts +58 -0
  279. package/dist/protected-action-DUYqb-Ma.js +80 -0
  280. package/dist/{protected-BlF0F6wL.js → protected-action-QEA8arRB.js} +48 -14
  281. package/dist/{provider-B1al-AZz.js → provider-C55OGXJ7.js} +5 -4
  282. package/dist/{provider-DILL9oPK.d.ts → provider-DXfq5c2d.d.ts} +1 -1
  283. package/dist/{provider-store-DM6DNcta.js → provider-store-CaTv00tr.js} +13 -9
  284. package/dist/pull-B65ndFNZ.js +1 -0
  285. package/dist/{pull-jEwbf80J.js → pull-CwpGaQSi.js} +12 -11
  286. package/dist/{push-BD4f15co.js → push-DgssgzkK.js} +62 -16
  287. package/dist/{pushed-policy-DCW91KQU.d.ts → pushed-policy-D1Eoi6NM.d.ts} +12 -6
  288. package/dist/{pushed-policy-CqtxkV4G.js → pushed-policy-ITwYKvvH.js} +10 -7
  289. package/dist/react/index.d.ts +9 -8
  290. package/dist/react/index.js +7 -6
  291. package/dist/react/provider-client.d.ts +1 -1
  292. package/dist/react/provider-client.js +1 -1
  293. package/dist/react-native/index.d.ts +104 -51
  294. package/dist/react-native/index.js +394 -67
  295. package/dist/{refs-K6eWUJ0H.js → refs-C8BKxc_e.js} +17 -3
  296. package/dist/{relation-walk-3OyDBF0S.js → relation-walk-DK_gkgL7.js} +12 -9
  297. package/dist/{relations-BnCWnJGI.js → relations-BxvRvDHK.js} +3 -3
  298. package/dist/{replay-Du1tJjG7.js → replay-BU09ad4L.js} +1 -1
  299. package/dist/{replay-Bkm-Ne4l.d.ts → replay-DNftIb_R.d.ts} +1 -1
  300. package/dist/{request-context-C81Pip9n.js → request-context-C25ilqiJ.js} +8 -8
  301. package/dist/{request-schema-CMreVuFM.js → request-schema-DhX7UbfQ.js} +4 -1
  302. package/dist/resend/index.d.ts +34 -28
  303. package/dist/resend/index.js +29 -29
  304. package/dist/resolve-names-CF7xXLSG.js +201 -0
  305. package/dist/{resource-relations-D_jw0BFx.js → resource-relations-8-pCScBO.js} +18 -9
  306. package/dist/{retire-CALjIQ7e.js → retire-B2xffQgY.js} +15 -6
  307. package/dist/{revocations-R07lFBnX.d.ts → revocations-BaUXHM1N.d.ts} +6 -3
  308. package/dist/{rls-DTvYd-lI.js → rls-CNEH2_BG.js} +743 -624
  309. package/dist/{rls-BAqP4q66.js → rls-Ca8Jz9b5.js} +41 -10
  310. package/dist/{role-builder-uWQZ4v84.js → role-builder-BK2-T6oD.js} +41 -20
  311. package/dist/rolldown-runtime-C3I60J0A.js +4 -0
  312. package/dist/{row-conditions-h2HythXQ.js → row-conditions-BAGHOmVq.js} +4 -3
  313. package/dist/{rpc-VSl5ylaQ.js → rpc-fNqAIqQk.js} +8 -5
  314. package/dist/{run-CUKuz0A8.js → run-Bz26OTfO.js} +26 -23
  315. package/dist/run-D-JE8QWb.js +1 -0
  316. package/dist/{run-ticket-DocwaTKn.d.ts → run-ticket-DbWI9f99.d.ts} +33 -13
  317. package/dist/{run-ticket-sxFI6LAk.js → run-ticket-Dv7aF7Dk.js} +29 -8
  318. package/dist/{runtime-D3VTAiCA.js → runtime-BGnrOkVH.js} +5 -2
  319. package/dist/{saas-BCXRuXca.js → saas-iWnUdwCt.js} +42 -29
  320. package/dist/{scan-qvOe0hS3.js → scan-DCj1KQfn.js} +1 -1
  321. package/dist/{schema-B4v0Qrac.js → schema-BOJjqlWL.js} +3 -2
  322. package/dist/{schema-yLuBWWsh.js → schema-Dst9I9Gs.js} +9 -5
  323. package/dist/scim/index.d.ts +3 -2
  324. package/dist/scim/index.js +3 -1
  325. package/dist/scim-D8YupzX1.js +44 -0
  326. package/dist/{scim-ClHtpyV3.js → scim-jJBJ7g1Z.js} +35 -551
  327. package/dist/{scopes-CUPSjo9q.js → scopes-0Up_UA2t.js} +42 -24
  328. package/dist/server/index.d.ts +12 -12
  329. package/dist/server/index.js +13 -13
  330. package/dist/{server-C3WXAHZj.js → server-3cVlTLde.js} +31 -31
  331. package/dist/{server-types-CKQiCnON.d.ts → server-types-CIlpSA2G.d.ts} +81 -46
  332. package/dist/{sha256-D9ihqmvd.js → sha256-C-4WXKIu.js} +4 -3
  333. package/dist/{shared-BAK8t4Uo.js → shared-Afctg7B0.js} +100 -61
  334. package/dist/{shared-DvvFzYXe.js → shared-l0oGGetg.js} +9 -6
  335. package/dist/{signals-D3NcTKUS.js → signals-B1vHR3fN.js} +2 -2
  336. package/dist/{sink-BEZSlMS_.js → sink-D9_vh372.js} +32 -21
  337. package/dist/{sink-4-eQIRWf.d.ts → sink-Dvi7YZG_.d.ts} +44 -20
  338. package/dist/{skills-B6lVdD_W.js → skills-Bjj7BNEQ.js} +16 -12
  339. package/dist/{skills-CTYwkl44.js → skills-OuoMR49L.js} +3 -3
  340. package/dist/{snapshot-B7DkYg6g.js → snapshot-CXlzi69u.js} +21 -18
  341. package/dist/{snapshot-cache-PXI-vGpY.d.ts → snapshot-cache-BAXZ0KOp.d.ts} +21 -12
  342. package/dist/{snapshot-cache-DZHQ0KF6.js → snapshot-cache-Bx_4xC_6.js} +14 -11
  343. package/dist/solid/index.d.ts +55 -15
  344. package/dist/solid/index.js +46 -12
  345. package/dist/solid-start/index.d.ts +30 -12
  346. package/dist/solid-start/index.js +3 -3
  347. package/dist/sources-B1Os_YUu.d.ts +312 -0
  348. package/dist/{sources-vs5dGOsS.js → sources-CMAM-2A3.js} +156 -51
  349. package/dist/sources-qoIJQrJv.js +11 -0
  350. package/dist/{sql-B5T1IL83.js → sql-0WjxIp9g.js} +32 -7
  351. package/dist/sql-B80DFdpG.d.ts +10 -0
  352. package/dist/{src-Cu2m75uo.js → src-DZ0l9UAg.js} +305 -123
  353. package/dist/ssf/index.d.ts +4 -4
  354. package/dist/ssf/index.js +665 -224
  355. package/dist/{standard-webhooks-rbD7LS6h.d.ts → standard-webhooks-C-qX4mJW.d.ts} +7 -7
  356. package/dist/{standard-webhooks-DgFFD-Ga.js → standard-webhooks-D67a3nzk.js} +5 -5
  357. package/dist/{store-BDutJkDL.js → store-RNFvaJJv.js} +43 -29
  358. package/dist/{store-options-u0ycEe8s.js → store-options-Dil3lraY.js} +105 -15
  359. package/dist/stores-C0Kta5Ft.d.ts +59 -0
  360. package/dist/{stores-CGhM8BN_.js → stores-DxZWDXCs.js} +42 -5
  361. package/dist/{stream-CvdUS9V1.js → stream-CDvF0sJm.js} +5 -5
  362. package/dist/{stream-CeCMJmBB.d.ts → stream-ltuLdtTG.d.ts} +4 -3
  363. package/dist/{style-DiKWnAvn.js → style-DblOtSga.js} +1 -1
  364. package/dist/{style-Uao76wO7.js → style-Ds11Hmk4.js} +3 -1
  365. package/dist/{subject-settings-CkEwrw3W.js → subject-settings-8sH5HlII.js} +8 -4
  366. package/dist/{row-check-Dt35czLy.d.ts → subject-settings-vNW8qmUH.d.ts} +30 -18
  367. package/dist/supabase/index.d.ts +48 -37
  368. package/dist/supabase/index.js +6 -6
  369. package/dist/supabase/middleware.d.ts +19 -13
  370. package/dist/supabase/middleware.js +7 -7
  371. package/dist/{supabase-x5JtR2tc.js → supabase-BL1qJzzY.js} +82 -36
  372. package/dist/{supabase-By_frk3U.js → supabase-D39cuGPt.js} +3 -3
  373. package/dist/{supabase-hook-BMoEhZir.js → supabase-hook-B-yXnzUl.js} +1206 -286
  374. package/dist/supabase-hook-H-MtE9Wd.js +1 -0
  375. package/dist/supautils-BU-pAEpf.js +808 -0
  376. package/dist/{support-session-C6xJQYut.js → support-session-BsmPCbz8.js} +22 -22
  377. package/dist/svelte/PermissionBoundary.svelte +2 -6
  378. package/dist/svelte/Protected.svelte +2 -8
  379. package/dist/svelte/index.d.ts +9 -8
  380. package/dist/svelte/index.js +10 -9
  381. package/dist/svelte/runtime.d.ts +4 -4
  382. package/dist/svelte/runtime.js +4 -4
  383. package/dist/svelte/source.d.ts +9 -8
  384. package/dist/svelte/source.js +6 -5
  385. package/dist/sveltekit/index.d.ts +30 -12
  386. package/dist/sveltekit/index.js +2 -2
  387. package/dist/{ownership-DqaJNJPn.js → tables-DeMNEy6V.js} +1025 -1085
  388. package/dist/tanstack-start/index.d.ts +22 -10
  389. package/dist/tanstack-start/index.js +2 -2
  390. package/dist/{target-Bw37TFNA.js → target-qdEAnnhU.js} +6 -6
  391. package/dist/{tenancy-DN2QAx9z.js → tenancy-5d1zVBvK.js} +36 -21
  392. package/dist/terminal/index.d.ts +23 -14
  393. package/dist/terminal/index.js +17 -20
  394. package/dist/testing/core.d.ts +2 -0
  395. package/dist/testing/core.js +1 -0
  396. package/dist/testing/fixtures/index.d.ts +15 -0
  397. package/dist/testing/fixtures/index.js +831 -0
  398. package/dist/testing/index.d.ts +235 -285
  399. package/dist/testing/index.js +502 -927
  400. package/dist/testing/saas/index.d.ts +43 -27
  401. package/dist/testing/saas/index.js +2 -2
  402. package/dist/testing/saas/permissions.d.ts +1 -1
  403. package/dist/testing/saas/permissions.js +1 -1
  404. package/dist/text-diff-BtfSmdUo.js +444 -0
  405. package/dist/{thenable-yD7SabqG.js → thenable-BNSM1U2R.js} +12 -3
  406. package/dist/{time-DkWjdL98.js → time-nR1JesoH.js} +32 -8
  407. package/dist/{token-BLZcjQgt.js → token-DC9EQiet.js} +15 -13
  408. package/dist/{tool-refusal-CMLN5xhn.js → tool-refusal-Qpjs_W6M.js} +5 -2
  409. package/dist/trpc/index.d.ts +11 -8
  410. package/dist/trpc/index.js +15 -9
  411. package/dist/type-helpers-BIPIDa6a.d.ts +50 -0
  412. package/dist/{types-8RnwUAvE.d.ts → types-AMJ5qoU_.d.ts} +49 -30
  413. package/dist/{types-C_IiEs64.d.ts → types-B2mlGuhW.d.ts} +14 -11
  414. package/dist/{types-_WhUP7ud.d.ts → types-B4uqKDnp.d.ts} +25 -12
  415. package/dist/{types-CX7AvRqP.d.ts → types-BJk0BKRX.d.ts} +24 -14
  416. package/dist/types-B_d_g7T3.d.ts +262 -0
  417. package/dist/{types-BdtSDbBO.d.ts → types-B_tiYvk8.d.ts} +59 -32
  418. package/dist/{types-DqzsnlSA.js → types-CcUXciSj.js} +17 -5
  419. package/dist/{types-Dfv0aTER.d.ts → types-DC1Loeh3.d.ts} +449 -168
  420. package/dist/{types-lUlG3TVd.d.ts → types-DHKPcqzr.d.ts} +2 -2
  421. package/dist/{types-C791HFu9.d.ts → types-DjuMBNF9.d.ts} +68 -32
  422. package/dist/{types-C863OQiR.d.ts → types-HzqOtvsJ.d.ts} +23 -12
  423. package/dist/{types-Druu9wLM.d.ts → types-ZzRGoViD.d.ts} +77 -24
  424. package/dist/{types-BzzaHxt3.d.ts → types-ah9NlU6j.d.ts} +137 -48
  425. package/dist/{types-CVZSNocA.d.ts → types-djVzLlIV.d.ts} +31 -14
  426. package/dist/{types-BtHtcKMr.d.ts → types-yUuPR5Hy.d.ts} +47 -24
  427. package/dist/unplugin/index.d.ts +1 -1
  428. package/dist/unplugin/index.js +2 -2
  429. package/dist/usage-CYeXek0p.js +1 -0
  430. package/dist/{usage-SveTRTyr.js → usage-CxEzS4ey.js} +50 -26
  431. package/dist/{usage-CRVl9V3t.js → usage-ab0PdusX.js} +2 -2
  432. package/dist/{validation-error-ZfUHbKvf.js → validation-error-CYg2kJEw.js} +4 -1
  433. package/dist/{validation-error-DHUrAkku.d.ts → validation-error-YGg2mXyH.d.ts} +5 -2
  434. package/dist/{validity-CZ7-y0Cj.js → validity-Buc7w8E9.js} +13 -10
  435. package/dist/{verifier-DHuh-okk.js → verifier-DUV6pLqZ.js} +10 -4
  436. package/dist/{verify-BaAKx7t6.js → verify-DZeqoWu5.js} +417 -489
  437. package/dist/version-DMQ0dnN5.js +48 -0
  438. package/dist/version-DizhmD72.js +1 -0
  439. package/dist/{views-DTIIO-oQ.js → views-CD8wuL4Z.js} +19 -6
  440. package/dist/vocabulary-DEJ5j4mR.d.ts +70 -0
  441. package/dist/vue/index.d.ts +71 -21
  442. package/dist/vue/index.js +50 -13
  443. package/dist/{waiter-B986w1oK.d.ts → waiter-Bu9zAlE0.d.ts} +13 -10
  444. package/dist/{waiter-BGUtGYoU.js → waiter-aBLM63_f.js} +1 -1
  445. package/dist/{watch-vea54PRw.js → watch-Cx_WciLE.js} +8 -8
  446. package/dist/watch-DB42U1ib.js +1 -0
  447. package/dist/webmcp/index.d.ts +11 -11
  448. package/dist/webmcp/index.js +8 -5
  449. package/dist/{where-scope-C9vfEphl.js → where-scope-DlCdCM_8.js} +56 -30
  450. package/dist/{who-can-DWBAcaCQ.js → who-can-rI7dCR9Q.js} +23 -20
  451. package/dist/workflow/index.d.ts +3 -3
  452. package/dist/workflow/index.js +13 -13
  453. package/dist/workflow-sdk/index.d.ts +19 -13
  454. package/dist/workflow-sdk/index.js +6 -6
  455. package/dist/{wrap-gX61EtpB.js → wrap-B2wziJI_.js} +11 -5
  456. package/dist/{wrap-C5jC6sKI.d.ts → wrap-DlJE3gS_.d.ts} +8 -5
  457. package/package.json +25 -14
  458. package/schemas/catalog-v1.json +3 -0
  459. package/schemas/cli-result-v1.json +1 -0
  460. package/schemas/cloud-api-v1.json +152 -7
  461. package/schemas/connector-v1.json +8 -0
  462. package/schemas/supabase-claims-v1.json +5 -0
  463. package/schemas/supabase-manifest-v1.json +308 -75
  464. package/skills/permdock/SKILL.md +1 -0
  465. package/skills/permdock-agents/references/runtimes.md +3 -1
  466. package/skills/permdock-approvals/references/stores-and-resume.md +2 -1
  467. package/skills/permdock-credentials/references/tokens-keys-links.md +8 -6
  468. package/skills/permdock-data/references/queries-and-rls.md +6 -2
  469. package/skills/permdock-tenancy/SKILL.md +1 -1
  470. package/skills/permdock-tenancy/references/ownership-and-custom-roles.md +2 -1
  471. package/skills/permdock-wire/references/adapters.md +28 -22
  472. package/skills/permdock-wire/references/policy-options.md +1 -0
  473. package/dist/catalog-BoWglDPI.js +0 -1
  474. package/dist/collect-D7eQDffE.js +0 -1
  475. package/dist/config-bs_kZeYq.js +0 -162
  476. package/dist/denied-text-CiFQNuMV.d.ts +0 -19
  477. package/dist/fields-OYG_JR78.js +0 -203
  478. package/dist/generate-CNU1pIOo.js +0 -171
  479. package/dist/headers-BIjfMaoC.js +0 -8
  480. package/dist/headers-CIbDTUTK.d.ts +0 -7
  481. package/dist/index-Cp_ilKi1.d.ts +0 -91
  482. package/dist/index-CueFnxQc.d.ts +0 -110
  483. package/dist/load-BxEtwlBS.js +0 -1
  484. package/dist/output-files-B3IZJksC.js +0 -1
  485. package/dist/package-root-Dk_ETdkp.js +0 -31
  486. package/dist/parse-Cxq0WxrA.js +0 -53
  487. package/dist/parse-local-manifest-5ODwqu8b.d.ts +0 -10
  488. package/dist/parse-local-manifest-CVSs6J9I.js +0 -34
  489. package/dist/peer-C8swJ2GH.js +0 -50
  490. package/dist/policies-DP2nqRoF.js +0 -295
  491. package/dist/powersync-BkWWCS1K.js +0 -538
  492. package/dist/powersync-MMJ2mI2q.js +0 -1
  493. package/dist/problem-details-B45V5d2b.d.ts +0 -7
  494. package/dist/prompt-DfZLJLIn.js +0 -32
  495. package/dist/protected-RFGpakN9.d.ts +0 -38
  496. package/dist/pull-CvpINcMK.js +0 -1
  497. package/dist/run-DDwUaJDU.js +0 -1
  498. package/dist/sources-Xc4zkszI.d.ts +0 -190
  499. package/dist/stores-BUGNbJTt.d.ts +0 -30
  500. package/dist/supabase-hook-CCw5m35C.js +0 -1
  501. package/dist/supautils-B6HYL9eL.js +0 -91
  502. package/dist/text-diff-BQcUapOb.js +0 -15
  503. package/dist/types-B3_ooZgZ.d.ts +0 -172
  504. package/dist/usage-CZpSQP6L.js +0 -1
  505. package/dist/version-CEbQ5UeM.js +0 -18
  506. package/dist/version-DXkYUISx.js +0 -1
  507. package/dist/watch--ovlPOc0.js +0 -1
@@ -1,29 +1,902 @@
1
1
  import { r as isRecord } from "./compact-CAf557ZB.js";
2
- import { a as hasConditionOp } from "./refs-K6eWUJ0H.js";
3
- import { c as rootScope, d as scopeList, l as scopeChain, o as resolveScope } from "./scopes-CUPSjo9q.js";
4
- import { t as APPROVAL_REQUEST_SCHEMA } from "./request-schema-CMreVuFM.js";
5
- import { a as describeError, i as configError } from "./errors-CWTY6uih.js";
6
- import { i as readJsonFile, o as sqlFiles, s as writeFileEnsuringDir } from "./files-D_JIzUrP.js";
7
- import { a as SUPABASE_MANIFEST_SCHEMA } from "./version-CEbQ5UeM.js";
8
- import { c as requirePolicy } from "./load-DFS_ry0W.js";
9
- import { r as scopeColumn } from "./compile-CMqMx_IN.js";
10
- import { t as authorizeSql } from "./supabase-x5JtR2tc.js";
11
- import "./budget-NbEtbJC_.js";
12
- import { i as qualifySqlTable } from "./sql-B5T1IL83.js";
13
- import { a as hookApiNames, d as keptKeys, t as AUTHZ_VERSION_TABLE, u as roleManifest } from "./sources-vs5dGOsS.js";
14
- import { o as readMemberships } from "./postgrest-DAjUkF9w.js";
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";
6
+ import { i as readJsonFile, o as sqlFiles, s as writeFileEnsuringDir } from "./files-BSjrtIHw.js";
7
+ import { a as SUPABASE_MANIFEST_SCHEMA } from "./version-DMQ0dnN5.js";
8
+ import { c as requirePolicy } from "./load-DjSU5KXO.js";
9
+ import { i as qualifySqlTable } from "./sql-0WjxIp9g.js";
10
+ import { i as scopeColumn } from "./compile-EzEMB-7v.js";
11
+ import { t as authorizeSql } from "./supabase-BL1qJzzY.js";
12
+ import "./budget-BELja5A9.js";
13
+ import { a as hookApiNames, d as keptKeys, t as AUTHZ_VERSION_TABLE, u as roleManifest } from "./sources-CMAM-2A3.js";
14
+ import { o as readMemberships } from "./postgrest-D4nuPXIQ.js";
15
15
  import { t as beforeFirst } from "./text-BMFRfBqc.js";
16
- import { n as GRANTS_MARKER, r as HOOK_MARKER, s as hookMarkerFields } from "./markers-C6joDI3o.js";
16
+ import { n as GRANTS_MARKER, r as HOOK_MARKER, s as hookMarkerFields } from "./markers-BeHZ4x9Q.js";
17
17
  import { n as formatManifestJson, t as MANIFEST_FILE } from "./manifest-json-CAGzls-C.js";
18
18
  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-DhRBBE4n.js";
20
- import { E as scopeTypeOf, F as quoteQualified, I as quoteTable, M as qualified, N as quoteIdent, O as tenantTypeOf, P as quoteLiteral, a as customRolesOn, l as USER_ID_HELPER, r as HELPERS, y as subjectIdSql } from "./shared-BAK8t4Uo.js";
21
- import { a as splitUndiffed, r as tableKey, t as decidingColumns } from "./deciding-columns-Sq12mEA6.js";
22
- import { a as readOnlyActorKinds, f as pgConnector, t as ACTOR_MAY_WRITE } from "./policies-DP2nqRoF.js";
23
- import { B as hasPermittedUsers, E as apiKeyFields, G as memberIdsHelper, H as memberForHelper, J as permittedIdsHelper, K as memberRoleOf, Q as activeRowSql, U as memberForSources, W as memberForTable, Z as scopeTable, a as guardedTables, c as PERMISSION_HELPERS, d as permissionKeysForHelper, et as checkSuspension, f as permittedByPermissionHelper, j as roleNames, l as checkName, o as ASSIGNMENTS, q as permittedForHelper, r as holderSources, s as OWNERSHIP, t as ownershipRules, v as globalRoleRows, w as API_KEY_ALLOWS, y as globalRoleSource, z as hasMemberFor } from "./ownership-DqaJNJPn.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-Afctg7B0.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-DeMNEy6V.js";
22
+ import { a as guardedTables, t as ownershipRules, u as roleNames } from "./ownership-B4L59T9u.js";
23
+ import { t as membershipSourcesOf } from "./sources-qoIJQrJv.js";
24
+ 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 { r as permittedUsersHelper, t as resolveNames } from "./resolve-names-CF7xXLSG.js";
27
+ import { c as ACTOR_MAY_WRITE, f as readOnlyActorKinds } from "./fields-D0vUI6dq.js";
24
28
  import { existsSync, readFileSync, readdirSync } from "node:fs";
25
29
  import { dirname, join, posix, resolve } from "node:path";
26
- import { parse } from "smol-toml";
30
+ //#region ../../node_modules/.pnpm/smol-toml@1.9.1/node_modules/smol-toml/dist/error.js
31
+ /*!
32
+ * Copyright (c) Squirrel Chat et al., All rights reserved.
33
+ * SPDX-License-Identifier: BSD-3-Clause
34
+ *
35
+ * Redistribution and use in source and binary forms, with or without
36
+ * modification, are permitted provided that the following conditions are met:
37
+ *
38
+ * 1. Redistributions of source code must retain the above copyright notice, this
39
+ * list of conditions and the following disclaimer.
40
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
41
+ * this list of conditions and the following disclaimer in the
42
+ * documentation and/or other materials provided with the distribution.
43
+ * 3. Neither the name of the copyright holder nor the names of its contributors
44
+ * may be used to endorse or promote products derived from this software without
45
+ * specific prior written permission.
46
+ *
47
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
48
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
49
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
50
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
51
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
52
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
53
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
54
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
55
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
56
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
57
+ */
58
+ function getLineColFromPtr(string, ptr) {
59
+ let lines = string.slice(0, ptr).split(/\r?\n/);
60
+ return [lines.length, lines.pop().length + 1];
61
+ }
62
+ function makeCodeBlock(string, line, column) {
63
+ let lines = string.split(/\r?\n/);
64
+ let codeblock = "";
65
+ let numberLen = (Math.log10(line + 1) | 0) + 1;
66
+ for (let i = line - 1; i <= line + 1; i++) {
67
+ let l = lines[i - 1];
68
+ if (!l) continue;
69
+ codeblock += i.toString().padEnd(numberLen, " ");
70
+ codeblock += ": ";
71
+ codeblock += l;
72
+ codeblock += "\n";
73
+ if (i === line) {
74
+ codeblock += " ".repeat(numberLen + column + 2);
75
+ codeblock += "^\n";
76
+ }
77
+ }
78
+ return codeblock;
79
+ }
80
+ var TomlError = class TomlError extends Error {
81
+ line;
82
+ column;
83
+ codeblock;
84
+ constructor(message, options) {
85
+ const [line, column] = getLineColFromPtr(options.toml, options.ptr);
86
+ const codeblock = makeCodeBlock(options.toml, line, column);
87
+ super(`Invalid TOML document: ${message}\n\n${codeblock}`, options);
88
+ this.line = line;
89
+ this.column = column;
90
+ this.codeblock = codeblock;
91
+ }
92
+ /** @internal */
93
+ static x(message, ctx, ptr) {
94
+ throw new TomlError(message, {
95
+ toml: ctx.s,
96
+ ptr: ptr ?? ctx.p
97
+ });
98
+ }
99
+ };
100
+ //#endregion
101
+ //#region ../../node_modules/.pnpm/smol-toml@1.9.1/node_modules/smol-toml/dist/primitive.js
102
+ /*!
103
+ * Copyright (c) Squirrel Chat et al., All rights reserved.
104
+ * SPDX-License-Identifier: BSD-3-Clause
105
+ *
106
+ * Redistribution and use in source and binary forms, with or without
107
+ * modification, are permitted provided that the following conditions are met:
108
+ *
109
+ * 1. Redistributions of source code must retain the above copyright notice, this
110
+ * list of conditions and the following disclaimer.
111
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
112
+ * this list of conditions and the following disclaimer in the
113
+ * documentation and/or other materials provided with the distribution.
114
+ * 3. Neither the name of the copyright holder nor the names of its contributors
115
+ * may be used to endorse or promote products derived from this software without
116
+ * specific prior written permission.
117
+ *
118
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
119
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
120
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
121
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
122
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
123
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
124
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
125
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
126
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
127
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
128
+ */
129
+ /** @internal */
130
+ function parseString(ctx) {
131
+ let startPtr = ctx.p;
132
+ let c = ctx.s.charCodeAt(ctx.p++);
133
+ let first = c;
134
+ let isLiteral = c === 39;
135
+ let isMultiline = c === ctx.s.charCodeAt(ctx.p) && c === ctx.s.charCodeAt(ctx.p + 1);
136
+ if (isMultiline) {
137
+ if ((c = ctx.s.charCodeAt(ctx.p += 2)) === 10) ctx.p++;
138
+ else if (c === 13 && ctx.s.charCodeAt(ctx.p + 1) === 10) ctx.p += 2;
139
+ }
140
+ let parsed = "";
141
+ let sliceStart = ctx.p;
142
+ let state = 0;
143
+ for (; ctx.p < ctx.s.length; ctx.p++) {
144
+ c = ctx.s.charCodeAt(ctx.p);
145
+ if (isMultiline && (c === 10 || c === 13 && ctx.s.charCodeAt(ctx.p + 1) === 10)) state = state && 3;
146
+ else if (c < 32 && c !== 9 || c === 127) TomlError.x("control characters are not allowed in strings", ctx);
147
+ else if ((!state || state === 3) && c === first && (!isMultiline || ctx.s.charCodeAt(ctx.p + 1) === first && ctx.s.charCodeAt(ctx.p + 2) === first)) {
148
+ if (isMultiline) {
149
+ if (ctx.s.charCodeAt(ctx.p + 3) === first) ctx.p++;
150
+ if (ctx.s.charCodeAt(ctx.p + 3) === first) ctx.p++;
151
+ }
152
+ if (!state) {
153
+ let s = ctx.s.slice(sliceStart, ctx.p);
154
+ parsed = parsed ? parsed + s : s;
155
+ }
156
+ ctx.p += isMultiline ? 3 : 1;
157
+ return parsed;
158
+ } else if (!state) {
159
+ if (!isLiteral && c === 92) {
160
+ parsed += ctx.s.slice(sliceStart, sliceStart = ctx.p);
161
+ state = 1;
162
+ }
163
+ } else if (state === 1) {
164
+ if (c === 120 || c === 117 || c === 85) {
165
+ let errPtr = ctx.p++ - 1;
166
+ let value = 0;
167
+ let len = c === 120 ? 2 : c === 117 ? 4 : 8;
168
+ for (let j = 0; j < len; j++, ctx.p++) {
169
+ let hex = ctx.s.charCodeAt(ctx.p);
170
+ let digit = hex >= 48 && hex <= 57 ? hex - 48 : hex >= 65 && hex <= 70 ? hex - 65 + 10 : hex >= 97 && hex <= 102 ? hex - 97 + 10 : -1;
171
+ if (digit < 0) TomlError.x("invalid non-hex character in unicode escape", ctx);
172
+ value = value << 4 | digit;
173
+ }
174
+ if (value < 0 || value > 1114111 || value >= 55296 && value <= 57343) TomlError.x("invalid unicode escape", ctx, errPtr);
175
+ parsed += String.fromCodePoint(value);
176
+ sliceStart = ctx.p--;
177
+ state = 0;
178
+ } else if (isMultiline && (c === 32 || c === 9)) state = 2;
179
+ else {
180
+ if (c === 98) parsed += "\b";
181
+ else if (c === 116) parsed += " ";
182
+ else if (c === 110) parsed += "\n";
183
+ else if (c === 102) parsed += "\f";
184
+ else if (c === 114) parsed += "\r";
185
+ else if (c === 101) parsed += "\x1B";
186
+ else if (c === 34) parsed += "\"";
187
+ else if (c === 92) parsed += "\\";
188
+ else TomlError.x("unrecognised escape sequence", ctx);
189
+ sliceStart = ctx.p + 1;
190
+ state = 0;
191
+ }
192
+ } else if (c !== 32 && c !== 9) {
193
+ if (state === 2) TomlError.x("invalid escape: only line-ending whitespace may be escaped", ctx, sliceStart);
194
+ state = !isLiteral && c === 92 ? 1 : 0;
195
+ sliceStart = ctx.p;
196
+ }
197
+ }
198
+ TomlError.x("unfinished string", ctx, startPtr);
199
+ }
200
+ //#endregion
201
+ //#region ../../node_modules/.pnpm/smol-toml@1.9.1/node_modules/smol-toml/dist/date.js
202
+ /*!
203
+ * Copyright (c) Squirrel Chat et al., All rights reserved.
204
+ * SPDX-License-Identifier: BSD-3-Clause
205
+ *
206
+ * Redistribution and use in source and binary forms, with or without
207
+ * modification, are permitted provided that the following conditions are met:
208
+ *
209
+ * 1. Redistributions of source code must retain the above copyright notice, this
210
+ * list of conditions and the following disclaimer.
211
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
212
+ * this list of conditions and the following disclaimer in the
213
+ * documentation and/or other materials provided with the distribution.
214
+ * 3. Neither the name of the copyright holder nor the names of its contributors
215
+ * may be used to endorse or promote products derived from this software without
216
+ * specific prior written permission.
217
+ *
218
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
219
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
220
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
221
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
222
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
223
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
224
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
225
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
226
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
227
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
228
+ */
229
+ let DATE_TIME_RE = /^(\d{4}-\d{2}-\d{2})?[Tt ]?(?:(\d{2}):\d{2}(?::\d{2}(?:\.\d+)?)?)?(Z|z|[-+]\d{2}:\d{2})?$/i;
230
+ var TomlDate = class TomlDate extends Date {
231
+ #hasDate = false;
232
+ #hasTime = false;
233
+ #offset = null;
234
+ constructor(date, fasttype, unsafeDelim) {
235
+ let hasDate = true;
236
+ let hasTime = true;
237
+ let offset = "Z";
238
+ let c;
239
+ if (typeof date === "string") {
240
+ if (fasttype) prep: {
241
+ if (fasttype < 3) {
242
+ if (+date.slice(11, 13) > 23) {
243
+ date = "";
244
+ break prep;
245
+ }
246
+ if (fasttype === 2) {
247
+ offset = null;
248
+ date += "Z";
249
+ } else if ((c = date.charCodeAt(date.length - 1)) !== 90 && c !== 122) offset = date.slice(date.length - 6);
250
+ if (unsafeDelim) date = date.slice(0, 10) + "T" + date.slice(11);
251
+ } else if (fasttype === 4) date = +date.slice(0, 2) > 23 ? "" : `0000-01-01T${date}Z`;
252
+ hasDate = fasttype !== 4;
253
+ hasTime = fasttype !== 3;
254
+ }
255
+ else {
256
+ let match = date.match(DATE_TIME_RE);
257
+ if (match) {
258
+ if (!match[1]) {
259
+ hasDate = false;
260
+ date = `0000-01-01T${date}`;
261
+ }
262
+ hasTime = !!match[2];
263
+ hasTime && date[10] === " " && (date = date.replace(" ", "T"));
264
+ if (match[2] && +match[2] > 23) date = "";
265
+ else {
266
+ offset = match[3] || null;
267
+ if (!offset && hasTime) date += "Z";
268
+ }
269
+ } else date = "";
270
+ }
271
+ }
272
+ super(date);
273
+ if (!isNaN(this.getTime())) {
274
+ this.#hasDate = hasDate;
275
+ this.#hasTime = hasTime;
276
+ this.#offset = offset;
277
+ }
278
+ }
279
+ isDateTime() {
280
+ return this.#hasDate && this.#hasTime;
281
+ }
282
+ isLocal() {
283
+ return !this.#hasDate || !this.#hasTime || !this.#offset;
284
+ }
285
+ isDate() {
286
+ return this.#hasDate && !this.#hasTime;
287
+ }
288
+ isTime() {
289
+ return this.#hasTime && !this.#hasDate;
290
+ }
291
+ isValid() {
292
+ return this.#hasDate || this.#hasTime;
293
+ }
294
+ toISOString() {
295
+ let iso = super.toISOString();
296
+ if (this.isDate()) return iso.slice(0, 10);
297
+ if (this.isTime()) return iso.slice(11, 23);
298
+ if (this.#offset === null) return iso.slice(0, -1);
299
+ if (this.#offset === "Z" || this.#offset === "z") return iso;
300
+ let offset = +this.#offset.slice(1, 3) * 60 + +this.#offset.slice(4, 6);
301
+ offset = this.#offset[0] === "-" ? offset : -offset;
302
+ return (/* @__PURE__ */ new Date(this.getTime() - offset * 6e4)).toISOString().slice(0, -1) + this.#offset;
303
+ }
304
+ static wrapAsOffsetDateTime(jsDate, offset = "Z") {
305
+ let date = new TomlDate(jsDate);
306
+ date.#offset = offset;
307
+ return date;
308
+ }
309
+ static wrapAsLocalDateTime(jsDate) {
310
+ let date = new TomlDate(jsDate);
311
+ date.#offset = null;
312
+ return date;
313
+ }
314
+ static wrapAsLocalDate(jsDate) {
315
+ let date = new TomlDate(jsDate);
316
+ date.#hasTime = false;
317
+ date.#offset = null;
318
+ return date;
319
+ }
320
+ static wrapAsLocalTime(jsDate) {
321
+ let date = new TomlDate(jsDate);
322
+ date.#hasDate = false;
323
+ date.#offset = null;
324
+ return date;
325
+ }
326
+ };
327
+ //#endregion
328
+ //#region ../../node_modules/.pnpm/smol-toml@1.9.1/node_modules/smol-toml/dist/extract.js
329
+ /*!
330
+ * Copyright (c) Squirrel Chat et al., All rights reserved.
331
+ * SPDX-License-Identifier: BSD-3-Clause
332
+ *
333
+ * Redistribution and use in source and binary forms, with or without
334
+ * modification, are permitted provided that the following conditions are met:
335
+ *
336
+ * 1. Redistributions of source code must retain the above copyright notice, this
337
+ * list of conditions and the following disclaimer.
338
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
339
+ * this list of conditions and the following disclaimer in the
340
+ * documentation and/or other materials provided with the distribution.
341
+ * 3. Neither the name of the copyright holder nor the names of its contributors
342
+ * may be used to endorse or promote products derived from this software without
343
+ * specific prior written permission.
344
+ *
345
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
346
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
347
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
348
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
349
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
350
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
351
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
352
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
353
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
354
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
355
+ */
356
+ function isDigit(char, base = 10) {
357
+ return base === 16 ? char > 47 && char < 58 || char > 64 && char < 71 || char > 96 && char < 103 : char > 47 && char < 48 + base;
358
+ }
359
+ function isEndOfValue(char, delim) {
360
+ return char === 32 || char === 9 || char === 10 || char === 13 || delim && (char === delim || char === 44) || char === 35;
361
+ }
362
+ /** @internal */
363
+ function extractValue(ctx, end) {
364
+ let errPtr = ctx.p;
365
+ let c = ctx.s.charCodeAt(ctx.p);
366
+ if (c === 91 || c === 123) {
367
+ ctx.d-- || TomlError.x("document contains excessively nested structures. aborting.", ctx);
368
+ let value = c === 91 ? parseArray(ctx) : parseInlineTable(ctx);
369
+ ctx.d++;
370
+ return value;
371
+ }
372
+ if (c === 34 || c === 39) return parseString(ctx);
373
+ if (c === 116) {
374
+ if (ctx.s.charCodeAt(++ctx.p) !== 114 || ctx.s.charCodeAt(++ctx.p) !== 117 || ctx.s.charCodeAt(++ctx.p) !== 101) TomlError.x("invalid value", ctx, errPtr);
375
+ return ctx.p++, true;
376
+ }
377
+ if (c === 102) {
378
+ if (ctx.s.charCodeAt(++ctx.p) !== 97 || ctx.s.charCodeAt(++ctx.p) !== 108 || ctx.s.charCodeAt(++ctx.p) !== 115 || ctx.s.charCodeAt(++ctx.p) !== 101) TomlError.x("invalid value", ctx, errPtr);
379
+ return ctx.p++, false;
380
+ }
381
+ if (c === 43 || c === 45) return parseNumber(ctx, ctx.p, ctx.s.charCodeAt(++ctx.p), 44 - c, end);
382
+ if (ctx.s.charCodeAt(ctx.p + 4) === 45 && ctx.s.charCodeAt(ctx.p + 7) === 45) return parseDate(ctx, c, end);
383
+ if (ctx.s.charCodeAt(ctx.p + 2) === 58) return parseTime(ctx, c, end);
384
+ return parseNumber(ctx, ctx.p, c, 0, end);
385
+ }
386
+ function parseNumber(ctx, startPtr, startChr, sign, endChr) {
387
+ let c = startChr;
388
+ let state = 0;
389
+ let hasUnderscores = false;
390
+ if (c === 105) {
391
+ if (ctx.s.charCodeAt(++ctx.p) !== 110 || ctx.s.charCodeAt(++ctx.p) !== 102) TomlError.x("invalid value", ctx, startPtr);
392
+ return ctx.p++, (sign || 1) / 0;
393
+ }
394
+ if (c === 110) {
395
+ if (ctx.s.charCodeAt(++ctx.p) !== 97 || ctx.s.charCodeAt(++ctx.p) !== 110) TomlError.x("invalid value", ctx, startPtr);
396
+ return ctx.p++, NaN;
397
+ }
398
+ if (c === 48) {
399
+ if (++ctx.p >= ctx.s.length || isEndOfValue(c = ctx.s.charCodeAt(ctx.p), endChr)) return ctx.bi === true ? 0n : 0;
400
+ if (!sign) {
401
+ if (c === 120) return parseIntegerBaseN(ctx, startPtr, 16, endChr);
402
+ else if (c === 98) return parseIntegerBaseN(ctx, startPtr, 2, endChr);
403
+ else if (c === 111) return parseIntegerBaseN(ctx, startPtr, 8, endChr);
404
+ }
405
+ if (c === 46) state = 2;
406
+ else if (c === 101 || c === 69) state = 4;
407
+ else TomlError.x("illegal leading zero", ctx, startPtr);
408
+ } else if (!isDigit(c)) TomlError.x("invalid value", ctx, startPtr);
409
+ while (++ctx.p < ctx.s.length && (c = ctx.s.charCodeAt(ctx.p), !isEndOfValue(c, endChr))) {
410
+ if (!state) state = 1;
411
+ if (c === 95) {
412
+ if (!(state & 1)) TomlError.x("illegal underscore", ctx);
413
+ state += 11;
414
+ hasUnderscores = true;
415
+ } else if (state === 1 && c === 46) state = 2;
416
+ else if ((state === 1 || state === 3) && (c === 101 || c === 69)) state = 4;
417
+ else if (state === 4 && (c === 43 || c === 45)) state = 6;
418
+ else if (!isDigit(c)) TomlError.x(`illegal character in numeric literal`, ctx);
419
+ else if (state > 9) state -= 11;
420
+ else if (!(state & 1)) state++;
421
+ }
422
+ if (!state) {
423
+ let val = (startChr - 48) * (sign || 1);
424
+ return ctx.bi === true ? BigInt(val) : val;
425
+ }
426
+ if (!(state & 1)) TomlError.x("unfinished numeric value", ctx, startPtr);
427
+ let str = ctx.s.slice(startPtr, ctx.p);
428
+ if (hasUnderscores) str = str.replaceAll("_", "");
429
+ return state > 1 ? parseFloat(str) : parseInteger(ctx, str, 10, startPtr);
430
+ }
431
+ function parseIntegerBaseN(ctx, startPtr, base, endChr) {
432
+ let c, underscore = 1;
433
+ while (++ctx.p < ctx.s.length && (c = ctx.s.charCodeAt(ctx.p), !isEndOfValue(c, endChr))) if (c === 95) {
434
+ if (underscore & 1) TomlError.x("illegal underscore", ctx);
435
+ underscore = 3;
436
+ } else if (!isDigit(c, base)) TomlError.x(`illegal character in numeric literal`, ctx);
437
+ else if (underscore & 1) underscore--;
438
+ if (underscore & 1) TomlError.x("unfinished numeric value", ctx);
439
+ let str = ctx.s.slice(startPtr + 2, ctx.p);
440
+ if (underscore) str = str.replaceAll("_", "");
441
+ return parseInteger(ctx, str, base, startPtr);
442
+ }
443
+ function parseInteger(ctx, str, base, startPtr) {
444
+ if (ctx.bi !== true) int: {
445
+ let val = parseInt(str, base);
446
+ if (!Number.isSafeInteger(val)) {
447
+ if (ctx.bi) break int;
448
+ TomlError.x("integer value cannot be represented losslessly", ctx, startPtr);
449
+ }
450
+ return val;
451
+ }
452
+ return base === 10 ? BigInt(str) : BigInt((base === 2 ? "0b" : base === 8 ? "0o" : "0x") + str);
453
+ }
454
+ function parseDate(ctx, c, endChr) {
455
+ let startPtr = ctx.p++, unsafeSeparator;
456
+ if (!isDigit(c) || !isDigit(ctx.s.charCodeAt(ctx.p++)) || !isDigit(ctx.s.charCodeAt(ctx.p++)) || !isDigit(ctx.s.charCodeAt(ctx.p++))) return parseNumber(ctx, ctx.p = startPtr, c, 0, endChr);
457
+ ctx.p += 5;
458
+ if (!isDigit(ctx.s.charCodeAt(ctx.p++))) TomlError.x("invalid date-time: date part is malformed", ctx, startPtr);
459
+ if (ctx.p >= ctx.s.length || ((c = ctx.s.charCodeAt(ctx.p)) !== 32 || (unsafeSeparator = true, !isDigit(ctx.s.charCodeAt(ctx.p + 1)))) && c !== 84 && c !== 116) return readDate(ctx, ctx.s.slice(startPtr, ctx.p), 3, false, startPtr);
460
+ if (ctx.s.charCodeAt(ctx.p += 3) !== 58) TomlError.x("invalid date-time: time part is malformed", ctx, startPtr);
461
+ if (ctx.s.charCodeAt(ctx.p += 3) === 58) ctx.p += 3;
462
+ if (ctx.s.charCodeAt(ctx.p) === 46) while (isDigit(ctx.s.charCodeAt(++ctx.p)));
463
+ if (c = ctx.s.charCodeAt(ctx.p)) {
464
+ if (c === 90 || c === 122) return readDate(ctx, ctx.s.slice(startPtr, ++ctx.p), 1, unsafeSeparator, startPtr, "[+00:00]");
465
+ if (c === 43 || c === 45) return readDate(ctx, ctx.s.slice(startPtr, ctx.p += 6), 1, unsafeSeparator, startPtr, !ctx.ld && "[" + ctx.s.slice(ctx.p - 6, ctx.p) + "]");
466
+ }
467
+ return readDate(ctx, ctx.s.slice(startPtr, ctx.p), 2, unsafeSeparator, startPtr);
468
+ }
469
+ function parseTime(ctx, c, endChr) {
470
+ let start = ctx.p;
471
+ if (!isDigit(c) || !isDigit(ctx.s.charCodeAt(++ctx.p))) return parseNumber(ctx, --ctx.p, c, 0, endChr);
472
+ if (ctx.s.charCodeAt(ctx.p += 4) === 58) ctx.p += 3;
473
+ if (ctx.s.charCodeAt(ctx.p) === 46) while (isDigit(ctx.s.charCodeAt(++ctx.p)));
474
+ return readDate(ctx, ctx.s.slice(start, ctx.p), 4, false, start);
475
+ }
476
+ function readDate(ctx, str, type, unsafeDelim, errPtr, temporalSuffix) {
477
+ if (ctx.ld) {
478
+ let date = new TomlDate(str, type, unsafeDelim);
479
+ if (!date.isValid()) TomlError.x("invalid date", ctx, errPtr);
480
+ return date;
481
+ }
482
+ try {
483
+ if (temporalSuffix) str += temporalSuffix;
484
+ switch (type) {
485
+ case 1: return Temporal.ZonedDateTime.from(str);
486
+ case 2: return Temporal.PlainDateTime.from(str);
487
+ case 3: return Temporal.PlainDate.from(str);
488
+ case 4: return Temporal.PlainTime.from(str);
489
+ }
490
+ } catch (e) {
491
+ TomlError.x(e instanceof Error ? e.message : "" + e, ctx, errPtr);
492
+ }
493
+ }
494
+ //#endregion
495
+ //#region ../../node_modules/.pnpm/smol-toml@1.9.1/node_modules/smol-toml/dist/util.js
496
+ /*!
497
+ * Copyright (c) Squirrel Chat et al., All rights reserved.
498
+ * SPDX-License-Identifier: BSD-3-Clause
499
+ *
500
+ * Redistribution and use in source and binary forms, with or without
501
+ * modification, are permitted provided that the following conditions are met:
502
+ *
503
+ * 1. Redistributions of source code must retain the above copyright notice, this
504
+ * list of conditions and the following disclaimer.
505
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
506
+ * this list of conditions and the following disclaimer in the
507
+ * documentation and/or other materials provided with the distribution.
508
+ * 3. Neither the name of the copyright holder nor the names of its contributors
509
+ * may be used to endorse or promote products derived from this software without
510
+ * specific prior written permission.
511
+ *
512
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
513
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
514
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
515
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
516
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
517
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
518
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
519
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
520
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
521
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
522
+ */
523
+ /** @internal */
524
+ function skipComment(ctx) {
525
+ for (; ctx.p < ctx.s.length; ctx.p++) {
526
+ let c = ctx.s.charCodeAt(ctx.p);
527
+ if (c === 10) break;
528
+ if (c === 13 && ctx.s.charCodeAt(ctx.p + 1) === 10) {
529
+ ctx.p++;
530
+ break;
531
+ }
532
+ if (c < 32 && c !== 9 || c === 127) TomlError.x("control characters are not allowed in comments", ctx);
533
+ }
534
+ }
535
+ /** @internal */
536
+ function skipVoid(ctx, banNewLines, banComments) {
537
+ let c;
538
+ while (ctx.p < ctx.s.length) {
539
+ while (ctx.p < ctx.s.length && ((c = ctx.s.charCodeAt(ctx.p)) === 32 || c === 9 || !banNewLines && (c === 10 || c === 13 && ctx.s.charCodeAt(ctx.p + 1) === 10))) ctx.p++;
540
+ if (banComments || c !== 35) break;
541
+ skipComment(ctx);
542
+ }
543
+ }
544
+ //#endregion
545
+ //#region ../../node_modules/.pnpm/smol-toml@1.9.1/node_modules/smol-toml/dist/struct.js
546
+ /*!
547
+ * Copyright (c) Squirrel Chat et al., All rights reserved.
548
+ * SPDX-License-Identifier: BSD-3-Clause
549
+ *
550
+ * Redistribution and use in source and binary forms, with or without
551
+ * modification, are permitted provided that the following conditions are met:
552
+ *
553
+ * 1. Redistributions of source code must retain the above copyright notice, this
554
+ * list of conditions and the following disclaimer.
555
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
556
+ * this list of conditions and the following disclaimer in the
557
+ * documentation and/or other materials provided with the distribution.
558
+ * 3. Neither the name of the copyright holder nor the names of its contributors
559
+ * may be used to endorse or promote products derived from this software without
560
+ * specific prior written permission.
561
+ *
562
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
563
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
564
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
565
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
566
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
567
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
568
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
569
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
570
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
571
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
572
+ */
573
+ /** @internal */
574
+ function parseKey(ctx, end = 61) {
575
+ let startPtr;
576
+ let state = 0;
577
+ let parsed = [];
578
+ let sliceStart;
579
+ let c = ctx.s.charCodeAt(startPtr = ctx.p);
580
+ do
581
+ if (c === end) {
582
+ if (!state) TomlError.x("unexpected end of key", ctx);
583
+ if (state === 1) parsed.push(ctx.s.slice(sliceStart, ctx.p));
584
+ return ctx.p++, parsed;
585
+ } else if (c === 46) {
586
+ if (!state) TomlError.x("illegal empty bare key", ctx);
587
+ if (state === 1) parsed.push(ctx.s.slice(sliceStart, ctx.p));
588
+ state = 0;
589
+ } else if (!state && (c === 34 || c === 39)) {
590
+ if (c === ctx.s.charCodeAt(ctx.p + 1) && c === ctx.s.charCodeAt(ctx.p + 2)) TomlError.x("illegal quoted key: multiline strings are not allowed", ctx);
591
+ parsed.push(parseString(ctx));
592
+ state = 2;
593
+ ctx.p--;
594
+ } else if (c === 32 || c === 9) {
595
+ if (state === 1) {
596
+ parsed.push(ctx.s.slice(sliceStart, ctx.p));
597
+ state = 2;
598
+ }
599
+ } else if (state === 2 || c < 48 && c !== 45 || c > 57 && c < 65 || c > 90 && c < 97 && c !== 95 || c > 122) TomlError.x("illegal character in key", ctx);
600
+ else if (!state) {
601
+ state = 1;
602
+ sliceStart = ctx.p;
603
+ }
604
+ while (c = ctx.s.charCodeAt(++ctx.p));
605
+ TomlError.x("incomplete key-value: cannot find end of key", ctx, startPtr);
606
+ }
607
+ /** @internal */
608
+ function parseInlineTable(ctx) {
609
+ let startPtr = ctx.p++;
610
+ let res = Object.create(null);
611
+ let seen = /* @__PURE__ */ new Set();
612
+ let c;
613
+ while (ctx.p < ctx.s.length) {
614
+ skipVoid(ctx);
615
+ if ((c = ctx.s.charCodeAt(ctx.p)) === 125) {
616
+ ctx.p++;
617
+ return res;
618
+ }
619
+ let k;
620
+ let t = res;
621
+ let hasOwn = false;
622
+ let errPtr = ctx.p;
623
+ let key = parseKey(ctx);
624
+ for (let i = 0; i < key.length; i++) {
625
+ if (i) t = hasOwn ? t[k] : t[k] = Object.create(null);
626
+ k = key[i];
627
+ if ((hasOwn = Object.hasOwn(t, k)) && (typeof t[k] !== "object" || seen.has(t[k]))) TomlError.x("trying to redefine an already defined value", ctx, errPtr);
628
+ let unsafe = k === "__proto__";
629
+ if (ctx.uk && (unsafe || k === "constructor")) {
630
+ t = ctx.uk !== 1 && TomlError.x("document contains an unsafe property", ctx, errPtr);
631
+ break;
632
+ }
633
+ if (!hasOwn && unsafe) Object.defineProperty(t, k, {
634
+ enumerable: true,
635
+ configurable: true,
636
+ writable: true
637
+ });
638
+ }
639
+ if (hasOwn) TomlError.x("trying to redefine an already defined value", ctx, errPtr);
640
+ skipVoid(ctx, true, true);
641
+ let value = extractValue(ctx, 125);
642
+ if (t && typeof (t[k] = value) === "object") seen.add(value);
643
+ skipVoid(ctx);
644
+ if ((c = ctx.s.charCodeAt(ctx.p++)) === 125) return res;
645
+ if (c !== 44) TomlError.x("expected comma or end of structure", ctx, ctx.p - 1);
646
+ }
647
+ TomlError.x("unfinished table", ctx, startPtr);
648
+ }
649
+ /** @internal */
650
+ function parseArray(ctx) {
651
+ let startPtr = ctx.p++;
652
+ let res = [];
653
+ let c;
654
+ while (ctx.p < ctx.s.length) {
655
+ skipVoid(ctx);
656
+ if ((c = ctx.s.charCodeAt(ctx.p)) === 93) {
657
+ ctx.p++;
658
+ return res;
659
+ }
660
+ res.push(extractValue(ctx, 93));
661
+ skipVoid(ctx);
662
+ if ((c = ctx.s.charCodeAt(ctx.p++)) === 93) return res;
663
+ if (c !== 44) TomlError.x("expected comma or end of structure", ctx, ctx.p - 1);
664
+ }
665
+ TomlError.x("unfinished array", ctx, startPtr);
666
+ }
667
+ //#endregion
668
+ //#region ../../node_modules/.pnpm/smol-toml@1.9.1/node_modules/smol-toml/dist/parse.js
669
+ /*!
670
+ * Copyright (c) Squirrel Chat et al., All rights reserved.
671
+ * SPDX-License-Identifier: BSD-3-Clause
672
+ *
673
+ * Redistribution and use in source and binary forms, with or without
674
+ * modification, are permitted provided that the following conditions are met:
675
+ *
676
+ * 1. Redistributions of source code must retain the above copyright notice, this
677
+ * list of conditions and the following disclaimer.
678
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
679
+ * this list of conditions and the following disclaimer in the
680
+ * documentation and/or other materials provided with the distribution.
681
+ * 3. Neither the name of the copyright holder nor the names of its contributors
682
+ * may be used to endorse or promote products derived from this software without
683
+ * specific prior written permission.
684
+ *
685
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
686
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
687
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
688
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
689
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
690
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
691
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
692
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
693
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
694
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
695
+ */
696
+ function peekTable(ctx, key, table, meta, type) {
697
+ let t = table;
698
+ let m = meta;
699
+ let k;
700
+ let hasOwn = false;
701
+ let state;
702
+ for (let i = 0; i < key.length; i++) {
703
+ if (i) {
704
+ t = hasOwn ? t[k] : t[k] = Object.create(null);
705
+ m = (state = m[k]).c;
706
+ if (type === 0 && (state.t === 1 || state.t === 2)) return null;
707
+ if (state.t === 2) {
708
+ let l = t.length - 1;
709
+ t = t[l];
710
+ m = m[l].c;
711
+ }
712
+ }
713
+ k = key[i];
714
+ if ((hasOwn = Object.hasOwn(t, k)) && m[k]?.t === 0 && m[k]?.d) return null;
715
+ if (!hasOwn) {
716
+ let unsafe = k === "__proto__";
717
+ if (ctx.uk && (unsafe || k === "constructor")) return false;
718
+ if (unsafe) {
719
+ Object.defineProperty(t, k, {
720
+ enumerable: true,
721
+ configurable: true,
722
+ writable: true
723
+ });
724
+ Object.defineProperty(m, k, {
725
+ enumerable: true,
726
+ configurable: true,
727
+ writable: true
728
+ });
729
+ }
730
+ m[k] = {
731
+ t: i < key.length - 1 && type === 2 ? 3 : type,
732
+ d: false,
733
+ i: 0,
734
+ c: Object.create(null)
735
+ };
736
+ }
737
+ }
738
+ state = m[k];
739
+ if (state.t !== type && !(type === 1 && state.t === 3)) return null;
740
+ if (type === 2) {
741
+ if (!state.d) {
742
+ state.d = true;
743
+ t[k] = [];
744
+ }
745
+ t[k].push(t = Object.create(null));
746
+ state.c[state.i++] = state = {
747
+ t: 1,
748
+ d: false,
749
+ i: 0,
750
+ c: Object.create(null)
751
+ };
752
+ }
753
+ if (state.d) return null;
754
+ state.d = true;
755
+ if (type === 1) t = hasOwn ? t[k] : t[k] = Object.create(null);
756
+ else if (type === 0 && hasOwn) return null;
757
+ return [
758
+ k,
759
+ t,
760
+ state.c
761
+ ];
762
+ }
763
+ function validateTablePeek(ctx, peek, ptr) {
764
+ if (peek === null || ctx.uk === 2) TomlError.x(peek === null ? "trying to redefine an already defined table or value" : "document contains an unsafe property", ctx, ptr);
765
+ }
766
+ function parse(toml, options = {}) {
767
+ let ctx = {
768
+ s: toml,
769
+ p: 0,
770
+ d: options.maxDepth ?? 1e3,
771
+ bi: options.integersAsBigInt ?? false,
772
+ ld: options.useLegacyDate ?? true,
773
+ uk: options.unsafeKeyBehaviour === "throw" ? 2 : options.unsafeKeyBehaviour === "drop" ? 1 : 0
774
+ };
775
+ let res = Object.create(null);
776
+ let meta = Object.create(null);
777
+ let tmp;
778
+ let skipping = false;
779
+ let tbl = res;
780
+ let m = meta;
781
+ if (toml.charCodeAt(0) === 65279) ctx.p++;
782
+ skipVoid(ctx);
783
+ while (ctx.p < toml.length) {
784
+ if (toml.charCodeAt(ctx.p) === 91) {
785
+ let isTableArray = toml.charCodeAt(++ctx.p) === 91;
786
+ tmp = ctx.p += +isTableArray;
787
+ skipping = false;
788
+ let k = parseKey(ctx, 93);
789
+ if (isTableArray) {
790
+ if (toml.charCodeAt(ctx.p) !== 93) TomlError.x("expected end of table array declaration", ctx);
791
+ ctx.p++;
792
+ }
793
+ let p = peekTable(ctx, k, res, meta, isTableArray ? 2 : 1);
794
+ if (!p) {
795
+ validateTablePeek(ctx, p, tmp);
796
+ skipping = true;
797
+ } else {
798
+ m = p[2];
799
+ tbl = p[1];
800
+ }
801
+ } else {
802
+ tmp = ctx.p;
803
+ let p = peekTable(ctx, parseKey(ctx), tbl, m, 0);
804
+ if (!p && !skipping) validateTablePeek(ctx, p, tmp);
805
+ skipVoid(ctx, true, true);
806
+ let v = extractValue(ctx, void 0);
807
+ if (p && !skipping) p[1][p[0]] = v;
808
+ }
809
+ skipVoid(ctx, true);
810
+ if (ctx.p < toml.length && (tmp = toml.charCodeAt(ctx.p)) !== 10 && (tmp !== 13 || toml.charCodeAt(ctx.p + 1) !== 10)) TomlError.x("each key-value declaration must be followed by an end-of-line", ctx);
811
+ skipVoid(ctx);
812
+ }
813
+ return res;
814
+ }
815
+ //#endregion
816
+ //#region src/cli/rls/rbac.ts
817
+ /**
818
+ * Where the helpers read roles and memberships: the flag, `rls.authorize`,
819
+ * `rls.rbac.authorize`, then `database` with `rls.membershipSources`, with
820
+ * `--rbac` or with a mapped memberships table, else `jwt`.
821
+ */
822
+ function resolveAuthorize(config, flags = {}) {
823
+ const rls = config.rls;
824
+ const explicit = flags.authorize ?? rls?.authorize ?? rls?.rbac?.authorize;
825
+ if (explicit !== void 0) return explicit;
826
+ if (rls?.membershipSources !== void 0 || flags.rbac === true) return "database";
827
+ const memberships = flags.memberships ?? rls?.memberships;
828
+ return Object.keys(memberships?.scopes ?? {}).length > 0 ? "database" : "jwt";
829
+ }
830
+ function parseRbacAuthorize(raw) {
831
+ if (raw === void 0) return;
832
+ if (raw === "database" || raw === "jwt") return raw;
833
+ throw configError(`PermDock CLI: --authorize must be database or jwt, got '${raw}'`);
834
+ }
835
+ function hookUri(schema) {
836
+ return `pg-functions://postgres/${schema}/custom_access_token_hook`;
837
+ }
838
+ function createEnum(schema, name, values) {
839
+ const list = values.map((value) => quoteLiteral(value)).join(", ");
840
+ return `do $$ begin
841
+ create type ${quoteTable(`${schema}.${name}`)} as enum (${list});
842
+ exception when duplicate_object then null;
843
+ end $$;`;
844
+ }
845
+ /**
846
+ * A read policy and `select` grant for `supabase_auth_admin` on a table the
847
+ * hook reads.
848
+ */
849
+ function authAdminRead(table, label) {
850
+ const t = quoteQualified(table);
851
+ const policy = quoteIdent(`permdock_auth_admin_read_${label}`);
852
+ return `grant select on table ${t} to supabase_auth_admin;
853
+ drop policy if exists ${policy} on ${t};
854
+ create policy ${policy} on ${t}
855
+ as permissive for select
856
+ to supabase_auth_admin
857
+ using (true);`;
858
+ }
859
+ /**
860
+ * Supabase's Custom Claims and RBAC scaffold on top of the PermDock helpers:
861
+ * enums, `user_roles` and `authorize()` over the shared `role_permissions`. The
862
+ * token hook comes only from `permdock supabase hook generate`, so one function
863
+ * writes the claims. Policies never call `authorize()` per row; they call the
864
+ * helpers. Never grants anything to `service_role`.
865
+ */
866
+ function rbacScaffold(policy, options) {
867
+ const schema = options.schema;
868
+ const q = (name) => quoteTable(`${schema}.${name}`);
869
+ const s = quoteIdent(schema);
870
+ const permissions = [...new Set(policy.grants.map((grant) => grant.permission.key))];
871
+ const authorizeFn = authorizeSql({
872
+ schema,
873
+ authorize: options.authorize,
874
+ ...options.scope === void 0 ? {} : { scope: options.scope },
875
+ ...options.memberships === void 0 ? {} : { tenant: options.memberships },
876
+ ...options.customRoles === void 0 ? {} : { customRoles: options.customRoles },
877
+ ...options.context?.suspension === void 0 ? {} : { suspension: options.context.suspension }
878
+ });
879
+ return {
880
+ head: `-- rbac scaffold (Supabase Custom Claims and RBAC)
881
+ -- authorize: ${options.authorize}${options.authorize === "jwt" ? " (reads the hook claims; stale until the token refreshes)" : " (reads user_roles on every statement)"}
882
+ -- the custom access token hook that writes user_role${options.authorize === "jwt" ? " and memberships" : ""}: permdock supabase hook generate
883
+ ${schema === "public" ? "" : `create schema if not exists ${s};\n`}${createEnum(schema, "app_role", roleNames(policy))}
884
+ ${createEnum(schema, "app_permission", permissions)}
885
+
886
+ create table if not exists ${q("user_roles")} (
887
+ user_id uuid not null references auth.users on delete cascade,
888
+ role ${options.customRoles === void 0 ? q("app_role") : "text"} not null,
889
+ primary key (user_id, role)
890
+ );
891
+
892
+ alter table ${q("user_roles")} enable row level security;
893
+ revoke all on table ${q("user_roles")} from authenticated, anon, public;
894
+ `,
895
+ tail: authorizeFn,
896
+ warnings: []
897
+ };
898
+ }
899
+ //#endregion
27
900
  //#region src/cli/supabase-config.ts
28
901
  const SUPABASE_CONFIG = "supabase/config.toml";
29
902
  function table(value) {
@@ -50,6 +923,9 @@ function readSupabaseConfig(cwd) {
50
923
  const paths = table(table(root["db"])?.["migrations"])?.["schema_paths"];
51
924
  const schemaPaths = strings(paths);
52
925
  const apiSchemas = strings(table(root["api"])?.["schemas"]);
926
+ const hookTable = table(table(table(root["auth"])?.["hook"])?.["custom_access_token"]);
927
+ const hookEnabled = hookTable?.["enabled"];
928
+ const hookUriValue = hookTable?.["uri"];
53
929
  const pgDelta = table(table(root["experimental"])?.["pgdelta"]);
54
930
  const schemaPath = pgDelta?.["declarative_schema_path"];
55
931
  const enabled = pgDelta?.["enabled"];
@@ -59,6 +935,10 @@ function readSupabaseConfig(cwd) {
59
935
  ...typeof expiry === "number" ? { jwtExpiry: expiry } : {},
60
936
  ...schemaPaths === void 0 ? {} : { schemaPaths },
61
937
  ...apiSchemas === void 0 ? {} : { apiSchemas },
938
+ ...hookTable === void 0 ? {} : { customAccessTokenHook: {
939
+ ...typeof hookEnabled === "boolean" ? { enabled: hookEnabled } : {},
940
+ ...typeof hookUriValue === "string" ? { uri: hookUriValue } : {}
941
+ } },
62
942
  ...pgDelta === void 0 ? {} : { pgDelta: {
63
943
  ...typeof enabled === "boolean" ? { enabled } : {},
64
944
  schemaDir: declarativeSchemaDir(schemaPath)
@@ -66,16 +946,25 @@ function readSupabaseConfig(cwd) {
66
946
  }
67
947
  };
68
948
  }
69
- /** `supabase/` joined with `declarative_schema_path`, which defaults to `schemas`. */
949
+ /**
950
+ * `supabase/` joined with `declarative_schema_path`, which defaults to
951
+ * `schemas`.
952
+ */
70
953
  function declarativeSchemaDir(schemaPath) {
71
954
  return posix.join("supabase", typeof schemaPath === "string" ? schemaPath : "schemas").replace(/\/$/u, "");
72
955
  }
73
- /** The parsed config, or `{}` when it is missing or does not parse (PD045 reports that). */
956
+ /**
957
+ * The parsed config, or `{}` when it is missing or does not parse (PD045
958
+ * reports that).
959
+ */
74
960
  function supabaseConfig(cwd) {
75
961
  const read = readSupabaseConfig(cwd);
76
962
  return read?.ok === true ? read.config : {};
77
963
  }
78
- /** PD045: a `supabase/config.toml` the CLI cannot parse, so every check that reads it falls back to defaults. */
964
+ /**
965
+ * PD045: a `supabase/config.toml` the CLI cannot parse, so every check that
966
+ * reads it falls back to defaults.
967
+ */
79
968
  function pd045(cwd) {
80
969
  const read = readSupabaseConfig(cwd);
81
970
  if (read === void 0 || read.ok) return [];
@@ -86,6 +975,32 @@ function pd045(cwd) {
86
975
  fix: `fix the TOML syntax in ${SUPABASE_CONFIG}; until then PermDock assumes Supabase's defaults for jwt_expiry, schema_paths and [experimental.pgdelta], and generates for pg-delta`
87
976
  }];
88
977
  }
978
+ /**
979
+ * PD074: `supabase.hook` is configured but `[auth.hook.custom_access_token]` in
980
+ * `supabase/config.toml` does not enable the generated function, so a local
981
+ * stack and every branch push issue tokens without memberships.
982
+ */
983
+ function pd074(cwd, config) {
984
+ const hook = config.supabase?.hook;
985
+ const read = readSupabaseConfig(cwd);
986
+ if (hook === void 0 || read === void 0 || !read.ok) return [];
987
+ const expected = hookUri(hook.schema ?? config.rls?.schema ?? "permdock");
988
+ const found = read.config.customAccessTokenHook;
989
+ const fix = `add to ${SUPABASE_CONFIG}:\n[auth.hook.custom_access_token]\nenabled = true\nuri = "${expected}"`;
990
+ if (found?.enabled !== true) return [{
991
+ code: "PD074",
992
+ severity: "warning",
993
+ message: `supabase.hook is configured but ${SUPABASE_CONFIG} does not set [auth.hook.custom_access_token] enabled = true, so Auth never calls the hook`,
994
+ fix
995
+ }];
996
+ if (found.uri !== expected) return [{
997
+ code: "PD074",
998
+ severity: "warning",
999
+ message: `[auth.hook.custom_access_token] uri is ${found.uri ?? "missing"}, but the generated hook is ${expected}`,
1000
+ fix: `set uri = "${expected}" in ${SUPABASE_CONFIG}`
1001
+ }];
1002
+ return [];
1003
+ }
89
1004
  //#endregion
90
1005
  //#region src/cli/claims-schema.ts
91
1006
  /**
@@ -123,6 +1038,11 @@ const PERMDOCK_CLAIMS_SCHEMA = {
123
1038
  description: "true when the size budget cut memberships or attrs.",
124
1039
  type: "boolean"
125
1040
  },
1041
+ team_ids: {
1042
+ description: "The uuid of every team the user belongs to (supabase.hook.teams), cut by the memberships budget.",
1043
+ type: "array",
1044
+ items: { type: "string" }
1045
+ },
126
1046
  tenant_id: {
127
1047
  description: "The active tenant (the default rls.tenantClaim): the canonical text of one instance of the first scope.",
128
1048
  type: "string"
@@ -221,8 +1141,8 @@ const USER_EDITABLE = /^(raw_)?user_meta(_)?data$/iu;
221
1141
  /**
222
1142
  * Splits `supabase.hook.attrs` into table columns and `app_metadata` keys and
223
1143
  * lists what cannot be compiled: `user_metadata` (the user can edit it), a
224
- * direct `auth.users` column, an unsafe or prototype key, a duplicate key,
225
- * or a table column without a table.
1144
+ * direct `auth.users` column, an unsafe or prototype key, a duplicate key, or a
1145
+ * table column without a table.
226
1146
  */
227
1147
  function attrsPlan(attrs) {
228
1148
  const errors = [];
@@ -268,6 +1188,7 @@ const RESERVED_CLAIMS = /* @__PURE__ */ new Set([
268
1188
  "user_role",
269
1189
  "memberships",
270
1190
  "memberships_truncated",
1191
+ "team_ids",
271
1192
  "attrs",
272
1193
  "authz_ver",
273
1194
  "sub",
@@ -336,8 +1257,8 @@ function beforeSql(before) {
336
1257
  }
337
1258
  /**
338
1259
  * `hook.validate`: the claims the hook writes, dropped together when they do
339
- * not match `supabase-claims-v1.json`, so a bad claim denies instead of
340
- * failing sign-in. `hook.claims` entries belong to other packages and stay.
1260
+ * not match `supabase-claims-v1.json`, so a bad claim denies instead of failing
1261
+ * sign-in. `hook.claims` entries belong to other packages and stay.
341
1262
  */
342
1263
  function validateSql(parts) {
343
1264
  if (parts.hook.validate !== true) return "";
@@ -346,6 +1267,7 @@ function validateSql(parts) {
346
1267
  "roles",
347
1268
  "memberships",
348
1269
  "memberships_truncated",
1270
+ ...parts.hook.teams === void 0 ? [] : ["team_ids"],
349
1271
  "attrs",
350
1272
  "authz_ver",
351
1273
  parts.tenantClaim
@@ -362,8 +1284,8 @@ grant usage on schema extensions to supabase_auth_admin;
362
1284
  grant execute on function extensions.jsonb_matches_schema(json, jsonb) to supabase_auth_admin;` : "";
363
1285
  }
364
1286
  /**
365
- * Fails the migration when a client role can write an `attrs` column: a
366
- * claim the user can set is not a server-owned attribute.
1287
+ * Fails the migration when a client role can write an `attrs` column: a claim
1288
+ * the user can set is not a server-owned attribute.
367
1289
  */
368
1290
  function attrsGuardSql(plan) {
369
1291
  if (plan?.table === void 0 || plan.columns.length === 0) return "";
@@ -398,6 +1320,7 @@ function hookClaims(parts) {
398
1320
  permdockClaim("memberships", true),
399
1321
  permdockClaim("memberships_truncated"),
400
1322
  permdockClaim(parts.tenantClaim),
1323
+ ...parts.hook.teams === void 0 ? [] : [permdockClaim("team_ids", true)],
401
1324
  ...parts.attrs === void 0 ? [] : [permdockClaim("attrs", true)],
402
1325
  ...parts.version ? [permdockClaim("authz_ver")] : [],
403
1326
  ...parts.extra.map((entry) => ({
@@ -408,6 +1331,19 @@ function hookClaims(parts) {
408
1331
  ];
409
1332
  }
410
1333
  //#endregion
1334
+ //#region src/cli/sql/declarative.ts
1335
+ /**
1336
+ * A migration's SQL as a declarative schema file: pg-delta diffs the file
1337
+ * against the database itself, so a `drop trigger if exists` or `drop policy if
1338
+ * exists` before its `create` is an error, and a trigger is `create or replace
1339
+ * trigger`. A constraint trigger stays `create constraint trigger`, because
1340
+ * pg-delta has no `create or replace constraint trigger`. A policy keeps its
1341
+ * plain `create policy`.
1342
+ */
1343
+ function declarativeSql(sql) {
1344
+ return sql.replaceAll(/^drop (?:trigger|policy) if exists [^;\n]+;\n/gmu, "").replaceAll(/^create trigger /gmu, "create or replace trigger ");
1345
+ }
1346
+ //#endregion
411
1347
  //#region src/cli/supabase-schemas.ts
412
1348
  const MODES = [
413
1349
  "pg-delta",
@@ -422,9 +1358,9 @@ function schemasRefusal(command, value) {
422
1358
  return value === void 0 || isSupabaseSchemas(value) ? void 0 : `${command} --schemas must be ${MODES.join(", ")} (got ${value})`;
423
1359
  }
424
1360
  /**
425
- * `--schemas`, else `supabase.schemas`, else `migra` when `config.toml`
426
- * sets `[experimental.pgdelta] enabled = false`, else `pg-delta`: the default
427
- * of new Supabase projects and of the next Supabase CLI major.
1361
+ * `--schemas`, else `supabase.schemas`, else `migra` when `config.toml` sets
1362
+ * `[experimental.pgdelta] enabled = false`, else `pg-delta`: the default of new
1363
+ * Supabase projects and of the next Supabase CLI major.
428
1364
  */
429
1365
  function resolveSchemas(cwd, config, flag) {
430
1366
  const toml = supabaseConfig(cwd).pgDelta;
@@ -445,7 +1381,10 @@ const HELPER_NAME = /^(?:permdock_has|permitted_[a-z][a-z0-9_]*_ids|member_[a-z]
445
1381
  function escape(text) {
446
1382
  return text.replaceAll(/[.*+?^${}()|[\]\\]/gu, String.raw`\$&`);
447
1383
  }
448
- /** The helper functions `sql` creates in `schema`; unqualified names count for `public`. */
1384
+ /**
1385
+ * The helper functions `sql` creates in `schema`; unqualified names count for
1386
+ * `public`.
1387
+ */
449
1388
  function helpersDefined(sql, schema) {
450
1389
  const qualifier = schema === "public" ? String.raw`(?:(?:"public"|public)\.)?` : String.raw`(?:"${escape(schema)}"|${escape(schema)})\.`;
451
1390
  const create = new RegExp(String.raw`\bcreate\s+(?:or\s+replace\s+)?function\s+${qualifier}"?([a-z_][a-z0-9_]*)"?\s*\(`, "giu");
@@ -457,9 +1396,9 @@ function helpersDefined(sql, schema) {
457
1396
  return names;
458
1397
  }
459
1398
  /**
460
- * SQL files that may hold the generated helpers: `rls.out` (else `rls.sql`;
461
- * its `helpers` part when it has `{part}`), the SQL files next to the hook,
462
- * and the migration folders, not the hook itself.
1399
+ * SQL files that may hold the generated helpers: `rls.out` (else `rls.sql`; its
1400
+ * `helpers` part when it has `{part}`), the SQL files next to the hook, and the
1401
+ * migration folders, not the hook itself.
463
1402
  */
464
1403
  function helperSources(cwd, config, hookOut) {
465
1404
  const hook = resolve(cwd, hookOut);
@@ -492,7 +1431,10 @@ where n.nspname = $1 and p.proname = any($2::text[])`, [manifest.helpers.schema,
492
1431
  function missingHelpersMessage(manifest, missing) {
493
1432
  return `PD039 schema ${manifest.helpers.schema} has no ${missing.join(", ")}: the hook's claims are read by these helpers; run permdock rls generate and apply its migration`;
494
1433
  }
495
- /** Bytes of JSON of each extra claim in the largest sample, for claims that pass the budget. */
1434
+ /**
1435
+ * Bytes of JSON of each extra claim in the largest sample, for claims that pass
1436
+ * the budget.
1437
+ */
496
1438
  function oversizedClaims(samples, manifest) {
497
1439
  const encoder = new TextEncoder();
498
1440
  const oversized = [];
@@ -576,87 +1518,6 @@ function readClaimsFixture(path) {
576
1518
  }
577
1519
  }
578
1520
  //#endregion
579
- //#region src/cli/rls/rbac.ts
580
- /**
581
- * Where the helpers read roles and memberships: the flag, `rls.authorize`,
582
- * `rls.rbac.authorize`, then `database` with `rls.membershipSources`, with
583
- * `--rbac` or with a mapped memberships table, else `jwt`.
584
- */
585
- function resolveAuthorize(config, flags = {}) {
586
- const rls = config.rls;
587
- const explicit = flags.authorize ?? rls?.authorize ?? rls?.rbac?.authorize;
588
- if (explicit !== void 0) return explicit;
589
- if (rls?.membershipSources !== void 0 || flags.rbac === true) return "database";
590
- const memberships = flags.memberships ?? rls?.memberships;
591
- return memberships?.tenant !== void 0 || memberships?.team !== void 0 || Object.keys(memberships?.scopes ?? {}).length > 0 ? "database" : "jwt";
592
- }
593
- function parseRbacAuthorize(raw) {
594
- if (raw === void 0) return;
595
- if (raw === "database" || raw === "jwt") return raw;
596
- throw configError(`PermDock CLI: --authorize must be database or jwt, got '${raw}'`);
597
- }
598
- function hookUri(schema) {
599
- return `pg-functions://postgres/${schema}/custom_access_token_hook`;
600
- }
601
- function createEnum(schema, name, values) {
602
- const list = values.map((value) => quoteLiteral(value)).join(", ");
603
- return `do $$ begin
604
- create type ${quoteTable(`${schema}.${name}`)} as enum (${list});
605
- exception when duplicate_object then null;
606
- end $$;`;
607
- }
608
- /** A read policy and `select` grant for `supabase_auth_admin` on a table the hook reads. */
609
- function authAdminRead(table, label) {
610
- const t = quoteQualified(table);
611
- const policy = quoteIdent(`permdock_auth_admin_read_${label}`);
612
- return `grant select on table ${t} to supabase_auth_admin;
613
- drop policy if exists ${policy} on ${t};
614
- create policy ${policy} on ${t}
615
- as permissive for select
616
- to supabase_auth_admin
617
- using (true);`;
618
- }
619
- /**
620
- * Supabase's Custom Claims and RBAC scaffold on top of the PermDock helpers:
621
- * enums, `user_roles` and `authorize()` over the shared `role_permissions`.
622
- * The token hook comes only from `permdock supabase hook generate`, so one
623
- * function writes the claims. Policies never call `authorize()` per row; they
624
- * call the helpers. Never grants anything to `service_role`.
625
- */
626
- function rbacScaffold(policy, options) {
627
- const schema = options.schema;
628
- const q = (name) => quoteTable(`${schema}.${name}`);
629
- const s = quoteIdent(schema);
630
- const permissions = [...new Set(policy.grants.map((grant) => grant.permission.key))];
631
- const authorizeFn = authorizeSql({
632
- schema,
633
- authorize: options.authorize,
634
- ...options.scope === void 0 ? {} : { scope: options.scope },
635
- ...options.memberships === void 0 ? {} : { tenant: options.memberships },
636
- ...options.customRoles === void 0 ? {} : { customRoles: options.customRoles },
637
- ...options.context?.suspension === void 0 ? {} : { suspension: options.context.suspension }
638
- });
639
- return {
640
- head: `-- rbac scaffold (Supabase Custom Claims and RBAC)
641
- -- authorize: ${options.authorize}${options.authorize === "jwt" ? " (reads the hook claims; stale until the token refreshes)" : " (reads user_roles on every statement)"}
642
- -- the custom access token hook that writes user_role${options.authorize === "jwt" ? " and memberships" : ""}: permdock supabase hook generate
643
- ${schema === "public" ? "" : `create schema if not exists ${s};\n`}${createEnum(schema, "app_role", roleNames(policy))}
644
- ${createEnum(schema, "app_permission", permissions)}
645
-
646
- create table if not exists ${q("user_roles")} (
647
- user_id uuid not null references auth.users on delete cascade,
648
- role ${options.customRoles === void 0 ? q("app_role") : "text"} not null,
649
- primary key (user_id, role)
650
- );
651
-
652
- alter table ${q("user_roles")} enable row level security;
653
- revoke all on table ${q("user_roles")} from authenticated, anon, public;
654
- `,
655
- tail: authorizeFn,
656
- warnings: []
657
- };
658
- }
659
- //#endregion
660
1521
  //#region src/cli/supabase-hook/memberships.ts
661
1522
  function memberForPlan(input) {
662
1523
  const memberFor = input.scopes.map((scope) => scope.name).filter((name) => hasMemberFor({
@@ -676,7 +1537,10 @@ function memberForPlan(input) {
676
1537
  memberships: [...entries.values()]
677
1538
  };
678
1539
  }
679
- /** An `rls.memberships` table in the manifest's `tableMembershipSource` / `junctionMembershipSource` shape, for scope `name`. */
1540
+ /**
1541
+ * An `rls.memberships` table in the manifest's `tableMembershipSource` /
1542
+ * `junctionMembershipSource` shape, for scope `name`.
1543
+ */
680
1544
  function mappedMembership(mapped, scopes, name) {
681
1545
  const id = scopeColumn(mapped, scopes, name) ?? "";
682
1546
  const within = {};
@@ -781,18 +1645,18 @@ ${source.sql.select(`v_user_${String(index)}`).replaceAll(/^/gmu, " ")}
781
1645
  //#region src/cli/supabase-hook/api.ts
782
1646
  const SUBJECT_FOR = "subject_for";
783
1647
  /**
784
- * `subject_for(p_user uuid) returns jsonb`: what the hook would put in a
785
- * token for `p_user`, from the same membership, role, suspension and version
786
- * reads, plus the custom roles the user holds when `database` mode keeps them
787
- * in tables. A backend that only has PostgREST (`postgrestSources`) builds a
788
- * subject for an acting user or a job from it. Naming the user is why no
789
- * client role may execute it.
1648
+ * `subject_for(p_user uuid) returns jsonb`: what the hook would put in a token
1649
+ * for `p_user`, from the same membership, role, suspension and version reads,
1650
+ * plus the custom roles the user holds when `database` mode keeps them in
1651
+ * tables. A backend that only has PostgREST (`postgrestSources`) builds a
1652
+ * subject for an acting user or a job from it. Naming the user is why no client
1653
+ * role may execute it.
790
1654
  */
791
1655
  function subjectForSql(parts, config) {
792
1656
  const schema = quoteIdent(parts.schema);
793
1657
  const fn = `${schema}.${SUBJECT_FOR}`;
794
1658
  const rows = parts.roles;
795
- const roles = rows === void 0 ? ` held := '[]'::jsonb;` : ` select coalesce(jsonb_agg(distinct ${rows.roleSql} order by ${rows.roleSql}), '[]'::jsonb)
1659
+ const roles = rows === void 0 ? ` held := '[]'::jsonb;` : ` select coalesce(jsonb_agg(distinct ${rows.roleSql} order by ${rows.roleSql}) filter (where ${rows.roleSql} is not null), '[]'::jsonb)
796
1660
  into held
797
1661
  from ${rows.from}
798
1662
  where ${rows.userSql} = v_roles_user;`;
@@ -803,6 +1667,20 @@ function subjectForSql(parts, config) {
803
1667
  const version = parts.version ? `
804
1668
  select v.version into ver from ${schema}.${quoteIdent(AUTHZ_VERSION_TABLE)} v where v.user_id = uid;
805
1669
  ver := coalesce(ver, 0);` : "";
1670
+ const teamsConfig = parts.hook.teams;
1671
+ const teams = teamsConfig === void 0 ? "" : `
1672
+ select coalesce(jsonb_agg(to_jsonb(t.${quoteIdent(teamsConfig.team)}::text) order by t.${quoteIdent(teamsConfig.team)}), '[]'::jsonb)
1673
+ into team_ids
1674
+ from ${quoteQualified(teamsConfig.table)} t
1675
+ where t.${quoteIdent(teamsConfig.user)} = uid;
1676
+ if team_ids <> '[]'::jsonb then
1677
+ claims := jsonb_set(claims, '{team_ids}', team_ids);
1678
+ end if;`;
1679
+ const extra = parts.extra.map((entry) => `
1680
+ extra := ${quoteTable(entry.fn)}(uid);
1681
+ if extra is not null then
1682
+ claims := jsonb_set(claims, ${quoteLiteral(`{${entry.claim}}`)}, extra);
1683
+ end if;`).join("");
806
1684
  const custom = customRolesOn(config.rls) && resolveAuthorize(config) === "database" ? customRolesOfSql(parts) : "";
807
1685
  return `-- the subject the hook would mint for p_user, for a backend acting for a stored user; no client role may execute it
808
1686
  create or replace function ${fn}(p_user uuid)
@@ -817,7 +1695,8 @@ declare
817
1695
  held jsonb;
818
1696
  memberships jsonb;
819
1697
  custom jsonb := '[]'::jsonb;
820
- ver bigint;${typedUsers(parts)}
1698
+ ver bigint;
1699
+ claims jsonb := '{}'::jsonb;${teamsConfig === void 0 ? "" : "\n team_ids jsonb := '[]'::jsonb;"}${parts.extra.length === 0 ? "" : "\n extra jsonb;"}${typedUsers(parts)}
821
1700
  begin
822
1701
  if uid is null or not exists (select 1 from auth.users u where u.id = uid) then
823
1702
  return null;
@@ -827,8 +1706,9 @@ ${roles}
827
1706
  into memberships
828
1707
  from (
829
1708
  ${entriesSql(parts).replaceAll(/^/gmu, " ")}
830
- ) x;${custom}${version}
1709
+ ) x;${custom}${version}${teams}${extra}
831
1710
  return jsonb_strip_nulls(jsonb_build_object(
1711
+ 'claims', case when claims = '{}'::jsonb then null else claims end,
832
1712
  'id', uid::text,
833
1713
  'active', true,
834
1714
  'roles', held,
@@ -841,8 +1721,11 @@ $$;
841
1721
  revoke execute on function ${fn}(uuid) from public, anon, authenticated;`;
842
1722
  }
843
1723
  /**
844
- * The PostgREST wrappers `supabase.hook.api` asks for: one `security definer`
1724
+ * The PostgREST wrappers `supabase.hook.api` asks for: one `security invoker`
845
1725
  * function per reader, in the API schema, executable by `service_role` only.
1726
+ * The `security definer` readers stay in the hook schema, which the Data API
1727
+ * does not expose; `service_role` gets `usage` on it and `execute` on each
1728
+ * reader, so no definer function sits in an exposed schema.
846
1729
  */
847
1730
  function apiWrappersSql(parts) {
848
1731
  const api = parts.hook.api;
@@ -857,13 +1740,16 @@ function apiWrappersSql(parts) {
857
1740
  returns ${returns}
858
1741
  language sql
859
1742
  stable
860
- security definer
1743
+ security invoker
861
1744
  set search_path = ''
862
1745
  as $$ select ${source}.${inner}(${args}) $$;
863
1746
  revoke execute on function ${fn}(${types}) from public, anon, authenticated;
864
- grant execute on function ${fn}(${types}) to service_role;`;
1747
+ grant execute on function ${fn}(${types}) to service_role;
1748
+ grant execute on function ${source}.${inner}(${types}) to service_role;`;
865
1749
  };
866
- return `-- supabase.hook.api: wrappers in ${quoteIdent(target)} for a backend that reaches the hook schema through the Data API; only service_role may execute them
1750
+ return `-- supabase.hook.api: security invoker wrappers in ${quoteIdent(target)} for a backend that reaches the hook schema through the Data API; only service_role may execute them, and the security definer readers stay in ${source}
1751
+ grant usage on schema ${source} to service_role;
1752
+
867
1753
  ${wrapper(names.subjectFor, SUBJECT_FOR, "p_user uuid", "p_user", "uuid", "jsonb")}
868
1754
 
869
1755
  ${wrapper(names.membersOf, MEMBERS_OF, "p_scope text, p_id text", "p_scope, p_id", "text, text", "jsonb")}
@@ -936,9 +1822,9 @@ revoke execute on function ${fn}(text, text) from public, anon, authenticated;`;
936
1822
  }
937
1823
  /**
938
1824
  * The custom roles `p_user` holds: tenant and shared roles named on a
939
- * membership of the scope (and instance) they live at, and platform roles
940
- * among the global roles, each with its grants and includes in `CustomRole`
941
- * form. A shadowed tenant role comes along; `resolveCustomRole`'s callers drop it.
1825
+ * membership of the scope (and instance) they live at, and platform roles among
1826
+ * the global roles, each with its grants and includes in `CustomRole` form. A
1827
+ * shadowed tenant role comes along; `resolveCustomRole`'s callers drop it.
942
1828
  */
943
1829
  function customRolesOfSql(parts) {
944
1830
  const helpers = quoteIdent(parts.helpers.schema);
@@ -989,9 +1875,15 @@ function customRolesOfSql(parts) {
989
1875
  }
990
1876
  //#endregion
991
1877
  //#region src/cli/rls/approvals.ts
992
- /** `rls.approvals`' approver check; better-supabase's `isApprover` template calls it. */
1878
+ /**
1879
+ * `rls.approvals`' approver check; better-supabase's `isApprover` template
1880
+ * calls it.
1881
+ */
993
1882
  const IS_APPROVER = "permdock_is_approver";
994
- /** The objects `rls.approvals` adds. Names are part of the SQL contract `supabaseApprovalStore` calls. */
1883
+ /**
1884
+ * The objects `rls.approvals` adds. Names are part of the SQL contract
1885
+ * `supabaseApprovalStore` calls.
1886
+ */
995
1887
  const APPROVAL_STORE = {
996
1888
  table: "approval_requests",
997
1889
  open: "permdock_approval_open",
@@ -1027,8 +1919,8 @@ function serverOnly(fn, args) {
1027
1919
  const BODY_CHECK = `${APPROVAL_STORE.table}_body_schema`;
1028
1920
  /**
1029
1921
  * `rls.jsonSchema`: a pg_jsonschema check that `body` matches
1030
- * `approval-request-v1.json`, added `not valid` and then validated. `auto`
1031
- * adds it only where the extension is available.
1922
+ * `approval-request-v1.json`, added `not valid` and then validated. `auto` adds
1923
+ * it only where the extension is available.
1032
1924
  */
1033
1925
  function bodySchemaSql(table, mode, body = "body", check = BODY_CHECK) {
1034
1926
  const statements = [
@@ -1050,11 +1942,11 @@ end
1050
1942
  $permdock$;\n`;
1051
1943
  }
1052
1944
  /**
1053
- * The approval store (`rls.approvals`): one table of `ApprovalRequest`
1054
- * bodies with the columns a list filters on, and one `security definer`
1055
- * function per `ApprovalStore` method, each one atomic statement. No client
1056
- * role may read the table or execute the functions: approvals are opened and
1057
- * resolved by the server, which grants its own role.
1945
+ * The approval store (`rls.approvals`): one table of `ApprovalRequest` bodies
1946
+ * with the columns a list filters on, and one `security definer` function per
1947
+ * `ApprovalStore` method, each one atomic statement. No client role may read
1948
+ * the table or execute the functions: approvals are opened and resolved by the
1949
+ * server, which grants its own role.
1058
1950
  */
1059
1951
  function approvalStoreSql(ctx, jsonSchema = false) {
1060
1952
  const table = qualified(ctx, APPROVAL_STORE.table);
@@ -1211,8 +2103,8 @@ ${serverOnly(fn(APPROVAL_STORE.cancel), "jsonb, text, text, text")}
1211
2103
  /**
1212
2104
  * `permdock_is_approver(p_approvers jsonb, p_tenant text default null)`: true
1213
2105
  * when the signed-in user matches the serialised approvers of a request
1214
- * (`approvers.by`), for policies on the app's own approval views. A list
1215
- * needs every item and `any-of` one of them; `user` compares the user id and
2106
+ * (`approvers.by`), for policies on the app's own approval views. A list needs
2107
+ * every item and `any-of` one of them; `user` compares the user id and
1216
2108
  * `holder(permission)` reads `permitted_<root>_ids_by_permission` in
1217
2109
  * `p_tenant`, or `permdock_has_permission` without one. Role, relation and
1218
2110
  * other grantee approvers need facts the database does not hold for every
@@ -1309,19 +2201,22 @@ function approvalsSql(ctx, approvals, jsonSchema) {
1309
2201
  }, jsonSchema);
1310
2202
  return store + isApproverSql(ctx) + (delegations === true ? approvalDelegationsSql(ctx) : "");
1311
2203
  }
1312
- /** The objects `rls.approvals.delegations` adds; `tableApprovalDelegationSource` reads the table. */
2204
+ /**
2205
+ * The objects `rls.approvals.delegations` adds; `tableApprovalDelegationSource`
2206
+ * reads the table.
2207
+ */
1313
2208
  const DELEGATIONS = {
1314
2209
  table: "approval_delegations",
1315
2210
  covers: "permdock_cover_approves"
1316
2211
  };
1317
2212
  /**
1318
- * `rls.approvals.delegations`: one table of out-of-office covers that a
1319
- * user writes for themselves, and a four-argument `permdock_is_approver`
1320
- * that also answers for a delegate inside an active cover. One hop: a cover
1321
- * is checked against the delegator's own approver rights, never the
1322
- * delegator's covers. A delegator who is the requester never counts. A
1323
- * `holder()` approver through a cover needs `rls.mode: "database"`, where
1324
- * the `_for` helpers exist; in `jwt` mode only `user()` approvers pass.
2213
+ * `rls.approvals.delegations`: one table of out-of-office covers that a user
2214
+ * writes for themselves, and a four-argument `permdock_is_approver` that also
2215
+ * answers for a delegate inside an active cover. One hop: a cover is checked
2216
+ * against the delegator's own approver rights, never the delegator's covers. A
2217
+ * delegator who is the requester never counts. A `holder()` approver through a
2218
+ * cover needs `rls.mode: "database"`, where the `_for` helpers exist; in `jwt`
2219
+ * mode only `user()` approvers pass.
1325
2220
  */
1326
2221
  function approvalDelegationsSql(ctx) {
1327
2222
  const table = qualified(ctx, DELEGATIONS.table);
@@ -1475,7 +2370,10 @@ revoke execute on function ${fn}(jsonb, text, text, text) from public, anon;
1475
2370
  grant execute on function ${fn}(jsonb, text, text, text) to authenticated;
1476
2371
  `;
1477
2372
  }
1478
- /** The request fields an adopted table may mirror into its own columns, as SQL over a body. */
2373
+ /**
2374
+ * The request fields an adopted table may mirror into its own columns, as SQL
2375
+ * over a body.
2376
+ */
1479
2377
  const MIRRORS = {
1480
2378
  status: (body) => `${body} ->> 'status'`,
1481
2379
  permission: (body) => `${body} ->> 'permission'`,
@@ -1499,7 +2397,10 @@ function mirrorsOf(adopt) {
1499
2397
  }
1500
2398
  return out;
1501
2399
  }
1502
- /** One row of `table` from `values` (column, SQL), each converted to the column's own type. */
2400
+ /**
2401
+ * One row of `table` from `values` (column, SQL), each converted to the
2402
+ * column's own type.
2403
+ */
1503
2404
  function populate(table, values) {
1504
2405
  return `pg_catalog.jsonb_populate_record(null::${table}, pg_catalog.jsonb_build_object(${values.map(([column, sql]) => `${quoteLiteral(column)}, ${sql}`).join(", ")}))`;
1505
2406
  }
@@ -1507,7 +2408,10 @@ function populate(table, values) {
1507
2408
  function mirrorRow(table, mirror, body) {
1508
2409
  return populate(table, mirror.map(([column, field]) => [column, MIRRORS[field](body)]));
1509
2410
  }
1510
- /** `, (<mirrored columns>) = (select …)` for an update that writes `body`; empty without mirrors. */
2411
+ /**
2412
+ * `, (<mirrored columns>) = (select …)` for an update that writes `body`; empty
2413
+ * without mirrors.
2414
+ */
1511
2415
  function mirrorSet(table, mirror, body) {
1512
2416
  if (mirror.length === 0) return "";
1513
2417
  const columns = mirror.map(([column]) => quoteIdent(column));
@@ -1515,12 +2419,12 @@ function mirrorSet(table, mirror, body) {
1515
2419
  return `,\n ${columns.length === 1 ? columns[0] ?? "" : `(${columns.join(", ")})`} = (select ${picked} from ${mirrorRow(table, mirror, body)} r)`;
1516
2420
  }
1517
2421
  /**
1518
- * The approval store over a table the app already has (`rls.approvals:
1519
- * { table, token?, body?, mirror? }`): the same `permdock_approval_*`
1520
- * functions, reading every field from the request body in `body`, keyed by
1521
- * the text column `token`, and copying the fields `mirror` names into the
1522
- * app's own columns, converted to their types, on every write. The table's
1523
- * grants and policies stay the app's.
2422
+ * The approval store over a table the app already has (`rls.approvals: { table,
2423
+ * token?, body?, mirror? }`): the same `permdock_approval_*` functions, reading
2424
+ * every field from the request body in `body`, keyed by the text column
2425
+ * `token`, and copying the fields `mirror` names into the app's own columns,
2426
+ * converted to their types, on every write. The table's grants and policies
2427
+ * stay the app's.
1524
2428
  */
1525
2429
  function adoptedApprovalStoreSql(ctx, adopt, jsonSchema = false) {
1526
2430
  const table = quoteQualified(adopt.table);
@@ -1704,99 +2608,13 @@ ${serverOnly(fn(APPROVAL_STORE.cancel), "jsonb, text, text, text")}
1704
2608
  `;
1705
2609
  }
1706
2610
  //#endregion
1707
- //#region src/cli/rls/permission-holders.ts
1708
- /** `permitted_<scope>_users(p_permission, p_id)`. Names are part of the SQL contract. */
1709
- function permittedUsersHelper(scope) {
1710
- return checkName(`permitted_${scope}_users`);
1711
- }
1712
- /** The users with a membership row on the instance `p_id`, or `undefined` when the scope's memberships are not all in tables. */
1713
- function candidatesSql(ctx, scope, user) {
1714
- const mapped = scopeTable(ctx, scope);
1715
- if (mapped !== void 0) return {
1716
- sql: ` select m.${quoteIdent(mapped.table.user)}::${user}
1717
- from ${quoteQualified(mapped.table.table)} m
1718
- where m.${quoteIdent(mapped.column)} = p_id`,
1719
- keys: []
1720
- };
1721
- const sources = holderSources(ctx, scope);
1722
- if (sources === void 0 || sources === "not-tables") return;
1723
- return {
1724
- sql: sources.map((source, index) => ` select h.user_id::${user}
1725
- from (
1726
- ${source.holders.rows(scope, { id: `v_key_${String(index)}` }).replaceAll(/^/gmu, " ")}
1727
- ) h`).join("\n union\n"),
1728
- keys: sources.map((source, index) => `v_key_${String(index)} ${source.holders.idType}`)
1729
- };
1730
- }
1731
- /** `language sql`, or PL/pgSQL when a source's id column needs `p_id` in a `%type` variable. */
1732
- function functionBody(keys, query) {
1733
- if (keys.length === 0) return `language sql
1734
- stable
1735
- security definer
1736
- set search_path = ''
1737
- as $$
1738
- ${query}
1739
- $$;`;
1740
- return `language plpgsql
1741
- stable
1742
- security definer
1743
- set search_path = ''
1744
- as $$
1745
- declare
1746
- ${keys.map((key) => ` ${key} := p_id;`).join("\n")}
1747
- begin
1748
- return query
1749
- ${query.replaceAll(/^/gmu, " ")};
1750
- end
1751
- $$;`;
1752
- }
1753
- /**
1754
- * One `permitted_<scope>_users(p_permission, p_id)` per scope in `database`
1755
- * mode: the users who hold a permission key on one instance, read from the
1756
- * scope's membership rows and the global-roles table and kept when
1757
- * `permitted_<scope>_ids_by_permission_for` lists the instance or
1758
- * `permdock_has_permission_for` answers, so denies, custom roles, expiry and
1759
- * suspension apply as for the user. It names other users, so no client role
1760
- * may execute it, and a backend role needs its own grant.
1761
- */
1762
- function permissionHoldersSql(ctx) {
1763
- if (ctx.authorize !== "database") return "";
1764
- const user = ctx.dialect === "supabase" ? "uuid" : "text";
1765
- const global = globalRoleRows(ctx);
1766
- const hasFor = qualified(ctx, PERMISSION_HELPERS.hasFor);
1767
- return `${ctx.scopes.map(({ name }) => {
1768
- const candidates = hasPermittedUsers(ctx, name) ? candidatesSql(ctx, name, user) : void 0;
1769
- if (candidates === void 0) return `-- ${name}: no memberships table or table source, so permitted_${name}_users is not written`;
1770
- const fn = qualified(ctx, permittedUsersHelper(name));
1771
- const ids = qualified(ctx, checkName(`${permittedByPermissionHelper(name)}_for`));
1772
- const type = scopeTypeOf(ctx, name);
1773
- return `-- the users who hold a permission on one ${name}: its members and the global-role holders for whom the _for helpers answer; no client role may execute it
1774
- create or replace function ${fn}(p_permission text, p_id ${type})
1775
- returns setof ${user}
1776
- ${functionBody(candidates.keys, ` select c.user_id
1777
- from (
1778
- ${candidates.sql}
1779
- union
1780
- select ${global.userSql}::${user}
1781
- from ${global.from}
1782
- ) c(user_id)
1783
- where c.user_id is not null
1784
- and (
1785
- p_id in (select ${ids}(c.user_id, p_permission))
1786
- or ${hasFor}(c.user_id, p_permission)
1787
- )
1788
- order by 1`)}
1789
- revoke execute on function ${fn}(text, ${type}) from public, anon, authenticated;`;
1790
- }).join("\n\n")}\n`;
1791
- }
1792
- //#endregion
1793
2611
  //#region src/cli/supabase-hook/sql.ts
1794
2612
  const MANAGED_TRIGGER = "permdock_protect_managed";
1795
2613
  function hookSql(parts) {
1796
2614
  const schema = quoteIdent(parts.schema);
1797
2615
  const fn = `${schema}.custom_access_token_hook`;
1798
2616
  const rows = parts.roles;
1799
- const roles = rows === void 0 ? ` held := '[]'::jsonb;` : ` select coalesce(jsonb_agg(distinct ${rows.roleSql} order by ${rows.roleSql}), '[]'::jsonb)
2617
+ const roles = rows === void 0 ? ` held := '[]'::jsonb;` : ` select coalesce(jsonb_agg(distinct ${rows.roleSql} order by ${rows.roleSql}) filter (where ${rows.roleSql} is not null), '[]'::jsonb)
1800
2618
  into held
1801
2619
  from ${rows.from}
1802
2620
  where ${rows.userSql} = v_roles_user;`;
@@ -1828,11 +2646,29 @@ function hookSql(parts) {
1828
2646
  if extra is not null then
1829
2647
  claims := jsonb_set(claims, ${quoteLiteral(`{${entry.claim}}`)}, extra);
1830
2648
  end if;`).join("");
2649
+ const dropTeams = parts.hook.teams === void 0 ? "" : " - 'team_ids'";
1831
2650
  const suspended = parts.users === void 0 ? "" : `
1832
2651
  if not ${activeRowSql(parts.users, "uid")} then
1833
- claims := claims - 'memberships_truncated' - 'attrs' - ${quoteLiteral(parts.tenantClaim)}${dropExtra};
2652
+ claims := claims - 'memberships_truncated' - 'attrs'${dropTeams} - ${quoteLiteral(parts.tenantClaim)}${dropExtra};
1834
2653
  claims := claims || jsonb_build_object('user_role', '[]'::jsonb, 'roles', '[]'::jsonb, 'memberships', '[]'::jsonb);${version}
1835
2654
  return jsonb_set(event, '{claims}', claims);
2655
+ end if;`;
2656
+ const teamsConfig = parts.hook.teams;
2657
+ const teams = teamsConfig === void 0 ? "" : `
2658
+ for team in
2659
+ select t.${quoteIdent(teamsConfig.team)}::text as id
2660
+ from ${quoteQualified(teamsConfig.table)} t
2661
+ where t.${quoteIdent(teamsConfig.user)} = uid
2662
+ order by ${teamsConfig.tenant === void 0 ? "" : `(t.${quoteIdent(teamsConfig.tenant)}::text is not distinct from active) desc, `}t.${quoteIdent(teamsConfig.team)}
2663
+ loop
2664
+ if octet_length(kept::text) + used + octet_length((team_ids || to_jsonb(team.id))::text) > budget then
2665
+ truncated := true;
2666
+ exit;
2667
+ end if;
2668
+ team_ids := team_ids || jsonb_build_array(team.id);
2669
+ end loop;
2670
+ if team_ids <> '[]'::jsonb then
2671
+ claims := jsonb_set(claims, '{team_ids}', team_ids);
1836
2672
  end if;`;
1837
2673
  return `${parts.schema === "public" ? "" : `create schema if not exists ${schema};\nrevoke all on schema ${schema} from public;\n\n`}create or replace function ${fn}(event jsonb)
1838
2674
  returns jsonb
@@ -1850,9 +2686,9 @@ declare
1850
2686
  in_active boolean := false;
1851
2687
  budget integer := ${String(parts.budget)};
1852
2688
  used integer := 0;
1853
- item record;${typedUsers(parts)}${plan === void 0 ? "" : "\n attrs jsonb;"}${parts.extra.length === 0 ? "" : "\n extra jsonb;"}${parts.version ? "\n ver bigint;" : ""}${parts.before.length === 0 ? "" : "\n checked jsonb;"}
2689
+ item record;${teamsConfig === void 0 ? "" : "\n team record;\n team_ids jsonb := '[]'::jsonb;"}${typedUsers(parts)}${plan === void 0 ? "" : "\n attrs jsonb;"}${parts.extra.length === 0 ? "" : "\n extra jsonb;"}${parts.version ? "\n ver bigint;" : ""}${parts.before.length === 0 ? "" : "\n checked jsonb;"}
1854
2690
  begin${beforeSql(parts.before)}${suspended}
1855
- claims := claims - 'attrs'${dropExtra};
2691
+ claims := claims - 'attrs'${dropTeams}${dropExtra};
1856
2692
  ${roles}
1857
2693
  claims := jsonb_set(claims, '{roles}', held);
1858
2694
  if jsonb_array_length(held) = 1 then
@@ -1875,7 +2711,7 @@ ${entriesSql(parts).replaceAll(/^/gmu, " ")}
1875
2711
  kept := kept || jsonb_build_array(item.entry);
1876
2712
  in_active := in_active or (active is not null and item.current);
1877
2713
  end loop;
1878
- claims := jsonb_set(claims, '{memberships}', kept);
2714
+ claims := jsonb_set(claims, '{memberships}', kept);${teams}
1879
2715
  if truncated then
1880
2716
  claims := jsonb_set(claims, '{memberships_truncated}', 'true'::jsonb);
1881
2717
  else
@@ -1902,11 +2738,11 @@ revoke execute on function ${fn}(jsonb) from authenticated, anon, public;${extra
1902
2738
  ].filter((chunk) => chunk !== "").join("\n");
1903
2739
  }
1904
2740
  function extraGrantsSql(extra) {
1905
- return [...[...new Set(extra.map((entry) => entry.fn.split(".")[0]))].map((name) => `\ngrant usage on schema ${quoteIdent(name ?? "")} to supabase_auth_admin;`), ...extra.map((entry) => `\ngrant execute on function ${quoteTable(entry.fn)}(uuid) to supabase_auth_admin;`)].join("");
2741
+ return [...[...new Set(extra.map((entry) => entry.fn.split(".")[0]))].map((name) => `\ngrant usage on schema ${quoteIdent(name ?? "")} to supabase_auth_admin;`), ...extra.map((entry) => `\nrevoke all on function ${quoteTable(entry.fn)}(uuid) from public, anon, authenticated;\ngrant execute on function ${quoteTable(entry.fn)}(uuid) to supabase_auth_admin;`)].join("");
1906
2742
  }
1907
2743
  function beforeGrantsSql(before, extra) {
1908
2744
  const granted = new Set(extra.map((entry) => entry.fn.split(".")[0]));
1909
- return [...[...new Set(before.map((fn) => beforeFirst(fn, ".")))].filter((name) => !granted.has(name)).map((name) => `\ngrant usage on schema ${quoteIdent(name)} to supabase_auth_admin;`), ...before.map((fn) => `\ngrant execute on function ${quoteTable(fn)}(jsonb) to supabase_auth_admin;`)].join("");
2745
+ return [...[...new Set(before.map((fn) => beforeFirst(fn, ".")))].filter((name) => !granted.has(name)).map((name) => `\ngrant usage on schema ${quoteIdent(name)} to supabase_auth_admin;`), ...before.map((fn) => `\nrevoke all on function ${quoteTable(fn)}(jsonb) from public, anon, authenticated;\ngrant execute on function ${quoteTable(fn)}(jsonb) to supabase_auth_admin;`)].join("");
1910
2746
  }
1911
2747
  /**
1912
2748
  * Execute on each `member_<scope>_ids_for(uuid)` for the `hook.claims`
@@ -1933,6 +2769,7 @@ function readsSql(parts) {
1933
2769
  reads.set(rolesTable, reads.get(rolesTable) ?? "roles");
1934
2770
  if (through !== void 0) reads.set(through.table, reads.get(through.table) ?? "role_keys");
1935
2771
  }
2772
+ if (parts.hook.teams !== void 0) reads.set(parts.hook.teams.table, reads.get(parts.hook.teams.table) ?? "teams");
1936
2773
  if (parts.attrs?.table !== void 0 && parts.attrs.columns.length > 0) reads.set(parts.attrs.table, reads.get(parts.attrs.table) ?? "attrs");
1937
2774
  if (parts.users !== void 0) reads.set(parts.users.table, reads.get(parts.users.table) ?? "status_users");
1938
2775
  return [...[...new Set([...reads.keys()].map((name) => name.includes(".") ? name.split(".")[0] : "public").filter((schema) => schema !== void 0 && schema !== parts.schema && schema !== "auth"))].map((schema) => `grant usage on schema ${quoteIdent(schema)} to supabase_auth_admin;`), ...[...reads].map(([name, label]) => authAdminRead(name, label))].join("\n");
@@ -2010,7 +2847,7 @@ function hookParts(scopes, config, overrides) {
2010
2847
  ...memberForPlan({
2011
2848
  scopes,
2012
2849
  ...config.rls?.memberships === void 0 ? {} : { memberships: config.rls.memberships },
2013
- memberSources: config.rls?.membershipSources ?? hook.memberships
2850
+ memberSources: membershipSourcesOf(config)
2014
2851
  })
2015
2852
  }
2016
2853
  };
@@ -2079,10 +2916,10 @@ function signedUp(user) {
2079
2916
  return `exists (select 1 from auth.users a where a.id = ${user})`;
2080
2917
  }
2081
2918
  /**
2082
- * Every membership source whose user id lives in another table: a row of
2083
- * the source bumps the users its old and new references hold, and a change
2084
- * of that table's user id (a contact re-linked to another login) bumps the
2085
- * old and the new user.
2919
+ * Every membership source whose user id lives in another table: a row of the
2920
+ * source bumps the users its old and new references hold, and a change of that
2921
+ * table's user id (a contact re-linked to another login) bumps the old and the
2922
+ * new user.
2086
2923
  */
2087
2924
  function memberUsersVersionSql(parts, bumpFor) {
2088
2925
  const holders = /* @__PURE__ */ new Map();
@@ -2194,7 +3031,10 @@ $$;
2194
3031
  revoke execute on function ${linkedBump}() from public, anon, authenticated;
2195
3032
  ${userTriggers}`;
2196
3033
  }
2197
- /** Every table whose role column references a roles table: the global roles and the membership sources. */
3034
+ /**
3035
+ * Every table whose role column references a roles table: the global roles and
3036
+ * the membership sources.
3037
+ */
2198
3038
  function roleKeyHolders(parts) {
2199
3039
  const holders = [];
2200
3040
  if (parts.roles?.through !== void 0) holders.push({
@@ -2228,7 +3068,10 @@ function roleKeyHolders(parts) {
2228
3068
  return true;
2229
3069
  });
2230
3070
  }
2231
- /** The bump for one roles table: unchanged keys and ids return early, else every holder of `old` is bumped. */
3071
+ /**
3072
+ * The bump for one roles table: unchanged keys and ids return early, else every
3073
+ * holder of `old` is bumped.
3074
+ */
2232
3075
  function roleKeysBumpSql(holders, versionTable, indent) {
2233
3076
  return `${indent}if tg_op = 'UPDATE'
2234
3077
  ${indent} and ${[...new Set(holders.flatMap((holder) => [holder.through.key, holder.through.id]))].map((column) => `new.${quoteIdent(column)} is not distinct from old.${quoteIdent(column)}`).join(`\n${indent} and `)} then
@@ -2244,9 +3087,9 @@ ${indent} and exists (select 1 from auth.users au where au.id = h.user_id)
2244
3087
  ${indent}on conflict (user_id) do update set version = v.version + 1;`;
2245
3088
  }
2246
3089
  /**
2247
- * A renamed role key changes the `roles` claim of everyone who holds it and
2248
- * the `roles` of every membership that references it, so updates to a roles
2249
- * table bump each holder.
3090
+ * A renamed role key changes the `roles` claim of everyone who holds it and the
3091
+ * `roles` of every membership that references it, so updates to a roles table
3092
+ * bump each holder.
2250
3093
  */
2251
3094
  function roleKeysVersionSql(parts, versionTable) {
2252
3095
  const holders = roleKeyHolders(parts);
@@ -2301,7 +3144,8 @@ function helperList(parts, types) {
2301
3144
  return [
2302
3145
  helperEntry(permittedIdsHelper(scope.name), "p_grant text", returns, client),
2303
3146
  helperEntry(memberIdsHelper(scope.name), "", returns, client),
2304
- ...parts.helpers.memberFor.includes(scope.name) ? [helperEntry(memberForHelper(scope.name), "p_user uuid", returns, parts.extra.length === 0 ? [] : ["supabase_auth_admin"])] : []
3147
+ ...parts.helpers.memberFor.includes(scope.name) ? [helperEntry(memberForHelper(scope.name), "p_user uuid", returns, parts.extra.length === 0 ? [] : ["supabase_auth_admin"])] : [],
3148
+ ...parts.helpers.memberFor.includes(scope.name) && isTeamScope(scope.name) ? [helperEntry(memberOfHelper(scope.name), "p_user uuid", returns, client)] : []
2305
3149
  ];
2306
3150
  })];
2307
3151
  }
@@ -2314,8 +3158,8 @@ function helperEntry(name, args, returns, execute) {
2314
3158
  };
2315
3159
  }
2316
3160
  /**
2317
- * The helpers `rls generate` writes beyond the ones the hook's claims feed:
2318
- * the `_for` forms in `database` mode, and the assignment checks when a role
3161
+ * The helpers `rls generate` writes beyond the ones the hook's claims feed: the
3162
+ * `_for` forms in `database` mode, and the assignment checks when a role
2319
3163
  * declares `assigns` (known only with the policy).
2320
3164
  */
2321
3165
  function trustedHelpers(parts, config, types, tenantType, policy) {
@@ -2333,8 +3177,9 @@ function trustedHelpers(parts, config, types, tenantType, policy) {
2333
3177
  const keyed = [
2334
3178
  helperEntry(USER_ID_HELPER, "", "uuid", client),
2335
3179
  ...config.rls?.apiKeys === void 0 ? [] : [helperEntry(API_KEY_ALLOWS, "p_grant text", "boolean", client)],
3180
+ ...config.rls?.tokenScopes === true ? [helperEntry(TOKEN_SCOPE_ALLOWS, "p_grant text", "boolean", client)] : [],
2336
3181
  ...readOnlyActorKinds(config.rls?.readOnlyActors) === void 0 ? [] : [helperEntry(ACTOR_MAY_WRITE, "", "boolean", client)],
2337
- ...!config.rls?.approvals ? [] : [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)],
3182
+ ...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)] : [],
2338
3183
  ...forUser
2339
3184
  ];
2340
3185
  if (!(policy !== void 0 && (ownershipRules(policy, parts.scopes)?.assigns.length ?? 0) > 0)) return keyed;
@@ -2361,7 +3206,10 @@ function activeRowManifest(row) {
2361
3206
  ...keep.length === 0 ? {} : { keep }
2362
3207
  };
2363
3208
  }
2364
- /** The `rls` settings a package writing SQL next to the helpers reads: custom roles, global roles, suspension and assignment triggers. */
3209
+ /**
3210
+ * The `rls` settings a package writing SQL next to the helpers reads: custom
3211
+ * roles, global roles, suspension and assignment triggers.
3212
+ */
2365
3213
  function rlsSettings(parts, config) {
2366
3214
  const rls = config.rls;
2367
3215
  const suspension = checkSuspension(rls?.suspension, parts.scopes);
@@ -2380,7 +3228,8 @@ function rlsSettings(parts, config) {
2380
3228
  ...suspension.memberships === void 0 ? {} : { memberships: { keep: keptKeys(suspension.memberships) } }
2381
3229
  } },
2382
3230
  ...assigned === void 0 ? {} : { assignments: { tables: assigned } },
2383
- ...rls?.apiKeys === void 0 ? {} : { apiKeys: apiKeyFields(rls.apiKeys) }
3231
+ ...rls?.apiKeys === void 0 ? {} : { apiKeys: apiKeyFields(rls.apiKeys) },
3232
+ ...rls?.tokenScopes === true ? { tokenScopes: true } : {}
2384
3233
  };
2385
3234
  }
2386
3235
  /** The `supabase/sdk` release `requires.capabilities` names features of. */
@@ -2416,8 +3265,7 @@ function manifestOf(parts, out, config, policy) {
2416
3265
  scopes: parts.scopes,
2417
3266
  tenantClaim: parts.tenantClaim,
2418
3267
  gucPrefix: rls?.gucPrefix ?? "app",
2419
- tenantType: rls?.tenantType ?? "uuid",
2420
- ...rls?.teamType === void 0 ? {} : { teamType: rls.teamType },
3268
+ tenantType: firstScopeType(rls?.scopeTypes, parts.scopes),
2421
3269
  ...rls?.scopeTypes === void 0 ? {} : { scopeTypes: rls.scopeTypes }
2422
3270
  };
2423
3271
  const types = new Map(parts.scopes.map((scope) => [scope.name, scopeTypeOf(ctx, scope.name)]));
@@ -2464,15 +3312,30 @@ function manifestOf(parts, out, config, policy) {
2464
3312
  decidingColumns: decidingColumns(config, parts.attrs === void 0 ? void 0 : {
2465
3313
  ...parts.attrs.table === void 0 ? {} : { table: parts.attrs.table },
2466
3314
  columns: parts.attrs.columns
2467
- }),
3315
+ }, parts.hook.teams),
2468
3316
  markers: {
2469
3317
  hook: "v1",
2470
3318
  grants: "v1"
2471
3319
  },
2472
- requires: requiredCapabilities(config, policy)
3320
+ requires: requiredCapabilities(config, policy),
3321
+ ...policy === void 0 ? {} : { names: resolveNames(policy, config, {
3322
+ schema: parts.helpers.schema,
3323
+ tenantClaim: parts.tenantClaim
3324
+ }) }
2473
3325
  };
2474
3326
  }
2475
- /** The first line of the generated hook: fields `--check` compares before the full text. */
3327
+ /**
3328
+ * The manifest without the token hook: what a project with no `supabase.hook`
3329
+ * records.
3330
+ */
3331
+ function databaseManifestOf(parts, out, config, policy) {
3332
+ const { hook: _hook, budget: _budget, claims: _claims, authzVersion: _authzVersion, authzVersionBump: _authzVersionBump, memberships: _memberships, ...rest } = manifestOf(parts, out, config, policy);
3333
+ return rest;
3334
+ }
3335
+ /**
3336
+ * The first line of the generated hook: fields `--check` compares before the
3337
+ * full text.
3338
+ */
2476
3339
  function hookMarker(manifest) {
2477
3340
  return `${HOOK_MARKER} schema=${manifest.hook.schema} tenant=${manifest.tenantClaim} budget=${String(manifest.budget.bytes)} claims=${manifest.claims.map((claim) => claim.name).join(",")}`;
2478
3341
  }
@@ -2498,7 +3361,10 @@ budget, the claims the hook writes, the membership sources and the columns that
2498
3361
  --out writes it as JSON, to permdock.manifest.json without a path; --check exits 1 when that
2499
3362
  file differs.
2500
3363
  `;
2501
- /** `supabase.hook.out`, else pg-delta's per-schema path under pg-delta, else `supabase/permdock-hook.sql`. */
3364
+ /**
3365
+ * `supabase.hook.out`, else pg-delta's per-schema path under pg-delta, else
3366
+ * `supabase/permdock-hook.sql`.
3367
+ */
2502
3368
  function hookOut(cwd, config, schema, flag) {
2503
3369
  const schemas = resolveSchemas(cwd, config, flag);
2504
3370
  return config.supabase?.hook?.out !== void 0 || schemas.mode !== "pg-delta" ? defaultOut(config) : pgDeltaPath(schemas.schemaDir, "hook", schema ?? config.supabase?.hook?.schema ?? config.rls?.schema ?? "permdock");
@@ -2519,8 +3385,26 @@ function supabaseHookManifest(scopes, config, overrides = {}, policy) {
2519
3385
  };
2520
3386
  }
2521
3387
  /**
2522
- * The hook migration. With `grantsOut`, the statements `supabase db diff`
2523
- * drops are left out of `sql` and returned in `grants` for that file.
3388
+ * The manifest of a project in `rls.authorize: 'database'` mode with no
3389
+ * `supabase.hook`: the helpers, scopes, membership sources and grants, and no
3390
+ * token hook.
3391
+ */
3392
+ function supabaseDatabaseManifest(scopes, config, overrides = {}, policy) {
3393
+ return databaseManifestOf(hookParts(scopes, {
3394
+ ...config,
3395
+ supabase: {
3396
+ ...config.supabase,
3397
+ hook: { memberships: membershipSourcesOf(config) }
3398
+ }
3399
+ }, overrides), overrides.out ?? defaultOut(config), config, policy);
3400
+ }
3401
+ /** Whether the project is in the one case that has a manifest without a hook. */
3402
+ function hooklessDatabase(config) {
3403
+ return config.supabase?.hook === void 0 && resolveAuthorize(config) === "database";
3404
+ }
3405
+ /**
3406
+ * The hook migration. With `grantsOut`, the statements `supabase db diff` drops
3407
+ * are left out of `sql` and returned in `grants` for that file.
2524
3408
  */
2525
3409
  function supabaseHookSql(scopes, config, overrides = {}, grantsOut) {
2526
3410
  const parts = hookParts(scopes, config, overrides);
@@ -2564,14 +3448,33 @@ function markerDrift(onDisk, expected, outRel) {
2564
3448
  const changed = Object.keys(want).filter((key) => found[key] !== want[key]).map((key) => `${key} ${found[key] ?? "(none)"} -> ${want[key] ?? ""}`);
2565
3449
  return changed.length === 0 ? "supabase hook drift" : `supabase hook drift: ${changed.join("; ")}`;
2566
3450
  }
2567
- function inspectText(manifest) {
3451
+ /** Supabase's default access token lifetime when `[auth] jwt_expiry` is unset. */
3452
+ const DEFAULT_JWT_EXPIRY = 3600;
3453
+ function managementApi(cwd, manifest) {
3454
+ return {
3455
+ hook_custom_access_token_enabled: true,
3456
+ hook_custom_access_token_uri: hookUri(manifest.hook.schema),
3457
+ jwt_exp: supabaseConfig(cwd).jwtExpiry ?? DEFAULT_JWT_EXPIRY
3458
+ };
3459
+ }
3460
+ function inspectText(manifest, api) {
2568
3461
  return [
2569
3462
  `hook ${manifest.hook.schema}.${manifest.hook.function} (${manifest.hook.out})`,
2570
3463
  `helpers ${manifest.helpers.functions.map((fn) => `${manifest.helpers.schema}.${fn}`).join(", ")}`,
2571
3464
  `tenant claim ${manifest.tenantClaim}`,
2572
3465
  `budget ${String(manifest.budget.bytes)} bytes of ${manifest.budget.measure}`,
2573
3466
  `claims ${manifest.claims.map((claim) => `${claim.name}${claim.source === "permdock" ? "" : ` (${claim.source})`}${claim.budget ? " [budget]" : ""}`).join(", ")}`,
2574
- `authz_ver ${manifest.authzVersion ? "on" : "off"}`
3467
+ `authz_ver ${manifest.authzVersion ? "on" : "off"}`,
3468
+ `hook_custom_access_token_enabled ${String(api.hook_custom_access_token_enabled)}`,
3469
+ `hook_custom_access_token_uri ${api.hook_custom_access_token_uri}`,
3470
+ `jwt_exp ${String(api.jwt_exp)}`
3471
+ ].join("\n");
3472
+ }
3473
+ function databaseInspectText(manifest) {
3474
+ return [
3475
+ "no token hook (rls.authorize: database, no supabase.hook)",
3476
+ `helpers ${manifest.helpers.functions.map((fn) => `${manifest.helpers.schema}.${fn}`).join(", ")}`,
3477
+ `tenant claim ${manifest.tenantClaim}`
2575
3478
  ].join("\n");
2576
3479
  }
2577
3480
  /**
@@ -2632,15 +3535,30 @@ async function runSupabase(input) {
2632
3535
  }).filter(([, value]) => value !== void 0));
2633
3536
  if (area === "inspect" && action === void 0) {
2634
3537
  const policy = await loadHookPolicy(input.cwd, input.config);
3538
+ if (hooklessDatabase(input.config)) {
3539
+ const bare = supabaseDatabaseManifest(scopeList(policy.scopes), input.config, overrides, policy);
3540
+ if (input.out !== void 0 || input.check) return manifestFile(input.cwd, typeof input.out === "string" ? input.out : MANIFEST_FILE, bare, input.check);
3541
+ return {
3542
+ code: 0,
3543
+ output: input.json === true ? JSON.stringify(bare, null, 2) : databaseInspectText(bare)
3544
+ };
3545
+ }
2635
3546
  const manifest = supabaseHookManifest(scopeList(policy.scopes), input.config, {
2636
3547
  ...overrides,
2637
3548
  out: hookOut(input.cwd, input.config, input.schema, flag),
2638
3549
  schemas: schemas.mode
2639
3550
  }, policy);
2640
- if (input.out !== void 0 || input.check) return manifestFile(input.cwd, typeof input.out === "string" ? input.out : MANIFEST_FILE, manifest, input.check);
3551
+ const api = managementApi(input.cwd, manifest);
3552
+ if (input.out !== void 0 || input.check) return manifestFile(input.cwd, typeof input.out === "string" ? input.out : MANIFEST_FILE, {
3553
+ ...manifest,
3554
+ managementApi: api
3555
+ }, input.check);
2641
3556
  return {
2642
3557
  code: 0,
2643
- output: input.json === true ? JSON.stringify(manifest, null, 2) : inspectText(manifest)
3558
+ output: input.json === true ? JSON.stringify({
3559
+ ...manifest,
3560
+ managementApi: managementApi(input.cwd, manifest)
3561
+ }, null, 2) : inspectText(manifest, api)
2644
3562
  };
2645
3563
  }
2646
3564
  if (area !== "hook" || action !== "generate") return {
@@ -2651,7 +3569,9 @@ async function runSupabase(input) {
2651
3569
  code: 2,
2652
3570
  output: `supabase hook generate --grants-out is for --schemas migra: ${schemas.mode === "pg-delta" ? "pg-delta keeps the grants in the hook file" : "a hand-written migration keeps its grants"}, so drop --grants-out`
2653
3571
  };
2654
- const { sql, grants, manifest } = supabaseHookSql(await loadScopes(input.cwd, input.config), input.config, overrides, grantsLabel(input.grantsOut));
3572
+ const generated = supabaseHookSql(await loadScopes(input.cwd, input.config), input.config, overrides, grantsLabel(input.grantsOut));
3573
+ const { grants, manifest } = generated;
3574
+ const sql = schemas.mode === "pg-delta" && typeof input.out !== "string" && input.config.supabase?.hook?.out === void 0 ? declarativeSql(generated.sql) : generated.sql;
2655
3575
  const outRel = typeof input.out === "string" ? input.out : hookOut(input.cwd, input.config, input.schema, flag);
2656
3576
  const outPath = resolve(input.cwd, outRel);
2657
3577
  const hook = input.config.supabase?.hook;
@@ -2702,4 +3622,4 @@ async function runSupabase(input) {
2702
3622
  };
2703
3623
  }
2704
3624
  //#endregion
2705
- export { pd045 as _, supabaseHookManifest as a, approvalsSql as c, resolveAuthorize as d, pd039 as f, attrsPlan as g, schemasRefusal as h, runSupabase as i, parseRbacAuthorize as l, resolveSchemas as m, hookOut as n, supabaseHookSql as o, isSupabaseSchemas as p, loadScopes as r, permissionHoldersSql as s, grantsLabel as t, rbacScaffold as u, readSupabaseConfig as v, supabaseConfig as y };
3625
+ export { supabaseConfig as _, supabaseHookManifest as a, resolveAuthorize as b, pd039 as c, schemasRefusal as d, declarativeSql as f, readSupabaseConfig as g, pd074 as h, runSupabase as i, isSupabaseSchemas as l, pd045 as m, hookOut as n, supabaseHookSql as o, attrsPlan as p, loadScopes as r, approvalsSql as s, grantsLabel as t, resolveSchemas as u, parseRbacAuthorize as v, rbacScaffold as y };