@warlock.js/core 5.30.0 → 5.31.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 (797) hide show
  1. package/CHANGELOG.md +142 -36
  2. package/README.md +28 -23
  3. package/bin/source-load-hook.mjs +63 -0
  4. package/bin/warlock.js +102 -42
  5. package/esm/cli/commands/add.command.mjs +4 -2
  6. package/esm/cli/commands/add.command.mjs.map +1 -1
  7. package/esm/cli/commands/agents-md/agents-md-command.action.mjs +69 -0
  8. package/esm/cli/commands/agents-md/agents-md-command.action.mjs.map +1 -0
  9. package/esm/cli/commands/agents-md.command.mjs +38 -0
  10. package/esm/cli/commands/agents-md.command.mjs.map +1 -0
  11. package/esm/cli/commands/board/board-command.action.mjs +279 -0
  12. package/esm/cli/commands/board/board-command.action.mjs.map +1 -0
  13. package/esm/cli/commands/board.command.mjs +78 -0
  14. package/esm/cli/commands/board.command.mjs.map +1 -0
  15. package/esm/cli/commands/build.command.mjs +6 -1
  16. package/esm/cli/commands/build.command.mjs.map +1 -1
  17. package/esm/cli/commands/check/check-command.action.mjs +57 -0
  18. package/esm/cli/commands/check/check-command.action.mjs.map +1 -0
  19. package/esm/cli/commands/check/child-typecheck.mjs +66 -0
  20. package/esm/cli/commands/check/child-typecheck.mjs.map +1 -0
  21. package/esm/cli/commands/check/format-problems.mjs +43 -0
  22. package/esm/cli/commands/check/format-problems.mjs.map +1 -0
  23. package/esm/cli/commands/check/typecheck-command.action.mjs +61 -0
  24. package/esm/cli/commands/check/typecheck-command.action.mjs.map +1 -0
  25. package/esm/cli/commands/check.command.mjs +50 -0
  26. package/esm/cli/commands/check.command.mjs.map +1 -0
  27. package/esm/cli/commands/dev-server.command.mjs +9 -1
  28. package/esm/cli/commands/dev-server.command.mjs.map +1 -1
  29. package/esm/cli/commands/doctor/boot-for-diagnostics.mjs +8 -3
  30. package/esm/cli/commands/doctor/boot-for-diagnostics.mjs.map +1 -1
  31. package/esm/cli/commands/doctor/check.types.d.mts +76 -0
  32. package/esm/cli/commands/doctor/check.types.d.mts.map +1 -0
  33. package/esm/cli/commands/doctor/checks/config.check.mjs +1 -0
  34. package/esm/cli/commands/doctor/checks/config.check.mjs.map +1 -1
  35. package/esm/cli/commands/doctor/checks/connectors.check.mjs +2 -0
  36. package/esm/cli/commands/doctor/checks/connectors.check.mjs.map +1 -1
  37. package/esm/cli/commands/doctor/checks/handler-signature.check.mjs +1 -0
  38. package/esm/cli/commands/doctor/checks/handler-signature.check.mjs.map +1 -1
  39. package/esm/cli/commands/doctor/checks/health.check.mjs +3 -0
  40. package/esm/cli/commands/doctor/checks/health.check.mjs.map +1 -1
  41. package/esm/cli/commands/doctor/checks/jwt-secret.check.mjs +1 -0
  42. package/esm/cli/commands/doctor/checks/jwt-secret.check.mjs.map +1 -1
  43. package/esm/cli/commands/doctor/checks/locales-ts-deprecated.check.mjs +1 -0
  44. package/esm/cli/commands/doctor/checks/locales-ts-deprecated.check.mjs.map +1 -1
  45. package/esm/cli/commands/doctor/checks/optional-peers.check.mjs +1 -0
  46. package/esm/cli/commands/doctor/checks/optional-peers.check.mjs.map +1 -1
  47. package/esm/cli/commands/doctor/checks/release-hygiene.check.mjs +4 -0
  48. package/esm/cli/commands/doctor/checks/release-hygiene.check.mjs.map +1 -1
  49. package/esm/cli/commands/doctor/checks/routes.check.mjs +3 -0
  50. package/esm/cli/commands/doctor/checks/routes.check.mjs.map +1 -1
  51. package/esm/cli/commands/doctor/doctor-command.action.mjs +14 -6
  52. package/esm/cli/commands/doctor/doctor-command.action.mjs.map +1 -1
  53. package/esm/cli/commands/doctor/format-report.mjs +30 -2
  54. package/esm/cli/commands/doctor/format-report.mjs.map +1 -1
  55. package/esm/cli/commands/doctor.command.mjs +4 -0
  56. package/esm/cli/commands/doctor.command.mjs.map +1 -1
  57. package/esm/cli/commands/explain/explain-command.action.mjs +64 -0
  58. package/esm/cli/commands/explain/explain-command.action.mjs.map +1 -0
  59. package/esm/cli/commands/explain.command.mjs +23 -0
  60. package/esm/cli/commands/explain.command.mjs.map +1 -0
  61. package/esm/cli/commands/generate/generate.command.mjs +124 -124
  62. package/esm/cli/commands/generate/generate.command.mjs.map +1 -1
  63. package/esm/cli/commands/generate/generators/endpoint.generator.mjs +311 -0
  64. package/esm/cli/commands/generate/generators/endpoint.generator.mjs.map +1 -0
  65. package/esm/cli/commands/generate/generators/migration.generator.mjs +1 -1
  66. package/esm/cli/commands/generate/generators/migration.generator.mjs.map +1 -1
  67. package/esm/cli/commands/generate/generators/model.generator.mjs +1 -1
  68. package/esm/cli/commands/generate/templates/endpoint-stubs.mjs +341 -0
  69. package/esm/cli/commands/generate/templates/endpoint-stubs.mjs.map +1 -0
  70. package/esm/cli/commands/generate/templates/stubs.mjs +19 -6
  71. package/esm/cli/commands/generate/templates/stubs.mjs.map +1 -1
  72. package/esm/cli/commands/generate/utils/endpoint-schema.mjs +137 -0
  73. package/esm/cli/commands/generate/utils/endpoint-schema.mjs.map +1 -0
  74. package/esm/cli/commands/generate/utils/name-parser.mjs +1 -1
  75. package/esm/cli/commands/generate/utils/name-parser.mjs.map +1 -1
  76. package/esm/cli/commands/generate/utils/prompt.mjs.map +1 -1
  77. package/esm/cli/commands/generate/utils/writer.mjs +38 -13
  78. package/esm/cli/commands/generate/utils/writer.mjs.map +1 -1
  79. package/esm/cli/commands/inspect/inspect-command.action.mjs +72 -0
  80. package/esm/cli/commands/inspect/inspect-command.action.mjs.map +1 -0
  81. package/esm/cli/commands/inspect.command.mjs +39 -0
  82. package/esm/cli/commands/inspect.command.mjs.map +1 -0
  83. package/esm/cli/commands/mcp/mcp-command.action.mjs +103 -0
  84. package/esm/cli/commands/mcp/mcp-command.action.mjs.map +1 -0
  85. package/esm/cli/commands/mcp.command.mjs +76 -0
  86. package/esm/cli/commands/mcp.command.mjs.map +1 -0
  87. package/esm/cli/commands/openapi-generator.action.mjs.map +1 -1
  88. package/esm/cli/commands/openapi-generator.command.mjs.map +1 -1
  89. package/esm/cli/commands/postman-generator.action.mjs.map +1 -1
  90. package/esm/cli/commands/postman-generator.command.mjs.map +1 -1
  91. package/esm/cli/commands/routes/routes-diff.action.mjs +1 -1
  92. package/esm/cli/commands/test.command.mjs +131 -0
  93. package/esm/cli/commands/test.command.mjs.map +1 -0
  94. package/esm/cli/commands/trace/trace-command.action.mjs +145 -0
  95. package/esm/cli/commands/trace/trace-command.action.mjs.map +1 -0
  96. package/esm/cli/commands/trace.command.mjs +60 -0
  97. package/esm/cli/commands/trace.command.mjs.map +1 -0
  98. package/esm/cli/commands/typecheck.command.mjs +40 -0
  99. package/esm/cli/commands/typecheck.command.mjs.map +1 -0
  100. package/esm/cli/commands/upgrade.command.mjs +46 -0
  101. package/esm/cli/commands/upgrade.command.mjs.map +1 -0
  102. package/esm/cli/flush-and-exit.mjs +34 -0
  103. package/esm/cli/flush-and-exit.mjs.map +1 -0
  104. package/esm/cli/framework-cli-commands.mjs +23 -1
  105. package/esm/cli/framework-cli-commands.mjs.map +1 -1
  106. package/esm/cli/parse-cli-args.mjs +1 -0
  107. package/esm/cli/parse-cli-args.mjs.map +1 -1
  108. package/esm/config/config-loader.d.mts.map +1 -1
  109. package/esm/config/config-loader.mjs +34 -13
  110. package/esm/config/config-loader.mjs.map +1 -1
  111. package/esm/config/config-schema.d.mts +67 -0
  112. package/esm/config/config-schema.d.mts.map +1 -0
  113. package/esm/config/config-schema.mjs +77 -0
  114. package/esm/config/config-schema.mjs.map +1 -0
  115. package/esm/config/index.d.mts +6 -0
  116. package/esm/config/index.mjs +1 -0
  117. package/esm/connectors/assert-no-reserved-connector-names.d.mts.map +1 -1
  118. package/esm/connectors/assert-no-reserved-connector-names.mjs +2 -1
  119. package/esm/connectors/assert-no-reserved-connector-names.mjs.map +1 -1
  120. package/esm/connectors/assert-unique-connector-names.d.mts.map +1 -1
  121. package/esm/connectors/assert-unique-connector-names.mjs +26 -2
  122. package/esm/connectors/assert-unique-connector-names.mjs.map +1 -1
  123. package/esm/connectors/http-connector.d.mts.map +1 -1
  124. package/esm/connectors/http-connector.mjs +3 -2
  125. package/esm/connectors/http-connector.mjs.map +1 -1
  126. package/esm/connectors/single-server-warnings.mjs.map +1 -1
  127. package/esm/connectors/socket-connector.d.mts.map +1 -1
  128. package/esm/connectors/socket-connector.mjs.map +1 -1
  129. package/esm/container/index.d.mts.map +1 -1
  130. package/esm/container/index.mjs.map +1 -1
  131. package/esm/database/migrate-action.mjs.map +1 -1
  132. package/esm/database/models/database-log/database-log.d.mts +0 -28
  133. package/esm/database/models/database-log/database-log.d.mts.map +1 -1
  134. package/esm/database/seeds/seeder.errors.d.mts +4 -0
  135. package/esm/database/seeds/seeder.errors.d.mts.map +1 -1
  136. package/esm/database/seeds/seeder.errors.mjs +2 -0
  137. package/esm/database/seeds/seeder.errors.mjs.map +1 -1
  138. package/esm/dev-server/boot-precondition-error.mjs +1 -0
  139. package/esm/dev-server/boot-precondition-error.mjs.map +1 -1
  140. package/esm/dev-server/create-worker.mjs +15 -9
  141. package/esm/dev-server/create-worker.mjs.map +1 -1
  142. package/esm/dev-server/dev-agent-tooling.mjs +135 -0
  143. package/esm/dev-server/dev-agent-tooling.mjs.map +1 -0
  144. package/esm/dev-server/dev-logger.mjs.map +1 -1
  145. package/esm/dev-server/development-server.mjs +8 -0
  146. package/esm/dev-server/development-server.mjs.map +1 -1
  147. package/esm/dev-server/files-orchestrator.mjs +4 -5
  148. package/esm/dev-server/files-orchestrator.mjs.map +1 -1
  149. package/esm/dev-server/files-watcher.mjs +1 -1
  150. package/esm/dev-server/health-checker/checkers/eslint-health-checker.mjs +2 -3
  151. package/esm/dev-server/health-checker/checkers/eslint-health-checker.mjs.map +1 -1
  152. package/esm/dev-server/health-checker/checkers/oxlint-health-checker.mjs +33 -0
  153. package/esm/dev-server/health-checker/checkers/oxlint-health-checker.mjs.map +1 -0
  154. package/esm/dev-server/health-checker/default-health-checkers.mjs +31 -0
  155. package/esm/dev-server/health-checker/default-health-checkers.mjs.map +1 -0
  156. package/esm/dev-server/health-checker/file-health-checker.contract.d.mts +9 -3
  157. package/esm/dev-server/health-checker/file-health-checker.contract.d.mts.map +1 -1
  158. package/esm/dev-server/health-checker/files-healthcare.manager.mjs +15 -4
  159. package/esm/dev-server/health-checker/files-healthcare.manager.mjs.map +1 -1
  160. package/esm/dev-server/health-checker/oxlint-runner.mjs +302 -0
  161. package/esm/dev-server/health-checker/oxlint-runner.mjs.map +1 -0
  162. package/esm/dev-server/health-checker/workers/oxlint-health.worker.d.mts +1 -0
  163. package/esm/dev-server/health-checker/workers/oxlint-health.worker.mjs +42 -0
  164. package/esm/dev-server/health-checker/workers/oxlint-health.worker.mjs.map +1 -0
  165. package/esm/dev-server/loader/loader-port-acks.mjs +1 -1
  166. package/esm/dev-server/loader/loader-port-acks.mjs.map +1 -1
  167. package/esm/dev-server/loader/register-loader.mjs +1 -1
  168. package/esm/dev-server/loader/register-loader.mjs.map +1 -1
  169. package/esm/dev-server/loader/resolve-hook.mjs +1 -1
  170. package/esm/dev-server/loader/transpile-cache.mjs +1 -1
  171. package/esm/dev-server/model-resource-typings.mjs.map +1 -1
  172. package/esm/dev-server/module-loader.mjs +1 -0
  173. package/esm/dev-server/module-loader.mjs.map +1 -1
  174. package/esm/dev-server/parse-imports.mjs +1 -1
  175. package/esm/dev-server/parse-imports.mjs.map +1 -1
  176. package/esm/dev-server/route-types-publisher.mjs +1 -1
  177. package/esm/dev-server/start-development-server.mjs.map +1 -1
  178. package/esm/dev-server/translation-keys-sources.mjs +1 -1
  179. package/esm/dev-server/translation-keys-sources.mjs.map +1 -1
  180. package/esm/dev-server/tsconfig-manager.mjs.map +1 -1
  181. package/esm/dev-server/type-generator.mjs +3 -3
  182. package/esm/dev-server/type-generator.mjs.map +1 -1
  183. package/esm/dev-server/types.d.mts.map +1 -1
  184. package/esm/errors/container-key-missing-error.mjs +1 -0
  185. package/esm/errors/container-key-missing-error.mjs.map +1 -1
  186. package/esm/errors/error-codes.d.mts +653 -0
  187. package/esm/errors/error-codes.d.mts.map +1 -0
  188. package/esm/errors/error-codes.mjs +634 -0
  189. package/esm/errors/error-codes.mjs.map +1 -0
  190. package/esm/errors/esbuild-binary-missing-error.mjs +1 -0
  191. package/esm/errors/esbuild-binary-missing-error.mjs.map +1 -1
  192. package/esm/errors/index.d.mts +3 -1
  193. package/esm/errors/index.mjs +3 -1
  194. package/esm/errors/unknown-locale-error.mjs +1 -0
  195. package/esm/errors/unknown-locale-error.mjs.map +1 -1
  196. package/esm/errors/warlock-error.d.mts +23 -0
  197. package/esm/errors/warlock-error.d.mts.map +1 -0
  198. package/esm/errors/warlock-error.mjs +22 -0
  199. package/esm/errors/warlock-error.mjs.map +1 -0
  200. package/esm/generations/add-command.action.mjs +19 -3
  201. package/esm/generations/add-command.action.mjs.map +1 -1
  202. package/esm/generations/features/access.feature.mjs +1 -1
  203. package/esm/generations/features/access.feature.mjs.map +1 -1
  204. package/esm/generations/features/bull-board.feature.mjs +1 -1
  205. package/esm/generations/features/bull-board.feature.mjs.map +1 -1
  206. package/esm/generations/features/mysql.feature.mjs.map +1 -1
  207. package/esm/generations/features/notifications.feature.mjs +5 -2
  208. package/esm/generations/features/notifications.feature.mjs.map +1 -1
  209. package/esm/generations/features/queue.feature.mjs +1 -1
  210. package/esm/generations/features/queue.feature.mjs.map +1 -1
  211. package/esm/generations/features/react-email.feature.mjs +1 -1
  212. package/esm/generations/features/react-email.feature.mjs.map +1 -1
  213. package/esm/generations/features/shadcn.feature.mjs +1 -1
  214. package/esm/generations/features/shadcn.feature.mjs.map +1 -1
  215. package/esm/generations/features/shared/link-ai-package-import.mjs +1 -1
  216. package/esm/generations/features/shared/link-ai-package-import.mjs.map +1 -1
  217. package/esm/generations/features/shared/merge-web-sitemap-config.mjs.map +1 -1
  218. package/esm/generations/features/shared/patch-tsconfig-include.mjs +1 -1
  219. package/esm/generations/features/shared/patch-tsconfig-include.mjs.map +1 -1
  220. package/esm/generations/features/shared/relocate-conflicting-home-route.mjs +1 -1
  221. package/esm/generations/features/shared/relocate-conflicting-home-route.mjs.map +1 -1
  222. package/esm/generations/features/sitemap.feature.mjs +1 -1
  223. package/esm/generations/features/sitemap.feature.mjs.map +1 -1
  224. package/esm/generations/features/tailwind.feature.mjs +1 -1
  225. package/esm/generations/features/tailwind.feature.mjs.map +1 -1
  226. package/esm/generations/features/test.feature.mjs +11 -6
  227. package/esm/generations/features/test.feature.mjs.map +1 -1
  228. package/esm/generations/features/web.feature.mjs +1 -1
  229. package/esm/generations/features/web.feature.mjs.map +1 -1
  230. package/esm/generations/generation-fs.mjs +73 -0
  231. package/esm/generations/generation-fs.mjs.map +1 -0
  232. package/esm/generations/generation-run.mjs +185 -0
  233. package/esm/generations/generation-run.mjs.map +1 -0
  234. package/esm/generations/stubs.mjs +155 -13
  235. package/esm/generations/stubs.mjs.map +1 -1
  236. package/esm/http/bounded-stream-queue.d.mts +10 -0
  237. package/esm/http/bounded-stream-queue.d.mts.map +1 -0
  238. package/esm/http/bounded-stream-queue.mjs +97 -0
  239. package/esm/http/bounded-stream-queue.mjs.map +1 -0
  240. package/esm/http/build-rate-limit-options.d.mts +13 -0
  241. package/esm/http/build-rate-limit-options.d.mts.map +1 -1
  242. package/esm/http/build-rate-limit-options.mjs.map +1 -1
  243. package/esm/http/conditional-request.d.mts +86 -0
  244. package/esm/http/conditional-request.d.mts.map +1 -0
  245. package/esm/http/conditional-request.mjs +121 -0
  246. package/esm/http/conditional-request.mjs.map +1 -0
  247. package/esm/http/csp.d.mts +2 -0
  248. package/esm/http/csp.d.mts.map +1 -1
  249. package/esm/http/csp.mjs +1 -0
  250. package/esm/http/csp.mjs.map +1 -1
  251. package/esm/http/csrf-origin-policy.mjs.map +1 -1
  252. package/esm/http/database/RequestLog.d.mts +24 -84
  253. package/esm/http/database/RequestLog.d.mts.map +1 -1
  254. package/esm/http/errors/errors.d.mts +2 -0
  255. package/esm/http/errors/errors.d.mts.map +1 -1
  256. package/esm/http/errors/errors.mjs +1 -0
  257. package/esm/http/errors/errors.mjs.map +1 -1
  258. package/esm/http/escape-header-value.d.mts +18 -0
  259. package/esm/http/escape-header-value.d.mts.map +1 -0
  260. package/esm/http/escape-header-value.mjs +27 -0
  261. package/esm/http/escape-header-value.mjs.map +1 -0
  262. package/esm/http/flush-pending-cookies.mjs.map +1 -1
  263. package/esm/http/index.d.mts +5 -2
  264. package/esm/http/index.mjs +4 -1
  265. package/esm/http/lazy-static.mjs +194 -0
  266. package/esm/http/lazy-static.mjs.map +1 -0
  267. package/esm/http/middleware/idempotency.middleware.mjs.map +1 -1
  268. package/esm/http/plugins.d.mts.map +1 -1
  269. package/esm/http/plugins.mjs +7 -4
  270. package/esm/http/plugins.mjs.map +1 -1
  271. package/esm/http/rate-limit-cache-store.mjs +2 -1
  272. package/esm/http/rate-limit-cache-store.mjs.map +1 -1
  273. package/esm/http/request-log-snapshot.d.mts +12 -5
  274. package/esm/http/request-log-snapshot.d.mts.map +1 -1
  275. package/esm/http/request-log-snapshot.mjs +83 -4
  276. package/esm/http/request-log-snapshot.mjs.map +1 -1
  277. package/esm/http/request.d.mts +2 -2
  278. package/esm/http/request.d.mts.map +1 -1
  279. package/esm/http/request.mjs +5 -4
  280. package/esm/http/request.mjs.map +1 -1
  281. package/esm/http/response.d.mts +11 -1
  282. package/esm/http/response.d.mts.map +1 -1
  283. package/esm/http/response.mjs +164 -76
  284. package/esm/http/response.mjs.map +1 -1
  285. package/esm/http/safe-redirect.d.mts +51 -0
  286. package/esm/http/safe-redirect.d.mts.map +1 -0
  287. package/esm/http/safe-redirect.mjs +80 -0
  288. package/esm/http/safe-redirect.mjs.map +1 -0
  289. package/esm/http/serialized.d.mts.map +1 -1
  290. package/esm/http/server.d.mts +3 -1
  291. package/esm/http/server.d.mts.map +1 -1
  292. package/esm/http/server.mjs +14 -4
  293. package/esm/http/server.mjs.map +1 -1
  294. package/esm/http/stream-transport.mjs +4 -2
  295. package/esm/http/stream-transport.mjs.map +1 -1
  296. package/esm/http/types.d.mts +44 -11
  297. package/esm/http/types.d.mts.map +1 -1
  298. package/esm/http/uploads/generate-image-variant.mjs +1 -1
  299. package/esm/http/uploads/generate-image-variants.d.mts +10 -7
  300. package/esm/http/uploads/generate-image-variants.d.mts.map +1 -1
  301. package/esm/http/uploads/generate-image-variants.mjs +61 -24
  302. package/esm/http/uploads/generate-image-variants.mjs.map +1 -1
  303. package/esm/http/uploads/image-variant-cache-entries.mjs +78 -0
  304. package/esm/http/uploads/image-variant-cache-entries.mjs.map +1 -0
  305. package/esm/http/uploads/image-variant-cache.mjs +72 -30
  306. package/esm/http/uploads/image-variant-cache.mjs.map +1 -1
  307. package/esm/http/uploads/image-variant-types.d.mts +2 -0
  308. package/esm/http/uploads/image-variant-types.d.mts.map +1 -1
  309. package/esm/http/uploads/image-variants-config-error.d.mts +3 -1
  310. package/esm/http/uploads/image-variants-config-error.d.mts.map +1 -1
  311. package/esm/http/uploads/image-variants-config-error.mjs +3 -2
  312. package/esm/http/uploads/image-variants-config-error.mjs.map +1 -1
  313. package/esm/http/uploads/load-variant-source.mjs +1 -1
  314. package/esm/http/uploads/load-variant-source.mjs.map +1 -1
  315. package/esm/http/uploads/purge-image-variants.d.mts +7 -2
  316. package/esm/http/uploads/purge-image-variants.d.mts.map +1 -1
  317. package/esm/http/uploads/purge-image-variants.mjs +16 -16
  318. package/esm/http/uploads/purge-image-variants.mjs.map +1 -1
  319. package/esm/http/uploads/remote-variant-source.mjs +115 -0
  320. package/esm/http/uploads/remote-variant-source.mjs.map +1 -0
  321. package/esm/http/uploads/resolve-image-variant.d.mts +3 -4
  322. package/esm/http/uploads/resolve-image-variant.d.mts.map +1 -1
  323. package/esm/http/uploads/resolve-image-variant.mjs +10 -18
  324. package/esm/http/uploads/resolve-image-variant.mjs.map +1 -1
  325. package/esm/http/uploads/resolve-image-variants-config.mjs +5 -3
  326. package/esm/http/uploads/resolve-image-variants-config.mjs.map +1 -1
  327. package/esm/http/uploads/resolve-remote-image-variant.mjs +89 -0
  328. package/esm/http/uploads/resolve-remote-image-variant.mjs.map +1 -0
  329. package/esm/http/uploads/trim-image-variant-cache.mjs +193 -0
  330. package/esm/http/uploads/trim-image-variant-cache.mjs.map +1 -0
  331. package/esm/http/uploads/uploaded-file.controller.d.mts +5 -3
  332. package/esm/http/uploads/uploaded-file.controller.d.mts.map +1 -1
  333. package/esm/http/uploads/uploaded-file.controller.mjs +16 -8
  334. package/esm/http/uploads/uploaded-file.controller.mjs.map +1 -1
  335. package/esm/http/uploads/variant-cache-key.mjs +1 -1
  336. package/esm/http/uploads-types.d.mts +6 -2
  337. package/esm/http/uploads-types.d.mts.map +1 -1
  338. package/esm/index.d.mts +17 -6
  339. package/esm/index.mjs +14 -3
  340. package/esm/localization/parse-locale-dictionary.d.mts +2 -0
  341. package/esm/localization/parse-locale-dictionary.d.mts.map +1 -1
  342. package/esm/localization/parse-locale-dictionary.mjs +1 -0
  343. package/esm/localization/parse-locale-dictionary.mjs.map +1 -1
  344. package/esm/mail/config.d.mts +12 -1
  345. package/esm/mail/config.d.mts.map +1 -1
  346. package/esm/mail/config.mjs +16 -1
  347. package/esm/mail/config.mjs.map +1 -1
  348. package/esm/mail/index.d.mts +1 -1
  349. package/esm/mail/index.mjs +1 -1
  350. package/esm/net/index.d.mts +2 -0
  351. package/esm/net/index.mjs +3 -0
  352. package/esm/openapi/build-openapi-document.d.mts.map +1 -1
  353. package/esm/openapi/build-openapi-document.mjs +8 -5
  354. package/esm/openapi/build-openapi-document.mjs.map +1 -1
  355. package/esm/openapi/error-responses.mjs +28 -2
  356. package/esm/openapi/error-responses.mjs.map +1 -1
  357. package/esm/openapi/postman/build-request-body.mjs.map +1 -1
  358. package/esm/openapi/postman/build-request-url.mjs.map +1 -1
  359. package/esm/openapi/postman/build-saved-responses.mjs.map +1 -1
  360. package/esm/openapi/postman/example-from-schema.d.mts.map +1 -1
  361. package/esm/openapi/postman/example-from-schema.mjs.map +1 -1
  362. package/esm/openapi/postman/openapi-to-postman-collection.d.mts.map +1 -1
  363. package/esm/openapi/postman/openapi-to-postman-collection.mjs.map +1 -1
  364. package/esm/openapi/postman/schema-refs.mjs.map +1 -1
  365. package/esm/openapi/postman/uuid-v5.mjs.map +1 -1
  366. package/esm/openapi/request-schemas.mjs.map +1 -1
  367. package/esm/openapi/response-schemas.mjs.map +1 -1
  368. package/esm/openapi/schema-registry.d.mts +1 -0
  369. package/esm/openapi/schema-registry.mjs.map +1 -1
  370. package/esm/openapi/security.mjs.map +1 -1
  371. package/esm/openapi/types.d.mts +3 -2
  372. package/esm/openapi/types.d.mts.map +1 -1
  373. package/esm/production/assert-generated-imports.mjs +1 -0
  374. package/esm/production/assert-generated-imports.mjs.map +1 -1
  375. package/esm/production/production-builder.mjs +12 -4
  376. package/esm/production/production-builder.mjs.map +1 -1
  377. package/esm/production/resolve-build-config.mjs +1 -0
  378. package/esm/production/resolve-build-config.mjs.map +1 -1
  379. package/esm/production/route-registration-child.mjs.map +1 -1
  380. package/esm/production/route-registration-snapshot.mjs.map +1 -1
  381. package/esm/repositories/contracts/query-builder.contract.d.mts.map +1 -1
  382. package/esm/repositories/contracts/types.d.mts.map +1 -1
  383. package/esm/repositories/repository.manager.mjs.map +1 -1
  384. package/esm/resource/resource.d.mts.map +1 -1
  385. package/esm/resource/resource.mjs.map +1 -1
  386. package/esm/resource/types.d.mts.map +1 -1
  387. package/esm/restful/restful.d.mts +5 -5
  388. package/esm/restful/restful.d.mts.map +1 -1
  389. package/esm/restful/restful.mjs.map +1 -1
  390. package/esm/router/build-route-rate-limit.mjs.map +1 -1
  391. package/esm/router/dev-dispatch.mjs +31 -12
  392. package/esm/router/dev-dispatch.mjs.map +1 -1
  393. package/esm/router/index.d.mts +4 -2
  394. package/esm/router/index.mjs +2 -0
  395. package/esm/router/log-request-lifecycle.mjs.map +1 -1
  396. package/esm/router/positional-handler-diagnostics.d.mts.map +1 -1
  397. package/esm/router/positional-handler-diagnostics.mjs.map +1 -1
  398. package/esm/router/resolve-route-rate-limit.mjs +47 -0
  399. package/esm/router/resolve-route-rate-limit.mjs.map +1 -0
  400. package/esm/router/resolve-route-validation.mjs +19 -0
  401. package/esm/router/resolve-route-validation.mjs.map +1 -0
  402. package/esm/router/route-guard-names.mjs +30 -0
  403. package/esm/router/route-guard-names.mjs.map +1 -0
  404. package/esm/router/route-name-taken-error.d.mts +14 -0
  405. package/esm/router/route-name-taken-error.d.mts.map +1 -0
  406. package/esm/router/route-name-taken-error.mjs +18 -0
  407. package/esm/router/route-name-taken-error.mjs.map +1 -0
  408. package/esm/router/router.d.mts +32 -13
  409. package/esm/router/router.d.mts.map +1 -1
  410. package/esm/router/router.mjs +71 -38
  411. package/esm/router/router.mjs.map +1 -1
  412. package/esm/router/types.d.mts +137 -17
  413. package/esm/router/types.d.mts.map +1 -1
  414. package/esm/router/unguarded-route-diagnostics.d.mts +40 -0
  415. package/esm/router/unguarded-route-diagnostics.d.mts.map +1 -0
  416. package/esm/router/unguarded-route-diagnostics.mjs +95 -0
  417. package/esm/router/unguarded-route-diagnostics.mjs.map +1 -0
  418. package/esm/storage/drivers/cloud-driver.d.mts.map +1 -1
  419. package/esm/storage/drivers/cloud-driver.mjs.map +1 -1
  420. package/esm/storage/drivers/local-driver.d.mts.map +1 -1
  421. package/esm/storage/drivers/local-driver.mjs.map +1 -1
  422. package/esm/storage/local-disk-roots.mjs +24 -0
  423. package/esm/storage/local-disk-roots.mjs.map +1 -0
  424. package/esm/storage/storage.d.mts +14 -0
  425. package/esm/storage/storage.d.mts.map +1 -1
  426. package/esm/storage/storage.mjs +22 -0
  427. package/esm/storage/storage.mjs.map +1 -1
  428. package/esm/storage/types.d.mts.map +1 -1
  429. package/esm/storage/utils/storage-not-initialized-error.d.mts +2 -0
  430. package/esm/storage/utils/storage-not-initialized-error.d.mts.map +1 -1
  431. package/esm/storage/utils/storage-not-initialized-error.mjs +1 -0
  432. package/esm/storage/utils/storage-not-initialized-error.mjs.map +1 -1
  433. package/esm/tests/authenticated-test-client.d.mts +32 -0
  434. package/esm/tests/authenticated-test-client.d.mts.map +1 -0
  435. package/esm/tests/authenticated-test-client.mjs +40 -0
  436. package/esm/tests/authenticated-test-client.mjs.map +1 -0
  437. package/esm/tests/factories.d.mts +59 -0
  438. package/esm/tests/factories.d.mts.map +1 -0
  439. package/esm/tests/factories.mjs +105 -0
  440. package/esm/tests/factories.mjs.map +1 -0
  441. package/esm/tests/fakes/cache-fake.d.mts +29 -0
  442. package/esm/tests/fakes/cache-fake.d.mts.map +1 -0
  443. package/esm/tests/fakes/cache-fake.mjs +79 -0
  444. package/esm/tests/fakes/cache-fake.mjs.map +1 -0
  445. package/esm/tests/fakes/clock-fake.d.mts +32 -0
  446. package/esm/tests/fakes/clock-fake.d.mts.map +1 -0
  447. package/esm/tests/fakes/clock-fake.mjs +69 -0
  448. package/esm/tests/fakes/clock-fake.mjs.map +1 -0
  449. package/esm/tests/fakes/fake-assertion-error.d.mts +13 -0
  450. package/esm/tests/fakes/fake-assertion-error.d.mts.map +1 -0
  451. package/esm/tests/fakes/fake-assertion-error.mjs +20 -0
  452. package/esm/tests/fakes/fake-assertion-error.mjs.map +1 -0
  453. package/esm/tests/fakes/ids-fake.d.mts +22 -0
  454. package/esm/tests/fakes/ids-fake.d.mts.map +1 -0
  455. package/esm/tests/fakes/ids-fake.mjs +57 -0
  456. package/esm/tests/fakes/ids-fake.mjs.map +1 -0
  457. package/esm/tests/fakes/index.d.mts +8 -0
  458. package/esm/tests/fakes/index.mjs +10 -0
  459. package/esm/tests/fakes/mail-fake.d.mts +41 -0
  460. package/esm/tests/fakes/mail-fake.d.mts.map +1 -0
  461. package/esm/tests/fakes/mail-fake.mjs +111 -0
  462. package/esm/tests/fakes/mail-fake.mjs.map +1 -0
  463. package/esm/tests/fakes/queue-fake.d.mts +48 -0
  464. package/esm/tests/fakes/queue-fake.d.mts.map +1 -0
  465. package/esm/tests/fakes/queue-fake.mjs +134 -0
  466. package/esm/tests/fakes/queue-fake.mjs.map +1 -0
  467. package/esm/tests/fakes/storage-fake.d.mts +31 -0
  468. package/esm/tests/fakes/storage-fake.d.mts.map +1 -0
  469. package/esm/tests/fakes/storage-fake.mjs +122 -0
  470. package/esm/tests/fakes/storage-fake.mjs.map +1 -0
  471. package/esm/tests/fakes/test-fakes.d.mts +39 -0
  472. package/esm/tests/fakes/test-fakes.d.mts.map +1 -0
  473. package/esm/tests/fakes/test-fakes.mjs +90 -0
  474. package/esm/tests/fakes/test-fakes.mjs.map +1 -0
  475. package/esm/tests/index.d.mts +14 -2
  476. package/esm/tests/index.mjs +15 -2
  477. package/esm/tests/snapshot-response.d.mts +34 -0
  478. package/esm/tests/snapshot-response.d.mts.map +1 -0
  479. package/esm/tests/snapshot-response.mjs +42 -0
  480. package/esm/tests/snapshot-response.mjs.map +1 -0
  481. package/esm/tests/start-http-development-server.d.mts +22 -0
  482. package/esm/tests/start-http-development-server.d.mts.map +1 -1
  483. package/esm/tests/start-http-development-server.mjs +36 -3
  484. package/esm/tests/start-http-development-server.mjs.map +1 -1
  485. package/esm/tests/test-helpers.d.mts +20 -1
  486. package/esm/tests/test-helpers.d.mts.map +1 -1
  487. package/esm/tests/test-helpers.mjs +40 -27
  488. package/esm/tests/test-helpers.mjs.map +1 -1
  489. package/esm/tests/test-http-server.d.mts +62 -0
  490. package/esm/tests/test-http-server.d.mts.map +1 -0
  491. package/esm/tests/test-http-server.mjs +119 -0
  492. package/esm/tests/test-http-server.mjs.map +1 -0
  493. package/esm/tests/vitest-setup.d.mts +11 -0
  494. package/esm/tests/vitest-setup.d.mts.map +1 -1
  495. package/esm/tests/vitest-setup.mjs +12 -4
  496. package/esm/tests/vitest-setup.mjs.map +1 -1
  497. package/esm/tooling/agents-md/agents-md-markers.d.mts +27 -0
  498. package/esm/tooling/agents-md/agents-md-markers.d.mts.map +1 -0
  499. package/esm/tooling/agents-md/agents-md-markers.mjs +59 -0
  500. package/esm/tooling/agents-md/agents-md-markers.mjs.map +1 -0
  501. package/esm/tooling/agents-md/agents-md-refresher.d.mts +36 -0
  502. package/esm/tooling/agents-md/agents-md-refresher.d.mts.map +1 -0
  503. package/esm/tooling/agents-md/agents-md-refresher.mjs +72 -0
  504. package/esm/tooling/agents-md/agents-md-refresher.mjs.map +1 -0
  505. package/esm/tooling/agents-md/index.mjs +7 -0
  506. package/esm/tooling/agents-md/installed-skills.d.mts +30 -0
  507. package/esm/tooling/agents-md/installed-skills.d.mts.map +1 -0
  508. package/esm/tooling/agents-md/installed-skills.mjs +74 -0
  509. package/esm/tooling/agents-md/installed-skills.mjs.map +1 -0
  510. package/esm/tooling/agents-md/render-agents-md.d.mts +33 -0
  511. package/esm/tooling/agents-md/render-agents-md.d.mts.map +1 -0
  512. package/esm/tooling/agents-md/render-agents-md.mjs +195 -0
  513. package/esm/tooling/agents-md/render-agents-md.mjs.map +1 -0
  514. package/esm/tooling/agents-md/write-agents-md.d.mts +33 -0
  515. package/esm/tooling/agents-md/write-agents-md.d.mts.map +1 -0
  516. package/esm/tooling/agents-md/write-agents-md.mjs +49 -0
  517. package/esm/tooling/agents-md/write-agents-md.mjs.map +1 -0
  518. package/esm/tooling/board/board-message.d.mts +31 -0
  519. package/esm/tooling/board/board-message.d.mts.map +1 -0
  520. package/esm/tooling/board/board-message.mjs +86 -0
  521. package/esm/tooling/board/board-message.mjs.map +1 -0
  522. package/esm/tooling/board/board.d.mts +109 -0
  523. package/esm/tooling/board/board.d.mts.map +1 -0
  524. package/esm/tooling/board/board.mjs +406 -0
  525. package/esm/tooling/board/board.mjs.map +1 -0
  526. package/esm/tooling/board/board.types.d.mts +72 -0
  527. package/esm/tooling/board/board.types.d.mts.map +1 -0
  528. package/esm/tooling/board/board.types.mjs +54 -0
  529. package/esm/tooling/board/board.types.mjs.map +1 -0
  530. package/esm/tooling/check/changed-files.d.mts +33 -0
  531. package/esm/tooling/check/changed-files.d.mts.map +1 -0
  532. package/esm/tooling/check/changed-files.mjs +73 -0
  533. package/esm/tooling/check/changed-files.mjs.map +1 -0
  534. package/esm/tooling/check/check-report.types.d.mts +62 -0
  535. package/esm/tooling/check/check-report.types.d.mts.map +1 -0
  536. package/esm/tooling/check/check-report.types.mjs +37 -0
  537. package/esm/tooling/check/check-report.types.mjs.map +1 -0
  538. package/esm/tooling/check/code-style-conventions.mjs +106 -0
  539. package/esm/tooling/check/code-style-conventions.mjs.map +1 -0
  540. package/esm/tooling/check/conventions-step.d.mts +34 -0
  541. package/esm/tooling/check/conventions-step.d.mts.map +1 -0
  542. package/esm/tooling/check/conventions-step.mjs +184 -0
  543. package/esm/tooling/check/conventions-step.mjs.map +1 -0
  544. package/esm/tooling/check/environment-step.d.mts +18 -0
  545. package/esm/tooling/check/environment-step.d.mts.map +1 -0
  546. package/esm/tooling/check/environment-step.mjs +78 -0
  547. package/esm/tooling/check/environment-step.mjs.map +1 -0
  548. package/esm/tooling/check/index.d.mts +8 -0
  549. package/esm/tooling/check/index.mjs +10 -0
  550. package/esm/tooling/check/lint-step.d.mts +19 -0
  551. package/esm/tooling/check/lint-step.d.mts.map +1 -0
  552. package/esm/tooling/check/lint-step.mjs +111 -0
  553. package/esm/tooling/check/lint-step.mjs.map +1 -0
  554. package/esm/tooling/check/request-input.mjs +132 -0
  555. package/esm/tooling/check/request-input.mjs.map +1 -0
  556. package/esm/tooling/check/run-check.d.mts +35 -0
  557. package/esm/tooling/check/run-check.d.mts.map +1 -0
  558. package/esm/tooling/check/run-check.mjs +192 -0
  559. package/esm/tooling/check/run-check.mjs.map +1 -0
  560. package/esm/tooling/check/run-tests.d.mts +48 -0
  561. package/esm/tooling/check/run-tests.d.mts.map +1 -0
  562. package/esm/tooling/check/run-tests.mjs +93 -0
  563. package/esm/tooling/check/run-tests.mjs.map +1 -0
  564. package/esm/tooling/check/security-conventions.mjs +648 -0
  565. package/esm/tooling/check/security-conventions.mjs.map +1 -0
  566. package/esm/tooling/check/source-ast.mjs +195 -0
  567. package/esm/tooling/check/source-ast.mjs.map +1 -0
  568. package/esm/tooling/check/source-files.mjs +27 -0
  569. package/esm/tooling/check/source-files.mjs.map +1 -0
  570. package/esm/tooling/check/tests-step.d.mts +34 -0
  571. package/esm/tooling/check/tests-step.d.mts.map +1 -0
  572. package/esm/tooling/check/tests-step.mjs +177 -0
  573. package/esm/tooling/check/tests-step.mjs.map +1 -0
  574. package/esm/tooling/dev-state/dev-server-state.d.mts +39 -0
  575. package/esm/tooling/dev-state/dev-server-state.d.mts.map +1 -0
  576. package/esm/tooling/dev-state/dev-server-state.mjs +67 -0
  577. package/esm/tooling/dev-state/dev-server-state.mjs.map +1 -0
  578. package/esm/tooling/devtools/devtools-client.d.mts +91 -0
  579. package/esm/tooling/devtools/devtools-client.d.mts.map +1 -0
  580. package/esm/tooling/devtools/devtools-client.mjs +155 -0
  581. package/esm/tooling/devtools/devtools-client.mjs.map +1 -0
  582. package/esm/tooling/generate/generation.d.mts +78 -0
  583. package/esm/tooling/generate/generation.d.mts.map +1 -0
  584. package/esm/tooling/generate/generation.mjs +123 -0
  585. package/esm/tooling/generate/generation.mjs.map +1 -0
  586. package/esm/tooling/generate/generator-spec.d.mts +57 -0
  587. package/esm/tooling/generate/generator-spec.d.mts.map +1 -0
  588. package/esm/tooling/generate/generator-spec.mjs +102 -0
  589. package/esm/tooling/generate/generator-spec.mjs.map +1 -0
  590. package/esm/tooling/generate/index.mjs +6 -0
  591. package/esm/tooling/generate/project-files.mjs +121 -0
  592. package/esm/tooling/generate/project-files.mjs.map +1 -0
  593. package/esm/tooling/generate/run-cli.d.mts +40 -0
  594. package/esm/tooling/generate/run-cli.d.mts.map +1 -0
  595. package/esm/tooling/generate/run-cli.mjs +93 -0
  596. package/esm/tooling/generate/run-cli.mjs.map +1 -0
  597. package/esm/tooling/generate/unified-diff.d.mts +37 -0
  598. package/esm/tooling/generate/unified-diff.d.mts.map +1 -0
  599. package/esm/tooling/generate/unified-diff.mjs +161 -0
  600. package/esm/tooling/generate/unified-diff.mjs.map +1 -0
  601. package/esm/tooling/index.d.mts +41 -0
  602. package/esm/tooling/index.mjs +45 -0
  603. package/esm/tooling/inspect/boot-for-inspect.d.mts +23 -0
  604. package/esm/tooling/inspect/boot-for-inspect.d.mts.map +1 -0
  605. package/esm/tooling/inspect/boot-for-inspect.mjs +63 -0
  606. package/esm/tooling/inspect/boot-for-inspect.mjs.map +1 -0
  607. package/esm/tooling/inspect/collect-config.mjs +77 -0
  608. package/esm/tooling/inspect/collect-config.mjs.map +1 -0
  609. package/esm/tooling/inspect/collect-models.d.mts +9 -0
  610. package/esm/tooling/inspect/collect-models.d.mts.map +1 -0
  611. package/esm/tooling/inspect/collect-models.mjs +154 -0
  612. package/esm/tooling/inspect/collect-models.mjs.map +1 -0
  613. package/esm/tooling/inspect/collect-packages.d.mts +10 -0
  614. package/esm/tooling/inspect/collect-packages.d.mts.map +1 -0
  615. package/esm/tooling/inspect/collect-packages.mjs +157 -0
  616. package/esm/tooling/inspect/collect-packages.mjs.map +1 -0
  617. package/esm/tooling/inspect/collect-pages.mjs +108 -0
  618. package/esm/tooling/inspect/collect-pages.mjs.map +1 -0
  619. package/esm/tooling/inspect/collect-routes.mjs +168 -0
  620. package/esm/tooling/inspect/collect-routes.mjs.map +1 -0
  621. package/esm/tooling/inspect/event-recorder.d.mts +37 -0
  622. package/esm/tooling/inspect/event-recorder.d.mts.map +1 -0
  623. package/esm/tooling/inspect/event-recorder.mjs +91 -0
  624. package/esm/tooling/inspect/event-recorder.mjs.map +1 -0
  625. package/esm/tooling/inspect/index.d.mts +7 -0
  626. package/esm/tooling/inspect/index.mjs +7 -0
  627. package/esm/tooling/inspect/inspect-app.d.mts +53 -0
  628. package/esm/tooling/inspect/inspect-app.d.mts.map +1 -0
  629. package/esm/tooling/inspect/inspect-app.mjs +92 -0
  630. package/esm/tooling/inspect/inspect-app.mjs.map +1 -0
  631. package/esm/tooling/inspect/inspect-report.schema.d.mts +15 -0
  632. package/esm/tooling/inspect/inspect-report.schema.d.mts.map +1 -0
  633. package/esm/tooling/inspect/inspect-report.schema.mjs +463 -0
  634. package/esm/tooling/inspect/inspect-report.schema.mjs.map +1 -0
  635. package/esm/tooling/inspect/inspect-report.types.d.mts +196 -0
  636. package/esm/tooling/inspect/inspect-report.types.d.mts.map +1 -0
  637. package/esm/tooling/inspect/inspect-report.types.mjs +33 -0
  638. package/esm/tooling/inspect/inspect-report.types.mjs.map +1 -0
  639. package/esm/tooling/mcp/create-mcp-context.d.mts +26 -0
  640. package/esm/tooling/mcp/create-mcp-context.d.mts.map +1 -0
  641. package/esm/tooling/mcp/create-mcp-context.mjs +75 -0
  642. package/esm/tooling/mcp/create-mcp-context.mjs.map +1 -0
  643. package/esm/tooling/mcp/db-schema.d.mts +49 -0
  644. package/esm/tooling/mcp/db-schema.d.mts.map +1 -0
  645. package/esm/tooling/mcp/db-schema.mjs +56 -0
  646. package/esm/tooling/mcp/db-schema.mjs.map +1 -0
  647. package/esm/tooling/mcp/docs-search.d.mts +72 -0
  648. package/esm/tooling/mcp/docs-search.d.mts.map +1 -0
  649. package/esm/tooling/mcp/docs-search.mjs +178 -0
  650. package/esm/tooling/mcp/docs-search.mjs.map +1 -0
  651. package/esm/tooling/mcp/index.mjs +9 -0
  652. package/esm/tooling/mcp/load-ai-tools.d.mts +62 -0
  653. package/esm/tooling/mcp/load-ai-tools.d.mts.map +1 -0
  654. package/esm/tooling/mcp/load-ai-tools.mjs +44 -0
  655. package/esm/tooling/mcp/load-ai-tools.mjs.map +1 -0
  656. package/esm/tooling/mcp/mcp-tools.d.mts +60 -0
  657. package/esm/tooling/mcp/mcp-tools.d.mts.map +1 -0
  658. package/esm/tooling/mcp/mcp-tools.mjs +513 -0
  659. package/esm/tooling/mcp/mcp-tools.mjs.map +1 -0
  660. package/esm/tooling/mcp/start-mcp-server.d.mts +56 -0
  661. package/esm/tooling/mcp/start-mcp-server.d.mts.map +1 -0
  662. package/esm/tooling/mcp/start-mcp-server.mjs +126 -0
  663. package/esm/tooling/mcp/start-mcp-server.mjs.map +1 -0
  664. package/esm/tooling/mcp/tool-input.d.mts +75 -0
  665. package/esm/tooling/mcp/tool-input.d.mts.map +1 -0
  666. package/esm/tooling/mcp/tool-input.mjs +72 -0
  667. package/esm/tooling/mcp/tool-input.mjs.map +1 -0
  668. package/esm/tooling/problem.d.mts +45 -0
  669. package/esm/tooling/problem.d.mts.map +1 -0
  670. package/esm/tooling/problem.mjs +28 -0
  671. package/esm/tooling/problem.mjs.map +1 -0
  672. package/esm/tooling/trace/trace-report.types.d.mts +71 -0
  673. package/esm/tooling/trace/trace-report.types.d.mts.map +1 -0
  674. package/esm/tooling/trace/trace-report.types.mjs +7 -0
  675. package/esm/tooling/trace/trace-report.types.mjs.map +1 -0
  676. package/esm/tooling/trace/trace-request.d.mts +83 -0
  677. package/esm/tooling/trace/trace-request.d.mts.map +1 -0
  678. package/esm/tooling/trace/trace-request.mjs +241 -0
  679. package/esm/tooling/trace/trace-request.mjs.map +1 -0
  680. package/esm/tooling/typecheck/index.d.mts +1 -0
  681. package/esm/tooling/typecheck/index.mjs +3 -0
  682. package/esm/tooling/typecheck/run-typecheck.d.mts +59 -0
  683. package/esm/tooling/typecheck/run-typecheck.d.mts.map +1 -0
  684. package/esm/tooling/typecheck/run-typecheck.mjs +153 -0
  685. package/esm/tooling/typecheck/run-typecheck.mjs.map +1 -0
  686. package/esm/upgrade/codemods/head-viewport.mjs +46 -0
  687. package/esm/upgrade/codemods/head-viewport.mjs.map +1 -0
  688. package/esm/upgrade/codemods/helpers.mjs +81 -0
  689. package/esm/upgrade/codemods/helpers.mjs.map +1 -0
  690. package/esm/upgrade/codemods/index.mjs +34 -0
  691. package/esm/upgrade/codemods/index.mjs.map +1 -0
  692. package/esm/upgrade/codemods/logger-sync-calls.mjs +57 -0
  693. package/esm/upgrade/codemods/logger-sync-calls.mjs.map +1 -0
  694. package/esm/upgrade/codemods/package-json.mjs +122 -0
  695. package/esm/upgrade/codemods/package-json.mjs.map +1 -0
  696. package/esm/upgrade/codemods/request-log-snapshot.mjs +82 -0
  697. package/esm/upgrade/codemods/request-log-snapshot.mjs.map +1 -0
  698. package/esm/upgrade/codemods/review-sites.mjs +262 -0
  699. package/esm/upgrade/codemods/review-sites.mjs.map +1 -0
  700. package/esm/upgrade/diff.mjs +119 -0
  701. package/esm/upgrade/diff.mjs.map +1 -0
  702. package/esm/upgrade/format-upgrade-report.mjs +32 -0
  703. package/esm/upgrade/format-upgrade-report.mjs.map +1 -0
  704. package/esm/upgrade/load-ts-morph.mjs +48 -0
  705. package/esm/upgrade/load-ts-morph.mjs.map +1 -0
  706. package/esm/upgrade/notes.mjs +16 -0
  707. package/esm/upgrade/notes.mjs.map +1 -0
  708. package/esm/upgrade/run-upgrade.mjs +246 -0
  709. package/esm/upgrade/run-upgrade.mjs.map +1 -0
  710. package/esm/upgrade/upgrade-command.action.mjs +37 -0
  711. package/esm/upgrade/upgrade-command.action.mjs.map +1 -0
  712. package/esm/upgrade/version.mjs +39 -0
  713. package/esm/upgrade/version.mjs.map +1 -0
  714. package/esm/use-cases/use-cases-registry.mjs.map +1 -1
  715. package/esm/utils/clock.d.mts +33 -0
  716. package/esm/utils/clock.d.mts.map +1 -0
  717. package/esm/utils/clock.mjs +27 -0
  718. package/esm/utils/clock.mjs.map +1 -0
  719. package/esm/utils/framework-vesion.mjs +1 -1
  720. package/esm/utils/framework-vesion.mjs.map +1 -1
  721. package/esm/utils/ids.d.mts +32 -0
  722. package/esm/utils/ids.d.mts.map +1 -0
  723. package/esm/utils/ids.mjs +33 -0
  724. package/esm/utils/ids.mjs.map +1 -0
  725. package/esm/utils/index.d.mts +3 -0
  726. package/esm/utils/index.mjs +3 -0
  727. package/esm/utils/runtime.d.mts +59 -0
  728. package/esm/utils/runtime.d.mts.map +1 -0
  729. package/esm/utils/runtime.mjs +85 -0
  730. package/esm/utils/runtime.mjs.map +1 -0
  731. package/esm/validation/index.d.mts +1 -1
  732. package/esm/validation/types.d.mts +57 -2
  733. package/esm/validation/types.d.mts.map +1 -1
  734. package/esm/validation/validateAll.mjs +19 -2
  735. package/esm/validation/validateAll.mjs.map +1 -1
  736. package/esm/validation/validation-failure-status.mjs +15 -0
  737. package/esm/validation/validation-failure-status.mjs.map +1 -0
  738. package/esm/validation/validators/file-validator.d.mts +0 -16
  739. package/esm/validation/validators/file-validator.d.mts.map +1 -1
  740. package/esm/warlock-config/bundle-config.mjs +1 -1
  741. package/esm/warlock-config/types.d.mts +27 -3
  742. package/esm/warlock-config/types.d.mts.map +1 -1
  743. package/llms-full.txt +3166 -736
  744. package/llms.txt +16 -6
  745. package/package.json +43 -13
  746. package/schemas/inspect-report.schema.json +554 -0
  747. package/skills/README.md +9 -0
  748. package/skills/add-connector/SKILL.md +26 -38
  749. package/skills/benchmark-code/SKILL.md +30 -24
  750. package/skills/build-restful/SKILL.md +14 -14
  751. package/skills/build-url/SKILL.md +18 -18
  752. package/skills/configure-app/SKILL.md +107 -14
  753. package/skills/create-controller/SKILL.md +25 -12
  754. package/skills/create-module/SKILL.md +3 -3
  755. package/skills/define-resource/SKILL.md +32 -29
  756. package/skills/encrypt-data/SKILL.md +21 -19
  757. package/skills/generate-openapi/SKILL.md +50 -24
  758. package/skills/hash-password/SKILL.md +2 -2
  759. package/skills/health-checks/SKILL.md +24 -7
  760. package/skills/index.md +9 -4
  761. package/skills/lower-stage3-decorators/SKILL.md +4 -4
  762. package/skills/make-endpoint/SKILL.md +110 -0
  763. package/skills/model-factories/SKILL.md +92 -0
  764. package/skills/process-image/SKILL.md +32 -30
  765. package/skills/register-route/SKILL.md +109 -10
  766. package/skills/request-memo/SKILL.md +1 -1
  767. package/skills/request-tracing/SKILL.md +4 -1
  768. package/skills/resolve-path/SKILL.md +45 -44
  769. package/skills/retry-operation/SKILL.md +20 -11
  770. package/skills/run-app/SKILL.md +106 -22
  771. package/skills/send-response/SKILL.md +179 -14
  772. package/skills/store-file/SKILL.md +93 -53
  773. package/skills/test-fakes/SKILL.md +123 -0
  774. package/skills/test-http/SKILL.md +125 -21
  775. package/skills/test-service/SKILL.md +41 -1
  776. package/skills/update-packages/SKILL.md +29 -18
  777. package/skills/upgrade-from-5-29/SKILL.md +413 -0
  778. package/skills/upload-file/SKILL.md +31 -33
  779. package/skills/use-app-context/SKILL.md +38 -31
  780. package/skills/use-middleware/SKILL.md +45 -25
  781. package/skills/use-model-transformers/SKILL.md +37 -28
  782. package/skills/use-repository/SKILL.md +2 -2
  783. package/skills/validate-input/SKILL.md +72 -28
  784. package/skills/warlock-agents-md/SKILL.md +96 -0
  785. package/skills/warlock-board/SKILL.md +123 -0
  786. package/skills/warlock-check/SKILL.md +132 -0
  787. package/skills/warlock-conventions/SKILL.md +115 -0
  788. package/skills/warlock-doctor/SKILL.md +55 -22
  789. package/skills/warlock-inspect/SKILL.md +134 -0
  790. package/skills/warlock-mcp/SKILL.md +120 -0
  791. package/skills/warlock-routes/SKILL.md +18 -11
  792. package/skills/warlock-trace/SKILL.md +81 -0
  793. package/skills/wire-socket/SKILL.md +8 -8
  794. package/skills/write-seeder/SKILL.md +46 -32
  795. package/skills/write-use-case/SKILL.md +40 -27
  796. package/esm/http/uploads/matches-if-none-match.mjs +0 -13
  797. package/esm/http/uploads/matches-if-none-match.mjs.map +0 -1
@@ -0,0 +1,39 @@
1
+ //#region ../../packages/core/src/tests/fakes/test-fakes.d.ts
2
+ /** The fakes the test kit installs. */
3
+ declare const TEST_FAKE_NAMES: readonly ["mail", "queue", "cache", "storage", "clock", "ids"];
4
+ type TestFakeName = (typeof TEST_FAKE_NAMES)[number];
5
+ /**
6
+ * Which fakes to install.
7
+ *
8
+ * - `true` (the default) — all of them.
9
+ * - `false` — none: real drivers, real clock, real ids.
10
+ * - an object — all of them except the ones set to `false`, e.g.
11
+ * `{ cache: false }` keeps the configured cache driver.
12
+ */
13
+ type TestFakesSelection = boolean | Partial<Record<TestFakeName, boolean>>;
14
+ /** Read `tests.fakes` from `src/config/tests.ts`, or `undefined` when unset. */
15
+ declare function readConfiguredFakes(): TestFakesSelection | undefined;
16
+ /**
17
+ * The fakes to install. Precedence: an explicit selection (the `fakes`
18
+ * option of `setupTest()` / `startHttpTestServer()`) > `tests.fakes` in
19
+ * `src/config/tests.ts` > all on.
20
+ */
21
+ declare function resolveTestFakes(explicit?: TestFakesSelection): TestFakeName[];
22
+ /**
23
+ * Install the selected fakes. Called by `setupTest()` and
24
+ * `startHttpTestServer()` once their connectors are up; call it yourself only
25
+ * when you bootstrap the framework without them.
26
+ *
27
+ * @returns the fakes that are now installed.
28
+ */
29
+ declare function installTestFakes(explicit?: TestFakesSelection): Promise<TestFakeName[]>;
30
+ /**
31
+ * Restore every installed fake, in reverse order. Every fake is restored even
32
+ * when one fails; the failures are rethrown together afterwards.
33
+ */
34
+ declare function restoreTestFakes(): Promise<void>;
35
+ /** The fakes installed right now. */
36
+ declare function installedTestFakes(): TestFakeName[];
37
+ //#endregion
38
+ export { TEST_FAKE_NAMES, TestFakeName, TestFakesSelection, installTestFakes, installedTestFakes, readConfiguredFakes, resolveTestFakes, restoreTestFakes };
39
+ //# sourceMappingURL=test-fakes.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-fakes.d.mts","names":[],"sources":["../../../../../../../../../packages/core/src/tests/fakes/test-fakes.ts"],"mappings":";;cAUa,eAAA;AAAA,KAED,YAAA,WAAuB,eAAe;;;AAF2C;AAE7F;;;;AAAkD;KAUtC,kBAAA,aAA+B,OAAA,CAAQ,MAAA,CAAO,YAAA;;iBAiB1C,mBAAA,IAAuB,kBAAkB;;;;;;iBA0CzC,gBAAA,CAAiB,QAAA,GAAW,kBAAA,GAAqB,YAAY;;;;AA3DP;AAiBtE;;;iBA2DsB,gBAAA,CAAiB,QAAA,GAAW,kBAAA,GAAqB,OAAA,CAAQ,YAAA;AA3DtB;AA0CzD;;;AA1CyD,iBA2EnC,gBAAA,IAAoB,OAAO;;iBAiBjC,kBAAA,IAAsB,YAAY"}
@@ -0,0 +1,90 @@
1
+ import { config } from "../../config/config-getter.mjs";
2
+ import "../../config/index.mjs";
3
+ import { cacheFake } from "./cache-fake.mjs";
4
+ import { clockFake } from "./clock-fake.mjs";
5
+ import { idsFake } from "./ids-fake.mjs";
6
+ import { mailFake } from "./mail-fake.mjs";
7
+ import { queueFake } from "./queue-fake.mjs";
8
+ import { storageFake } from "./storage-fake.mjs";
9
+
10
+ //#region ../../packages/core/src/tests/fakes/test-fakes.ts
11
+ /** The fakes the test kit installs. */
12
+ const TEST_FAKE_NAMES = [
13
+ "mail",
14
+ "queue",
15
+ "cache",
16
+ "storage",
17
+ "clock",
18
+ "ids"
19
+ ];
20
+ const fakes = {
21
+ mail: mailFake,
22
+ queue: queueFake,
23
+ cache: cacheFake,
24
+ storage: storageFake,
25
+ clock: clockFake,
26
+ ids: idsFake
27
+ };
28
+ let active = [];
29
+ /** Read `tests.fakes` from `src/config/tests.ts`, or `undefined` when unset. */
30
+ function readConfiguredFakes() {
31
+ return validateSelection((config.get("tests", {}) ?? {}).fakes, "tests.fakes");
32
+ }
33
+ function validateSelection(value, source) {
34
+ if (value === void 0 || typeof value === "boolean") return value;
35
+ if (typeof value !== "object" || value === null || Array.isArray(value)) throw new Error(`${source} must be true, false, or an object such as { cache: false }; got ${JSON.stringify(value)}.`);
36
+ const selection = {};
37
+ for (const [key, flag] of Object.entries(value)) {
38
+ const name = TEST_FAKE_NAMES.find((candidate) => candidate === key);
39
+ if (!name) throw new Error(`${source} has an unknown fake "${key}". Known fakes: ${TEST_FAKE_NAMES.join(", ")}.`);
40
+ if (typeof flag !== "boolean") throw new Error(`${source}.${key} must be true or false; got ${JSON.stringify(flag)}.`);
41
+ selection[name] = flag;
42
+ }
43
+ return selection;
44
+ }
45
+ /**
46
+ * The fakes to install. Precedence: an explicit selection (the `fakes`
47
+ * option of `setupTest()` / `startHttpTestServer()`) > `tests.fakes` in
48
+ * `src/config/tests.ts` > all on.
49
+ */
50
+ function resolveTestFakes(explicit) {
51
+ const selection = explicit !== void 0 ? validateSelection(explicit, "fakes") : readConfiguredFakes();
52
+ if (selection === void 0 || selection === true) return [...TEST_FAKE_NAMES];
53
+ if (selection === false) return [];
54
+ return TEST_FAKE_NAMES.filter((name) => selection[name] !== false);
55
+ }
56
+ /**
57
+ * Install the selected fakes. Called by `setupTest()` and
58
+ * `startHttpTestServer()` once their connectors are up; call it yourself only
59
+ * when you bootstrap the framework without them.
60
+ *
61
+ * @returns the fakes that are now installed.
62
+ */
63
+ async function installTestFakes(explicit) {
64
+ const selected = resolveTestFakes(explicit);
65
+ for (const name of selected) await fakes[name].install();
66
+ active = [...new Set([...active, ...selected])];
67
+ return selected;
68
+ }
69
+ /**
70
+ * Restore every installed fake, in reverse order. Every fake is restored even
71
+ * when one fails; the failures are rethrown together afterwards.
72
+ */
73
+ async function restoreTestFakes() {
74
+ const errors = [];
75
+ for (const name of [...active].reverse()) try {
76
+ await fakes[name].restore();
77
+ } catch (error) {
78
+ errors.push(error);
79
+ }
80
+ active = [];
81
+ if (errors.length > 0) throw new AggregateError(errors, "Restoring the test fakes failed.");
82
+ }
83
+ /** The fakes installed right now. */
84
+ function installedTestFakes() {
85
+ return [...active];
86
+ }
87
+
88
+ //#endregion
89
+ export { TEST_FAKE_NAMES, installTestFakes, installedTestFakes, readConfiguredFakes, resolveTestFakes, restoreTestFakes };
90
+ //# sourceMappingURL=test-fakes.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-fakes.mjs","names":[],"sources":["../../../../../../../../../packages/core/src/tests/fakes/test-fakes.ts"],"sourcesContent":["import type { GenericObject } from \"@mongez/reinforcements\";\nimport { config } from \"../../config\";\nimport { cacheFake } from \"./cache-fake\";\nimport { clockFake } from \"./clock-fake\";\nimport { idsFake } from \"./ids-fake\";\nimport { mailFake } from \"./mail-fake\";\nimport { queueFake } from \"./queue-fake\";\nimport { storageFake } from \"./storage-fake\";\n\n/** The fakes the test kit installs. */\nexport const TEST_FAKE_NAMES = [\"mail\", \"queue\", \"cache\", \"storage\", \"clock\", \"ids\"] as const;\n\nexport type TestFakeName = (typeof TEST_FAKE_NAMES)[number];\n\n/**\n * Which fakes to install.\n *\n * - `true` (the default) — all of them.\n * - `false` — none: real drivers, real clock, real ids.\n * - an object — all of them except the ones set to `false`, e.g.\n * `{ cache: false }` keeps the configured cache driver.\n */\nexport type TestFakesSelection = boolean | Partial<Record<TestFakeName, boolean>>;\n\nconst fakes: Record<\n TestFakeName,\n { install(): void | Promise<void>; restore(): void | Promise<void> }\n> = {\n mail: mailFake,\n queue: queueFake,\n cache: cacheFake,\n storage: storageFake,\n clock: clockFake,\n ids: idsFake,\n};\n\nlet active: TestFakeName[] = [];\n\n/** Read `tests.fakes` from `src/config/tests.ts`, or `undefined` when unset. */\nexport function readConfiguredFakes(): TestFakesSelection | undefined {\n // `config.get` resolves an absent key to `null`, not to its default's shape.\n const testsConfig = config.get<GenericObject>(\"tests\", {}) ?? {};\n\n return validateSelection(testsConfig.fakes as unknown, \"tests.fakes\");\n}\n\nfunction validateSelection(value: unknown, source: string): TestFakesSelection | undefined {\n if (value === undefined || typeof value === \"boolean\") return value;\n\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw new Error(\n `${source} must be true, false, or an object such as { cache: false }; got ${JSON.stringify(value)}.`,\n );\n }\n\n const selection: Partial<Record<TestFakeName, boolean>> = {};\n\n for (const [key, flag] of Object.entries(value)) {\n const name = TEST_FAKE_NAMES.find((candidate) => candidate === key);\n\n if (!name) {\n throw new Error(\n `${source} has an unknown fake \"${key}\". Known fakes: ${TEST_FAKE_NAMES.join(\", \")}.`,\n );\n }\n\n if (typeof flag !== \"boolean\") {\n throw new Error(`${source}.${key} must be true or false; got ${JSON.stringify(flag)}.`);\n }\n\n selection[name] = flag;\n }\n\n return selection;\n}\n\n/**\n * The fakes to install. Precedence: an explicit selection (the `fakes`\n * option of `setupTest()` / `startHttpTestServer()`) > `tests.fakes` in\n * `src/config/tests.ts` > all on.\n */\nexport function resolveTestFakes(explicit?: TestFakesSelection): TestFakeName[] {\n const selection =\n explicit !== undefined ? validateSelection(explicit, \"fakes\") : readConfiguredFakes();\n\n if (selection === undefined || selection === true) return [...TEST_FAKE_NAMES];\n if (selection === false) return [];\n\n return TEST_FAKE_NAMES.filter((name) => selection[name] !== false);\n}\n\n/**\n * Install the selected fakes. Called by `setupTest()` and\n * `startHttpTestServer()` once their connectors are up; call it yourself only\n * when you bootstrap the framework without them.\n *\n * @returns the fakes that are now installed.\n */\nexport async function installTestFakes(explicit?: TestFakesSelection): Promise<TestFakeName[]> {\n const selected = resolveTestFakes(explicit);\n\n for (const name of selected) {\n await fakes[name].install();\n }\n\n active = [...new Set([...active, ...selected])];\n\n return selected;\n}\n\n/**\n * Restore every installed fake, in reverse order. Every fake is restored even\n * when one fails; the failures are rethrown together afterwards.\n */\nexport async function restoreTestFakes(): Promise<void> {\n const errors: unknown[] = [];\n\n for (const name of [...active].reverse()) {\n try {\n await fakes[name].restore();\n } catch (error) {\n errors.push(error);\n }\n }\n\n active = [];\n\n if (errors.length > 0) throw new AggregateError(errors, \"Restoring the test fakes failed.\");\n}\n\n/** The fakes installed right now. */\nexport function installedTestFakes(): TestFakeName[] {\n return [...active];\n}\n"],"mappings":";;;;;;;;;;;AAUA,MAAa,kBAAkB;CAAC;CAAQ;CAAS;CAAS;CAAW;CAAS;AAAK;AAcnF,MAAM,QAGF;CACF,MAAM;CACN,OAAO;CACP,OAAO;CACP,SAAS;CACT,OAAO;CACP,KAAK;AACP;AAEA,IAAI,SAAyB,CAAC;;AAG9B,SAAgB,sBAAsD;CAIpE,OAAO,mBAFa,OAAO,IAAmB,SAAS,CAAC,CAAC,KAAK,CAAC,EAE3B,CAAC,OAAkB,aAAa;AACtE;AAEA,SAAS,kBAAkB,OAAgB,QAAgD;CACzF,IAAI,UAAU,UAAa,OAAO,UAAU,WAAW,OAAO;CAE9D,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,KAAK,GACpE,MAAM,IAAI,MACR,GAAG,OAAO,mEAAmE,KAAK,UAAU,KAAK,EAAE,EACrG;CAGF,MAAM,YAAoD,CAAC;CAE3D,KAAK,MAAM,CAAC,KAAK,SAAS,OAAO,QAAQ,KAAK,GAAG;EAC/C,MAAM,OAAO,gBAAgB,MAAM,cAAc,cAAc,GAAG;EAElE,IAAI,CAAC,MACH,MAAM,IAAI,MACR,GAAG,OAAO,wBAAwB,IAAI,kBAAkB,gBAAgB,KAAK,IAAI,EAAE,EACrF;EAGF,IAAI,OAAO,SAAS,WAClB,MAAM,IAAI,MAAM,GAAG,OAAO,GAAG,IAAI,8BAA8B,KAAK,UAAU,IAAI,EAAE,EAAE;EAGxF,UAAU,QAAQ;CACpB;CAEA,OAAO;AACT;;;;;;AAOA,SAAgB,iBAAiB,UAA+C;CAC9E,MAAM,YACJ,aAAa,SAAY,kBAAkB,UAAU,OAAO,IAAI,oBAAoB;CAEtF,IAAI,cAAc,UAAa,cAAc,MAAM,OAAO,CAAC,GAAG,eAAe;CAC7E,IAAI,cAAc,OAAO,OAAO,CAAC;CAEjC,OAAO,gBAAgB,QAAQ,SAAS,UAAU,UAAU,KAAK;AACnE;;;;;;;;AASA,eAAsB,iBAAiB,UAAwD;CAC7F,MAAM,WAAW,iBAAiB,QAAQ;CAE1C,KAAK,MAAM,QAAQ,UACjB,MAAM,MAAM,KAAK,CAAC,QAAQ;CAG5B,SAAS,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,QAAQ,GAAG,QAAQ,CAAC,CAAC;CAE9C,OAAO;AACT;;;;;AAMA,eAAsB,mBAAkC;CACtD,MAAM,SAAoB,CAAC;CAE3B,KAAK,MAAM,QAAQ,CAAC,GAAG,MAAM,CAAC,CAAC,QAAQ,GACrC,IAAI;EACF,MAAM,MAAM,KAAK,CAAC,QAAQ;CAC5B,SAAS,OAAO;EACd,OAAO,KAAK,KAAK;CACnB;CAGF,SAAS,CAAC;CAEV,IAAI,OAAO,SAAS,GAAG,MAAM,IAAI,eAAe,QAAQ,kCAAkC;AAC5F;;AAGA,SAAgB,qBAAqC;CACnD,OAAO,CAAC,GAAG,MAAM;AACnB"}
@@ -1,6 +1,18 @@
1
1
  import { assertPortIsAvailable, isPortAvailable } from "../http/port-preflight.mjs";
2
+ import { TEST_FAKE_NAMES, TestFakeName, TestFakesSelection, installTestFakes, installedTestFakes, readConfiguredFakes, resolveTestFakes, restoreTestFakes } from "./fakes/test-fakes.mjs";
2
3
  import { StartHttpTestServerOptions, isTestServerRunning, startHttpTestServer, stopHttpTestServer } from "./start-http-development-server.mjs";
3
- import { expectJson, getTestServerUrl, parseJsonResponse, testDelete, testGet, testPatch, testPost, testPut, testRequest } from "./test-helpers.mjs";
4
+ import { TestRequestClient, createTestRequestClient, expectJson, getTestServerUrl, parseJsonResponse, testDelete, testGet, testPatch, testPost, testPut, testRequest } from "./test-helpers.mjs";
5
+ import { AuthenticatedTestClient, TestAuthenticableUser, actingAs } from "./authenticated-test-client.mjs";
4
6
  import { TestConnectorsSelection } from "./test-connectors-selection.mjs";
5
7
  import { TestLifecycleError, TestSetupOptions, setupTest, teardownTest, warnMissingImportModule } from "./vitest-setup.mjs";
6
- export { StartHttpTestServerOptions, type TestConnectorsSelection, TestLifecycleError, TestSetupOptions, assertPortIsAvailable, expectJson, getTestServerUrl, isPortAvailable, isTestServerRunning, parseJsonResponse, setupTest, startHttpTestServer, stopHttpTestServer, teardownTest, testDelete, testGet, testPatch, testPost, testPut, testRequest, warnMissingImportModule };
8
+ import { cacheFake } from "./fakes/cache-fake.mjs";
9
+ import { DEFAULT_FAKE_NOW, clockFake } from "./fakes/clock-fake.mjs";
10
+ import { FakeAssertionError, describeRecorded } from "./fakes/fake-assertion-error.mjs";
11
+ import { idsFake } from "./fakes/ids-fake.mjs";
12
+ import { MailMatcher, mailFake } from "./fakes/mail-fake.mjs";
13
+ import { JobReference, PushedJob, PushedJobMatcher, queueFake } from "./fakes/queue-fake.mjs";
14
+ import { storageFake } from "./fakes/storage-fake.mjs";
15
+ import { Factory, FactoryAttributes, FactoryOverrides, FactorySeed, FactoryState, defineFactory, resetFactorySequences } from "./factories.mjs";
16
+ import { CreateTestHttpServerOptions, TestHttpServer, createTestHttpServer } from "./test-http-server.mjs";
17
+ import { REDACTED, ResponseSnapshot, SnapshotResponseOptions, snapshotResponse } from "./snapshot-response.mjs";
18
+ export { AuthenticatedTestClient, CreateTestHttpServerOptions, DEFAULT_FAKE_NOW, Factory, FactoryAttributes, FactoryOverrides, FactorySeed, FactoryState, FakeAssertionError, JobReference, MailMatcher, PushedJob, PushedJobMatcher, REDACTED, ResponseSnapshot, SnapshotResponseOptions, StartHttpTestServerOptions, TEST_FAKE_NAMES, TestAuthenticableUser, type TestConnectorsSelection, TestFakeName, TestFakesSelection, TestHttpServer, TestLifecycleError, TestRequestClient, TestSetupOptions, actingAs, assertPortIsAvailable, cacheFake, clockFake, createTestHttpServer, createTestRequestClient, defineFactory, describeRecorded, expectJson, getTestServerUrl, idsFake, installTestFakes, installedTestFakes, isPortAvailable, isTestServerRunning, mailFake, parseJsonResponse, queueFake, readConfiguredFakes, resetFactorySequences, resolveTestFakes, restoreTestFakes, setupTest, snapshotResponse, startHttpTestServer, stopHttpTestServer, storageFake, teardownTest, testDelete, testGet, testPatch, testPost, testPut, testRequest, warnMissingImportModule };
@@ -1,6 +1,19 @@
1
1
  import { assertPortIsAvailable, isPortAvailable } from "../http/port-preflight.mjs";
2
+ import { FakeAssertionError, describeRecorded } from "./fakes/fake-assertion-error.mjs";
3
+ import { cacheFake } from "./fakes/cache-fake.mjs";
4
+ import { DEFAULT_FAKE_NOW, clockFake } from "./fakes/clock-fake.mjs";
5
+ import { idsFake } from "./fakes/ids-fake.mjs";
6
+ import { mailFake } from "./fakes/mail-fake.mjs";
7
+ import { queueFake } from "./fakes/queue-fake.mjs";
8
+ import { storageFake } from "./fakes/storage-fake.mjs";
9
+ import { TEST_FAKE_NAMES, installTestFakes, installedTestFakes, readConfiguredFakes, resolveTestFakes, restoreTestFakes } from "./fakes/test-fakes.mjs";
2
10
  import { isTestServerRunning, startHttpTestServer, stopHttpTestServer } from "./start-http-development-server.mjs";
3
- import { expectJson, getTestServerUrl, parseJsonResponse, testDelete, testGet, testPatch, testPost, testPut, testRequest } from "./test-helpers.mjs";
11
+ import { createTestRequestClient, expectJson, getTestServerUrl, parseJsonResponse, testDelete, testGet, testPatch, testPost, testPut, testRequest } from "./test-helpers.mjs";
12
+ import { actingAs } from "./authenticated-test-client.mjs";
4
13
  import { TestLifecycleError, setupTest, teardownTest, warnMissingImportModule } from "./vitest-setup.mjs";
14
+ import "./fakes/index.mjs";
15
+ import { defineFactory, resetFactorySequences } from "./factories.mjs";
16
+ import { createTestHttpServer } from "./test-http-server.mjs";
17
+ import { REDACTED, snapshotResponse } from "./snapshot-response.mjs";
5
18
 
6
- export { TestLifecycleError, assertPortIsAvailable, expectJson, getTestServerUrl, isPortAvailable, isTestServerRunning, parseJsonResponse, setupTest, startHttpTestServer, stopHttpTestServer, teardownTest, testDelete, testGet, testPatch, testPost, testPut, testRequest, warnMissingImportModule };
19
+ export { DEFAULT_FAKE_NOW, FakeAssertionError, REDACTED, TEST_FAKE_NAMES, TestLifecycleError, actingAs, assertPortIsAvailable, cacheFake, clockFake, createTestHttpServer, createTestRequestClient, defineFactory, describeRecorded, expectJson, getTestServerUrl, idsFake, installTestFakes, installedTestFakes, isPortAvailable, isTestServerRunning, mailFake, parseJsonResponse, queueFake, readConfiguredFakes, resetFactorySequences, resolveTestFakes, restoreTestFakes, setupTest, snapshotResponse, startHttpTestServer, stopHttpTestServer, storageFake, teardownTest, testDelete, testGet, testPatch, testPost, testPut, testRequest, warnMissingImportModule };
@@ -0,0 +1,34 @@
1
+ //#region ../../packages/core/src/tests/snapshot-response.d.ts
2
+ /**
3
+ * A response reduced to what a snapshot should pin: the status, the content
4
+ * type and the body — with the values that differ on every run (ids, tokens,
5
+ * timestamps) replaced, so the snapshot fails only when the shape or a stable
6
+ * value changes.
7
+ */
8
+ type ResponseSnapshot = {
9
+ status: number;
10
+ contentType: string | null;
11
+ body: unknown;
12
+ };
13
+ type SnapshotResponseOptions = {
14
+ /**
15
+ * Dot paths whose values are replaced by `"[redacted]"`. `*` matches any
16
+ * key or array index: `"post.id"`, `"posts.*.createdAt"`, `"*.token"`.
17
+ */
18
+ redact?: string[];
19
+ };
20
+ declare const REDACTED = "[redacted]";
21
+ /**
22
+ * Read a response into a {@link ResponseSnapshot} for `toMatchSnapshot()`.
23
+ * Consumes the body: call it instead of `response.json()`, not after.
24
+ *
25
+ * @example
26
+ * const response = await testPost("/posts", { title: "Hello" });
27
+ *
28
+ * expect(await snapshotResponse(response, { redact: ["post.id", "post.createdAt"] }))
29
+ * .toMatchSnapshot();
30
+ */
31
+ declare function snapshotResponse(response: Response, options?: SnapshotResponseOptions): Promise<ResponseSnapshot>;
32
+ //#endregion
33
+ export { REDACTED, ResponseSnapshot, SnapshotResponseOptions, snapshotResponse };
34
+ //# sourceMappingURL=snapshot-response.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot-response.d.mts","names":[],"sources":["../../../../../../../../packages/core/src/tests/snapshot-response.ts"],"mappings":";;AAMA;;;;;KAAY,gBAAA;EACV,MAAA;EACA,WAAA;EACA,IAAA;AAAA;AAAA,KAGU,uBAAA;;;AAKJ;AAGR;EAHE,MAAM;AAAA;AAAA,cAGK,QAAA;AAAQ;AAkCrB;;;;;;;;;AAlCqB,iBAkCC,gBAAA,CACpB,QAAA,EAAU,QAAA,EACV,OAAA,GAAS,uBAAA,GACR,OAAA,CAAQ,gBAAA"}
@@ -0,0 +1,42 @@
1
+ //#region ../../packages/core/src/tests/snapshot-response.ts
2
+ const REDACTED = "[redacted]";
3
+ function redactPath(value, segments) {
4
+ if (segments.length === 0) return REDACTED;
5
+ if (typeof value !== "object" || value === null) return value;
6
+ const [head, ...rest] = segments;
7
+ if (Array.isArray(value)) return value.map((item, index) => head === "*" || head === String(index) ? redactPath(item, rest) : item);
8
+ const record = value;
9
+ const copy = { ...record };
10
+ for (const key of Object.keys(record)) if (head === "*" || head === key) copy[key] = redactPath(record[key], rest);
11
+ return copy;
12
+ }
13
+ /**
14
+ * Read a response into a {@link ResponseSnapshot} for `toMatchSnapshot()`.
15
+ * Consumes the body: call it instead of `response.json()`, not after.
16
+ *
17
+ * @example
18
+ * const response = await testPost("/posts", { title: "Hello" });
19
+ *
20
+ * expect(await snapshotResponse(response, { redact: ["post.id", "post.createdAt"] }))
21
+ * .toMatchSnapshot();
22
+ */
23
+ async function snapshotResponse(response, options = {}) {
24
+ const contentType = response.headers.get("content-type");
25
+ const text = await response.text();
26
+ let body = text;
27
+ if (contentType?.includes("json") && text !== "") try {
28
+ body = JSON.parse(text);
29
+ } catch {
30
+ body = text;
31
+ }
32
+ for (const path of options.redact ?? []) body = redactPath(body, path.split("."));
33
+ return {
34
+ status: response.status,
35
+ contentType,
36
+ body
37
+ };
38
+ }
39
+
40
+ //#endregion
41
+ export { REDACTED, snapshotResponse };
42
+ //# sourceMappingURL=snapshot-response.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot-response.mjs","names":[],"sources":["../../../../../../../../packages/core/src/tests/snapshot-response.ts"],"sourcesContent":["/**\n * A response reduced to what a snapshot should pin: the status, the content\n * type and the body — with the values that differ on every run (ids, tokens,\n * timestamps) replaced, so the snapshot fails only when the shape or a stable\n * value changes.\n */\nexport type ResponseSnapshot = {\n status: number;\n contentType: string | null;\n body: unknown;\n};\n\nexport type SnapshotResponseOptions = {\n /**\n * Dot paths whose values are replaced by `\"[redacted]\"`. `*` matches any\n * key or array index: `\"post.id\"`, `\"posts.*.createdAt\"`, `\"*.token\"`.\n */\n redact?: string[];\n};\n\nexport const REDACTED = \"[redacted]\";\n\nfunction redactPath(value: unknown, segments: readonly string[]): unknown {\n if (segments.length === 0) return REDACTED;\n if (typeof value !== \"object\" || value === null) return value;\n\n const [head, ...rest] = segments;\n\n if (Array.isArray(value)) {\n return value.map((item, index) =>\n head === \"*\" || head === String(index) ? redactPath(item, rest) : item,\n );\n }\n\n const record = value as Record<string, unknown>;\n const copy: Record<string, unknown> = { ...record };\n\n for (const key of Object.keys(record)) {\n if (head === \"*\" || head === key) copy[key] = redactPath(record[key], rest);\n }\n\n return copy;\n}\n\n/**\n * Read a response into a {@link ResponseSnapshot} for `toMatchSnapshot()`.\n * Consumes the body: call it instead of `response.json()`, not after.\n *\n * @example\n * const response = await testPost(\"/posts\", { title: \"Hello\" });\n *\n * expect(await snapshotResponse(response, { redact: [\"post.id\", \"post.createdAt\"] }))\n * .toMatchSnapshot();\n */\nexport async function snapshotResponse(\n response: Response,\n options: SnapshotResponseOptions = {},\n): Promise<ResponseSnapshot> {\n const contentType = response.headers.get(\"content-type\");\n const text = await response.text();\n let body: unknown = text;\n\n if (contentType?.includes(\"json\") && text !== \"\") {\n try {\n body = JSON.parse(text) as unknown;\n } catch {\n body = text;\n }\n }\n\n for (const path of options.redact ?? []) {\n body = redactPath(body, path.split(\".\"));\n }\n\n return { status: response.status, contentType, body };\n}\n"],"mappings":";AAoBA,MAAa,WAAW;AAExB,SAAS,WAAW,OAAgB,UAAsC;CACxE,IAAI,SAAS,WAAW,GAAG,OAAO;CAClC,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM,OAAO;CAExD,MAAM,CAAC,MAAM,GAAG,QAAQ;CAExB,IAAI,MAAM,QAAQ,KAAK,GACrB,OAAO,MAAM,KAAK,MAAM,UACtB,SAAS,OAAO,SAAS,OAAO,KAAK,IAAI,WAAW,MAAM,IAAI,IAAI,IACpE;CAGF,MAAM,SAAS;CACf,MAAM,OAAgC,EAAE,GAAG,OAAO;CAElD,KAAK,MAAM,OAAO,OAAO,KAAK,MAAM,GAClC,IAAI,SAAS,OAAO,SAAS,KAAK,KAAK,OAAO,WAAW,OAAO,MAAM,IAAI;CAG5E,OAAO;AACT;;;;;;;;;;;AAYA,eAAsB,iBACpB,UACA,UAAmC,CAAC,GACT;CAC3B,MAAM,cAAc,SAAS,QAAQ,IAAI,cAAc;CACvD,MAAM,OAAO,MAAM,SAAS,KAAK;CACjC,IAAI,OAAgB;CAEpB,IAAI,aAAa,SAAS,MAAM,KAAK,SAAS,IAC5C,IAAI;EACF,OAAO,KAAK,MAAM,IAAI;CACxB,QAAQ;EACN,OAAO;CACT;CAGF,KAAK,MAAM,QAAQ,QAAQ,UAAU,CAAC,GACpC,OAAO,WAAW,MAAM,KAAK,MAAM,GAAG,CAAC;CAGzC,OAAO;EAAE,QAAQ,SAAS;EAAQ;EAAa;CAAK;AACtD"}
@@ -1,3 +1,5 @@
1
+ import { TestFakesSelection } from "./fakes/test-fakes.mjs";
2
+
1
3
  //#region ../../packages/core/src/tests/start-http-development-server.d.ts
2
4
  type StartHttpTestServerOptions = {
3
5
  /**
@@ -5,6 +7,10 @@ type StartHttpTestServerOptions = {
5
7
  *
6
8
  * Needed because the server cannot be moved from outside: this function
7
9
  * bootstraps the app itself, and that bootstrap re-reads `.env`.
10
+ *
11
+ * `0` asks the OS for a free port. The port actually bound is published to
12
+ * the test workers, so `testGet()`, `actingAs()` and friends follow it, and
13
+ * a suite never collides with `warlock dev` or another suite.
8
14
  */
9
15
  port?: number;
10
16
  /**
@@ -17,6 +23,18 @@ type StartHttpTestServerOptions = {
17
23
  * @default true
18
24
  */
19
25
  web?: boolean;
26
+ /**
27
+ * Which test fakes the server process installs (mail, queue, cache,
28
+ * storage, clock, ids). Same values and precedence as `setupTest({ fakes })`:
29
+ * this option > `tests.fakes` config > all on.
30
+ *
31
+ * A fake records what happens in ITS process: mail sent while this server
32
+ * handles a request is captured here, not in the test worker that sent the
33
+ * request. To assert on what an HTTP request did, serve it in the worker
34
+ * with `createTestHttpServer()`. The storage fake is the exception: its
35
+ * temp root is shared with the workers.
36
+ */
37
+ fakes?: TestFakesSelection;
20
38
  };
21
39
  /**
22
40
  * Start the HTTP test server (minimal - no file watching)
@@ -25,6 +43,10 @@ type StartHttpTestServerOptions = {
25
43
  * @example
26
44
  * // run this suite on its own port, whatever `.env` says
27
45
  * await startHttpTestServer({ port: 3999 });
46
+ *
47
+ * @example
48
+ * // let the OS pick a free port; the request helpers follow it
49
+ * await startHttpTestServer({ port: 0 });
28
50
  */
29
51
  declare function startHttpTestServer(options?: StartHttpTestServerOptions): Promise<void>;
30
52
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"start-http-development-server.d.mts","names":[],"sources":["../../../../../../../../packages/core/src/tests/start-http-development-server.ts"],"mappings":";KAyBY,0BAAA;EAAA;;;;AAkBP;AAkGL;EA7GE,IAAA;;;;;;;AA6G0F;AA0G5F;;EA5ME,GAAG;AAAA;AA4M8C;AA6BnD;;;;AAAmC;;;AA7BgB,iBA1G7B,mBAAA,CAAoB,OAAA,GAAS,0BAAA,GAAkC,OAAO;;;;;iBA0GtE,kBAAA,IAAsB,OAAO;;;;iBA6BnC,mBAAA"}
1
+ {"version":3,"file":"start-http-development-server.d.mts","names":[],"sources":["../../../../../../../../packages/core/src/tests/start-http-development-server.ts"],"mappings":";;;KA4BY,0BAAA;;AAAZ;;;;;;;;;EAWE,IAAA;EAqJoB;;;;;;;;AAAsE;EA1I1F,GAAA;EAqQsC;;;AAAW;AAmCnD;;;;AAAmC;;;EA3RjC,KAAA,GAAQ,kBAAkB;AAAA;;;;;;;;;;;;;iBA6HN,mBAAA,CAAoB,OAAA,GAAS,0BAAA,GAAkC,OAAO;;;;;iBA2HtE,kBAAA,IAAsB,OAAO;;;;iBAmCnC,mBAAA"}
@@ -1,6 +1,7 @@
1
1
  import { Application } from "../application/application.mjs";
2
2
  import "../application/index.mjs";
3
3
  import { assertPortIsAvailable } from "../http/port-preflight.mjs";
4
+ import { getHttpReadyReport } from "../http/ready-report.mjs";
4
5
  import { loadEnvironmentFiles } from "../utils/load-environment.mjs";
5
6
  import { bootstrap } from "../bootstrap.mjs";
6
7
  import { ConnectorLifecyclePhase } from "../connectors/types.mjs";
@@ -8,6 +9,7 @@ import { connectorsManager } from "../connectors/connectors-manager.mjs";
8
9
  import { warlockConfigManager } from "../warlock-config/warlock-config.manager.mjs";
9
10
  import { filesOrchestrator } from "../dev-server/files-orchestrator.mjs";
10
11
  import { loadConfigFiles } from "../config/load-config-files.mjs";
12
+ import { installTestFakes, restoreTestFakes } from "./fakes/test-fakes.mjs";
11
13
  import { publishTestServerPort, withdrawTestServerPort } from "./test-server-port-channel.mjs";
12
14
  import config from "@mongez/config";
13
15
 
@@ -50,14 +52,28 @@ async function startTestServerPhase(phase) {
50
52
  async function applyTestServerPort(port) {
51
53
  if (!config.get("http")) {
52
54
  if (port !== void 0) throw new Error(`startHttpTestServer({ port: ${port} }) was given a port, but this app has no \`http\` config, so no HTTP server is started. Add \`src/config/http.ts\` first.`);
53
- return;
55
+ return "none";
54
56
  }
55
57
  if (port !== void 0) config.set("http.port", port);
56
58
  const resolvedPort = config.get("http.port");
57
59
  if (typeof resolvedPort !== "number") throw new Error(`startHttpTestServer() cannot use \`http.port\` value ${JSON.stringify(resolvedPort)} — it did not round-trip through Number() (env() only coerces a value when \`String(Number(v)) === v\`, so "03999", "+3999", "1e3", and values with stray whitespace stay strings). Fix \`HTTP_PORT\` in .env, or pass an explicit numeric port: startHttpTestServer({ port: 3999 }).`);
58
- if (resolvedPort <= 0) throw new Error(`startHttpTestServer() cannot run on port ${resolvedPort}. Pass an explicit port — e.g. startHttpTestServer({ port: 3999 }) — or set \`http.port\` in your config. Test workers are separate processes that resolve the server's URL from the port published at startup, and an OS-assigned port is not knowable to them.`);
60
+ if (resolvedPort === 0) return "ephemeral";
61
+ if (resolvedPort < 0) throw new Error(`startHttpTestServer() cannot run on port ${resolvedPort}. Pass a port number, or 0 to let the OS pick a free one — e.g. startHttpTestServer({ port: 0 }).`);
59
62
  await assertPortIsAvailable(resolvedPort, config.get("http.host") || "localhost");
60
63
  publishTestServerPort(resolvedPort);
64
+ return "published";
65
+ }
66
+ /**
67
+ * Publish the port an ephemeral (`port: 0`) bind actually took.
68
+ *
69
+ * `before` is the ready report from before the late phase: the report is a
70
+ * module-level record, so an unchanged one means THIS boot bound nothing and an
71
+ * older report must not be mistaken for it.
72
+ */
73
+ function publishEphemeralPort(before) {
74
+ const report = getHttpReadyReport();
75
+ if (!report || report === before || report.port <= 0) throw new Error("startHttpTestServer({ port: 0 }) booted, but the HTTP connector did not bind a port, so there is no address to give the test workers. Check that `src/config/http.ts` exists and that this process serves HTTP (its role is not worker-only).");
76
+ publishTestServerPort(report.port);
61
77
  }
62
78
  /**
63
79
  * Start the HTTP test server (minimal - no file watching)
@@ -66,6 +82,10 @@ async function applyTestServerPort(port) {
66
82
  * @example
67
83
  * // run this suite on its own port, whatever `.env` says
68
84
  * await startHttpTestServer({ port: 3999 });
85
+ *
86
+ * @example
87
+ * // let the OS pick a free port; the request helpers follow it
88
+ * await startHttpTestServer({ port: 0 });
69
89
  */
70
90
  async function startHttpTestServer(options = {}) {
71
91
  const nodeEnvironment = process.env.NODE_ENV;
@@ -87,11 +107,14 @@ async function startHttpTestServer(options = {}) {
87
107
  await loadConfigFiles(true);
88
108
  if (options.web === false) await startTestServerPhase("early");
89
109
  else await connectorsManager.startPhase("early");
110
+ await installTestFakes(options.fakes);
90
111
  await filesOrchestrator.moduleLoader.loadAll();
91
- await applyTestServerPort(options.port);
112
+ const portMode = await applyTestServerPort(options.port);
113
+ const readyReportBefore = getHttpReadyReport();
92
114
  await Application.runStartupValidators();
93
115
  if (options.web === false) await startTestServerPhase("late");
94
116
  else await connectorsManager.startPhase("late");
117
+ if (portMode === "ephemeral") publishEphemeralPort(readyReportBefore);
95
118
  isServerRunning = true;
96
119
  } catch (error) {
97
120
  await unwindPartialStartup();
@@ -106,6 +129,11 @@ async function startHttpTestServer(options = {}) {
106
129
  * already in flight, and the caller is about to rethrow it.
107
130
  */
108
131
  async function unwindPartialStartup() {
132
+ try {
133
+ await restoreTestFakes();
134
+ } catch (fakesError) {
135
+ console.error("[test-server] Restoring the test fakes after a failed start did not complete:", fakesError);
136
+ }
109
137
  try {
110
138
  await connectorsManager.shutdown();
111
139
  } catch (shutdownError) {
@@ -124,6 +152,11 @@ async function stopHttpTestServer() {
124
152
  return;
125
153
  }
126
154
  try {
155
+ try {
156
+ await restoreTestFakes();
157
+ } catch (fakesError) {
158
+ console.error("[test-server] Restoring the test fakes did not complete:", fakesError);
159
+ }
127
160
  await connectorsManager.shutdown();
128
161
  console.log("[test-server] HTTP test server stopped");
129
162
  } catch (error) {
@@ -1 +1 @@
1
- {"version":3,"file":"start-http-development-server.mjs","names":[],"sources":["../../../../../../../../packages/core/src/tests/start-http-development-server.ts"],"sourcesContent":["/**\n * HTTP Test Server\n *\n * Starts a minimal HTTP server for testing.\n * Unlike the full DevelopmentServer, this:\n * - Does NOT watch files\n * - Does NOT do HMR\n * - Only starts connectors needed for HTTP requests\n *\n * Used in Vitest's globalSetup to start server once for all test workers.\n */\nimport config from \"@mongez/config\";\nimport { Application } from \"../application\";\nimport { bootstrap } from \"../bootstrap\";\nimport { loadConfigFiles } from \"../config/load-config-files\";\nimport { connectorsManager } from \"../connectors/connectors-manager\";\nimport { ConnectorLifecyclePhase } from \"../connectors/types\";\nimport { filesOrchestrator } from \"../dev-server/files-orchestrator\";\nimport { assertPortIsAvailable } from \"../http/port-preflight\";\nimport { loadEnvironmentFiles } from \"../utils/load-environment\";\nimport { warlockConfigManager } from \"../warlock-config/warlock-config.manager\";\nimport { publishTestServerPort, withdrawTestServerPort } from \"./test-server-port-channel\";\n\nlet isServerRunning = false;\n\nexport type StartHttpTestServerOptions = {\n /**\n * Port the test server binds to, overriding `http.port`.\n *\n * Needed because the server cannot be moved from outside: this function\n * bootstraps the app itself, and that bootstrap re-reads `.env`.\n */\n port?: number;\n\n /**\n * Whether to boot the optional web connector.\n *\n * Defaults to `true` to preserve the full-stack test server. Pass `false`\n * for API-only suites: the web connector's lazy delegate is skipped before\n * `boot()`, so it never constructs its Vite-backed implementation.\n *\n * @default true\n */\n web?: boolean;\n};\n\n/**\n * Start one lifecycle phase while omitting the web connector.\n *\n * Kept here rather than changing the manager's public API: this is a\n * test-server-only selection, and retaining the manager's boot-all / start-all\n * ordering is essential for HTTP and socket connector wiring.\n */\nasync function startTestServerPhase(phase: ConnectorLifecyclePhase): Promise<void> {\n const connectors = connectorsManager\n .list()\n .filter((connector) => connector.lifecyclePhase === phase)\n .filter((connector) => connector.name !== \"web\");\n\n for (const connector of connectors) {\n await connector.boot();\n }\n\n for (const connector of connectors) {\n await connector.start();\n }\n}\n\n/**\n * Apply the caller's port and preflight the bind.\n *\n * Called at the last moment before the HTTP connector binds, and that timing is\n * the fix: `bootstrap()` re-reads `.env` through `loadEnv()` (dotenv overrides\n * by default), and `src/config/http.ts` then resolves its port from that store,\n * so anything the caller set earlier is gone by the time the port is read.\n * Writing into `config` here is also the only channel that works — assigning\n * `process.env.HTTP_PORT` has no effect, since `env()` reads dotenv's own store\n * and never falls back to `process.env`.\n */\nasync function applyTestServerPort(port?: number): Promise<void> {\n const httpConfig = config.get(\"http\");\n\n if (!httpConfig) {\n if (port !== undefined) {\n throw new Error(\n `startHttpTestServer({ port: ${port} }) was given a port, but this app has no \\`http\\` config, so no HTTP server is started. Add \\`src/config/http.ts\\` first.`,\n );\n }\n\n return;\n }\n\n if (port !== undefined) {\n config.set(\"http.port\", port);\n }\n\n const resolvedPort = config.get(\"http.port\");\n\n // No configured port at all is fine: Fastify falls back to its own default and\n // the workers resolve the same one from their own config, so both ends agree\n // without the channel.\n //\n // A non-numeric port is NOT fine, and must fail loudly rather than skip the\n // preflight silently. `env()` coerces a value only when it round-trips exactly\n // (`String(Number(v)) === v`), so `HTTP_PORT=3999` and `HTTP_PORT=0` arrive as\n // numbers, but `03999`, `+3999`, `1e3` and anything with stray whitespace stay\n // strings. Letting those through used to reach `HttpConnector.start()`'s\n // `listen({ port })` unchanged — no preflight, no published port, and every\n // test worker resolving a URL from a channel nothing ever wrote to.\n if (typeof resolvedPort !== \"number\") {\n throw new Error(\n `startHttpTestServer() cannot use \\`http.port\\` value ${JSON.stringify(resolvedPort)} — it did not round-trip through Number() (env() only coerces a value when \\`String(Number(v)) === v\\`, so \"03999\", \"+3999\", \"1e3\", and values with stray whitespace stay strings). Fix \\`HTTP_PORT\\` in .env, or pass an explicit numeric port: startHttpTestServer({ port: 3999 }).`,\n );\n }\n\n // `0` is the OS's \"pick a free one for me\" idiom, and the test server cannot\n // support it. Preflighting 0 would bind some unrelated ephemeral port and pass\n // without proving anything, and there is nothing meaningful to publish: the\n // port Fastify ends up binding is never recorded — `HttpConnector.start()`\n // stores the port it ASKED for, not the one it got. Accepting 0 silently is\n // what left `getTestServerUrl()` resolving to `http://host:0` through its own\n // config fallback, so every worker request went to a port nothing listens on.\n if (resolvedPort <= 0) {\n throw new Error(\n `startHttpTestServer() cannot run on port ${resolvedPort}. Pass an explicit port — e.g. startHttpTestServer({ port: 3999 }) — or set \\`http.port\\` in your config. Test workers are separate processes that resolve the server's URL from the port published at startup, and an OS-assigned port is not knowable to them.`,\n );\n }\n\n await assertPortIsAvailable(resolvedPort, config.get(\"http.host\") || \"localhost\");\n\n publishTestServerPort(resolvedPort);\n}\n\n/**\n * Start the HTTP test server (minimal - no file watching)\n * Call this in Vitest's globalSetup\n *\n * @example\n * // run this suite on its own port, whatever `.env` says\n * await startHttpTestServer({ port: 3999 });\n */\nexport async function startHttpTestServer(options: StartHttpTestServerOptions = {}): Promise<void> {\n const nodeEnvironment = process.env.NODE_ENV;\n\n if (nodeEnvironment === undefined) {\n process.env.NODE_ENV = \"test\";\n } else if (nodeEnvironment !== \"test\") {\n throw new Error(\n `startHttpTestServer() requires NODE_ENV=\"test\", but received NODE_ENV=${JSON.stringify(nodeEnvironment)}. Set NODE_ENV=test before starting the test server.`,\n );\n }\n\n if (isServerRunning) {\n console.log(\"[test-server] Server already running, skipping start\");\n return;\n }\n\n console.log(\"[test-server] Starting HTTP test server...\");\n\n try {\n // `globalSetup` runs in Vitest's main process, where Vitest's worker env\n // setup has not run. Load `.env.test` here, before any config is read.\n await loadEnvironmentFiles();\n\n // Set environment\n Application.setRuntimeStrategy(\"development\");\n Application.setEnvironment(\"test\");\n\n // Bootstrap (env, etc.)\n await warlockConfigManager.load();\n await bootstrap();\n\n // Initialize file orchestrator (but don't watch)\n await filesOrchestrator.init();\n await filesOrchestrator.initializeAll();\n\n // Load config files\n await loadConfigFiles(true);\n\n // Early-phase connectors (database, cache, logger, storage, mailer,\n // herald) must start BEFORE app modules load: a module's `main.ts` boot\n // side-effect can query the DB at import time, so the data source has to\n // be registered first. This mirrors the dev/prod boot order (see\n // `cli-commands.manager`, `production-builder`, and `DevelopmentServer`).\n if (options.web === false) {\n await startTestServerPhase(ConnectorLifecyclePhase.Early);\n } else {\n await connectorsManager.startPhase(ConnectorLifecyclePhase.Early);\n }\n\n // Load application modules (their boot side-effects now see a live DB).\n await filesOrchestrator.moduleLoader.loadAll();\n\n await applyTestServerPort(options.port);\n\n // A rejecting validator (Application.onValidateBoot) must abort boot\n // before late-phase connectors bind a port — same slot as\n // `DevelopmentServer.start()` and the generated production `app.ts`.\n await Application.runStartupValidators();\n\n // Late-phase connectors (http, socket) bind after app code has\n // registered its routes and listeners.\n if (options.web === false) {\n await startTestServerPhase(ConnectorLifecyclePhase.Late);\n } else {\n await connectorsManager.startPhase(ConnectorLifecyclePhase.Late);\n }\n\n isServerRunning = true;\n } catch (error) {\n // This function owns the connectors it starts, so a failure part-way\n // through has to leave nothing behind. Without this, `isServerRunning` was\n // still `false` — it is only set on the last line — so `globalTeardown`'s\n // `stopHttpTestServer()` reported \"No server to stop\" and walked away from\n // live early-phase connectors and a published port that outlived them.\n await unwindPartialStartup();\n\n // Rethrown unchanged: the startup failure is the one the caller needs to\n // read. A cleanup failure that replaced it would hide the actual cause.\n throw error;\n }\n}\n\n/**\n * Best-effort teardown of whatever a failed {@link startHttpTestServer} managed\n * to start.\n *\n * Every step is independent and none may throw: this runs while an error is\n * already in flight, and the caller is about to rethrow it.\n */\nasync function unwindPartialStartup(): Promise<void> {\n try {\n await connectorsManager.shutdown();\n } catch (shutdownError) {\n // Reported, not thrown — it is secondary to the startup error being\n // rethrown, and losing that one to this would be the worse outcome.\n console.error(\"[test-server] Cleanup after a failed start did not complete:\", shutdownError);\n }\n\n withdrawTestServerPort();\n isServerRunning = false;\n}\n\n/**\n * Stop the HTTP test server\n * Call this in Vitest's globalTeardown\n */\nexport async function stopHttpTestServer(): Promise<void> {\n if (!isServerRunning) {\n console.log(\"[test-server] No server to stop\");\n return;\n }\n\n try {\n await connectorsManager.shutdown();\n\n console.log(\"[test-server] HTTP test server stopped\");\n } catch (error) {\n // Surfaced, never swallowed — cleaning up is not the same as the shutdown\n // having succeeded, and a suite whose teardown failed should say so.\n console.error(\"[test-server] Error stopping HTTP server:\", error);\n\n throw error;\n } finally {\n // In a `finally` rather than after the `await`: when `shutdown()` threw,\n // the published port survived the server it pointed at, so the next run in\n // the same process inherited a stale one and sent every request to it.\n withdrawTestServerPort();\n\n isServerRunning = false;\n }\n}\n\n/**\n * Check if test server is running\n */\nexport function isTestServerRunning(): boolean {\n return isServerRunning;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAuBA,IAAI,kBAAkB;;;;;;;;AA8BtB,eAAe,qBAAqB,OAA+C;CACjF,MAAM,aAAa,kBAChB,KAAK,CAAC,CACN,QAAQ,cAAc,UAAU,mBAAmB,KAAK,CAAC,CACzD,QAAQ,cAAc,UAAU,SAAS,KAAK;CAEjD,KAAK,MAAM,aAAa,YACtB,MAAM,UAAU,KAAK;CAGvB,KAAK,MAAM,aAAa,YACtB,MAAM,UAAU,MAAM;AAE1B;;;;;;;;;;;;AAaA,eAAe,oBAAoB,MAA8B;CAG/D,IAAI,CAFe,OAAO,IAAI,MAEhB,GAAG;EACf,IAAI,SAAS,QACX,MAAM,IAAI,MACR,+BAA+B,KAAK,2HACtC;EAGF;CACF;CAEA,IAAI,SAAS,QACX,OAAO,IAAI,aAAa,IAAI;CAG9B,MAAM,eAAe,OAAO,IAAI,WAAW;CAa3C,IAAI,OAAO,iBAAiB,UAC1B,MAAM,IAAI,MACR,wDAAwD,KAAK,UAAU,YAAY,EAAE,sRACvF;CAUF,IAAI,gBAAgB,GAClB,MAAM,IAAI,MACR,4CAA4C,aAAa,iQAC3D;CAGF,MAAM,sBAAsB,cAAc,OAAO,IAAI,WAAW,KAAK,WAAW;CAEhF,sBAAsB,YAAY;AACpC;;;;;;;;;AAUA,eAAsB,oBAAoB,UAAsC,CAAC,GAAkB;CACjG,MAAM,kBAAkB,QAAQ,IAAI;CAEpC,IAAI,oBAAoB,QACtB,QAAQ,IAAI,WAAW;MAClB,IAAI,oBAAoB,QAC7B,MAAM,IAAI,MACR,yEAAyE,KAAK,UAAU,eAAe,EAAE,qDAC3G;CAGF,IAAI,iBAAiB;EACnB,QAAQ,IAAI,sDAAsD;EAClE;CACF;CAEA,QAAQ,IAAI,4CAA4C;CAExD,IAAI;EAGF,MAAM,qBAAqB;EAG3B,YAAY,mBAAmB,aAAa;EAC5C,YAAY,eAAe,MAAM;EAGjC,MAAM,qBAAqB,KAAK;EAChC,MAAM,UAAU;EAGhB,MAAM,kBAAkB,KAAK;EAC7B,MAAM,kBAAkB,cAAc;EAGtC,MAAM,gBAAgB,IAAI;EAO1B,IAAI,QAAQ,QAAQ,OAClB,MAAM,4BAAkD;OAExD,MAAM,kBAAkB,kBAAwC;EAIlE,MAAM,kBAAkB,aAAa,QAAQ;EAE7C,MAAM,oBAAoB,QAAQ,IAAI;EAKtC,MAAM,YAAY,qBAAqB;EAIvC,IAAI,QAAQ,QAAQ,OAClB,MAAM,2BAAiD;OAEvD,MAAM,kBAAkB,iBAAuC;EAGjE,kBAAkB;CACpB,SAAS,OAAO;EAMd,MAAM,qBAAqB;EAI3B,MAAM;CACR;AACF;;;;;;;;AASA,eAAe,uBAAsC;CACnD,IAAI;EACF,MAAM,kBAAkB,SAAS;CACnC,SAAS,eAAe;EAGtB,QAAQ,MAAM,gEAAgE,aAAa;CAC7F;CAEA,uBAAuB;CACvB,kBAAkB;AACpB;;;;;AAMA,eAAsB,qBAAoC;CACxD,IAAI,CAAC,iBAAiB;EACpB,QAAQ,IAAI,iCAAiC;EAC7C;CACF;CAEA,IAAI;EACF,MAAM,kBAAkB,SAAS;EAEjC,QAAQ,IAAI,wCAAwC;CACtD,SAAS,OAAO;EAGd,QAAQ,MAAM,6CAA6C,KAAK;EAEhE,MAAM;CACR,UAAU;EAIR,uBAAuB;EAEvB,kBAAkB;CACpB;AACF;;;;AAKA,SAAgB,sBAA+B;CAC7C,OAAO;AACT"}
1
+ {"version":3,"file":"start-http-development-server.mjs","names":[],"sources":["../../../../../../../../packages/core/src/tests/start-http-development-server.ts"],"sourcesContent":["/**\n * HTTP Test Server\n *\n * Starts a minimal HTTP server for testing.\n * Unlike the full DevelopmentServer, this:\n * - Does NOT watch files\n * - Does NOT do HMR\n * - Only starts connectors needed for HTTP requests\n *\n * Used in Vitest's globalSetup to start server once for all test workers.\n */\nimport config from \"@mongez/config\";\nimport { Application } from \"../application\";\nimport { bootstrap } from \"../bootstrap\";\nimport { loadConfigFiles } from \"../config/load-config-files\";\nimport { connectorsManager } from \"../connectors/connectors-manager\";\nimport { ConnectorLifecyclePhase } from \"../connectors/types\";\nimport { filesOrchestrator } from \"../dev-server/files-orchestrator\";\nimport { assertPortIsAvailable } from \"../http/port-preflight\";\nimport { getHttpReadyReport } from \"../http/ready-report\";\nimport { loadEnvironmentFiles } from \"../utils/load-environment\";\nimport { warlockConfigManager } from \"../warlock-config/warlock-config.manager\";\nimport { installTestFakes, restoreTestFakes } from \"./fakes/test-fakes\";\nimport type { TestFakesSelection } from \"./fakes/test-fakes\";\nimport { publishTestServerPort, withdrawTestServerPort } from \"./test-server-port-channel\";\n\nlet isServerRunning = false;\n\nexport type StartHttpTestServerOptions = {\n /**\n * Port the test server binds to, overriding `http.port`.\n *\n * Needed because the server cannot be moved from outside: this function\n * bootstraps the app itself, and that bootstrap re-reads `.env`.\n *\n * `0` asks the OS for a free port. The port actually bound is published to\n * the test workers, so `testGet()`, `actingAs()` and friends follow it, and\n * a suite never collides with `warlock dev` or another suite.\n */\n port?: number;\n\n /**\n * Whether to boot the optional web connector.\n *\n * Defaults to `true` to preserve the full-stack test server. Pass `false`\n * for API-only suites: the web connector's lazy delegate is skipped before\n * `boot()`, so it never constructs its Vite-backed implementation.\n *\n * @default true\n */\n web?: boolean;\n\n /**\n * Which test fakes the server process installs (mail, queue, cache,\n * storage, clock, ids). Same values and precedence as `setupTest({ fakes })`:\n * this option > `tests.fakes` config > all on.\n *\n * A fake records what happens in ITS process: mail sent while this server\n * handles a request is captured here, not in the test worker that sent the\n * request. To assert on what an HTTP request did, serve it in the worker\n * with `createTestHttpServer()`. The storage fake is the exception: its\n * temp root is shared with the workers.\n */\n fakes?: TestFakesSelection;\n};\n\n/**\n * Start one lifecycle phase while omitting the web connector.\n *\n * Kept here rather than changing the manager's public API: this is a\n * test-server-only selection, and retaining the manager's boot-all / start-all\n * ordering is essential for HTTP and socket connector wiring.\n */\nasync function startTestServerPhase(phase: ConnectorLifecyclePhase): Promise<void> {\n const connectors = connectorsManager\n .list()\n .filter((connector) => connector.lifecyclePhase === phase)\n .filter((connector) => connector.name !== \"web\");\n\n for (const connector of connectors) {\n await connector.boot();\n }\n\n for (const connector of connectors) {\n await connector.start();\n }\n}\n\n/**\n * Apply the caller's port and preflight the bind.\n *\n * Called at the last moment before the HTTP connector binds, and that timing is\n * the fix: `bootstrap()` re-reads `.env` through `loadEnv()` (dotenv overrides\n * by default), and `src/config/http.ts` then resolves its port from that store,\n * so anything the caller set earlier is gone by the time the port is read.\n * Writing into `config` here is also the only channel that works — assigning\n * `process.env.HTTP_PORT` has no effect, since `env()` reads dotenv's own store\n * and never falls back to `process.env`.\n */\nasync function applyTestServerPort(port?: number): Promise<\"published\" | \"ephemeral\" | \"none\"> {\n const httpConfig = config.get(\"http\");\n\n if (!httpConfig) {\n if (port !== undefined) {\n throw new Error(\n `startHttpTestServer({ port: ${port} }) was given a port, but this app has no \\`http\\` config, so no HTTP server is started. Add \\`src/config/http.ts\\` first.`,\n );\n }\n\n return \"none\";\n }\n\n if (port !== undefined) {\n config.set(\"http.port\", port);\n }\n\n const resolvedPort = config.get(\"http.port\");\n\n // No configured port at all is fine: Fastify falls back to its own default and\n // the workers resolve the same one from their own config, so both ends agree\n // without the channel.\n //\n // A non-numeric port is NOT fine, and must fail loudly rather than skip the\n // preflight silently. `env()` coerces a value only when it round-trips exactly\n // (`String(Number(v)) === v`), so `HTTP_PORT=3999` and `HTTP_PORT=0` arrive as\n // numbers, but `03999`, `+3999`, `1e3` and anything with stray whitespace stay\n // strings. Letting those through used to reach `HttpConnector.start()`'s\n // `listen({ port })` unchanged — no preflight, no published port, and every\n // test worker resolving a URL from a channel nothing ever wrote to.\n if (typeof resolvedPort !== \"number\") {\n throw new Error(\n `startHttpTestServer() cannot use \\`http.port\\` value ${JSON.stringify(resolvedPort)} — it did not round-trip through Number() (env() only coerces a value when \\`String(Number(v)) === v\\`, so \"03999\", \"+3999\", \"1e3\", and values with stray whitespace stay strings). Fix \\`HTTP_PORT\\` in .env, or pass an explicit numeric port: startHttpTestServer({ port: 3999 }).`,\n );\n }\n\n // `0` is the OS's \"pick a free one for me\". There is nothing to preflight —\n // probing 0 would bind some unrelated port and prove nothing — and nothing to\n // publish yet: the port is only known once the HTTP connector has bound, and\n // `HttpConnector.start()` records the port `listen()` actually returned (see\n // `ready-report.ts`). It is published right after the late phase instead.\n if (resolvedPort === 0) {\n return \"ephemeral\";\n }\n\n if (resolvedPort < 0) {\n throw new Error(\n `startHttpTestServer() cannot run on port ${resolvedPort}. Pass a port number, or 0 to let the OS pick a free one — e.g. startHttpTestServer({ port: 0 }).`,\n );\n }\n\n await assertPortIsAvailable(resolvedPort, config.get(\"http.host\") || \"localhost\");\n\n publishTestServerPort(resolvedPort);\n\n return \"published\";\n}\n\n/**\n * Publish the port an ephemeral (`port: 0`) bind actually took.\n *\n * `before` is the ready report from before the late phase: the report is a\n * module-level record, so an unchanged one means THIS boot bound nothing and an\n * older report must not be mistaken for it.\n */\nfunction publishEphemeralPort(before: ReturnType<typeof getHttpReadyReport>): void {\n const report = getHttpReadyReport();\n\n if (!report || report === before || report.port <= 0) {\n throw new Error(\n \"startHttpTestServer({ port: 0 }) booted, but the HTTP connector did not bind a port, so there is no address to give the test workers. Check that `src/config/http.ts` exists and that this process serves HTTP (its role is not worker-only).\",\n );\n }\n\n publishTestServerPort(report.port);\n}\n\n/**\n * Start the HTTP test server (minimal - no file watching)\n * Call this in Vitest's globalSetup\n *\n * @example\n * // run this suite on its own port, whatever `.env` says\n * await startHttpTestServer({ port: 3999 });\n *\n * @example\n * // let the OS pick a free port; the request helpers follow it\n * await startHttpTestServer({ port: 0 });\n */\nexport async function startHttpTestServer(options: StartHttpTestServerOptions = {}): Promise<void> {\n const nodeEnvironment = process.env.NODE_ENV;\n\n if (nodeEnvironment === undefined) {\n process.env.NODE_ENV = \"test\";\n } else if (nodeEnvironment !== \"test\") {\n throw new Error(\n `startHttpTestServer() requires NODE_ENV=\"test\", but received NODE_ENV=${JSON.stringify(nodeEnvironment)}. Set NODE_ENV=test before starting the test server.`,\n );\n }\n\n if (isServerRunning) {\n console.log(\"[test-server] Server already running, skipping start\");\n return;\n }\n\n console.log(\"[test-server] Starting HTTP test server...\");\n\n try {\n // `globalSetup` runs in Vitest's main process, where Vitest's worker env\n // setup has not run. Load `.env.test` here, before any config is read.\n await loadEnvironmentFiles();\n\n // Set environment\n Application.setRuntimeStrategy(\"development\");\n Application.setEnvironment(\"test\");\n\n // Bootstrap (env, etc.)\n await warlockConfigManager.load();\n await bootstrap();\n\n // Initialize file orchestrator (but don't watch)\n await filesOrchestrator.init();\n await filesOrchestrator.initializeAll();\n\n // Load config files\n await loadConfigFiles(true);\n\n // Early-phase connectors (database, cache, logger, storage, mailer,\n // herald) must start BEFORE app modules load: a module's `main.ts` boot\n // side-effect can query the DB at import time, so the data source has to\n // be registered first. This mirrors the dev/prod boot order (see\n // `cli-commands.manager`, `production-builder`, and `DevelopmentServer`).\n if (options.web === false) {\n await startTestServerPhase(ConnectorLifecyclePhase.Early);\n } else {\n await connectorsManager.startPhase(ConnectorLifecyclePhase.Early);\n }\n\n // Fakes before app modules load, so module boot code already sees them.\n await installTestFakes(options.fakes);\n\n // Load application modules (their boot side-effects now see a live DB).\n await filesOrchestrator.moduleLoader.loadAll();\n\n const portMode = await applyTestServerPort(options.port);\n const readyReportBefore = getHttpReadyReport();\n\n // A rejecting validator (Application.onValidateBoot) must abort boot\n // before late-phase connectors bind a port — same slot as\n // `DevelopmentServer.start()` and the generated production `app.ts`.\n await Application.runStartupValidators();\n\n // Late-phase connectors (http, socket) bind after app code has\n // registered its routes and listeners.\n if (options.web === false) {\n await startTestServerPhase(ConnectorLifecyclePhase.Late);\n } else {\n await connectorsManager.startPhase(ConnectorLifecyclePhase.Late);\n }\n\n if (portMode === \"ephemeral\") {\n publishEphemeralPort(readyReportBefore);\n }\n\n isServerRunning = true;\n } catch (error) {\n // This function owns the connectors it starts, so a failure part-way\n // through has to leave nothing behind. Without this, `isServerRunning` was\n // still `false` — it is only set on the last line — so `globalTeardown`'s\n // `stopHttpTestServer()` reported \"No server to stop\" and walked away from\n // live early-phase connectors and a published port that outlived them.\n await unwindPartialStartup();\n\n // Rethrown unchanged: the startup failure is the one the caller needs to\n // read. A cleanup failure that replaced it would hide the actual cause.\n throw error;\n }\n}\n\n/**\n * Best-effort teardown of whatever a failed {@link startHttpTestServer} managed\n * to start.\n *\n * Every step is independent and none may throw: this runs while an error is\n * already in flight, and the caller is about to rethrow it.\n */\nasync function unwindPartialStartup(): Promise<void> {\n try {\n await restoreTestFakes();\n } catch (fakesError) {\n console.error(\n \"[test-server] Restoring the test fakes after a failed start did not complete:\",\n fakesError,\n );\n }\n\n try {\n await connectorsManager.shutdown();\n } catch (shutdownError) {\n // Reported, not thrown — it is secondary to the startup error being\n // rethrown, and losing that one to this would be the worse outcome.\n console.error(\"[test-server] Cleanup after a failed start did not complete:\", shutdownError);\n }\n\n withdrawTestServerPort();\n isServerRunning = false;\n}\n\n/**\n * Stop the HTTP test server\n * Call this in Vitest's globalTeardown\n */\nexport async function stopHttpTestServer(): Promise<void> {\n if (!isServerRunning) {\n console.log(\"[test-server] No server to stop\");\n return;\n }\n\n try {\n try {\n await restoreTestFakes();\n } catch (fakesError) {\n console.error(\"[test-server] Restoring the test fakes did not complete:\", fakesError);\n }\n\n await connectorsManager.shutdown();\n\n console.log(\"[test-server] HTTP test server stopped\");\n } catch (error) {\n // Surfaced, never swallowed — cleaning up is not the same as the shutdown\n // having succeeded, and a suite whose teardown failed should say so.\n console.error(\"[test-server] Error stopping HTTP server:\", error);\n\n throw error;\n } finally {\n // In a `finally` rather than after the `await`: when `shutdown()` threw,\n // the published port survived the server it pointed at, so the next run in\n // the same process inherited a stale one and sent every request to it.\n withdrawTestServerPort();\n\n isServerRunning = false;\n }\n}\n\n/**\n * Check if test server is running\n */\nexport function isTestServerRunning(): boolean {\n return isServerRunning;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,IAAI,kBAAkB;;;;;;;;AA+CtB,eAAe,qBAAqB,OAA+C;CACjF,MAAM,aAAa,kBAChB,KAAK,CAAC,CACN,QAAQ,cAAc,UAAU,mBAAmB,KAAK,CAAC,CACzD,QAAQ,cAAc,UAAU,SAAS,KAAK;CAEjD,KAAK,MAAM,aAAa,YACtB,MAAM,UAAU,KAAK;CAGvB,KAAK,MAAM,aAAa,YACtB,MAAM,UAAU,MAAM;AAE1B;;;;;;;;;;;;AAaA,eAAe,oBAAoB,MAA4D;CAG7F,IAAI,CAFe,OAAO,IAAI,MAEhB,GAAG;EACf,IAAI,SAAS,QACX,MAAM,IAAI,MACR,+BAA+B,KAAK,2HACtC;EAGF,OAAO;CACT;CAEA,IAAI,SAAS,QACX,OAAO,IAAI,aAAa,IAAI;CAG9B,MAAM,eAAe,OAAO,IAAI,WAAW;CAa3C,IAAI,OAAO,iBAAiB,UAC1B,MAAM,IAAI,MACR,wDAAwD,KAAK,UAAU,YAAY,EAAE,sRACvF;CAQF,IAAI,iBAAiB,GACnB,OAAO;CAGT,IAAI,eAAe,GACjB,MAAM,IAAI,MACR,4CAA4C,aAAa,kGAC3D;CAGF,MAAM,sBAAsB,cAAc,OAAO,IAAI,WAAW,KAAK,WAAW;CAEhF,sBAAsB,YAAY;CAElC,OAAO;AACT;;;;;;;;AASA,SAAS,qBAAqB,QAAqD;CACjF,MAAM,SAAS,mBAAmB;CAElC,IAAI,CAAC,UAAU,WAAW,UAAU,OAAO,QAAQ,GACjD,MAAM,IAAI,MACR,+OACF;CAGF,sBAAsB,OAAO,IAAI;AACnC;;;;;;;;;;;;;AAcA,eAAsB,oBAAoB,UAAsC,CAAC,GAAkB;CACjG,MAAM,kBAAkB,QAAQ,IAAI;CAEpC,IAAI,oBAAoB,QACtB,QAAQ,IAAI,WAAW;MAClB,IAAI,oBAAoB,QAC7B,MAAM,IAAI,MACR,yEAAyE,KAAK,UAAU,eAAe,EAAE,qDAC3G;CAGF,IAAI,iBAAiB;EACnB,QAAQ,IAAI,sDAAsD;EAClE;CACF;CAEA,QAAQ,IAAI,4CAA4C;CAExD,IAAI;EAGF,MAAM,qBAAqB;EAG3B,YAAY,mBAAmB,aAAa;EAC5C,YAAY,eAAe,MAAM;EAGjC,MAAM,qBAAqB,KAAK;EAChC,MAAM,UAAU;EAGhB,MAAM,kBAAkB,KAAK;EAC7B,MAAM,kBAAkB,cAAc;EAGtC,MAAM,gBAAgB,IAAI;EAO1B,IAAI,QAAQ,QAAQ,OAClB,MAAM,4BAAkD;OAExD,MAAM,kBAAkB,kBAAwC;EAIlE,MAAM,iBAAiB,QAAQ,KAAK;EAGpC,MAAM,kBAAkB,aAAa,QAAQ;EAE7C,MAAM,WAAW,MAAM,oBAAoB,QAAQ,IAAI;EACvD,MAAM,oBAAoB,mBAAmB;EAK7C,MAAM,YAAY,qBAAqB;EAIvC,IAAI,QAAQ,QAAQ,OAClB,MAAM,2BAAiD;OAEvD,MAAM,kBAAkB,iBAAuC;EAGjE,IAAI,aAAa,aACf,qBAAqB,iBAAiB;EAGxC,kBAAkB;CACpB,SAAS,OAAO;EAMd,MAAM,qBAAqB;EAI3B,MAAM;CACR;AACF;;;;;;;;AASA,eAAe,uBAAsC;CACnD,IAAI;EACF,MAAM,iBAAiB;CACzB,SAAS,YAAY;EACnB,QAAQ,MACN,iFACA,UACF;CACF;CAEA,IAAI;EACF,MAAM,kBAAkB,SAAS;CACnC,SAAS,eAAe;EAGtB,QAAQ,MAAM,gEAAgE,aAAa;CAC7F;CAEA,uBAAuB;CACvB,kBAAkB;AACpB;;;;;AAMA,eAAsB,qBAAoC;CACxD,IAAI,CAAC,iBAAiB;EACpB,QAAQ,IAAI,iCAAiC;EAC7C;CACF;CAEA,IAAI;EACF,IAAI;GACF,MAAM,iBAAiB;EACzB,SAAS,YAAY;GACnB,QAAQ,MAAM,4DAA4D,UAAU;EACtF;EAEA,MAAM,kBAAkB,SAAS;EAEjC,QAAQ,IAAI,wCAAwC;CACtD,SAAS,OAAO;EAGd,QAAQ,MAAM,6CAA6C,KAAK;EAEhE,MAAM;CACR,UAAU;EAIR,uBAAuB;EAEvB,kBAAkB;CACpB;AACF;;;;AAKA,SAAgB,sBAA+B;CAC7C,OAAO;AACT"}
@@ -13,6 +13,25 @@ declare function getTestServerUrl(): string;
13
13
  * Uses native fetch - lightweight, no extra dependencies
14
14
  */
15
15
  declare function testRequest(path: string, options?: RequestInit): Promise<Response>;
16
+ /** The request helpers, bound to one server. */
17
+ type TestRequestClient = {
18
+ request(path: string, options?: RequestInit): Promise<Response>;
19
+ get(path: string, options?: RequestInit): Promise<Response>;
20
+ post(path: string, body?: unknown, options?: RequestInit): Promise<Response>;
21
+ put(path: string, body?: unknown, options?: RequestInit): Promise<Response>;
22
+ patch(path: string, body?: unknown, options?: RequestInit): Promise<Response>;
23
+ delete(path: string, options?: RequestInit): Promise<Response>;
24
+ };
25
+ /**
26
+ * Request helpers bound to `baseUrl` (a string, or a function read on every
27
+ * request). `testGet()` and friends are this, bound to the shared test server;
28
+ * `createTestHttpServer()` returns one bound to its own port.
29
+ *
30
+ * @example
31
+ * const client = createTestRequestClient("http://127.0.0.1:4100");
32
+ * await client.post("/posts", { title: "Hello" });
33
+ */
34
+ declare function createTestRequestClient(baseUrl: string | (() => string)): TestRequestClient;
16
35
  /**
17
36
  * GET request helper
18
37
  */
@@ -42,5 +61,5 @@ declare function parseJsonResponse<T>(response: Response): Promise<T>;
42
61
  */
43
62
  declare function expectJson<T>(response: Response, expectedStatus?: number): Promise<T>;
44
63
  //#endregion
45
- export { expectJson, getTestServerUrl, parseJsonResponse, testDelete, testGet, testPatch, testPost, testPut, testRequest };
64
+ export { TestRequestClient, createTestRequestClient, expectJson, getTestServerUrl, parseJsonResponse, testDelete, testGet, testPatch, testPost, testPut, testRequest };
46
65
  //# sourceMappingURL=test-helpers.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"test-helpers.d.mts","names":[],"sources":["../../../../../../../../packages/core/src/tests/test-helpers.ts"],"mappings":";;AAaA;;;;AAAgC;AA6BhC;;AA7BgC,iBAAhB,gBAAA;;;;;iBA6BM,WAAA,CAAY,IAAA,UAAc,OAAA,GAAS,WAAA,GAAmB,OAAA,CAAQ,QAAA;;;;iBAgD9D,OAAA,CAAQ,IAAA,UAAc,OAAA,GAAS,WAAA,GAAmB,OAAA,CAAQ,QAAA;;;AAhDY;iBAuDtE,QAAA,CACpB,IAAA,UACA,IAAA,YACA,OAAA,GAAS,WAAA,GACR,OAAA,CAAQ,QAAA;;;;iBAWW,OAAA,CACpB,IAAA,UACA,IAAA,YACA,OAAA,GAAS,WAAA,GACR,OAAA,CAAQ,QAAA;;;;iBAOW,UAAA,CAAW,IAAA,UAAc,OAAA,GAAS,WAAA,GAAmB,OAAA,CAAQ,QAAA;;;;iBAO7D,SAAA,CACpB,IAAA,UACA,IAAA,YACA,OAAA,GAAS,WAAA,GACR,OAAA,CAAQ,QAAA;;AA5C6E;AAOxF;iBAgDsB,iBAAA,IAAqB,QAAA,EAAU,QAAA,GAAW,OAAA,CAAQ,CAAA;;;;iBAOlD,UAAA,IAAc,QAAA,EAAU,QAAA,EAAU,cAAA,YAAuB,OAAA,CAAQ,CAAA"}
1
+ {"version":3,"file":"test-helpers.d.mts","names":[],"sources":["../../../../../../../../packages/core/src/tests/test-helpers.ts"],"mappings":";;AAaA;;;;AAAgC;AA6BhC;;AA7BgC,iBAAhB,gBAAA;;;;;iBA6BM,WAAA,CAAY,IAAA,UAAc,OAAA,GAAS,WAAA,GAAmB,OAAA,CAAQ,QAAA;;KA8CxE,iBAAA;EACV,OAAA,CAAQ,IAAA,UAAc,OAAA,GAAU,WAAA,GAAc,OAAA,CAAQ,QAAA;EACtD,GAAA,CAAI,IAAA,UAAc,OAAA,GAAU,WAAA,GAAc,OAAA,CAAQ,QAAA;EAClD,IAAA,CAAK,IAAA,UAAc,IAAA,YAAgB,OAAA,GAAU,WAAA,GAAc,OAAA,CAAQ,QAAA;EACnE,GAAA,CAAI,IAAA,UAAc,IAAA,YAAgB,OAAA,GAAU,WAAA,GAAc,OAAA,CAAQ,QAAA;EAClE,KAAA,CAAM,IAAA,UAAc,IAAA,YAAgB,OAAA,GAAU,WAAA,GAAc,OAAA,CAAQ,QAAA;EACpE,MAAA,CAAO,IAAA,UAAc,OAAA,GAAU,WAAA,GAAc,OAAA,CAAQ,QAAA;AAAA;;;;;;;;;;iBAYvC,uBAAA,CAAwB,OAAA,4BAAmC,iBAAiB;;;;iBAqBtE,OAAA,CAAQ,IAAA,UAAc,OAAA,GAAS,WAAA,GAAmB,OAAA,CAAQ,QAAA;;;;iBAO1D,QAAA,CACpB,IAAA,UACA,IAAA,YACA,OAAA,GAAS,WAAA,GACR,OAAA,CAAQ,QAAA;;;;iBAOW,OAAA,CACpB,IAAA,UACA,IAAA,YACA,OAAA,GAAS,WAAA,GACR,OAAA,CAAQ,QAAA;;;;iBAOW,UAAA,CAAW,IAAA,UAAc,OAAA,GAAS,WAAA,GAAmB,OAAA,CAAQ,QAAA;;;;iBAO7D,SAAA,CACpB,IAAA,UACA,IAAA,YACA,OAAA,GAAS,WAAA,GACR,OAAA,CAAQ,QAAA;;;;iBAOW,iBAAA,IAAqB,QAAA,EAAU,QAAA,GAAW,OAAA,CAAQ,CAAA;;;;iBAOlD,UAAA,IAAc,QAAA,EAAU,QAAA,EAAU,cAAA,YAAuB,OAAA,CAAQ,CAAA"}