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,41 +1,45 @@
1
- import { a as hasConditionOp } from "./refs-K6eWUJ0H.js";
2
- import { c as listPermissions, h as formerKeys } from "./permission-registry-Br4jSNVi.js";
3
- import { u as isPrincipalRelation } from "./resource-relations-D_jw0BFx.js";
4
- import { t as canonicalJson } from "./canonical-json-BC8_nMTw.js";
5
- import { a as normalizeMemberships, d as scopeList, o as resolveScope } from "./scopes-CUPSjo9q.js";
6
- import { o as flattenGrantee } from "./grantee-hxrUsbpM.js";
7
- import { c as separationConflicts } from "./policy-DbM5YYtV.js";
8
- import { C as validateCustomRole } from "./evaluate-CNClBvcj.js";
9
- import { s as parseCredential } from "./credential-BcoiejpY.js";
10
- import { a as describeError } from "./errors-CWTY6uih.js";
11
- import { t as policyRowConditionKeys } from "./row-conditions-h2HythXQ.js";
12
- import { a as rel, n as doctorSrcPath, o as sqlFiles, r as listSourceFiles } from "./files-D_JIzUrP.js";
13
- import { i as DOCTOR_REPORT_SCHEMA } from "./version-CEbQ5UeM.js";
14
- import { r as catalogOAuthScopes, s as jsonSchemaOf } from "./catalog-doc-Cdn7-0pQ.js";
15
- import { a as loadModule, i as loadConfiguredPolicy, n as asPolicy, s as pickNamed } from "./load-DFS_ry0W.js";
16
- import { r as runCollect } from "./collect-mLTY4nwb.js";
1
+ import { o as hasConditionOp } from "./refs-C8BKxc_e.js";
2
+ import { c as listPermissions, h as formerKeys } from "./permission-registry-B8tYxPIt.js";
3
+ import { u as isPrincipalRelation } from "./resource-relations-8-pCScBO.js";
4
+ import { t as canonicalJson } from "./canonical-json-DwilZ1iB.js";
5
+ import { f as scopeList, o as normalizeMemberships, s as resolveScope } from "./scopes-0Up_UA2t.js";
6
+ import { o as flattenGrantee } from "./grantee-Dke-9rd1.js";
7
+ import { u as separationConflicts } from "./policy-CLQ8__GF.js";
8
+ import { T as validateCustomRole } from "./evaluate-Dd8Ta0Ie.js";
9
+ import { s as parseCredential } from "./credential-CyyyvCsL.js";
10
+ import { a as describeError } from "./errors-Vpu6rKHl.js";
11
+ import { t as policyRowConditionKeys } from "./row-conditions-BAGHOmVq.js";
12
+ import { a as rel, n as doctorSrcPath, o as sqlFiles, r as listSourceFiles } from "./files-BSjrtIHw.js";
13
+ import { i as DOCTOR_REPORT_SCHEMA } from "./version-DMQ0dnN5.js";
14
+ import { c as jsonSchemaOf, i as catalogOAuthScopes } from "./catalog-doc-DjMKzJp9.js";
15
+ import { a as loadModule, i as loadConfiguredPolicy, n as asPolicy, s as pickNamed } from "./load-DjSU5KXO.js";
17
16
  import { t as catalogPath } from "./catalog-path-CnI0XTFK.js";
18
- import { n as supabaseTenantClaim } from "./budget-NbEtbJC_.js";
19
- import { s as quoteSqlLiteral } from "./sql-B5T1IL83.js";
20
- import { d as keptKeys, r as PERMDOCK_SCHEMA } from "./sources-vs5dGOsS.js";
21
- import { t as parseCatalog } from "./parse-Cxq0WxrA.js";
22
- import "./markers-C6joDI3o.js";
23
- import { t as didYouMean } from "./args-IIolxxKA.js";
24
- import { t as DOCS_BASE } from "./manifest-dvL2XEe1.js";
25
- import { t as createStyle } from "./style-Uao76wO7.js";
26
- import { r as findingOf } from "./output-1im__-08.js";
27
- import { i as runSkillsInstall } from "./skills-B6lVdD_W.js";
17
+ import { r as runCollect } from "./collect-B7ZFAJU3.js";
18
+ import { i as qualifySqlTable, s as quoteSqlLiteral } from "./sql-0WjxIp9g.js";
19
+ import { a as scopeMembershipTable } from "./compile-EzEMB-7v.js";
20
+ import { n as supabaseTenantClaim } from "./budget-BELja5A9.js";
21
+ import { d as keptKeys, r as PERMDOCK_SCHEMA } from "./sources-CMAM-2A3.js";
22
+ import { t as parseCatalog } from "./parse-1_ZheTW5.js";
23
+ import "./markers-BeHZ4x9Q.js";
24
+ import { t as didYouMean } from "./args-0FrVs5EH.js";
25
+ import { t as DOCS_BASE } from "./manifest-Cgiq5oqc.js";
26
+ import { t as createStyle } from "./style-Ds11Hmk4.js";
27
+ import { a as nonEmptyOr, r as findingOf } from "./output-tkju6U7R.js";
28
+ import { i as runSkillsInstall } from "./skills-Bjj7BNEQ.js";
28
29
  import { n as MIGRATION_DIRS, t as DEFAULT_SENSITIVE_ACTIONS } from "./constants-DcJABbLW.js";
29
- import { l as partPath } from "./output-files-DhRBBE4n.js";
30
- import { _ as pd045, a as supabaseHookManifest, f as pd039, g as attrsPlan, m as resolveSchemas, n as hookOut, v as readSupabaseConfig, y as supabaseConfig } from "./supabase-hook-BMoEhZir.js";
31
- import { i as group, n as membershipColumns, o as sqlStatements, r as tableKey } from "./deciding-columns-Sq12mEA6.js";
32
- import { C as byKey, L as graphSqlName, N as contextRefs, a as guardedTables, t as ownershipRules } from "./ownership-DqaJNJPn.js";
33
- import { a as pd010, c as pd014, d as pd038, f as pd041, i as pd008, l as pd015, n as pd001, o as pd011, p as pd057, r as pd007, s as pd013, t as runUsage, u as pd036 } from "./usage-SveTRTyr.js";
34
- import { d as rowConditionMessage, f as commandFor, i as graphPlan, m as tableFor, p as compileGrants, s as ROW_CONDITION_FIX, u as helperTablePolicies } from "./verify-BaAKx7t6.js";
35
- import { t as FIELD_VIEWS } from "./fields-OYG_JR78.js";
36
- import { r as staleFiles, t as powersyncFiles } from "./powersync-BkWWCS1K.js";
37
- import { n as legacyHelperNames, r as retirePlan, t as legacyHelperCalls } from "./retire-CALjIQ7e.js";
38
- import { t as supautilsRejections } from "./supautils-B6HYL9eL.js";
30
+ import { l as partPath } from "./output-files-BIQ_9pIs.js";
31
+ import { _ as supabaseConfig, a as supabaseHookManifest, c as pd039, g as readSupabaseConfig, h as pd074, m as pd045, n as hookOut, p as attrsPlan, u as resolveSchemas } from "./supabase-hook-B-yXnzUl.js";
32
+ import { G as byKey, Q as graphSqlName, n as tableNameOf, o as graphPlan, r as tableNames } from "./tables-DeMNEy6V.js";
33
+ import { a as guardedTables, p as contextRefs, r as unsatisfiedKinds, t as ownershipRules } from "./ownership-B4L59T9u.js";
34
+ import { t as membershipSourcesOf } from "./sources-qoIJQrJv.js";
35
+ import { i as group, n as membershipColumns, o as sqlStatements, r as tableKey } from "./deciding-columns-NB4wcyBf.js";
36
+ import { t as resolveNames } from "./resolve-names-CF7xXLSG.js";
37
+ import { t as FIELD_VIEWS } from "./fields-D0vUI6dq.js";
38
+ import { a as pd010, c as pd014, d as pd038, f as pd041, i as pd008, l as pd015, n as pd001, o as pd011, p as pd057, r as pd007, s as pd013, t as runUsage, u as pd036 } from "./usage-CxEzS4ey.js";
39
+ import { d as rowConditionMessage, f as commandFor, m as tableFor, p as compileGrants, s as ROW_CONDITION_FIX, u as helperTablePolicies } from "./verify-DZeqoWu5.js";
40
+ import { a as streamOf, i as scopeSourcesOf, r as staleFiles, t as powersyncFiles } from "./powersync-DHNQX06W.js";
41
+ import { a as generateOptions, c as buildContext, n as inheritTargets, o as isRefusal, t as supautilsRejections } from "./supautils-BU-pAEpf.js";
42
+ import { n as legacyHelperNames, r as retirePlan, t as legacyHelperCalls } from "./retire-B2xffQgY.js";
39
43
  import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
40
44
  import { basename, dirname, join, resolve } from "node:path";
41
45
  import { createRequire } from "node:module";
@@ -169,7 +173,10 @@ function membershipsFixture(input) {
169
173
  //#endregion
170
174
  //#region src/cli/doctor/assignments.ts
171
175
  const TRIGGER = new RegExp(String.raw`^create\s+(?:or\s+replace\s+)?trigger\s+"?permdock_assignment"?\s[\s\S]*?\bon\s+((?:"[^"]+"|\w+)(?:\.(?:"[^"]+"|\w+))?)`, "iu");
172
- /** The tables a `permdock_assignment` trigger is created on in the migrations and the `rls generate` output. */
176
+ /**
177
+ * The tables a `permdock_assignment` trigger is created on in the migrations
178
+ * and the `rls generate` output.
179
+ */
173
180
  function triggeredTables(input) {
174
181
  const out = input.config.rls?.out ?? "rls.sql";
175
182
  const files = sqlFiles(input.cwd, [...input.config.doctor?.migrations ?? MIGRATION_DIRS, ...new Set([
@@ -185,10 +192,10 @@ function triggeredTables(input) {
185
192
  return tables;
186
193
  }
187
194
  /**
188
- * PD064: `rls.assignments` guards a table (a membership table, the
189
- * global-roles table or a listed table) that no `permdock_assignment`
190
- * trigger is created on in the migrations or the `rls generate` output, so a
191
- * client may write any role there.
195
+ * PD064: `rls.assignments` guards a table (a membership table, the global-roles
196
+ * table or a listed table) that no `permdock_assignment` trigger is created on
197
+ * in the migrations or the `rls generate` output, so a client may write any
198
+ * role there.
192
199
  */
193
200
  async function pd064(input) {
194
201
  if (input.config.rls?.assignments === void 0) return [];
@@ -207,8 +214,8 @@ async function pd064(input) {
207
214
  //#endregion
208
215
  //#region src/cli/doctor/catalog.ts
209
216
  /**
210
- * A policy that declares `oauthScopes` against a catalog on disk without
211
- * them, or with another set. `authorizationProvider` builds better-supabase's
217
+ * A policy that declares `oauthScopes` against a catalog on disk without them,
218
+ * or with another set. `authorizationProvider` builds better-supabase's
212
219
  * `delegation.scopes` from the catalog, so its SQL checks deny a token that
213
220
  * holds only the coarse scope.
214
221
  */
@@ -289,6 +296,72 @@ async function pd067(input) {
289
296
  }]));
290
297
  }
291
298
  //#endregion
299
+ //#region src/cli/doctor/config-names.ts
300
+ const PLACEHOLDER = /\{([^{}]*)\}/gu;
301
+ /** The scope aliases `ScopeNames` admits next to the declared names. */
302
+ const ALIASES = ["tenant", "team"];
303
+ function keysOf(record) {
304
+ return record === void 0 ? [] : Object.keys(record);
305
+ }
306
+ function named(where, kind, names) {
307
+ return names.map((name) => ({
308
+ where,
309
+ kind,
310
+ name
311
+ }));
312
+ }
313
+ function namedIn(config) {
314
+ const rls = config.rls;
315
+ return [
316
+ ...named("rls.tables", "resource", keysOf(rls?.tables)),
317
+ ...named("rls.scopeTypes", "scope", keysOf(rls?.scopeTypes)),
318
+ ...named("rls.actions", "action", keysOf(rls?.actions)),
319
+ ...named("rls.memberships.scopes", "scope", keysOf(rls?.memberships?.scopes)),
320
+ ...named("rls.suspension.scopes", "scope", keysOf(rls?.suspension?.scopes)),
321
+ ...Object.keys(rls?.realtime?.topics ?? {}).flatMap((pattern) => named(`rls.realtime.topics['${pattern}']`, "scope", [...pattern.matchAll(PLACEHOLDER)].map((match) => match[1] ?? ""))),
322
+ ...Object.entries(rls?.storage?.buckets ?? {}).flatMap(([name, bucket]) => named(`rls.storage.buckets.${name}.scope`, "scope", [bucket.scope])),
323
+ ...named("powersync.resources", "resource", config.powersync?.resources ?? []),
324
+ ...named("powersync.action", "action", config.powersync?.action === void 0 ? [] : [config.powersync.action])
325
+ ];
326
+ }
327
+ /**
328
+ * PD077: a config key or value names a scope, resource or action the policy
329
+ * does not declare, such as a Realtime topic `{organisation}` placeholder for
330
+ * the scope `organization`. `defineConfig` with the policy value reports the
331
+ * same names at compile time. Also a SQL helper name `resolveNames` rejects:
332
+ * two sources sharing one, or one Postgres cannot hold.
333
+ */
334
+ async function pd077(input) {
335
+ if (input.config.policy === void 0) return [];
336
+ const policy = await policyOf(input);
337
+ if (policy === void 0) return [];
338
+ const leaves = listPermissions(policy.vocabulary.permissions);
339
+ const declared = {
340
+ scope: /* @__PURE__ */ new Set([...policy.scopes.map((scope) => scope.name), ...ALIASES]),
341
+ resource: new Set(leaves.map((leaf) => leaf.resource)),
342
+ action: new Set(leaves.map((leaf) => leaf.action))
343
+ };
344
+ return [...namedIn(input.config).filter((entry) => !declared[entry.kind].has(entry.name)).map((entry) => ({
345
+ code: "PD077",
346
+ severity: "error",
347
+ message: `${entry.where} names the ${entry.kind} '${entry.name}', which the policy does not declare`,
348
+ fix: `use one of ${[...declared[entry.kind]].toSorted().join(", ")}, or pass the policy value to defineConfig to catch this at compile time`
349
+ })), ...helperNames(policy, input.config)];
350
+ }
351
+ function helperNames(policy, config) {
352
+ try {
353
+ resolveNames(policy, config);
354
+ return [];
355
+ } catch (cause) {
356
+ return [{
357
+ code: "PD077",
358
+ severity: "error",
359
+ message: describeError(cause).replace(/^PermDock CLI: /u, ""),
360
+ fix: "rename the scope or resource so each generated SQL helper has its own name of at most 63 bytes"
361
+ }];
362
+ }
363
+ }
364
+ //#endregion
292
365
  //#region src/cli/doctor/declarative.ts
293
366
  const SCHEMAS = "supabase/schemas";
294
367
  const MIGRATIONS = "supabase/migrations";
@@ -300,7 +373,10 @@ const CALLS_HELPER = /\b(?:permdock_has|(?:permitted|member)_[a-z][a-z0-9_]*_ids
300
373
  function uncommented(text) {
301
374
  return text.replaceAll(/--[^\n]*/gu, "").replaceAll(/\/\*[\s\S]*?\*\//gu, "");
302
375
  }
303
- /** Whether `text` starts with a line `rls generate` or `supabase hook generate` writes. */
376
+ /**
377
+ * Whether `text` starts with a line `rls generate` or `supabase hook generate`
378
+ * writes.
379
+ */
304
380
  function generatedByPermDock(text) {
305
381
  return text.startsWith("-- permdock:") || text.startsWith("-- generated by permdock");
306
382
  }
@@ -308,9 +384,9 @@ function generatedByPermDock(text) {
308
384
  * PD042: under migra, a hook declared under `supabase/schemas` reaches the
309
385
  * database through `supabase db diff`, which drops its `supabase_auth_admin`
310
386
  * grants. pg-delta keeps them, so the check runs only for `migra`. A function
311
- * created (or dropped and created again) without them is executable by
312
- * `public` and not by the auth server, so a migration at or after the one
313
- * that creates it must carry the grants.
387
+ * created (or dropped and created again) without them is executable by `public`
388
+ * and not by the auth server, so a migration at or after the one that creates
389
+ * it must carry the grants.
314
390
  */
315
391
  function pd042(cwd, config, files = nodeFiles) {
316
392
  if (config.supabase?.hook === void 0 || resolveSchemas(cwd, config).mode !== "migra") return [];
@@ -338,10 +414,10 @@ function generatedSchemaFiles(cwd, schemaDir, files) {
338
414
  }
339
415
  /**
340
416
  * PD068: PermDock generates for pg-delta (the default), but
341
- * `supabase/config.toml` does not set `[experimental.pgdelta] enabled =
342
- * true`, so Supabase CLI 2.x diffs the schema files with migra. migra drops
343
- * the hook's `supabase_auth_admin` grants and the helpers' privileges, and
344
- * PermDock wrote no `--grants-out` file to restore them.
417
+ * `supabase/config.toml` does not set `[experimental.pgdelta] enabled = true`,
418
+ * so Supabase CLI 2.x diffs the schema files with migra. migra drops the hook's
419
+ * `supabase_auth_admin` grants and the helpers' privileges, and PermDock wrote
420
+ * no `--grants-out` file to restore them.
345
421
  */
346
422
  function pd068(cwd, config, files = nodeFiles) {
347
423
  const read = readSupabaseConfig(cwd);
@@ -360,8 +436,8 @@ function pd068(cwd, config, files = nodeFiles) {
360
436
  /**
361
437
  * PD069: leftovers of declarative schemas on migra in a pg-delta project:
362
438
  * `[db.migrations] schema_paths`, which pg-delta's dependency order makes
363
- * unnecessary, and numbered `NNN_permdock_<part>.sql` files that duplicate
364
- * the per-schema layout `rls generate --split` now writes.
439
+ * unnecessary, and numbered `NNN_permdock_<part>.sql` files that duplicate the
440
+ * per-schema layout `rls generate --split` now writes.
365
441
  */
366
442
  function pd069(cwd, config, files = nodeFiles) {
367
443
  const schemas = resolveSchemas(cwd, config);
@@ -381,20 +457,26 @@ function pd069(cwd, config, files = nodeFiles) {
381
457
  });
382
458
  return findings;
383
459
  }
384
- /** The `[db.migrations] schema_paths` globs of `supabase/config.toml`, or Supabase's default. */
460
+ /**
461
+ * The `[db.migrations] schema_paths` globs of `supabase/config.toml`, or
462
+ * Supabase's default.
463
+ */
385
464
  function schemaPaths(cwd) {
386
465
  const paths = supabaseConfig(cwd).schemaPaths ?? [];
387
466
  return paths.length === 0 ? ["./schemas/**/*.sql"] : paths;
388
467
  }
389
- /** Schema files in the order `supabase db diff` applies them: each glob in turn, sorted within it. */
468
+ /**
469
+ * Schema files in the order `supabase db diff` applies them: each glob in turn,
470
+ * sorted within it.
471
+ */
390
472
  function orderedSchemaFiles(cwd) {
391
473
  return sqlFiles(join(cwd, "supabase"), schemaPaths(cwd), { order: "entry" });
392
474
  }
393
475
  /**
394
- * PD043: under migra, `db diff` applies schema files in `schema_paths`
395
- * order, so a policy that calls `permdock_has` or `permitted_<scope>_ids`
396
- * before the file that defines them fails to apply. pg-delta orders by
397
- * dependencies instead.
476
+ * PD043: under migra, `db diff` applies schema files in `schema_paths` order,
477
+ * so a policy that calls `permdock_has` or `permitted_<scope>_ids` before the
478
+ * file that defines them fails to apply. pg-delta orders by dependencies
479
+ * instead.
398
480
  */
399
481
  function pd043(cwd, config, files = nodeFiles) {
400
482
  if (resolveSchemas(cwd, config).mode !== "migra") return [];
@@ -475,7 +557,7 @@ async function pd018(input) {
475
557
  for (const conflict of separationConflicts(policy, record.memberships ?? [])) findings.push({
476
558
  code: "PD018",
477
559
  severity: "warning",
478
- message: `membership ${conflict.principal || "unknown"} holds exclusive roles ${conflict.roles.join(" and ")}`,
560
+ message: `membership ${nonEmptyOr(conflict.principal, "unknown")} holds exclusive roles ${conflict.roles.join(" and ")}`,
479
561
  fix: "remove one of the exclusive roles from the membership fixture"
480
562
  });
481
563
  return findings;
@@ -510,9 +592,9 @@ async function pd023(input) {
510
592
  return findings;
511
593
  }
512
594
  /**
513
- * PD055: a stored custom role names a permission by a key it was renamed
514
- * from. It still resolves; the alias can only be dropped once storage holds
515
- * the current key.
595
+ * PD055: a stored custom role names a permission by a key it was renamed from.
596
+ * It still resolves; the alias can only be dropped once storage holds the
597
+ * current key.
516
598
  */
517
599
  async function pd055(input) {
518
600
  const files = filesOf(input);
@@ -538,7 +620,10 @@ async function pd055(input) {
538
620
  });
539
621
  return findings;
540
622
  }
541
- /** Fixture API keys that never expire, credential policies that allow it, and records that are not v1 credentials. */
623
+ /**
624
+ * Fixture API keys that never expire, credential policies that allow it, and
625
+ * records that are not v1 credentials.
626
+ */
542
627
  function pd029(input) {
543
628
  const parsed = readFixture(input, input.config.doctor?.credentials);
544
629
  const findings = [];
@@ -604,7 +689,10 @@ const ROUTE_GLOBS = ["**/api/permdock/route.{ts,tsx,js,jsx,mjs}"];
604
689
  const ENDPOINT = /\bendpoint\s*(?::|=)\s*\{?\s*['"`]/u;
605
690
  const NATIVE_IMPORT = /\bfrom\s*['"]permdock\/react-native['"]/u;
606
691
  const CLIENT_READS = /* @__PURE__ */ new Set(["usePermission", "reference"]);
607
- /** A grant the snapshot marks `portable: false`, so a client check needs the endpoint. */
692
+ /**
693
+ * A grant the snapshot marks `portable: false`, so a client check needs the
694
+ * endpoint.
695
+ */
608
696
  function serverOnly(policy, grant) {
609
697
  if (!grant.portable || hasConditionOp(grant.where, "related")) return true;
610
698
  const relations = policy.resources.get(grant.permission.resource)?.relations;
@@ -619,7 +707,10 @@ function serverOnlyKeys(policy) {
619
707
  for (const grant of [...policy.grants, ...policy.roles.flatMap((binding) => binding.grants)]) if (grant.hosted === void 0 && grant.effect === "allow" && serverOnly(policy, grant)) keys.add(grant.permission.key);
620
708
  return keys;
621
709
  }
622
- /** An `app/**\/api/permdock/route.ts` that exports `permdockHandler`'s result, or an `endpoint` string in the source. */
710
+ /**
711
+ * An `app/**\/api/permdock/route.ts` that exports `permdockHandler`'s result,
712
+ * or an `endpoint` string in the source.
713
+ */
623
714
  function hasEndpoint(files, cwd, sources) {
624
715
  if (listSourceFiles(cwd, ROUTE_GLOBS).filter((file) => /(?:^|[\\/])app[\\/]/u.test(rel(cwd, file))).some((file) => files.read(file).includes("permdockHandler"))) return true;
625
716
  return sources.some((file) => ENDPOINT.test(files.read(file)));
@@ -751,11 +842,14 @@ async function pd019(input) {
751
842
  fix: "set rls.authorize: 'database', or lower [auth] jwt_expiry in supabase/config.toml to 3600 or less"
752
843
  }];
753
844
  }
754
- /** Fixture memberships the policy's scopes would drop: an undeclared scope, a missing parent id, mixed shapes. */
755
845
  /**
756
- * A scope whose roles can all be removed can end up with nobody able to
757
- * manage it. Setting `min` on any of its roles (even `min: 0`) records the
758
- * decision and silences the warning.
846
+ * Fixture memberships the policy's scopes would drop: an undeclared scope, a
847
+ * missing parent id, mixed shapes.
848
+ */
849
+ /**
850
+ * A scope whose roles can all be removed can end up with nobody able to manage
851
+ * it. Setting `min` on any of its roles (even `min: 0`) records the decision
852
+ * and silences the warning.
759
853
  */
760
854
  async function pd026(input) {
761
855
  if (input.config.policy === void 0) return [];
@@ -832,10 +926,28 @@ async function pd035(input) {
832
926
  //#endregion
833
927
  //#region src/cli/doctor/powersync.ts
834
928
  /**
929
+ * Why each membership source of a scope the streams read through sources has no
930
+ * stream form, once per source.
931
+ */
932
+ function sourceGaps(policy, config) {
933
+ const scopes = scopeList(policy.scopes);
934
+ const sources = membershipSourcesOf(config);
935
+ const gaps = /* @__PURE__ */ new Set();
936
+ for (const scope of scopes) {
937
+ if (scopeMembershipTable(config.rls?.memberships, scopes, scope.name) !== void 0) continue;
938
+ for (const source of scopeSourcesOf(sources, scope.name)) {
939
+ const stream = streamOf(source);
940
+ if (typeof stream === "string") gaps.add(stream);
941
+ }
942
+ }
943
+ return [...gaps];
944
+ }
945
+ /**
835
946
  * PD058: `sync-config.yaml` or the `powersync.manifest` file is not what the
836
- * policy compiles to, so PowerSync syncs rows, or the device builds
837
- * snapshots, by an older policy. A policy that does not compile is a finding
838
- * too.
947
+ * policy compiles to, so PowerSync syncs rows, or the device builds snapshots,
948
+ * by an older policy. A policy that does not compile is a finding too, and so
949
+ * is each membership source of a synced scope with no stream form: its members
950
+ * sync none of the rows it grants.
839
951
  */
840
952
  async function pd058(input) {
841
953
  const { cwd, config } = input;
@@ -853,12 +965,18 @@ async function pd058(input) {
853
965
  fix: "fix the powersync and rls config, then run permdock powersync generate"
854
966
  }];
855
967
  }
856
- return staleFiles(cwd, compiled.files).map((file) => ({
968
+ const gaps = sourceGaps(policy, config).map((gap) => ({
969
+ code: "PD058",
970
+ severity: "warning",
971
+ message: gap,
972
+ fix: "build the source with tableMembershipSource or junctionMembershipSource, without expiresAt or disabledAt, or serve its members from the server"
973
+ }));
974
+ return [...staleFiles(cwd, compiled.files).map((file) => ({
857
975
  code: "PD058",
858
976
  severity: "warning",
859
977
  message: file.missing ? `${file.path} is missing, so ${file.path === config.powersync?.manifest ? "the device builds no local snapshot" : "PowerSync syncs no stream the policy compiles to"}` : `${file.path} is not what the policy compiles to, so ${file.path === config.powersync?.manifest ? "the device builds snapshots" : "PowerSync syncs rows"} by an older policy`,
860
978
  fix: "run permdock powersync generate and deploy the files"
861
- }));
979
+ })), ...gaps];
862
980
  }
863
981
  //#endregion
864
982
  //#region src/cli/doctor/project.ts
@@ -889,7 +1007,10 @@ function isWorkspaceRoot(files, dir) {
889
1007
  return false;
890
1008
  }
891
1009
  }
892
- /** Whether `dir` holds a skills lock: PermDock's own, or the `skills` CLI's naming the `permdock` skill. */
1010
+ /**
1011
+ * Whether `dir` holds a skills lock: PermDock's own, or the `skills` CLI's
1012
+ * naming the `permdock` skill.
1013
+ */
893
1014
  function hasSkillsLock(files, dir) {
894
1015
  if (files.exists(join(dir, ".permdock/skills-lock.json"))) return true;
895
1016
  const shared = join(dir, "skills-lock.json");
@@ -994,10 +1115,10 @@ const ALTER_VIEW = new RegExp(String.raw`\balter\s+view\s+(?:if\s+exists\s+)?${V
994
1115
  const INVOKER = /\bsecurity_invoker\s*(?:=\s*(?:true|on|'true'|'on'|1)\b|[,)]|$)/iu;
995
1116
  const COMPANION = new RegExp(String.raw`\bcomment\s+on\s+view\s+${VIEW_NAME}\s+is\s+'${FIELD_VIEWS.comment}\b`, "giu");
996
1117
  /**
997
- * Views run as their owner unless `security_invoker` is set, so they read
998
- * past RLS on the tables beneath them. The `<table>_visible_fields`
999
- * companion `rls generate --revoke-columns` writes reads as its owner on
1000
- * purpose and carries a comment that says so.
1118
+ * Views run as their owner unless `security_invoker` is set, so they read past
1119
+ * RLS on the tables beneath them. The `<table>_visible_fields` companion `rls
1120
+ * generate --revoke-columns` writes reads as its owner on purpose and carries a
1121
+ * comment that says so.
1001
1122
  */
1002
1123
  function pd022(cwd, config, files = nodeFiles) {
1003
1124
  if (config.rls === void 0 && config.doctor?.migrations === void 0) return [];
@@ -1025,9 +1146,9 @@ function pd022(cwd, config, files = nodeFiles) {
1025
1146
  }
1026
1147
  const AUTH_ROLE = /\bauth\.role\s*\(\s*\)/giu;
1027
1148
  /**
1028
- * PD040: `auth.role()` in a migration. Supabase deprecated it; a policy
1029
- * names its Postgres roles with `to authenticated` instead, and the role
1030
- * claim it reads is the one PostgREST already switched to.
1149
+ * PD040: `auth.role()` in a migration. Supabase deprecated it; a policy names
1150
+ * its Postgres roles with `to authenticated` instead, and the role claim it
1151
+ * reads is the one PostgREST already switched to.
1031
1152
  */
1032
1153
  function pd040(cwd, config, files = nodeFiles) {
1033
1154
  const findings = [];
@@ -1064,10 +1185,10 @@ function applyPrivilege(writable, verb, part) {
1064
1185
  const CREATE_TABLE$1 = /^create\s+(?:(?:global|local)\s+)?(?:(?:temp|temporary|unlogged)\s+)?table\s+(?:if\s+not\s+exists\s+)?((?:"[^"]+"|\w+)(?:\.(?:"[^"]+"|\w+))?)\s*\(/iu;
1065
1186
  const REVOKE_DEFAULT_TABLES = /^alter\s+default\s+privileges\s+(?:for\s+(?:role|user)\s+[\w\s,"]+?\s+)?in\s+schema\s+"?public"?\s+revoke\s+[\s\S]+?\s+on\s+tables\s+from\s+[\s\S]*\b(?:anon|authenticated)\b/iu;
1066
1187
  /**
1067
- * Columns of `table` a client role may insert or update, per the migrations
1068
- * in order; `*` for every column. On Supabase a table created in `public`
1069
- * starts writable: the default privileges grant `anon` and `authenticated`
1070
- * everything, until a migration revokes them.
1188
+ * Columns of `table` a client role may insert or update, per the migrations in
1189
+ * order; `*` for every column. On Supabase a table created in `public` starts
1190
+ * writable: the default privileges grant `anon` and `authenticated` everything,
1191
+ * until a migration revokes them.
1071
1192
  */
1072
1193
  function clientWritable(files, cwd, config, target) {
1073
1194
  const writable = {
@@ -1096,7 +1217,10 @@ function clientWritable(files, cwd, config, target) {
1096
1217
  }
1097
1218
  return /* @__PURE__ */ new Set([...writable.insert, ...writable.update]);
1098
1219
  }
1099
- /** Membership columns a client can write: a user who sets `user_id` or `role` grants themselves access. */
1220
+ /**
1221
+ * Membership columns a client can write: a user who sets `user_id` or `role`
1222
+ * grants themselves access.
1223
+ */
1100
1224
  function membershipFindings(files, cwd, config) {
1101
1225
  const findings = [];
1102
1226
  for (const [table, columns] of membershipColumns(config)) {
@@ -1204,7 +1328,10 @@ async function pd020(input) {
1204
1328
  fix: "remove them from hostable, or drop their tables from rls.tables and enforce them in the application"
1205
1329
  }];
1206
1330
  }
1207
- /** Columns of `resource` a field-limited read grant can hide: missing from an allow's list, or on a deny's. */
1331
+ /**
1332
+ * Columns of `resource` a field-limited read grant can hide: missing from an
1333
+ * allow's list, or on a deny's.
1334
+ */
1208
1335
  function limitedColumns(policy, resource, actions) {
1209
1336
  const reads = policy.grants.filter((grant) => grant.permission.resource === resource && grant.fields !== void 0 && commandFor(grant.permission.action, actions) === "select");
1210
1337
  const node = policy.resources.get(resource);
@@ -1216,8 +1343,8 @@ function limitedColumns(policy, resource, actions) {
1216
1343
  }
1217
1344
  /**
1218
1345
  * `fields` redact in the application; RLS is row-level unless field views
1219
- * compile, and a field view protects nothing while the base table still
1220
- * returns the columns to a direct read.
1346
+ * compile, and a field view protects nothing while the base table still returns
1347
+ * the columns to a direct read.
1221
1348
  */
1222
1349
  async function pd030(input) {
1223
1350
  const rls = input.config.rls;
@@ -1229,8 +1356,8 @@ async function pd030(input) {
1229
1356
  for (const resource of resources) {
1230
1357
  const columns = limitedColumns(policy, resource, rls.actions);
1231
1358
  if (columns.length === 0) continue;
1232
- const table = tableFor(resource, rls.tables);
1233
- if (rls.fields !== "views") {
1359
+ const table = tableFor(resource, tableNames(rls.tables));
1360
+ if (rls.fields === void 0) {
1234
1361
  findings.push({
1235
1362
  code: "PD030",
1236
1363
  severity: "warning",
@@ -1249,9 +1376,9 @@ async function pd030(input) {
1249
1376
  return findings;
1250
1377
  }
1251
1378
  /**
1252
- * A self-parented resource no `through` grant walks, or a `restricted`
1253
- * column no graph grant reaches: the declaration has no effect on any
1254
- * decision, and `rls generate` keeps no closure for it.
1379
+ * A self-parented resource no `through` grant walks, or a `restricted` column
1380
+ * no graph grant reaches: the declaration has no effect on any decision, and
1381
+ * `rls generate` keeps no closure for it.
1255
1382
  */
1256
1383
  async function pd031(input) {
1257
1384
  if (input.config.policy === void 0) return [];
@@ -1279,8 +1406,8 @@ async function pd031(input) {
1279
1406
  }
1280
1407
  /**
1281
1408
  * Under an `rls` config, a graph resource `rls generate` cannot name a helper
1282
- * for: one that shares a scope's name (its `permitted_<name>_ids` would
1283
- * replace the scope helper) or is not a lowercase SQL name.
1409
+ * for: one that shares a scope's name (its `permitted_<name>_ids` would replace
1410
+ * the scope helper) or is not a lowercase SQL name.
1284
1411
  */
1285
1412
  async function pd032(input) {
1286
1413
  if (input.config.rls === void 0 || input.config.policy === void 0) return [];
@@ -1336,8 +1463,35 @@ async function pd034(input) {
1336
1463
  }));
1337
1464
  }
1338
1465
  /**
1339
- * Storage and Realtime policies written outside PermDock that call the SQL helpers for a permission whose grants
1340
- * carry row conditions: the helpers check only role and scope.
1466
+ * PD076: `rls.actions` entries set to `'none'` that change nothing: a verb that
1467
+ * is not one of the six default verbs and does not read as a write compiles to
1468
+ * no policy anyway, and a verb no permission uses compiles to nothing at all. A
1469
+ * write-sounding `none` stays, because it silences PD071.
1470
+ */
1471
+ async function pd076(input) {
1472
+ const actions = input.config.rls?.actions;
1473
+ if (actions === void 0 || input.config.policy === void 0) return [];
1474
+ const policy = await policyOf(input);
1475
+ if (policy === void 0) return [];
1476
+ const used = new Set(listPermissions(policy.vocabulary.permissions).map((leaf) => leaf.action));
1477
+ const unused = Object.keys(actions).filter((verb) => !used.has(verb)).toSorted();
1478
+ const noop = Object.entries(actions).filter(([verb, command]) => command === "none" && used.has(verb) && commandFor(verb) === void 0 && !suggestsWrite(verb)).map(([verb]) => verb).toSorted();
1479
+ return [...noop.length === 0 ? [] : [{
1480
+ code: "PD076",
1481
+ severity: "info",
1482
+ message: `rls.actions sets ${noop.join(", ")} to 'none', which is already what ${noop.length === 1 ? "that verb compiles" : "those verbs compile"} to`,
1483
+ fix: `delete these entries: ${noop.join(", ")}`
1484
+ }], ...unused.length === 0 ? [] : [{
1485
+ code: "PD076",
1486
+ severity: "info",
1487
+ message: `rls.actions maps ${unused.join(", ")}, which no permission uses`,
1488
+ fix: `delete these entries, or fix the verb's spelling: ${unused.join(", ")}`
1489
+ }]];
1490
+ }
1491
+ /**
1492
+ * Storage and Realtime policies written outside PermDock that call the SQL
1493
+ * helpers for a permission whose grants carry row conditions: the helpers check
1494
+ * only role and scope.
1341
1495
  */
1342
1496
  async function pd037(input) {
1343
1497
  const files = filesOf(input);
@@ -1374,7 +1528,10 @@ const WRITE_VERB_PREFIXES = [
1374
1528
  "confirm",
1375
1529
  "pause"
1376
1530
  ];
1377
- /** `verb` starts with a write prefix that ends at a word boundary: `markPaid`, not `market`. */
1531
+ /**
1532
+ * `verb` starts with a write prefix that ends at a word boundary: `markPaid`,
1533
+ * not `market`.
1534
+ */
1378
1535
  function suggestsWrite(verb) {
1379
1536
  return WRITE_VERB_PREFIXES.some((prefix) => {
1380
1537
  if (!verb.startsWith(prefix)) return false;
@@ -1399,20 +1556,100 @@ async function pd071(input) {
1399
1556
  fix: `map it on purpose in rls.actions: ${verb}: "insert", "update", "delete" or "none"`
1400
1557
  }));
1401
1558
  }
1559
+ /**
1560
+ * PD072: a membership source reads role keys through the table of custom roles
1561
+ * (`rls.customRoleWrites.roles`), which tenants write.
1562
+ */
1563
+ function pd072(input) {
1564
+ const roles = input.config.rls?.customRoleWrites?.roles;
1565
+ if (roles?.tenant === void 0) return [];
1566
+ const target = qualifySqlTable(roles.table);
1567
+ return membershipSourcesOf(input.config).filter((source) => source.sql.throughs.some((through) => through.table === target)).map((source) => ({
1568
+ code: "PD072",
1569
+ severity: "warning",
1570
+ message: `the ${source.sql.table} membership source reads role keys through ${target}, whose tenant rows tenants write: a tenant row named like a declared role must not grant it`,
1571
+ fix: `keep the permdock_custom_role_name_guard trigger on ${target} (rls generate emits it with customRoleWrites.roles) and generate with this config, so helpers read a tenant row named like a declared role as no role`
1572
+ }));
1573
+ }
1574
+ /** PD073: a role's `for` lists kinds no membership source of its scope can hold. */
1575
+ async function pd073(input) {
1576
+ const rls = input.config.rls;
1577
+ if (rls === void 0 || input.config.policy === void 0) return [];
1578
+ const policy = await policyOf(input);
1579
+ if (policy === void 0) return [];
1580
+ const scopes = scopeList(policy.scopes);
1581
+ const ownership = ownershipRules(policy, scopes);
1582
+ const sources = membershipSourcesOf(input.config);
1583
+ const ctx = {
1584
+ dialect: "supabase",
1585
+ scopes,
1586
+ tenantClaim: "tenant_id",
1587
+ gucPrefix: "app",
1588
+ ...rls.memberships === void 0 ? {} : { memberships: rls.memberships },
1589
+ ...sources === void 0 ? {} : { memberSources: sources },
1590
+ ...ownership === void 0 ? {} : { ownership }
1591
+ };
1592
+ return unsatisfiedKinds(ctx, policy).map((item) => ({
1593
+ code: "PD073",
1594
+ severity: "error",
1595
+ message: `role ${item.role} is for ${item.for.join(", ")}, but its membership sources hold ${item.sources.join(", ")}: no membership can hold it`,
1596
+ fix: `set via on one of those sources to ${item.for.join(" or ")}, or change for on role ${item.role}`
1597
+ }));
1598
+ }
1599
+ /**
1600
+ * PD075: two resources that `rls.tables` maps to one table, each with its own
1601
+ * keys and helpers for the same rows. `doctor.sharedTables` lists tables split
1602
+ * on purpose (two resources over disjoint rows).
1603
+ */
1604
+ async function pd075(input) {
1605
+ const rls = input.config.rls;
1606
+ if (rls === void 0 || input.config.policy === void 0) return [];
1607
+ const policy = await policyOf(input);
1608
+ if (policy === void 0) return [];
1609
+ const allowed = new Set((input.config.doctor?.sharedTables ?? []).map(qualifySqlTable));
1610
+ const byTable = /* @__PURE__ */ new Map();
1611
+ for (const leaf of listPermissions(policy.vocabulary.permissions)) {
1612
+ const table = qualifySqlTable(tableNameOf(rls.tables?.[leaf.resource], leaf.resource));
1613
+ byTable.set(table, (byTable.get(table) ?? /* @__PURE__ */ new Set()).add(leaf.resource));
1614
+ }
1615
+ return [...byTable.entries()].filter(([table, resources]) => resources.size > 1 && !allowed.has(table)).toSorted(byKey).map(([table, resources]) => {
1616
+ return {
1617
+ code: "PD075",
1618
+ severity: "warning",
1619
+ message: `rls.tables maps ${[...resources].toSorted().join(" and ")} to ${table}, so the same rows carry two sets of keys and helpers`,
1620
+ fix: `merge them into one resource (https://permdock.com/docs/guides/merge-resources), or list ${table} in doctor.sharedTables when the resources cover disjoint rows`
1621
+ };
1622
+ });
1623
+ }
1402
1624
  //#endregion
1403
1625
  //#region src/cli/doctor/seeds.ts
1404
1626
  const SEED_INSERT = /^insert\s+into\s+((?:"[^"]+"|\w+)(?:\.(?:"[^"]+"|\w+))?)\s*\(\s*role\s*,\s*permission\s*,\s*grant_key\s*,\s*scope\s*,\s*effect\s*\)\s*values\s*([\s\S]*?)\s*on\s+conflict\b/iu;
1405
1627
  const SEED_CLEAR = /^delete\s+from\s+((?:"[^"]+"|\w+)(?:\.(?:"[^"]+"|\w+))?)\s*$/iu;
1406
1628
  const LITERAL = String.raw`'((?:[^']|'')*)'`;
1407
1629
  const SEED_ROW = new RegExp(String.raw`\(\s*${LITERAL}\s*,\s*${LITERAL}\s*,\s*${LITERAL}\s*,\s*${LITERAL}\s*,\s*${LITERAL}\s*\)`, "gu");
1630
+ const SEED_VIEW = /^create\s+(?:or\s+replace\s+)?view\s+((?:"[^"]+"|\w+)(?:\.(?:"[^"]+"|\w+))?)\s*\([^)]*\)\s*with\s*\([^)]*\)\s*as\s+([\s\S]*)$/iu;
1631
+ const SEED_FUNCTION = /^create\s+(?:or\s+replace\s+)?function\s+(?:"[^"]+"|\w+)\.(?:"seed"|seed)\s*\(\s*\)[\s\S]*?\$(\w*)\$([\s\S]*)\$\1\$/iu;
1408
1632
  function rowKey(values) {
1409
1633
  return values.join(" ");
1410
1634
  }
1411
- /** The rows of the last statement that seeds or clears `table`, in migration order. */
1635
+ /**
1636
+ * The statements of a file, with the body of `<schema>.seed()` (`rls.seeds:
1637
+ * 'function'`) in place of its `create function`.
1638
+ */
1639
+ function seedStatements(sql) {
1640
+ return sqlStatements(sql).flatMap((statement) => {
1641
+ const fn = SEED_FUNCTION.exec(statement.text);
1642
+ return fn === null ? [statement] : sqlStatements(group(fn, 2));
1643
+ });
1644
+ }
1645
+ /**
1646
+ * The rows of the last statement that seeds or clears `table`, in migration
1647
+ * order.
1648
+ */
1412
1649
  function lastSeed(files, cwd, config, table) {
1413
1650
  let seeded;
1414
- for (const file of sqlFiles(cwd, config.doctor?.migrations ?? MIGRATION_DIRS)) for (const { text } of sqlStatements(files.read(file))) {
1415
- const insert = SEED_INSERT.exec(text);
1651
+ for (const file of sqlFiles(cwd, config.doctor?.migrations ?? MIGRATION_DIRS)) for (const { text } of seedStatements(files.read(file))) {
1652
+ const insert = SEED_INSERT.exec(text) ?? SEED_VIEW.exec(text);
1416
1653
  if (insert !== null && tableKey(group(insert, 1)) === table) {
1417
1654
  const rows = /* @__PURE__ */ new Set();
1418
1655
  for (const row of group(insert, 2).matchAll(SEED_ROW)) rows.add(rowKey(row.slice(1, 6).map((value) => value.replaceAll("''", "'"))));
@@ -1435,8 +1672,8 @@ function sample(rows) {
1435
1672
  return rows.slice(0, 3).map((row) => `(${row})`).join(", ");
1436
1673
  }
1437
1674
  /**
1438
- * PD054: the `role_permissions` rows the migrations seed last are not the
1439
- * rows the policy compiles to, so the helpers answer from a stale policy.
1675
+ * PD054: the `role_permissions` rows the migrations seed last are not the rows
1676
+ * the policy compiles to, so the helpers answer from a stale policy.
1440
1677
  */
1441
1678
  async function pd054(input) {
1442
1679
  const { cwd, config } = input;
@@ -1447,18 +1684,26 @@ async function pd054(input) {
1447
1684
  if (seeded === void 0) return [];
1448
1685
  const policy = await policyOf(input);
1449
1686
  if (policy === void 0) return [];
1450
- const ctx = {
1687
+ const generate = {
1688
+ cwd,
1689
+ config,
1690
+ target: "sql",
1451
1691
  dialect: rls?.dialect ?? "supabase",
1452
- scopes: scopeList(policy.scopes),
1453
- tenantClaim: rls?.tenantClaim ?? "tenant_id",
1454
- gucPrefix: rls?.gucPrefix ?? "app",
1455
- ...rls?.actions === void 0 ? {} : { actions: rls.actions },
1456
- schema,
1457
- ...rls?.fields === "views" ? { fields: "views" } : {}
1692
+ rbac: false,
1693
+ check: false,
1694
+ skipClosures: true,
1695
+ inlineFunctions: false,
1696
+ io: {
1697
+ stdout: () => void 0,
1698
+ stderr: () => void 0
1699
+ }
1458
1700
  };
1459
1701
  let expected;
1460
1702
  try {
1461
- expected = new Set(compileGrants(policy, ctx, rls?.tables, [], true).rolePermissions.map((row) => rowKey([
1703
+ const options = generateOptions(generate);
1704
+ const built = isRefusal(options) ? options : buildContext(generate, policy, options);
1705
+ if (isRefusal(built)) return [];
1706
+ expected = new Set(compileGrants(policy, built.ctx, tableNames(rls?.tables), [], true, rls?.rowHelpers !== void 0 || inheritTargets(policy).length > 0).rolePermissions.map((row) => rowKey([
1462
1707
  row.role,
1463
1708
  row.permission,
1464
1709
  row.grantKey,
@@ -1518,7 +1763,10 @@ function pd046(cwd, config, files = nodeFiles) {
1518
1763
  }];
1519
1764
  }
1520
1765
  const USER_METADATA = /\b(raw_user_meta_data|user_metadata)\b/giu;
1521
- /** PD047: SQL that reads `user_metadata`, which every user can edit for themselves. */
1766
+ /**
1767
+ * PD047: SQL that reads `user_metadata`, which every user can edit for
1768
+ * themselves.
1769
+ */
1522
1770
  function pd047(cwd, config, files = nodeFiles) {
1523
1771
  if (!isSupabase(files, cwd, config)) return [];
1524
1772
  return migrationStatements(files, cwd, config).flatMap((statement) => [...statement.text.matchAll(USER_METADATA)].map((match) => ({
@@ -1542,7 +1790,10 @@ function createdFunctions(statements) {
1542
1790
  }];
1543
1791
  });
1544
1792
  }
1545
- /** PD048: a function without `set search_path`, so a caller's objects can shadow the ones it names. */
1793
+ /**
1794
+ * PD048: a function without `set search_path`, so a caller's objects can shadow
1795
+ * the ones it names.
1796
+ */
1546
1797
  function pd048(cwd, config, files = nodeFiles) {
1547
1798
  if (!isSupabase(files, cwd, config)) return [];
1548
1799
  const statements = migrationStatements(files, cwd, config);
@@ -1560,7 +1811,10 @@ function pd048(cwd, config, files = nodeFiles) {
1560
1811
  };
1561
1812
  });
1562
1813
  }
1563
- /** Roles each `revoke` statement takes `execute` from, per function key or `schema.*`. */
1814
+ /**
1815
+ * Roles each `revoke` statement takes `execute` from, per function key or
1816
+ * `schema.*`.
1817
+ */
1564
1818
  function revokedExecute(statements) {
1565
1819
  const revoked = /* @__PURE__ */ new Map();
1566
1820
  const add = (key, roles) => {
@@ -1583,24 +1837,53 @@ function revokedExecute(statements) {
1583
1837
  return revoked;
1584
1838
  }
1585
1839
  /**
1840
+ * `supabase.hook.claims` and `hook.before` functions, by key, with the argument
1841
+ * type the hook calls them with.
1842
+ */
1843
+ function hookClaimFunctions(config) {
1844
+ const hook = config.supabase?.hook;
1845
+ const before = hook?.before;
1846
+ const functions = /* @__PURE__ */ new Map();
1847
+ for (const fn of Object.values(hook?.claims ?? {})) if (typeof fn === "string") functions.set(tableKey(fn), "uuid");
1848
+ for (const fn of typeof before === "string" ? [before] : before ?? []) if (typeof fn === "string") functions.set(tableKey(fn), "jsonb");
1849
+ return functions;
1850
+ }
1851
+ /**
1586
1852
  * PD049: a `security definer` function `public` (every role) or, in Supabase's
1587
1853
  * `public` schema, `anon` may still execute: Postgres grants `execute` to
1588
- * `public` on create, and Supabase's default privileges grant it to `anon`.
1854
+ * `public` on create, and Supabase's default privileges grant it to `anon`. A
1855
+ * hook claim function returns any user's claims, so `authenticated` must not
1856
+ * execute it either, definer or not.
1589
1857
  */
1590
1858
  function pd049(cwd, config, files = nodeFiles) {
1591
1859
  if (!isSupabase(files, cwd, config)) return [];
1592
1860
  const statements = migrationStatements(files, cwd, config);
1593
1861
  const revoked = revokedExecute(statements);
1862
+ const hookFunctions = hookClaimFunctions(config);
1594
1863
  const findings = [];
1595
1864
  for (const fn of createdFunctions(statements)) {
1596
- if (!/\bsecurity\s+definer\b/iu.test(fn.head) || /\breturns\s+(?:event_)?trigger\b/iu.test(fn.head)) continue;
1865
+ const hookArgument = hookFunctions.get(fn.key);
1866
+ if (hookArgument === void 0 && (!/\bsecurity\s+definer\b/iu.test(fn.head) || /\breturns\s+(?:event_)?trigger\b/iu.test(fn.head))) continue;
1597
1867
  const schema = schemaOf(fn.key);
1598
1868
  const from = /* @__PURE__ */ new Set([
1599
1869
  ...revoked.get(fn.key) ?? [],
1600
1870
  ...revoked.get(`${schema}.*`) ?? [],
1601
1871
  ...revoked.get("*.*") ?? []
1602
1872
  ]);
1603
- const missing = ["public", ...schema === "public" ? ["anon"] : []].filter((role) => !from.has(role));
1873
+ const missing = (hookArgument === void 0 ? ["public", ...schema === "public" ? ["anon"] : []] : [
1874
+ "public",
1875
+ "anon",
1876
+ "authenticated"
1877
+ ]).filter((role) => !from.has(role));
1878
+ if (missing.length > 0 && hookArgument !== void 0) {
1879
+ findings.push({
1880
+ code: "PD049",
1881
+ severity: "warning",
1882
+ message: `${fn.file}:${String(fn.line)} hook claim function ${fn.key} returns any user's claims and can be executed by ${missing.join(" and ")}`,
1883
+ fix: `regenerate the hook (permdock rls generate), which revokes it, or add revoke all on function ${fn.key}(${hookArgument}) from public, anon, authenticated;`
1884
+ });
1885
+ continue;
1886
+ }
1604
1887
  if (missing.length > 0) findings.push({
1605
1888
  code: "PD049",
1606
1889
  severity: "warning",
@@ -1613,7 +1896,10 @@ function pd049(cwd, config, files = nodeFiles) {
1613
1896
  const CREATE_TABLE = new RegExp(String.raw`^create\s+(?:(?:global|local)\s+)?(?:(?:temp|temporary|unlogged)\s+)?table\s+(?:if\s+not\s+exists\s+)?${NAME}\s*\(`, "iu");
1614
1897
  const ENABLE_RLS = new RegExp(String.raw`^alter\s+table\s+(?:if\s+exists\s+)?(?:only\s+)?${NAME}[\s\S]*\benable\s+row\s+level\s+security\b`, "iu");
1615
1898
  const DROP_TABLE = /^drop\s+table\s+(?:if\s+exists\s+)?([\s\S]+?)(?:\s+(?:cascade|restrict))?$/iu;
1616
- /** PD050: a `public` table without row level security, which the Data API serves whole. */
1899
+ /**
1900
+ * PD050: a `public` table without row level security, which the Data API serves
1901
+ * whole.
1902
+ */
1617
1903
  function pd050(cwd, config, files = nodeFiles) {
1618
1904
  if (!isSupabase(files, cwd, config)) return [];
1619
1905
  const created = /* @__PURE__ */ new Map();
@@ -1641,7 +1927,10 @@ function pd050(cwd, config, files = nodeFiles) {
1641
1927
  }
1642
1928
  const CREATE_POLICY = new RegExp(String.raw`^create\s+policy\s+${IDENT}\s+on\s+${NAME}([\s\S]*)$`, "iu");
1643
1929
  const UNWRAPPED_AUTH = /(?<!\bselect\s{1,20})\bauth\.(uid|jwt)\s*\(\s*\)/giu;
1644
- /** PD051: a policy that calls `auth.uid()` or `auth.jwt()` bare, so Postgres runs it once per row. */
1930
+ /**
1931
+ * PD051: a policy that calls `auth.uid()` or `auth.jwt()` bare, so Postgres
1932
+ * runs it once per row.
1933
+ */
1645
1934
  function pd051(cwd, config, files = nodeFiles) {
1646
1935
  if (!isSupabase(files, cwd, config)) return [];
1647
1936
  return migrationStatements(files, cwd, config).flatMap((statement) => {
@@ -1657,7 +1946,10 @@ function pd051(cwd, config, files = nodeFiles) {
1657
1946
  }];
1658
1947
  });
1659
1948
  }
1660
- /** PD052: an update policy without `with check`, so nothing states what a row may become. */
1949
+ /**
1950
+ * PD052: an update policy without `with check`, so nothing states what a row
1951
+ * may become.
1952
+ */
1661
1953
  function pd052(cwd, config, files = nodeFiles) {
1662
1954
  if (!isSupabase(files, cwd, config)) return [];
1663
1955
  return migrationStatements(files, cwd, config).flatMap((statement) => {
@@ -1690,9 +1982,9 @@ function topLevelParts(body) {
1690
1982
  return parts.filter((part) => part !== "");
1691
1983
  }
1692
1984
  /**
1693
- * One column definition or table constraint of a `create table` body: its
1694
- * first column, whether it is a foreign key, and whether a primary key or
1695
- * unique constraint indexes that column.
1985
+ * One column definition or table constraint of a `create table` body: its first
1986
+ * column, whether it is a foreign key, and whether a primary key or unique
1987
+ * constraint indexes that column.
1696
1988
  */
1697
1989
  function tablePart(raw) {
1698
1990
  const part = raw.replace(/^constraint\s+(?:"[^"]+"|\w+)\s+/iu, "");
@@ -1716,7 +2008,10 @@ function firstColumn(list) {
1716
2008
  }
1717
2009
  const ADD_CONSTRAINT = new RegExp(String.raw`^alter\s+table\s+(?:if\s+exists\s+)?(?:only\s+)?${NAME}\s+add\s+(?:constraint\s+${IDENT}\s+)?(foreign\s+key|primary\s+key|unique)\s*\(([^)]*)\)`, "iu");
1718
2010
  const CREATE_INDEX = new RegExp(String.raw`^create\s+(?:unique\s+)?index\s+(?:concurrently\s+)?(?:if\s+not\s+exists\s+)?(?:${IDENT}\s+)?on\s+(?:only\s+)?${NAME}\s*(?:using\s+\w+\s*)?\(\s*${IDENT}`, "iu");
1719
- /** PD053: a foreign key no index starts with, so joins and deletes on the referenced row scan the table. */
2011
+ /**
2012
+ * PD053: a foreign key no index starts with, so joins and deletes on the
2013
+ * referenced row scan the table.
2014
+ */
1720
2015
  function pd053(cwd, config, files = nodeFiles) {
1721
2016
  if (!isSupabase(files, cwd, config)) return [];
1722
2017
  const keys = [];
@@ -1765,10 +2060,10 @@ function at(statement) {
1765
2060
  return `${statement.file}:${String(statement.line)}`;
1766
2061
  }
1767
2062
  /**
1768
- * PD062: SQL that reads or sets a per-claim `request.jwt.claim.<name>`
1769
- * setting. Current PostgREST, `withPostgresClient`, PermDock's `withSubject`
1770
- * and `rls verify` set only `request.jwt.claims`. A function replaced by a
1771
- * later migration is judged by its last definition.
2063
+ * PD062: SQL that reads or sets a per-claim `request.jwt.claim.<name>` setting.
2064
+ * Current PostgREST, `withPostgresClient`, PermDock's `withSubject` and `rls
2065
+ * verify` set only `request.jwt.claims`. A function replaced by a later
2066
+ * migration is judged by its last definition.
1772
2067
  */
1773
2068
  function pd062(cwd, config, files = nodeFiles) {
1774
2069
  if (!isSupabase(files, cwd, config)) return [];
@@ -1787,8 +2082,8 @@ function pd062(cwd, config, files = nodeFiles) {
1787
2082
  });
1788
2083
  }
1789
2084
  /**
1790
- * PD063: a migration statement supautils rejects for `postgres`, so
1791
- * `supabase db push` fails on it.
2085
+ * PD063: a migration statement supautils rejects for `postgres`, so `supabase
2086
+ * db push` fails on it.
1792
2087
  */
1793
2088
  function pd063(cwd, config, files = nodeFiles) {
1794
2089
  if (!isSupabase(files, cwd, config)) return [];
@@ -1846,9 +2141,9 @@ function pd066(cwd, config, files = nodeFiles) {
1846
2141
  //#endregion
1847
2142
  //#region src/cli/doctor/suspension.ts
1848
2143
  /**
1849
- * PD061: a suspended scope keeps permissions. Each scope's kept keys are
1850
- * listed for review, since its members hold them while the instance is
1851
- * suspended, and a key the definitions do not declare is named apart.
2144
+ * PD061: a suspended scope keeps permissions. Each scope's kept keys are listed
2145
+ * for review, since its members hold them while the instance is suspended, and
2146
+ * a key the definitions do not declare is named apart.
1852
2147
  */
1853
2148
  async function pd061(input) {
1854
2149
  const suspension = input.config.rls?.suspension;
@@ -2078,6 +2373,31 @@ const DOCTOR_CHECKS = [
2078
2373
  groups: ["rls"],
2079
2374
  run: pd071
2080
2375
  },
2376
+ {
2377
+ code: "PD072",
2378
+ groups: ["rls"],
2379
+ run: pd072
2380
+ },
2381
+ {
2382
+ code: "PD073",
2383
+ groups: ["rls", "ownership"],
2384
+ run: pd073
2385
+ },
2386
+ {
2387
+ code: "PD075",
2388
+ groups: ["rls"],
2389
+ run: pd075
2390
+ },
2391
+ {
2392
+ code: "PD076",
2393
+ groups: ["rls"],
2394
+ run: pd076
2395
+ },
2396
+ {
2397
+ code: "PD077",
2398
+ groups: ["rls", "scopes"],
2399
+ run: pd077
2400
+ },
2081
2401
  {
2082
2402
  code: "PD028",
2083
2403
  groups: ["attrs", "supabase"],
@@ -2181,6 +2501,12 @@ const DOCTOR_CHECKS = [
2181
2501
  groups: ["supabase"],
2182
2502
  run: (project) => pd045(project.cwd)
2183
2503
  },
2504
+ {
2505
+ code: "PD074",
2506
+ groups: ["supabase", "helpers"],
2507
+ when: (config) => config.supabase?.hook !== void 0,
2508
+ run: (project) => pd074(project.cwd, project.config)
2509
+ },
2184
2510
  ...[
2185
2511
  ["PD046", pd046],
2186
2512
  ["PD047", pd047],
@@ -2295,7 +2621,10 @@ async function runDoctor(input) {
2295
2621
  }))
2296
2622
  };
2297
2623
  }
2298
- /** PD059: the configured policy module throws or exports no policy, so every policy check is skipped. */
2624
+ /**
2625
+ * PD059: the configured policy module throws or exports no policy, so every
2626
+ * policy check is skipped.
2627
+ */
2299
2628
  async function pd059(project) {
2300
2629
  const load = await project.policyLoad();
2301
2630
  if (load.status !== "failed") return [];
@@ -2306,7 +2635,10 @@ async function pd059(project) {
2306
2635
  fix: "fix the module so it exports policy from definePolicy, or point policy in permdock.config.ts at the module that does"
2307
2636
  }];
2308
2637
  }
2309
- /** PD060: a source file under srcPath has a syntax error, so collect and usage miss what it references. */
2638
+ /**
2639
+ * PD060: a source file under srcPath has a syntax error, so collect and usage
2640
+ * miss what it references.
2641
+ */
2310
2642
  async function pd060(project) {
2311
2643
  return ((await project.collected()).scan?.unparsed ?? []).map((item) => ({
2312
2644
  code: "PD060",
@@ -2315,7 +2647,10 @@ async function pd060(project) {
2315
2647
  fix: "fix the syntax error, or exclude the file from collect.srcPath"
2316
2648
  }));
2317
2649
  }
2318
- /** A usage message for the first `--only` value that names no check code or group. */
2650
+ /**
2651
+ * A usage message for the first `--only` value that names no check code or
2652
+ * group.
2653
+ */
2319
2654
  function unknownOnly(wanted) {
2320
2655
  const known = /* @__PURE__ */ new Set();
2321
2656
  for (const check of DOCTOR_CHECKS) {
@@ -2333,15 +2668,24 @@ function formatDoctor(report, color) {
2333
2668
  for (const change of report.fixed) lines.push(` ${style.okMark} fixed ${change}`);
2334
2669
  if (report.fixed.length > 0) lines.push("");
2335
2670
  for (const finding of report.findings) {
2336
- const mark = finding.severity === "error" ? style.errorMark : style.warnMark;
2671
+ const mark = markOf(finding.severity, style);
2337
2672
  lines.push(` ${mark} ${style.paint("bold", finding.code)} ${finding.message}`);
2338
2673
  lines.push(` ${style.paint("dim", `fix: ${finding.fix}`)}`);
2339
2674
  }
2340
2675
  if (report.findings.length === 0) lines.push(" no findings");
2341
2676
  lines.push("");
2342
- lines.push(` ${String(report.errors)} error${report.errors === 1 ? "" : "s"}, ${String(report.warnings)} warning${report.warnings === 1 ? "" : "s"}`);
2677
+ const notes = report.findings.filter((finding) => finding.severity === "info").length;
2678
+ lines.push(` ${String(report.errors)} error${report.errors === 1 ? "" : "s"}, ${String(report.warnings)} warning${report.warnings === 1 ? "" : "s"}${notes === 0 ? "" : `, ${String(notes)} note${notes === 1 ? "" : "s"}`}`);
2343
2679
  return `${lines.join("\n")}\n`;
2344
2680
  }
2681
+ function markOf(severity, style) {
2682
+ switch (severity) {
2683
+ case "error": return style.errorMark;
2684
+ case "warning": return style.warnMark;
2685
+ case "info": return style.infoMark;
2686
+ default: return severity;
2687
+ }
2688
+ }
2345
2689
  async function supabaseSetup(input) {
2346
2690
  const policy = await input.policy();
2347
2691
  if (policy === void 0) return [];