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
@@ -1,21 +1,24 @@
1
- import { g as listPermissions, n as definePermissions, y as resource } from "../permissions-DC7GROPA.js";
2
- import { r as principal } from "../refs-ChLSxbST.js";
3
- import { a as definePolicy, d as role, m as memoryLimitStore, t as allow } from "../policy-ANp36PnI.js";
4
- import { m as memoryRoleSource, u as snapshotFor } from "../src-CTNT-PBW.js";
5
- import { i as normalizeMemberships, u as scopeList } from "../scopes-cKVp_WTw.js";
6
- import { o as parseCredential, s as memoryRevocationFeed } from "../credential-B_rkUNlY.js";
7
- import { n as parseSnapshot } from "../snapshot-DE8dE_hz.js";
8
- import { i as parsePolicyDocument, r as mergeHostedGrants } from "../hosted-BwKQ1BTA.js";
9
- import { _ as approvalPoliciesFor, d as membershipsClaim, p as validateCustomRole, t as createPermDock } from "../permdock-yoZ7EjxX.js";
1
+ import { _ as listPermissions, b as resource, n as definePermissions } from "../permissions-DVoF6dMt.js";
2
+ import { r as principal } from "../refs-KYb4ntaz.js";
3
+ import { _ as memoryLimitStore, a as definePolicy, m as role, t as allow } from "../policy-xyWg7QdR.js";
4
+ import { _ as memoryRoleSource, u as snapshotFor } from "../src-BDwEZWrZ.js";
5
+ import { t as memoryRevocationFeed } from "../revocations-Bhr0aMIC.js";
6
+ import { a as normalizeMemberships, d as scopeList } from "../scopes-CVdPrWN-.js";
7
+ import { n as parseSnapshot, p as evaluateCondition } from "../snapshot-Enxd0n-s.js";
8
+ import { i as parsePolicyDocument, r as mergeHostedGrants } from "../hosted-DJQw46hn.js";
9
+ import { E as approvalPoliciesFor, b as validateCustomRole, t as createPermDock, v as membershipsClaim } from "../permdock-CbgvLnuo.js";
10
10
  import { t as byCodePoint } from "../compare-pfyVnBjE.js";
11
- import { n as fromSnapshot } from "../from-snapshot-BMGnhmgv.js";
12
- import { h as APPROVAL_HEADER, o as resolveApproval, p as memoryApprovalStore } from "../helpers-DnSOrhB9.js";
13
- import { a as parseApiKey } from "../credentials-BgRX3WEg.js";
14
- import { S as sha256Hex, n as directoryMembershipSource, r as scimHandler } from "../scim-9NFa0XVZ.js";
11
+ import { n as fromSnapshot } from "../from-snapshot-CTLijvdm.js";
12
+ import { o as parseCredential } from "../credential-8P81ff4u.js";
13
+ import { o as problemFromDecision } from "../problem-B43ztKIm.js";
14
+ import { l as APPROVAL_HEADER, r as memoryApprovalStore } from "../store-DMAWwAJV.js";
15
+ import { o as resolveApproval } from "../helpers-H_KARDVC.js";
16
+ import { a as parseApiKey } from "../server-DlZ28Oz5.js";
17
+ import { S as sha256Hex, n as directoryMembershipSource, r as scimHandler } from "../scim-BFGBBAqR.js";
15
18
  import { t as supabaseMembershipsBudget } from "../budget-NbEtbJC_.js";
16
- import { r as quoteSqlIdent, t as SQL_IDENT } from "../sql-Bll1d7y0.js";
17
- import { i as saasPermissions } from "../permissions-CofRqesP.js";
18
- import { C as saasOrg, E as saasSeed, S as saasMemberships, a as saasProject, g as verifySaasSession, h as signSaasToken, k as saasPolicy, t as saasDoc, w as saasPrincipal, x as saasCustomRoles } from "../saas-BRrZzJkM.js";
19
+ import { a as quoteSqlTable, r as quoteSqlIdent, t as SQL_IDENT } from "../sql-xdg5f4Fi.js";
20
+ import { i as saasPermissions } from "../permissions-RJrovw98.js";
21
+ import { C as saasOrg, E as saasSeed, S as saasMemberships, a as saasProject, g as verifySaasSession, h as signSaasToken, k as saasPolicy, t as saasDoc, w as saasPrincipal, x as saasCustomRoles } from "../saas-DhpJjnBA.js";
19
22
  import { afterAll, beforeAll, describe, expect, expectTypeOf, it, vi } from "vitest";
20
23
  //#region src/testing/describe-policy.ts
21
24
  function isOutcomeCell(value) {
@@ -139,7 +142,7 @@ function subjectSettings(dialect, subject, gucPrefix, tenantClaim, roleClaim, cu
139
142
  * a base table whose restricted columns are revoked does not reject it.
140
143
  */
141
144
  function statementSql(action, table, keyOnly) {
142
- const quoted = quoteSqlIdent(table);
145
+ const quoted = quoteSqlTable(table);
143
146
  const id = quoteSqlIdent("id");
144
147
  const back = keyOnly ? id : "*";
145
148
  switch (action) {
@@ -163,11 +166,11 @@ function isRead(action) {
163
166
  async function viewColumns(query, table, key) {
164
167
  const id = quoteSqlIdent("id");
165
168
  await query("savepoint permdock_fields");
166
- const view = await query(`select * from ${quoteSqlIdent(`${table}_visible`)} where ${id} = $1`, [key]);
169
+ const view = await query(`select * from ${quoteSqlTable(`${table}_visible`)} where ${id} = $1`, [key]);
167
170
  if (view.code === void 0) return valued(view.rows[0]);
168
171
  await query("rollback to savepoint permdock_fields");
169
172
  if (view.code !== "42P01") return view.code;
170
- const base = await query(`select * from ${quoteSqlIdent(table)} where ${id} = $1`, [key]);
173
+ const base = await query(`select * from ${quoteSqlTable(table)} where ${id} = $1`, [key]);
171
174
  return base.code ?? valued(base.rows[0]);
172
175
  }
173
176
  function dbOutcome(result) {
@@ -616,6 +619,63 @@ function testClientStore(name, createStore) {
616
619
  await settle();
617
620
  expect(net.calls).toHaveLength(2);
618
621
  });
622
+ it("answers a row edited in place once the task that read it ends", async () => {
623
+ const net = recorder(unreachable);
624
+ const store = createStore({
625
+ snapshot: snapshotOf("bob", "acme"),
626
+ tenant: "acme",
627
+ fetch: net.fetch
628
+ });
629
+ const row = {
630
+ ...acmeProject,
631
+ ownerId: "bob"
632
+ };
633
+ expect(store.get().status(p.project.update, row)).toBe("ready");
634
+ expect(store.get().can(p.project.update, row)).toBe(true);
635
+ row.ownerId = "alice";
636
+ await settle();
637
+ expect(store.get().can(p.project.update, row)).toBe(false);
638
+ });
639
+ it("answers a check on a row that throws as denied, without throwing", () => {
640
+ const net = recorder(unreachable);
641
+ const store = createStore({
642
+ snapshot: snapshotOf("bob", "acme"),
643
+ tenant: "acme",
644
+ fetch: net.fetch
645
+ });
646
+ const hostile = new Proxy({}, { get() {
647
+ throw new Error("hostile row");
648
+ } });
649
+ expect(store.get().status(p.project.update, hostile)).not.toBe("pending");
650
+ expect(store.get().can(p.project.update, hostile)).toBe(false);
651
+ });
652
+ it("notifies every subscriber of a logout when one of them throws", () => {
653
+ const reported = vi.fn();
654
+ vi.stubGlobal("reportError", reported);
655
+ try {
656
+ const net = recorder(unreachable);
657
+ const store = createStore({
658
+ snapshot: snapshotOf("bob", "acme"),
659
+ tenant: "acme",
660
+ fetch: net.fetch
661
+ });
662
+ let after = 0;
663
+ const offThrowing = store.get().subscribe(() => {
664
+ throw new Error("subscriber failed");
665
+ });
666
+ const offCounting = store.get().subscribe(() => {
667
+ after += 1;
668
+ });
669
+ store.get().clear();
670
+ expect(after).toBe(1);
671
+ expect(reported).toHaveBeenCalled();
672
+ expect(store.get().can(p.project.read, acmeProject)).toBe(false);
673
+ offThrowing();
674
+ offCounting();
675
+ } finally {
676
+ vi.unstubAllGlobals();
677
+ }
678
+ });
619
679
  it("does not notify subscribers synchronously from a status read", () => {
620
680
  const net = recorder(() => json({ evaluations: [] }));
621
681
  const store = createStore({
@@ -684,7 +744,7 @@ async function* ticks(org, signal) {
684
744
  function demotionKey(user, org) {
685
745
  return JSON.stringify([user, org]);
686
746
  }
687
- function createDomain() {
747
+ function createDomain$1() {
688
748
  const demoted = /* @__PURE__ */ new Set();
689
749
  const principalOf = (sub, path) => {
690
750
  const principal = saasPrincipal(sub, orgOf(path));
@@ -927,7 +987,7 @@ function testHttpAdapter(options) {
927
987
  it.skipIf(reason !== void 0)(reason === void 0 ? title : `${title} (${reason})`, run, timeout);
928
988
  };
929
989
  describe(`${options.name}: real-life HTTP scenarios`, () => {
930
- const domain = createDomain();
990
+ const domain = createDomain$1();
931
991
  const tokens = /* @__PURE__ */ new Map();
932
992
  let mounted;
933
993
  beforeAll(async () => {
@@ -1096,14 +1156,24 @@ function testHttpAdapter(options) {
1096
1156
  }
1097
1157
  })).status).toBe(403);
1098
1158
  });
1099
- scenario("assert", "maps assert inside a handler to a 403 Problem", async () => {
1159
+ scenario("assert", "maps assert inside a handler to the Problem protect sends", async () => {
1100
1160
  const denied = await send("bob", {
1101
1161
  op: "project.delete",
1102
1162
  org: "acme",
1103
1163
  id: "p2"
1104
1164
  });
1105
1165
  expect(denied.status).toBe(403);
1106
- expect(field(denied.body, "type")).toBe("https://permdock.dev/problems/denied");
1166
+ expect(field(denied.body, "type")).toBe("https://permdock.com/problems/denied");
1167
+ const bob = await createPermDock(saasPolicy, saasPrincipal("bob", "acme"), { tenant: "acme" });
1168
+ const permission = saasPolicy.permissions.project.delete;
1169
+ const fromProtect = await readResult(problemFromDecision(bob.decide(permission, project$1("p2")), permission, bob.subject));
1170
+ expect(denied.status).toBe(fromProtect.status);
1171
+ for (const key of [
1172
+ "type",
1173
+ "title",
1174
+ "permission",
1175
+ "denials"
1176
+ ]) expect(field(denied.body, key)).toEqual(field(fromProtect.body, key));
1107
1177
  expect((await send("bob", {
1108
1178
  op: "project.delete",
1109
1179
  org: "acme",
@@ -1121,7 +1191,7 @@ function testHttpAdapter(options) {
1121
1191
  org: "acme"
1122
1192
  });
1123
1193
  expect(asked.status).toBe(403);
1124
- expect(field(asked.body, "type")).toBe("https://permdock.dev/problems/approval-required");
1194
+ expect(field(asked.body, "type")).toBe("https://permdock.com/problems/approval-required");
1125
1195
  const token = field(asked.body, "token");
1126
1196
  expect(typeof token).toBe("string");
1127
1197
  await resolveApproval(domain.store, String(token), {
@@ -1230,7 +1300,7 @@ function testHttpAdapter(options) {
1230
1300
  });
1231
1301
  const end = await untilEnd(stream);
1232
1302
  expect(end.problem).toMatchObject({
1233
- type: "https://permdock.dev/problems/unauthenticated",
1303
+ type: "https://permdock.com/problems/unauthenticated",
1234
1304
  status: 401,
1235
1305
  detail: "session-revoked"
1236
1306
  });
@@ -1252,7 +1322,7 @@ function testHttpAdapter(options) {
1252
1322
  });
1253
1323
  const end = await untilEnd(stream);
1254
1324
  expect(end.problem).toMatchObject({
1255
- type: "https://permdock.dev/problems/denied",
1325
+ type: "https://permdock.com/problems/denied",
1256
1326
  status: 403
1257
1327
  });
1258
1328
  expect(end.ended).toBe(true);
@@ -1290,7 +1360,7 @@ function testHttpAdapter(options) {
1290
1360
  expect((await stream.next())?.event).toBe("message");
1291
1361
  const end = await untilEnd(stream);
1292
1362
  expect(end.problem).toMatchObject({
1293
- type: "https://permdock.dev/problems/unauthenticated",
1363
+ type: "https://permdock.com/problems/unauthenticated",
1294
1364
  detail: "expired"
1295
1365
  });
1296
1366
  expect(end.ended).toBe(true);
@@ -1301,6 +1371,148 @@ function testHttpAdapter(options) {
1301
1371
  });
1302
1372
  }
1303
1373
  //#endregion
1374
+ //#region src/testing/agent-adapter.ts
1375
+ /** The user whose subject resolver throws. */
1376
+ const AGENT_THROWING_USER = "throws";
1377
+ /** The project id whose loader throws. */
1378
+ const AGENT_THROWING_ROW = "throws";
1379
+ const SCENARIOS = [
1380
+ {
1381
+ name: "granted",
1382
+ title: "grants a member reading a project in their org",
1383
+ call: {
1384
+ user: "alice",
1385
+ org: "acme",
1386
+ tool: "project_read",
1387
+ args: { id: "p1" }
1388
+ },
1389
+ expected: "granted"
1390
+ },
1391
+ {
1392
+ name: "denied",
1393
+ title: "denies a user with no membership",
1394
+ call: {
1395
+ user: "mallory",
1396
+ org: "acme",
1397
+ tool: "project_read",
1398
+ args: { id: "p1" }
1399
+ },
1400
+ expected: "denied"
1401
+ },
1402
+ {
1403
+ name: "cross-tenant",
1404
+ title: "denies a row from another org",
1405
+ call: {
1406
+ user: "alice",
1407
+ org: "acme",
1408
+ tool: "project_read",
1409
+ args: { id: "g1" }
1410
+ },
1411
+ expected: "denied"
1412
+ },
1413
+ {
1414
+ name: "anonymous",
1415
+ title: "denies a call with no user",
1416
+ call: {
1417
+ user: null,
1418
+ org: "acme",
1419
+ tool: "project_read",
1420
+ args: { id: "p1" }
1421
+ },
1422
+ expected: "denied"
1423
+ },
1424
+ {
1425
+ name: "subject-throws",
1426
+ title: "denies when the subject resolver throws",
1427
+ call: {
1428
+ user: AGENT_THROWING_USER,
1429
+ org: "acme",
1430
+ tool: "project_read",
1431
+ args: { id: "p1" }
1432
+ },
1433
+ expected: "denied"
1434
+ },
1435
+ {
1436
+ name: "loader-throws",
1437
+ title: "denies when the row loader throws",
1438
+ call: {
1439
+ user: "alice",
1440
+ org: "acme",
1441
+ tool: "project_read",
1442
+ args: { id: AGENT_THROWING_ROW }
1443
+ },
1444
+ expected: "denied"
1445
+ },
1446
+ {
1447
+ name: "missing-row",
1448
+ title: "denies when the row does not exist",
1449
+ call: {
1450
+ user: "alice",
1451
+ org: "acme",
1452
+ tool: "project_read",
1453
+ args: { id: "missing" }
1454
+ },
1455
+ expected: "denied"
1456
+ },
1457
+ {
1458
+ name: "approval-required",
1459
+ title: "asks for approval before revoking every API key",
1460
+ call: {
1461
+ user: "alice",
1462
+ org: "acme",
1463
+ tool: "api_keys_revoke_all",
1464
+ args: {}
1465
+ },
1466
+ expected: "approval-required"
1467
+ }
1468
+ ];
1469
+ function loadProject(args) {
1470
+ const id = typeof args === "object" && args !== null ? args.id : void 0;
1471
+ if (id === "throws") throw new Error("project store unavailable");
1472
+ return saasSeed.projects.find((row) => row.id === id) ?? null;
1473
+ }
1474
+ function createDomain() {
1475
+ return {
1476
+ policy: saasPolicy,
1477
+ subject: (user, org) => {
1478
+ if (user === "throws") throw new Error("session store unavailable");
1479
+ return user === null ? null : saasPrincipal(user, org);
1480
+ },
1481
+ tools: {
1482
+ project_read: {
1483
+ permission: saasPermissions.project.read,
1484
+ data: loadProject
1485
+ },
1486
+ api_keys_revoke_all: { permission: saasPermissions.apiKey.revokeAll }
1487
+ },
1488
+ customRoles: memoryRoleSource(saasCustomRoles),
1489
+ store: memoryApprovalStore()
1490
+ };
1491
+ }
1492
+ /**
1493
+ * Runs the same tool calls through an agent adapter: a grant, the denials an
1494
+ * attacker or an outage produces, and an approval. Every failure denies.
1495
+ */
1496
+ function testAgentAdapter(options) {
1497
+ describe(`${options.name}: agent adapter scenarios`, () => {
1498
+ const domain = createDomain();
1499
+ let mounted;
1500
+ beforeAll(async () => {
1501
+ mounted = await options.mount(domain);
1502
+ });
1503
+ afterAll(async () => {
1504
+ await mounted.close?.();
1505
+ });
1506
+ const outcomeOf = (call) => mounted.call(call);
1507
+ for (const scenario of SCENARIOS) {
1508
+ const reason = options.skip?.[scenario.name];
1509
+ it.skipIf(reason !== void 0)(reason === void 0 ? scenario.title : `${scenario.title} (${reason})`, async () => {
1510
+ expect(await outcomeOf(scenario.call)).toBe(scenario.expected);
1511
+ });
1512
+ }
1513
+ });
1514
+ }
1515
+ //#endregion
1304
1516
  //#region src/testing/authzen.ts
1305
1517
  function sortKey(value) {
1306
1518
  return JSON.stringify(Object.fromEntries(Object.entries(value).toSorted(([a], [b]) => byCodePoint(a, b))));
@@ -1592,11 +1804,12 @@ function testSubjectResolver(resolver, options) {
1592
1804
  });
1593
1805
  }
1594
1806
  function testMembershipSource(source, options) {
1807
+ const query = options.tenant === void 0 ? {} : { tenant: options.tenant };
1595
1808
  it("returns well-formed memberships and fails closed on throw", async () => {
1596
1809
  for (const principal of options.principals) {
1597
1810
  let memberships = [];
1598
1811
  try {
1599
- memberships = await source.membershipsFor(principal, {});
1812
+ memberships = await source.membershipsFor(principal, query);
1600
1813
  } catch {
1601
1814
  memberships = [];
1602
1815
  }
@@ -1618,7 +1831,7 @@ function testMembershipSource(source, options) {
1618
1831
  for (const principal of options.principals) {
1619
1832
  let memberships = [];
1620
1833
  try {
1621
- memberships = await source.membershipsFor(principal, {});
1834
+ memberships = await source.membershipsFor(principal, query);
1622
1835
  } catch {
1623
1836
  continue;
1624
1837
  }
@@ -1726,6 +1939,22 @@ function testRelationSource(source, options) {
1726
1939
  expect(linked.ancestors.map((ancestor) => ancestor.id)).toEqual([id]);
1727
1940
  }
1728
1941
  });
1942
+ it("reads each object's row as an object, or null when there is none", async () => {
1943
+ if (source.row === void 0) return;
1944
+ const read = (query) => source.row?.(query);
1945
+ for (const object of options.objects) {
1946
+ const row = await read({
1947
+ resource: object.resource,
1948
+ id: object.id
1949
+ });
1950
+ expect(row === null || row === void 0 || typeof row === "object" && !Array.isArray(row)).toBe(true);
1951
+ }
1952
+ const missing = await read({
1953
+ resource: options.objects[0]?.resource ?? "",
1954
+ id: "permdock-missing-object"
1955
+ });
1956
+ expect(missing ?? null).toBeNull();
1957
+ });
1729
1958
  it("answers an unknown object with nothing instead of throwing", async () => {
1730
1959
  const first = options.objects[0];
1731
1960
  if (first === void 0) return;
@@ -1767,6 +1996,11 @@ function testRoleSource(source, options) {
1767
1996
  for (const name of assignable) expect(declared).toContain(name);
1768
1997
  }
1769
1998
  });
1999
+ const every = options.every;
2000
+ if (every !== void 0) it("returns every custom role of the tenant, held or not", async () => {
2001
+ const roles = await source.rolesFor(options.tenant, { held: [] });
2002
+ expect([...new Set(roles.map((role) => role.name))].toSorted()).toEqual([...new Set(every)].toSorted());
2003
+ });
1770
2004
  }
1771
2005
  function testLimitStore(store) {
1772
2006
  it("counts down synchronously and fails closed when exhausted", async () => {
@@ -2320,6 +2554,44 @@ function testApprovalStore(store, options = {}) {
2320
2554
  expect(second.resolvedBy).toBe("u_10");
2321
2555
  expect(await store.consume("quorum-token")).not.toBeNull();
2322
2556
  });
2557
+ it("resolves a vouched verdict at once, records its rule, and still refuses the requester", async () => {
2558
+ await store.create({
2559
+ ...sampleApproval("vouched-token"),
2560
+ approvers: {
2561
+ by: admin,
2562
+ quorum: 2
2563
+ }
2564
+ });
2565
+ await expect(Promise.resolve().then(() => store.resolve("vouched-token", {
2566
+ status: "approved",
2567
+ by: {
2568
+ principal: {
2569
+ id: "u_1",
2570
+ roles: []
2571
+ },
2572
+ context: {}
2573
+ },
2574
+ vouched: "app-rule"
2575
+ }))).rejects.toThrow(/principal/u);
2576
+ const resolved = await store.resolve("vouched-token", {
2577
+ status: "approved",
2578
+ by: {
2579
+ principal: {
2580
+ id: "u_outsider",
2581
+ roles: []
2582
+ },
2583
+ context: {}
2584
+ },
2585
+ vouched: "app-rule"
2586
+ });
2587
+ expect(resolved.status).toBe("approved");
2588
+ expect(resolved.vouched).toBe("app-rule");
2589
+ expect(resolved.approvals).toEqual([{
2590
+ by: "u_outsider",
2591
+ at: expect.any(String),
2592
+ vouched: "app-rule"
2593
+ }]);
2594
+ });
2323
2595
  it("lets one rejection end a quorum request", async () => {
2324
2596
  await store.create({
2325
2597
  ...sampleApproval("veto-token"),
@@ -2629,7 +2901,176 @@ function testTokenSigner(signer, options) {
2629
2901
  }
2630
2902
  });
2631
2903
  }
2904
+ const WHERE_ROWS = [
2905
+ {
2906
+ id: "r1",
2907
+ authorId: "u1",
2908
+ score: 5,
2909
+ title: "Plan 100%",
2910
+ archived: false,
2911
+ note: null
2912
+ },
2913
+ {
2914
+ id: "r2",
2915
+ authorId: "u2",
2916
+ score: 10,
2917
+ title: "plan_b",
2918
+ archived: true,
2919
+ note: "kept"
2920
+ },
2921
+ {
2922
+ id: "r3",
2923
+ authorId: null,
2924
+ score: null,
2925
+ title: null,
2926
+ archived: null,
2927
+ note: null
2928
+ }
2929
+ ];
2930
+ const WHERE_CASES = [
2931
+ ["eq", {
2932
+ op: "eq",
2933
+ field: "authorId",
2934
+ value: "u1"
2935
+ }],
2936
+ ["ne", {
2937
+ op: "ne",
2938
+ field: "authorId",
2939
+ value: "u1"
2940
+ }],
2941
+ ["eq on a boolean", {
2942
+ op: "eq",
2943
+ field: "archived",
2944
+ value: false
2945
+ }],
2946
+ ["gt", {
2947
+ op: "gt",
2948
+ field: "score",
2949
+ value: 5
2950
+ }],
2951
+ ["gte", {
2952
+ op: "gte",
2953
+ field: "score",
2954
+ value: 5
2955
+ }],
2956
+ ["lt", {
2957
+ op: "lt",
2958
+ field: "score",
2959
+ value: 10
2960
+ }],
2961
+ ["lte", {
2962
+ op: "lte",
2963
+ field: "score",
2964
+ value: 10
2965
+ }],
2966
+ ["contains a literal %", {
2967
+ op: "contains",
2968
+ field: "title",
2969
+ value: "100%"
2970
+ }],
2971
+ ["contains a literal _", {
2972
+ op: "contains",
2973
+ field: "title",
2974
+ value: "n_b"
2975
+ }],
2976
+ ["in", {
2977
+ op: "in",
2978
+ field: "authorId",
2979
+ value: ["u1", "u2"]
2980
+ }],
2981
+ ["notIn", {
2982
+ op: "notIn",
2983
+ field: "authorId",
2984
+ value: ["u1"]
2985
+ }],
2986
+ ["isNull", {
2987
+ op: "isNull",
2988
+ field: "note",
2989
+ value: true
2990
+ }],
2991
+ ["is not null", {
2992
+ op: "isNull",
2993
+ field: "note",
2994
+ value: false
2995
+ }],
2996
+ ["and", {
2997
+ op: "and",
2998
+ conditions: [{
2999
+ op: "eq",
3000
+ field: "authorId",
3001
+ value: "u1"
3002
+ }, {
3003
+ op: "lt",
3004
+ field: "score",
3005
+ value: 10
3006
+ }]
3007
+ }],
3008
+ ["or", {
3009
+ op: "or",
3010
+ conditions: [{
3011
+ op: "eq",
3012
+ field: "authorId",
3013
+ value: "u1"
3014
+ }, {
3015
+ op: "eq",
3016
+ field: "archived",
3017
+ value: true
3018
+ }]
3019
+ }],
3020
+ ["not over a NULL field", {
3021
+ op: "not",
3022
+ condition: {
3023
+ op: "eq",
3024
+ field: "authorId",
3025
+ value: "u1"
3026
+ }
3027
+ }],
3028
+ ["not over and", {
3029
+ op: "not",
3030
+ condition: {
3031
+ op: "and",
3032
+ conditions: [{
3033
+ op: "eq",
3034
+ field: "authorId",
3035
+ value: "u2"
3036
+ }, {
3037
+ op: "gt",
3038
+ field: "score",
3039
+ value: 5
3040
+ }]
3041
+ }
3042
+ }],
3043
+ ["and of nothing", {
3044
+ op: "and",
3045
+ conditions: []
3046
+ }],
3047
+ ["not of the empty allow set", {
3048
+ op: "not",
3049
+ condition: {
3050
+ op: "or",
3051
+ conditions: []
3052
+ }
3053
+ }]
3054
+ ];
3055
+ const WHERE_SUBJECT = {
3056
+ principal: null,
3057
+ context: {}
3058
+ };
3059
+ /**
3060
+ * `matches` answers whether the compiled output selects `row`, for example
3061
+ * by running it against a table holding only that row. With it, every case
3062
+ * must select the rows the in-memory evaluator keeps, including rows whose
3063
+ * fields are NULL.
3064
+ */
2632
3065
  function testWhereCompiler(compiler, options) {
3066
+ const { matches } = options;
3067
+ it.skipIf(matches === void 0).each(WHERE_CASES)("selects the rows the evaluator keeps: %s", async (_name, condition) => {
3068
+ if (matches === void 0) return;
3069
+ const compiled = compiler(condition, options.target);
3070
+ const selected = [];
3071
+ for (const row of WHERE_ROWS) if (await matches(compiled, row)) selected.push(row["id"]);
3072
+ expect(selected).toEqual(WHERE_ROWS.filter((row) => evaluateCondition(condition, row, WHERE_SUBJECT)).map((row) => row["id"]));
3073
+ });
2633
3074
  it("fails closed on an empty allow set", () => {
2634
3075
  const compiled = compiler({
2635
3076
  op: "or",
@@ -2815,7 +3256,7 @@ const supabaseClaimFixtures = {
2815
3256
  }]
2816
3257
  }
2817
3258
  },
2818
- betterSupabase: {
3259
+ tenantPlans: {
2819
3260
  claims: {
2820
3261
  ...base,
2821
3262
  user_role: null,
@@ -2923,11 +3364,7 @@ const supabaseClaimFixtures = {
2923
3364
  id: "5f0e4d3c-2b1a-4098-8776-655443322110",
2924
3365
  kind: "oauth-client"
2925
3366
  },
2926
- delegation: { scopes: [
2927
- "openid",
2928
- "email",
2929
- "posts:read"
2930
- ] }
3367
+ delegation: { scopes: ["posts:read"] }
2931
3368
  }
2932
3369
  },
2933
3370
  actChain: {
@@ -3061,14 +3498,25 @@ const supabaseClaimFixtures = {
3061
3498
  }
3062
3499
  }
3063
3500
  };
3501
+ const supabaseClaimVectors = {
3502
+ feature: "auth.session.get_claims",
3503
+ cases: Object.entries(supabaseClaimFixtures).map(([name, fixture]) => ({
3504
+ name,
3505
+ input: {
3506
+ claims: fixture.claims,
3507
+ ...fixture.options === void 0 ? {} : { options: fixture.options }
3508
+ },
3509
+ expected: fixture.expect
3510
+ }))
3511
+ };
3064
3512
  /**
3065
3513
  * The `permdock supabase inspect --json` manifest for a policy with one
3066
3514
  * `tenant` scope, the default `supabase.hook` and a `features` claim from
3067
- * `better_supabase.feature_claims`. A package that reads the manifest tests its
3515
+ * `public.feature_claims`. A package that reads the manifest tests its
3068
3516
  * parser against this value.
3069
3517
  */
3070
3518
  const supabaseHookManifestFixture = {
3071
- $schema: "https://permdock.dev/schemas/supabase-manifest-v1.json",
3519
+ $schema: "https://permdock.com/schemas/supabase-manifest-v1.json",
3072
3520
  version: 1,
3073
3521
  hook: {
3074
3522
  schema: "permdock",
@@ -3122,7 +3570,7 @@ const supabaseHookManifestFixture = {
3122
3570
  },
3123
3571
  {
3124
3572
  name: "features",
3125
- source: "better_supabase.feature_claims",
3573
+ source: "public.feature_claims",
3126
3574
  budget: false
3127
3575
  }
3128
3576
  ],
@@ -3177,6 +3625,12 @@ const supabaseHookManifestFixture = {
3177
3625
  args: "p_user uuid",
3178
3626
  returns: "setof uuid",
3179
3627
  execute: ["supabase_auth_admin"]
3628
+ },
3629
+ {
3630
+ name: "permdock_user_id",
3631
+ args: "",
3632
+ returns: "uuid",
3633
+ execute: ["authenticated"]
3180
3634
  }
3181
3635
  ],
3182
3636
  memberships: [{
@@ -3191,7 +3645,13 @@ const supabaseHookManifestFixture = {
3191
3645
  "scope_id",
3192
3646
  "role"
3193
3647
  ]
3194
- }]
3648
+ }],
3649
+ customRoles: false,
3650
+ roles: {
3651
+ table: "permdock.user_roles",
3652
+ user: { column: "user_id" },
3653
+ role: { column: "role" }
3654
+ }
3195
3655
  },
3196
3656
  decidingColumns: [
3197
3657
  "public.memberships.role",
@@ -3202,7 +3662,11 @@ const supabaseHookManifestFixture = {
3202
3662
  markers: {
3203
3663
  hook: "v1",
3204
3664
  grants: "v1"
3665
+ },
3666
+ requires: {
3667
+ matrix: "capability-matrix-v1.12.0",
3668
+ capabilities: ["auth.session.get_claims"]
3205
3669
  }
3206
3670
  };
3207
3671
  //#endregion
3208
- export { authzenTodoData, authzenTodoPermissions, authzenTodoPolicy, authzenTodoUsers, authzenTodoVectors, describePolicy, expectTypeOf, jwtFixtureAudience, jwtFixtureIssuer, jwtFixtureJwks, jwtFixtureTokens, ormParity, rlsParity, snapshotFixture, supabaseClaimFixtures, supabaseHookManifestFixture, supabaseMembershipsBudget, testApprovalPolicySource, testApprovalStore, testAuthZen, testClientParity, testClientStore, testCredentialVerifier, testDecisionSink, testDirectoryStore, testEntitlementSource, testHttpAdapter, testLimitStore, testMembershipSource, testPolicySource, testRelationSource, testReplayStore, testRevocationFeed, testRoleSource, testSettingsSource, testSnapshotSource, testSubjectResolver, testTokenSigner, testTokenVerifier, testWhereCompiler };
3672
+ export { AGENT_THROWING_ROW, AGENT_THROWING_USER, authzenTodoData, authzenTodoPermissions, authzenTodoPolicy, authzenTodoUsers, authzenTodoVectors, describePolicy, expectTypeOf, jwtFixtureAudience, jwtFixtureIssuer, jwtFixtureJwks, jwtFixtureTokens, ormParity, rlsParity, snapshotFixture, supabaseClaimFixtures, supabaseClaimVectors, supabaseHookManifestFixture, supabaseMembershipsBudget, testAgentAdapter, testApprovalPolicySource, testApprovalStore, testAuthZen, testClientParity, testClientStore, testCredentialVerifier, testDecisionSink, testDirectoryStore, testEntitlementSource, testHttpAdapter, testLimitStore, testMembershipSource, testPolicySource, testRelationSource, testReplayStore, testRevocationFeed, testRoleSource, testSettingsSource, testSnapshotSource, testSubjectResolver, testTokenSigner, testTokenVerifier, testWhereCompiler };