permdock 0.7.0 → 0.9.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 (483) hide show
  1. package/README.md +1 -3
  2. package/dist/a2a/index.d.ts +7 -7
  3. package/dist/a2a/index.js +8 -8
  4. package/dist/action-result-BcudBQOF.d.ts +19 -0
  5. package/dist/{adapter-context-CRhqyzCk.js → adapter-context-CIQpQxbE.js} +8 -2
  6. package/dist/{adoption-scan-D-feE7BE.js → adoption-scan-Ch07MdxN.js} +5 -5
  7. package/dist/agent/index.d.ts +2 -2
  8. package/dist/agent/index.js +1 -1
  9. package/dist/ai-sdk/index.d.ts +19 -13
  10. package/dist/ai-sdk/index.js +6 -6
  11. package/dist/{app-data-MuyzVqX8.js → app-data-UNNm07jV.js} +10 -7
  12. package/dist/{approval-header-CJACtHkv.js → approval-header-8QV6MU4H.js} +6 -3
  13. package/dist/{approval-prompt-K0faOLFp.d.ts → approval-prompt-3BqWczTt.d.ts} +13 -11
  14. package/dist/{approval-prompt-Dg5LeAcT.js → approval-prompt-B8hQY69x.js} +5 -6
  15. package/dist/approvals/index.d.ts +4 -4
  16. package/dist/approvals/index.js +6 -6
  17. package/dist/{approvals-CMRfsbBh.js → approvals-DnIBTuXE.js} +66 -42
  18. package/dist/{approvers-CqPOLD-o.js → approvers-B4r0N_Uz.js} +8 -2
  19. package/dist/{arazzo-ClrF3PVb.js → arazzo-BpS7LnV0.js} +2 -2
  20. package/dist/{arazzo-rdeJ8n1J.js → arazzo-CmQaGPkM.js} +6 -6
  21. package/dist/{args-CC3OwyHW.js → args-0FrVs5EH.js} +14 -7
  22. package/dist/astro/index.d.ts +30 -12
  23. package/dist/astro/index.js +2 -2
  24. package/dist/{audience-BrMs8c4o.js → audience-DTjR8xet.js} +8 -8
  25. package/dist/{auth-CscUX8Sy.js → auth--yPyZNgr.js} +19 -7
  26. package/dist/authzen/index.d.ts +34 -28
  27. package/dist/authzen/index.js +23 -20
  28. package/dist/{automation-DOtAFWdy.d.ts → automation-C6Jg75xq.d.ts} +42 -32
  29. package/dist/{automation-ySsxp_Yp.js → automation-x3KEUusw.js} +22 -21
  30. package/dist/better-auth/index.d.ts +2 -2
  31. package/dist/better-auth/index.js +13 -7
  32. package/dist/better-supabase/index.d.ts +357 -227
  33. package/dist/better-supabase/index.js +219 -140
  34. package/dist/{bind-D1nO6fiC.js → bind-BNQA9JK9.js} +26 -10
  35. package/dist/{bind-JDuvxjuW.d.ts → bind-YYjvfpB9.d.ts} +32 -12
  36. package/dist/{body-CH5of8Ne.js → body-CJQwYVa8.js} +3 -3
  37. package/dist/{body-text-QcXok_SI.js → body-text-DQhcmqdY.js} +8 -4
  38. package/dist/{boundary-BM8a_P6E.js → boundary-BV3O1eud.js} +8 -2
  39. package/dist/{boundary-BmHxVH1J.d.ts → boundary-C9ck-3uK.d.ts} +13 -4
  40. package/dist/{budget-NbEtbJC_.js → budget-BELja5A9.js} +6 -3
  41. package/dist/{budget-JqcRqyhK.d.ts → budget-hYsPz_yE.d.ts} +6 -3
  42. package/dist/{build-instance-DxE7czo9.js → build-instance-BWXqwQYU.js} +3 -3
  43. package/dist/{capability-L7NnfhiE.js → capability-BqX94r07.js} +31 -25
  44. package/dist/{capability-D4UC9TTW.d.ts → capability-Di9tiUvi.d.ts} +41 -29
  45. package/dist/{casbin-BHijLuHY.js → casbin-B7_yS-oo.js} +2 -2
  46. package/dist/{casbin-BW9pS47J.js → casbin-bHyIxTNQ.js} +16 -8
  47. package/dist/{casl-CmJlgziS.js → casl-C4OINZHI.js} +2 -2
  48. package/dist/{casl-UbI8v-Wq.js → casl-CHHoCldP.js} +19 -10
  49. package/dist/catalog/index.d.ts +51 -30
  50. package/dist/catalog/index.js +18 -15
  51. package/dist/{catalog-D69WhFii.js → catalog-CGlSwU6j.js} +20 -19
  52. package/dist/catalog-D3oS2GH3.js +1 -0
  53. package/dist/{catalog-BaMQfQ6Y.js → catalog-amPDr0JQ.js} +3 -3
  54. package/dist/{catalog-doc-CV9s6B1S.js → catalog-doc-DjMKzJp9.js} +28 -14
  55. package/dist/{catalog-fingerprint-C144oW4M.js → catalog-fingerprint-e6aCWosn.js} +18 -14
  56. package/dist/catalog-operations-DeHTrJSV.js +60 -0
  57. package/dist/{challenge-nGWma08S.js → challenge-DImNcR7B.js} +48 -27
  58. package/dist/chat/index.d.ts +1 -1
  59. package/dist/chat/index.js +13 -10
  60. package/dist/chat-sdk/index.d.ts +44 -26
  61. package/dist/chat-sdk/index.js +17 -17
  62. package/dist/{checks-BC_0mPIq.js → checks-CGkP3Z7A.js} +4 -1
  63. package/dist/{claims-map-7oQ3ue4X.js → claims-map-CKkoAAYF.js} +5 -2
  64. package/dist/{claims-map-Ca-QX8C6.d.ts → claims-map-D1Pb5oRq.d.ts} +8 -5
  65. package/dist/claude-agent/index.d.ts +6 -6
  66. package/dist/claude-agent/index.js +6 -3
  67. package/dist/clerk/index.d.ts +11 -7
  68. package/dist/clerk/index.js +6 -6
  69. package/dist/cli/bin.js +4 -4
  70. package/dist/cli/index.d.ts +82 -7
  71. package/dist/cli/index.js +6 -6
  72. package/dist/{clients-C7zLFuWT.d.ts → clients-C_NOET3z.d.ts} +5 -5
  73. package/dist/{clients-DjU5ABMy.js → clients-DYr3U86j.js} +3 -3
  74. package/dist/cloud/index.d.ts +84 -52
  75. package/dist/cloud/index.js +53 -39
  76. package/dist/{cloud-CO8pYtwr.js → cloud-3kWfjnYy.js} +4 -5
  77. package/dist/{codemod-BP6n8N9L.js → codemod-Bv5i-Mzo.js} +523 -201
  78. package/dist/{codemod-i4N2BhDc.js → codemod-D9Aiii1r.js} +3 -4
  79. package/dist/{collect-DNm3oKOk.js → collect-B80GYEot.js} +4 -5
  80. package/dist/collect-D-eroIfV.js +1 -0
  81. package/dist/{collect-BaWeMjwV.js → collect-WCl8cJQV.js} +26 -63
  82. package/dist/{compare-pfyVnBjE.js → compare-DTfyUunF.js} +2 -2
  83. package/dist/compile/index.d.ts +2 -2
  84. package/dist/compile/index.js +1 -1
  85. package/dist/{compile-COM2VKuN.d.ts → compile-BEklRUYo.d.ts} +36 -12
  86. package/dist/{compile-BAEO5bOk.js → compile-EzEMB-7v.js} +77 -33
  87. package/dist/{completion-BNdVf7X2.js → completion-_bc0OUQ-.js} +17 -8
  88. package/dist/config-BwPBfN0t.js +108 -0
  89. package/dist/{config-DGZzMV1B.js → config-D5XrLWpk.js} +2 -2
  90. package/dist/{config-report-Cm7UITNA.js → config-report-BmWIskD7.js} +9 -6
  91. package/dist/config-shape-ykV0Vm2n.js +134 -0
  92. package/dist/{connection-DjhIJSs2.js → connection-B72dg5Q2.js} +23 -22
  93. package/dist/{connector-schema-_VCSsdtD.js → connector-schema-CYLQNMYq.js} +3 -2
  94. package/dist/{context--uM9V3Ui.js → context-BnIzxTNE.js} +4 -3
  95. package/dist/convex/index.d.ts +13 -7
  96. package/dist/convex/index.js +9 -6
  97. package/dist/{core-CQkE8Esr.d.ts → core-CFepFiDP.d.ts} +49 -22
  98. package/dist/{core-B5-w6Kw9.js → core-DzVINFbU.js} +26 -20
  99. package/dist/{create-Cb86Z8Im.js → create-6EwRQlig.js} +10 -7
  100. package/dist/{create-DJrlhEp9.js → create-BLPKnJKa.js} +35 -25
  101. package/dist/{create-UTnUVETj.d.ts → create-BPUopdfL.d.ts} +70 -37
  102. package/dist/{create-QHuuPw3q.d.ts → create-BamXmeob.d.ts} +37 -29
  103. package/dist/{create-B2-CQqCI.d.ts → create-DBvUsgzK.d.ts} +49 -28
  104. package/dist/{credential-CIM7wHwA.js → credential-CyyyvCsL.js} +41 -38
  105. package/dist/{credentials-BpuTwd7a.js → credentials-CdDxp7jN.js} +6 -6
  106. package/dist/{deciding-columns-DRo2QM6E.js → deciding-columns-NB4wcyBf.js} +2 -2
  107. package/dist/{delegation-C5rOdTp5.js → delegation-CDB6_keF.js} +31 -22
  108. package/dist/delivery/index.d.ts +4 -4
  109. package/dist/delivery/index.js +5 -5
  110. package/dist/{delivery-rwOKLWRm.js → delivery-BupfvJIV.js} +34 -22
  111. package/dist/{delivery-event-xX4obB8F.js → delivery-event-JioK5YbS.js} +6 -6
  112. package/dist/denied-text-DHldhVUv.d.ts +22 -0
  113. package/dist/{describe-DZlnEtLy.js → describe-Bb4hGK5d.js} +5 -5
  114. package/dist/{describe-O0SwYIK8.d.ts → describe-BbFPBSms.d.ts} +5 -5
  115. package/dist/{device-BARQ8eYG.js → device-BwbJNmb2.js} +11 -8
  116. package/dist/{diff-Btr1c1Ow.js → diff-BwR1JdP2.js} +2 -2
  117. package/dist/{diff-DzT-xD13.js → diff-CQegtBAo.js} +22 -13
  118. package/dist/{digest-B3kc_PgQ.d.ts → digest-8Yx2CchM.d.ts} +3 -3
  119. package/dist/{doctor-BU1szn63.js → doctor-ClRVAtXQ.js} +287 -135
  120. package/dist/{doctor-BoK_y0KO.js → doctor-LPMYjSqO.js} +4 -4
  121. package/dist/drizzle/index.d.ts +33 -19
  122. package/dist/drizzle/index.js +17 -9
  123. package/dist/elysia/index.d.ts +17 -11
  124. package/dist/elysia/index.js +5 -5
  125. package/dist/{errors-BKy0EfhN.js → errors-B6R_lg2a.js} +13 -4
  126. package/dist/{errors-B_Qg9D3e.d.ts → errors-BIM4MFsJ.d.ts} +22 -6
  127. package/dist/{errors-BWXBMaKK.d.ts → errors-CHwoRRpB.d.ts} +4 -1
  128. package/dist/{errors-DpP_U6Bf.js → errors-Vpu6rKHl.js} +13 -10
  129. package/dist/{evaluate-B_oqFbWC.js → evaluate-BAmf_AQd.js} +153 -82
  130. package/dist/{evaluations-BCddEOfO.d.ts → evaluations-DOWuBpWv.d.ts} +11 -5
  131. package/dist/{evaluations-DReoiVBw.js → evaluations-IBceAeKT.js} +40 -19
  132. package/dist/eve/index.d.ts +9 -6
  133. package/dist/eve/index.js +4 -4
  134. package/dist/{event-time-CsegxXxB.js → event-time-BGy48400.js} +8 -4
  135. package/dist/{expiry-D4_YKRKD.js → expiry-6XByK0dm.js} +8 -5
  136. package/dist/express/index.d.ts +9 -6
  137. package/dist/express/index.js +9 -6
  138. package/dist/fastify/index.d.ts +16 -10
  139. package/dist/fastify/index.js +8 -5
  140. package/dist/{fetch-adapter-CuhyYwC1.d.ts → fetch-adapter-BIbBAtPZ.d.ts} +9 -6
  141. package/dist/{fetch-adapter-De-u6vhJ.js → fetch-adapter-dPTgJVHd.js} +14 -11
  142. package/dist/fields-D0vUI6dq.js +498 -0
  143. package/dist/{files-acUbNwWt.js → files-B3AA05f1.js} +8 -5
  144. package/dist/{files-D_JIzUrP.js → files-BSjrtIHw.js} +11 -4
  145. package/dist/{fixtures-BTMW6zgU.js → fixtures-A1_sp_tR.js} +15 -6
  146. package/dist/{flags-aaeRAdiD.js → flags-DXjoTVbS.js} +2 -2
  147. package/dist/{freeze-CrU8nQeX.js → freeze-jjan0lCv.js} +4 -1
  148. package/dist/{from-snapshot-Bz469dIh.js → from-snapshot-DCakWRsr.js} +18 -15
  149. package/dist/gen-BFfzZSLH.js +58 -0
  150. package/dist/gen-BtfFWGbz.js +827 -0
  151. package/dist/{generate-3FNO5P5Q.js → generate-CRVV5V7l.js} +14 -8
  152. package/dist/generate-CezbCaTI.js +275 -0
  153. package/dist/{grantee-BrRANrpT.js → grantee-Dke-9rd1.js} +4 -4
  154. package/dist/{grantee-conditions-C6P1Tvol.js → grantee-conditions-BrYPe-w0.js} +12 -12
  155. package/dist/{grantee-match-0RtHWQDx.js → grantee-match-7RZZvoT_.js} +12 -6
  156. package/dist/{graph-sql-B-dsAT6j.d.ts → graph-sql-BwFC4Qjs.d.ts} +3 -3
  157. package/dist/h3/index.d.ts +10 -7
  158. package/dist/h3/index.js +3 -3
  159. package/dist/headers-B9jQxjtW.d.ts +10 -0
  160. package/dist/{helpers-DY3vXuGs.js → helpers-DJicaG6f.js} +40 -28
  161. package/dist/hono/index.d.ts +16 -10
  162. package/dist/hono/index.js +5 -5
  163. package/dist/{hosted-XBgU6RGT.js → hosted-D0IzESu_.js} +42 -21
  164. package/dist/{hosted-BmjzxQhp.d.ts → hosted-DVxlLZMe.d.ts} +33 -21
  165. package/dist/{http-ujKm0JXE.js → http-DH94eh6f.js} +4 -4
  166. package/dist/{http-BBoKefeS.js → http-DKLXrFGk.js} +13 -7
  167. package/dist/{http-Ca3Sr5x1.js → http-DOL33cO0.js} +11 -8
  168. package/dist/{import-DB2EG_iy.js → import-ACkOrv6g.js} +6 -6
  169. package/dist/{import-Bz0GefWg.js → import-CST57XLp.js} +64 -51
  170. package/dist/{index-CMiPH2Tv.d.ts → index-BinlXeU-.d.ts} +64 -37
  171. package/dist/{index-BSfRl0hZ.d.ts → index-CV-7DWeD.d.ts} +64 -52
  172. package/dist/{index-BE8y3moU.d.ts → index-DJwEgYzA.d.ts} +127 -82
  173. package/dist/{index-DH9DUDEM.d.ts → index-Dj2qF9VC.d.ts} +54 -30
  174. package/dist/{index-BTkwrK7v.d.ts → index-vYjMrXyK.d.ts} +336 -173
  175. package/dist/{index-DLwcuCN_.d.ts → index-ymept53A.d.ts} +51 -30
  176. package/dist/index.d.ts +22 -22
  177. package/dist/index.js +34 -34
  178. package/dist/{init-B-4t1NzC.js → init-BjuFDYT1.js} +10 -10
  179. package/dist/{init-5TXNji88.js → init-txYTuW9u.js} +5 -5
  180. package/dist/{instance-options-CU0YQCLH.d.ts → instance-options-CoHn-0e8.d.ts} +4 -4
  181. package/dist/{instance-snapshot-CjcwnEiV.js → instance-snapshot-DuWf1cT3.js} +86 -61
  182. package/dist/{instant-BluqDvyS.js → instant-DK3Iz83e.js} +2 -2
  183. package/dist/{internals-Dk8A8fX3.js → internals-B3IgHrvo.js} +6 -3
  184. package/dist/{json-schema-B-vAwlde.js → json-schema-BPGa-RjQ.js} +9 -3
  185. package/dist/{json-schema-CN_iLFH2.d.ts → json-schema-BfXgnRNT.d.ts} +4 -4
  186. package/dist/jwt/index.d.ts +57 -27
  187. package/dist/jwt/index.js +24 -21
  188. package/dist/{kernel-DVExUwkp.js → kernel-qv4cr9w8.js} +32 -23
  189. package/dist/kysely/index.d.ts +49 -33
  190. package/dist/kysely/index.js +9 -7
  191. package/dist/{live-options-BaAFCIiu.js → live-options-BBIT68le.js} +2 -2
  192. package/dist/{load-DxroEzH1.js → load-DjSU5KXO.js} +6 -6
  193. package/dist/load-Dm0pSYH3.js +1 -0
  194. package/dist/{login-ClSJh5t5.js → login-CfImTJGb.js} +4 -4
  195. package/dist/{login-WC9HPJpU.js → login-CgfCTO3F.js} +16 -9
  196. package/dist/{manifest-Dv6q4i5s.js → manifest-B2QPh19C.js} +49 -38
  197. package/dist/{manifest-BVhExYhw.d.ts → manifest-CzzWtnAb.d.ts} +126 -31
  198. package/dist/{manifest-schema-Cv492Qev.js → manifest-schema-2r37XRhD.js} +44 -3
  199. package/dist/{manifest-B79YuF2T.js → manifest-wg8WkkpD.js} +6 -6
  200. package/dist/{map-claims-etGIS_Dv.js → map-claims-C-nv08_n.js} +16 -9
  201. package/dist/{map-error-BQGyDm_M.js → map-error-pasIGqMT.js} +7 -7
  202. package/dist/{markers-C6joDI3o.js → markers-BeHZ4x9Q.js} +20 -5
  203. package/dist/mcp/index.d.ts +114 -61
  204. package/dist/mcp/index.js +70 -40
  205. package/dist/{migrate-Dodel0IJ.js → migrate-B7oP_sQU.js} +35 -17
  206. package/dist/module-values-BJTBdo6y.js +107 -0
  207. package/dist/nest/index.d.ts +23 -13
  208. package/dist/nest/index.js +18 -11
  209. package/dist/next/client.d.ts +5 -2
  210. package/dist/next/client.js +1 -1
  211. package/dist/next/index.d.ts +79 -26
  212. package/dist/next/index.js +121 -10
  213. package/dist/next/plugin.d.ts +1 -1
  214. package/dist/next/plugin.js +4 -3
  215. package/dist/node/index.d.ts +5 -5
  216. package/dist/node/index.js +3 -3
  217. package/dist/{ocsf-BFp-PZZA.js → ocsf-TcjRBgIs.js} +15 -5
  218. package/dist/openai/index.d.ts +13 -7
  219. package/dist/openai/index.js +3 -3
  220. package/dist/openapi/index.d.ts +51 -30
  221. package/dist/openapi/index.js +2 -2
  222. package/dist/{openapi-ztVaux6j.js → openapi-BGeuunWC.js} +23 -14
  223. package/dist/{openapi-DMocl1bh.js → openapi-BIpw3Mb7.js} +4 -5
  224. package/dist/{openapi-Ddb4628T.js → openapi-BOsx0xn9.js} +33 -18
  225. package/dist/{operation-findings-kRcEp8lE.js → operation-findings-CXtFzlKJ.js} +3 -3
  226. package/dist/{operations-BNLes61x.d.ts → operations-Ci_rT6Uo.d.ts} +10 -7
  227. package/dist/orpc/index.d.ts +68 -14
  228. package/dist/orpc/index.js +62 -13
  229. package/dist/otel/index.d.ts +7 -4
  230. package/dist/otel/index.js +8 -5
  231. package/dist/{output-DgSDLrta.js → output-DV5dwOTs.js} +9 -5
  232. package/dist/output-files-BHOIlrfD.js +1 -0
  233. package/dist/{output-files-CCMdcFWb.js → output-files-BIQ_9pIs.js} +29 -17
  234. package/dist/ownership-DA5YdYTm.js +1059 -0
  235. package/dist/{parse-Ddhz2xf4.js → parse-1_ZheTW5.js} +16 -13
  236. package/dist/parse-local-manifest-CCmbhnxP.d.ts +10 -0
  237. package/dist/{parse-local-manifest-T1Q8X3A2.js → parse-local-manifest-DEiCF4ah.js} +19 -7
  238. package/dist/{parse-request-D_tUXG6M.js → parse-request-CwCZpyjV.js} +7 -8
  239. package/dist/{paths-DXSHAMIa.js → paths-CUvURzHp.js} +4 -1
  240. package/dist/pdp/index.d.ts +9 -6
  241. package/dist/pdp/index.js +20 -13
  242. package/dist/{peer-DOzzMfZL.js → peer-C9LvBCcb.js} +1 -1
  243. package/dist/{peer-12Q5I_RH.js → peer-Q0fuZ6hx.js} +9 -3
  244. package/dist/{permdock-BfWEeMqk.js → permdock-BvjivVb9.js} +200 -140
  245. package/dist/{permdock-Dco6dyCK.d.ts → permdock-CprAPN3w.d.ts} +260 -129
  246. package/dist/{permission-registry-DpPtSKNZ.js → permission-registry-B8tYxPIt.js} +23 -10
  247. package/dist/{permission-types-DhNEmoRG.d.ts → permission-types-CAY-GU7e.d.ts} +127 -41
  248. package/dist/{permissions-CoqCOfJ3.d.ts → permissions-Bx6UI8n1.d.ts} +6 -3
  249. package/dist/{permissions-CyH2MV_B.js → permissions-CVXmRILq.js} +3 -3
  250. package/dist/{permissions-DArULThq.js → permissions-CYcHj_w7.js} +8 -5
  251. package/dist/pg-DQTqRrou.js +60 -0
  252. package/dist/{pins-8ILTftC9.js → pins-nqarl3oE.js} +4 -1
  253. package/dist/{pkce-5h8NgMQJ.js → pkce-CnmmYqUZ.js} +1 -1
  254. package/dist/{policy-B7dg_yzu.d.ts → policy-BycVKnXv.d.ts} +5 -5
  255. package/dist/{policy-DaJy4nK4.js → policy-CLQ8__GF.js} +43 -23
  256. package/dist/{policy-from-catalog-DFWYkNdu.js → policy-from-catalog-CU3An8uP.js} +28 -25
  257. package/dist/{policy-module-CTlwMvLI.js → policy-module-xym9fnSq.js} +12 -6
  258. package/dist/{policy-types-B-F-qAZk.d.ts → policy-types-DGIO_gxq.d.ts} +782 -357
  259. package/dist/{postgres-store-BL9M_CA1.js → postgres-store-DcyrPS-r.js} +43 -16
  260. package/dist/{postgrest-r5faDIzD.js → postgrest-5Dr3W64L.js} +84 -86
  261. package/dist/{postgrest-CYacM_u7.d.ts → postgrest-D5nUGm-c.d.ts} +55 -35
  262. package/dist/powersync-B701tvhE.js +1 -0
  263. package/dist/{powersync-13odBwiM.js → powersync-Bg8u-JcR.js} +3 -3
  264. package/dist/{powersync-53ryOZip.js → powersync-CJrT1DSc.js} +127 -69
  265. package/dist/preset/index.d.ts +38 -28
  266. package/dist/preset/index.js +1 -1
  267. package/dist/{preset-CHTbd-DQ.js → preset-BjLzeFpp.js} +56 -32
  268. package/dist/{principal-source-pHneukrx.js → principal-source-C6N60GtM.js} +10 -10
  269. package/dist/prisma/index.d.ts +69 -41
  270. package/dist/prisma/index.js +21 -17
  271. package/dist/{problem-CTviyH5L.js → problem-BVLHFK33.js} +41 -21
  272. package/dist/{problem-details-cn5X30gZ.js → problem-details-CLDgX1KV.js} +13 -4
  273. package/dist/{problem-types-CJ2325SZ.js → problem-types-DSsRfONQ.js} +4 -1
  274. package/dist/{prompt-DwtVemER.js → prompt-BYc6drYW.js} +4 -1
  275. package/dist/protected-action-D8x73IGm.d.ts +58 -0
  276. package/dist/protected-action-DUYqb-Ma.js +80 -0
  277. package/dist/{protected-DXE3cQYg.js → protected-action-QEA8arRB.js} +48 -14
  278. package/dist/{provider-BQsTYYy0.js → provider-C55OGXJ7.js} +5 -4
  279. package/dist/{provider-Csk-THAn.d.ts → provider-DfLeek9O.d.ts} +1 -1
  280. package/dist/{provider-store-IgqQipCO.js → provider-store-CaTv00tr.js} +13 -9
  281. package/dist/{pull-CN5OLxrF.js → pull-2nJr0qg_.js} +12 -11
  282. package/dist/pull-C3EEGzSw.js +1 -0
  283. package/dist/{push-tVdG8dUL.js → push-Bn-lMEmI.js} +19 -13
  284. package/dist/{pushed-policy-CmYeSQqq.js → pushed-policy-CDuOL2de.js} +10 -7
  285. package/dist/{pushed-policy-BbcY9r_4.d.ts → pushed-policy-CryQheKq.d.ts} +12 -6
  286. package/dist/react/index.d.ts +9 -8
  287. package/dist/react/index.js +7 -6
  288. package/dist/react/provider-client.d.ts +1 -1
  289. package/dist/react/provider-client.js +1 -1
  290. package/dist/react-native/index.d.ts +94 -55
  291. package/dist/react-native/index.js +200 -61
  292. package/dist/{refs-CNJBiTFo.js → refs-C8BKxc_e.js} +2 -2
  293. package/dist/{relation-walk-3OyDBF0S.js → relation-walk-DK_gkgL7.js} +12 -9
  294. package/dist/{relations-BnCWnJGI.js → relations-BxvRvDHK.js} +3 -3
  295. package/dist/{replay-Du1tJjG7.js → replay-BU09ad4L.js} +1 -1
  296. package/dist/{replay-DCDD_ZfL.d.ts → replay-Bs9Df2fQ.d.ts} +1 -1
  297. package/dist/{request-context-BykKLmyE.js → request-context-Duzdf0cd.js} +8 -8
  298. package/dist/{request-schema-CMreVuFM.js → request-schema-DhX7UbfQ.js} +4 -1
  299. package/dist/resend/index.d.ts +34 -28
  300. package/dist/resend/index.js +29 -29
  301. package/dist/resolve-names-ConCSj1y.js +201 -0
  302. package/dist/{resource-relations-D_jw0BFx.js → resource-relations-8-pCScBO.js} +18 -9
  303. package/dist/{retire-Wj6dkyDE.js → retire-B2xffQgY.js} +15 -6
  304. package/dist/{revocations-R07lFBnX.d.ts → revocations-BaUXHM1N.d.ts} +6 -3
  305. package/dist/{rls-Ck_PocSp.js → rls-Ba9wN0SP.js} +13 -6
  306. package/dist/{rls-CxBZb4rZ.js → rls-Cx0dtsB7.js} +310 -128
  307. package/dist/{role-builder-C1VJzvcr.js → role-builder-BK2-T6oD.js} +41 -20
  308. package/dist/{row-conditions-h2HythXQ.js → row-conditions-BAGHOmVq.js} +4 -3
  309. package/dist/{rpc-Bk1bE-ch.js → rpc-vHIwyXCp.js} +8 -5
  310. package/dist/run-Ck22anC2.js +1 -0
  311. package/dist/{run-uLD2aWuO.js → run-PbRlXTfh.js} +26 -23
  312. package/dist/{run-ticket-BpNi7BCi.d.ts → run-ticket-B2o2Kxz8.d.ts} +29 -14
  313. package/dist/{run-ticket-B5d_63Ma.js → run-ticket-Dv7aF7Dk.js} +9 -9
  314. package/dist/{runtime-Vif3_-zf.js → runtime-BGnrOkVH.js} +5 -2
  315. package/dist/{saas-Az_Kz-4D.js → saas-DK4V-3Is.js} +42 -29
  316. package/dist/{scan-DSljDE1Y.js → scan-CRTj6fke.js} +1 -1
  317. package/dist/{schema-B4v0Qrac.js → schema-BOJjqlWL.js} +3 -2
  318. package/dist/{schema-gIcCx7zM.js → schema-BTsE1WRT.js} +8 -4
  319. package/dist/scim/index.d.ts +2 -2
  320. package/dist/scim/index.js +2 -2
  321. package/dist/{scim-C7JYhySg.js → scim-D8YupzX1.js} +2 -2
  322. package/dist/{scim-YNieBO1U.js → scim-jJBJ7g1Z.js} +33 -15
  323. package/dist/{scopes-BHsc-wp-.js → scopes-0Up_UA2t.js} +41 -23
  324. package/dist/server/index.d.ts +11 -11
  325. package/dist/server/index.js +12 -12
  326. package/dist/{server-Bnga6I50.js → server-3cVlTLde.js} +31 -31
  327. package/dist/{server-types-C4gZUEZy.d.ts → server-types-CyRN0-Cd.d.ts} +88 -46
  328. package/dist/{sha256-D9ihqmvd.js → sha256-C-4WXKIu.js} +4 -3
  329. package/dist/{shared-fMKOv8hP.js → shared-Afctg7B0.js} +65 -32
  330. package/dist/{shared-C8LjUdVU.js → shared-l0oGGetg.js} +9 -6
  331. package/dist/{signals-D3NcTKUS.js → signals-B1vHR3fN.js} +2 -2
  332. package/dist/{sink-Cp_Eot9W.d.ts → sink-B5zoUW_O.d.ts} +44 -20
  333. package/dist/{sink-BEZSlMS_.js → sink-D9_vh372.js} +32 -21
  334. package/dist/{skills-g_3BS9NC.js → skills-C9uKfSF5.js} +3 -3
  335. package/dist/{skills-Dcjw9_1C.js → skills-CQQcuGBi.js} +12 -8
  336. package/dist/{snapshot-CbGmYiJx.js → snapshot-CXlzi69u.js} +21 -18
  337. package/dist/{snapshot-cache-Pahd3IYJ.d.ts → snapshot-cache-BjAWkchD.d.ts} +21 -12
  338. package/dist/{snapshot-cache-DT2Kx1F8.js → snapshot-cache-Bx_4xC_6.js} +14 -11
  339. package/dist/solid/index.d.ts +55 -16
  340. package/dist/solid/index.js +46 -12
  341. package/dist/solid-start/index.d.ts +30 -12
  342. package/dist/solid-start/index.js +3 -3
  343. package/dist/{sources-B-zYB4GS.js → sources-CMAM-2A3.js} +46 -27
  344. package/dist/{sources-DEEuGb8S.d.ts → sources-CWG32C0G.d.ts} +126 -53
  345. package/dist/{sql-B96movIM.js → sql-0WjxIp9g.js} +28 -7
  346. package/dist/{sql-CDEPCA0g.d.ts → sql-B80DFdpG.d.ts} +2 -2
  347. package/dist/{src-DLFrtrrC.js → src-C_pi2Rnh.js} +292 -101
  348. package/dist/ssf/index.d.ts +3 -3
  349. package/dist/ssf/index.js +47 -35
  350. package/dist/{standard-webhooks-DgFFD-Ga.js → standard-webhooks-D67a3nzk.js} +5 -5
  351. package/dist/{standard-webhooks-B_qRg0ws.d.ts → standard-webhooks-DOYEuOLx.d.ts} +7 -7
  352. package/dist/{store-DSP9oGvh.js → store-RNFvaJJv.js} +32 -26
  353. package/dist/{store-options-B_poyYvg.js → store-options-Dil3lraY.js} +105 -15
  354. package/dist/stores-DZJvxFIZ.d.ts +59 -0
  355. package/dist/{stores-BqEuHC05.js → stores-DxZWDXCs.js} +42 -5
  356. package/dist/{stream-2Vwhl7Er.d.ts → stream-9y9qw51m.d.ts} +4 -3
  357. package/dist/{stream-CvdUS9V1.js → stream-CDvF0sJm.js} +5 -5
  358. package/dist/{style-Ds1gNm77.js → style-DblOtSga.js} +1 -1
  359. package/dist/{style-Cqo7-73x.js → style-Ds11Hmk4.js} +2 -1
  360. package/dist/{subject-settings-CkEwrw3W.js → subject-settings-8sH5HlII.js} +8 -4
  361. package/dist/{row-check-Dt35czLy.d.ts → subject-settings-vNW8qmUH.d.ts} +30 -18
  362. package/dist/supabase/index.d.ts +48 -38
  363. package/dist/supabase/index.js +5 -5
  364. package/dist/supabase/middleware.d.ts +19 -13
  365. package/dist/supabase/middleware.js +7 -7
  366. package/dist/{supabase--0aJdLEd.js → supabase-DnMMg5Fn.js} +79 -35
  367. package/dist/{supabase-Bqp7iIY2.js → supabase-SBs3MYUE.js} +3 -3
  368. package/dist/supabase-hook-C0FyEACZ.js +1 -0
  369. package/dist/{supabase-hook-Dg0SrQWR.js → supabase-hook-CrgU06WH.js} +175 -196
  370. package/dist/{supautils-MESd81bF.js → supautils-ByezN3b8.js} +385 -219
  371. package/dist/{support-session-Cna49-3f.js → support-session-BsmPCbz8.js} +21 -21
  372. package/dist/svelte/PermissionBoundary.svelte +2 -6
  373. package/dist/svelte/Protected.svelte +2 -8
  374. package/dist/svelte/index.d.ts +9 -8
  375. package/dist/svelte/index.js +10 -9
  376. package/dist/svelte/runtime.d.ts +4 -4
  377. package/dist/svelte/runtime.js +4 -4
  378. package/dist/svelte/source.d.ts +9 -8
  379. package/dist/svelte/source.js +6 -5
  380. package/dist/sveltekit/index.d.ts +30 -12
  381. package/dist/sveltekit/index.js +2 -2
  382. package/dist/{ownership-Z2LpxsGa.js → tables-BqrxBCir.js} +641 -1104
  383. package/dist/tanstack-start/index.d.ts +22 -10
  384. package/dist/tanstack-start/index.js +2 -2
  385. package/dist/{target-Bw37TFNA.js → target-qdEAnnhU.js} +6 -6
  386. package/dist/{tenancy-CmeBQ6Nv.js → tenancy-5d1zVBvK.js} +25 -19
  387. package/dist/terminal/index.d.ts +23 -14
  388. package/dist/terminal/index.js +17 -20
  389. package/dist/testing/core.d.ts +1 -1
  390. package/dist/testing/core.js +1 -1
  391. package/dist/testing/fixtures/index.d.ts +8 -5
  392. package/dist/testing/fixtures/index.js +78 -17
  393. package/dist/testing/index.d.ts +225 -141
  394. package/dist/testing/index.js +352 -234
  395. package/dist/testing/saas/index.d.ts +43 -27
  396. package/dist/testing/saas/index.js +2 -2
  397. package/dist/testing/saas/permissions.d.ts +1 -1
  398. package/dist/testing/saas/permissions.js +1 -1
  399. package/dist/{text-diff-DhITNCnD.js → text-diff-BtfSmdUo.js} +2 -2
  400. package/dist/{thenable-yD7SabqG.js → thenable-BNSM1U2R.js} +12 -3
  401. package/dist/{time-DkWjdL98.js → time-nR1JesoH.js} +32 -8
  402. package/dist/{token-2qYDvXz2.js → token-DC9EQiet.js} +14 -12
  403. package/dist/{tool-refusal-reAhIzdl.js → tool-refusal-Qpjs_W6M.js} +5 -2
  404. package/dist/trpc/index.d.ts +11 -8
  405. package/dist/trpc/index.js +15 -9
  406. package/dist/type-helpers-c7Xo_2Cu.d.ts +50 -0
  407. package/dist/{types-CfiKC5aN.d.ts → types-B2efzoSX.d.ts} +14 -11
  408. package/dist/{types-CIeZcG8v.d.ts → types-B6ExllNo.d.ts} +2 -2
  409. package/dist/{types-DBHftjgS.d.ts → types-BB-zWDcR.d.ts} +45 -33
  410. package/dist/{types-BfVmNJO5.d.ts → types-BMVDHvI0.d.ts} +128 -50
  411. package/dist/{types-DXmwu78Z.d.ts → types-CEinc15V.d.ts} +31 -14
  412. package/dist/{types-g7Oy6Zg4.d.ts → types-CN0LsqbK.d.ts} +47 -24
  413. package/dist/{types-CeIscIKp.d.ts → types-CWBsAwqn.d.ts} +23 -12
  414. package/dist/{types-DqzsnlSA.js → types-CcUXciSj.js} +17 -5
  415. package/dist/{types-BWZybqs9.d.ts → types-CzOeVvcC.d.ts} +384 -203
  416. package/dist/{types-DC44-hqb.d.ts → types-DLvhVm1r.d.ts} +59 -32
  417. package/dist/{types-D3A19w4A.d.ts → types-DlelvQk4.d.ts} +22 -13
  418. package/dist/{types-cTos-H7p.d.ts → types-DsHGPtkR.d.ts} +68 -32
  419. package/dist/{types-BXMYB7BY.d.ts → types-ZzRGoViD.d.ts} +77 -24
  420. package/dist/{types-CQVEQawv.d.ts → types-rCRV4Ge-.d.ts} +24 -14
  421. package/dist/types-tQB2CEnY.d.ts +262 -0
  422. package/dist/unplugin/index.d.ts +1 -1
  423. package/dist/unplugin/index.js +2 -2
  424. package/dist/usage-0hjZPIRX.js +1 -0
  425. package/dist/{usage-Bybmck7f.js → usage-B9EtHWLa.js} +50 -26
  426. package/dist/{usage-CDaLXCfL.js → usage-CBzgwfIs.js} +2 -2
  427. package/dist/{validation-error-ZfUHbKvf.js → validation-error-CYg2kJEw.js} +4 -1
  428. package/dist/{validation-error-CQpoquwj.d.ts → validation-error-uvp-kyfO.d.ts} +5 -2
  429. package/dist/{validity-CZ7-y0Cj.js → validity-Buc7w8E9.js} +13 -10
  430. package/dist/{verifier-DHuh-okk.js → verifier-DUV6pLqZ.js} +10 -4
  431. package/dist/{verify-pe8rL_Qw.js → verify-DlUcTDBz.js} +148 -487
  432. package/dist/version-DMQ0dnN5.js +48 -0
  433. package/dist/version-DizhmD72.js +1 -0
  434. package/dist/{views-BB8E9dTP.js → views-CD8wuL4Z.js} +19 -6
  435. package/dist/{vocabulary-Bg3eeT2H.d.ts → vocabulary-DEJ5j4mR.d.ts} +7 -4
  436. package/dist/vue/index.d.ts +71 -22
  437. package/dist/vue/index.js +50 -13
  438. package/dist/{waiter-DwEyouan.d.ts → waiter-CqUKX6CY.d.ts} +13 -10
  439. package/dist/{waiter-BGUtGYoU.js → waiter-aBLM63_f.js} +1 -1
  440. package/dist/{watch-C-4VmFlL.js → watch-BFDKqmUa.js} +8 -8
  441. package/dist/watch-ClLuO2TL.js +1 -0
  442. package/dist/webmcp/index.d.ts +11 -11
  443. package/dist/webmcp/index.js +8 -5
  444. package/dist/{where-scope-wq2coopv.js → where-scope-DlCdCM_8.js} +24 -18
  445. package/dist/{who-can-BwNsI_Js.js → who-can-BoDJm0Nc.js} +23 -20
  446. package/dist/workflow/index.d.ts +3 -3
  447. package/dist/workflow/index.js +13 -13
  448. package/dist/workflow-sdk/index.d.ts +19 -13
  449. package/dist/workflow-sdk/index.js +6 -6
  450. package/dist/{wrap-CiSc_KCq.js → wrap-B2wziJI_.js} +4 -4
  451. package/dist/{wrap-B6R0cMRL.d.ts → wrap-DxXB54Wu.d.ts} +8 -5
  452. package/package.json +8 -8
  453. package/schemas/catalog-v1.json +3 -0
  454. package/schemas/supabase-manifest-v1.json +33 -1
  455. package/skills/permdock-credentials/references/tokens-keys-links.md +8 -6
  456. package/skills/permdock-data/references/queries-and-rls.md +2 -1
  457. package/skills/permdock-tenancy/references/ownership-and-custom-roles.md +2 -2
  458. package/skills/permdock-wire/references/adapters.md +16 -23
  459. package/dist/catalog-BCCjSAdH.js +0 -1
  460. package/dist/collect-k_Dulxr5.js +0 -1
  461. package/dist/config-CoQHDrDi.js +0 -166
  462. package/dist/denied-text-D4qkEtFz.d.ts +0 -19
  463. package/dist/fields-ClcQLrVc.js +0 -238
  464. package/dist/generate-CNU1pIOo.js +0 -171
  465. package/dist/headers-BIjfMaoC.js +0 -8
  466. package/dist/headers-CIbDTUTK.d.ts +0 -7
  467. package/dist/load-DrMHXzgN.js +0 -1
  468. package/dist/output-files-DPAY7-GX.js +0 -1
  469. package/dist/package-root-Dk_ETdkp.js +0 -31
  470. package/dist/parse-local-manifest-e4mdwAKd.d.ts +0 -10
  471. package/dist/policies-B2lZIurj.js +0 -295
  472. package/dist/powersync-CExtTLyA.js +0 -1
  473. package/dist/problem-details-Tcfmj3bV.d.ts +0 -7
  474. package/dist/protected-BwZYL1X_.d.ts +0 -39
  475. package/dist/pull-Cty6Ovyu.js +0 -1
  476. package/dist/run-Bz7DXGEv.js +0 -1
  477. package/dist/stores-BAZwSYZA.d.ts +0 -31
  478. package/dist/supabase-hook-DJxC4PoP.js +0 -1
  479. package/dist/types-CKV71kKh.d.ts +0 -172
  480. package/dist/usage-y-kBNdqs.js +0 -1
  481. package/dist/version-CEbQ5UeM.js +0 -18
  482. package/dist/version-DXkYUISx.js +0 -1
  483. package/dist/watch-Bd9mx3rd.js +0 -1
@@ -1,46 +1,47 @@
1
1
  import { r as isRecord } from "../compact-CAf557ZB.js";
2
- import { n as freezeDeep } from "../freeze-CrU8nQeX.js";
3
- import { i as principal } from "../refs-CNJBiTFo.js";
4
- import { n as role, r as allow } from "../role-builder-C1VJzvcr.js";
5
- import { A as memoryCustomRoleSource, S as memoryLimitStore, T as approvalPoliciesFor, d as snapshotFor, x as limits } from "../src-DLFrtrrC.js";
2
+ import { n as freezeDeep } from "../freeze-jjan0lCv.js";
3
+ import { i as principal } from "../refs-C8BKxc_e.js";
4
+ import { n as role, r as allow } from "../role-builder-BK2-T6oD.js";
5
+ import { C as memoryLimitStore, E as approvalPoliciesFor, S as limits, d as snapshotFor, j as memoryCustomRoleSource } from "../src-C_pi2Rnh.js";
6
6
  import { t as memoryRevocationFeed } from "../revocations-Bhr0aMIC.js";
7
- import { n as loadPrincipalByIdentity, t as loadPrincipal } from "../principal-source-pHneukrx.js";
8
- import { v as resource } from "../permission-registry-DpPtSKNZ.js";
9
- import { d as isoNow, f as nowMillis, p as nowSeconds, u as isoAt } from "../time-DkWjdL98.js";
10
- import { r as parseAutomation } from "../automation-ySsxp_Yp.js";
11
- import { f as scopeList, o as normalizeMemberships } from "../scopes-BHsc-wp-.js";
12
- import { u as evaluateCondition } from "../delegation-C5rOdTp5.js";
13
- import { a as authenticated } from "../grantee-BrRANrpT.js";
14
- import { n as definePolicy } from "../policy-DaJy4nK4.js";
15
- import { t as byCodePoint } from "../compare-pfyVnBjE.js";
16
- import { c as mergeHostedGrants, l as parsePolicyDocument } from "../hosted-XBgU6RGT.js";
17
- import { t as definePermissions } from "../permissions-CyH2MV_B.js";
18
- import { T as validateCustomRole } from "../evaluate-B_oqFbWC.js";
19
- import { n as parseSnapshot } from "../snapshot-CbGmYiJx.js";
20
- import { n as fromSnapshot } from "../from-snapshot-Bz469dIh.js";
21
- import { t as getPermDock } from "../permdock-BfWEeMqk.js";
22
- import { t as APPROVAL_HEADER } from "../types-DqzsnlSA.js";
23
- import { i as memoryApprovalStore } from "../store-DSP9oGvh.js";
24
- import { t as catalogFingerprint } from "../catalog-fingerprint-C144oW4M.js";
25
- import { s as parseCredential } from "../credential-CIM7wHwA.js";
26
- import { s as problemFromDecision } from "../problem-CTviyH5L.js";
27
- import { o as resolveApproval } from "../helpers-DY3vXuGs.js";
28
- import { t as APPROVAL_REQUEST_SCHEMA } from "../request-schema-CMreVuFM.js";
29
- import { t as catalogSchema } from "../schema-B4v0Qrac.js";
30
- import { c as parseApiKey } from "../server-Bnga6I50.js";
31
- import { n as discoverAuthorizationServer } from "../device-BARQ8eYG.js";
32
- import { t as CONNECTOR_SCHEMA } from "../connector-schema-_VCSsdtD.js";
33
- import { l as sha256Hex, n as scimHandler, t as directoryMembershipSource } from "../scim-YNieBO1U.js";
34
- import { i as cloudEndpoints, n as cloud, s as approverHeaders, t as bearerChallenge } from "../challenge-nGWma08S.js";
35
- import { t as supabaseMembershipsBudget } from "../budget-NbEtbJC_.js";
36
- import { t as supabaseManifestSchema } from "../manifest-schema-Cv492Qev.js";
37
- import { t as PUSHED_POLICY_SCHEMA } from "../pushed-policy-CmYeSQqq.js";
38
- import { i as policyMatrixLayout, n as testRlsParity, r as policyMatrix, t as testOrmParity } from "../core-B5-w6Kw9.js";
39
- import { i as saasPermissions } from "../permissions-DArULThq.js";
40
- 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-Az_Kz-4D.js";
41
- import { t as POLICY_NOT_PUBLISHED } from "../problem-types-CJ2325SZ.js";
7
+ import { n as loadPrincipalByIdentity, t as loadPrincipal } from "../principal-source-C6N60GtM.js";
8
+ import { v as resource } from "../permission-registry-B8tYxPIt.js";
9
+ import { d as isoNow, f as nowMillis, p as nowSeconds, u as isoAt } from "../time-nR1JesoH.js";
10
+ import { r as parseAutomation } from "../automation-x3KEUusw.js";
11
+ import { f as scopeList, o as normalizeMemberships } from "../scopes-0Up_UA2t.js";
12
+ import { u as evaluateCondition } from "../delegation-CDB6_keF.js";
13
+ import { a as authenticated } from "../grantee-Dke-9rd1.js";
14
+ import { t as byCodePoint } from "../compare-DTfyUunF.js";
15
+ import { r as definePolicy } from "../policy-CLQ8__GF.js";
16
+ import { c as mergeHostedGrants, l as parsePolicyDocument } from "../hosted-D0IzESu_.js";
17
+ import { t as definePermissions } from "../permissions-CVXmRILq.js";
18
+ import { T as validateCustomRole } from "../evaluate-BAmf_AQd.js";
19
+ import { n as parseSnapshot } from "../snapshot-CXlzi69u.js";
20
+ import { n as fromSnapshot } from "../from-snapshot-DCakWRsr.js";
21
+ import { t as getPermDock } from "../permdock-BvjivVb9.js";
22
+ import { t as APPROVAL_HEADER } from "../types-CcUXciSj.js";
23
+ import { i as memoryApprovalStore } from "../store-RNFvaJJv.js";
24
+ import { t as catalogFingerprint } from "../catalog-fingerprint-e6aCWosn.js";
25
+ import { s as parseCredential } from "../credential-CyyyvCsL.js";
26
+ import { c as problemFromDecision } from "../problem-BVLHFK33.js";
27
+ import { o as resolveApproval } from "../helpers-DJicaG6f.js";
28
+ import { t as APPROVAL_REQUEST_SCHEMA } from "../request-schema-DhX7UbfQ.js";
29
+ import { t as catalogSchema } from "../schema-BOJjqlWL.js";
30
+ import { c as parseApiKey } from "../server-3cVlTLde.js";
31
+ import { n as discoverAuthorizationServer } from "../device-BwbJNmb2.js";
32
+ import { t as CONNECTOR_SCHEMA } from "../connector-schema-CYLQNMYq.js";
33
+ import { l as sha256Hex, n as scimHandler, t as directoryMembershipSource } from "../scim-jJBJ7g1Z.js";
34
+ import { c as quoteSqlTable, o as quoteSqlIdent } from "../sql-0WjxIp9g.js";
35
+ import { i as cloudEndpoints, n as cloud, s as approverHeaders, t as bearerChallenge } from "../challenge-DImNcR7B.js";
36
+ import { t as supabaseMembershipsBudget } from "../budget-BELja5A9.js";
37
+ import { t as supabaseManifestSchema } from "../manifest-schema-2r37XRhD.js";
38
+ import { t as PUSHED_POLICY_SCHEMA } from "../pushed-policy-CDuOL2de.js";
39
+ import { i as policyMatrixLayout, n as testRlsParity, r as policyMatrix, t as testOrmParity } from "../core-DzVINFbU.js";
40
+ import { i as saasPermissions } from "../permissions-CYcHj_w7.js";
41
+ 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-DK4V-3Is.js";
42
+ import { t as POLICY_NOT_PUBLISHED } from "../problem-types-DSsRfONQ.js";
42
43
  import { t as require__2020 } from "../2020-CJbO8Bvz.js";
43
- import { afterAll, beforeAll, describe, expect, expectTypeOf, it, vi } from "vitest";
44
+ import { afterAll, assert, beforeAll, describe, expect, expectTypeOf, it, vi } from "vitest";
44
45
  //#region src/testing/describe-policy.ts
45
46
  /** `policyMatrix` under Vitest: one test per cell, plus the exhaustive check. */
46
47
  function describePolicy(policy, config) {
@@ -59,7 +60,7 @@ function describePolicy(policy, config) {
59
60
  it(title, () => {
60
61
  const decided = state.report?.cells.find((item) => item.name === cell.name);
61
62
  expect(decided, `cell ${cell.name} was not decided`).toBeDefined();
62
- expect(decided?.failures).toEqual([]);
63
+ expect(decided?.failures).toStrictEqual([]);
63
64
  });
64
65
  }
65
66
  });
@@ -79,8 +80,8 @@ async function outcomes(policy, entry, options) {
79
80
  };
80
81
  }
81
82
  /**
82
- * Asserts that `fromSnapshot(permdock.snapshot())` never grants what the
83
- * server denies, and matches it exactly unless a case is marked `stricter`.
83
+ * Asserts that `fromSnapshot(permdock.snapshot())` never grants what the server
84
+ * denies, and matches it exactly unless a case is marked `stricter`.
84
85
  */
85
86
  function testClientParity(policy, cases, options = {}) {
86
87
  for (const entry of cases) it(`client parity: ${entry.name}`, async () => {
@@ -95,9 +96,9 @@ function testClientParity(policy, cases, options = {}) {
95
96
  //#endregion
96
97
  //#region src/testing/legacy-parity.ts
97
98
  /**
98
- * Asserts that the policy answers each case as the application's legacy
99
- * check does, or as the case's `expect` says where the difference is
100
- * intended. Run it before enforcing a permission with `shadowMode`.
99
+ * Asserts that the policy answers each case as the application's legacy check
100
+ * does, or as the case's `expect` says where the difference is intended. Run it
101
+ * before enforcing a permission with `shadowMode`.
101
102
  */
102
103
  function testLegacyParity(policy, legacy, cases) {
103
104
  for (const entry of cases) it(`legacy parity: ${entry.name}`, async () => {
@@ -111,7 +112,7 @@ function testLegacyParity(policy, legacy, cases) {
111
112
  expect({
112
113
  permission: entry.permission.key,
113
114
  granted: ours
114
- }).toEqual({
115
+ }).toStrictEqual({
115
116
  permission: entry.permission.key,
116
117
  granted: entry.expect ?? theirs
117
118
  });
@@ -217,9 +218,9 @@ function unreachable() {
217
218
  }
218
219
  /**
219
220
  * Race and cache scenarios for a client snapshot store: tenant switches,
220
- * `replace` and `refresh`, logout and a second user during a refresh, stale
221
- * and signed snapshots, and endpoint answers cached per tenant. Runs against
222
- * the saas domain; `createStore` wraps the store an adapter ships.
221
+ * `replace` and `refresh`, logout and a second user during a refresh, stale and
222
+ * signed snapshots, and endpoint answers cached per tenant. Runs against the
223
+ * saas domain; `createStore` wraps the store an adapter ships.
223
224
  */
224
225
  function testClientStore(name, createStore) {
225
226
  const acmeProject = saasProject("p1");
@@ -251,7 +252,7 @@ function testClientStore(name, createStore) {
251
252
  fetch: net.fetch
252
253
  });
253
254
  await store.get().refresh({ tenant: "globex" });
254
- expect(net.calls.map((call) => call.url)).toEqual(["/api/snapshot?v=1&tenant=globex"]);
255
+ expect(net.calls.map((call) => call.url)).toStrictEqual(["/api/snapshot?v=1&tenant=globex"]);
255
256
  expect(store.get().subject.principal?.tenant).toBe("acme");
256
257
  expect(store.get().can(p.project.update, acmeProject)).toBe(true);
257
258
  expect(store.get().status()).toBe("stale");
@@ -499,15 +500,36 @@ function testClientStore(name, createStore) {
499
500
  async function snapshotFixture(policy, subject, options = {}) {
500
501
  const instance = await getPermDock(policy, subject, options.tenant === void 0 ? {} : { tenant: options.tenant });
501
502
  const target = options.simulated === true ? instance.simulate({}) : instance;
502
- if (Array.isArray(target)) throw new Error("PermDock: snapshotFixture expected a PermDock instance");
503
+ if (Array.isArray(target)) throw new TypeError("PermDock: snapshotFixture expected a PermDock instance");
503
504
  const snapshot = options.include === void 0 && options.tenants === void 0 ? target.snapshot() : target.snapshot({
504
505
  ...options.include === void 0 ? {} : { include: options.include },
505
506
  ...options.tenants === void 0 ? {} : { tenants: options.tenants }
506
507
  });
507
- if (typeof snapshot === "string" || snapshot instanceof Promise) throw new Error("PermDock: snapshotFixture expected a JSON snapshot");
508
+ if (typeof snapshot === "string" || snapshot instanceof Promise) throw new TypeError("PermDock: snapshotFixture expected a JSON snapshot");
508
509
  return snapshot;
509
510
  }
510
511
  //#endregion
512
+ //#region src/testing/seed-rows.ts
513
+ /**
514
+ * Inserts `factories.*` rows through the `query` function `testRlsParity`
515
+ * takes, one parameterised `insert` per row with the row's own keys as quoted
516
+ * column names. `undefined` fields are left to the column default. Run it as
517
+ * the table owner, before RLS applies. Resolves to the number of rows
518
+ * inserted.
519
+ */
520
+ async function seedRows(query, rows) {
521
+ let inserted = 0;
522
+ for (const [table, list] of Object.entries(rows)) {
523
+ const target = quoteSqlTable(table);
524
+ for (const row of list) {
525
+ const columns = Object.keys(row).filter((key) => row[key] !== void 0);
526
+ await query(columns.length === 0 ? `insert into ${target} default values` : `insert into ${target} (${columns.map((column) => quoteSqlIdent(column)).join(", ")}) values (${columns.map((_, index) => `$${String(index + 1)}`).join(", ")})`, columns.map((column) => row[column]));
527
+ inserted += 1;
528
+ }
529
+ }
530
+ return inserted;
531
+ }
532
+ //#endregion
511
533
  //#region src/testing/http-adapter/domain.ts
512
534
  function project$1(id) {
513
535
  const row = saasSeed.projects.find((candidate) => candidate.id === id);
@@ -828,11 +850,12 @@ function testHttpAdapter(options) {
828
850
  return eventStream(await mounted.fetch(new Request(`http://app.test/${org}/projects/${id}/events`, { headers })));
829
851
  };
830
852
  scenario("tenant", "resolves the tenant from the path on every protect", async () => {
831
- expect((await send("alice", {
853
+ const { status } = await send("alice", {
832
854
  op: "project.get",
833
855
  org: "acme",
834
856
  id: "p2"
835
- })).status).toBe(200);
857
+ });
858
+ expect(status).toBe(200);
836
859
  expect((await send("alice", {
837
860
  op: "project.get",
838
861
  org: "globex",
@@ -855,11 +878,12 @@ function testHttpAdapter(options) {
855
878
  })).status).toBe(401);
856
879
  });
857
880
  scenario("roles", "applies the role held in the requested org", async () => {
858
- expect((await send("alice", {
881
+ const { status } = await send("alice", {
859
882
  op: "project.update",
860
883
  org: "acme",
861
884
  id: "p1"
862
- })).status).toBe(200);
885
+ });
886
+ expect(status).toBe(200);
863
887
  expect((await send("alice", {
864
888
  op: "project.update",
865
889
  org: "globex",
@@ -884,11 +908,12 @@ function testHttpAdapter(options) {
884
908
  name: "Contract",
885
909
  archived: false
886
910
  };
887
- expect((await send("dave", {
911
+ const { status } = await send("dave", {
888
912
  op: "project.create",
889
913
  org: "acme",
890
914
  body
891
- })).status).toBe(201);
915
+ });
916
+ expect(status).toBe(201);
892
917
  expect((await send("hank", {
893
918
  op: "project.create",
894
919
  org: "acme",
@@ -896,29 +921,34 @@ function testHttpAdapter(options) {
896
921
  })).status).toBe(403);
897
922
  });
898
923
  scenario("plans", "gates a feature on the plan of the requested org", async () => {
899
- expect((await send("erin", {
924
+ const { status } = await send("erin", {
900
925
  op: "analytics.read",
901
926
  org: "globex"
902
- })).status).toBe(200);
927
+ });
928
+ expect(status).toBe(200);
903
929
  const upgrade = await send("erin", {
904
930
  op: "analytics.read",
905
931
  org: "acme"
906
932
  });
907
933
  expect(upgrade.status).toBe(403);
908
- expect(new Set(reasonsOf(upgrade.body))).toEqual(/* @__PURE__ */ new Set(["not-entitled"]));
934
+ expect(new Set(reasonsOf(upgrade.body))).toStrictEqual(/* @__PURE__ */ new Set(["not-entitled"]));
909
935
  });
910
936
  scenario("expired", "ignores an expired membership", async () => {
911
- expect((await send("frank", {
937
+ const { status } = await send("frank", {
912
938
  op: "project.get",
913
939
  org: "acme",
914
940
  id: "p1"
915
- })).status).toBe(403);
941
+ });
942
+ expect(status).toBe(403);
916
943
  });
917
944
  scenario("limits", "counts a quota per subject and tenant", async () => {
918
- for (let index = 0; index < 5; index += 1) expect((await send("erin", {
919
- op: "apiKey.create",
920
- org: "acme"
921
- })).status).toBe(201);
945
+ for (let index = 0; index < 5; index += 1) {
946
+ const { status } = await send("erin", {
947
+ op: "apiKey.create",
948
+ org: "acme"
949
+ });
950
+ expect(status).toBe(201);
951
+ }
922
952
  const exhausted = await send("erin", {
923
953
  op: "apiKey.create",
924
954
  org: "acme"
@@ -938,11 +968,12 @@ function testHttpAdapter(options) {
938
968
  name: "New",
939
969
  archived: false
940
970
  };
941
- expect((await send("bob", {
971
+ const { status } = await send("bob", {
942
972
  op: "project.create",
943
973
  org: "acme",
944
974
  body: valid
945
- })).status).toBe(201);
975
+ });
976
+ expect(status).toBe(201);
946
977
  const invalid = await send("bob", {
947
978
  op: "project.create",
948
979
  org: "acme",
@@ -978,12 +1009,13 @@ function testHttpAdapter(options) {
978
1009
  "title",
979
1010
  "permission",
980
1011
  "denials"
981
- ]) expect(field(denied.body, key)).toEqual(field(fromProtect.body, key));
982
- expect((await send("bob", {
1012
+ ]) expect(field(denied.body, key)).toStrictEqual(field(fromProtect.body, key));
1013
+ const { status } = await send("bob", {
983
1014
  op: "project.delete",
984
1015
  org: "acme",
985
1016
  id: "p3"
986
- })).status).toBe(204);
1017
+ });
1018
+ expect(status).toBe(204);
987
1019
  expect((await send("bob", {
988
1020
  op: "project.delete",
989
1021
  org: "acme",
@@ -998,7 +1030,7 @@ function testHttpAdapter(options) {
998
1030
  expect(asked.status).toBe(403);
999
1031
  expect(field(asked.body, "type")).toBe("https://permdock.com/problems/approval-required");
1000
1032
  const token = field(asked.body, "token");
1001
- expect(typeof token).toBe("string");
1033
+ expect(token).toBeTypeOf("string");
1002
1034
  await resolveApproval(domain.store, String(token), {
1003
1035
  status: "approved",
1004
1036
  by: await approverSubject("carol", "acme")
@@ -1017,11 +1049,12 @@ function testHttpAdapter(options) {
1017
1049
  })).status).toBe(204);
1018
1050
  });
1019
1051
  scenario("stale-approval", "ignores an approval header meant for another request", async () => {
1020
- expect((await send("bob", {
1052
+ const { status } = await send("bob", {
1021
1053
  op: "project.get",
1022
1054
  org: "acme",
1023
1055
  id: "p1"
1024
- }, "pd1.not-a-real-token")).status).toBe(200);
1056
+ }, "pd1.not-a-real-token");
1057
+ expect(status).toBe(200);
1025
1058
  });
1026
1059
  scenario("evaluations", "answers the decision endpoint in the path tenant", async () => {
1027
1060
  const result = await send("bob", {
@@ -1045,7 +1078,7 @@ function testHttpAdapter(options) {
1045
1078
  });
1046
1079
  expect(result.status).toBe(200);
1047
1080
  const rows = field(result.body, "evaluations");
1048
- expect(Array.isArray(rows) ? rows.map((row) => field(row, "decision")) : rows).toEqual([true, false]);
1081
+ expect(Array.isArray(rows) ? rows.map((row) => field(row, "decision")) : rows).toStrictEqual([true, false]);
1049
1082
  });
1050
1083
  scenario("upload", "leaves a multipart body to the framework parser", async () => {
1051
1084
  const file = {
@@ -1059,22 +1092,24 @@ function testHttpAdapter(options) {
1059
1092
  file
1060
1093
  });
1061
1094
  expect(uploaded.status).toBe(201);
1062
- expect(uploaded.body).toEqual({
1095
+ expect(uploaded.body).toStrictEqual({
1063
1096
  name: "notes.txt",
1064
1097
  size: 5
1065
1098
  });
1066
- expect((await send("bob", {
1099
+ const { status } = await send("bob", {
1067
1100
  op: "project.upload",
1068
1101
  org: "acme",
1069
1102
  id: "p2",
1070
1103
  file
1071
- })).status).toBe(403);
1104
+ });
1105
+ expect(status).toBe(403);
1072
1106
  });
1073
1107
  scenario("sub-app", "protects a route inside a sub-app", async () => {
1074
- expect((await send("alice", {
1108
+ const { status } = await send("alice", {
1075
1109
  op: "admin.members",
1076
1110
  org: "acme"
1077
- })).status).toBe(200);
1111
+ });
1112
+ expect(status).toBe(200);
1078
1113
  expect((await send("bob", {
1079
1114
  op: "admin.members",
1080
1115
  org: "acme"
@@ -1091,7 +1126,7 @@ function testHttpAdapter(options) {
1091
1126
  org: entry.org,
1092
1127
  id: entry.id
1093
1128
  })).status));
1094
- expect(statuses).toEqual(calls.map((entry) => entry.status));
1129
+ expect(statuses).toStrictEqual(calls.map((entry) => entry.status));
1095
1130
  });
1096
1131
  scenario("stream-revoked", "closes an open stream when the session is revoked", async () => {
1097
1132
  expect((await openStream(null, "acme", "p1")).status).toBe(401);
@@ -1146,7 +1181,7 @@ function testHttpAdapter(options) {
1146
1181
  expect(frame?.event).toBe("message");
1147
1182
  ids.push(String(field(JSON.parse(frame?.data ?? "{}"), "id")));
1148
1183
  }
1149
- expect(new Set(ids)).toEqual(/* @__PURE__ */ new Set([
1184
+ expect(new Set(ids)).toStrictEqual(/* @__PURE__ */ new Set([
1150
1185
  "p1",
1151
1186
  "p3",
1152
1187
  "p4"
@@ -1473,10 +1508,11 @@ function testAgentRuntime(options) {
1473
1508
  const listed = await agent().allowedOperations(alice);
1474
1509
  expect(listed.has("project_read")).toBe(true);
1475
1510
  expect(listed.has("drop_database")).toBe(false);
1476
- expect([...await agent().allowedOperations(mallory)]).toEqual([]);
1511
+ expect([...await agent().allowedOperations(mallory)]).toStrictEqual([]);
1477
1512
  });
1478
1513
  scenario("model-gate", "grants a model by its permission and denies one the map does not name", async () => {
1479
- expect((await agent().decideModel("frontier", erin)).outcome).toBe("granted");
1514
+ const { outcome } = await agent().decideModel("frontier", erin);
1515
+ expect(outcome).toBe("granted");
1480
1516
  expect((await agent().decideModel("frontier", alice)).outcome).toBe("denied");
1481
1517
  expect((await agent().decideModel("unlisted", erin)).outcome).toBe("denied");
1482
1518
  expect((await agent().decideModel("standard", {
@@ -1485,15 +1521,15 @@ function testAgentRuntime(options) {
1485
1521
  })).outcome).toBe("denied");
1486
1522
  });
1487
1523
  scenario("permitted-models", "returns the granted models in declaration order", async () => {
1488
- expect(await agent().permittedModels(erin)).toEqual(["standard", "frontier"]);
1489
- expect(await agent().permittedModels(alice)).toEqual(["standard"]);
1490
- expect(await agent().permittedModels(mallory)).toEqual([]);
1524
+ expect(await agent().permittedModels(erin)).toStrictEqual(["standard", "frontier"]);
1525
+ expect(await agent().permittedModels(alice)).toStrictEqual(["standard"]);
1526
+ expect(await agent().permittedModels(mallory)).toStrictEqual([]);
1491
1527
  });
1492
1528
  scenario("results-filter", "keeps the rows the results permission grants, and none for an unknown operation", async () => {
1493
1529
  const rows = projects("p1", "g1", "p2");
1494
- expect((await agent().filterResults("project_search", rows, alice)).map((row) => row.id)).toEqual(["p1", "p2"]);
1495
- expect(await agent().filterResults("project_search", rows, mallory)).toEqual([]);
1496
- expect(await agent().filterResults("drop_database", rows, alice)).toEqual([]);
1530
+ expect((await agent().filterResults("project_search", rows, alice)).map((row) => row.id)).toStrictEqual(["p1", "p2"]);
1531
+ expect(await agent().filterResults("project_search", rows, mallory)).toStrictEqual([]);
1532
+ expect(await agent().filterResults("drop_database", rows, alice)).toStrictEqual([]);
1497
1533
  });
1498
1534
  scenario("gateway-options", "attributes gateway usage to the principal, and to nobody for an anonymous call", async () => {
1499
1535
  const attributed = await agent().gatewayOptions(alice);
@@ -1543,7 +1579,7 @@ function testAuthzen(handle, options) {
1543
1579
  }
1544
1580
  for (const [index, vector] of (options.vectors.evaluations ?? []).entries()) it(`evaluations ${index}: ${vector.request.evaluations.length} items`, async () => {
1545
1581
  const body = await post("/access/v1/evaluations", vector.request);
1546
- expect(body.evaluations.map((row) => ({ decision: row.decision }))).toEqual(vector.expected);
1582
+ expect(body.evaluations.map((row) => ({ decision: row.decision }))).toStrictEqual(vector.expected);
1547
1583
  });
1548
1584
  const search = options.vectors.search ?? {};
1549
1585
  for (const kind of [
@@ -1552,10 +1588,13 @@ function testAuthzen(handle, options) {
1552
1588
  "action"
1553
1589
  ]) for (const [index, vector] of (search[kind] ?? []).entries()) it(`search/${kind} ${index}`, async () => {
1554
1590
  const body = await post(`/access/v1/search/${kind}`, vector.request);
1555
- expect(body.results.map(sortKey).toSorted()).toEqual(vector.expected.results.map(sortKey).toSorted());
1591
+ expect(body.results.map(sortKey).toSorted()).toStrictEqual(vector.expected.results.map(sortKey).toSorted());
1556
1592
  });
1557
1593
  }
1558
- /** The AuthZEN interop Todo directory: each user is addressable by email or by identity. */
1594
+ /**
1595
+ * The AuthZEN interop Todo directory: each user is addressable by email or by
1596
+ * identity.
1597
+ */
1559
1598
  const authzenTodoUsers = Object.freeze([
1560
1599
  {
1561
1600
  id: "rick@the-citadel.com",
@@ -1600,7 +1639,10 @@ const authzenTodoPermissions = definePermissions({
1600
1639
  });
1601
1640
  const todo = authzenTodoPermissions.todo;
1602
1641
  const everyone = [allow(authzenTodoPermissions.user.can_read_user), allow(todo.can_read_todos)];
1603
- /** The interop Todo rules: viewers read, editors write their own, admins delete and evil geniuses update anything. */
1642
+ /**
1643
+ * The interop Todo rules: viewers read, editors write their own, admins delete
1644
+ * and evil geniuses update anything.
1645
+ */
1604
1646
  const authzenTodoPolicy = definePolicy(authzenTodoPermissions, {
1605
1647
  roles: [
1606
1648
  role("viewer", everyone),
@@ -1635,7 +1677,10 @@ const TODOS = Object.freeze(authzenTodoUsers.map((user, index) => ({
1635
1677
  id: `todo-${String(index + 1)}`,
1636
1678
  ownerID: user.id
1637
1679
  })));
1638
- /** Rows for `resources.todo.list` and records for `subjects.list` in the Todo domain. */
1680
+ /**
1681
+ * Rows for `resources.todo.list` and records for `subjects.list` in the Todo
1682
+ * domain.
1683
+ */
1639
1684
  const authzenTodoData = Object.freeze({
1640
1685
  todos: TODOS,
1641
1686
  users: Object.freeze(authzenTodoUsers.map((user) => ({ id: user.id })))
@@ -1653,9 +1698,9 @@ function expectedFor(user, action, ownerID) {
1653
1698
  }
1654
1699
  }
1655
1700
  /**
1656
- * PermDock's vectors over the interop Todo domain, in the interop layout:
1657
- * every user against every action on their own and on Rick's todo, one batch
1658
- * per user, and the three searches.
1701
+ * PermDock's vectors over the interop Todo domain, in the interop layout: every
1702
+ * user against every action on their own and on Rick's todo, one batch per
1703
+ * user, and the three searches.
1659
1704
  */
1660
1705
  function authzenTodoVectors() {
1661
1706
  const rick = authzenTodoUsers[0];
@@ -1855,9 +1900,9 @@ function testApprovalStore(store, options = {}) {
1855
1900
  });
1856
1901
  const [first, second] = await Promise.all([store.consume("once-token"), store.consume("once-token")]);
1857
1902
  expect([first, second].filter((item) => item !== null)).toHaveLength(1);
1858
- expect((first ?? second)?.consumedAt).toEqual(expect.any(String));
1903
+ expect((first ?? second)?.consumedAt).toStrictEqual(expect.any(String));
1859
1904
  expect(await store.consume("once-token")).toBeNull();
1860
- expect((await store.get("once-token"))?.consumedAt).toEqual(expect.any(String));
1905
+ expect((await store.get("once-token"))?.consumedAt).toStrictEqual(expect.any(String));
1861
1906
  });
1862
1907
  it("refuses an approver from another tenant", async () => {
1863
1908
  await store.create(tenantApproval("tenant-token", "o_1"));
@@ -1873,6 +1918,7 @@ function testApprovalStore(store, options = {}) {
1873
1918
  status: "approved",
1874
1919
  by: approver
1875
1920
  });
1921
+ assert.isDefined(options.reopen);
1876
1922
  const reopened = await options.reopen();
1877
1923
  expect((await reopened.get("restart-token"))?.status).toBe("approved");
1878
1924
  expect(await reopened.consume("restart-token")).not.toBeNull();
@@ -1880,6 +1926,7 @@ function testApprovalStore(store, options = {}) {
1880
1926
  });
1881
1927
  it.skipIf(options.capabilities?.expire === void 0)("replaces an expired request on a new ask", async () => {
1882
1928
  await store.create(sampleApproval("renew-token"));
1929
+ assert.isDefined(options.capabilities?.expire);
1883
1930
  await options.capabilities.expire("renew-token");
1884
1931
  const renewed = {
1885
1932
  ...sampleApproval("renew-token"),
@@ -1894,8 +1941,8 @@ function testApprovalStore(store, options = {}) {
1894
1941
  const request = sampleApproval("opaque-token");
1895
1942
  await store.create(request);
1896
1943
  const loaded = await store.get("opaque-token");
1897
- expect(loaded).toEqual(request);
1898
- expect(JSON.parse(JSON.stringify(loaded))).toEqual(request);
1944
+ expect(loaded).toStrictEqual(request);
1945
+ expect(JSON.parse(JSON.stringify(loaded))).toStrictEqual(request);
1899
1946
  const listed = await store.list({ status: "pending" });
1900
1947
  expect(listed.items.some((item) => item.token === "opaque-token")).toBe(true);
1901
1948
  const resolved = await store.resolve("opaque-token", {
@@ -1906,7 +1953,7 @@ function testApprovalStore(store, options = {}) {
1906
1953
  await expect(Promise.resolve().then(() => store.resolve("opaque-token", {
1907
1954
  status: "rejected",
1908
1955
  by: approver
1909
- }))).rejects.toThrow(/not pending/);
1956
+ }))).rejects.toThrow(/not pending/u);
1910
1957
  await store.create(sampleApproval("stale-token"));
1911
1958
  const expired = await store.expire({ epochMilliseconds: nowMillis() + 72e5 });
1912
1959
  expect(expired).toBeGreaterThanOrEqual(1);
@@ -1929,19 +1976,20 @@ function testApprovalStore(store, options = {}) {
1929
1976
  principalId: "u_pager",
1930
1977
  limit: 2
1931
1978
  });
1932
- expect(first.items.map((item) => item.token)).toEqual(["page-a", "page-b"]);
1933
- expect(typeof first.next).toBe("string");
1979
+ expect(first.items.map((item) => item.token)).toStrictEqual(["page-a", "page-b"]);
1980
+ expect(first.next).toBeTypeOf("string");
1981
+ assert.isDefined(first.next);
1934
1982
  const second = await store.list({
1935
1983
  principalId: "u_pager",
1936
1984
  limit: 2,
1937
1985
  cursor: first.next
1938
1986
  });
1939
- expect(second.items.map((item) => item.token)).toEqual(["page-c"]);
1987
+ expect(second.items.map((item) => item.token)).toStrictEqual(["page-c"]);
1940
1988
  expect(second.next).toBeUndefined();
1941
1989
  expect((await store.list({
1942
1990
  principalId: "u_pager",
1943
1991
  cursor: "not a cursor"
1944
- })).items).toEqual([]);
1992
+ })).items).toStrictEqual([]);
1945
1993
  });
1946
1994
  it("refuses an approver who does not match request.approvers", async () => {
1947
1995
  const request = {
@@ -1963,7 +2011,7 @@ function testApprovalStore(store, options = {}) {
1963
2011
  await expect(Promise.resolve().then(() => store.resolve("gated-token", {
1964
2012
  status: "approved",
1965
2013
  by: member
1966
- }))).rejects.toThrow(/eligible|not pending|not found/);
2014
+ }))).rejects.toThrow(/eligible|not pending|not found/u);
1967
2015
  });
1968
2016
  it("refuses the principal as approver unless the grant sets distinct: false", async () => {
1969
2017
  const principal = {
@@ -2018,7 +2066,7 @@ function testApprovalStore(store, options = {}) {
2018
2066
  by: approver
2019
2067
  });
2020
2068
  expect(first.status).toBe("pending");
2021
- expect(first.approvals).toEqual([{
2069
+ expect(first.approvals).toStrictEqual([{
2022
2070
  by: "u_9",
2023
2071
  at: expect.any(String)
2024
2072
  }]);
@@ -2032,7 +2080,7 @@ function testApprovalStore(store, options = {}) {
2032
2080
  by: secondApprover
2033
2081
  });
2034
2082
  expect(second.status).toBe("approved");
2035
- expect(second.approvals?.map((item) => item.by)).toEqual(["u_9", "u_10"]);
2083
+ expect(second.approvals?.map((item) => item.by)).toStrictEqual(["u_9", "u_10"]);
2036
2084
  expect(second.resolvedBy).toBe("u_10");
2037
2085
  expect(await store.consume("quorum-token")).not.toBeNull();
2038
2086
  });
@@ -2068,7 +2116,7 @@ function testApprovalStore(store, options = {}) {
2068
2116
  });
2069
2117
  expect(resolved.status).toBe("approved");
2070
2118
  expect(resolved.vouched).toBe("app-rule");
2071
- expect(resolved.approvals).toEqual([{
2119
+ expect(resolved.approvals).toStrictEqual([{
2072
2120
  by: "u_outsider",
2073
2121
  at: expect.any(String),
2074
2122
  vouched: "app-rule"
@@ -2151,7 +2199,7 @@ function testApprovalStore(store, options = {}) {
2151
2199
  by: secondApprover
2152
2200
  });
2153
2201
  expect(first.status).toBe("pending");
2154
- expect(first.approvals).toEqual([{
2202
+ expect(first.approvals).toStrictEqual([{
2155
2203
  by: "u_10",
2156
2204
  at: expect.any(String),
2157
2205
  stage: 0
@@ -2161,7 +2209,7 @@ function testApprovalStore(store, options = {}) {
2161
2209
  by: approver
2162
2210
  });
2163
2211
  expect(second.status).toBe("approved");
2164
- expect(second.approvals?.map((item) => item.stage)).toEqual([0, 1]);
2212
+ expect(second.approvals?.map((item) => item.stage)).toStrictEqual([0, 1]);
2165
2213
  });
2166
2214
  it("matches a relation approver only through the verdict's relations", async () => {
2167
2215
  const manager = {
@@ -2192,21 +2240,21 @@ function testApprovalStore(store, options = {}) {
2192
2240
  }
2193
2241
  /**
2194
2242
  * Checks an `ApprovalPolicySource`: entries are plain JSON, belong to the
2195
- * queried tenant or to none, and every entry loads against `policy` (an
2196
- * entry that does not would deny every call).
2243
+ * queried tenant or to none, and every entry loads against `policy` (an entry
2244
+ * that does not would deny every call).
2197
2245
  */
2198
2246
  function testApprovalPolicySource(source, options) {
2199
2247
  it("answers per tenant with plain entries that load against the policy", async () => {
2200
2248
  const entries = await source.approvalPoliciesFor({ tenants: [options.tenant] });
2201
2249
  expect(Array.isArray(entries)).toBe(true);
2202
2250
  for (const entry of entries) {
2203
- expect(JSON.parse(JSON.stringify(entry))).toEqual(entry);
2251
+ expect(JSON.parse(JSON.stringify(entry))).toStrictEqual(entry);
2204
2252
  expect([void 0, options.tenant]).toContain(entry.tenant);
2205
2253
  }
2206
2254
  const loaded = await approvalPoliciesFor(options.policy, source, [options.tenant], []);
2207
2255
  expect(loaded).not.toBe("failed");
2208
2256
  const other = await source.approvalPoliciesFor({ tenants: [options.unknown ?? "__permdock_unknown__"] });
2209
- expect(other.filter((entry) => entry.tenant !== void 0)).toEqual([]);
2257
+ expect(other.filter((entry) => entry.tenant !== void 0)).toStrictEqual([]);
2210
2258
  });
2211
2259
  }
2212
2260
  const reviewItem = {
@@ -2251,7 +2299,7 @@ function testAccessReviewStore(store) {
2251
2299
  limit: 1
2252
2300
  });
2253
2301
  expect(page.items).toHaveLength(1);
2254
- expect(page.next).toEqual(expect.any(String));
2302
+ expect(page.next).toStrictEqual(expect.any(String));
2255
2303
  const kept = await store.decide("rev", reviewItem.id, {
2256
2304
  status: "kept",
2257
2305
  decidedBy: "u_9",
@@ -2292,7 +2340,7 @@ function testApprovalDelegationSource(source, options) {
2292
2340
  expect(entries.some((entry) => entry.delegate === options.delegate && entry.delegator === options.delegator)).toBe(true);
2293
2341
  const instant = Date.parse(at);
2294
2342
  for (const entry of entries) {
2295
- expect(JSON.parse(JSON.stringify(entry))).toEqual(entry);
2343
+ expect(JSON.parse(JSON.stringify(entry))).toStrictEqual(entry);
2296
2344
  expect(entry.delegate).toBe(options.delegate);
2297
2345
  expect(Date.parse(entry.from)).toBeLessThanOrEqual(instant);
2298
2346
  expect(Date.parse(entry.until)).toBeGreaterThan(instant);
@@ -2301,13 +2349,13 @@ function testApprovalDelegationSource(source, options) {
2301
2349
  delegate: "__permdock_unknown__",
2302
2350
  ...options.tenant === void 0 ? {} : { tenant: options.tenant },
2303
2351
  at
2304
- })).toEqual([]);
2352
+ })).toStrictEqual([]);
2305
2353
  });
2306
2354
  }
2307
2355
  /**
2308
- * Checks an `IdempotencyStore`: a stored response comes back as written
2309
- * until it expires, keys never share an entry, and a later `set` replaces an
2310
- * earlier one.
2356
+ * Checks an `IdempotencyStore`: a stored response comes back as written until
2357
+ * it expires, keys never share an entry, and a later `set` replaces an earlier
2358
+ * one.
2311
2359
  */
2312
2360
  function testIdempotencyStore(store) {
2313
2361
  it("replays a stored response per key and keeps keys apart", async () => {
@@ -2322,14 +2370,14 @@ function testIdempotencyStore(store) {
2322
2370
  const later = nowMillis() + 36e5;
2323
2371
  expect(await store.get(key)).toBeUndefined();
2324
2372
  await store.set(key, response, later);
2325
- expect(await store.get(key)).toEqual(response);
2373
+ expect(await store.get(key)).toStrictEqual(response);
2326
2374
  expect(await store.get(other)).toBeUndefined();
2327
2375
  const replaced = {
2328
2376
  ...response,
2329
2377
  status: 201
2330
2378
  };
2331
2379
  await store.set(key, replaced, later);
2332
- expect(await store.get(key)).toEqual(replaced);
2380
+ expect(await store.get(key)).toStrictEqual(replaced);
2333
2381
  });
2334
2382
  }
2335
2383
  //#endregion
@@ -2347,7 +2395,7 @@ function testLimitStore(store) {
2347
2395
  expect(first.remaining).toBeGreaterThanOrEqual(0);
2348
2396
  const peeked = store.remaining(input);
2349
2397
  if (peeked !== void 0) {
2350
- expect(typeof peeked.remaining).toBe("number");
2398
+ expect(peeked.remaining).toBeTypeOf("number");
2351
2399
  expect(peeked !== null && typeof peeked === "object" && "then" in peeked && typeof peeked.then === "function").toBe(false);
2352
2400
  }
2353
2401
  await store.consume(input);
@@ -2391,7 +2439,7 @@ function testPolicySource(source, options = {}) {
2391
2439
  };
2392
2440
  it("returns null or a v1 policy document synchronously", () => {
2393
2441
  const document = readCurrent();
2394
- if (document !== null) expect(parsePolicyDocument(document)).toEqual(document);
2442
+ if (document !== null) expect(parsePolicyDocument(document)).toStrictEqual(document);
2395
2443
  });
2396
2444
  it("refreshes without rejecting and keeps current() synchronous", async () => {
2397
2445
  await expect(Promise.resolve(source.refresh())).resolves.toBeUndefined();
@@ -2408,6 +2456,59 @@ function testPolicySource(source, options = {}) {
2408
2456
  });
2409
2457
  }
2410
2458
  }
2459
+ function testVersionCache(cache) {
2460
+ const counted = (version) => {
2461
+ const calls = { count: 0 };
2462
+ const read = async () => {
2463
+ calls.count += 1;
2464
+ return version;
2465
+ };
2466
+ return {
2467
+ calls,
2468
+ read
2469
+ };
2470
+ };
2471
+ it("reads live for a write and answers a read from that entry", async () => {
2472
+ const { calls, read } = counted(4);
2473
+ const principal = { id: "u-version-write" };
2474
+ expect(await cache.current(principal, read, { live: true })).toBe(4);
2475
+ expect(await cache.current(principal, read, { live: true })).toBe(4);
2476
+ expect(calls.count).toBe(2);
2477
+ if (cache.maxStaleMs > 0) {
2478
+ expect(await cache.current(principal, read, { live: false })).toBe(4);
2479
+ expect(calls.count).toBe(2);
2480
+ }
2481
+ });
2482
+ it("shares one read between concurrent reads", async () => {
2483
+ const { calls, read } = counted(2);
2484
+ const principal = { id: "u-version-shared" };
2485
+ const answers = await Promise.all(Array.from({ length: 5 }, async () => cache.current(principal, read, { live: false })));
2486
+ expect(answers).toStrictEqual([
2487
+ 2,
2488
+ 2,
2489
+ 2,
2490
+ 2,
2491
+ 2
2492
+ ]);
2493
+ expect(calls.count).toBe(1);
2494
+ });
2495
+ it("stores no rejected read", async () => {
2496
+ const principal = { id: "u-version-failed" };
2497
+ await expect(cache.current(principal, () => Promise.reject(/* @__PURE__ */ new Error("down")), { live: false })).rejects.toThrow("down");
2498
+ const { calls, read } = counted(1);
2499
+ expect(await cache.current(principal, read, { live: false })).toBe(1);
2500
+ expect(calls.count).toBe(1);
2501
+ });
2502
+ it("reads again after evict", async () => {
2503
+ const { calls, read } = counted(3);
2504
+ const principal = { id: "u-version-evict" };
2505
+ await cache.current(principal, read, { live: false });
2506
+ cache.evict(principal.id);
2507
+ await cache.current(principal, read, { live: false });
2508
+ expect(calls.count).toBe(2);
2509
+ expect(cache.stats().reads).toBeGreaterThanOrEqual(2);
2510
+ });
2511
+ }
2411
2512
  //#endregion
2412
2513
  //#region src/testing/cloud-api/platform.ts
2413
2514
  const CATALOG = "https://permdock.com/schemas/catalog-v1.json";
@@ -2454,7 +2555,10 @@ const TOO_MANY = problem$1("Rate limited; retry after Retry-After seconds", {
2454
2555
  schema: { type: "string" }
2455
2556
  }
2456
2557
  });
2457
- /** The RFC 6750 section 3 challenge a refused read carries, so a client tells a dead token from a missing scope. */
2558
+ /**
2559
+ * The RFC 6750 section 3 challenge a refused read carries, so a client tells a
2560
+ * dead token from a missing scope.
2561
+ */
2458
2562
  const challenge = (example) => ({ "WWW-Authenticate": {
2459
2563
  description: `RFC 6750 Bearer challenge (\`${example}\`)`,
2460
2564
  schema: { type: "string" }
@@ -2627,7 +2731,10 @@ const PROJECT_ID = {
2627
2731
  minLength: 1
2628
2732
  }
2629
2733
  };
2630
- /** Routes of the platform issuer and its read API; they sit at the API root, outside /v1/environments/{env}. */
2734
+ /**
2735
+ * Routes of the platform issuer and its read API; they sit at the API root,
2736
+ * outside /v1/environments/{env}.
2737
+ */
2631
2738
  const PLATFORM_PATHS = {
2632
2739
  "/.well-known/oauth-authorization-server": { get: {
2633
2740
  security: [],
@@ -2828,7 +2935,10 @@ const PLATFORM_SECURITY_SCHEMES = {
2828
2935
  //#endregion
2829
2936
  //#region src/testing/cloud-api/platform-checks.ts
2830
2937
  const ITEM = /^"[^"]+"(?:;[a-z]+=-?\d+)+$/u;
2831
- /** Whether a RateLimit or RateLimit-Policy field value lists items with the parameters `keys` (draft-ietf-httpapi-ratelimit-headers-11). */
2938
+ /**
2939
+ * Whether a RateLimit or RateLimit-Policy field value lists items with the
2940
+ * parameters `keys` (draft-ietf-httpapi-ratelimit-headers-11).
2941
+ */
2832
2942
  function rateLimitField(value, keys) {
2833
2943
  if (value === null || value.trim() === "") return false;
2834
2944
  return value.split(",").every((raw) => {
@@ -2853,14 +2963,14 @@ function testCloudPlatform(url, environment, options, fetchFn) {
2853
2963
  body: new URLSearchParams(fields).toString()
2854
2964
  });
2855
2965
  it("publishes RFC 8414 metadata for the platform issuer", async () => {
2856
- const metadata = await discoverAuthorizationServer(url, { fetch: (input, init) => fetchFn(String(input), init) });
2966
+ const metadata = await discoverAuthorizationServer(url, { fetch: (input, init) => fetchFn(input instanceof Request ? input.url : input.toString(), init) });
2857
2967
  expect(metadata).not.toBeNull();
2858
2968
  expect(metadata).toMatchObject({
2859
2969
  issuer: url,
2860
2970
  code_challenge_methods_supported: ["S256"]
2861
2971
  });
2862
2972
  const scopes = metadata?.["scopes_supported"];
2863
- expect(scopes).toEqual(expect.arrayContaining(Object.keys(PLATFORM_SCOPES)));
2973
+ expect(scopes).toStrictEqual(expect.arrayContaining(Object.keys(PLATFORM_SCOPES)));
2864
2974
  });
2865
2975
  it("lists and reads the project and its policy with RateLimit fields", async () => {
2866
2976
  const list = await read("/v1/projects", options.token);
@@ -2979,7 +3089,8 @@ function testCloudPlatform(url, environment, options, fetchFn) {
2979
3089
  const loopback = await register("http://127.0.0.1:33418/callback");
2980
3090
  expect(loopback.status).toBe(201);
2981
3091
  expect(await loopback.json()).toMatchObject({ client_id: expect.any(String) });
2982
- expect((await register("http://mcp.example.invalid/callback")).status).toBe(400);
3092
+ const { status } = await register("http://mcp.example.invalid/callback");
3093
+ expect(status).toBe(400);
2983
3094
  });
2984
3095
  }
2985
3096
  //#endregion
@@ -3998,7 +4109,8 @@ const bearer = (description) => ({
3998
4109
  });
3999
4110
  /**
4000
4111
  * `schemas/cloud-api-v1.json`: the PermDock Cloud HTTP API as an OpenAPI 3.1
4001
- * document. The route tables in `adapters/cloud.mdx` and `docs:drift` keep it whole.
4112
+ * document. The route tables in `adapters/cloud.mdx` and `docs:drift` keep it
4113
+ * whole.
4002
4114
  */
4003
4115
  const CLOUD_API_DOCUMENT = freezeDeep({
4004
4116
  openapi: "3.1.1",
@@ -4101,7 +4213,10 @@ function routesOf(paths) {
4101
4213
  function pointer(parts) {
4102
4214
  return parts.map((part) => part.replaceAll("~", "~0").replaceAll("/", "~1")).join("/");
4103
4215
  }
4104
- /** A checker for responses of the PermDock Cloud API, compiled once from `CLOUD_API_DOCUMENT`. */
4216
+ /**
4217
+ * A checker for responses of the PermDock Cloud API, compiled once from
4218
+ * `CLOUD_API_DOCUMENT`.
4219
+ */
4105
4220
  function cloudApiValidator() {
4106
4221
  const ajv = new import__2020.Ajv2020({
4107
4222
  strict: false,
@@ -4211,8 +4326,8 @@ async function problemCode(response) {
4211
4326
  * Runs the conformance runners and the HTTP contract checks against one
4212
4327
  * PermDock Cloud environment, and validates every response body against
4213
4328
  * `cloud-api-v1.json`. Point it at a test environment: it creates approvals,
4214
- * sends decision events and deliveries to `.invalid` addresses, and pushes
4215
- * the catalog the environment already holds.
4329
+ * sends decision events and deliveries to `.invalid` addresses, and pushes the
4330
+ * catalog the environment already holds.
4216
4331
  */
4217
4332
  function testCloudApi(baseUrl, keys, options) {
4218
4333
  const fetchFn = options.fetch ?? globalThis.fetch.bind(globalThis);
@@ -4224,16 +4339,13 @@ function testCloudApi(baseUrl, keys, options) {
4224
4339
  environment
4225
4340
  });
4226
4341
  const check = cloudApiValidator();
4227
- const problems = [];
4228
4342
  const checks = [];
4229
4343
  const recording = async (input, init) => {
4230
4344
  const request = new Request(input, init);
4231
4345
  const response = await fetchFn(request);
4232
4346
  const { pathname } = new URL(request.url);
4233
4347
  const path = pathname === `${METADATA}${prefix}` ? METADATA : pathname.slice(prefix.length);
4234
- checks.push(check(request.method, path, response.clone()).then((found) => {
4235
- problems.push(...found);
4236
- }));
4348
+ checks.push(check(request.method, path, response.clone()));
4237
4349
  return response;
4238
4350
  };
4239
4351
  const client = cloud({
@@ -4301,17 +4413,19 @@ function testCloudApi(baseUrl, keys, options) {
4301
4413
  issuer,
4302
4414
  jwks_uri: `${issuer}/.well-known/jwks.json`
4303
4415
  });
4304
- expect((await recording(`${url}/v1/environment`)).status).toBe(401);
4416
+ const { status } = await recording(`${url}/v1/environment`);
4417
+ expect(status).toBe(401);
4305
4418
  });
4306
4419
  it("answers 403 to a key of another kind", async () => {
4307
- expect((await call("/hosted-grants", keys.client)).status).toBe(403);
4420
+ const { status } = await call("/hosted-grants", keys.client);
4421
+ expect(status).toBe(403);
4308
4422
  if (keys.export !== void 0) expect((await call("/approvals", keys.export)).status).toBe(403);
4309
4423
  });
4310
4424
  it("sends an ETag on the approval read and refuses an approver token with a stale one", async () => {
4311
4425
  const token = tag();
4312
4426
  await client.approvals.create(sample(token));
4313
4427
  const { request, etag } = await current(token);
4314
- expect(etag).toEqual(expect.any(String));
4428
+ expect(etag).toStrictEqual(expect.any(String));
4315
4429
  const stale = await resolveRaw(token, {
4316
4430
  status: "approved",
4317
4431
  by: admin
@@ -4372,7 +4486,7 @@ function testCloudApi(baseUrl, keys, options) {
4372
4486
  aud: issuer
4373
4487
  })
4374
4488
  });
4375
- expect([typ, response.status]).toEqual([typ, 422]);
4489
+ expect([typ, response.status]).toStrictEqual([typ, 422]);
4376
4490
  }
4377
4491
  });
4378
4492
  it("repeats a delivery for a repeated Idempotency-Key and requires one", async () => {
@@ -4400,7 +4514,8 @@ function testCloudApi(baseUrl, keys, options) {
4400
4514
  expect(first.ok && second.ok).toBe(true);
4401
4515
  const [a, b] = await Promise.all([first.json(), second.json()]);
4402
4516
  expect(isRecord(a) && isRecord(b) && a["id"] === b["id"]).toBe(true);
4403
- expect((await send({})).status).toBe(400);
4517
+ const { status } = await send({});
4518
+ expect(status).toBe(400);
4404
4519
  });
4405
4520
  it("answers unchanged for the catalog it already holds", async (context) => {
4406
4521
  const response = await call("/catalog", keys.client);
@@ -4437,12 +4552,12 @@ function testCloudApi(baseUrl, keys, options) {
4437
4552
  const first = await get({ "permdock-subject": token });
4438
4553
  expect(first.status).toBe(200);
4439
4554
  expect(first.headers.get("content-type")).toMatch(/^application\/jwt/u);
4440
- expect((await get({ "permdock-subject": token })).status).toBe(401);
4555
+ const { status } = await get({ "permdock-subject": token });
4556
+ expect(status).toBe(401);
4441
4557
  expect((await get({})).status).toBe(401);
4442
4558
  });
4443
4559
  it("answers every request in the shapes cloud-api-v1.json documents", async () => {
4444
- await Promise.all(checks);
4445
- expect(problems).toEqual([]);
4560
+ expect((await Promise.all(checks)).flat()).toStrictEqual([]);
4446
4561
  });
4447
4562
  }
4448
4563
  //#endregion
@@ -4603,10 +4718,10 @@ const WHERE_SUBJECT = {
4603
4718
  context: {}
4604
4719
  };
4605
4720
  /**
4606
- * `matches` answers whether the compiled output selects `row`, for example
4607
- * by running it against a table holding only that row. With it, every case
4608
- * must select the rows the in-memory evaluator keeps, including rows whose
4609
- * fields are NULL.
4721
+ * `matches` answers whether the compiled output selects `row`, for example by
4722
+ * running it against a table holding only that row. With it, every case must
4723
+ * select the rows the in-memory evaluator keeps, including rows whose fields
4724
+ * are NULL.
4610
4725
  */
4611
4726
  function testWhereCompiler(compiler, options) {
4612
4727
  const { matches } = options;
@@ -4615,7 +4730,7 @@ function testWhereCompiler(compiler, options) {
4615
4730
  const compiled = compiler(condition, options.target);
4616
4731
  const selected = [];
4617
4732
  for (const row of WHERE_ROWS) if (await matches(compiled, row)) selected.push(row["id"]);
4618
- expect(selected).toEqual(WHERE_ROWS.filter((row) => evaluateCondition(condition, row, WHERE_SUBJECT)).map((row) => row["id"]));
4733
+ expect(selected).toStrictEqual(WHERE_ROWS.filter((row) => evaluateCondition(condition, row, WHERE_SUBJECT)).map((row) => row["id"]));
4619
4734
  });
4620
4735
  it("fails closed on an empty allow set", () => {
4621
4736
  const compiled = compiler({
@@ -4683,7 +4798,7 @@ function testReplayStore(store) {
4683
4798
  }
4684
4799
  const expiresAt = nowSeconds() + 60;
4685
4800
  const results = await Promise.all([store.claim("claim-key", expiresAt), store.claim("claim-key", expiresAt)]);
4686
- expect(results.toSorted()).toEqual([false, true]);
4801
+ expect(results.toSorted()).toStrictEqual([false, true]);
4687
4802
  expect(await store.seen("claim-key")).toBe(true);
4688
4803
  await store.release("claim-key");
4689
4804
  expect(await store.claim("claim-key", expiresAt)).toBe(true);
@@ -4694,18 +4809,18 @@ function testSetQueue(queue) {
4694
4809
  await queue.enqueue("stream-a", "a1", "set-a1");
4695
4810
  await queue.enqueue("stream-a", "a2", "set-a2");
4696
4811
  await queue.enqueue("stream-b", "b1", "set-b1");
4697
- expect(await queue.pending("stream-a", 10)).toEqual([{
4812
+ expect(await queue.pending("stream-a", 10)).toStrictEqual([{
4698
4813
  jti: "a1",
4699
4814
  set: "set-a1"
4700
4815
  }, {
4701
4816
  jti: "a2",
4702
4817
  set: "set-a2"
4703
4818
  }]);
4704
- expect(await queue.pending("stream-a", 1)).toEqual([{
4819
+ expect(await queue.pending("stream-a", 1)).toStrictEqual([{
4705
4820
  jti: "a1",
4706
4821
  set: "set-a1"
4707
4822
  }]);
4708
- expect(await queue.pending("stream-b", 10)).toEqual([{
4823
+ expect(await queue.pending("stream-b", 10)).toStrictEqual([{
4709
4824
  jti: "b1",
4710
4825
  set: "set-b1"
4711
4826
  }]);
@@ -4720,7 +4835,7 @@ function testSetQueue(queue) {
4720
4835
  description: "unknown kid"
4721
4836
  });
4722
4837
  await queue.ack("stream-other", "c3");
4723
- expect(await queue.pending("stream-c", 10)).toEqual([{
4838
+ expect(await queue.pending("stream-c", 10)).toStrictEqual([{
4724
4839
  jti: "c3",
4725
4840
  set: "set-c3"
4726
4841
  }]);
@@ -4745,18 +4860,18 @@ function testSsfStreamStore(store) {
4745
4860
  await store.create(owner, streamConfiguration(first));
4746
4861
  await store.create(owner, streamConfiguration(second));
4747
4862
  await store.create("someone-else", streamConfiguration(id("c")));
4748
- expect(await store.get(first)).toEqual({
4863
+ expect(await store.get(first)).toStrictEqual({
4749
4864
  owner,
4750
4865
  configuration: streamConfiguration(first)
4751
4866
  });
4752
- expect(await store.status(first)).toEqual({
4867
+ expect(await store.status(first)).toStrictEqual({
4753
4868
  stream_id: first,
4754
4869
  status: "enabled"
4755
4870
  });
4756
4871
  const listed = await store.list(owner);
4757
- expect(listed.map((stream) => stream.configuration.stream_id)).toEqual([first, second]);
4872
+ expect(listed.map((stream) => stream.configuration.stream_id)).toStrictEqual([first, second]);
4758
4873
  const all = await store.list();
4759
- expect(all.map((stream) => stream.configuration.stream_id)).toEqual(expect.arrayContaining([first, second]));
4874
+ expect(all.map((stream) => stream.configuration.stream_id)).toStrictEqual(expect.arrayContaining([first, second]));
4760
4875
  });
4761
4876
  it("answers null for a stream that does not exist", async () => {
4762
4877
  expect(await store.get(id("missing"))).toBeNull();
@@ -4771,11 +4886,11 @@ function testSsfStreamStore(store) {
4771
4886
  reason: "maintenance"
4772
4887
  });
4773
4888
  await store.update(streamConfiguration(stream, "renamed"));
4774
- expect(await store.get(stream)).toEqual({
4889
+ expect(await store.get(stream)).toStrictEqual({
4775
4890
  owner: "owner-update",
4776
4891
  configuration: streamConfiguration(stream, "renamed")
4777
4892
  });
4778
- expect(await store.status(stream)).toEqual({
4893
+ expect(await store.status(stream)).toStrictEqual({
4779
4894
  stream_id: stream,
4780
4895
  status: "paused",
4781
4896
  reason: "maintenance"
@@ -4807,8 +4922,8 @@ function testRevocationFeed(feed) {
4807
4922
  };
4808
4923
  await feed.revoke(revoked);
4809
4924
  await vi.waitFor(() => {
4810
- expect(first).toEqual([revoked]);
4811
- expect(second).toEqual([revoked]);
4925
+ expect(first).toStrictEqual([revoked]);
4926
+ expect(second).toStrictEqual([revoked]);
4812
4927
  });
4813
4928
  stopFirst();
4814
4929
  const changed = {
@@ -4818,9 +4933,9 @@ function testRevocationFeed(feed) {
4818
4933
  };
4819
4934
  await feed.revoke(changed);
4820
4935
  await vi.waitFor(() => {
4821
- expect(second).toEqual([revoked, changed]);
4936
+ expect(second).toStrictEqual([revoked, changed]);
4822
4937
  });
4823
- expect(first).toEqual([revoked]);
4938
+ expect(first).toStrictEqual([revoked]);
4824
4939
  stopSecond();
4825
4940
  });
4826
4941
  it("keeps delivering when a listener throws", async () => {
@@ -4837,7 +4952,7 @@ function testRevocationFeed(feed) {
4837
4952
  };
4838
4953
  await feed.revoke(event);
4839
4954
  await vi.waitFor(() => {
4840
- expect(seen).toEqual([event]);
4955
+ expect(seen).toStrictEqual([event]);
4841
4956
  });
4842
4957
  stopThrowing();
4843
4958
  stop();
@@ -4856,7 +4971,7 @@ function testRevocationFeed(feed) {
4856
4971
  }]) await expect((async () => {
4857
4972
  await feed.revoke(event);
4858
4973
  })()).rejects.toThrow(TypeError);
4859
- expect(seen).toEqual([]);
4974
+ expect(seen).toStrictEqual([]);
4860
4975
  stop();
4861
4976
  });
4862
4977
  }
@@ -4931,8 +5046,8 @@ function flipLast(value) {
4931
5046
  }
4932
5047
  /**
4933
5048
  * `key` is a live key the verifier knows, or a function issuing one (called
4934
- * once). `revoke`, when given, revokes it; the runner then expects the key
4935
- * to stop verifying.
5049
+ * once). `revoke`, when given, revokes it; the runner then expects the key to
5050
+ * stop verifying.
4936
5051
  */
4937
5052
  function testCredentialVerifier(verifier, options) {
4938
5053
  let issued;
@@ -4948,7 +5063,7 @@ function testCredentialVerifier(verifier, options) {
4948
5063
  const credential = parseCredential(await verifier.verify(key));
4949
5064
  expect(credential).toBeDefined();
4950
5065
  expect(credential?.id).toBe(parts?.id);
4951
- expect(parseCredential(await verifier.verify(key))).toEqual(credential);
5066
+ expect(parseCredential(await verifier.verify(key))).toStrictEqual(credential);
4952
5067
  });
4953
5068
  it("never throws and answers null for every other key", async () => {
4954
5069
  const key = await live();
@@ -4978,7 +5093,7 @@ function testCredentialVerifier(verifier, options) {
4978
5093
  const id = parseApiKey(key)?.id ?? "";
4979
5094
  await verifier.touch?.(id, { epochMilliseconds: nowMillis() });
4980
5095
  await verifier.touch?.("unknown-id", { epochMilliseconds: nowMillis() });
4981
- expect(parseCredential(await verifier.verify(key))).toEqual(before);
5096
+ expect(parseCredential(await verifier.verify(key))).toStrictEqual(before);
4982
5097
  });
4983
5098
  if (options.revoke !== void 0) {
4984
5099
  const revoke = options.revoke;
@@ -4999,7 +5114,7 @@ function testTokenSigner(signer, options) {
4999
5114
  audience: "https://app.example.com"
5000
5115
  });
5001
5116
  const header = decodeHeader(token);
5002
- expect(Object.keys(header).toSorted()).toEqual([
5117
+ expect(Object.keys(header).toSorted()).toStrictEqual([
5003
5118
  "alg",
5004
5119
  "kid",
5005
5120
  "typ"
@@ -5045,7 +5160,7 @@ function testDecisionProvider(provider, options) {
5045
5160
  local: LOCAL
5046
5161
  });
5047
5162
  it("names itself and claims the permission synchronously", () => {
5048
- expect(typeof provider.name).toBe("string");
5163
+ expect(provider.name).toBeTypeOf("string");
5049
5164
  expect(provider.name.length).toBeGreaterThan(0);
5050
5165
  expect(provider.handles(options.permission)).toBe(true);
5051
5166
  });
@@ -5121,12 +5236,12 @@ function testRelationSource(source, options) {
5121
5236
  });
5122
5237
  expect(Array.isArray(full.ancestors)).toBe(true);
5123
5238
  for (const ancestor of full.ancestors) {
5124
- expect(typeof ancestor.id).toBe("string");
5239
+ expect(ancestor.id).toBeTypeOf("string");
5125
5240
  expect(ancestor.id).not.toBe("");
5126
5241
  }
5127
5242
  expect(full.ancestors.length).toBeLessThanOrEqual(32);
5128
5243
  const expected = options.expect?.ancestors?.[`${object.resource}:${object.id}`];
5129
- if (expected !== void 0) expect(full.ancestors.map((ancestor) => ancestor.id)).toEqual(expected);
5244
+ if (expected !== void 0) expect(full.ancestors.map((ancestor) => ancestor.id)).toStrictEqual(expected);
5130
5245
  if (full.ancestors.length > 1) {
5131
5246
  const short = await source.ancestors({
5132
5247
  resource: object.resource,
@@ -5134,7 +5249,7 @@ function testRelationSource(source, options) {
5134
5249
  through: "parent",
5135
5250
  depth: 1
5136
5251
  });
5137
- expect(short.ancestors.map((ancestor) => ancestor.id)).toEqual([full.ancestors[0]?.id]);
5252
+ expect(short.ancestors.map((ancestor) => ancestor.id)).toStrictEqual([full.ancestors[0]?.id]);
5138
5253
  expect(short.truncated).toBe(true);
5139
5254
  }
5140
5255
  const none = await source.ancestors({
@@ -5143,7 +5258,7 @@ function testRelationSource(source, options) {
5143
5258
  through: "parent",
5144
5259
  depth: 0
5145
5260
  });
5146
- expect(none.ancestors).toEqual([]);
5261
+ expect(none.ancestors).toStrictEqual([]);
5147
5262
  }
5148
5263
  });
5149
5264
  it("returns well-formed holders", async () => {
@@ -5161,14 +5276,14 @@ function testRelationSource(source, options) {
5161
5276
  holder.group.id,
5162
5277
  holder.group.relation
5163
5278
  ]) {
5164
- expect(typeof part).toBe("string");
5279
+ expect(part).toBeTypeOf("string");
5165
5280
  expect(part).not.toBe("");
5166
5281
  }
5167
- else expect(typeof holder.principal.id).toBe("string");
5282
+ else expect(holder.principal.id).toBeTypeOf("string");
5168
5283
  for (const instant of [holder.startsAt, holder.expiresAt]) expect(instant === void 0 || typeof instant === "number" && Number.isFinite(instant)).toBe(true);
5169
5284
  }
5170
5285
  const expected = options.expect?.holders?.[`${object.resource}:${object.id}#${object.relation}`];
5171
- if (expected !== void 0) expect(holders.map(holderKey).toSorted()).toEqual([...expected].toSorted());
5286
+ if (expected !== void 0) expect(holders.map(holderKey).toSorted()).toStrictEqual([...expected].toSorted());
5172
5287
  }
5173
5288
  });
5174
5289
  it("follows each link to exactly one instance", async () => {
@@ -5182,7 +5297,7 @@ function testRelationSource(source, options) {
5182
5297
  through,
5183
5298
  depth: 1
5184
5299
  });
5185
- expect(linked.ancestors.map((ancestor) => ancestor.id)).toEqual([id]);
5300
+ expect(linked.ancestors.map((ancestor) => ancestor.id)).toStrictEqual([id]);
5186
5301
  }
5187
5302
  });
5188
5303
  it("reads each object's row as an object, or null when there is none", async () => {
@@ -5212,11 +5327,11 @@ function testRelationSource(source, options) {
5212
5327
  ...missing,
5213
5328
  through: "parent",
5214
5329
  depth: 16
5215
- })).ancestors).toEqual([]);
5330
+ })).ancestors).toStrictEqual([]);
5216
5331
  if (first.relation !== void 0) expect(await source.related({
5217
5332
  ...missing,
5218
5333
  relation: first.relation
5219
- })).toEqual([]);
5334
+ })).toStrictEqual([]);
5220
5335
  });
5221
5336
  }
5222
5337
  //#endregion
@@ -5228,8 +5343,8 @@ function isFrozenDeep(value) {
5228
5343
  /**
5229
5344
  * Checks a `PrincipalSource`: `principal` answers each listed id with the
5230
5345
  * expected principal or `null`, never another id; `principalByIdentity`
5231
- * resolves each listed identity to the expected principal id or `null`, and
5232
- * an email matches trimmed and in any case.
5346
+ * resolves each listed identity to the expected principal id or `null`, and an
5347
+ * email matches trimmed and in any case.
5233
5348
  */
5234
5349
  function testPrincipalSource(source, options) {
5235
5350
  it("returns the principal with the asked id, or null", async () => {
@@ -5241,8 +5356,8 @@ function testPrincipalSource(source, options) {
5241
5356
  found = null;
5242
5357
  }
5243
5358
  expect(found === null || typeof found === "object").toBe(true);
5244
- if (found !== null) expect(await loadPrincipal(source, entry.id, entry.tenant)).toEqual(found);
5245
- if (entry.expect !== void 0) expect(found).toEqual(entry.expect);
5359
+ if (found !== null) expect(await loadPrincipal(source, entry.id, entry.tenant)).toStrictEqual(found);
5360
+ if (entry.expect !== void 0) expect(found).toStrictEqual(entry.expect);
5246
5361
  }
5247
5362
  });
5248
5363
  it("returns principals a caller cannot change", async () => {
@@ -5285,10 +5400,10 @@ async function automationOf(source, id, tenant) {
5285
5400
  }
5286
5401
  }
5287
5402
  /**
5288
- * Checks an `AutomationSource`: `automation(id)` answers each listed id
5289
- * with a valid Automation v1 record of that id or `null`, never another id;
5290
- * a record held to one tenant is `null` when asked for another; an empty or
5291
- * unknown id is `null`.
5403
+ * Checks an `AutomationSource`: `automation(id)` answers each listed id with a
5404
+ * valid Automation v1 record of that id or `null`, never another id; a record
5405
+ * held to one tenant is `null` when asked for another; an empty or unknown id
5406
+ * is `null`.
5292
5407
  */
5293
5408
  function testAutomationSource(source, options) {
5294
5409
  it("returns a valid v1 record with the asked id, or null", async () => {
@@ -5296,10 +5411,10 @@ function testAutomationSource(source, options) {
5296
5411
  const found = await automationOf(source, entry.id, entry.tenant);
5297
5412
  if (found !== null) {
5298
5413
  const parsed = parseAutomation(found);
5299
- expect(parsed).toEqual(found);
5414
+ expect(parsed).toStrictEqual(found);
5300
5415
  expect(parsed?.id).toBe(entry.id);
5301
5416
  }
5302
- if (entry.expect !== void 0) expect(found).toEqual(entry.expect);
5417
+ if (entry.expect !== void 0) expect(found).toStrictEqual(entry.expect);
5303
5418
  }
5304
5419
  });
5305
5420
  it("refuses a record held to another tenant", async () => {
@@ -5322,9 +5437,9 @@ async function sessionOf(source, id) {
5322
5437
  }
5323
5438
  }
5324
5439
  /**
5325
- * Checks a `SupportSessionSource`: `session(id)` answers each listed id
5326
- * with a record of that id or `null`, never another id; `ended` is a
5327
- * boolean when present; an empty or unknown id is `null`.
5440
+ * Checks a `SupportSessionSource`: `session(id)` answers each listed id with a
5441
+ * record of that id or `null`, never another id; `ended` is a boolean when
5442
+ * present; an empty or unknown id is `null`.
5328
5443
  */
5329
5444
  function testSupportSessionSource(source, options) {
5330
5445
  it("returns the session with the asked id, or null", async () => {
@@ -5349,7 +5464,10 @@ function testSupportSessionSource(source, options) {
5349
5464
  });
5350
5465
  }
5351
5466
  const SETTLED = Symbol("settled");
5352
- /** Whether `promise` settles within `ms` milliseconds; a rejection counts as settled. */
5467
+ /**
5468
+ * Whether `promise` settles within `ms` milliseconds; a rejection counts as
5469
+ * settled.
5470
+ */
5353
5471
  async function settlesWithin(promise, ms) {
5354
5472
  let timer;
5355
5473
  const timeout = new Promise((resolve) => {
@@ -5364,12 +5482,12 @@ async function settlesWithin(promise, ms) {
5364
5482
  }
5365
5483
  }
5366
5484
  /**
5367
- * Checks an `ApprovalWaiter`: a wait ends when its token is woken and not
5368
- * when another token is; waking a token nobody waits on resolves; a wait
5369
- * whose `expiresAt` has passed ends; an aborted `signal` rejects the wait with its reason.
5370
- * Pass `expiry: false` or `abort: false` for a waiter whose runner offers no
5371
- * timer or no cancellation, `pending` when the waiter reads a store, and
5372
- * `parked` when a wait parks asynchronously.
5485
+ * Checks an `ApprovalWaiter`: a wait ends when its token is woken and not when
5486
+ * another token is; waking a token nobody waits on resolves; a wait whose
5487
+ * `expiresAt` has passed ends; an aborted `signal` rejects the wait with its
5488
+ * reason. Pass `expiry: false` or `abort: false` for a waiter whose runner
5489
+ * offers no timer or no cancellation, `pending` when the waiter reads a store,
5490
+ * and `parked` when a wait parks asynchronously.
5373
5491
  */
5374
5492
  function testApprovalWaiter(waiter, options = {}) {
5375
5493
  const timeout = options.timeout ?? 1e3;
@@ -5431,9 +5549,9 @@ function key(suffix) {
5431
5549
  }
5432
5550
  /**
5433
5551
  * Conformance for a `DeliveryTransport`: it sends a checked target with its
5434
- * idempotency key, keeps the key on a retry, refuses a target without a
5435
- * granted decision before calling the provider, and maps provider errors to
5436
- * retryable or final failures without rejecting.
5552
+ * idempotency key, keeps the key on a retry, refuses a target without a granted
5553
+ * decision before calling the provider, and maps provider errors to retryable
5554
+ * or final failures without rejecting.
5437
5555
  */
5438
5556
  function testDeliveryTransport(name, options) {
5439
5557
  const targetWith = async (decision) => ({
@@ -5447,14 +5565,14 @@ function testDeliveryTransport(name, options) {
5447
5565
  it("names its channel and provider", () => {
5448
5566
  const { transport } = options.create();
5449
5567
  expect(transport.channel).toBe(options.channel);
5450
- expect(typeof transport.name).toBe("string");
5568
+ expect(transport.name).toBeTypeOf("string");
5451
5569
  expect(transport.name).not.toBe("");
5452
5570
  });
5453
5571
  it("sends a checked target with its idempotency key", async () => {
5454
5572
  const harness = options.create();
5455
5573
  const result = await send(harness, await targetWith(await grantedDecision()), "a");
5456
5574
  expect(result.status).toBe("sent");
5457
- expect(await harness.received()).toEqual([{ idempotencyKey: "pdd_runner_a" }]);
5575
+ expect(await harness.received()).toStrictEqual([{ idempotencyKey: "pdd_runner_a" }]);
5458
5576
  });
5459
5577
  it("passes the same key on a retry of the same delivery", async () => {
5460
5578
  const harness = options.create();
@@ -5480,7 +5598,7 @@ function testDeliveryTransport(name, options) {
5480
5598
  cause: "invalid-recipient",
5481
5599
  retryable: false
5482
5600
  });
5483
- expect(await harness.received()).toEqual([]);
5601
+ expect(await harness.received()).toStrictEqual([]);
5484
5602
  });
5485
5603
  it("maps a retryable provider error to a retryable failure", async () => {
5486
5604
  const harness = options.create();
@@ -5511,7 +5629,7 @@ function testDeliveryTransport(name, options) {
5511
5629
  status: "failed",
5512
5630
  retryable: true
5513
5631
  });
5514
- expect(await harness.received()).toEqual([]);
5632
+ expect(await harness.received()).toStrictEqual([]);
5515
5633
  });
5516
5634
  });
5517
5635
  }
@@ -5549,7 +5667,7 @@ function testMembershipSource(source, options) {
5549
5667
  if (options.policy !== void 0) expect(normalizeMemberships([membership], scopeList(options.policy.scopes))).toHaveLength(1);
5550
5668
  }
5551
5669
  const expected = options.expect?.[principal.id];
5552
- if (expected !== void 0) expect(memberships).toEqual(expected);
5670
+ if (expected !== void 0) expect(memberships).toStrictEqual(expected);
5553
5671
  }
5554
5672
  });
5555
5673
  if (source.list !== void 0) it("lists every member of an instance it returns a membership for", async () => {
@@ -5581,9 +5699,9 @@ function testEntitlementSource(source, options) {
5581
5699
  it("returns plan names for a tenant and none without one", async () => {
5582
5700
  const found = await source.entitlementsFor(options.principal, { tenant: options.tenant });
5583
5701
  expect(Array.isArray(found)).toBe(true);
5584
- for (const name of found) expect(typeof name).toBe("string");
5585
- if (options.expect !== void 0) expect([...found].toSorted()).toEqual([...options.expect].toSorted());
5586
- expect(await source.entitlementsFor(options.principal, {})).toEqual([]);
5702
+ for (const name of found) expect(name).toBeTypeOf("string");
5703
+ if (options.expect !== void 0) expect([...found].toSorted()).toStrictEqual([...options.expect].toSorted());
5704
+ expect(await source.entitlementsFor(options.principal, {})).toStrictEqual([]);
5587
5705
  });
5588
5706
  }
5589
5707
  function testCustomRoleSource(source, options) {
@@ -5593,7 +5711,7 @@ function testCustomRoleSource(source, options) {
5593
5711
  for (const role of roles) {
5594
5712
  expect(role.tenant).toBe(options.tenant);
5595
5713
  for (const included of role.includes ?? []) expect(declared).toContain(included);
5596
- if (options.policy !== void 0) expect(validateCustomRole(options.policy, role).dropped).toEqual([]);
5714
+ if (options.policy !== void 0) expect(validateCustomRole(options.policy, role).dropped).toStrictEqual([]);
5597
5715
  }
5598
5716
  if (source.assignable !== void 0) {
5599
5717
  const assignable = await source.assignable(options.tenant);
@@ -5603,7 +5721,7 @@ function testCustomRoleSource(source, options) {
5603
5721
  const every = options.every;
5604
5722
  if (every !== void 0) it("returns every custom role of the tenant, held or not", async () => {
5605
5723
  const roles = await source.rolesFor(options.tenant, { held: [] });
5606
- expect([...new Set(roles.map((role) => role.name))].toSorted()).toEqual([...new Set(every)].toSorted());
5724
+ expect([...new Set(roles.map((role) => role.name))].toSorted()).toStrictEqual([...new Set(every)].toSorted());
5607
5725
  });
5608
5726
  }
5609
5727
  function testDirectoryStore(store, options) {
@@ -5633,7 +5751,7 @@ function testDirectoryStore(store, options) {
5633
5751
  created: "",
5634
5752
  lastModified: ""
5635
5753
  }
5636
- })).rejects.toThrow(/userName/);
5754
+ })).rejects.toThrow(/userName/u);
5637
5755
  const group = await store.putGroup(home, {
5638
5756
  id: "g_editors",
5639
5757
  displayName: "Editors",
@@ -5644,11 +5762,11 @@ function testDirectoryStore(store, options) {
5644
5762
  lastModified: ""
5645
5763
  }
5646
5764
  });
5647
- expect(await store.groupsFor(home, created.id)).toEqual([expect.objectContaining({
5765
+ expect(await store.groupsFor(home, created.id)).toStrictEqual([expect.objectContaining({
5648
5766
  id: group.id,
5649
5767
  displayName: "Editors"
5650
5768
  })]);
5651
- expect(await store.groupsFor(other, created.id)).toEqual([]);
5769
+ expect(await store.groupsFor(other, created.id)).toStrictEqual([]);
5652
5770
  const patched = await store.patchUser(home, created.id, [{
5653
5771
  op: "replace",
5654
5772
  path: "active",
@@ -5656,13 +5774,13 @@ function testDirectoryStore(store, options) {
5656
5774
  }]);
5657
5775
  expect(patched.active).toBe(false);
5658
5776
  const source = directoryMembershipSource(store, { assignable: ["editor"] });
5659
- expect(await source.membershipsFor({ id: "00u1" }, { tenant: home })).toEqual([]);
5777
+ expect(await source.membershipsFor({ id: "00u1" }, { tenant: home })).toStrictEqual([]);
5660
5778
  await store.patchUser(home, created.id, [{
5661
5779
  op: "replace",
5662
5780
  path: "active",
5663
5781
  value: true
5664
5782
  }]);
5665
- expect(await source.membershipsFor({ id: "00u1" }, { tenant: home })).toEqual([{
5783
+ expect(await source.membershipsFor({ id: "00u1" }, { tenant: home })).toStrictEqual([{
5666
5784
  tenant: home,
5667
5785
  roles: ["editor"],
5668
5786
  via: `group:${group.id}`,
@@ -5673,7 +5791,7 @@ function testDirectoryStore(store, options) {
5673
5791
  path: "members",
5674
5792
  value: [{ value: created.id }]
5675
5793
  }]);
5676
- expect(await store.groupsFor(home, created.id)).toEqual([]);
5794
+ expect(await store.groupsFor(home, created.id)).toStrictEqual([]);
5677
5795
  });
5678
5796
  it("ends sessions when scimHandler deactivates a user in this store", async () => {
5679
5797
  const feed = memoryRevocationFeed();
@@ -5726,7 +5844,7 @@ function testDirectoryStore(store, options) {
5726
5844
  kind: "session-revoked"
5727
5845
  });
5728
5846
  expect(seen.every((event) => event.kind === "session-revoked")).toBe(true);
5729
- expect(kinds).toEqual(["changed", "session-revoked"]);
5847
+ expect(kinds).toStrictEqual(["changed", "session-revoked"]);
5730
5848
  });
5731
5849
  }
5732
5850
  /** Settings for `tenant`, or `undefined`; a thrown source fails the runner. */
@@ -5734,13 +5852,13 @@ function testSettingsSource(source, options) {
5734
5852
  it("answers per tenant with plain settings and nothing for an unknown tenant", async () => {
5735
5853
  const settings = await source.settingsFor(options.tenant);
5736
5854
  if (settings !== void 0) {
5737
- expect(typeof settings).toBe("object");
5855
+ expect(settings).toBeTypeOf("object");
5738
5856
  const credentials = settings.credentials;
5739
5857
  if (credentials !== void 0) {
5740
5858
  expect(credentials.maxTtl === void 0 || Number.isFinite(credentials.maxTtl) && credentials.maxTtl >= 0).toBe(true);
5741
5859
  expect(credentials.kinds === void 0 || credentials.kinds.every((kind) => kind === "user" || kind === "service" || kind === "feed")).toBe(true);
5742
5860
  }
5743
- expect(JSON.parse(JSON.stringify(settings))).toEqual(settings);
5861
+ expect(JSON.parse(JSON.stringify(settings))).toStrictEqual(settings);
5744
5862
  }
5745
5863
  expect(await source.settingsFor(options.unknown ?? "__permdock_unknown__")).toBeUndefined();
5746
5864
  });
@@ -6175,8 +6293,8 @@ const supabaseClaimVectors = {
6175
6293
  /**
6176
6294
  * The `permdock supabase inspect --json` manifest for a policy with one
6177
6295
  * `tenant` scope, the default `supabase.hook` and a `features` claim from
6178
- * `public.feature_claims`. A package that reads the manifest tests its
6179
- * parser against this value.
6296
+ * `public.feature_claims`. A package that reads the manifest tests its parser
6297
+ * against this value.
6180
6298
  */
6181
6299
  const supabaseHookManifestFixture = {
6182
6300
  $schema: "https://permdock.com/schemas/supabase-manifest-v1.json",
@@ -6467,4 +6585,4 @@ const PROBLEM_EXAMPLES = Object.freeze({
6467
6585
  }
6468
6586
  });
6469
6587
  //#endregion
6470
- export { AGENT_THROWING_ROW, AGENT_THROWING_USER, PROBLEM_EXAMPLES, authzenTodoData, authzenTodoPermissions, authzenTodoPolicy, authzenTodoUsers, authzenTodoVectors, describePolicy, expectTypeOf, jwtFixtureAudience, jwtFixtureIssuer, jwtFixtureJwks, jwtFixtureTokens, policyMatrix, snapshotFixture, supabaseClaimFixtures, supabaseClaimVectors, supabaseHookManifestFixture, supabaseMembershipsBudget, testAccessReviewStore, testAgentAdapter, testAgentRuntime, testApprovalDelegationSource, testApprovalPolicySource, testApprovalStore, testApprovalWaiter, testAuthzen, testAutomationSource, testClientParity, testClientStore, testCloudApi, testCredentialVerifier, testCustomRoleSource, testDecisionProvider, testDecisionSink, testDeliveryTransport, testDirectoryStore, testEntitlementSource, testHttpAdapter, testIdempotencyStore, testLegacyParity, testLimitStore, testMembershipSource, testOrmParity, testPolicySource, testPrincipalSource, testRelationSource, testReplayStore, testRevocationFeed, testRlsParity, testSetQueue, testSettingsSource, testSnapshotSource, testSnapshotStorage, testSsfStreamStore, testSubjectResolver, testSupportSessionSource, testTokenSigner, testTokenVerifier, testWhereCompiler };
6588
+ export { AGENT_THROWING_ROW, AGENT_THROWING_USER, PROBLEM_EXAMPLES, authzenTodoData, authzenTodoPermissions, authzenTodoPolicy, authzenTodoUsers, authzenTodoVectors, describePolicy, expectTypeOf, jwtFixtureAudience, jwtFixtureIssuer, jwtFixtureJwks, jwtFixtureTokens, policyMatrix, seedRows, snapshotFixture, supabaseClaimFixtures, supabaseClaimVectors, supabaseHookManifestFixture, supabaseMembershipsBudget, testAccessReviewStore, testAgentAdapter, testAgentRuntime, testApprovalDelegationSource, testApprovalPolicySource, testApprovalStore, testApprovalWaiter, testAuthzen, testAutomationSource, testClientParity, testClientStore, testCloudApi, testCredentialVerifier, testCustomRoleSource, testDecisionProvider, testDecisionSink, testDeliveryTransport, testDirectoryStore, testEntitlementSource, testHttpAdapter, testIdempotencyStore, testLegacyParity, testLimitStore, testMembershipSource, testOrmParity, testPolicySource, testPrincipalSource, testRelationSource, testReplayStore, testRevocationFeed, testRlsParity, testSetQueue, testSettingsSource, testSnapshotSource, testSnapshotStorage, testSsfStreamStore, testSubjectResolver, testSupportSessionSource, testTokenSigner, testTokenVerifier, testVersionCache, testWhereCompiler };