@classytic/arc 2.41.1 → 2.44.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 (248) hide show
  1. package/dist/{EventTransport-CbUKDzZZ.d.mts → EventTransport-CiicKz2Z.d.mts} +1 -1
  2. package/dist/{EventTransport-DSqD_Xsg.mjs → EventTransport-DZWDsaPa.mjs} +22 -17
  3. package/dist/{HookSystem-CMF94SEA.mjs → HookSystem-yjEgn7Cm.mjs} +2 -2
  4. package/dist/{QueryCache-DFA-QrU9.d.mts → QueryCache--5uAuYPW.d.mts} +7 -3
  5. package/dist/{ResourceRegistry-MGpXoxHZ.mjs → ResourceRegistry-DJxHUpE4.mjs} +44 -13
  6. package/dist/acquire-BozJ-9yt.mjs +35 -0
  7. package/dist/actionPermissions-5N04zBL4.mjs +772 -0
  8. package/dist/audit/index.d.mts +46 -8
  9. package/dist/audit/index.mjs +48 -26
  10. package/dist/auth/audit.d.mts +8 -8
  11. package/dist/auth/audit.mjs +1 -1
  12. package/dist/auth/index.d.mts +46 -16
  13. package/dist/auth/index.mjs +134 -156
  14. package/dist/auth/redis-session.d.mts +4 -5
  15. package/dist/auth/redis-session.mjs +1 -1
  16. package/dist/{authorizationDecision-DawKGoXb.mjs → authorizationDecision-wX3SA9w_.mjs} +7 -102
  17. package/dist/{base-CxrV1LmG.d.mts → base-CZyixEQR.d.mts} +27 -5
  18. package/dist/boundedMap-DWiKW7lP.mjs +57 -0
  19. package/dist/{buildHandler-CvxKOc0m.mjs → buildHandler-Bswu_vNb.mjs} +4 -4
  20. package/dist/cache/index.d.mts +31 -43
  21. package/dist/cache/index.mjs +4 -4
  22. package/dist/{caching-DbCBxlgw.mjs → caching-Drp68DIS.mjs} +3 -3
  23. package/dist/claimed-DYvQoZLv.mjs +8 -0
  24. package/dist/cleanup/index.d.mts +18 -22
  25. package/dist/cleanup/index.mjs +27 -73
  26. package/dist/cli/commands/describe.d.mts +7 -5
  27. package/dist/cli/commands/describe.mjs +7 -4
  28. package/dist/cli/commands/docs.d.mts +2 -3
  29. package/dist/cli/commands/docs.mjs +3 -3
  30. package/dist/cli/commands/doctor.d.mts +2 -3
  31. package/dist/cli/commands/doctor.mjs +1 -1
  32. package/dist/cli/commands/generate.mjs +2 -3
  33. package/dist/cli/commands/init.mjs +2 -3
  34. package/dist/cli/commands/introspect.d.mts +2 -3
  35. package/dist/cli/commands/introspect.mjs +2 -2
  36. package/dist/cli/index.mjs +3 -3
  37. package/dist/{constants-D5Ubn1fe.mjs → constants-B2QHb6u6.mjs} +4 -2
  38. package/dist/context/index.d.mts +11 -14
  39. package/dist/context/index.mjs +18 -38
  40. package/dist/core/index.d.mts +3 -3
  41. package/dist/core/index.mjs +8 -8
  42. package/dist/{core-5lazhva9.mjs → core-COcqo0Cp.mjs} +15 -5
  43. package/dist/{createActionRouter-DNqoaK81.mjs → createActionRouter-zG13rpPJ.mjs} +97 -39
  44. package/dist/{createAggregationRouter-BcbQJf10.mjs → createAggregationRouter-CWRz96Vr.mjs} +11 -8
  45. package/dist/{preloadResources-f3boenVZ.mjs → createApp-BGLYtErt.mjs} +305 -394
  46. package/dist/{createMcpServer-CbDWkZ1T.d.mts → createMcpServer-DSztofa9.d.mts} +1 -1
  47. package/dist/{defineAggregation-D_eJjm5A.mjs → defineAggregation--3xguLkk.mjs} +1 -1
  48. package/dist/{defineResource-DxkMTjRn.mjs → defineResource-gUp9ug66.mjs} +118 -1024
  49. package/dist/discovery/index.d.mts +6 -7
  50. package/dist/discovery/index.mjs +1 -1
  51. package/dist/docs/index.d.mts +11 -5
  52. package/dist/docs/index.mjs +4 -4
  53. package/dist/{elevation-CkvG0LG2.mjs → elevation-BG4gnMsJ.mjs} +41 -12
  54. package/dist/{elevation-BXCfVcNG.d.mts → elevation-BW2J3tNj.d.mts} +1 -2
  55. package/dist/encryption/index.d.mts +5 -5
  56. package/dist/encryption/index.mjs +3 -3
  57. package/dist/{errorHandler-D1GHKGlV.mjs → errorHandler-COHw3N1b.mjs} +26 -5
  58. package/dist/{errors-BH7YU_9O.mjs → errors-CW4anJBy.mjs} +58 -23
  59. package/dist/{errors-BGdVwP25.d.mts → errors-JYc9vwqE.d.mts} +9 -0
  60. package/dist/{eventPlugin-B52abJ8W.d.mts → eventPlugin-BtmA4-3P.d.mts} +65 -9
  61. package/dist/{eventPlugin-zZY-unhr.mjs → eventPlugin-BweHAVws.mjs} +82 -21
  62. package/dist/{subscribe-helpers-DatDkcuG.mjs → eventTypes-N4-omQFR.mjs} +151 -17
  63. package/dist/events/index.d.mts +43 -18
  64. package/dist/events/index.mjs +49 -53
  65. package/dist/events/transports/redis-stream-entry.d.mts +1 -1
  66. package/dist/events/transports/redis-stream-entry.mjs +139 -157
  67. package/dist/events/transports/redis.d.mts +5 -6
  68. package/dist/events/transports/redis.mjs +2 -2
  69. package/dist/factory/index.d.mts +42 -27
  70. package/dist/factory/index.mjs +213 -32
  71. package/dist/{fastify-augmentation-Cq2nHVaW.d.mts → fastify-augmentation-DRlCIWE9.d.mts} +11 -25
  72. package/dist/{fields-BHrkoF5y.mjs → fields-A5crhsJb.mjs} +1 -1
  73. package/dist/{fields-I_EeRWND.d.mts → fields-BBSpf8pS.d.mts} +1 -1
  74. package/dist/filter-merge-DGM-GQ1J.mjs +99 -0
  75. package/dist/{generate-BLRf2m3y.mjs → generate-BXKo2Gc8.mjs} +2 -2
  76. package/dist/{headers-BIXWKrzQ.mjs → headers-DKZQKL-Z.mjs} +2 -2
  77. package/dist/health-BYAwA6YS.mjs +22 -0
  78. package/dist/{health-ZRHeDHXH.mjs → health-CrqUp3sz.mjs} +115 -55
  79. package/dist/hooks/index.d.mts +2 -2
  80. package/dist/hooks/index.mjs +2 -3
  81. package/dist/idempotency/index.d.mts +36 -10
  82. package/dist/idempotency/index.mjs +230 -111
  83. package/dist/idempotency/redis.d.mts +1 -1
  84. package/dist/idempotency/redis.mjs +77 -12
  85. package/dist/{index-D4u76eQW.d.mts → index-Beg3aNnK.d.mts} +23 -101
  86. package/dist/{preloadResources-CjS2OfpU.d.mts → index-BkV55WlV.d.mts} +37 -38
  87. package/dist/{index-BHdZD8zK.d.mts → index-Bxriq3so.d.mts} +84 -21
  88. package/dist/index-CUJvoyw3.d.mts +510 -0
  89. package/dist/{index-CbJiYrfv.d.mts → index-Chgz3d0i.d.mts} +1 -1
  90. package/dist/{index-DHbyPo5j.d.mts → index-WH7xgvxS.d.mts} +304 -254
  91. package/dist/index.d.mts +9 -9
  92. package/dist/index.mjs +11 -11
  93. package/dist/{init-CpLkjU18.mjs → init-BPzK5Lnr.mjs} +1 -1
  94. package/dist/integrations/event-gateway.d.mts +11 -7
  95. package/dist/integrations/event-gateway.mjs +4 -4
  96. package/dist/integrations/index.d.mts +3 -3
  97. package/dist/integrations/index.mjs +1 -1
  98. package/dist/integrations/jobs/index.d.mts +1 -1
  99. package/dist/integrations/jobs/index.mjs +18 -5
  100. package/dist/integrations/mcp/index.d.mts +102 -89
  101. package/dist/integrations/mcp/index.mjs +19 -4
  102. package/dist/integrations/mcp/testing.d.mts +8 -9
  103. package/dist/integrations/mcp/testing.mjs +2 -2
  104. package/dist/integrations/streamline.d.mts +85 -144
  105. package/dist/integrations/streamline.mjs +131 -55
  106. package/dist/integrations/webhooks.d.mts +83 -143
  107. package/dist/integrations/webhooks.mjs +36 -80
  108. package/dist/integrations/websocket-pushref-redis.d.mts +5 -6
  109. package/dist/integrations/websocket-pushref-redis.mjs +1 -1
  110. package/dist/integrations/websocket-redis.d.mts +5 -6
  111. package/dist/integrations/websocket-redis.mjs +1 -1
  112. package/dist/integrations/websocket.d.mts +3 -3
  113. package/dist/integrations/websocket.mjs +2 -2
  114. package/dist/{interface-DEWNOMza.d.mts → interface-JJzwH4Ro.d.mts} +34 -2
  115. package/dist/{jsonBody-ELR9lfeU.mjs → jsonBody-YIq-vGLv.mjs} +2 -2
  116. package/dist/{keys-cpZCtcIE.mjs → keys-CpoiZ8hU.mjs} +7 -18
  117. package/dist/{loadResources-BPfWiI5s.mjs → loadResources-6jO52-RR.mjs} +3 -3
  118. package/dist/{loadResourcesFromEntry-ixtfL3J2.mjs → loadResourcesFromEntry-MP8xEppu.mjs} +2 -2
  119. package/dist/logger/index.d.mts +9 -17
  120. package/dist/logger/index.mjs +2 -153
  121. package/dist/logger-D4V1zGLI.mjs +160 -0
  122. package/dist/{mcpPlugin-BX5PujI0.mjs → mcpPlugin-srPc7ItN.mjs} +446 -170
  123. package/dist/{memory-Iotz0cCx.mjs → memory-CTa5pOCW.mjs} +36 -34
  124. package/dist/{metrics-NMsmpRmY.mjs → metrics-DsZrvnpB.mjs} +39 -72
  125. package/dist/middleware/index.d.mts +5 -5
  126. package/dist/middleware/index.mjs +3 -3
  127. package/dist/migrations/index.d.mts +13 -13
  128. package/dist/migrations/index.mjs +2 -2
  129. package/dist/{module-DpLJG2_N.mjs → module--L0iBIZz.mjs} +8 -8
  130. package/dist/mongodb-memory-server-CHhYSq5y.mjs +35539 -0
  131. package/dist/mongoose-CYJCLyi-.mjs +67451 -0
  132. package/dist/multiTenant-CAtYlW6H.d.mts +104 -0
  133. package/dist/{multipartBody-DtRWM6_U.mjs → multipartBody-Cc7eZ9cq.mjs} +46 -7
  134. package/dist/node-D8UZv_8c.mjs +41236 -0
  135. package/dist/{openapi-CmFf3yq_.mjs → openapi-CMegfsm8.mjs} +48 -10
  136. package/dist/outbox-admin/index.d.mts +5 -5
  137. package/dist/outbox-admin/index.mjs +6 -18
  138. package/dist/{outbox-module-D2z5WkDY.mjs → outbox-module-Ryk270jd.mjs} +203 -33
  139. package/dist/{outbox-module-BHdUnuuK.d.mts → outbox-module-gZCHoE4H.d.mts} +79 -6
  140. package/dist/permissions/index.d.mts +5 -4
  141. package/dist/permissions/index.mjs +8 -6
  142. package/dist/{permissions-D8TBH44E.mjs → permissions-C5ijIz5Q.mjs} +149 -33
  143. package/dist/{pipe-FMWNheSO.mjs → pipe-D81zMtWs.mjs} +2 -2
  144. package/dist/pipeline/index.d.mts +7 -7
  145. package/dist/pipeline/index.mjs +2 -2
  146. package/dist/plan-CJGMKoui.mjs +565 -0
  147. package/dist/{BaseController-CYEwjyjN.mjs → plugin-DALd9dcF.mjs} +1269 -346
  148. package/dist/plugins/index.d.mts +17 -14
  149. package/dist/plugins/index.mjs +44 -22
  150. package/dist/plugins/response-cache.d.mts +5 -6
  151. package/dist/plugins/response-cache.mjs +8 -14
  152. package/dist/plugins/tracing-entry.mjs +2 -2
  153. package/dist/{pluralize-CXWZIzTv.mjs → pluralize-COUNYo3d.mjs} +1 -1
  154. package/dist/presets/filesUpload.d.mts +8 -8
  155. package/dist/presets/filesUpload.mjs +5 -5
  156. package/dist/presets/index.d.mts +35 -40
  157. package/dist/presets/index.mjs +4 -4
  158. package/dist/presets/multiTenant.d.mts +2 -107
  159. package/dist/presets/multiTenant.mjs +22 -162
  160. package/dist/presets/search.d.mts +9 -10
  161. package/dist/presets/search.mjs +2 -2
  162. package/dist/{presets-ZJSPgmT2.mjs → presets-CONf2Qem.mjs} +99 -107
  163. package/dist/{projection-BzIgzoKZ.mjs → projection-wFoLqdss.mjs} +2 -2
  164. package/dist/{pushref-registry-Dov9l4qE.d.mts → pushref-registry-UxCkoA4C.d.mts} +1 -1
  165. package/dist/{queryCachePlugin-DZHPOm9p.mjs → queryCachePlugin-BATECpyh.mjs} +12 -14
  166. package/dist/{queryCachePlugin-BzqxconG.d.mts → queryCachePlugin-C2lZjTxk.d.mts} +1 -1
  167. package/dist/{rateLimitKey-BvOvcBDi.mjs → rateLimitKey-DVEZ_UpV.mjs} +1 -1
  168. package/dist/{realtime-8tIQWZz4.mjs → realtime-xyubMKSB.mjs} +25 -21
  169. package/dist/{redis-Bzi1y3F9.d.mts → redis-BDgv9Glw.d.mts} +17 -24
  170. package/dist/redis-stream-BMk-bpQS.d.mts +219 -0
  171. package/dist/redisShapes-CQksY67q.d.mts +55 -0
  172. package/dist/registry/index.d.mts +15 -10
  173. package/dist/registry/index.mjs +4 -4
  174. package/dist/{registry-DNkgGQcK.mjs → registry-Bdzg-hdm.mjs} +13 -10
  175. package/dist/{renewingLease-yF8BdW4b.mjs → renewingLease-BFJxGPuh.mjs} +1 -1
  176. package/dist/{replyHelpers-CNdvMfM4.mjs → replyHelpers-Bnc6lJyy.mjs} +2 -2
  177. package/dist/{requestContext-cDkAUr-P.mjs → requestContext-C10UeFe5.mjs} +1 -1
  178. package/dist/requirement-Bu50QALH.mjs +35 -0
  179. package/dist/requirement-CbiLdQ1n.d.mts +22 -0
  180. package/dist/resourceRateLimit-Wf6d6FL9.d.mts +30 -0
  181. package/dist/resourceRateLimit-urWPJxrt.mjs +180 -0
  182. package/dist/rolldown-runtime-MYrLNGnq.mjs +45 -0
  183. package/dist/routeValidator-DHtpzrzk.mjs +70 -0
  184. package/dist/{runtimeCapabilities-CkhS6jn6.mjs → runtimeCapabilities-DIMKMV2G.mjs} +1 -1
  185. package/dist/{schedules-j6uXXAeJ.mjs → schedules-CKTs5ys8.mjs} +46 -37
  186. package/dist/{schemaConverter-BVA7cFRG.mjs → schemaConverter-BVjkQ5DD.mjs} +2 -2
  187. package/dist/{schemaIR-CTvPDoPB.mjs → schemaIR-BA0Hb21Y.mjs} +2 -2
  188. package/dist/schemas/index.d.mts +20 -10
  189. package/dist/schemas/index.mjs +8 -3
  190. package/dist/scim/index.d.mts +13 -13
  191. package/dist/scim/index.mjs +2 -2
  192. package/dist/scope/index.d.mts +4 -4
  193. package/dist/scope/index.mjs +6 -6
  194. package/dist/{scope-BUi1xV1I.mjs → scope-DINaj7Ax.mjs} +4 -4
  195. package/dist/shutdown-LpLMH8T1.mjs +59 -0
  196. package/dist/{simpleEqualityMatcher-C9bzq2gO.mjs → simpleEqualityMatcher-DbwIM1f1.mjs} +1 -1
  197. package/dist/{sse-BeqVKQKu.mjs → sse-BzJFPX_1.mjs} +11 -15
  198. package/dist/{sseStream-Ppzo-WUH.mjs → sseStream-DQChzGTs.mjs} +2 -2
  199. package/dist/{store-helpers-dW71XVWL.mjs → store-helpers-Coj9RhOZ.mjs} +1 -1
  200. package/dist/{streaming-IcRFjWQU.mjs → streaming-JzB5CAga.mjs} +1 -1
  201. package/dist/subscriberIdentity-DeyppIif.mjs +28 -0
  202. package/dist/tenancy-DxV8OuX2.mjs +43 -0
  203. package/dist/tenantPreparation-CBvvAcAj.mjs +67 -0
  204. package/dist/testing/cleanupStoreContract.d.mts +4 -5
  205. package/dist/testing/cleanupStoreContract.mjs +1 -1
  206. package/dist/testing/index.d.mts +215 -197
  207. package/dist/testing/index.mjs +289 -214
  208. package/dist/testing/outboxStoreContract.d.mts +4 -5
  209. package/dist/testing/outboxStoreContract.mjs +137 -2
  210. package/dist/testing/requiredPorts.d.mts +16 -0
  211. package/dist/testing/requiredPorts.mjs +65 -0
  212. package/dist/testing/storageContract.d.mts +4 -5
  213. package/dist/testing/storageContract.mjs +1 -1
  214. package/dist/timing-CntavTlR.mjs +46 -0
  215. package/dist/{transactionContext-CPbdlnVw.mjs → transactionContext-orvnGu4F.mjs} +1 -1
  216. package/dist/{typeGuards-BLjPgVBm.mjs → typeGuards-kEaP_WmO.mjs} +1 -1
  217. package/dist/types/index.d.mts +4 -4
  218. package/dist/types/index.mjs +1 -1
  219. package/dist/types/storage.mjs +1 -1
  220. package/dist/{types-DfVDvkdP.d.mts → types-BJ-2XqVF.d.mts} +189 -204
  221. package/dist/{types-CWQn9-IC.d.mts → types-D3Ixsh00.d.mts} +22 -9
  222. package/dist/{types-CgenB1gv.mjs → types-fvO6Ovzx.mjs} +4 -4
  223. package/dist/usage/index.d.mts +5 -6
  224. package/dist/usage/index.mjs +5 -5
  225. package/dist/{userHelpers-ChRvkuSZ.mjs → userHelpers-C76zD5pa.mjs} +1 -1
  226. package/dist/utils/index.d.mts +125 -264
  227. package/dist/utils/index.mjs +13 -12
  228. package/dist/{utils-CxcctrAh.mjs → utils-BpkVZ8rB.mjs} +315 -404
  229. package/dist/{validate-DrYWnOzI.mjs → validate-CWp-lsrm.mjs} +6 -14
  230. package/dist/{versioning-D6JIK8Tk.d.mts → versioning-Bsb51gGT.d.mts} +28 -13
  231. package/dist/{versioning-DKkT4hNJ.mjs → versioning-CHhL9P3o.mjs} +4 -4
  232. package/dist/{websocket-BOXVggMf.d.mts → websocket-Cs4awVyD.d.mts} +1 -1
  233. package/dist/{workScope-CxKqoIFn.mjs → workScope-n9a7d_lZ.mjs} +2 -2
  234. package/package.json +57 -59
  235. package/skills/arc/SKILL.md +13 -4
  236. package/skills/arc/references/auth.md +8 -5
  237. package/skills/arc/references/integrations.md +1 -1
  238. package/skills/arc/references/mcp.md +8 -6
  239. package/skills/arc/references/multi-tenancy.md +19 -14
  240. package/skills/arc/references/production.md +27 -10
  241. package/dist/actionPermissions-BoPGQ5-4.mjs +0 -350
  242. package/dist/index-CFfLKMH4.d.mts +0 -290
  243. package/dist/interface-YzIbF7Ii.mjs +0 -17
  244. package/dist/redis-stream-BPKscsTB.d.mts +0 -260
  245. package/dist/registerRoute-Bsnk6NiZ.mjs +0 -364
  246. package/dist/rolldown-runtime-eysyzFAF.mjs +0 -15
  247. package/dist/sync/changelog.d.mts +0 -3
  248. package/dist/sync/changelog.mjs +0 -3
@@ -1,12 +1,14 @@
1
- /*! @classytic/arc v2.41.1 | MIT | https://classytic.com */
2
- import { t as CRUD_OPERATIONS } from "../constants-D5Ubn1fe.mjs";
3
- import { g as getUserId } from "../types-CgenB1gv.mjs";
4
- import { t as BaseController } from "../BaseController-CYEwjyjN.mjs";
5
- import { t as defineAggregation } from "../defineAggregation-D_eJjm5A.mjs";
6
- import { t as defineResource } from "../defineResource-DxkMTjRn.mjs";
7
- import { E as requireOrgRole } from "../permissions-D8TBH44E.mjs";
8
- import { a as createApp, n as preloadResourcesAsync, t as preloadResources } from "../preloadResources-f3boenVZ.mjs";
9
- import { n as getModuleExports } from "../module-DpLJG2_N.mjs";
1
+ /*! @classytic/arc v2.44.0 | MIT | https://classytic.com */
2
+ import { o as __toESM } from "../rolldown-runtime-MYrLNGnq.mjs";
3
+ import { t as CRUD_OPERATIONS } from "../constants-B2QHb6u6.mjs";
4
+ import { c as BaseController } from "../plugin-DALd9dcF.mjs";
5
+ import { g as getUserId } from "../types-fvO6Ovzx.mjs";
6
+ import { t as defineAggregation } from "../defineAggregation--3xguLkk.mjs";
7
+ import { t as defineResource } from "../defineResource-gUp9ug66.mjs";
8
+ import { E as requireOrgRole } from "../permissions-C5ijIz5Q.mjs";
9
+ import { h as asModulePorts, r as createApp } from "../createApp-BGLYtErt.mjs";
10
+ import { d as resolveModule, l as isLazyBridge, o as resolveModuleClosure } from "../plan-CJGMKoui.mjs";
11
+ import { n as getModuleExports } from "../module--L0iBIZz.mjs";
10
12
  import { runStorageContract } from "./storageContract.mjs";
11
13
  import Fastify from "fastify";
12
14
  import { afterAll, describe, expect, it, vi } from "vitest";
@@ -134,6 +136,243 @@ function expectArc(response) {
134
136
  return assertion;
135
137
  }
136
138
  //#endregion
139
+ //#region src/testing/testActor.ts
140
+ /**
141
+ * Test-only actor installation — how a package's HTTP tests say "run this
142
+ * request as a manager in org X".
143
+ *
144
+ * Identity in arc comes from `request.scope` and only from `request.scope`;
145
+ * headers like `x-role` are not identity. That rule left tests with no seam —
146
+ * `bootModuleApp` boots with `auth: false`, so every injected request arrived as
147
+ * `PUBLIC_SCOPE` and any role-gated route answered 401 with no supported way to
148
+ * be somebody.
149
+ *
150
+ * The `x-test-actor` header is a TRANSPORT for the test's intent, not a trusted
151
+ * claim. The authenticator that reads it is installed by `bootModuleApp` alone,
152
+ * behind the `@classytic/arc/testing` entrypoint; `createApp` never registers
153
+ * it, so no production build turns a forged header into identity. It is
154
+ * per-request rather than boot-only because the interesting authorization tests
155
+ * are the ones where a cashier is refused what a manager is allowed.
156
+ *
157
+ * Gate the routes under test with arc's own primitives — `requireRoles`,
158
+ * `requireOrgMembership`, `allOf(...)`. A test-specific gate would be a second
159
+ * implementation of authorization whose semantics could drift from the one
160
+ * actually shipping.
161
+ */
162
+ /** The header the testing harness uses to carry a request's actor. */
163
+ const TEST_ACTOR_HEADER = "x-test-actor";
164
+ /**
165
+ * Build the headers that make an injected request act as `actor`.
166
+ *
167
+ * A string is shorthand for a single role. `null` means "stay public", so a test
168
+ * can prove an endpoint is reachable anonymously.
169
+ *
170
+ * @example
171
+ * ```ts
172
+ * t.app.inject({ method: 'GET', url: '/pos/shifts/current',
173
+ * headers: testActorHeaders('manager', ORG) });
174
+ * ```
175
+ */
176
+ function testActorHeaders(actor, organizationId) {
177
+ if (actor === null) return {};
178
+ const org = organizationId !== void 0 ? { organizationId } : {};
179
+ const spec = typeof actor === "string" ? {
180
+ roles: [actor],
181
+ ...org
182
+ } : {
183
+ ...actor,
184
+ ...org
185
+ };
186
+ return { [TEST_ACTOR_HEADER]: JSON.stringify(spec) };
187
+ }
188
+ /**
189
+ * Turn a spec into a `RequestScope`.
190
+ *
191
+ * `orgRoles` defaults to `roles`: a test that says "manager" means it at both
192
+ * levels, and making the caller repeat itself only produces tests that pass a
193
+ * global gate and mysteriously fail an org one.
194
+ */
195
+ function scopeFromTestActor(spec) {
196
+ const roles = spec.roles ?? [];
197
+ const userId = spec.userId ?? `test-${roles.join("-") || "anon"}`;
198
+ if (spec.elevated !== void 0 && spec.elevated !== false) return {
199
+ kind: "elevated",
200
+ userId,
201
+ elevatedBy: spec.elevated === true ? "test" : spec.elevated,
202
+ ...spec.organizationId !== void 0 ? { organizationId: spec.organizationId } : {},
203
+ ...spec.context !== void 0 ? { context: Object.freeze({ ...spec.context }) } : {}
204
+ };
205
+ if (spec.organizationId !== void 0) return {
206
+ kind: "member",
207
+ userId,
208
+ userRoles: roles,
209
+ organizationId: spec.organizationId,
210
+ orgRoles: spec.orgRoles ?? roles,
211
+ ...spec.teamId !== void 0 ? { teamId: spec.teamId } : {},
212
+ ...spec.context !== void 0 ? { context: Object.freeze({ ...spec.context }) } : {}
213
+ };
214
+ return {
215
+ kind: "authenticated",
216
+ userId,
217
+ userRoles: roles
218
+ };
219
+ }
220
+ /**
221
+ * Build the `auth` option that makes the test actor arc's authenticator.
222
+ *
223
+ * It must be an authenticator, not a hook. Fastify encapsulates plugins and
224
+ * modules register DURING `createApp`, so a hook added to the root instance
225
+ * afterwards never runs for their routes — every request still resolves as
226
+ * public and every role gate still answers 401, which reads exactly like a
227
+ * broken authorization rule in the code under test. Registering as
228
+ * `auth: { type: 'authenticator' }` puts the scope where arc's own auth would,
229
+ * at the phase arc expects, so tenant filtering and permission checks behave
230
+ * identically to production.
231
+ *
232
+ * `defaultActor` applies to requests carrying no header. A malformed header
233
+ * REJECTS rather than falling back to public — a test that meant to be an admin
234
+ * and got quietly demoted is the most expensive way to fail.
235
+ */
236
+ function testActorAuth(defaultActor) {
237
+ const authenticate = async (request) => {
238
+ const req = request;
239
+ const raw = req.headers[TEST_ACTOR_HEADER];
240
+ let spec = defaultActor;
241
+ if (typeof raw === "string") try {
242
+ spec = JSON.parse(raw);
243
+ } catch {
244
+ throw new Error(`[arc-testing] malformed ${TEST_ACTOR_HEADER} header: ${raw}. Build it with testActorHeaders() rather than by hand.`);
245
+ }
246
+ if (spec === void 0) return;
247
+ req.scope = scopeFromTestActor(spec);
248
+ req.user = {
249
+ id: getUserId(req.scope) ?? "test-anon",
250
+ ...spec.roles !== void 0 ? { role: spec.roles } : {},
251
+ ...spec.organizationId !== void 0 ? { organizationId: spec.organizationId } : {}
252
+ };
253
+ };
254
+ return {
255
+ type: "authenticator",
256
+ authenticate
257
+ };
258
+ }
259
+ //#endregion
260
+ //#region src/testing/bootModuleApp.ts
261
+ /**
262
+ * The built-in DB factory: in-memory MongoDB via lazy devDep imports.
263
+ * Everything Mongo-specific about the harness lives HERE — the harness
264
+ * itself is driver-blind and any kit can replace this via `database`.
265
+ */
266
+ async function mongoMemoryDatabase(opts) {
267
+ let mms;
268
+ try {
269
+ mms = await import("../mongodb-memory-server-CHhYSq5y.mjs").then((m) => /* @__PURE__ */ __toESM(m.default, 1));
270
+ } catch {
271
+ throw new Error("[arc-testing] bootModuleApp's default database is in-memory MongoDB — install 'mongodb-memory-server' + 'mongoose' as devDependencies, or inject your own `database` factory for a different store");
272
+ }
273
+ const server = opts.replset ? await mms.MongoMemoryReplSet.create({ replSet: { count: 1 } }) : await mms.MongoMemoryServer.create();
274
+ const uri = server.getUri();
275
+ const mongoose = (await import("../mongoose-CYJCLyi-.mjs").then((m) => /* @__PURE__ */ __toESM(m.default, 1))).default;
276
+ if (mongoose.connection.readyState !== 0) await mongoose.disconnect();
277
+ await mongoose.connect(uri);
278
+ mongoose.connection.deleteModel(/.*/);
279
+ return {
280
+ uri,
281
+ connection: mongoose.connection,
282
+ teardown: async () => {
283
+ if (mongoose.connection.readyState !== 0) await mongoose.disconnect().catch(() => void 0);
284
+ await server.stop().catch(() => void 0);
285
+ }
286
+ };
287
+ }
288
+ async function bootModuleApp(modules, options = {}) {
289
+ const db = await (options.database ?? mongoMemoryDatabase)({ replset: options.replset ?? false });
290
+ const ctx = {
291
+ uri: db.uri,
292
+ connection: db.connection
293
+ };
294
+ const resolved = typeof modules === "function" ? await modules(ctx) : modules;
295
+ const list = Array.isArray(resolved) ? resolved : [resolved];
296
+ let app;
297
+ try {
298
+ app = await createApp({
299
+ preset: "testing",
300
+ /**
301
+ * The test actor is arc's AUTHENTICATOR rather than a bolted-on hook, so the scope
302
+ * lands at the phase the rest of the pipeline expects — tenant filtering and
303
+ * permission checks then behave exactly as they do in production.
304
+ *
305
+ * This replaces the old `auth: false`. The authenticator is inert for a request
306
+ * carrying no `x-test-actor` header and no configured default, so a suite that
307
+ * never mentions an actor behaves as it did before. `options.app` still wins, so a
308
+ * suite exercising real auth can override it.
309
+ */
310
+ auth: testActorAuth(options.actor),
311
+ sensible: false,
312
+ ...options.app,
313
+ ...options.ports ? { ports: options.ports } : {},
314
+ modules: list
315
+ });
316
+ await app.ready();
317
+ } catch (err) {
318
+ await db.teardown().catch(() => void 0);
319
+ throw err;
320
+ }
321
+ let closed = false;
322
+ return {
323
+ app,
324
+ uri: db.uri,
325
+ connection: db.connection,
326
+ exports: (name) => getModuleExports(app, name),
327
+ close: async () => {
328
+ if (closed) return;
329
+ closed = true;
330
+ await app.close().catch(() => void 0);
331
+ await db.teardown().catch(() => void 0);
332
+ }
333
+ };
334
+ }
335
+ //#endregion
336
+ //#region src/testing/assertModuleBootsAlone.ts
337
+ /**
338
+ * Boot a module inside its closure — `resolveModuleClosure` (its `dependsOn` and
339
+ * `requires.modules`, transitively, plus every platform module) and every bridge in the list,
340
+ * which arc activates only when both ends are present — and fail naming the module when the boot
341
+ * or the `probe` throws. A hidden edge fails here, by name.
342
+ *
343
+ * ```ts
344
+ * it("order boots alone", () => assertModuleBootsAlone(allModules, "order", { probe: (t) => drivePorts(t) }));
345
+ * ```
346
+ */
347
+ async function assertModuleBootsAlone(modules, name, options = {}) {
348
+ const roots = typeof name === "string" ? [name] : name;
349
+ const label = roots.map((r) => `"${r}"`).join(" + ");
350
+ let closure = [];
351
+ try {
352
+ const { probe, ...bootOptions } = options;
353
+ const t = await bootModuleApp(async (ctx) => {
354
+ const resolved = typeof modules === "function" ? await modules(ctx) : modules;
355
+ const inputs = isInputList(resolved) ? resolved : [resolved];
356
+ const nodes = await Promise.all(inputs.map((input) => isLazyBridge(input) ? input : resolveModule(input)));
357
+ const included = new Set(resolveModuleClosure(nodes, roots).map((m) => m.name));
358
+ closure = nodes.filter((m) => included.has(m.name)).map((m) => m.name);
359
+ return nodes.filter((m) => included.has(m.name) || m.kind === "bridge");
360
+ }, bootOptions);
361
+ try {
362
+ await probe?.(t);
363
+ } finally {
364
+ await t.close();
365
+ }
366
+ } catch (err) {
367
+ const msg = err instanceof Error ? err.message : String(err);
368
+ throw new Error(`[arc/testing] module ${label} does not boot alone in its closure [${closure.join(", ") || "unresolved"}]: ${msg}`, { cause: err });
369
+ }
370
+ return { closure };
371
+ }
372
+ function isInputList(value) {
373
+ return Array.isArray(value);
374
+ }
375
+ //#endregion
137
376
  //#region src/testing/mocks.ts
138
377
  /**
139
378
  * Create a mock repository for testing
@@ -833,202 +1072,6 @@ async function setupBetterAuthTestApp(input) {
833
1072
  };
834
1073
  }
835
1074
  //#endregion
836
- //#region src/testing/testActor.ts
837
- /**
838
- * Test-only actor installation — how a package's HTTP tests say "run this
839
- * request as a manager in org X".
840
- *
841
- * Identity in arc comes from `request.scope` and only from `request.scope`;
842
- * headers like `x-role` are not identity. That rule left tests with no seam —
843
- * `bootModuleApp` boots with `auth: false`, so every injected request arrived as
844
- * `PUBLIC_SCOPE` and any role-gated route answered 401 with no supported way to
845
- * be somebody.
846
- *
847
- * The `x-test-actor` header is a TRANSPORT for the test's intent, not a trusted
848
- * claim. The authenticator that reads it is installed by `bootModuleApp` alone,
849
- * behind the `@classytic/arc/testing` entrypoint; `createApp` never registers
850
- * it, so no production build turns a forged header into identity. It is
851
- * per-request rather than boot-only because the interesting authorization tests
852
- * are the ones where a cashier is refused what a manager is allowed.
853
- *
854
- * Gate the routes under test with arc's own primitives — `requireRoles`,
855
- * `requireOrgMembership`, `allOf(...)`. A test-specific gate would be a second
856
- * implementation of authorization whose semantics could drift from the one
857
- * actually shipping.
858
- */
859
- /** The header the testing harness uses to carry a request's actor. */
860
- const TEST_ACTOR_HEADER = "x-test-actor";
861
- /**
862
- * Build the headers that make an injected request act as `actor`.
863
- *
864
- * A string is shorthand for a single role. `null` means "stay public", so a test
865
- * can prove an endpoint is reachable anonymously.
866
- *
867
- * @example
868
- * ```ts
869
- * t.app.inject({ method: 'GET', url: '/pos/shifts/current',
870
- * headers: testActorHeaders('manager', ORG) });
871
- * ```
872
- */
873
- function testActorHeaders(actor, organizationId) {
874
- if (actor === null) return {};
875
- const org = organizationId !== void 0 ? { organizationId } : {};
876
- const spec = typeof actor === "string" ? {
877
- roles: [actor],
878
- ...org
879
- } : {
880
- ...actor,
881
- ...org
882
- };
883
- return { [TEST_ACTOR_HEADER]: JSON.stringify(spec) };
884
- }
885
- /**
886
- * Turn a spec into a `RequestScope`.
887
- *
888
- * `orgRoles` defaults to `roles`: a test that says "manager" means it at both
889
- * levels, and making the caller repeat itself only produces tests that pass a
890
- * global gate and mysteriously fail an org one.
891
- */
892
- function scopeFromTestActor(spec) {
893
- const roles = spec.roles ?? [];
894
- const userId = spec.userId ?? `test-${roles.join("-") || "anon"}`;
895
- if (spec.elevated !== void 0 && spec.elevated !== false) return {
896
- kind: "elevated",
897
- userId,
898
- elevatedBy: spec.elevated === true ? "test" : spec.elevated,
899
- ...spec.organizationId !== void 0 ? { organizationId: spec.organizationId } : {},
900
- ...spec.context !== void 0 ? { context: Object.freeze({ ...spec.context }) } : {}
901
- };
902
- if (spec.organizationId !== void 0) return {
903
- kind: "member",
904
- userId,
905
- userRoles: roles,
906
- organizationId: spec.organizationId,
907
- orgRoles: spec.orgRoles ?? roles,
908
- ...spec.teamId !== void 0 ? { teamId: spec.teamId } : {},
909
- ...spec.context !== void 0 ? { context: Object.freeze({ ...spec.context }) } : {}
910
- };
911
- return {
912
- kind: "authenticated",
913
- userId,
914
- userRoles: roles
915
- };
916
- }
917
- /**
918
- * Build the `auth` option that makes the test actor arc's authenticator.
919
- *
920
- * It must be an authenticator, not a hook. Fastify encapsulates plugins and
921
- * modules register DURING `createApp`, so a hook added to the root instance
922
- * afterwards never runs for their routes — every request still resolves as
923
- * public and every role gate still answers 401, which reads exactly like a
924
- * broken authorization rule in the code under test. Registering as
925
- * `auth: { type: 'authenticator' }` puts the scope where arc's own auth would,
926
- * at the phase arc expects, so tenant filtering and permission checks behave
927
- * identically to production.
928
- *
929
- * `defaultActor` applies to requests carrying no header. A malformed header
930
- * REJECTS rather than falling back to public — a test that meant to be an admin
931
- * and got quietly demoted is the most expensive way to fail.
932
- */
933
- function testActorAuth(defaultActor) {
934
- const authenticate = async (request) => {
935
- const req = request;
936
- const raw = req.headers[TEST_ACTOR_HEADER];
937
- let spec = defaultActor;
938
- if (typeof raw === "string") try {
939
- spec = JSON.parse(raw);
940
- } catch {
941
- throw new Error(`[arc-testing] malformed ${TEST_ACTOR_HEADER} header: ${raw}. Build it with testActorHeaders() rather than by hand.`);
942
- }
943
- if (spec === void 0) return;
944
- req.scope = scopeFromTestActor(spec);
945
- req.user = {
946
- id: getUserId(req.scope) ?? "test-anon",
947
- ...spec.roles !== void 0 ? { role: spec.roles } : {},
948
- ...spec.organizationId !== void 0 ? { organizationId: spec.organizationId } : {}
949
- };
950
- };
951
- return {
952
- type: "authenticator",
953
- authenticate
954
- };
955
- }
956
- //#endregion
957
- //#region src/testing/bootModuleApp.ts
958
- /**
959
- * The built-in DB factory: in-memory MongoDB via lazy devDep imports.
960
- * Everything Mongo-specific about the harness lives HERE — the harness
961
- * itself is driver-blind and any kit can replace this via `database`.
962
- */
963
- async function mongoMemoryDatabase(opts) {
964
- let mms;
965
- try {
966
- mms = await import("mongodb-memory-server");
967
- } catch {
968
- throw new Error("[arc-testing] bootModuleApp's default database is in-memory MongoDB — install 'mongodb-memory-server' + 'mongoose' as devDependencies, or inject your own `database` factory for a different store");
969
- }
970
- const server = opts.replset ? await mms.MongoMemoryReplSet.create({ replSet: { count: 1 } }) : await mms.MongoMemoryServer.create();
971
- const uri = server.getUri();
972
- const mongoose = (await import("mongoose")).default;
973
- if (mongoose.connection.readyState !== 0) await mongoose.disconnect();
974
- await mongoose.connect(uri);
975
- mongoose.connection.deleteModel(/.*/);
976
- return {
977
- uri,
978
- connection: mongoose.connection,
979
- teardown: async () => {
980
- if (mongoose.connection.readyState !== 0) await mongoose.disconnect().catch(() => void 0);
981
- await server.stop().catch(() => void 0);
982
- }
983
- };
984
- }
985
- async function bootModuleApp(modules, options = {}) {
986
- const db = await (options.database ?? mongoMemoryDatabase)({ replset: options.replset ?? false });
987
- const ctx = {
988
- uri: db.uri,
989
- connection: db.connection
990
- };
991
- const resolved = typeof modules === "function" ? await modules(ctx) : modules;
992
- const list = Array.isArray(resolved) ? resolved : [resolved];
993
- let app;
994
- try {
995
- app = await createApp({
996
- preset: "testing",
997
- /**
998
- * The test actor is arc's AUTHENTICATOR rather than a bolted-on hook, so the scope
999
- * lands at the phase the rest of the pipeline expects — tenant filtering and
1000
- * permission checks then behave exactly as they do in production.
1001
- *
1002
- * This replaces the old `auth: false`. The authenticator is inert for a request
1003
- * carrying no `x-test-actor` header and no configured default, so a suite that
1004
- * never mentions an actor behaves as it did before. `options.app` still wins, so a
1005
- * suite exercising real auth can override it.
1006
- */
1007
- auth: testActorAuth(options.actor),
1008
- sensible: false,
1009
- ...options.app,
1010
- modules: list
1011
- });
1012
- await app.ready();
1013
- } catch (err) {
1014
- await db.teardown().catch(() => void 0);
1015
- throw err;
1016
- }
1017
- let closed = false;
1018
- return {
1019
- app,
1020
- uri: db.uri,
1021
- connection: db.connection,
1022
- exports: (name) => getModuleExports(app, name),
1023
- close: async () => {
1024
- if (closed) return;
1025
- closed = true;
1026
- await app.close().catch(() => void 0);
1027
- await db.teardown().catch(() => void 0);
1028
- }
1029
- };
1030
- }
1031
- //#endregion
1032
1075
  //#region src/testing/fixtures.ts
1033
1076
  function createTestFixtures() {
1034
1077
  const registry = /* @__PURE__ */ new Map();
@@ -1356,13 +1399,45 @@ function createHttpTestHarness(resource, optionsOrGetter) {
1356
1399
  }
1357
1400
  //#endregion
1358
1401
  //#region src/testing/moduleSetup.ts
1359
- function createTestModuleSetup() {
1402
+ /**
1403
+ * A real `ModuleSetupContext` for tests that invoke a module's setup phases
1404
+ * DIRECTLY — `mod.bootstrap(app, ctx)`, `mod.plugins(app, ctx)` — instead of
1405
+ * booting a whole app through `createApp` / `bootModuleApp`.
1406
+ *
1407
+ * ## Why this is not `{ defer: () => {} }`
1408
+ *
1409
+ * That literal satisfies the type and throws away every disposer the module
1410
+ * registers. A test written against it passes whether the module releases what
1411
+ * it acquired or leaks it, so the one thing `defer` exists to make testable
1412
+ * becomes the one thing that cannot be tested. It also gives a false negative
1413
+ * in the other direction: a module that starts deferring later keeps its green
1414
+ * test, which is precisely the "compiles today, wrong tomorrow" shape the
1415
+ * disposer contract was introduced to remove.
1416
+ *
1417
+ * This collects them instead, and `dispose()` unwinds LIFO — the same order
1418
+ * arc's own teardown uses, so an ordering bug surfaces here rather than in
1419
+ * production shutdown.
1420
+ *
1421
+ * @example
1422
+ * ```ts
1423
+ * const setup = createTestModuleSetup();
1424
+ * const engine = await mod.bootstrap?.(app, setup.context);
1425
+ *
1426
+ * expect(setup.deferred).toHaveLength(1); // it registered its teardown
1427
+ * await setup.dispose(); // and it actually releases
1428
+ * expect(engine.closed).toBe(true);
1429
+ * ```
1430
+ */
1431
+ function createTestModuleSetup(options = {}) {
1360
1432
  const deferred = [];
1361
1433
  return {
1362
- context: { defer(disposer) {
1363
- if (typeof disposer !== "function") throw new TypeError(`[arc/testing] defer() expected a function, received ${typeof disposer}.`);
1364
- deferred.push(disposer);
1365
- } },
1434
+ context: {
1435
+ ports: asModulePorts(Object.freeze({ ...options.ports })),
1436
+ defer(disposer) {
1437
+ if (typeof disposer !== "function") throw new TypeError(`[arc/testing] defer() expected a function, received ${typeof disposer}.`);
1438
+ deferred.push(disposer);
1439
+ }
1440
+ },
1366
1441
  deferred,
1367
1442
  async dispose() {
1368
1443
  const errors = [];
@@ -1473,7 +1548,7 @@ function scopeRoleGate(...allowed) {
1473
1548
  */
1474
1549
  async function startInMemoryMongo() {
1475
1550
  try {
1476
- const { MongoMemoryServer } = await import("mongodb-memory-server");
1551
+ const { MongoMemoryServer } = await import("../mongodb-memory-server-CHhYSq5y.mjs").then((m) => /* @__PURE__ */ __toESM(m.default, 1));
1477
1552
  const mongod = await MongoMemoryServer.create();
1478
1553
  return {
1479
1554
  uri: mongod.getUri(),
@@ -1487,7 +1562,7 @@ async function startInMemoryMongo() {
1487
1562
  }
1488
1563
  async function connectMongooseToUri(uri) {
1489
1564
  try {
1490
- const mongoose = (await import("mongoose")).default;
1565
+ const mongoose = (await import("../mongoose-CYJCLyi-.mjs").then((m) => /* @__PURE__ */ __toESM(m.default, 1))).default;
1491
1566
  await mongoose.connect(uri);
1492
1567
  return { async disconnect() {
1493
1568
  await mongoose.disconnect();
@@ -1504,7 +1579,7 @@ function pickDefaultAuth(authMode, callerAuth) {
1504
1579
  };
1505
1580
  }
1506
1581
  async function createTestApp(options = {}) {
1507
- const { createApp } = await import("../preloadResources-f3boenVZ.mjs").then((n) => n.o);
1582
+ const { createApp } = await import("../createApp-BGLYtErt.mjs").then((n) => n.i);
1508
1583
  const { resources = [], db = "in-memory", connectMongoose = false, authMode = "jwt", defaultOrgId, plugins, auth: callerAuth, ...appOptions } = options;
1509
1584
  let dbHandle;
1510
1585
  let dbUri;
@@ -1574,4 +1649,4 @@ function createMinimalTestApp(options = {}) {
1574
1649
  });
1575
1650
  }
1576
1651
  //#endregion
1577
- export { HttpTestHarness, TEST_ACTOR_HEADER, bootModuleApp, createBetterAuthProvider, createBetterAuthTestHelpers, createCustomAuthProvider, createDataFactory, createHttpTestHarness, createJwtAuthProvider, createMinimalTestApp, createMockController, createMockReply, createMockRepository, createMockRequest, createMockUser, createSpy, createTestApp, createTestFixtures, createTestModuleSetup, createTestTimer, expectArc, mongoMemoryDatabase, preloadResources, preloadResourcesAsync, runAuthorizationConformance, runStorageContract, safeParseBody, scopeFromTestActor, scopeRoleGate, setupBetterAuthTestApp, testActorAuth, testActorHeaders, waitFor };
1652
+ export { HttpTestHarness, TEST_ACTOR_HEADER, assertModuleBootsAlone, bootModuleApp, createBetterAuthProvider, createBetterAuthTestHelpers, createCustomAuthProvider, createDataFactory, createHttpTestHarness, createJwtAuthProvider, createMinimalTestApp, createMockController, createMockReply, createMockRepository, createMockRequest, createMockUser, createSpy, createTestApp, createTestFixtures, createTestModuleSetup, createTestTimer, expectArc, mongoMemoryDatabase, runAuthorizationConformance, runStorageContract, safeParseBody, scopeFromTestActor, scopeRoleGate, setupBetterAuthTestApp, testActorAuth, testActorHeaders, waitFor };
@@ -1,7 +1,7 @@
1
1
 
2
2
  import { OutboxStore } from "@classytic/primitives/outbox";
3
3
  //#region src/testing/outboxStoreContract.d.ts
4
- interface OutboxStoreContractSetupResult {
4
+ export interface OutboxStoreContractSetupResult {
5
5
  store: OutboxStore;
6
6
  /** Called once after the suite. */
7
7
  teardown?: () => Promise<void>;
@@ -17,7 +17,6 @@ interface OutboxStoreContractSetupResult {
17
17
  */
18
18
  reset: () => Promise<void>;
19
19
  }
20
- type OutboxStoreContractSetup = () => Promise<OutboxStoreContractSetupResult>;
21
- declare function runOutboxStoreContract(name: string, setup: OutboxStoreContractSetup): void;
22
- //#endregion
23
- export { OutboxStoreContractSetup, OutboxStoreContractSetupResult, runOutboxStoreContract };
20
+ export type OutboxStoreContractSetup = () => Promise<OutboxStoreContractSetupResult>;
21
+ export declare function runOutboxStoreContract(name: string, setup: OutboxStoreContractSetup): void;
22
+ //#endregion