permdock 0.1.0 → 0.3.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 (350) hide show
  1. package/README.md +106 -47
  2. package/dist/a2a/index.d.ts +7 -16
  3. package/dist/a2a/index.js +59 -98
  4. package/dist/adapter-context-mlWsVGGg.js +23 -0
  5. package/dist/ai-sdk/index.d.ts +37 -16
  6. package/dist/ai-sdk/index.js +30 -13
  7. package/dist/approvals/index.d.ts +3 -3
  8. package/dist/approvals/index.js +5 -4
  9. package/dist/{approvals-DaxY-Bdg.js → approvals-DbYAuNkG.js} +17 -11
  10. package/dist/approvers-DT4AVyIg.js +52 -0
  11. package/dist/{arazzo-CTeVuXr5.js → arazzo-BAgw9ap6.js} +2 -2
  12. package/dist/{arazzo-aoTkqYsJ.js → arazzo-CKwwqFWz.js} +2 -2
  13. package/dist/authzen/index.d.ts +4 -13
  14. package/dist/authzen/index.js +16 -50
  15. package/dist/better-auth/index.d.ts +20 -3
  16. package/dist/better-auth/index.js +27 -7
  17. package/dist/better-supabase/index.d.ts +223 -0
  18. package/dist/better-supabase/index.js +648 -0
  19. package/dist/bind-C_ob3LKa.d.ts +25 -0
  20. package/dist/bind-CuzGytRf.js +97 -0
  21. package/dist/boundary-BM8a_P6E.js +13 -0
  22. package/dist/boundary-BmHxVH1J.d.ts +15 -0
  23. package/dist/canonical-json-DemiK4Vp.js +26 -0
  24. package/dist/{capability-BDG_nkxt.d.ts → capability-2kYTMWDv.d.ts} +2 -2
  25. package/dist/{capability-B68OFnZx.js → capability-4qPdO9gk.js} +7 -5
  26. package/dist/catalog/index.d.ts +1 -1
  27. package/dist/catalog/index.js +1 -1
  28. package/dist/catalog-CRW5Mx_B.js +2 -0
  29. package/dist/{catalog-H-vFGwWK.js → catalog-DWF5cYqB.js} +4 -4
  30. package/dist/{catalog-B0E6bggc.js → catalog-dFZdWCGN.js} +2 -2
  31. package/dist/{catalog-doc-BSo_Q_-6.js → catalog-doc-DdGm82XT.js} +20 -32
  32. package/dist/claude-agent/index.d.ts +5 -14
  33. package/dist/claude-agent/index.js +4 -10
  34. package/dist/clerk/index.d.ts +12 -3
  35. package/dist/clerk/index.js +26 -5
  36. package/dist/cli/bin.js +1 -1
  37. package/dist/cli/index.d.ts +3 -3
  38. package/dist/cli/index.js +2 -2
  39. package/dist/clients-C7zLFuWT.d.ts +12 -0
  40. package/dist/clients-DjU5ABMy.js +23 -0
  41. package/dist/cloud/index.d.ts +4 -5
  42. package/dist/cloud/index.js +20 -6
  43. package/dist/{cloud-BNQTrmrr.js → cloud-CB_ELYuX.js} +2 -2
  44. package/dist/{cloud-Cuxr6Czw.js → cloud-DWLXO2af.js} +7 -6
  45. package/dist/collect-DClJsheJ.js +83 -0
  46. package/dist/{collect-O-tOtbnk.js → collect-DSTE3ml9.js} +194 -42
  47. package/dist/collect-DSWOk19R.js +2 -0
  48. package/dist/{commands-BMh_Etm2.js → commands-DSxCqG9A.js} +16 -12
  49. package/dist/compile/index.d.ts +3 -0
  50. package/dist/compile/index.js +2 -0
  51. package/dist/{compile-D22iwvuV.js → compile-Ba4blROR.js} +85 -30
  52. package/dist/compile-BkRyBDBw.d.ts +94 -0
  53. package/dist/config-BJiM-xAm.js +157 -0
  54. package/dist/config-Dnszbv-6.js +36 -0
  55. package/dist/config-report-DMvWKUxL.js +44 -0
  56. package/dist/{connection-JvqwHODC.js → connection-CU8MQxRi.js} +1 -1
  57. package/dist/{context-CKEAabd7.js → context-Bcy85rGi.js} +36 -27
  58. package/dist/convex/index.d.ts +9 -4
  59. package/dist/convex/index.js +14 -4
  60. package/dist/create-B1d519XK.d.ts +245 -0
  61. package/dist/create-CMwIl-w2.js +253 -0
  62. package/dist/{credential-B_rkUNlY.js → credential-8P81ff4u.js} +26 -46
  63. package/dist/delegation-D8pUEuce.js +103 -0
  64. package/dist/{describe-Bt1YD5uS.js → describe-B_gVZEVi.js} +10 -15
  65. package/dist/{describe-DernyItf.d.ts → describe-DMYiCjJV.d.ts} +9 -10
  66. package/dist/{diff-x5Il8LVa.js → diff-2VaeChzX.js} +44 -11
  67. package/dist/{diff-BUzf5Poi.js → diff-DBIhz_f2.js} +2 -2
  68. package/dist/{doctor-Bqo6FwUa.js → doctor-BwCAMLx_.js} +2 -2
  69. package/dist/doctor-collect-CHk6XWOA.js +665 -0
  70. package/dist/doctor-igIiM_Hl.js +1194 -0
  71. package/dist/drizzle/index.d.ts +4 -3
  72. package/dist/drizzle/index.js +3 -3
  73. package/dist/elysia/index.d.ts +6 -28
  74. package/dist/elysia/index.js +16 -60
  75. package/dist/{errors-DSMnAVNa.js → errors-CWfoNg9N.js} +8 -4
  76. package/dist/{errors-Iy71s7Oj.js → errors-Cz5zn0mW.js} +17 -71
  77. package/dist/{errors-DbZ1YOnb.d.ts → errors-DPdqI50v.d.ts} +8 -21
  78. package/dist/{errors-m3u9TmDu.js → errors-DRnGZHzF.js} +4 -1
  79. package/dist/evaluation-items-CfCCejQd.js +40 -0
  80. package/dist/{evaluations-DsAU9ppl.js → evaluations-tz6D9A2G.js} +28 -46
  81. package/dist/eve/index.d.ts +6 -15
  82. package/dist/eve/index.js +7 -12
  83. package/dist/expiry-BoBJ8Tvc.js +7 -0
  84. package/dist/express/index.d.ts +6 -29
  85. package/dist/express/index.js +28 -58
  86. package/dist/fastify/index.d.ts +6 -29
  87. package/dist/fastify/index.js +16 -65
  88. package/dist/fields-BMl1RxoX.js +26 -0
  89. package/dist/{files-B_wAGYmt.js → files-DWUN9PzI.js} +5 -1
  90. package/dist/{fixtures-Cvaw0gDG.js → fixtures-ht28Cplr.js} +5 -2
  91. package/dist/{freeze-y1_jQL4v.js → freeze-CrU8nQeX.js} +31 -2
  92. package/dist/{from-snapshot-BMGnhmgv.js → from-snapshot-CTLijvdm.js} +66 -48
  93. package/dist/{grantee-Bv04_Vzf.js → grantee-Cv5Sogfv.js} +88 -7
  94. package/dist/graph-sql-B-dsAT6j.d.ts +29 -0
  95. package/dist/{headers-B5RRv3Xm.js → headers-BZSDieNT.js} +1 -1
  96. package/dist/{headers-C8SHQccD.d.ts → headers-Cf-zWvsO.d.ts} +1 -1
  97. package/dist/helpers-H_KARDVC.js +421 -0
  98. package/dist/hono/index.d.ts +6 -28
  99. package/dist/hono/index.js +11 -43
  100. package/dist/{hosted-BwKQ1BTA.js → hosted-DJQw46hn.js} +6 -5
  101. package/dist/{http-GgVApX1k.js → http-BIhmLfCc.js} +4 -20
  102. package/dist/http-SO7qGttf.js +44 -0
  103. package/dist/ids-DC4V4CFu.js +18 -0
  104. package/dist/index-0nNqHspG.d.ts +6 -0
  105. package/dist/{index-xIxJLwOQ.d.ts → index-BNc7Wer_.d.ts} +75 -7
  106. package/dist/{index-CltcQ4Bf.d.ts → index-C7Tw7MaW.d.ts} +68 -5
  107. package/dist/{index-LF_hS-yn.d.ts → index-C8z4RjQV.d.ts} +1 -1
  108. package/dist/index.d.ts +14 -9
  109. package/dist/index.js +22 -17
  110. package/dist/instance-options-Dhhcnm3y.js +22 -0
  111. package/dist/instance-options-jARdwfPN.d.ts +11 -0
  112. package/dist/{parse-DPfIvFMU.js → json-schema-BsAflUGW.js} +28 -57
  113. package/dist/jwt/index.d.ts +10 -6
  114. package/dist/jwt/index.js +32 -13
  115. package/dist/kernel-_RRHmnMY.js +208 -0
  116. package/dist/kysely/index.d.ts +4 -3
  117. package/dist/kysely/index.js +3 -3
  118. package/dist/live-options-H2eG8dfJ.js +60 -0
  119. package/dist/{load-BZ24CpZP.js → load-DhWEB9P1.js} +16 -10
  120. package/dist/load-DwJUafYN.js +2 -0
  121. package/dist/manifest-iaoBXHKc.js +783 -0
  122. package/dist/manifest-uDS9y5de.d.ts +206 -0
  123. package/dist/{map-DowSO96j.js → map-AcxK9o_D.js} +4 -15
  124. package/dist/{map-claims-B_6I1Rn-.js → map-claims-Z4QZOiFF.js} +13 -4
  125. package/dist/map-error-pgUWNNtG.js +23 -0
  126. package/dist/may-use-DndQ5tQ-.js +77 -0
  127. package/dist/mcp/index.d.ts +54 -22
  128. package/dist/mcp/index.js +218 -178
  129. package/dist/nest/index.d.ts +26 -31
  130. package/dist/nest/index.js +75 -84
  131. package/dist/next/client.d.ts +7 -8
  132. package/dist/next/client.js +11 -9
  133. package/dist/next/index.d.ts +30 -47
  134. package/dist/next/index.js +45 -60
  135. package/dist/next/plugin.d.ts +1 -1
  136. package/dist/next/plugin.js +32 -1
  137. package/dist/node/index.d.ts +9 -28
  138. package/dist/node/index.js +11 -43
  139. package/dist/openai/index.d.ts +6 -15
  140. package/dist/openai/index.js +7 -20
  141. package/dist/openapi/index.d.ts +87 -4
  142. package/dist/openapi/index.js +3 -3
  143. package/dist/{openapi-DcqM8nU7.js → openapi-BqRBvAng.js} +237 -5
  144. package/dist/{openapi-DWD0Uc_4.js → openapi-CqqEbHsL.js} +5 -5
  145. package/dist/{openapi-import-BWRUNNeW.js → openapi-import-cmwetbzw.js} +1 -1
  146. package/dist/{openapi-CwePaF7C.js → openapi-l0xYHkcv.js} +3 -3
  147. package/dist/{openapi-schema-D8j_T9tO.js → openapi-schema--ARjyfQr.js} +2 -2
  148. package/dist/orpc/index.d.ts +15 -28
  149. package/dist/orpc/index.js +74 -117
  150. package/dist/otel/index.d.ts +2 -2
  151. package/dist/parse-BuyjxhZV.js +53 -0
  152. package/dist/parse-local-manifest-BrMozJCo.js +36 -0
  153. package/dist/parse-local-manifest-JLnaBH0S.d.ts +10 -0
  154. package/dist/pdp/index.d.ts +2 -2
  155. package/dist/pdp/index.js +14 -127
  156. package/dist/{permdock-yoZ7EjxX.js → permdock-CbgvLnuo.js} +672 -149
  157. package/dist/{permissions-B8vCg_bI.d.ts → permissions-CDgvKG5L.d.ts} +2 -2
  158. package/dist/{permissions-DC7GROPA.js → permissions-DVoF6dMt.js} +77 -15
  159. package/dist/{permissions-B4apnahQ.d.ts → permissions-DttnqqxC.d.ts} +34 -5
  160. package/dist/{permissions-CofRqesP.js → permissions-RJrovw98.js} +3 -3
  161. package/dist/{pins-CqE1jZuF.js → pins-8ILTftC9.js} +2 -2
  162. package/dist/{policy-Cq2fB8Q5.d.ts → policy-D2W7uv19.d.ts} +2 -2
  163. package/dist/{policy-CInmNGkM.d.ts → policy-IB6yxpC3.d.ts} +351 -42
  164. package/dist/{policy-ANp36PnI.js → policy-xyWg7QdR.js} +173 -22
  165. package/dist/powersync-BylawD_U.js +540 -0
  166. package/dist/powersync-DliZK_-y.js +62 -0
  167. package/dist/powersync-e_AZrKbg.js +2 -0
  168. package/dist/prisma/index.d.ts +3 -2
  169. package/dist/prisma/index.js +45 -20
  170. package/dist/{problem-Cgp9-KZA.js → problem-B43ztKIm.js} +74 -109
  171. package/dist/problem-details-DX075l9V.d.ts +7 -0
  172. package/dist/problem-details-_AMOYz-w.js +144 -0
  173. package/dist/{protected-BuPAycJT.d.ts → protected-BdnIEFkY.d.ts} +5 -4
  174. package/dist/protected-utU-SLuy.js +100 -0
  175. package/dist/protected-xAr24FEC.d.ts +40 -0
  176. package/dist/provider-CSQd7m92.js +52 -0
  177. package/dist/{provider-wTAUda2v.d.ts → provider-DZY281jO.d.ts} +1 -1
  178. package/dist/provider-store-Cfbvo4DE.js +43 -0
  179. package/dist/react/index.d.ts +7 -5
  180. package/dist/react/index.js +5 -4
  181. package/dist/react/provider-client.d.ts +1 -1
  182. package/dist/react/provider-client.js +1 -1
  183. package/dist/react-native/index.d.ts +166 -10
  184. package/dist/react-native/index.js +607 -85
  185. package/dist/{refs-ChLSxbST.js → refs-KYb4ntaz.js} +4 -3
  186. package/dist/{relations-r4soIFZB.js → relations-cjOL01hZ.js} +110 -31
  187. package/dist/replay-BsOyTrdV.js +28 -0
  188. package/dist/replay-CYyiLiwO.d.ts +5 -0
  189. package/dist/resource-ref-CaS9yVPi.js +20 -0
  190. package/dist/revocations-Bhr0aMIC.js +27 -0
  191. package/dist/{rls-BOFU3chG.js → rls-B4ur8nKQ.js} +8 -3
  192. package/dist/rls-DQtdgTHB.js +2521 -0
  193. package/dist/rls-fields-74oZPXWL.js +3582 -0
  194. package/dist/{rls-graph-DxQ39PJj.js → rls-graph-CHwx0V8q.js} +100 -36
  195. package/dist/{rls-import-CXV6LBlS.js → rls-import-BTFVk3jH.js} +7 -6
  196. package/dist/{rls-migrate-DrFPbf8p.js → rls-migrate-CN4TlJTO.js} +6 -5
  197. package/dist/rls-ownership-RuFqaqGz.js +843 -0
  198. package/dist/rls-shared-Cewd_-zI.js +495 -0
  199. package/dist/rls-verify-CVQTHTh5.js +746 -0
  200. package/dist/{row-check-BajTgQZ-.d.ts → row-check-Dt35czLy.d.ts} +12 -15
  201. package/dist/row-conditions-h2HythXQ.js +27 -0
  202. package/dist/rpc-DL9Sqvb1.js +89 -0
  203. package/dist/{run-CJ6UvS3a.js → run-DKDbM4Du.js} +31 -12
  204. package/dist/runtime-CB8gQFvS.js +11 -0
  205. package/dist/{saas-BRrZzJkM.js → saas-DhpJjnBA.js} +17 -7
  206. package/dist/{schema-P8yoma__.js → schema-D3MnDMxa.js} +8 -4
  207. package/dist/scim/index.d.ts +1 -1
  208. package/dist/scim/index.js +1 -1
  209. package/dist/{scim-9NFa0XVZ.js → scim-BFGBBAqR.js} +1 -1
  210. package/dist/{scopes-cKVp_WTw.js → scopes-CVdPrWN-.js} +35 -8
  211. package/dist/server/index.d.ts +22 -11
  212. package/dist/server/index.js +11 -8
  213. package/dist/{credentials-BgRX3WEg.js → server-DlZ28Oz5.js} +1 -1
  214. package/dist/shared-DRu8VFVM.js +123 -0
  215. package/dist/{sink-Cfr9-7YC.d.ts → sink-B1fZzIMf.d.ts} +1 -1
  216. package/dist/skills-Biq5uup3.js +192 -0
  217. package/dist/{skills-C_lpV4Jx.js → skills-Bx-U0irG.js} +10 -4
  218. package/dist/{snapshot-DE8dE_hz.js → snapshot-Enxd0n-s.js} +138 -214
  219. package/dist/snapshot-cache-B-LxUahj.d.ts +45 -0
  220. package/dist/snapshot-cache-D6jLelln.js +44 -0
  221. package/dist/solid/index.d.ts +39 -9
  222. package/dist/solid/index.js +76 -85
  223. package/dist/sources-4p0-4xQm.js +545 -0
  224. package/dist/sources-BdOYLw9j.d.ts +192 -0
  225. package/dist/{sql-Bll1d7y0.js → sql-xdg5f4Fi.js} +6 -1
  226. package/dist/{src-CTNT-PBW.js → src-BDwEZWrZ.js} +149 -11
  227. package/dist/ssf/index.d.ts +3 -2
  228. package/dist/ssf/index.js +3 -29
  229. package/dist/store-DMAWwAJV.js +371 -0
  230. package/dist/{store-Bq90395i.d.ts → store-jOBYpiXC.d.ts} +13 -4
  231. package/dist/store-options-ByhZq1jV.js +716 -0
  232. package/dist/{stores-CkG2HrSg.js → stores-BT2pSCub.js} +10 -63
  233. package/dist/{stores-CvOnu_2T.d.ts → stores-C0IMQrGI.d.ts} +20 -9
  234. package/dist/{stream-BhMfZOwr.d.ts → stream-D1RXubw2.d.ts} +2 -2
  235. package/dist/{stream-Q_xlB6Ko.js → stream-DDpvynSB.js} +16 -2
  236. package/dist/subject-settings-BwBmCdTR.js +128 -0
  237. package/dist/supabase/index.d.ts +133 -6
  238. package/dist/supabase/index.js +4 -3
  239. package/dist/supabase/middleware.d.ts +32 -27
  240. package/dist/supabase/middleware.js +56 -22
  241. package/dist/{supabase-D8UlBA7Z.js → supabase-Boqb9a_Y.js} +3 -3
  242. package/dist/{supabase-DTxGtYdi.js → supabase-C0qESOa-.js} +347 -367
  243. package/dist/supabase-config-BpPXt3x1.js +472 -0
  244. package/dist/supabase-hook-6sYLXg_u.js +2 -0
  245. package/dist/{supabase-hook-D_OqGb_V.js → supabase-hook-CSLQ4zJ3.js} +1037 -705
  246. package/dist/supautils-Cn4R4cJ4.js +91 -0
  247. package/dist/svelte/PermissionBoundary.svelte +37 -0
  248. package/dist/svelte/Protected.svelte +8 -2
  249. package/dist/svelte/index.d.ts +9 -6
  250. package/dist/svelte/index.js +61 -7
  251. package/dist/svelte/runtime.d.ts +4 -3
  252. package/dist/svelte/runtime.js +4 -3
  253. package/dist/svelte/source.d.ts +9 -6
  254. package/dist/svelte/source.js +7 -4
  255. package/dist/terminal/index.d.ts +6 -14
  256. package/dist/terminal/index.js +44 -32
  257. package/dist/testing/index.d.ts +105 -16
  258. package/dist/testing/index.js +504 -40
  259. package/dist/testing/saas/index.d.ts +4 -4
  260. package/dist/testing/saas/index.js +2 -2
  261. package/dist/testing/saas/permissions.d.ts +1 -1
  262. package/dist/testing/saas/permissions.js +1 -1
  263. package/dist/token-CIWxJOCh.js +50 -0
  264. package/dist/trpc/index.d.ts +7 -26
  265. package/dist/trpc/index.js +17 -100
  266. package/dist/types-BnIEz1sU.d.ts +48 -0
  267. package/dist/{types-CxquUByI.d.ts → types-Bvc4oWT6.d.ts} +1 -1
  268. package/dist/{sources-DOpW5Ila.d.ts → types-C97IskBw.d.ts} +86 -127
  269. package/dist/types-CKNSyIf_.d.ts +52 -0
  270. package/dist/types-Cq_H8N_X.d.ts +197 -0
  271. package/dist/{types-D6Z6-rKJ.d.ts → types-DbjRN55U.d.ts} +273 -22
  272. package/dist/{types-BBK-exvJ.d.ts → types-Dnemwd77.d.ts} +7 -1
  273. package/dist/{types-BvBk1wgn.d.ts → types-DxiCGmmd.d.ts} +5 -3
  274. package/dist/{types-B9dmiiab.d.ts → types-QCuYJh4q.d.ts} +1 -1
  275. package/dist/{types-B8w5PFtS.d.ts → types-aqOHTHcp.d.ts} +17 -1
  276. package/dist/unplugin/index.d.ts +1 -1
  277. package/dist/unplugin/index.js +10 -9
  278. package/dist/usage-DorAJiU_.js +2 -0
  279. package/dist/{usage-1ozMubLY.js → usage-GTixvDDU.js} +2 -2
  280. package/dist/{usage-CUnK6Ou9.js → usage-ItS7nLcl.js} +225 -62
  281. package/dist/validation-error-Ba264OaJ.d.ts +26 -0
  282. package/dist/validation-error-CnjZ4t92.js +33 -0
  283. package/dist/{validity-D0uRmJKJ.js → validity-uOp8UpYn.js} +57 -36
  284. package/dist/{verifier-B90agnhl.js → verifier-BxBo6I44.js} +10 -5
  285. package/dist/version-BvacVTZR.js +17 -0
  286. package/dist/views-Soe7bGSC.js +95 -0
  287. package/dist/{vocabulary-Dk0fs-Jk.d.ts → vocabulary-DA8a8zif.d.ts} +1 -1
  288. package/dist/vue/index.d.ts +35 -13
  289. package/dist/vue/index.js +86 -93
  290. package/dist/watch-BwxLTYMZ.js +2 -0
  291. package/dist/watch-DVBJ9cBq.js +128 -0
  292. package/dist/webmcp/index.d.ts +2 -2
  293. package/dist/webmcp/index.js +7 -13
  294. package/package.json +62 -36
  295. package/schemas/approval-request-v1.json +175 -0
  296. package/schemas/catalog-v1.json +29 -1
  297. package/schemas/supabase-claims-v1.json +6 -1
  298. package/schemas/supabase-manifest-v1.json +150 -6
  299. package/skills/permdock/SKILL.md +7 -7
  300. package/skills/permdock-agents/SKILL.md +5 -5
  301. package/skills/permdock-agents/references/runtimes.md +12 -10
  302. package/skills/permdock-approvals/SKILL.md +4 -4
  303. package/skills/permdock-approvals/references/stores-and-resume.md +15 -4
  304. package/skills/permdock-audit/SKILL.md +3 -3
  305. package/skills/permdock-credentials/SKILL.md +4 -4
  306. package/skills/permdock-credentials/references/tokens-keys-links.md +7 -2
  307. package/skills/permdock-data/SKILL.md +4 -4
  308. package/skills/permdock-data/references/queries-and-rls.md +14 -6
  309. package/skills/permdock-data/references/relationships.md +5 -3
  310. package/skills/permdock-tenancy/SKILL.md +9 -6
  311. package/skills/permdock-tenancy/references/ownership-and-custom-roles.md +14 -8
  312. package/skills/permdock-wire/SKILL.md +4 -4
  313. package/skills/permdock-wire/references/adapters.md +42 -30
  314. package/skills/permdock-wire/references/policy-options.md +5 -3
  315. package/dist/approvers-aH0PJkmf.js +0 -20
  316. package/dist/catalog-idsHc0vo.js +0 -2
  317. package/dist/collect-B7_TIfmg.js +0 -49
  318. package/dist/collect-fRPAQIWb.js +0 -2
  319. package/dist/compile-CQbvyIBr.d.ts +0 -30
  320. package/dist/config-BPYmjTOp.js +0 -26
  321. package/dist/context-gtAwAILx.js +0 -6
  322. package/dist/create-BKF3dgFk.d.ts +0 -162
  323. package/dist/create-CSkhDU9T.js +0 -222
  324. package/dist/doctor-BGle8Gqi.js +0 -1314
  325. package/dist/helpers-DnSOrhB9.js +0 -682
  326. package/dist/index-fG6NSXlc.d.ts +0 -9
  327. package/dist/kernel-YOGCWNLf.js +0 -211
  328. package/dist/load-QOOm1z70.js +0 -2
  329. package/dist/manifest-DDQbC6K0.d.ts +0 -118
  330. package/dist/map-error-RJ3ZsUyA.js +0 -16
  331. package/dist/may-use-CnFEjVEp.js +0 -37
  332. package/dist/pg-4GJWDUxG.js +0 -953
  333. package/dist/plugin-4gr7IxFJ.js +0 -65
  334. package/dist/protected-B4K3BKoX.js +0 -138
  335. package/dist/protected-wY7nXhY9.d.ts +0 -23
  336. package/dist/provider-_wx46HpB.js +0 -48
  337. package/dist/rls-CJVja9Ww.js +0 -2119
  338. package/dist/rls-helpers-BxRuif0l.js +0 -1346
  339. package/dist/runtime-DP9ttFh1.js +0 -27
  340. package/dist/skills-Dx3QLnMY.js +0 -110
  341. package/dist/source-DoBBYJi2.js +0 -6
  342. package/dist/sources-DVHM3Mwq.js +0 -284
  343. package/dist/store-C6hFW6ta.js +0 -508
  344. package/dist/subject-settings-xt7V845g.js +0 -82
  345. package/dist/supabase-hook-DW-xP4hU.js +0 -2
  346. package/dist/types-DbWdEfcm.d.ts +0 -87
  347. package/dist/types-bva3i4Gf.d.ts +0 -98
  348. package/dist/types-i4BAOvdb.d.ts +0 -97
  349. package/dist/usage-PyEor6GA.js +0 -2
  350. package/dist/version-CnSh33Fj.js +0 -16
@@ -0,0 +1,648 @@
1
+ import { n as freezeDeep } from "../freeze-CrU8nQeX.js";
2
+ import { _ as listPermissions, p as isPermission } from "../permissions-DVoF6dMt.js";
3
+ import { d as scopeList } from "../scopes-CVdPrWN-.js";
4
+ import { t as anonymousSubject } from "../subject-C6dLxqHU.js";
5
+ import { t as mayUse } from "../may-use-DndQ5tQ-.js";
6
+ import { o as parseCredential, r as credentialSubject } from "../credential-8P81ff4u.js";
7
+ import { t as policyRowConditionKeys } from "../row-conditions-h2HythXQ.js";
8
+ import { i as quoteSqlLiteral, o as sqlIdent } from "../sql-xdg5f4Fi.js";
9
+ import "../sources-4p0-4xQm.js";
10
+ import { o as subjectFromSupabaseSession, t as parseSupabaseManifest } from "../manifest-iaoBXHKc.js";
11
+ import { t as parseCatalog } from "../parse-BuyjxhZV.js";
12
+ import { AsyncResult, dbError } from "better-supabase";
13
+ //#region src/better-supabase/provider.ts
14
+ /**
15
+ * The helper each template calls (with `{scope}` unfilled), its default
16
+ * argument types and the role that calls it: `postgres` for the templates
17
+ * better-supabase runs inside its own `security definer` functions.
18
+ */
19
+ const TEMPLATES = {
20
+ idsWith: {
21
+ helper: "permitted_{scope}_ids_by_permission",
22
+ listedAs: "permitted_{scope}_ids",
23
+ args: "text",
24
+ role: "authenticated",
25
+ sql: "permitted_{scope}_ids_by_permission({permission})"
26
+ },
27
+ isPlatform: {
28
+ helper: "permdock_has_permission",
29
+ listedAs: "permdock_has",
30
+ args: "text",
31
+ role: "authenticated",
32
+ sql: "permdock_has_permission({permission})"
33
+ },
34
+ idsWithFor: {
35
+ helper: "permitted_{scope}_ids_by_permission_for",
36
+ listedAs: "permitted_{scope}_ids_for",
37
+ args: "uuid, text",
38
+ role: "postgres",
39
+ sql: "permitted_{scope}_ids_by_permission_for({user}, {permission})"
40
+ },
41
+ isPlatformFor: {
42
+ helper: "permdock_has_permission_for",
43
+ listedAs: "permdock_has_for",
44
+ args: "uuid, text",
45
+ role: "postgres",
46
+ sql: "permdock_has_permission_for({user}, {permission})"
47
+ },
48
+ memberIds: {
49
+ helper: "member_{scope}_ids",
50
+ args: "",
51
+ role: "authenticated",
52
+ sql: "member_{scope}_ids()"
53
+ },
54
+ memberIdsFor: {
55
+ helper: "member_{scope}_ids_for",
56
+ args: "uuid",
57
+ role: "supabase_auth_admin",
58
+ sql: "member_{scope}_ids_for({user})"
59
+ },
60
+ canAssign: {
61
+ helper: "permdock_can_assign",
62
+ args: "text, text",
63
+ role: "authenticated",
64
+ sql: "permdock_can_assign({role}, {tenant}::text)"
65
+ },
66
+ canAssignFor: {
67
+ helper: "permdock_can_assign_for",
68
+ args: "uuid, text, text",
69
+ role: "postgres",
70
+ sql: "permdock_can_assign_for({user}, {role}, {tenant}::text)"
71
+ },
72
+ permissionsFor: {
73
+ helper: "permitted_{scope}_permission_keys_for",
74
+ args: "uuid, uuid",
75
+ role: "postgres",
76
+ sql: "array(select {schema}.permitted_{scope}_permission_keys_for({user}, {tenant}))"
77
+ }
78
+ };
79
+ const ASSIGN_ANY = {
80
+ canAssign: {
81
+ helper: "permdock_can_assign_any",
82
+ args: "text, uuid, text, text",
83
+ role: "authenticated",
84
+ sql: "permdock_can_assign_any({role}, {tenant}, '{scope}', {tenant}::text)"
85
+ },
86
+ canAssignFor: {
87
+ helper: "permdock_can_assign_any_for",
88
+ args: "uuid, text, uuid, text, text",
89
+ role: "postgres",
90
+ sql: "permdock_can_assign_any_for({user}, {role}, {tenant}, '{scope}', {tenant}::text)"
91
+ }
92
+ };
93
+ const listedName = (entry) => entry.listedAs ?? entry.helper;
94
+ const OPTIONAL = [
95
+ "idsWithFor",
96
+ "isPlatformFor",
97
+ "memberIds",
98
+ "memberIdsFor",
99
+ "canAssign",
100
+ "canAssignFor",
101
+ "permissionsFor"
102
+ ];
103
+ /** Postgres aliases of the id types better-supabase reads (`uuid`, `text`, `bigint`, `integer`). */
104
+ const ID_TYPES = {
105
+ uuid: "uuid",
106
+ text: "text",
107
+ bigint: "bigint",
108
+ int8: "bigint",
109
+ integer: "integer",
110
+ int: "integer",
111
+ int4: "integer"
112
+ };
113
+ const withSchema = (schema, sql) => sql.includes("{schema}") ? sql.replaceAll("{schema}", schema) : `${schema}.${sql}`;
114
+ /** `p_user uuid, p_grant text` as `uuid, text`. */
115
+ const argTypes = (args) => args.split(",").map((arg) => arg.trim().split(/\s+/u).slice(1).join(" ")).filter((type) => type !== "").join(", ");
116
+ function tenantScopeOf(manifest, explicit) {
117
+ const names = manifest.rls.scopes.map((scope) => scope.name);
118
+ if (explicit !== void 0) {
119
+ if (!names.includes(explicit)) throw new TypeError(`PermDock: scope "${explicit}" is not in the manifest's rls.scopes (${names.join(", ")}).`);
120
+ return explicit;
121
+ }
122
+ const roots = manifest.rls.scopes.filter((scope) => scope.within === void 0);
123
+ const [root] = roots;
124
+ if (root === void 0 || roots.length > 1) throw new TypeError(`PermDock: the manifest has ${roots.length} root scopes (${roots.map((scope) => scope.name).join(", ") || "none"}), so it can't tell which scope tenants are. Pass { scope } with one of ${names.join(", ")}.`);
125
+ return root.name;
126
+ }
127
+ function covers(membership, scope) {
128
+ return !("value" in membership.scope) || membership.scope.value === scope;
129
+ }
130
+ /** `source` as better-supabase reads it, for a source that covers `scope`. */
131
+ function membershipOf(source, scope, problems) {
132
+ if ("through" in source.user) {
133
+ problems.push(`${source.table} reads its user id through ${source.user.through.table}, which better-supabase's membership reads don't follow.`);
134
+ return;
135
+ }
136
+ return {
137
+ table: source.table,
138
+ userColumn: source.user.column,
139
+ scope: "column" in source.scope ? { column: source.scope.column } : { value: scope },
140
+ idColumn: source.id.column
141
+ };
142
+ }
143
+ function roleSourceOf(source) {
144
+ const role = source.role;
145
+ if (Array.isArray(role) || !("column" in role) || !("through" in role)) return;
146
+ return {
147
+ table: source.table,
148
+ role: {
149
+ column: role.column,
150
+ through: {
151
+ table: role.through.table,
152
+ id: role.through.id,
153
+ column: role.through.column
154
+ }
155
+ }
156
+ };
157
+ }
158
+ function disabledRow(row) {
159
+ return {
160
+ table: row.table,
161
+ id: row.id,
162
+ ...row.disabledAt === void 0 ? {} : { disabledAt: row.disabledAt },
163
+ ...row.status === void 0 || row.active === void 0 ? {} : {
164
+ status: row.status,
165
+ active: row.active
166
+ }
167
+ };
168
+ }
169
+ function permissionsOf(catalog, scopes) {
170
+ return catalog.permissions.map((permission) => {
171
+ const granted = /* @__PURE__ */ new Set();
172
+ for (const grant of catalog.grants ?? []) if (grant.permission === permission.key && typeof grant.scope === "string" && scopes.has(grant.scope)) granted.add(grant.scope);
173
+ return {
174
+ key: permission.key,
175
+ sqlComplete: !permission.rowConditions,
176
+ ...granted.size > 0 ? { scopes: [...granted].toSorted() } : {}
177
+ };
178
+ });
179
+ }
180
+ function tokenHookOf(manifest) {
181
+ const owned = manifest.claims.filter((claim) => claim.source === "permdock");
182
+ const registered = manifest.claims.filter((claim) => claim.source !== "permdock");
183
+ const budgeted = manifest.claims.filter((claim) => claim.budget);
184
+ return {
185
+ function: `${manifest.hook.schema}.${manifest.hook.function}`,
186
+ tenantClaim: manifest.tenantClaim,
187
+ ownedClaims: owned.map((claim) => claim.name),
188
+ ...registered.length > 0 ? { registeredClaims: registered.map((claim) => ({
189
+ name: claim.name,
190
+ function: claim.source
191
+ })) } : {},
192
+ budget: {
193
+ claims: budgeted.map((claim) => claim.name),
194
+ bytes: manifest.budget.bytes,
195
+ ...owned.some((claim) => claim.name === "memberships_truncated") ? { truncatedClaim: "memberships_truncated" } : {}
196
+ },
197
+ markers: {
198
+ hook: `-- permdock:hook ${manifest.markers.hook}`,
199
+ grants: `-- permdock:grants ${manifest.markers.grants}`
200
+ },
201
+ grantsCommand: `permdock supabase hook generate --grants-out supabase/migrations/<timestamp>_permdock_hook_grants.sql`
202
+ };
203
+ }
204
+ /**
205
+ * better-supabase's `authorization` config value, built from PermDock's
206
+ * manifest and catalog: the scopes, the `rls generate` helpers as SQL
207
+ * templates, the membership tables, suspension rows, the token hook and
208
+ * every catalog key with `sqlComplete` set from its `rowConditions`. A
209
+ * `_for` template and `permissionsFor` are set only when the manifest lists
210
+ * their helper, which `rls.mode: 'database'` writes; `canApprove` only with
211
+ * `approver`. Throws when the manifest or catalog is invalid, or when the
212
+ * tenant scope is ambiguous.
213
+ */
214
+ function authorizationProvider(options) {
215
+ const manifest = parseSupabaseManifest(options.manifest);
216
+ const catalog = options.catalog === void 0 ? void 0 : parseCatalog(options.catalog);
217
+ const rls = manifest.rls;
218
+ const problems = [];
219
+ if (catalog === void 0) problems.push("No catalog: better-supabase cannot check that the permission keys its SQL modules use (ai_chat, workflow, inbox and the rest) exist. Pass `catalog`.");
220
+ const tenantScope = tenantScopeOf(manifest, options.scope);
221
+ const scopeNames = rls.scopes.map((scope) => scope.name);
222
+ const helpers = new Map(rls.helpers.map((helper) => [helper.name, helper]));
223
+ const schema = sqlIdent(rls.schema);
224
+ const rootTenant = rls.scopes.find((scope) => scope.name === tenantScope)?.within === void 0;
225
+ const assignAny = rls.customRoles === true && rootTenant;
226
+ const entryOf = (template) => assignAny && (template === "canAssign" || template === "canAssignFor") ? ASSIGN_ANY[template] : TEMPLATES[template];
227
+ const listed = (template, scope) => helpers.has(listedName(entryOf(template)).replaceAll("{scope}", scope));
228
+ const templates = [
229
+ "idsWith",
230
+ "isPlatform",
231
+ ...OPTIONAL.filter((template) => listed(template, tenantScope))
232
+ ];
233
+ for (const template of ["idsWith", "isPlatform"]) if (!listed(template, tenantScope)) problems.push(`The manifest's rls.helpers has no ${rls.schema}.${listedName(TEMPLATES[template]).replaceAll("{scope}", tenantScope)}. Run \`permdock rls generate\`, then \`permdock supabase inspect --out\`.`);
234
+ if (rls.customRoles === true && !rootTenant && templates.includes("canAssign")) problems.push(`The tenant scope "${tenantScope}" is not a root scope, so canAssign checks declared roles only: ${rls.schema}.${ASSIGN_ANY.canAssign.helper}, which also answers for custom roles, takes the root tenant id.`);
235
+ const optional = {};
236
+ const requires = [];
237
+ const required = /* @__PURE__ */ new Set();
238
+ for (const template of templates) {
239
+ const entry = entryOf(template);
240
+ optional[template] = withSchema(schema, entry.sql);
241
+ for (const scope of entry.helper.includes("{scope}") ? scopeNames : [tenantScope]) {
242
+ const name = entry.helper.replaceAll("{scope}", scope);
243
+ const fn = `${schema}.${sqlIdent(name)}`;
244
+ if (required.has(fn)) continue;
245
+ required.add(fn);
246
+ const helper = helpers.get(name);
247
+ const args = helper === void 0 ? entry.args : argTypes(helper.args);
248
+ requires.push({
249
+ function: fn,
250
+ ...args === "" ? {} : { args },
251
+ role: entry.role
252
+ });
253
+ }
254
+ }
255
+ const memberships = [];
256
+ const roleSources = [];
257
+ for (const source of rls.memberships) {
258
+ if (!covers(source, tenantScope)) continue;
259
+ const membership = membershipOf(source, tenantScope, problems);
260
+ if (membership) memberships.push(membership);
261
+ const roleSource = roleSourceOf(source);
262
+ if (roleSource) roleSources.push(roleSource);
263
+ }
264
+ const users = rls.suspension?.users;
265
+ const tenants = rls.suspension?.scopes?.[tenantScope];
266
+ const approver = options.approver;
267
+ let canApprove;
268
+ if (approver !== void 0) {
269
+ if (catalog !== void 0 && !catalog.permissions.some((permission) => permission.key === approver.key)) problems.push(`The approver permission ${approver.key} is not in the catalog. Run \`permdock catalog\` after adding it to the policy.`);
270
+ const name = `permitted_${tenantScope}_ids_by_permission`;
271
+ canApprove = `{tenant} in (select ${schema}.${sqlIdent(name)}(${quoteSqlLiteral(approver.key)}))`;
272
+ requires.push({
273
+ function: `${schema}.${sqlIdent(name)}`,
274
+ args: "text",
275
+ role: "postgres"
276
+ });
277
+ }
278
+ const functions = {
279
+ ...optional,
280
+ idsWith: `${schema}.${TEMPLATES.idsWith.sql}`,
281
+ isPlatform: `${schema}.${TEMPLATES.isPlatform.sql}`,
282
+ ...canApprove === void 0 ? {} : { canApprove }
283
+ };
284
+ const scopes = rls.scopes.map((scope) => {
285
+ const idType = ID_TYPES[scope.type.trim().toLowerCase()];
286
+ if (idType === void 0) problems.push(`Scope "${scope.name}" has ids of type ${scope.type}; better-supabase reads uuid, text, bigint and integer ids.`);
287
+ return scope.within === void 0 ? {
288
+ name: scope.name,
289
+ idType: idType ?? scope.type
290
+ } : {
291
+ name: scope.name,
292
+ idType: idType ?? scope.type,
293
+ parent: scope.within
294
+ };
295
+ });
296
+ return freezeDeep({
297
+ apiVersion: 1,
298
+ name: "PermDock",
299
+ scopes,
300
+ tenantScope,
301
+ functions,
302
+ requires,
303
+ ...catalog ? { permissions: permissionsOf(catalog, new Set(scopeNames)) } : {},
304
+ ...memberships.length > 0 ? { memberships } : {},
305
+ ...users || tenants ? { suspension: {
306
+ ...users ? { user: disabledRow(users) } : {},
307
+ ...tenants ? { tenant: disabledRow(tenants) } : {}
308
+ } } : {},
309
+ ...roleSources.length > 0 ? { roleSources } : {},
310
+ ...canApprove === void 0 ? {} : { approvals: { distinctApprover: true } },
311
+ decidingColumns: manifest.decidingColumns,
312
+ tokenHook: tokenHookOf(manifest),
313
+ ...problems.length > 0 ? { problems } : {}
314
+ });
315
+ }
316
+ //#endregion
317
+ //#region src/better-supabase/policies.ts
318
+ /** PermDock splits a key with row conditions into `key#1`, `key#2`, ... in the policies it generates. */
319
+ const SPLIT_KEY = /#\d+$/u;
320
+ function checkedKey(where, permission, facts, scope) {
321
+ const key = permission.key;
322
+ if (SPLIT_KEY.test(key)) throw new TypeError(`PermDock: ${where} "${key}" is one part of a permission split by row condition. Use the policies \`permdock rls generate\` writes for it.`);
323
+ const entry = facts(key);
324
+ if (!entry.known) throw new TypeError(`PermDock: ${where} "${key}" is not in permissions.catalog.json. Run \`permdock catalog\`.`);
325
+ if (entry.rowConditions) throw new TypeError(`PermDock: ${where} "${key}" has row conditions (rowConditions: true), which the SQL helpers don't check, so the policy would grant every object in the scope. Use the policies \`permdock rls generate\` writes for it.`);
326
+ const grantScope = scope === "platform" ? "global" : scope;
327
+ const scopes = entry.grantScopes;
328
+ if (scopes.length > 0 && !scopes.includes(grantScope)) throw new TypeError(`PermDock: ${where} "${key}" is granted at ${[...new Set(scopes)].join(", ")}, not at ${grantScope}. Check it at one of those scopes.`);
329
+ return key;
330
+ }
331
+ function target(options) {
332
+ const policy = options.policy;
333
+ let names;
334
+ let schemaName;
335
+ let facts;
336
+ if (policy === void 0) {
337
+ const manifest = parseSupabaseManifest(options.manifest);
338
+ const catalog = parseCatalog(options.catalog);
339
+ names = manifest.rls.scopes.map((scope) => scope.name);
340
+ schemaName = manifest.rls.schema;
341
+ facts = (key) => {
342
+ const entry = catalog.permissions.find((candidate) => candidate.key === key);
343
+ return {
344
+ known: entry !== void 0,
345
+ rowConditions: entry?.rowConditions === true,
346
+ grantScopes: (catalog.grants ?? []).flatMap((grant) => grant.permission === key && typeof grant.scope === "string" ? [grant.scope] : [])
347
+ };
348
+ };
349
+ } else {
350
+ names = scopeList(policy.scopes).map((scope) => scope.name);
351
+ schemaName = options.schema ?? "permdock";
352
+ const conditioned = policyRowConditionKeys(policy);
353
+ facts = (key) => ({
354
+ known: true,
355
+ rowConditions: conditioned.has(key),
356
+ grantScopes: policy.grants.flatMap((grant) => grant.hosted === void 0 && grant.permission.key === key && typeof grant.scope === "string" ? [grant.scope] : [])
357
+ });
358
+ }
359
+ if (options.scope !== "platform" && !names.includes(options.scope)) throw new TypeError(`PermDock: scope "${options.scope}" is not in the ${policy === void 0 ? "manifest's rls.scopes" : "policy's scopes"} (${names.join(", ")}) and is not "platform".`);
360
+ const schema = sqlIdent(schemaName);
361
+ return {
362
+ facts,
363
+ sql: {
364
+ idsWith: `${schema}.permitted_{scope}_ids_by_permission({permission})`,
365
+ isPlatform: `${schema}.permdock_has_permission({permission})`
366
+ }
367
+ };
368
+ }
369
+ /**
370
+ * A better-supabase bucket `policy` that checks PermDock permissions with
371
+ * the `rls generate` helpers at `scope`. The helpers check role and scope
372
+ * only, so a permission with row conditions (`rowConditions: true` in the
373
+ * catalog, or a conditioned grant in `policy`), or one not granted at
374
+ * `scope`, throws.
375
+ */
376
+ function bucketPolicy(access, options) {
377
+ const { facts, sql } = target(options);
378
+ const key = (name, permission) => checkedKey(`bucket access.${name}`, permission, facts, options.scope);
379
+ return freezeDeep({
380
+ access: {
381
+ read: key("read", access.read),
382
+ ...access.list ? { list: key("list", access.list) } : {},
383
+ write: key("write", access.write),
384
+ ...access.delete ? { delete: key("delete", access.delete) } : {}
385
+ },
386
+ scope: options.scope,
387
+ ...options.segment === void 0 ? {} : { segment: options.segment },
388
+ sql
389
+ });
390
+ }
391
+ /** As {@link bucketPolicy}, for a better-supabase Realtime topic. */
392
+ function topicPolicy(access, options) {
393
+ const { facts, sql } = target(options);
394
+ const key = (name, permission) => checkedKey(`topic ${name}`, permission, facts, options.scope);
395
+ return freezeDeep({
396
+ receive: key("receive", access.receive),
397
+ ...access.send ? { send: key("send", access.send) } : {},
398
+ scope: options.scope,
399
+ ...options.segment === void 0 ? {} : { segment: options.segment },
400
+ sql
401
+ });
402
+ }
403
+ //#endregion
404
+ //#region src/better-supabase/api-keys.ts
405
+ const seconds = (instant) => Math.floor(instant.epochMilliseconds / 1e3);
406
+ /** When a key stops verifying: its expiry, or the end of a rotated key's grace period. */
407
+ function endOf(key) {
408
+ const { expiresAt, revokedAt } = key;
409
+ if (revokedAt === void 0) return expiresAt;
410
+ if (expiresAt === void 0) return revokedAt;
411
+ return revokedAt.epochMilliseconds < expiresAt.epochMilliseconds ? revokedAt : expiresAt;
412
+ }
413
+ /** `rls.apiKeys.serviceRoles` from the manifest, when it has `rls.apiKeys`. */
414
+ function manifestServiceRoles(manifest) {
415
+ return manifest === void 0 ? void 0 : parseSupabaseManifest(manifest).rls.apiKeys?.serviceRoles;
416
+ }
417
+ /**
418
+ * A personal key as a `user` credential acting as its user, a tenant key as
419
+ * a `service` credential holding `roles` in its tenant; `null` when `*`
420
+ * has no expansion, a tenant key has no roles, or the record is invalid.
421
+ */
422
+ function keyCredential(key, roles, allPermissions) {
423
+ const scopes = key.scopes.includes("*") ? allPermissions?.map((permission) => permission.key) : key.scopes;
424
+ if (scopes === void 0) return null;
425
+ const owner = key.userId;
426
+ const base = {
427
+ v: 1,
428
+ id: key.id,
429
+ permissions: scopes.map((permission) => ({ permission })),
430
+ createdBy: key.createdBy ?? owner ?? key.id,
431
+ createdAt: key.createdAt ?? 0,
432
+ ...key.expiresAt === void 0 ? {} : { expiresAt: key.expiresAt },
433
+ name: key.name
434
+ };
435
+ if (owner !== void 0) return parseCredential({
436
+ ...base,
437
+ kind: "user",
438
+ principal: owner,
439
+ ...key.organizationId === void 0 ? {} : { tenant: key.organizationId }
440
+ }) ?? null;
441
+ if (roles === void 0 || key.organizationId === void 0) return null;
442
+ return parseCredential({
443
+ ...base,
444
+ kind: "service",
445
+ principal: key.id,
446
+ tenant: key.organizationId,
447
+ roles
448
+ }) ?? null;
449
+ }
450
+ /**
451
+ * better-supabase's API keys as a `CredentialVerifier`, for
452
+ * `subjectFromApiKey` from `permdock/server`, which reads PermDock's
453
+ * `pdk_<id>_<secret>` format: create the keys with `prefix: "pdk"`. The
454
+ * credential id is the key's `publicId`, the id in the token. A personal key
455
+ * is a `user` credential acting as its user (inside its tenant when the key
456
+ * is limited to one), a tenant key a `service` credential holding
457
+ * `serviceRoles` in its tenant, and the key's scopes are the credential's
458
+ * permissions. better-supabase records the use when it verifies, so there is
459
+ * no `touch`. A rotated key in its grace period verifies, and its credential
460
+ * expires when the grace period ends. An invalid, revoked, expired or
461
+ * rate-limited key, and a failed lookup, are `null`. `permdock/server` exports a different
462
+ * `apiKeyVerifier`, over the application's own key records.
463
+ */
464
+ function apiKeyVerifier(options) {
465
+ const fallback = manifestServiceRoles(options.manifest);
466
+ return freezeDeep({ async verify(secret) {
467
+ try {
468
+ const checked = await options.keys.verify(secret);
469
+ if (!checked.ok || checked.data.status !== "ok") return null;
470
+ const { key } = checked.data;
471
+ if (key.state !== "active" && key.state !== "grace") return null;
472
+ const end = endOf(key);
473
+ const roles = typeof options.serviceRoles === "function" ? options.serviceRoles(key) : options.serviceRoles ?? fallback;
474
+ return keyCredential({
475
+ id: key.publicId,
476
+ name: key.name,
477
+ scopes: key.scopes,
478
+ createdAt: seconds(key.createdAt),
479
+ ...key.organizationId === void 0 ? {} : { organizationId: key.organizationId },
480
+ ...key.userId === void 0 ? {} : { userId: key.userId },
481
+ ...key.createdBy === void 0 ? {} : { createdBy: key.createdBy },
482
+ ...end === void 0 ? {} : { expiresAt: seconds(end) }
483
+ }, roles, options.allPermissions);
484
+ } catch {
485
+ return null;
486
+ }
487
+ } });
488
+ }
489
+ /**
490
+ * The `claim` and `tenantClaim` options of better-supabase's
491
+ * `apiKeyClaims()`, from the manifest's `rls.apiKeys`, so a key's token
492
+ * carries the scopes ceiling, tenant and roles the `rls generate` helpers
493
+ * read. Throws when the manifest has no `rls.apiKeys`.
494
+ */
495
+ function apiKeyClaimOptions(manifest) {
496
+ const rls = parseSupabaseManifest(manifest).rls;
497
+ const apiKeys = rls.apiKeys;
498
+ if (!apiKeys) throw new TypeError("PermDock: the manifest has no rls.apiKeys. Set rls.apiKeys in permdock.config.ts, then run `permdock rls generate` and `permdock supabase inspect --out`.");
499
+ return freezeDeep({
500
+ claim: {
501
+ name: apiKeys.claim,
502
+ scopes: apiKeys.scopes,
503
+ tenant: apiKeys.tenant,
504
+ roles: apiKeys.roles,
505
+ serviceRoles: apiKeys.serviceRoles
506
+ },
507
+ tenantClaim: rls.tenantClaim
508
+ });
509
+ }
510
+ //#endregion
511
+ //#region src/better-supabase/credentials.ts
512
+ /**
513
+ * `provider` with every `getToken`, `startAuthorization`,
514
+ * `completeAuthorization` and `revoke` decided by PermDock first, on the
515
+ * `CredentialRef` as the row. Anything but `granted` is a `forbidden`
516
+ * error with hint `PERMDOCK_DENIED`, and a failed check is one too.
517
+ * `capabilities` and `verifyInbound` (a third party's request, with no
518
+ * user) pass through. Build it per request, with that request's PermDock.
519
+ */
520
+ function credentialGuard(provider, options) {
521
+ const allowed = async (permission, ref) => {
522
+ try {
523
+ return (await options.permdock()).can(permission, ref);
524
+ } catch {
525
+ return false;
526
+ }
527
+ };
528
+ const guarded = (permission, ref, run) => AsyncResult.from(async () => await allowed(permission, ref) ? run() : AsyncResult.err(dbError("forbidden", `PermDock denied ${permission.key}`, { hint: "PERMDOCK_DENIED" })));
529
+ const revoke = options.revoke ?? options.use;
530
+ const start = provider.startAuthorization?.bind(provider);
531
+ const complete = provider.completeAuthorization?.bind(provider);
532
+ const inbound = provider.verifyInbound?.bind(provider);
533
+ return Object.freeze({
534
+ apiVersion: 1,
535
+ name: provider.name,
536
+ getToken: (ref, getOptions) => guarded(options.use, ref, () => provider.getToken(ref, getOptions)),
537
+ capabilities: (ref) => provider.capabilities(ref),
538
+ ...start === void 0 ? {} : { startAuthorization: (ref, startOptions) => guarded(options.use, ref, () => start(ref, startOptions)) },
539
+ ...complete === void 0 ? {} : { completeAuthorization: (ref, completeOptions) => guarded(options.use, ref, () => complete(ref, completeOptions)) },
540
+ revoke: (ref, revokeOptions) => guarded(revoke, ref, () => provider.revoke(ref, revokeOptions)),
541
+ ...inbound === void 0 ? {} : { verifyInbound: inbound }
542
+ });
543
+ }
544
+ //#endregion
545
+ //#region src/better-supabase/mcp.ts
546
+ const refused = (reason) => ({
547
+ allowed: false,
548
+ reason
549
+ });
550
+ /**
551
+ * The `authorize` and `visible` hooks of better-supabase's `createMcp`, for
552
+ * tools whose `meta` is a PermDock permission. A tool without a permission
553
+ * is hidden and refused. `authorize` grants only a `granted` decision: an
554
+ * approval-required call is refused, because `createMcp`
555
+ * has no approval flow. A throw anywhere refuses.
556
+ */
557
+ function toolPolicy(options) {
558
+ return Object.freeze({
559
+ async authorize(ctx, tool, args) {
560
+ const permission = tool.meta;
561
+ if (!isPermission(permission)) return refused("This tool has no PermDock permission.");
562
+ try {
563
+ const permdock = await options.permdock(ctx);
564
+ const data = await options.data?.(ctx, tool, args);
565
+ const decision = permdock.decide(permission, data);
566
+ switch (decision.outcome) {
567
+ case "granted": return { allowed: true };
568
+ case "approval-required": return refused(`${permission.key} needs approval, which this server does not collect.`);
569
+ case "denied": return refused(`PermDock denied ${permission.key}.`);
570
+ default: return decision;
571
+ }
572
+ } catch {
573
+ return refused("The permission check failed.");
574
+ }
575
+ },
576
+ async visible(ctx, tool) {
577
+ const permission = tool.meta;
578
+ if (!isPermission(permission)) return false;
579
+ try {
580
+ return mayUse(await options.permdock(ctx), permission);
581
+ } catch {
582
+ return false;
583
+ }
584
+ }
585
+ });
586
+ }
587
+ //#endregion
588
+ //#region src/better-supabase/subject.ts
589
+ const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
590
+ /** `session` with the short codes in `claim` turned back into feature keys. */
591
+ function decodedFeatures(session, claim, keys) {
592
+ const claims = session?.claims;
593
+ if (session === null || session === void 0 || !isRecord(claims)) return session;
594
+ const coded = claims[claim];
595
+ if (!isRecord(coded)) return session;
596
+ const byCode = new Map(Object.entries(keys).map(([key, code]) => [code, key]));
597
+ const decoded = Object.fromEntries(Object.entries(coded).map(([tenant, codes]) => [tenant, Array.isArray(codes) ? codes.flatMap((code) => {
598
+ const key = typeof code === "string" ? byCode.get(code) : void 0;
599
+ return key === void 0 ? [] : [key];
600
+ }) : codes]));
601
+ return {
602
+ ...session,
603
+ claims: {
604
+ ...claims,
605
+ [claim]: decoded
606
+ }
607
+ };
608
+ }
609
+ function isApiKeySession(session) {
610
+ if (typeof session !== "object" || session === null) return false;
611
+ const record = Object.fromEntries(Object.entries(session));
612
+ return record["kind"] === "apiKey" && typeof record["keyId"] === "string" && typeof record["name"] === "string" && Array.isArray(record["scopes"]) && record["scopes"].every((scope) => typeof scope === "string");
613
+ }
614
+ function apiKeySubject(session, options) {
615
+ const roles = typeof options.serviceRoles === "function" ? options.serviceRoles(session) : options.serviceRoles ?? manifestServiceRoles(options.manifest);
616
+ const credential = keyCredential({
617
+ id: session.keyId,
618
+ name: session.name,
619
+ scopes: session.scopes,
620
+ ...session.organizationId === void 0 ? {} : { organizationId: session.organizationId },
621
+ ...session.userId === void 0 ? {} : { userId: session.userId },
622
+ ...session.createdBy === void 0 ? {} : { createdBy: session.createdBy },
623
+ ...session.createdAt === void 0 ? {} : { createdAt: session.createdAt }
624
+ }, roles, listPermissions(options.permissions));
625
+ return credential === null ? anonymousSubject() : credentialSubject(credential, { permissions: options.permissions });
626
+ }
627
+ /**
628
+ * `subjectFromSupabaseSession` for better-supabase's `AuthSession`, reading
629
+ * `memberships` for the memberships and the entitlements module's `features`
630
+ * claim for `principal.plans` (`plans` names another claim). With `apiKeys`,
631
+ * a verified `apiKey` session is the key's credential subject: a personal key
632
+ * acts as its user within the key's scopes, a tenant key as a `service`
633
+ * principal holding `serviceRoles`. Without `apiKeys`, and for `anon`,
634
+ * `service` and `invalid` sessions, the subject is anonymous.
635
+ */
636
+ function subjectFromBetterSupabase(session, options = {}) {
637
+ const { apiKeys, plans = "features", ...rest } = options;
638
+ if (isApiKeySession(session)) return apiKeys === void 0 ? anonymousSubject() : apiKeySubject(session, apiKeys);
639
+ const claim = typeof plans === "string" ? plans : plans.claim ?? "features";
640
+ const keys = typeof plans === "string" ? void 0 : plans.keys;
641
+ return subjectFromSupabaseSession(keys === void 0 ? session : decodedFeatures(session, claim, keys), {
642
+ memberships: "memberships",
643
+ ...rest,
644
+ plans: claim
645
+ });
646
+ }
647
+ //#endregion
648
+ export { apiKeyClaimOptions, apiKeyVerifier, authorizationProvider, bucketPolicy, credentialGuard, subjectFromBetterSupabase, toolPolicy, topicPolicy };
@@ -0,0 +1,25 @@
1
+ import { f as ApprovalStore } from "./types-aqOHTHcp.js";
2
+ import { t as InstanceOptions } from "./instance-options-jARdwfPN.js";
3
+ import { r as PdpFactory } from "./types-DxiCGmmd.js";
4
+ import { o as OtelWrap } from "./types-QCuYJh4q.js";
5
+ import { T as TenantOption, b as WebBotAuthVerifier } from "./create-B1d519XK.js";
6
+ //#region src/server/bind.d.ts
7
+ /** The options of every framework adapter; `TContext` is what its callbacks receive. */
8
+ type ServerAdapterOptions<TContext, TUser = unknown> = InstanceOptions & ServerAdapterServices & {
9
+ readonly subject: (context: TContext) => TUser | Promise<TUser>;
10
+ /** The agent or service acting for the subject; anything but an `Actor` is ignored. */
11
+ readonly actor?: (context: TContext) => unknown;
12
+ readonly tenant?: TenantOption<TContext>;
13
+ };
14
+ /** The services an adapter hands to its kernel unchanged. */
15
+ type ServerAdapterServices = {
16
+ readonly store?: ApprovalStore;
17
+ /** `createPermDock` from `permdock/pdp`; `protect` then decides delegated permissions remotely. */
18
+ readonly pdp?: PdpFactory;
19
+ /** `(permdock) => withOtel(permdock, options)` from `permdock/otel`. */
20
+ readonly otel?: OtelWrap;
21
+ /** `(request) => verifyWebBotAuth(request, options)`; a verified bot becomes the actor. */
22
+ readonly webBotAuth?: WebBotAuthVerifier;
23
+ };
24
+ //#endregion
25
+ export { ServerAdapterServices as n, ServerAdapterOptions as t };