@warlock.js/core 4.12.0 → 4.14.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 (189) hide show
  1. package/CHANGELOG.md +214 -0
  2. package/esm/cli/cli-commands.manager.mjs.map +1 -1
  3. package/esm/cli/commands/add.command.mjs +1 -1
  4. package/esm/cli/commands/add.command.mjs.map +1 -1
  5. package/esm/cli/commands/build.command.mjs +1 -1
  6. package/esm/cli/commands/build.command.mjs.map +1 -1
  7. package/esm/cli/commands/create-database.command.mjs +1 -1
  8. package/esm/cli/commands/create-database.command.mjs.map +1 -1
  9. package/esm/cli/commands/dev-server.command.mjs +1 -1
  10. package/esm/cli/commands/dev-server.command.mjs.map +1 -1
  11. package/esm/cli/commands/doctor/doctor-command.action.mjs.map +1 -1
  12. package/esm/cli/commands/doctor.command.mjs +1 -1
  13. package/esm/cli/commands/doctor.command.mjs.map +1 -1
  14. package/esm/cli/commands/drop-tables.command.mjs +1 -1
  15. package/esm/cli/commands/drop-tables.command.mjs.map +1 -1
  16. package/esm/cli/commands/generate/generate.command.mjs +1 -1
  17. package/esm/cli/commands/generate/generate.command.mjs.map +1 -1
  18. package/esm/cli/commands/generate/generators/controller.generator.mjs.map +1 -1
  19. package/esm/cli/commands/generate/generators/migration.generator.mjs +1 -1
  20. package/esm/cli/commands/generate/generators/migration.generator.mjs.map +1 -1
  21. package/esm/cli/commands/generate/generators/model.generator.mjs +1 -1
  22. package/esm/cli/commands/generate/generators/model.generator.mjs.map +1 -1
  23. package/esm/cli/commands/generate/generators/module.generator.mjs +1 -1
  24. package/esm/cli/commands/generate/generators/module.generator.mjs.map +1 -1
  25. package/esm/cli/commands/generate/generators/repository.generator.mjs.map +1 -1
  26. package/esm/cli/commands/generate/generators/resource.generator.mjs.map +1 -1
  27. package/esm/cli/commands/generate/generators/service.generator.mjs.map +1 -1
  28. package/esm/cli/commands/generate/utils/path-resolver.mjs +1 -1
  29. package/esm/cli/commands/generate/utils/writer.mjs +1 -1
  30. package/esm/cli/commands/migrate.command.mjs +1 -1
  31. package/esm/cli/commands/migrate.command.mjs.map +1 -1
  32. package/esm/cli/commands/routes/routes-command.action.mjs.map +1 -1
  33. package/esm/cli/commands/routes.command.mjs +1 -1
  34. package/esm/cli/commands/routes.command.mjs.map +1 -1
  35. package/esm/cli/commands/seed.command.mjs +1 -1
  36. package/esm/cli/commands/seed.command.mjs.map +1 -1
  37. package/esm/cli/commands/start-production.command.mjs +1 -1
  38. package/esm/cli/commands/start-production.command.mjs.map +1 -1
  39. package/esm/cli/commands/storage-put.action.mjs.map +1 -1
  40. package/esm/cli/commands/storage-put.command.mjs +1 -1
  41. package/esm/cli/commands/storage-put.command.mjs.map +1 -1
  42. package/esm/cli/commands/typings-generator.command.mjs +2 -2
  43. package/esm/cli/commands/typings-generator.command.mjs.map +1 -1
  44. package/esm/cli/commands/update.command.mjs +1 -1
  45. package/esm/cli/commands/update.command.mjs.map +1 -1
  46. package/esm/cli/commands-loader.mjs +1 -1
  47. package/esm/cli/commands-loader.mjs.map +1 -1
  48. package/esm/{cli → commands}/cli-command.d.mts +1 -1
  49. package/esm/commands/cli-command.d.mts.map +1 -0
  50. package/esm/{cli → commands}/cli-command.mjs +1 -1
  51. package/esm/commands/cli-command.mjs.map +1 -0
  52. package/esm/{cli → commands}/types.d.mts +1 -1
  53. package/esm/commands/types.d.mts.map +1 -0
  54. package/esm/config/load-config-files.mjs +1 -1
  55. package/esm/config/load-config-files.mjs.map +1 -1
  56. package/esm/connectors/base-connector.mjs +1 -1
  57. package/esm/connectors/base-connector.mjs.map +1 -1
  58. package/esm/connectors/connectors-manager.d.mts.map +1 -1
  59. package/esm/connectors/connectors-manager.mjs +5 -3
  60. package/esm/connectors/connectors-manager.mjs.map +1 -1
  61. package/esm/connectors/http-connector.d.mts.map +1 -1
  62. package/esm/connectors/http-connector.mjs +0 -2
  63. package/esm/connectors/http-connector.mjs.map +1 -1
  64. package/esm/database/create-database-action.mjs.map +1 -1
  65. package/esm/database/drop-tables-action.mjs.map +1 -1
  66. package/esm/database/migrate-action.mjs +1 -1
  67. package/esm/database/migrate-action.mjs.map +1 -1
  68. package/esm/database/seed-command-action.mjs +1 -1
  69. package/esm/database/seed-command-action.mjs.map +1 -1
  70. package/esm/dev-server/dev-logger.mjs +1 -1
  71. package/esm/dev-server/dev-logger.mjs.map +1 -1
  72. package/esm/dev-server/development-server.mjs +2 -2
  73. package/esm/dev-server/file-event-handler.mjs +1 -1
  74. package/esm/dev-server/file-event-handler.mjs.map +1 -1
  75. package/esm/dev-server/file-manager.mjs +1 -1
  76. package/esm/dev-server/file-manager.mjs.map +1 -1
  77. package/esm/dev-server/file-operations.mjs +1 -1
  78. package/esm/dev-server/file-operations.mjs.map +1 -1
  79. package/esm/dev-server/files-orchestrator.mjs +3 -18
  80. package/esm/dev-server/files-orchestrator.mjs.map +1 -1
  81. package/esm/dev-server/files-watcher.mjs +1 -1
  82. package/esm/dev-server/files-watcher.mjs.map +1 -1
  83. package/esm/dev-server/health-checker/file-health-checker.contract.d.mts +1 -1
  84. package/esm/dev-server/layer-executor.mjs +1 -1
  85. package/esm/dev-server/loader/register-loader.mjs +1 -1
  86. package/esm/dev-server/package-json-manager.mjs +1 -1
  87. package/esm/dev-server/package-json-manager.mjs.map +1 -1
  88. package/esm/dev-server/parse-imports.mjs +2 -2
  89. package/esm/dev-server/parse-imports.mjs.map +1 -1
  90. package/esm/dev-server/tsconfig-manager.mjs +1 -1
  91. package/esm/dev-server/tsconfig-manager.mjs.map +1 -1
  92. package/esm/dev-server/type-generator.mjs +1 -1
  93. package/esm/dev-server/type-generator.mjs.map +1 -1
  94. package/esm/dev-server/utils.mjs +1 -1
  95. package/esm/dev-server/utils.mjs.map +1 -1
  96. package/esm/generations/add-command.action.mjs +20 -8
  97. package/esm/generations/add-command.action.mjs.map +1 -1
  98. package/esm/http/build-cors-options.mjs +32 -0
  99. package/esm/http/build-cors-options.mjs.map +1 -0
  100. package/esm/http/middleware/max-body-size.middleware.d.mts +13 -5
  101. package/esm/http/middleware/max-body-size.middleware.d.mts.map +1 -1
  102. package/esm/http/middleware/max-body-size.middleware.mjs +13 -5
  103. package/esm/http/middleware/max-body-size.middleware.mjs.map +1 -1
  104. package/esm/http/plugins.d.mts.map +1 -1
  105. package/esm/http/plugins.mjs +2 -9
  106. package/esm/http/plugins.mjs.map +1 -1
  107. package/esm/http/server.d.mts.map +1 -1
  108. package/esm/http/server.mjs +3 -8
  109. package/esm/http/server.mjs.map +1 -1
  110. package/esm/index.d.mts +9 -17
  111. package/esm/index.mjs +4 -15
  112. package/esm/production/production-builder.mjs +51 -3
  113. package/esm/production/production-builder.mjs.map +1 -1
  114. package/esm/production/resolve-build-config.mjs +1 -1
  115. package/esm/production/resolve-build-config.mjs.map +1 -1
  116. package/esm/router/router.d.mts +9 -0
  117. package/esm/router/router.d.mts.map +1 -1
  118. package/esm/router/router.mjs +58 -5
  119. package/esm/router/router.mjs.map +1 -1
  120. package/esm/router/types.d.mts +24 -1
  121. package/esm/router/types.d.mts.map +1 -1
  122. package/esm/tests/index.d.mts +3 -2
  123. package/esm/tests/index.mjs +2 -3
  124. package/esm/tests/start-http-development-server.d.mts.map +1 -1
  125. package/esm/tests/start-http-development-server.mjs +38 -15
  126. package/esm/tests/start-http-development-server.mjs.map +1 -1
  127. package/esm/tests/test-connectors-selection.d.mts +14 -0
  128. package/esm/tests/test-connectors-selection.d.mts.map +1 -0
  129. package/esm/tests/test-connectors-selection.mjs +72 -0
  130. package/esm/tests/test-connectors-selection.mjs.map +1 -0
  131. package/esm/tests/test-helpers.d.mts.map +1 -1
  132. package/esm/tests/test-helpers.mjs +34 -13
  133. package/esm/tests/test-helpers.mjs.map +1 -1
  134. package/esm/tests/test-lifecycle-state.mjs +27 -0
  135. package/esm/tests/test-lifecycle-state.mjs.map +1 -0
  136. package/esm/tests/test-setup-timeout.mjs +53 -0
  137. package/esm/tests/test-setup-timeout.mjs.map +1 -0
  138. package/esm/tests/vitest-setup.d.mts +64 -8
  139. package/esm/tests/vitest-setup.d.mts.map +1 -1
  140. package/esm/tests/vitest-setup.mjs +317 -11
  141. package/esm/tests/vitest-setup.mjs.map +1 -1
  142. package/esm/utils/framework-vesion.mjs +1 -1
  143. package/esm/utils/index.d.mts +1 -0
  144. package/esm/utils/index.mjs +1 -0
  145. package/esm/utils/normalized-path.d.mts +55 -0
  146. package/esm/utils/normalized-path.d.mts.map +1 -0
  147. package/esm/{dev-server/path.mjs → utils/normalized-path.mjs} +15 -2
  148. package/esm/utils/normalized-path.mjs.map +1 -0
  149. package/esm/vite/index.d.mts +2 -0
  150. package/esm/vite/index.mjs +1 -1
  151. package/esm/vite/lower-stage3-decorators.d.mts +1 -1
  152. package/esm/vite/lower-stage3-decorators.mjs +1 -1
  153. package/esm/vite/lower-stage3-decorators.mjs.map +1 -1
  154. package/esm/warlock-config/index.mjs +1 -1
  155. package/esm/warlock-config/types.d.mts +34 -1
  156. package/esm/warlock-config/types.d.mts.map +1 -1
  157. package/esm/warlock-config/warlock-config.manager.d.mts.map +1 -1
  158. package/esm/warlock-config/warlock-config.manager.mjs +1 -2
  159. package/esm/warlock-config/warlock-config.manager.mjs.map +1 -1
  160. package/llms-full.txt +78 -23
  161. package/llms.txt +3 -3
  162. package/package.json +24 -12
  163. package/skills/lower-stage3-decorators/SKILL.md +4 -2
  164. package/skills/run-app/SKILL.md +6 -0
  165. package/skills/test-http/SKILL.md +37 -12
  166. package/skills/test-service/SKILL.md +167 -24
  167. package/skills/use-middleware/SKILL.md +5 -1
  168. package/esm/cli/cli-command.d.mts.map +0 -1
  169. package/esm/cli/cli-command.mjs.map +0 -1
  170. package/esm/cli/types.d.mts.map +0 -1
  171. package/esm/dev-server/files-orchestrator.d.mts +0 -89
  172. package/esm/dev-server/files-orchestrator.d.mts.map +0 -1
  173. package/esm/dev-server/files-watcher.d.mts +0 -69
  174. package/esm/dev-server/files-watcher.d.mts.map +0 -1
  175. package/esm/dev-server/health-checker/checkers/base-health-checker.d.mts +0 -55
  176. package/esm/dev-server/health-checker/checkers/base-health-checker.d.mts.map +0 -1
  177. package/esm/dev-server/health-checker/checkers/eslint-health-checker.d.mts +0 -44
  178. package/esm/dev-server/health-checker/checkers/eslint-health-checker.d.mts.map +0 -1
  179. package/esm/dev-server/health-checker/checkers/typescript-health-checker.d.mts +0 -60
  180. package/esm/dev-server/health-checker/checkers/typescript-health-checker.d.mts.map +0 -1
  181. package/esm/dev-server/health-checker/files-healthcare.manager.d.mts +0 -119
  182. package/esm/dev-server/health-checker/files-healthcare.manager.d.mts.map +0 -1
  183. package/esm/dev-server/health-checker/index.mjs +0 -7
  184. package/esm/dev-server/module-loader.d.mts +0 -63
  185. package/esm/dev-server/module-loader.d.mts.map +0 -1
  186. package/esm/dev-server/path.mjs.map +0 -1
  187. package/esm/tests/test-server-port-channel.d.mts +0 -27
  188. package/esm/tests/test-server-port-channel.d.mts.map +0 -1
  189. /package/esm/{cli → commands}/index.d.mts +0 -0
@@ -1,23 +1,16 @@
1
1
  import { rootPath } from "../utils/paths.mjs";
2
2
  import "../utils/index.mjs";
3
+ import { buildCorsOptions } from "./build-cors-options.mjs";
3
4
  import config from "@mongez/config";
4
5
  import fastifyMultipart from "@fastify/multipart";
5
6
 
6
7
  //#region ../core/src/http/plugins.ts
7
- const defaultCorsOptions = {
8
- origin: "*",
9
- methods: "*"
10
- };
11
8
  async function registerHttpPlugins(server) {
12
9
  server.register(import("@fastify/rate-limit"), {
13
10
  max: config.get("http.rateLimit.max", 60),
14
11
  timeWindow: config.get("http.rateLimit.duration", 60 * 1e3)
15
12
  });
16
- const corsOptions = {
17
- ...config.get("http.cors", {}),
18
- ...defaultCorsOptions
19
- };
20
- server.register(import("@fastify/cors"), corsOptions);
13
+ server.register(import("@fastify/cors"), buildCorsOptions());
21
14
  server.register(fastifyMultipart, {
22
15
  attachFieldsToBody: true,
23
16
  limits: { fileSize: config.get("http.fileUploadLimit", 10 * 1024 * 1024) }
@@ -1 +1 @@
1
- {"version":3,"file":"plugins.mjs","names":[],"sources":["../../../../../../../core/src/http/plugins.ts"],"sourcesContent":["import type { FastifyCorsOptions } from \"@fastify/cors\";\nimport fastifyMultipart from \"@fastify/multipart\";\nimport config from \"@mongez/config\";\nimport { rootPath } from \"../utils\";\nimport type { FastifyInstance } from \"./server\";\n\nconst defaultCorsOptions: FastifyCorsOptions = {\n origin: \"*\",\n methods: \"*\",\n};\n\nexport async function registerHttpPlugins(server: FastifyInstance) {\n // 👇🏻 register rate-limit plugin\n server.register(import(\"@fastify/rate-limit\"), {\n // max requests per time window\n max: config.get(\"http.rateLimit.max\", 60),\n // maximum time that is will allow max requests\n timeWindow: config.get(\"http.rateLimit.duration\", 60 * 1000),\n });\n\n // 👇🏻 register cors plugin\n const corsOptions: FastifyCorsOptions | undefined = {\n ...config.get(\"http.cors\", {}),\n ...defaultCorsOptions,\n };\n\n server.register(import(\"@fastify/cors\"), corsOptions);\n\n // 👇🏻 import multipart plugin\n server.register(fastifyMultipart, {\n attachFieldsToBody: true,\n limits: {\n // file size could be up to 10MB\n fileSize: config.get(\"http.fileUploadLimit\", 10 * 1024 * 1024),\n },\n });\n\n server.register(import(\"@fastify/static\"), {\n root: config.get(\"storage.publicRoot\", rootPath(\"public\")),\n prefix: config.get(\"storage.publicPrefix\", \"/public/\"),\n });\n\n // 👇🏻 register cookie plugin\n server.register(import(\"@fastify/cookie\"), {\n secret: config.get(\"http.cookies.secret\"), // Optional: allow signed cookies\n parseOptions: config.get(\"http.cookies.options\", {}),\n });\n}\n"],"mappings":";;;;;;AAMA,MAAM,qBAAyC;CAC7C,QAAQ;CACR,SAAS;AACX;AAEA,eAAsB,oBAAoB,QAAyB;CAEjE,OAAO,SAAS,OAAO,wBAAwB;EAE7C,KAAK,OAAO,IAAI,sBAAsB,EAAE;EAExC,YAAY,OAAO,IAAI,2BAA2B,KAAK,GAAI;CAC7D,CAAC;CAGD,MAAM,cAA8C;EAClD,GAAG,OAAO,IAAI,aAAa,CAAC,CAAC;EAC7B,GAAG;CACL;CAEA,OAAO,SAAS,OAAO,kBAAkB,WAAW;CAGpD,OAAO,SAAS,kBAAkB;EAChC,oBAAoB;EACpB,QAAQ,EAEN,UAAU,OAAO,IAAI,wBAAwB,KAAK,OAAO,IAAI,EAC/D;CACF,CAAC;CAED,OAAO,SAAS,OAAO,oBAAoB;EACzC,MAAM,OAAO,IAAI,sBAAsB,SAAS,QAAQ,CAAC;EACzD,QAAQ,OAAO,IAAI,wBAAwB,UAAU;CACvD,CAAC;CAGD,OAAO,SAAS,OAAO,oBAAoB;EACzC,QAAQ,OAAO,IAAI,qBAAqB;EACxC,cAAc,OAAO,IAAI,wBAAwB,CAAC,CAAC;CACrD,CAAC;AACH"}
1
+ {"version":3,"file":"plugins.mjs","names":[],"sources":["../../../../../../../core/src/http/plugins.ts"],"sourcesContent":["import fastifyMultipart from \"@fastify/multipart\";\nimport config from \"@mongez/config\";\nimport { rootPath } from \"../utils\";\nimport { buildCorsOptions } from \"./build-cors-options\";\nimport type { FastifyInstance } from \"./server\";\n\nexport async function registerHttpPlugins(server: FastifyInstance) {\n // 👇🏻 register rate-limit plugin\n server.register(import(\"@fastify/rate-limit\"), {\n // max requests per time window\n max: config.get(\"http.rateLimit.max\", 60),\n // maximum time that is will allow max requests\n timeWindow: config.get(\"http.rateLimit.duration\", 60 * 1000),\n });\n\n // 👇🏻 register cors plugin\n server.register(import(\"@fastify/cors\"), buildCorsOptions());\n\n // 👇🏻 import multipart plugin\n server.register(fastifyMultipart, {\n attachFieldsToBody: true,\n limits: {\n // file size could be up to 10MB\n fileSize: config.get(\"http.fileUploadLimit\", 10 * 1024 * 1024),\n },\n });\n\n server.register(import(\"@fastify/static\"), {\n root: config.get(\"storage.publicRoot\", rootPath(\"public\")),\n prefix: config.get(\"storage.publicPrefix\", \"/public/\"),\n });\n\n // 👇🏻 register cookie plugin\n server.register(import(\"@fastify/cookie\"), {\n secret: config.get(\"http.cookies.secret\"), // Optional: allow signed cookies\n parseOptions: config.get(\"http.cookies.options\", {}),\n });\n}\n"],"mappings":";;;;;;;AAMA,eAAsB,oBAAoB,QAAyB;CAEjE,OAAO,SAAS,OAAO,wBAAwB;EAE7C,KAAK,OAAO,IAAI,sBAAsB,EAAE;EAExC,YAAY,OAAO,IAAI,2BAA2B,KAAK,GAAI;CAC7D,CAAC;CAGD,OAAO,SAAS,OAAO,kBAAkB,iBAAiB,CAAC;CAG3D,OAAO,SAAS,kBAAkB;EAChC,oBAAoB;EACpB,QAAQ,EAEN,UAAU,OAAO,IAAI,wBAAwB,KAAK,OAAO,IAAI,EAC/D;CACF,CAAC;CAED,OAAO,SAAS,OAAO,oBAAoB;EACzC,MAAM,OAAO,IAAI,sBAAsB,SAAS,QAAQ,CAAC;EACzD,QAAQ,OAAO,IAAI,wBAAwB,UAAU;CACvD,CAAC;CAGD,OAAO,SAAS,OAAO,oBAAoB;EACzC,QAAQ,OAAO,IAAI,qBAAqB;EACxC,cAAc,OAAO,IAAI,wBAAwB,CAAC,CAAC;CACrD,CAAC;AACH"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.mts","names":[],"sources":["../../../../../../../core/src/http/server.ts"],"mappings":";;;KAGY,iBAAA,GAAkB,UAAU,QAAQ,OAAA;AAAA,iBAYhC,eAAA,CAAgB,OAAA,GAAU,oBAAA,GAAuB,iBAAe;AAZhF;;;AAAA,iBA8BgB,aAAA,IAAiB,iBAAe;AA9BO;AAYvD;;;AAZuD,KAsC3C,cAAA;EAAmB,KAAA,QAAa,OAAO;AAAA;;;AA1B6B;AAkBhF;;;;iBAiBsB,sBAAA,CACpB,MAAA,EAAQ,cAAA,EACR,SAAA,WACC,OAAO"}
1
+ {"version":3,"file":"server.d.mts","names":[],"sources":["../../../../../../../core/src/http/server.ts"],"mappings":";;;KAGY,iBAAA,GAAkB,UAAU,QAAQ,OAAA;AAAA,iBAKhC,eAAA,CAAgB,OAAA,GAAU,oBAAA,GAAuB,iBAAe;AALhF;;;AAAA,iBAiCgB,aAAA,IAAiB,iBAAe;AAjCO;AAKvD;;;AALuD,KAyC3C,cAAA;EAAmB,KAAA,QAAa,OAAO;AAAA;;;AApC6B;AA4BhF;;;;iBAiBsB,sBAAA,CACpB,MAAA,EAAQ,cAAA,EACR,SAAA,WACC,OAAO"}
@@ -2,17 +2,12 @@ import config from "@mongez/config";
2
2
  import Fastify from "fastify";
3
3
 
4
4
  //#region ../core/src/http/server.ts
5
- /**
6
- * Default Fastify body limit. Kept at the historical 200GB so existing apps
7
- * don't regress on upgrade. Override via `http.bodyLimit` in config; for
8
- * per-route caps use the `maxBodySize()` middleware.
9
- */
10
- const DEFAULT_BODY_LIMIT = 200 * 1024 * 1024 * 1024;
11
5
  let server = void 0;
12
6
  function startHttpServer(options) {
7
+ const bodyLimit = config.get("http.bodyLimit") ?? void 0;
13
8
  return server = Fastify({
14
- trustProxy: config.get("http.trustProxy", true),
15
- bodyLimit: config.get("http.bodyLimit", DEFAULT_BODY_LIMIT),
9
+ trustProxy: config.get("http.trustProxy", false),
10
+ ...bodyLimit !== void 0 && { bodyLimit },
16
11
  forceCloseConnections: config.get("http.gracefulShutdown.forceCloseConnections", "idle"),
17
12
  ...options
18
13
  });
@@ -1 +1 @@
1
- {"version":3,"file":"server.mjs","names":[],"sources":["../../../../../../../core/src/http/server.ts"],"sourcesContent":["import config from \"@mongez/config\";\r\nimport Fastify, { FastifyServerOptions } from \"fastify\";\r\n\r\nexport type FastifyInstance = ReturnType<typeof Fastify>;\r\n\r\n/**\r\n * Default Fastify body limit. Kept at the historical 200GB so existing apps\r\n * don't regress on upgrade. Override via `http.bodyLimit` in config; for\r\n * per-route caps use the `maxBodySize()` middleware.\r\n */\r\nconst DEFAULT_BODY_LIMIT = 200 * 1024 * 1024 * 1024;\r\n\r\n// Instantiate Fastify server\r\nlet server: FastifyInstance | undefined = undefined;\r\n\r\nexport function startHttpServer(options?: FastifyServerOptions): FastifyInstance {\r\n return (server = Fastify({\r\n // Configurable so deployments NOT behind a trusted proxy can disable\r\n // `X-Forwarded-For` resolution (it's client-settable and spoofable).\r\n // Defaults to `true` to preserve historical behavior for proxied apps.\r\n trustProxy: config.get(\"http.trustProxy\", true),\r\n bodyLimit: config.get(\"http.bodyLimit\", DEFAULT_BODY_LIMIT),\r\n // Close idle keep-alive connections on shutdown while letting in-flight\r\n // requests finish — the basis for graceful draining. Override via\r\n // `http.gracefulShutdown.forceCloseConnections`.\r\n forceCloseConnections: config.get(\"http.gracefulShutdown.forceCloseConnections\", \"idle\"),\r\n ...options,\r\n }));\r\n}\r\n\r\n/**\r\n * Expose the server to be publicly accessible\r\n */\r\nexport function getHttpServer(): FastifyInstance {\r\n return server;\r\n}\r\n\r\n/**\r\n * Minimal shape needed to close a server — lets {@link closeServerWithTimeout}\r\n * be unit-tested with a fake instead of a real Fastify instance.\r\n */\r\nexport type ClosableServer = { close: () => Promise<unknown> };\r\n\r\n/**\r\n * Close a server, bounded by a timeout. Fastify's `close()` stops accepting new\r\n * requests (it answers 503 while closing) and drains the in-flight ones; this\r\n * wraps it so a single stuck request can't hang shutdown forever.\r\n *\r\n * @returns `true` if the server drained cleanly, `false` if the timeout fired first.\r\n */\r\nexport async function closeServerWithTimeout(\r\n server: ClosableServer,\r\n timeoutMs: number,\r\n): Promise<boolean> {\r\n let timer: ReturnType<typeof setTimeout> | undefined;\r\n\r\n const drained = server.close().then(() => true);\r\n\r\n const timedOut = new Promise<boolean>((resolve) => {\r\n timer = setTimeout(() => resolve(false), timeoutMs);\r\n });\r\n\r\n try {\r\n return await Promise.race([drained, timedOut]);\r\n } finally {\r\n if (timer) {\r\n clearTimeout(timer);\r\n }\r\n }\r\n}\r\n"],"mappings":";;;;;;;;;AAUA,MAAM,qBAAqB,MAAM,OAAO,OAAO;AAG/C,IAAI,SAAsC;AAE1C,SAAgB,gBAAgB,SAAiD;CAC/E,OAAQ,SAAS,QAAQ;EAIvB,YAAY,OAAO,IAAI,mBAAmB,IAAI;EAC9C,WAAW,OAAO,IAAI,kBAAkB,kBAAkB;EAI1D,uBAAuB,OAAO,IAAI,+CAA+C,MAAM;EACvF,GAAG;CACL,CAAC;AACH;;;;AAKA,SAAgB,gBAAiC;CAC/C,OAAO;AACT;;;;;;;;AAeA,eAAsB,uBACpB,QACA,WACkB;CAClB,IAAI;CAEJ,MAAM,UAAU,OAAO,MAAM,CAAC,CAAC,WAAW,IAAI;CAE9C,MAAM,WAAW,IAAI,SAAkB,YAAY;EACjD,QAAQ,iBAAiB,QAAQ,KAAK,GAAG,SAAS;CACpD,CAAC;CAED,IAAI;EACF,OAAO,MAAM,QAAQ,KAAK,CAAC,SAAS,QAAQ,CAAC;CAC/C,UAAU;EACR,IAAI,OACF,aAAa,KAAK;CAEtB;AACF"}
1
+ {"version":3,"file":"server.mjs","names":[],"sources":["../../../../../../../core/src/http/server.ts"],"sourcesContent":["import config from \"@mongez/config\";\r\nimport Fastify, { FastifyServerOptions } from \"fastify\";\r\n\r\nexport type FastifyInstance = ReturnType<typeof Fastify>;\r\n\r\n// Instantiate Fastify server\r\nlet server: FastifyInstance | undefined = undefined;\r\n\r\nexport function startHttpServer(options?: FastifyServerOptions): FastifyInstance {\r\n // `config.set(key, undefined)` stores null rather than unsetting, so an app\r\n // that clears a key would otherwise hand Fastify `null` and crash the boot.\r\n const bodyLimit = config.get(\"http.bodyLimit\") ?? undefined;\r\n\r\n return (server = Fastify({\r\n // `X-Forwarded-For` is client-settable and spoofable, and `request.ip` is\r\n // what @fastify/rate-limit keys its buckets on so trusting it by default\r\n // makes rate limiting bypassable on any deployment NOT behind a proxy that\r\n // strips the header. Apps behind such a proxy opt in explicitly.\r\n trustProxy: config.get(\"http.trustProxy\", false),\r\n // No default: an app that configures nothing keeps Fastify's own 1MB limit\r\n // rather than the historical 200GB, which silently removed the protection\r\n // Fastify provides. Per-route caps go through `serverOptions.bodyLimit`;\r\n // the `maxBodySize()` middleware runs AFTER parsing and cannot reject\r\n // before the bytes are resident.\r\n ...(bodyLimit !== undefined && { bodyLimit }),\r\n // Close idle keep-alive connections on shutdown while letting in-flight\r\n // requests finish — the basis for graceful draining. Override via\r\n // `http.gracefulShutdown.forceCloseConnections`.\r\n forceCloseConnections: config.get(\"http.gracefulShutdown.forceCloseConnections\", \"idle\"),\r\n ...options,\r\n }));\r\n}\r\n\r\n/**\r\n * Expose the server to be publicly accessible\r\n */\r\nexport function getHttpServer(): FastifyInstance {\r\n return server;\r\n}\r\n\r\n/**\r\n * Minimal shape needed to close a server — lets {@link closeServerWithTimeout}\r\n * be unit-tested with a fake instead of a real Fastify instance.\r\n */\r\nexport type ClosableServer = { close: () => Promise<unknown> };\r\n\r\n/**\r\n * Close a server, bounded by a timeout. Fastify's `close()` stops accepting new\r\n * requests (it answers 503 while closing) and drains the in-flight ones; this\r\n * wraps it so a single stuck request can't hang shutdown forever.\r\n *\r\n * @returns `true` if the server drained cleanly, `false` if the timeout fired first.\r\n */\r\nexport async function closeServerWithTimeout(\r\n server: ClosableServer,\r\n timeoutMs: number,\r\n): Promise<boolean> {\r\n let timer: ReturnType<typeof setTimeout> | undefined;\r\n\r\n const drained = server.close().then(() => true);\r\n\r\n const timedOut = new Promise<boolean>((resolve) => {\r\n timer = setTimeout(() => resolve(false), timeoutMs);\r\n });\r\n\r\n try {\r\n return await Promise.race([drained, timedOut]);\r\n } finally {\r\n if (timer) {\r\n clearTimeout(timer);\r\n }\r\n }\r\n}\r\n"],"mappings":";;;;AAMA,IAAI,SAAsC;AAE1C,SAAgB,gBAAgB,SAAiD;CAG/E,MAAM,YAAY,OAAO,IAAI,gBAAgB,KAAK;CAElD,OAAQ,SAAS,QAAQ;EAKvB,YAAY,OAAO,IAAI,mBAAmB,KAAK;EAM/C,GAAI,cAAc,UAAa,EAAE,UAAU;EAI3C,uBAAuB,OAAO,IAAI,+CAA+C,MAAM;EACvF,GAAG;CACL,CAAC;AACH;;;;AAKA,SAAgB,gBAAiC;CAC/C,OAAO;AACT;;;;;;;;AAeA,eAAsB,uBACpB,QACA,WACkB;CAClB,IAAI;CAEJ,MAAM,UAAU,OAAO,MAAM,CAAC,CAAC,WAAW,IAAI;CAE9C,MAAM,WAAW,IAAI,SAAkB,YAAY;EACjD,QAAQ,iBAAiB,QAAQ,KAAK,GAAG,SAAS;CACpD,CAAC;CAED,IAAI;EACF,OAAO,MAAM,QAAQ,KAAK,CAAC,SAAS,QAAQ,CAAC;CAC/C,UAAU;EACR,IAAI,OACF,aAAa,KAAK;CAEtB;AACF"}
package/esm/index.d.mts CHANGED
@@ -63,6 +63,11 @@ import { NoopChannel } from "./benchmark/channels/noop.channel.mjs";
63
63
  import { bootstrap } from "./bootstrap.mjs";
64
64
  import { displayEnvironmentMode } from "./bootstrap/setup.mjs";
65
65
  import { DatabaseCacheDriver, DatabaseCacheOptions } from "./cache/database-cache-driver.mjs";
66
+ import { ConfigKey, ConfigKeyRegistry, ConfigName, ConfigRegistry } from "./config/types.mjs";
67
+ import { config } from "./config/config-getter.mjs";
68
+ import { registerAppConfig } from "./config/config-handlers.mjs";
69
+ import { setConfig } from "./config/config-setter.mjs";
70
+ import { ConfigSpecialHandlers, configSpecialHandlers } from "./config/config-special-handlers.mjs";
66
71
  import { Connector, ConnectorLifecyclePhase, ConnectorName, ConnectorPriority } from "./connectors/types.mjs";
67
72
  import { BaseConnector } from "./connectors/base-connector.mjs";
68
73
  import { AccessConnector } from "./connectors/access-connector.mjs";
@@ -77,23 +82,14 @@ import { MailerConnector } from "./connectors/mail-connector.mjs";
77
82
  import { NotificationsConnector } from "./connectors/notifications-connector.mjs";
78
83
  import { SocketConnector } from "./connectors/socket-connector.mjs";
79
84
  import { StorageConnector } from "./connectors/storage.connector.mjs";
80
- import { CLICommandAction, CLICommandOption, CLICommandOptions, CLICommandPreload, CLICommandSource, CommandActionData, ResolvedCLICommandOption } from "./cli/types.mjs";
81
- import { CLICommand, command } from "./cli/cli-command.mjs";
82
- import { ConfigKey, ConfigKeyRegistry, ConfigName, ConfigRegistry } from "./config/types.mjs";
83
- import { config } from "./config/config-getter.mjs";
84
- import { registerAppConfig } from "./config/config-handlers.mjs";
85
- import { setConfig } from "./config/config-setter.mjs";
86
- import { ConfigSpecialHandlers, configSpecialHandlers } from "./config/config-special-handlers.mjs";
85
+ import { CLICommandAction, CLICommandOption, CLICommandOptions, CLICommandPreload, CLICommandSource, CommandActionData, ResolvedCLICommandOption } from "./commands/types.mjs";
86
+ import { CLICommand, command } from "./commands/cli-command.mjs";
87
87
  import { ContainerTypes, container } from "./container/index.mjs";
88
88
  import { DatabaseLogModel } from "./database/models/database-log/database-log.mjs";
89
89
  import { SeedClock, SeedContext, SeedRecordRef, SeedResult, SeederMetadata, Track, TrackableModel } from "./database/seeds/types.mjs";
90
90
  import { Seeder, seeder } from "./database/seeds/seeder.mjs";
91
91
  import { SeederDependencyCycleError, UnknownSeederDependencyError } from "./database/seeds/seeder.errors.mjs";
92
92
  import { useComputedModel, useComputedSlug, useHashedPassword } from "./database/utils.mjs";
93
- import { FilesOrchestrator, filesOrchestrator, onCleanup } from "./dev-server/files-orchestrator.mjs";
94
- import { BaseHealthChecker } from "./dev-server/health-checker/checkers/base-health-checker.mjs";
95
- import { EslintHealthChecker } from "./dev-server/health-checker/checkers/eslint-health-checker.mjs";
96
- import { TypescriptHealthChecker } from "./dev-server/health-checker/checkers/typescript-health-checker.mjs";
97
93
  import { decrypt, encrypt } from "./encryption/encrypt.mjs";
98
94
  import { hmacHash } from "./encryption/hash.mjs";
99
95
  import { hashPassword, verifyPassword } from "./encryption/password.mjs";
@@ -120,10 +116,6 @@ import { RegisterResource } from "./resource/register-resource.mjs";
120
116
  import { Restful } from "./restful/restful.mjs";
121
117
  import { SocketOptions } from "./socket/types.mjs";
122
118
  import { getSocketServer } from "./socket/utils.mjs";
123
- import { StartHttpTestServerOptions, isTestServerRunning, startHttpTestServer, stopHttpTestServer } from "./tests/start-http-development-server.mjs";
124
- import { expectJson, getTestServerUrl, parseJsonResponse, testDelete, testGet, testPatch, testPost, testPut, testRequest } from "./tests/test-helpers.mjs";
125
- import { TEST_SERVER_PORT_ENV_KEY, publishTestServerPort, withdrawTestServerPort } from "./tests/test-server-port-channel.mjs";
126
- import { setupTest } from "./tests/vitest-setup.mjs";
127
119
  import { RegisteredUseCase, UseCase, UseCaseAfterMiddleware, UseCaseBeforeMiddleware, UseCaseBroadcastChannel, UseCaseBroadcastEvent, UseCaseBroadcastOption, UseCaseConfigurations, UseCaseContext, UseCaseErrorResult, UseCaseEventsCallbacksMap, UseCaseGuard, UseCaseHandler, UseCaseOnExecutingContext, UseCaseResult, UseCaseRuntimeOptions, UseCaseWithSchema } from "./use-cases/types.mjs";
128
120
  import { useCase } from "./use-cases/use-case.mjs";
129
121
  import { broadcastUseCaseResult } from "./use-cases/use-case-broadcast.mjs";
@@ -133,6 +125,7 @@ import { BadSchemaUseCaseError } from "./use-cases/use-case.errors.mjs";
133
125
  import { $registerUseCase, $unregisterUseCase, addUseCaseHistory, getUseCase, getUseCaseHistory, getUseCases, increaseUseCaseFailedCalls, increaseUseCaseSuccessCalls } from "./use-cases/use-cases-registry.mjs";
134
126
  import { appLog } from "./utils/app-log.mjs";
135
127
  import { DatabaseLog, DatabaseLogOptions } from "./utils/database-log.mjs";
128
+ import { Path } from "./utils/normalized-path.mjs";
136
129
  import { fetchLatestVersion } from "./utils/npm-registry.mjs";
137
130
  import { appPath, cachePath, configPath, logsPath, paths, publicPath, rootPath, sanitizePath, srcPath, storagePath, tempPath, uploadsPath, warlockPath } from "./utils/paths.mjs";
138
131
  import { promiseAllObject } from "./utils/promise-all-object.mjs";
@@ -150,14 +143,13 @@ import { uniqueExceptCurrentUserRule } from "./validation/database/unique-except
150
143
  import { FileValidator, uploadedFileMetadataSchema } from "./validation/validators/file-validator.mjs";
151
144
  import { ValidationConfiguration } from "./validation/types.mjs";
152
145
  import { fileExtensionRule, fileRule, fileTypeRule, imageRule } from "./validation/file/file.mjs";
153
- import { DecoratorLoweringPlugin, lowerStage3Decorators } from "./vite/lower-stage3-decorators.mjs";
154
146
  import { WarlockConfig } from "./warlock-config/types.mjs";
155
147
  import { defineConfig } from "./warlock-config/define-config.mjs";
156
148
  import { WarlockConfigManager, isUnknownTsExtensionError, warlockConfigManager } from "./warlock-config/warlock-config.manager.mjs";
157
149
  import { env } from "@mongez/dotenv";
158
150
  import { colors } from "@mongez/copper";
159
151
  export * from "@mongez/localization";
160
- export { $registerUseCase, $unregisterUseCase, AccessConnector, AggregateExpressionInput, AggregateExpressions, AiConnector, AllRepositoryOptions, AppConfigurations, Application, BOOT_SIGNAL_ENV_KEY, BOOT_SIGNAL_VERSION, BadRequestError, BadSchemaUseCaseError, BaseConnector, BaseHealthChecker, type BenchmarkChannel, type BenchmarkConfigurations, type BenchmarkErrorResult, type BenchmarkOptions, BenchmarkProfiler, type BenchmarkProfilerOptions, type BenchmarkResult, BenchmarkSnapshots, type BenchmarkSnapshotsOptions, type BenchmarkStats, type BenchmarkSuccessResult, BootContext, BootListener, BootSignal, BootSignalType, CLICommand, CLICommandAction, CLICommandOption, CLICommandOptions, CLICommandPreload, CLICommandSource, CacheConnector, type CacheMiddlewareOptions, CachedRepositoryOptions, type CapturedMail, CascadeAdapter, CascadeQueryBuilder, ChunkCallback, ClosableServer, CloudDriver, CloudStorageDriverContract, CloudStorageDriverOptions, CloudStorageFileData, CommandActionData, type ConcurrencyLimitOptions, ConfigKey, ConfigKeyRegistry, ConfigName, ConfigRegistry, ConfigSpecialHandlers, ConflictError, Connector, ConnectorLifecyclePhase, ConnectorName, ConnectorPriority, ConnectorsManager, ConsoleChannel, ContainerTypes, CookieOptions, CursorPaginationOptions, CursorPaginationResult, DOSpacesDriver, DatabaseCacheDriver, type DatabaseCacheOptions, DatabaseConnector, DatabaseLog, DatabaseLogModel, DatabaseLogOptions, DecoratorLoweringPlugin, DefineResourceOptions, DeleteManyResult, EncryptionConfigurations, EncryptionPasswordConfigurations, Environment, EslintHealthChecker, EventSubscription, ExistsExceptCurrentIdRuleOptions, ExistsExceptCurrentUserRuleOptions, FastifyInstance, FileNamingStrategy, FileValidationOptions, FileValidator, FileVisibility, FilesOrchestrator, FilterFunction, FilterOperator, FilterOptions, FilterRule, FilterRules, ForbiddenError, GroupByFields, GroupedRoutesOptions, HealthCheck, HealthStatus, HeraldConnector, HttpConfigurations, HttpConnector, HttpError, HttpErrorCodes, type IdempotencyOptions, Image, ImageFormat, ImageInput, ImageTransformCallback, ImageTransformConfig, ImageTransformOptions, type IpFilterOptions, ListOptions, LocalDriver, LocalStorageDriverOptions, LocalizedObject, LogConfigurations, LoggerConnector, MAIL_EVENTS, Mail, type MailAddress, type MailAttachment, type MailConfigurations, MailError, type MailErrorCode, type MailEvents, type MailMode, type MailOptions, type MailPriority, type MailResult, MailerConnector, type MailersConfig, type MaintenanceOptions, Middleware, MiddlewareResponse, MimeTypes, NoopChannel, type NormalizedMail, NotAcceptableError, NotAllowedError, NotificationsConnector, PaginationMode, PaginationResult, PartialMiddleware, PartialPick, PipelineOptions, PortInUseError, PrefixConfig, PrefixOptions, PresignedOptions, PresignedUploadOptions, PutDirectoryOptions, PutDirectoryResult, PutFromUrlOptions, PutOptions, QueryBuilderContract, Queue, R2Driver, R2StorageDriverOptions, type RateLimitOptions, RegisterResource, RegisteredUseCase, RepositoryAdapterContract, RepositoryConfigurations, RepositoryEvent, RepositoryManager, RepositoryOptions, RepositoryOptionsWithCursor, RepositoryOptionsWithPages, Request, RequestContextStore, RequestController, RequestControllerContract, RequestEvent, RequestHandler, RequestHandlerType, RequestHandlerValidation, RequestLog, RequestMethod, ResolvedCLICommandOption, Resource, ResourceArraySchema, ResourceCastType, ResourceConstructor, ResourceContract, ResourceFieldBuilder, ResourceFieldBuilderDateOutputOptions, ResourceFieldConfig, ResourceMethod, ResourceNotFoundError, ResourceOutputValueCastType, ResourceSchema, ResourceSelfReference, Response, ResponseBodyValue, ResponseEvent, ResponseSSEController, ResponseSchema, ResponseStatus, ResponseStreamController, Restful, RestfulMiddleware, ReturnedResponse, Route, RouteOptions, RouteResource, Router, RouterGroupCallback, RouterStacks, RuntimeStrategy, S3Driver, type SESConfigurations, type SMTPConfigurations, SafeFetchOptions, SafeFetchResult, SaveAsOptions, SaveMode, SaveOptions, ScopedStorage, ScopedStorageContract, SeedClock, SeedContext, SeedRecordRef, SeedResult, Seeder, SeederDependencyCycleError, SeederMetadata, SendBufferOptions, SendFileOptions, ServerError, ShutdownListener, SocketConnector, SocketOptions, StartHttpTestServerOptions, Storage, StorageConfigurations, StorageConnector, StorageCopyEventPayload, StorageDriverConfig, StorageDriverContextStore, StorageDriverContract, StorageDriverName, StorageDriverRegistry, StorageDriverType, StorageError, StorageErrorOptions, StorageEventHandler, StorageEventPayload, StorageEventType, StorageFile, StorageFileData, StorageFileInfo, StorageManagerContract, StoragePutEventPayload, TEST_SERVER_PORT_ENV_KEY, TemporaryTokenError, TemporaryTokenPayload, TemporaryTokenValidation, Track, TrackableModel, TypedAllRepositoryOptions, TypedRepositoryOptions, TypedRepositoryOptionsWithCursor, TypedRepositoryOptionsWithPages, TypescriptHealthChecker, UPLOADS_DEFAULTS, UnAuthorizedError, UniqueExceptCurrentIdRuleOptions, UniqueExceptCurrentUserRuleOptions, UnknownSeederDependencyError, UploadedFile, UploadedFileImageOptions, UploadsConfigurations, UseCase, UseCaseAfterMiddleware, UseCaseBeforeMiddleware, UseCaseBroadcastChannel, UseCaseBroadcastEvent, UseCaseBroadcastOption, UseCaseConfigurations, UseCaseContext, UseCaseErrorResult, UseCaseEventsCallbacksMap, UseCaseGuard, UseCaseHandler, UseCaseOnExecutingContext, UseCaseResult, UseCaseRuntimeOptions, UseCaseWithSchema, ValidationConfiguration, WarlockConfig, WarlockConfigManager, WatermarkConfig, WhereOperator, addUseCaseHistory, anyMatch, app, appLog, appPath, assertMailCount, assertMailSent, assertPortIsAvailable, assetsUrl, bootstrap, broadcastUseCaseResult, buildIdempotencyCacheKey, cachePath, captureMail, clearTestMailbox, closeAllMailers, closeMailer, closeServerWithTimeout, colors, command, config, configPath, configSpecialHandlers, connectorsManager, container, createHttpApplication, createRequestStore, decrypt, defaultHttpConfigurations, defineConfig, defineResource, displayEnvironmentMode, encrypt, env, environment, existsExceptCurrentIdRule, existsExceptCurrentUserRule, expectJson, fetchLatestVersion, fileExtensionRule, fileRule, fileTypeRule, filesOrchestrator, findMailsBySubject, findMailsTo, fireLifecycleEvent, fromRequest, generateMailId, getDefaultMailConfig, getHttpServer, getLastMail, getLocalized, getMailEventName, getMailMode, getMailboxSize, getMailer, getMailerConfig, getMimeType, getPoolStats, getSocketServer, getTestMailbox, getTestServerUrl, getUseCase, getUseCaseHistory, getUseCases, globalEventsCallbacksMap, globalUseCasesEvents, hashBody, hashPassword, health, hmacHash, httpConfig, imageRule, increaseUseCaseFailedCalls, increaseUseCaseSuccessCalls, ipMatches, isBootSignal, isDevelopmentMode, isNewerVersion, isPortAvailable, isPrivateOrReservedIp, isProductionMode, isTestMode, isTestServerRunning, isUnknownTsExtensionError, isValidIdempotencyKey, loadS3, logResponse, logsPath, lowerStage3Decorators, mailEvents, measure, middleware, onCleanup, parseJsonResponse, parseSize, paths, promiseAllObject, publicPath, publicUrl, publishTestServerPort, registerAppConfig, registerHttpPlugins, renderReact, renderReactMail, requestContext, resetMailConfig, resolveMailConfig, resolveWithinRoot, rootPath, router, runPipeline, safeFetchToBuffer, sanitizePath, seeder, sendBootSignal, sendMail, setBaseUrl, setConfig, setEnvironment, setLogConfigurations, setMailConfigurations, setMailMode, setupTest, sleep, sluggable, srcPath, startHttpServer, startHttpTestServer, stopHttpApplication, stopHttpTestServer, storage, storageConfig, storageConfigurations, storageDriverContext, storagePath, t, tempPath, testDelete, testGet, testPatch, testPost, testPut, testRequest, toJson, uniqueExceptCurrentIdRule, uniqueExceptCurrentUserRule, uploadedFileMetadataSchema, uploadsConfig, uploadsPath, uploadsUrl, url, useCase, useComputedModel, useComputedSlug, useCurrentUser, useHashedPassword, useRequest, useRequestStore, verifyMailer, verifyPassword, warlockConfigManager, warlockPath, wasMailSentTo, wasMailSentWithSubject, withdrawTestServerPort, wrapResponseInDataKey };
152
+ export { $registerUseCase, $unregisterUseCase, AccessConnector, AggregateExpressionInput, AggregateExpressions, AiConnector, AllRepositoryOptions, AppConfigurations, Application, BOOT_SIGNAL_ENV_KEY, BOOT_SIGNAL_VERSION, BadRequestError, BadSchemaUseCaseError, BaseConnector, type BenchmarkChannel, type BenchmarkConfigurations, type BenchmarkErrorResult, type BenchmarkOptions, BenchmarkProfiler, type BenchmarkProfilerOptions, type BenchmarkResult, BenchmarkSnapshots, type BenchmarkSnapshotsOptions, type BenchmarkStats, type BenchmarkSuccessResult, BootContext, BootListener, BootSignal, BootSignalType, CLICommand, type CLICommandAction, type CLICommandOption, type CLICommandOptions, type CLICommandPreload, type CLICommandSource, CacheConnector, type CacheMiddlewareOptions, CachedRepositoryOptions, type CapturedMail, CascadeAdapter, CascadeQueryBuilder, ChunkCallback, ClosableServer, CloudDriver, CloudStorageDriverContract, CloudStorageDriverOptions, CloudStorageFileData, type CommandActionData, type ConcurrencyLimitOptions, ConfigKey, ConfigKeyRegistry, ConfigName, ConfigRegistry, ConfigSpecialHandlers, ConflictError, Connector, ConnectorLifecyclePhase, ConnectorName, ConnectorPriority, ConnectorsManager, ConsoleChannel, ContainerTypes, CookieOptions, CursorPaginationOptions, CursorPaginationResult, DOSpacesDriver, DatabaseCacheDriver, type DatabaseCacheOptions, DatabaseConnector, DatabaseLog, DatabaseLogModel, DatabaseLogOptions, DefineResourceOptions, DeleteManyResult, EncryptionConfigurations, EncryptionPasswordConfigurations, Environment, EventSubscription, ExistsExceptCurrentIdRuleOptions, ExistsExceptCurrentUserRuleOptions, FastifyInstance, FileNamingStrategy, FileValidationOptions, FileValidator, FileVisibility, FilterFunction, FilterOperator, FilterOptions, FilterRule, FilterRules, ForbiddenError, GroupByFields, GroupedRoutesOptions, HealthCheck, HealthStatus, HeraldConnector, HttpConfigurations, HttpConnector, HttpError, HttpErrorCodes, type IdempotencyOptions, Image, ImageFormat, ImageInput, ImageTransformCallback, ImageTransformConfig, ImageTransformOptions, type IpFilterOptions, ListOptions, LocalDriver, LocalStorageDriverOptions, LocalizedObject, LogConfigurations, LoggerConnector, MAIL_EVENTS, Mail, type MailAddress, type MailAttachment, type MailConfigurations, MailError, type MailErrorCode, type MailEvents, type MailMode, type MailOptions, type MailPriority, type MailResult, MailerConnector, type MailersConfig, type MaintenanceOptions, Middleware, MiddlewareResponse, MimeTypes, NoopChannel, type NormalizedMail, NotAcceptableError, NotAllowedError, NotificationsConnector, PaginationMode, PaginationResult, PartialMiddleware, PartialPick, Path, PipelineOptions, PortInUseError, PrefixConfig, PrefixOptions, PresignedOptions, PresignedUploadOptions, PutDirectoryOptions, PutDirectoryResult, PutFromUrlOptions, PutOptions, QueryBuilderContract, Queue, R2Driver, R2StorageDriverOptions, type RateLimitOptions, RegisterResource, RegisteredUseCase, RepositoryAdapterContract, RepositoryConfigurations, RepositoryEvent, RepositoryManager, RepositoryOptions, RepositoryOptionsWithCursor, RepositoryOptionsWithPages, Request, RequestContextStore, RequestController, RequestControllerContract, RequestEvent, RequestHandler, RequestHandlerType, RequestHandlerValidation, RequestLog, RequestMethod, type ResolvedCLICommandOption, Resource, ResourceArraySchema, ResourceCastType, ResourceConstructor, ResourceContract, ResourceFieldBuilder, ResourceFieldBuilderDateOutputOptions, ResourceFieldConfig, ResourceMethod, ResourceNotFoundError, ResourceOutputValueCastType, ResourceSchema, ResourceSelfReference, Response, ResponseBodyValue, ResponseEvent, ResponseSSEController, ResponseSchema, ResponseStatus, ResponseStreamController, Restful, RestfulMiddleware, ReturnedResponse, Route, RouteOptions, RouteResource, Router, RouterGroupCallback, RouterStacks, RuntimeStrategy, S3Driver, type SESConfigurations, type SMTPConfigurations, SafeFetchOptions, SafeFetchResult, SaveAsOptions, SaveMode, SaveOptions, ScopedStorage, ScopedStorageContract, SeedClock, SeedContext, SeedRecordRef, SeedResult, Seeder, SeederDependencyCycleError, SeederMetadata, SendBufferOptions, SendFileOptions, ServerError, ShutdownListener, SocketConnector, SocketOptions, Storage, StorageConfigurations, StorageConnector, StorageCopyEventPayload, StorageDriverConfig, StorageDriverContextStore, StorageDriverContract, StorageDriverName, StorageDriverRegistry, StorageDriverType, StorageError, StorageErrorOptions, StorageEventHandler, StorageEventPayload, StorageEventType, StorageFile, StorageFileData, StorageFileInfo, StorageManagerContract, StoragePutEventPayload, TemporaryTokenError, TemporaryTokenPayload, TemporaryTokenValidation, Track, TrackableModel, TypedAllRepositoryOptions, TypedRepositoryOptions, TypedRepositoryOptionsWithCursor, TypedRepositoryOptionsWithPages, UPLOADS_DEFAULTS, UnAuthorizedError, UniqueExceptCurrentIdRuleOptions, UniqueExceptCurrentUserRuleOptions, UnknownSeederDependencyError, UploadedFile, UploadedFileImageOptions, UploadsConfigurations, UseCase, UseCaseAfterMiddleware, UseCaseBeforeMiddleware, UseCaseBroadcastChannel, UseCaseBroadcastEvent, UseCaseBroadcastOption, UseCaseConfigurations, UseCaseContext, UseCaseErrorResult, UseCaseEventsCallbacksMap, UseCaseGuard, UseCaseHandler, UseCaseOnExecutingContext, UseCaseResult, UseCaseRuntimeOptions, UseCaseWithSchema, ValidationConfiguration, WarlockConfig, WarlockConfigManager, WatermarkConfig, WhereOperator, addUseCaseHistory, anyMatch, app, appLog, appPath, assertMailCount, assertMailSent, assertPortIsAvailable, assetsUrl, bootstrap, broadcastUseCaseResult, buildIdempotencyCacheKey, cachePath, captureMail, clearTestMailbox, closeAllMailers, closeMailer, closeServerWithTimeout, colors, command, config, configPath, configSpecialHandlers, connectorsManager, container, createHttpApplication, createRequestStore, decrypt, defaultHttpConfigurations, defineConfig, defineResource, displayEnvironmentMode, encrypt, env, environment, existsExceptCurrentIdRule, existsExceptCurrentUserRule, fetchLatestVersion, fileExtensionRule, fileRule, fileTypeRule, findMailsBySubject, findMailsTo, fireLifecycleEvent, fromRequest, generateMailId, getDefaultMailConfig, getHttpServer, getLastMail, getLocalized, getMailEventName, getMailMode, getMailboxSize, getMailer, getMailerConfig, getMimeType, getPoolStats, getSocketServer, getTestMailbox, getUseCase, getUseCaseHistory, getUseCases, globalEventsCallbacksMap, globalUseCasesEvents, hashBody, hashPassword, health, hmacHash, httpConfig, imageRule, increaseUseCaseFailedCalls, increaseUseCaseSuccessCalls, ipMatches, isBootSignal, isDevelopmentMode, isNewerVersion, isPortAvailable, isPrivateOrReservedIp, isProductionMode, isTestMode, isUnknownTsExtensionError, isValidIdempotencyKey, loadS3, logResponse, logsPath, mailEvents, measure, middleware, parseSize, paths, promiseAllObject, publicPath, publicUrl, registerAppConfig, registerHttpPlugins, renderReact, renderReactMail, requestContext, resetMailConfig, resolveMailConfig, resolveWithinRoot, rootPath, router, runPipeline, safeFetchToBuffer, sanitizePath, seeder, sendBootSignal, sendMail, setBaseUrl, setConfig, setEnvironment, setLogConfigurations, setMailConfigurations, setMailMode, sleep, sluggable, srcPath, startHttpServer, stopHttpApplication, storage, storageConfig, storageConfigurations, storageDriverContext, storagePath, t, tempPath, toJson, uniqueExceptCurrentIdRule, uniqueExceptCurrentUserRule, uploadedFileMetadataSchema, uploadsConfig, uploadsPath, uploadsUrl, url, useCase, useComputedModel, useComputedSlug, useCurrentUser, useHashedPassword, useRequest, useRequestStore, verifyMailer, verifyPassword, warlockConfigManager, warlockPath, wasMailSentTo, wasMailSentWithSubject, wrapResponseInDataKey };
161
153
  import "./config/types.mjs";
162
154
  import "./storage/types.mjs";
163
155
  import "./validation/types.mjs";
package/esm/index.mjs CHANGED
@@ -9,6 +9,7 @@ import { DatabaseLog } from "./utils/database-log.mjs";
9
9
  import { environment, setEnvironment } from "./utils/environment.mjs";
10
10
  import { requestContext, useCurrentUser, useRequest, useRequestStore } from "./http/context/request-context.mjs";
11
11
  import { getLocalized } from "./utils/get-localized.mjs";
12
+ import { Path } from "./utils/normalized-path.mjs";
12
13
  import { fetchLatestVersion } from "./utils/npm-registry.mjs";
13
14
  import { appPath, cachePath, configPath, logsPath, paths, publicPath, rootPath, sanitizePath, srcPath, storagePath, tempPath, uploadsPath, warlockPath } from "./utils/paths.mjs";
14
15
  import { promiseAllObject } from "./utils/promise-all-object.mjs";
@@ -82,7 +83,7 @@ import { bootstrap } from "./bootstrap.mjs";
82
83
  import { displayEnvironmentMode } from "./bootstrap/setup.mjs";
83
84
  import { DatabaseCacheDriver } from "./cache/database-cache-driver.mjs";
84
85
  import "./cache/index.mjs";
85
- import { CLICommand, command } from "./cli/cli-command.mjs";
86
+ import { CLICommand, command } from "./commands/cli-command.mjs";
86
87
  import { ConnectorLifecyclePhase, ConnectorPriority } from "./connectors/types.mjs";
87
88
  import { BaseConnector } from "./connectors/base-connector.mjs";
88
89
  import { AccessConnector } from "./connectors/access-connector.mjs";
@@ -113,12 +114,6 @@ import { seeder } from "./database/seeds/seeder.mjs";
113
114
  import { SeederDependencyCycleError, UnknownSeederDependencyError } from "./database/seeds/seeder.errors.mjs";
114
115
  import { useComputedModel, useComputedSlug, useHashedPassword } from "./database/utils.mjs";
115
116
  import "./database/index.mjs";
116
- import { WarlockConfigManager, isUnknownTsExtensionError, warlockConfigManager } from "./warlock-config/warlock-config.manager.mjs";
117
- import { BaseHealthChecker } from "./dev-server/health-checker/checkers/base-health-checker.mjs";
118
- import { EslintHealthChecker } from "./dev-server/health-checker/checkers/eslint-health-checker.mjs";
119
- import { TypescriptHealthChecker } from "./dev-server/health-checker/checkers/typescript-health-checker.mjs";
120
- import { FilesOrchestrator, filesOrchestrator, onCleanup } from "./dev-server/files-orchestrator.mjs";
121
- import "./dev-server/health-checker/index.mjs";
122
117
  import { decrypt, encrypt } from "./encryption/encrypt.mjs";
123
118
  import { hmacHash } from "./encryption/hash.mjs";
124
119
  import { hashPassword, verifyPassword } from "./encryption/password.mjs";
@@ -136,11 +131,6 @@ import { Restful } from "./restful/restful.mjs";
136
131
  import "./restful/index.mjs";
137
132
  import { getSocketServer } from "./socket/utils.mjs";
138
133
  import "./socket/index.mjs";
139
- import { TEST_SERVER_PORT_ENV_KEY, publishTestServerPort, withdrawTestServerPort } from "./tests/test-server-port-channel.mjs";
140
- import { isTestServerRunning, startHttpTestServer, stopHttpTestServer } from "./tests/start-http-development-server.mjs";
141
- import { expectJson, getTestServerUrl, parseJsonResponse, testDelete, testGet, testPatch, testPost, testPut, testRequest } from "./tests/test-helpers.mjs";
142
- import { setupTest } from "./tests/vitest-setup.mjs";
143
- import "./tests/index.mjs";
144
134
  import { broadcastUseCaseResult } from "./use-cases/use-case-broadcast.mjs";
145
135
  import { fireLifecycleEvent, globalEventsCallbacksMap, globalUseCasesEvents } from "./use-cases/use-case-events.mjs";
146
136
  import { BadSchemaUseCaseError } from "./use-cases/use-case.errors.mjs";
@@ -149,13 +139,12 @@ import { $registerUseCase, $unregisterUseCase, addUseCaseHistory, getUseCase, ge
149
139
  import { useCase } from "./use-cases/use-case.mjs";
150
140
  import "./use-cases/index.mjs";
151
141
  import "./validation/index.mjs";
152
- import { lowerStage3Decorators } from "./vite/lower-stage3-decorators.mjs";
153
- import "./vite/index.mjs";
154
142
  import { defineConfig } from "./warlock-config/define-config.mjs";
143
+ import { WarlockConfigManager, isUnknownTsExtensionError, warlockConfigManager } from "./warlock-config/warlock-config.manager.mjs";
155
144
  import "./warlock-config/index.mjs";
156
145
  import { env } from "@mongez/dotenv";
157
146
  import { colors } from "@mongez/copper";
158
147
 
159
148
  export * from "@mongez/localization"
160
149
 
161
- export { $registerUseCase, $unregisterUseCase, AccessConnector, AiConnector, Application, BOOT_SIGNAL_ENV_KEY, BOOT_SIGNAL_VERSION, BadRequestError, BadSchemaUseCaseError, BaseConnector, BaseHealthChecker, BenchmarkProfiler, BenchmarkSnapshots, CLICommand, CacheConnector, CascadeAdapter, CascadeQueryBuilder, CloudDriver, ConfigSpecialHandlers, ConflictError, ConnectorLifecyclePhase, ConnectorPriority, ConnectorsManager, ConsoleChannel, DOSpacesDriver, DatabaseCacheDriver, DatabaseConnector, DatabaseLog, DatabaseLogModel, EslintHealthChecker, FileValidator, FilesOrchestrator, ForbiddenError, HeraldConnector, HttpConnector, HttpError, HttpErrorCodes, Image, LocalDriver, LoggerConnector, MAIL_EVENTS, Mail, MailError, MailerConnector, MimeTypes, NoopChannel, NotAcceptableError, NotAllowedError, NotificationsConnector, PortInUseError, Queue, R2Driver, RegisterResource, RepositoryManager, Request, RequestController, RequestLog, Resource, ResourceFieldBuilder, ResourceNotFoundError, Response, ResponseStatus, Restful, Router, S3Driver, ScopedStorage, SeederDependencyCycleError, ServerError, SocketConnector, Storage, StorageConnector, StorageError, StorageFile, TEST_SERVER_PORT_ENV_KEY, TypescriptHealthChecker, UPLOADS_DEFAULTS, UnAuthorizedError, UnknownSeederDependencyError, UploadedFile, WarlockConfigManager, addUseCaseHistory, anyMatch, app, appLog, appPath, assertMailCount, assertMailSent, assertPortIsAvailable, assetsUrl, bootstrap, broadcastUseCaseResult, buildIdempotencyCacheKey, cachePath, captureMail, clearTestMailbox, closeAllMailers, closeMailer, closeServerWithTimeout, colors, command, config, configPath, configSpecialHandlers, connectorsManager, container, createHttpApplication, createRequestStore, decrypt, defaultHttpConfigurations, defineConfig, defineResource, displayEnvironmentMode, encrypt, env, environment, existsExceptCurrentIdRule, existsExceptCurrentUserRule, expectJson, fetchLatestVersion, fileExtensionRule, fileRule, fileTypeRule, filesOrchestrator, findMailsBySubject, findMailsTo, fireLifecycleEvent, fromRequest, generateMailId, getDefaultMailConfig, getHttpServer, getLastMail, getLocalized, getMailEventName, getMailMode, getMailboxSize, getMailer, getMailerConfig, getMimeType, getPoolStats, getSocketServer, getTestMailbox, getTestServerUrl, getUseCase, getUseCaseHistory, getUseCases, globalEventsCallbacksMap, globalUseCasesEvents, hashBody, hashPassword, health, hmacHash, httpConfig, imageRule, increaseUseCaseFailedCalls, increaseUseCaseSuccessCalls, ipMatches, isBootSignal, isDevelopmentMode, isNewerVersion, isPortAvailable, isPrivateOrReservedIp, isProductionMode, isTestMode, isTestServerRunning, isUnknownTsExtensionError, isValidIdempotencyKey, loadS3, logResponse, logsPath, lowerStage3Decorators, mailEvents, measure, middleware, onCleanup, parseJsonResponse, parseSize, paths, promiseAllObject, publicPath, publicUrl, publishTestServerPort, registerAppConfig, registerHttpPlugins, renderReact, renderReactMail, requestContext, resetMailConfig, resolveMailConfig, resolveWithinRoot, rootPath, router, runPipeline, safeFetchToBuffer, sanitizePath, seeder, sendBootSignal, sendMail, setBaseUrl, setConfig, setEnvironment, setLogConfigurations, setMailConfigurations, setMailMode, setupTest, sleep, sluggable, srcPath, startHttpServer, startHttpTestServer, stopHttpApplication, stopHttpTestServer, storage, storageConfig, storageConfigurations, storageDriverContext, storagePath, t, tempPath, testDelete, testGet, testPatch, testPost, testPut, testRequest, toJson, uniqueExceptCurrentIdRule, uniqueExceptCurrentUserRule, uploadedFileMetadataSchema, uploadsConfig, uploadsPath, uploadsUrl, url, useCase, useComputedModel, useComputedSlug, useCurrentUser, useHashedPassword, useRequest, useRequestStore, verifyMailer, verifyPassword, warlockConfigManager, warlockPath, wasMailSentTo, wasMailSentWithSubject, withdrawTestServerPort, wrapResponseInDataKey };
150
+ export { $registerUseCase, $unregisterUseCase, AccessConnector, AiConnector, Application, BOOT_SIGNAL_ENV_KEY, BOOT_SIGNAL_VERSION, BadRequestError, BadSchemaUseCaseError, BaseConnector, BenchmarkProfiler, BenchmarkSnapshots, CLICommand, CacheConnector, CascadeAdapter, CascadeQueryBuilder, CloudDriver, ConfigSpecialHandlers, ConflictError, ConnectorLifecyclePhase, ConnectorPriority, ConnectorsManager, ConsoleChannel, DOSpacesDriver, DatabaseCacheDriver, DatabaseConnector, DatabaseLog, DatabaseLogModel, FileValidator, ForbiddenError, HeraldConnector, HttpConnector, HttpError, HttpErrorCodes, Image, LocalDriver, LoggerConnector, MAIL_EVENTS, Mail, MailError, MailerConnector, MimeTypes, NoopChannel, NotAcceptableError, NotAllowedError, NotificationsConnector, Path, PortInUseError, Queue, R2Driver, RegisterResource, RepositoryManager, Request, RequestController, RequestLog, Resource, ResourceFieldBuilder, ResourceNotFoundError, Response, ResponseStatus, Restful, Router, S3Driver, ScopedStorage, SeederDependencyCycleError, ServerError, SocketConnector, Storage, StorageConnector, StorageError, StorageFile, UPLOADS_DEFAULTS, UnAuthorizedError, UnknownSeederDependencyError, UploadedFile, WarlockConfigManager, addUseCaseHistory, anyMatch, app, appLog, appPath, assertMailCount, assertMailSent, assertPortIsAvailable, assetsUrl, bootstrap, broadcastUseCaseResult, buildIdempotencyCacheKey, cachePath, captureMail, clearTestMailbox, closeAllMailers, closeMailer, closeServerWithTimeout, colors, command, config, configPath, configSpecialHandlers, connectorsManager, container, createHttpApplication, createRequestStore, decrypt, defaultHttpConfigurations, defineConfig, defineResource, displayEnvironmentMode, encrypt, env, environment, existsExceptCurrentIdRule, existsExceptCurrentUserRule, fetchLatestVersion, fileExtensionRule, fileRule, fileTypeRule, findMailsBySubject, findMailsTo, fireLifecycleEvent, fromRequest, generateMailId, getDefaultMailConfig, getHttpServer, getLastMail, getLocalized, getMailEventName, getMailMode, getMailboxSize, getMailer, getMailerConfig, getMimeType, getPoolStats, getSocketServer, getTestMailbox, getUseCase, getUseCaseHistory, getUseCases, globalEventsCallbacksMap, globalUseCasesEvents, hashBody, hashPassword, health, hmacHash, httpConfig, imageRule, increaseUseCaseFailedCalls, increaseUseCaseSuccessCalls, ipMatches, isBootSignal, isDevelopmentMode, isNewerVersion, isPortAvailable, isPrivateOrReservedIp, isProductionMode, isTestMode, isUnknownTsExtensionError, isValidIdempotencyKey, loadS3, logResponse, logsPath, mailEvents, measure, middleware, parseSize, paths, promiseAllObject, publicPath, publicUrl, registerAppConfig, registerHttpPlugins, renderReact, renderReactMail, requestContext, resetMailConfig, resolveMailConfig, resolveWithinRoot, rootPath, router, runPipeline, safeFetchToBuffer, sanitizePath, seeder, sendBootSignal, sendMail, setBaseUrl, setConfig, setEnvironment, setLogConfigurations, setMailConfigurations, setMailMode, sleep, sluggable, srcPath, startHttpServer, stopHttpApplication, storage, storageConfig, storageConfigurations, storageDriverContext, storagePath, t, tempPath, toJson, uniqueExceptCurrentIdRule, uniqueExceptCurrentUserRule, uploadedFileMetadataSchema, uploadsConfig, uploadsPath, uploadsUrl, url, useCase, useComputedModel, useComputedSlug, useCurrentUser, useHashedPassword, useRequest, useRequestStore, verifyMailer, verifyPassword, warlockConfigManager, warlockPath, wasMailSentTo, wasMailSentWithSubject, wrapResponseInDataKey };
@@ -13,6 +13,44 @@ import esbuild from "esbuild";
13
13
 
14
14
  //#region ../core/src/production/production-builder.ts
15
15
  /**
16
+ * Recreates `require`, `__filename` and `__dirname` at the top of an ESM bundle.
17
+ *
18
+ * Bundled CommonJS dependencies call `require("node:assert")` and read
19
+ * `__dirname` to locate their own assets. Neither exists in an ES module, so
20
+ * esbuild substitutes a stub that throws — **after the build has reported
21
+ * success**. `Dynamic require of "node:assert" is not supported` is that stub
22
+ * firing, and it is the defect this shim removes.
23
+ *
24
+ * `__dirname` matters as much as `require`: without it a dependency resolving
25
+ * an asset path silently gets `undefined` and fails later, further from the
26
+ * cause.
27
+ *
28
+ * Written as one line because esbuild inserts a banner verbatim above the
29
+ * bundle and a multi-line string here would shift every mapped line.
30
+ */
31
+ const ESM_INTEROP_SHIM = "import{createRequire as __wlCreateRequire}from'node:module';import{fileURLToPath as __wlFileURLToPath}from'node:url';import{dirname as __wlDirname}from'node:path';const require=__wlCreateRequire(import.meta.url);const __filename=__wlFileURLToPath(import.meta.url);const __dirname=__wlDirname(__filename);";
32
+ /**
33
+ * Combine the framework's banner with the user's, keeping both.
34
+ *
35
+ * esbuild's `banner` is an object keyed by output type, and every merge in the
36
+ * path to it — the config merge and the options spread — REPLACES that object
37
+ * rather than merging it. So whichever is applied second silently deletes the
38
+ * other. This is the only place the two can coexist.
39
+ *
40
+ * The shim goes first: it defines `require`, which a user banner may use.
41
+ *
42
+ * @param userBanner banner from `warlock.config.ts`, if any
43
+ * @param shim the interop shim, or undefined when it does not apply
44
+ */
45
+ function mergeBanner(userBanner, shim) {
46
+ if (!shim) return userBanner;
47
+ const userJs = userBanner?.js;
48
+ return {
49
+ ...userBanner,
50
+ js: userJs ? `${shim}${userJs}` : shim
51
+ };
52
+ }
53
+ /**
16
54
  * Production Builder
17
55
  * Generates production-ready files and bundles them for deployment
18
56
  * Build options are loaded from warlock.config.ts
@@ -244,17 +282,26 @@ bootstrap();
244
282
  const outDir = this.options.outdir;
245
283
  const outFileName = this.options.outFile;
246
284
  const entryName = path.basename(outFileName, path.extname(outFileName));
285
+ const singleBundle = this.options.singleBundle === true;
286
+ const esmShim = this.options.esmShim !== false;
287
+ const userBanner = this.options.banner;
247
288
  delete this.options.outFile;
248
289
  delete this.options.entryPath;
290
+ delete this.options.singleBundle;
291
+ delete this.options.esmShim;
292
+ delete this.options.banner;
249
293
  await ensureDirectoryAsync(outDir);
250
294
  const alias = this.buildAliasMapFromTsconfig();
295
+ const isEsm = (this.options.format ?? "esm") === "esm";
296
+ const banner = mergeBanner(userBanner, esmShim && isEsm ? ESM_INTEROP_SHIM : void 0);
297
+ if (singleBundle) console.log(colors.magenta(" Single-bundle mode — one JS file" + (esmShim && isEsm ? " with the ESM interop shim" : "") + ". Native .node addons are still emitted alongside it."));
251
298
  try {
252
299
  await esbuild.build({
253
300
  platform: "node",
254
301
  entryPoints: [entryPoint],
255
302
  bundle: true,
256
- splitting: true,
257
- packages: "external",
303
+ splitting: !singleBundle,
304
+ packages: singleBundle ? "bundle" : "external",
258
305
  minify: this.options.minify,
259
306
  sourcemap: this.options.sourcemap === true ? "linked" : this.options.sourcemap,
260
307
  format: "esm",
@@ -263,7 +310,8 @@ bootstrap();
263
310
  entryNames: entryName,
264
311
  alias,
265
312
  plugins: [nativeNodeModulesPlugin],
266
- ...this.options
313
+ ...this.options,
314
+ ...banner ? { banner } : {}
267
315
  });
268
316
  } catch (e) {
269
317
  console.log(e);
@@ -1 +1 @@
1
- {"version":3,"file":"production-builder.mjs","names":[],"sources":["../../../../../../../core/src/production/production-builder.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\r\nimport {\r\n ensureDirectoryAsync,\r\n fileExistsAsync,\r\n getFileAsync,\r\n getJsonFileAsync,\r\n putFileAsync,\r\n removeDirectoryAsync,\r\n} from \"@warlock.js/fs\";\r\nimport esbuild from \"esbuild\";\r\nimport glob from \"fast-glob\";\r\nimport path from \"path\";\r\nimport { tsconfigManager } from \"../dev-server/tsconfig-manager\";\r\nimport { appPath, rootPath, warlockPath } from \"../utils\";\r\nimport { assertGeneratedImportsAreDeclared } from \"./assert-generated-imports\";\r\nimport { nativeNodeModulesPlugin } from \"./esbuild-plugins\";\r\nimport { resolveBuildConfig, type ResolvedBuildConfig } from \"./resolve-build-config\";\r\nimport { toCamelCase, toKebabCase } from \"@mongez/reinforcements\";\r\n\r\n/**\r\n * Production Builder\r\n * Generates production-ready files and bundles them for deployment\r\n * Build options are loaded from warlock.config.ts\r\n */\r\nexport class ProductionBuilder {\r\n private options!: ResolvedBuildConfig;\r\n private readonly productionDir = warlockPath(\"production\");\r\n\r\n /**\r\n * Main build entry point\r\n */\r\n public async build(): Promise<void> {\r\n console.log(colors.cyan(\"Building for production...\\n\"));\r\n\r\n // Step 1: Initialize options from config\r\n await this.initializeOptions();\r\n\r\n // Step 2: Generate combined files\r\n await this.generateCombinedFiles();\r\n\r\n // Step 3: Generate entry point\r\n await this.generateEntryPoint();\r\n\r\n // Step 4: Refuse to bundle code the app could not resolve at runtime\r\n await this.assertGeneratedImports();\r\n\r\n // Step 5: Bundle with esbuild\r\n await this.bundle();\r\n\r\n // Step 6: Remove production folder\r\n await removeDirectoryAsync(this.productionDir);\r\n\r\n console.log(colors.green(\"Build complete!\"));\r\n console.log(`Start production server by running ${colors.cyan(\"warlock start\")}`);\r\n }\r\n\r\n /**\r\n * Initialize options from warlock.config.ts\r\n */\r\n private async initializeOptions(): Promise<void> {\r\n this.options = resolveBuildConfig();\r\n\r\n // Ensure production directory exists\r\n await ensureDirectoryAsync(this.productionDir);\r\n }\r\n\r\n /**\r\n * Track which special files were generated\r\n */\r\n private generatedFiles = {\r\n locales: false,\r\n events: false,\r\n main: false,\r\n routes: false,\r\n };\r\n\r\n /**\r\n * Generate all combined files\r\n */\r\n private async generateCombinedFiles(): Promise<void> {\r\n console.log(colors.yellow(\" Generating production files...\"));\r\n\r\n // Generate bootstrap.ts file\r\n await this.generateBootstrap();\r\n\r\n // Generate config loader\r\n await this.generateConfigLoader();\r\n\r\n // Generate special files and track which ones have content\r\n const [locales, events, main, routes] = await Promise.all([\r\n this.generateLocales(),\r\n this.generateEvents(),\r\n this.generateMain(),\r\n this.generateRoutes(),\r\n ]);\r\n\r\n this.generatedFiles = { locales, events, main, routes };\r\n }\r\n\r\n /**\r\n * Generate bootstrap.ts - ensures bootstrap() runs first and sets production environment\r\n */\r\n private async generateBootstrap(): Promise<void> {\r\n let content = `import { bootstrap, Application } from \"@warlock.js/core\";\r\n\r\n// Set production environment\r\nApplication.setRuntimeStrategy(\"production\");\r\nApplication.setEnvironment(\"production\");\r\n\r\n// Bootstrap the application\r\nbootstrap();\r\n`;\r\n if (await fileExistsAsync(appPath(\"bootstrap.ts\"))) {\r\n content += \"import './../../src/app/bootstrap';\\n\";\r\n }\r\n\r\n await putFileAsync(path.join(this.productionDir, \"bootstrap.ts\"), content);\r\n }\r\n\r\n /**\r\n * Fail the build when generated code imports a package the app does not\r\n * declare.\r\n *\r\n * The bundler is configured `packages: \"external\"`, so every bare specifier\r\n * written above survives verbatim into an artifact that resolves against the\r\n * **consuming app's** node_modules. A framework-internal dependency imported\r\n * there resolves by accident under npm/yarn hoisting and dies under pnpm —\r\n * which is how a production app shipped that could not boot. Rewriting the\r\n * offending import fixes today's bundle; this check is what stops the next\r\n * change to the generator from quietly reintroducing it.\r\n */\r\n private async assertGeneratedImports(): Promise<void> {\r\n const generatedPaths = await glob(\"**/*.{ts,tsx,js,mjs}\", {\r\n cwd: this.productionDir,\r\n absolute: false,\r\n });\r\n\r\n const [files, appPackage] = await Promise.all([\r\n Promise.all(\r\n generatedPaths.map(async (file) => ({\r\n file,\r\n content: await getFileAsync(path.join(this.productionDir, file)),\r\n })),\r\n ),\r\n getJsonFileAsync<{ dependencies?: Record<string, string> }>(rootPath(\"package.json\")),\r\n ]);\r\n\r\n assertGeneratedImportsAreDeclared(files, Object.keys(appPackage.dependencies ?? {}));\r\n }\r\n\r\n /**\r\n * Glob for module files matching a pattern\r\n * Returns relative paths from .warlock/production/ to src/app/\r\n */\r\n private async globModule(fileName: string): Promise<string[]> {\r\n const pattern = `**/${fileName}.{ts,tsx}`;\r\n const appDirectory = appPath();\r\n\r\n const files = await glob(pattern, {\r\n cwd: appDirectory,\r\n absolute: false,\r\n });\r\n\r\n // Convert to relative paths from .warlock/production/ to src/app/\r\n // e.g., \"users/main\" -> \"../../src/app/users/main\"\r\n return files.map((file) => \"../../src/app/\" + file.replace(/\\.(ts|tsx)$/, \"\"));\r\n }\r\n\r\n /**\r\n * Glob for files in a specific directory pattern\r\n * Returns relative paths from .warlock/production/ to src/app/\r\n */\r\n private async globModuleDirectory(directory: string): Promise<string[]> {\r\n const pattern = `**/${directory}/*.{ts,tsx}`;\r\n const appDirectory = appPath();\r\n\r\n const files = await glob(pattern, {\r\n cwd: appDirectory,\r\n absolute: false,\r\n });\r\n\r\n return files.map((file) => \"../../src/app/\" + file.replace(/\\.(ts|tsx)$/, \"\"));\r\n }\r\n\r\n /**\r\n * Generate config-loader.ts\r\n */\r\n private async generateConfigLoader(): Promise<void> {\r\n const configDirectory = path.join(process.cwd(), \"src/config\");\r\n\r\n const files = await glob(\"*.{ts,tsx}\", {\r\n cwd: configDirectory,\r\n absolute: false,\r\n });\r\n\r\n const configNames = files.map((f) => f.replace(/\\.(ts|tsx)$/, \"\"));\r\n\r\n // Only `@warlock.js/core` — the one package the app itself declares. See\r\n // `assertGeneratedImportsAreDeclared`: `@mongez/config` is core's own\r\n // dependency, so a bare import of it resolved by luck under npm/yarn\r\n // hoisting and died under pnpm's strict layout.\r\n const imports: string[] = [\r\n 'import { setConfig, configSpecialHandlers } from \"@warlock.js/core\";',\r\n ];\r\n const configImports: string[] = [];\r\n const configSetCalls: string[] = [];\r\n const executors: string[] = [];\r\n\r\n for (const configName of configNames) {\r\n const properConfigName = toCamelCase(configName);\r\n const varName = `${properConfigName}Config`;\r\n configImports.push(`import ${varName} from \"../../src/config/${configName}\";`);\r\n configSetCalls.push(`setConfig(\"${properConfigName}\", ${varName});`);\r\n executors.push(`await configSpecialHandlers.execute(\"${properConfigName}\", ${varName});`);\r\n }\r\n\r\n let content = [\r\n ...imports,\r\n \"\",\r\n \"// Config imports\",\r\n ...configImports,\r\n \"\",\r\n \"// Register configs\",\r\n ...configSetCalls,\r\n \"\",\r\n \"// Special handlers\",\r\n ...executors,\r\n \"\",\r\n ].join(\"\\n\");\r\n\r\n if (await fileExistsAsync(appPath(\"prestart.ts\"))) {\r\n content += \"import './../../src/app/prestart';\\n\";\r\n }\r\n\r\n await putFileAsync(path.join(this.productionDir, \"config-loader.ts\"), content);\r\n }\r\n\r\n /**\r\n * Generate locales.ts (only if there are locale files)\r\n * @returns true if file was generated with content\r\n */\r\n private async generateLocales(): Promise<boolean> {\r\n const files = await this.globModule(\"utils/locales\");\r\n if (files.length === 0) return false;\r\n await this.generateImportsFile(files, \"locales.ts\");\r\n return true;\r\n }\r\n\r\n /**\r\n * Generate events.ts (only if there are event files)\r\n * @returns true if file was generated with content\r\n */\r\n private async generateEvents(): Promise<boolean> {\r\n const files = await this.globModuleDirectory(\"events\");\r\n if (files.length === 0) return false;\r\n await this.generateImportsFile(files, \"events.ts\");\r\n return true;\r\n }\r\n\r\n /**\r\n * Generate main.ts (only if there are main files)\r\n * @returns true if file was generated with content\r\n */\r\n private async generateMain(): Promise<boolean> {\r\n const files = await this.globModule(\"main\");\r\n if (files.length === 0) return false;\r\n await this.generateImportsFile(files, \"main.ts\");\r\n return true;\r\n }\r\n\r\n /**\r\n * Generate routes.ts (only if there are route files)\r\n * @returns true if file was generated with content\r\n */\r\n private async generateRoutes(): Promise<boolean> {\r\n const files = await this.globModule(\"routes\");\r\n if (files.length === 0) return false;\r\n await this.generateImportsFile(files, \"routes.ts\");\r\n return true;\r\n }\r\n\r\n /**\r\n * Generate a file with imports from all given files\r\n */\r\n private async generateImportsFile(importPaths: string[], outputFile: string): Promise<void> {\r\n const imports = importPaths.map((importPath) => `import \"${importPath}\";`);\r\n const content = imports.join(\"\\n\") + \"\\n\";\r\n await putFileAsync(path.join(this.productionDir, outputFile), content);\r\n }\r\n\r\n /**\r\n * Generate the main entry point (app.ts)\r\n */\r\n private async generateEntryPoint(): Promise<void> {\r\n console.log(colors.yellow(\" Generating entry point...\"));\r\n\r\n // Build imports based on which files were generated\r\n const imports: string[] = [\r\n \"// 1. Bootstrap (loads .env, initializes framework)\",\r\n 'import \"./bootstrap\";',\r\n \"\",\r\n \"// 2. Load configs\",\r\n 'import \"./config-loader\";',\r\n \"\",\r\n \"// 3. Start early-phase connectors (database, cache, logger, ...)\",\r\n \"// so data sources, cache, etc. are ready before app code runs\",\r\n 'import { Application, connectorsManager, ConnectorLifecyclePhase } from \"@warlock.js/core\";',\r\n \"await connectorsManager.startPhase(ConnectorLifecyclePhase.Early);\",\r\n ];\r\n\r\n // App code uses dynamic `await import(...)` so each module's side\r\n // effects fire at THIS point in execution. Static imports would be\r\n // hoisted to module-instantiation time (before the early-phase await\r\n // resolves), which is exactly the bug this split is meant to fix.\r\n // Requires `splitting: true` in esbuild (set below in bundle()).\r\n imports.push(\"\", \"// 4. Load app code (events, locales, main, routes)\");\r\n\r\n if (this.generatedFiles.events) {\r\n imports.push('await import(\"./events\");');\r\n }\r\n if (this.generatedFiles.locales) {\r\n imports.push('await import(\"./locales\");');\r\n }\r\n if (this.generatedFiles.main) {\r\n imports.push('await import(\"./main\");');\r\n }\r\n if (this.generatedFiles.routes) {\r\n imports.push('await import(\"./routes\");');\r\n }\r\n\r\n // Start late-phase connectors after app code registers routes/listeners\r\n imports.push(\r\n \"\",\r\n \"// 5. Start late-phase connectors (http, socket) — routes and\",\r\n \"// listeners registered by app code are now ready to bind\",\r\n \"await connectorsManager.startPhase(ConnectorLifecyclePhase.Late);\",\r\n \"\",\r\n \"// 6. Signal a complete boot so `Application.onceBooted(...)` listeners fire\",\r\n \"Application.markBooted({ environment: Application.environment, runtimeStrategy: Application.runtimeStrategy });\",\r\n \"connectorsManager.shutdownOnProcessKill();\",\r\n );\r\n\r\n const content = imports.join(\"\\n\") + \"\\n\";\r\n await putFileAsync(path.join(this.productionDir, \"app.ts\"), content);\r\n }\r\n\r\n /**\r\n * Bundle with esbuild\r\n */\r\n private async bundle(): Promise<void> {\r\n console.log(colors.magenta(\" Bundling with esbuild...\"));\r\n\r\n const entryPoint = path.join(this.productionDir, \"app.ts\");\r\n const outDir = this.options.outdir!;\r\n const outFileName = this.options.outFile!;\r\n // Strip extension so entryNames produces \"<base>.js\" via esbuild\r\n const entryName = path.basename(outFileName, path.extname(outFileName));\r\n\r\n delete this.options.outFile;\r\n delete this.options.entryPath;\r\n\r\n await ensureDirectoryAsync(outDir);\r\n\r\n const alias = this.buildAliasMapFromTsconfig();\r\n\r\n\r\n try {\r\n \r\n await esbuild.build({\r\n platform: \"node\",\r\n entryPoints: [entryPoint],\r\n bundle: true,\r\n // Required so dynamic `await import(\"./main\")` in the generated\r\n // app.ts produces separate chunks loaded at the runtime call site,\r\n // instead of inlining the modules at instantiation time (which\r\n // would defeat the early/late phase split).\r\n splitting: true,\r\n packages: \"external\",\r\n minify: this.options!.minify,\r\n sourcemap: this.options!.sourcemap === true ? \"linked\" : this.options!.sourcemap,\r\n format: \"esm\",\r\n // Targeting a concrete Node version (not \"esnext\") so esbuild\r\n // transpiles TC39 stage 3 decorators into helpers — Node does not\r\n // implement them natively yet.\r\n target: [\"node22\"],\r\n outdir: outDir,\r\n entryNames: entryName,\r\n alias,\r\n plugins: [nativeNodeModulesPlugin],\r\n ...(this.options as any),\r\n });\r\n } catch (e) {\r\n console.log(e);\r\n throw e;\r\n }\r\n }\r\n\r\n /**\r\n * Build an alias map from tsconfig `paths` so esbuild resolves local\r\n * source aliases (e.g. `@warlock.js/cascade`) to their on-disk source\r\n * folders during bundling. Without this, `packages: \"external\"` would\r\n * leave those bare specifiers as raw imports and Node would fail to\r\n * resolve them at runtime (they aren't installed in node_modules).\r\n *\r\n * Only exact (non-wildcard) aliases are included — esbuild's `alias`\r\n * option doesn't support glob-style mappings.\r\n */\r\n private buildAliasMapFromTsconfig(): Record<string, string> {\r\n tsconfigManager.init();\r\n\r\n const alias: Record<string, string> = {};\r\n const baseUrl = path.resolve(process.cwd(), tsconfigManager.baseUrl);\r\n\r\n for (const [from, to] of Object.entries(tsconfigManager.aliases)) {\r\n if (from.endsWith(\"/*\") || !Array.isArray(to) || to.length === 0) {\r\n continue;\r\n }\r\n\r\n alias[from] = path.resolve(baseUrl, to[0]);\r\n }\r\n\r\n return alias;\r\n }\r\n}\r\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAwBA,IAAa,oBAAb,MAA+B;;uBAEI,YAAY,YAAY;wBA2ChC;GACvB,SAAS;GACT,QAAQ;GACR,MAAM;GACN,QAAQ;EACV;;;;;CA3CA,MAAa,QAAuB;EAClC,QAAQ,IAAI,OAAO,KAAK,8BAA8B,CAAC;EAGvD,MAAM,KAAK,kBAAkB;EAG7B,MAAM,KAAK,sBAAsB;EAGjC,MAAM,KAAK,mBAAmB;EAG9B,MAAM,KAAK,uBAAuB;EAGlC,MAAM,KAAK,OAAO;EAGlB,MAAM,qBAAqB,KAAK,aAAa;EAE7C,QAAQ,IAAI,OAAO,MAAM,iBAAiB,CAAC;EAC3C,QAAQ,IAAI,sCAAsC,OAAO,KAAK,eAAe,GAAG;CAClF;;;;CAKA,MAAc,oBAAmC;EAC/C,KAAK,UAAU,mBAAmB;EAGlC,MAAM,qBAAqB,KAAK,aAAa;CAC/C;;;;CAeA,MAAc,wBAAuC;EACnD,QAAQ,IAAI,OAAO,OAAO,mCAAmC,CAAC;EAG9D,MAAM,KAAK,kBAAkB;EAG7B,MAAM,KAAK,qBAAqB;EAGhC,MAAM,CAAC,SAAS,QAAQ,MAAM,UAAU,MAAM,QAAQ,IAAI;GACxD,KAAK,gBAAgB;GACrB,KAAK,eAAe;GACpB,KAAK,aAAa;GAClB,KAAK,eAAe;EACtB,CAAC;EAED,KAAK,iBAAiB;GAAE;GAAS;GAAQ;GAAM;EAAO;CACxD;;;;CAKA,MAAc,oBAAmC;EAC/C,IAAI,UAAU;;;;;;;;;EASd,IAAI,MAAM,gBAAgB,QAAQ,cAAc,CAAC,GAC/C,WAAW;EAGb,MAAM,aAAa,KAAK,KAAK,KAAK,eAAe,cAAc,GAAG,OAAO;CAC3E;;;;;;;;;;;;;CAcA,MAAc,yBAAwC;EACpD,MAAM,iBAAiB,MAAM,KAAK,wBAAwB;GACxD,KAAK,KAAK;GACV,UAAU;EACZ,CAAC;EAED,MAAM,CAAC,OAAO,cAAc,MAAM,QAAQ,IAAI,CAC5C,QAAQ,IACN,eAAe,IAAI,OAAO,UAAU;GAClC;GACA,SAAS,MAAM,aAAa,KAAK,KAAK,KAAK,eAAe,IAAI,CAAC;EACjE,EAAE,CACJ,GACA,iBAA4D,SAAS,cAAc,CAAC,CACtF,CAAC;EAED,kCAAkC,OAAO,OAAO,KAAK,WAAW,gBAAgB,CAAC,CAAC,CAAC;CACrF;;;;;CAMA,MAAc,WAAW,UAAqC;EAW5D,QAAO,MAPa,KAAK,MAHH,SAAS,YAGG;GAChC,KAHmB,QAGH;GAChB,UAAU;EACZ,CAAC,EAIW,CAAC,KAAK,SAAS,mBAAmB,KAAK,QAAQ,eAAe,EAAE,CAAC;CAC/E;;;;;CAMA,MAAc,oBAAoB,WAAsC;EAStE,QAAO,MALa,KAAK,MAHH,UAAU,cAGE;GAChC,KAHmB,QAGH;GAChB,UAAU;EACZ,CAAC,EAEW,CAAC,KAAK,SAAS,mBAAmB,KAAK,QAAQ,eAAe,EAAE,CAAC;CAC/E;;;;CAKA,MAAc,uBAAsC;EAQlD,MAAM,eAAc,MALA,KAAK,cAAc;GACrC,KAHsB,KAAK,KAAK,QAAQ,IAAI,GAAG,YAG5B;GACnB,UAAU;EACZ,CAAC,EAEwB,CAAC,KAAK,MAAM,EAAE,QAAQ,eAAe,EAAE,CAAC;EAMjE,MAAM,UAAoB,CACxB,wEACF;EACA,MAAM,gBAA0B,CAAC;EACjC,MAAM,iBAA2B,CAAC;EAClC,MAAM,YAAsB,CAAC;EAE7B,KAAK,MAAM,cAAc,aAAa;GACpC,MAAM,mBAAmB,YAAY,UAAU;GAC/C,MAAM,UAAU,GAAG,iBAAiB;GACpC,cAAc,KAAK,UAAU,QAAQ,0BAA0B,WAAW,GAAG;GAC7E,eAAe,KAAK,cAAc,iBAAiB,KAAK,QAAQ,GAAG;GACnE,UAAU,KAAK,wCAAwC,iBAAiB,KAAK,QAAQ,GAAG;EAC1F;EAEA,IAAI,UAAU;GACZ,GAAG;GACH;GACA;GACA,GAAG;GACH;GACA;GACA,GAAG;GACH;GACA;GACA,GAAG;GACH;EACF,CAAC,CAAC,KAAK,IAAI;EAEX,IAAI,MAAM,gBAAgB,QAAQ,aAAa,CAAC,GAC9C,WAAW;EAGb,MAAM,aAAa,KAAK,KAAK,KAAK,eAAe,kBAAkB,GAAG,OAAO;CAC/E;;;;;CAMA,MAAc,kBAAoC;EAChD,MAAM,QAAQ,MAAM,KAAK,WAAW,eAAe;EACnD,IAAI,MAAM,WAAW,GAAG,OAAO;EAC/B,MAAM,KAAK,oBAAoB,OAAO,YAAY;EAClD,OAAO;CACT;;;;;CAMA,MAAc,iBAAmC;EAC/C,MAAM,QAAQ,MAAM,KAAK,oBAAoB,QAAQ;EACrD,IAAI,MAAM,WAAW,GAAG,OAAO;EAC/B,MAAM,KAAK,oBAAoB,OAAO,WAAW;EACjD,OAAO;CACT;;;;;CAMA,MAAc,eAAiC;EAC7C,MAAM,QAAQ,MAAM,KAAK,WAAW,MAAM;EAC1C,IAAI,MAAM,WAAW,GAAG,OAAO;EAC/B,MAAM,KAAK,oBAAoB,OAAO,SAAS;EAC/C,OAAO;CACT;;;;;CAMA,MAAc,iBAAmC;EAC/C,MAAM,QAAQ,MAAM,KAAK,WAAW,QAAQ;EAC5C,IAAI,MAAM,WAAW,GAAG,OAAO;EAC/B,MAAM,KAAK,oBAAoB,OAAO,WAAW;EACjD,OAAO;CACT;;;;CAKA,MAAc,oBAAoB,aAAuB,YAAmC;EAE1F,MAAM,UADU,YAAY,KAAK,eAAe,WAAW,WAAW,GAChD,CAAC,CAAC,KAAK,IAAI,IAAI;EACrC,MAAM,aAAa,KAAK,KAAK,KAAK,eAAe,UAAU,GAAG,OAAO;CACvE;;;;CAKA,MAAc,qBAAoC;EAChD,QAAQ,IAAI,OAAO,OAAO,8BAA8B,CAAC;EAGzD,MAAM,UAAoB;GACxB;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;EAOA,QAAQ,KAAK,IAAI,qDAAqD;EAEtE,IAAI,KAAK,eAAe,QACtB,QAAQ,KAAK,6BAA2B;EAE1C,IAAI,KAAK,eAAe,SACtB,QAAQ,KAAK,8BAA4B;EAE3C,IAAI,KAAK,eAAe,MACtB,QAAQ,KAAK,2BAAyB;EAExC,IAAI,KAAK,eAAe,QACtB,QAAQ,KAAK,6BAA2B;EAI1C,QAAQ,KACN,IACA,mEACA,gEACA,qEACA,IACA,gFACA,mHACA,4CACF;EAEA,MAAM,UAAU,QAAQ,KAAK,IAAI,IAAI;EACrC,MAAM,aAAa,KAAK,KAAK,KAAK,eAAe,QAAQ,GAAG,OAAO;CACrE;;;;CAKA,MAAc,SAAwB;EACpC,QAAQ,IAAI,OAAO,QAAQ,6BAA6B,CAAC;EAEzD,MAAM,aAAa,KAAK,KAAK,KAAK,eAAe,QAAQ;EACzD,MAAM,SAAS,KAAK,QAAQ;EAC5B,MAAM,cAAc,KAAK,QAAQ;EAEjC,MAAM,YAAY,KAAK,SAAS,aAAa,KAAK,QAAQ,WAAW,CAAC;EAEtE,OAAO,KAAK,QAAQ;EACpB,OAAO,KAAK,QAAQ;EAEpB,MAAM,qBAAqB,MAAM;EAEjC,MAAM,QAAQ,KAAK,0BAA0B;EAG7C,IAAI;GAEJ,MAAM,QAAQ,MAAM;IAClB,UAAU;IACV,aAAa,CAAC,UAAU;IACxB,QAAQ;IAKR,WAAW;IACX,UAAU;IACV,QAAQ,KAAK,QAAS;IACtB,WAAW,KAAK,QAAS,cAAc,OAAO,WAAW,KAAK,QAAS;IACvE,QAAQ;IAIR,QAAQ,CAAC,QAAQ;IACjB,QAAQ;IACR,YAAY;IACZ;IACA,SAAS,CAAC,uBAAuB;IACjC,GAAI,KAAK;GACX,CAAC;EACD,SAAS,GAAG;GACV,QAAQ,IAAI,CAAC;GACb,MAAM;EACR;CACF;;;;;;;;;;;CAYA,AAAQ,4BAAoD;EAC1D,gBAAgB,KAAK;EAErB,MAAM,QAAgC,CAAC;EACvC,MAAM,UAAU,KAAK,QAAQ,QAAQ,IAAI,GAAG,gBAAgB,OAAO;EAEnE,KAAK,MAAM,CAAC,MAAM,OAAO,OAAO,QAAQ,gBAAgB,OAAO,GAAG;GAChE,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,QAAQ,EAAE,KAAK,GAAG,WAAW,GAC7D;GAGF,MAAM,QAAQ,KAAK,QAAQ,SAAS,GAAG,EAAE;EAC3C;EAEA,OAAO;CACT;AACF"}
1
+ {"version":3,"file":"production-builder.mjs","names":[],"sources":["../../../../../../../core/src/production/production-builder.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\r\nimport {\r\n ensureDirectoryAsync,\r\n fileExistsAsync,\r\n getFileAsync,\r\n getJsonFileAsync,\r\n putFileAsync,\r\n removeDirectoryAsync,\r\n} from \"@warlock.js/fs\";\r\nimport esbuild from \"esbuild\";\r\nimport glob from \"fast-glob\";\r\nimport path from \"path\";\r\nimport { tsconfigManager } from \"../dev-server/tsconfig-manager\";\r\nimport { appPath, rootPath, warlockPath } from \"../utils\";\r\nimport { assertGeneratedImportsAreDeclared } from \"./assert-generated-imports\";\r\nimport { nativeNodeModulesPlugin } from \"./esbuild-plugins\";\r\nimport { resolveBuildConfig, type ResolvedBuildConfig } from \"./resolve-build-config\";\r\nimport { toCamelCase, toKebabCase } from \"@mongez/reinforcements\";\r\n\r\n/**\r\n * Recreates `require`, `__filename` and `__dirname` at the top of an ESM bundle.\r\n *\r\n * Bundled CommonJS dependencies call `require(\"node:assert\")` and read\r\n * `__dirname` to locate their own assets. Neither exists in an ES module, so\r\n * esbuild substitutes a stub that throws — **after the build has reported\r\n * success**. `Dynamic require of \"node:assert\" is not supported` is that stub\r\n * firing, and it is the defect this shim removes.\r\n *\r\n * `__dirname` matters as much as `require`: without it a dependency resolving\r\n * an asset path silently gets `undefined` and fails later, further from the\r\n * cause.\r\n *\r\n * Written as one line because esbuild inserts a banner verbatim above the\r\n * bundle and a multi-line string here would shift every mapped line.\r\n */\r\nconst ESM_INTEROP_SHIM =\r\n \"import{createRequire as __wlCreateRequire}from'node:module';\" +\r\n \"import{fileURLToPath as __wlFileURLToPath}from'node:url';\" +\r\n \"import{dirname as __wlDirname}from'node:path';\" +\r\n \"const require=__wlCreateRequire(import.meta.url);\" +\r\n \"const __filename=__wlFileURLToPath(import.meta.url);\" +\r\n \"const __dirname=__wlDirname(__filename);\";\r\n\r\n/**\r\n * Combine the framework's banner with the user's, keeping both.\r\n *\r\n * esbuild's `banner` is an object keyed by output type, and every merge in the\r\n * path to it — the config merge and the options spread — REPLACES that object\r\n * rather than merging it. So whichever is applied second silently deletes the\r\n * other. This is the only place the two can coexist.\r\n *\r\n * The shim goes first: it defines `require`, which a user banner may use.\r\n *\r\n * @param userBanner banner from `warlock.config.ts`, if any\r\n * @param shim the interop shim, or undefined when it does not apply\r\n */\r\nfunction mergeBanner(\r\n userBanner: Record<string, string> | undefined,\r\n shim: string | undefined,\r\n): Record<string, string> | undefined {\r\n if (!shim) return userBanner;\r\n\r\n const userJs = userBanner?.js;\r\n\r\n return {\r\n ...userBanner,\r\n js: userJs ? `${shim}${userJs}` : shim,\r\n };\r\n}\r\n\r\n/**\r\n * Production Builder\r\n * Generates production-ready files and bundles them for deployment\r\n * Build options are loaded from warlock.config.ts\r\n */\r\nexport class ProductionBuilder {\r\n private options!: ResolvedBuildConfig;\r\n private readonly productionDir = warlockPath(\"production\");\r\n\r\n /**\r\n * Main build entry point\r\n */\r\n public async build(): Promise<void> {\r\n console.log(colors.cyan(\"Building for production...\\n\"));\r\n\r\n // Step 1: Initialize options from config\r\n await this.initializeOptions();\r\n\r\n // Step 2: Generate combined files\r\n await this.generateCombinedFiles();\r\n\r\n // Step 3: Generate entry point\r\n await this.generateEntryPoint();\r\n\r\n // Step 4: Refuse to bundle code the app could not resolve at runtime\r\n await this.assertGeneratedImports();\r\n\r\n // Step 5: Bundle with esbuild\r\n await this.bundle();\r\n\r\n // Step 6: Remove production folder\r\n await removeDirectoryAsync(this.productionDir);\r\n\r\n console.log(colors.green(\"Build complete!\"));\r\n console.log(`Start production server by running ${colors.cyan(\"warlock start\")}`);\r\n }\r\n\r\n /**\r\n * Initialize options from warlock.config.ts\r\n */\r\n private async initializeOptions(): Promise<void> {\r\n this.options = resolveBuildConfig();\r\n\r\n // Ensure production directory exists\r\n await ensureDirectoryAsync(this.productionDir);\r\n }\r\n\r\n /**\r\n * Track which special files were generated\r\n */\r\n private generatedFiles = {\r\n locales: false,\r\n events: false,\r\n main: false,\r\n routes: false,\r\n };\r\n\r\n /**\r\n * Generate all combined files\r\n */\r\n private async generateCombinedFiles(): Promise<void> {\r\n console.log(colors.yellow(\" Generating production files...\"));\r\n\r\n // Generate bootstrap.ts file\r\n await this.generateBootstrap();\r\n\r\n // Generate config loader\r\n await this.generateConfigLoader();\r\n\r\n // Generate special files and track which ones have content\r\n const [locales, events, main, routes] = await Promise.all([\r\n this.generateLocales(),\r\n this.generateEvents(),\r\n this.generateMain(),\r\n this.generateRoutes(),\r\n ]);\r\n\r\n this.generatedFiles = { locales, events, main, routes };\r\n }\r\n\r\n /**\r\n * Generate bootstrap.ts - ensures bootstrap() runs first and sets production environment\r\n */\r\n private async generateBootstrap(): Promise<void> {\r\n let content = `import { bootstrap, Application } from \"@warlock.js/core\";\r\n\r\n// Set production environment\r\nApplication.setRuntimeStrategy(\"production\");\r\nApplication.setEnvironment(\"production\");\r\n\r\n// Bootstrap the application\r\nbootstrap();\r\n`;\r\n if (await fileExistsAsync(appPath(\"bootstrap.ts\"))) {\r\n content += \"import './../../src/app/bootstrap';\\n\";\r\n }\r\n\r\n await putFileAsync(path.join(this.productionDir, \"bootstrap.ts\"), content);\r\n }\r\n\r\n /**\r\n * Fail the build when generated code imports a package the app does not\r\n * declare.\r\n *\r\n * The bundler is configured `packages: \"external\"`, so every bare specifier\r\n * written above survives verbatim into an artifact that resolves against the\r\n * **consuming app's** node_modules. A framework-internal dependency imported\r\n * there resolves by accident under npm/yarn hoisting and dies under pnpm —\r\n * which is how a production app shipped that could not boot. Rewriting the\r\n * offending import fixes today's bundle; this check is what stops the next\r\n * change to the generator from quietly reintroducing it.\r\n */\r\n private async assertGeneratedImports(): Promise<void> {\r\n const generatedPaths = await glob(\"**/*.{ts,tsx,js,mjs}\", {\r\n cwd: this.productionDir,\r\n absolute: false,\r\n });\r\n\r\n const [files, appPackage] = await Promise.all([\r\n Promise.all(\r\n generatedPaths.map(async (file) => ({\r\n file,\r\n content: await getFileAsync(path.join(this.productionDir, file)),\r\n })),\r\n ),\r\n getJsonFileAsync<{ dependencies?: Record<string, string> }>(rootPath(\"package.json\")),\r\n ]);\r\n\r\n assertGeneratedImportsAreDeclared(files, Object.keys(appPackage.dependencies ?? {}));\r\n }\r\n\r\n /**\r\n * Glob for module files matching a pattern\r\n * Returns relative paths from .warlock/production/ to src/app/\r\n */\r\n private async globModule(fileName: string): Promise<string[]> {\r\n const pattern = `**/${fileName}.{ts,tsx}`;\r\n const appDirectory = appPath();\r\n\r\n const files = await glob(pattern, {\r\n cwd: appDirectory,\r\n absolute: false,\r\n });\r\n\r\n // Convert to relative paths from .warlock/production/ to src/app/\r\n // e.g., \"users/main\" -> \"../../src/app/users/main\"\r\n return files.map((file) => \"../../src/app/\" + file.replace(/\\.(ts|tsx)$/, \"\"));\r\n }\r\n\r\n /**\r\n * Glob for files in a specific directory pattern\r\n * Returns relative paths from .warlock/production/ to src/app/\r\n */\r\n private async globModuleDirectory(directory: string): Promise<string[]> {\r\n const pattern = `**/${directory}/*.{ts,tsx}`;\r\n const appDirectory = appPath();\r\n\r\n const files = await glob(pattern, {\r\n cwd: appDirectory,\r\n absolute: false,\r\n });\r\n\r\n return files.map((file) => \"../../src/app/\" + file.replace(/\\.(ts|tsx)$/, \"\"));\r\n }\r\n\r\n /**\r\n * Generate config-loader.ts\r\n */\r\n private async generateConfigLoader(): Promise<void> {\r\n const configDirectory = path.join(process.cwd(), \"src/config\");\r\n\r\n const files = await glob(\"*.{ts,tsx}\", {\r\n cwd: configDirectory,\r\n absolute: false,\r\n });\r\n\r\n const configNames = files.map((f) => f.replace(/\\.(ts|tsx)$/, \"\"));\r\n\r\n // Only `@warlock.js/core` — the one package the app itself declares. See\r\n // `assertGeneratedImportsAreDeclared`: `@mongez/config` is core's own\r\n // dependency, so a bare import of it resolved by luck under npm/yarn\r\n // hoisting and died under pnpm's strict layout.\r\n const imports: string[] = [\r\n 'import { setConfig, configSpecialHandlers } from \"@warlock.js/core\";',\r\n ];\r\n const configImports: string[] = [];\r\n const configSetCalls: string[] = [];\r\n const executors: string[] = [];\r\n\r\n for (const configName of configNames) {\r\n const properConfigName = toCamelCase(configName);\r\n const varName = `${properConfigName}Config`;\r\n configImports.push(`import ${varName} from \"../../src/config/${configName}\";`);\r\n configSetCalls.push(`setConfig(\"${properConfigName}\", ${varName});`);\r\n executors.push(`await configSpecialHandlers.execute(\"${properConfigName}\", ${varName});`);\r\n }\r\n\r\n let content = [\r\n ...imports,\r\n \"\",\r\n \"// Config imports\",\r\n ...configImports,\r\n \"\",\r\n \"// Register configs\",\r\n ...configSetCalls,\r\n \"\",\r\n \"// Special handlers\",\r\n ...executors,\r\n \"\",\r\n ].join(\"\\n\");\r\n\r\n if (await fileExistsAsync(appPath(\"prestart.ts\"))) {\r\n content += \"import './../../src/app/prestart';\\n\";\r\n }\r\n\r\n await putFileAsync(path.join(this.productionDir, \"config-loader.ts\"), content);\r\n }\r\n\r\n /**\r\n * Generate locales.ts (only if there are locale files)\r\n * @returns true if file was generated with content\r\n */\r\n private async generateLocales(): Promise<boolean> {\r\n const files = await this.globModule(\"utils/locales\");\r\n if (files.length === 0) return false;\r\n await this.generateImportsFile(files, \"locales.ts\");\r\n return true;\r\n }\r\n\r\n /**\r\n * Generate events.ts (only if there are event files)\r\n * @returns true if file was generated with content\r\n */\r\n private async generateEvents(): Promise<boolean> {\r\n const files = await this.globModuleDirectory(\"events\");\r\n if (files.length === 0) return false;\r\n await this.generateImportsFile(files, \"events.ts\");\r\n return true;\r\n }\r\n\r\n /**\r\n * Generate main.ts (only if there are main files)\r\n * @returns true if file was generated with content\r\n */\r\n private async generateMain(): Promise<boolean> {\r\n const files = await this.globModule(\"main\");\r\n if (files.length === 0) return false;\r\n await this.generateImportsFile(files, \"main.ts\");\r\n return true;\r\n }\r\n\r\n /**\r\n * Generate routes.ts (only if there are route files)\r\n * @returns true if file was generated with content\r\n */\r\n private async generateRoutes(): Promise<boolean> {\r\n const files = await this.globModule(\"routes\");\r\n if (files.length === 0) return false;\r\n await this.generateImportsFile(files, \"routes.ts\");\r\n return true;\r\n }\r\n\r\n /**\r\n * Generate a file with imports from all given files\r\n */\r\n private async generateImportsFile(importPaths: string[], outputFile: string): Promise<void> {\r\n const imports = importPaths.map((importPath) => `import \"${importPath}\";`);\r\n const content = imports.join(\"\\n\") + \"\\n\";\r\n await putFileAsync(path.join(this.productionDir, outputFile), content);\r\n }\r\n\r\n /**\r\n * Generate the main entry point (app.ts)\r\n */\r\n private async generateEntryPoint(): Promise<void> {\r\n console.log(colors.yellow(\" Generating entry point...\"));\r\n\r\n // Build imports based on which files were generated\r\n const imports: string[] = [\r\n \"// 1. Bootstrap (loads .env, initializes framework)\",\r\n 'import \"./bootstrap\";',\r\n \"\",\r\n \"// 2. Load configs\",\r\n 'import \"./config-loader\";',\r\n \"\",\r\n \"// 3. Start early-phase connectors (database, cache, logger, ...)\",\r\n \"// so data sources, cache, etc. are ready before app code runs\",\r\n 'import { Application, connectorsManager, ConnectorLifecyclePhase } from \"@warlock.js/core\";',\r\n \"await connectorsManager.startPhase(ConnectorLifecyclePhase.Early);\",\r\n ];\r\n\r\n // App code uses dynamic `await import(...)` so each module's side\r\n // effects fire at THIS point in execution. Static imports would be\r\n // hoisted to module-instantiation time (before the early-phase await\r\n // resolves), which is exactly the bug this split is meant to fix.\r\n //\r\n // The guarantee comes from the imports being DYNAMIC — esbuild wraps a\r\n // dynamically-imported module in its `__esm(() => {…})` helper and runs\r\n // it at the await, not at instantiation. It does NOT come from\r\n // `splitting: true`, which only decides one-file-vs-chunks. This\r\n // previously said splitting was required; it is not, and `singleBundle`\r\n // (splitting: false) preserves the ordering.\r\n imports.push(\"\", \"// 4. Load app code (events, locales, main, routes)\");\r\n\r\n if (this.generatedFiles.events) {\r\n imports.push('await import(\"./events\");');\r\n }\r\n if (this.generatedFiles.locales) {\r\n imports.push('await import(\"./locales\");');\r\n }\r\n if (this.generatedFiles.main) {\r\n imports.push('await import(\"./main\");');\r\n }\r\n if (this.generatedFiles.routes) {\r\n imports.push('await import(\"./routes\");');\r\n }\r\n\r\n // Start late-phase connectors after app code registers routes/listeners\r\n imports.push(\r\n \"\",\r\n \"// 5. Start late-phase connectors (http, socket) — routes and\",\r\n \"// listeners registered by app code are now ready to bind\",\r\n \"await connectorsManager.startPhase(ConnectorLifecyclePhase.Late);\",\r\n \"\",\r\n \"// 6. Signal a complete boot so `Application.onceBooted(...)` listeners fire\",\r\n \"Application.markBooted({ environment: Application.environment, runtimeStrategy: Application.runtimeStrategy });\",\r\n \"connectorsManager.shutdownOnProcessKill();\",\r\n );\r\n\r\n const content = imports.join(\"\\n\") + \"\\n\";\r\n await putFileAsync(path.join(this.productionDir, \"app.ts\"), content);\r\n }\r\n\r\n /**\r\n * Bundle with esbuild\r\n */\r\n private async bundle(): Promise<void> {\r\n console.log(colors.magenta(\" Bundling with esbuild...\"));\r\n\r\n const entryPoint = path.join(this.productionDir, \"app.ts\");\r\n const outDir = this.options.outdir!;\r\n const outFileName = this.options.outFile!;\r\n // Strip extension so entryNames produces \"<base>.js\" via esbuild\r\n const entryName = path.basename(outFileName, path.extname(outFileName));\r\n\r\n // `singleBundle` and `esmShim` are ours, not esbuild's — it throws on\r\n // unknown keys, and the user options are spread into its call verbatim.\r\n const singleBundle = this.options.singleBundle === true;\r\n const esmShim = this.options.esmShim !== false;\r\n // Read before deleting: the merged banner is applied AFTER the user\r\n // spread, so a user banner must not be lost to it or clobber the shim.\r\n const userBanner = this.options.banner;\r\n\r\n delete this.options.outFile;\r\n delete this.options.entryPath;\r\n delete this.options.singleBundle;\r\n delete this.options.esmShim;\r\n delete this.options.banner;\r\n\r\n await ensureDirectoryAsync(outDir);\r\n\r\n const alias = this.buildAliasMapFromTsconfig();\r\n\r\n // The user can override `format`, so gate the shim on the EFFECTIVE\r\n // format rather than on the default below. A CJS build already has\r\n // `require` and friends; injecting them there would be a redefinition.\r\n const isEsm = (this.options.format ?? \"esm\") === \"esm\";\r\n const banner = mergeBanner(userBanner, esmShim && isEsm ? ESM_INTEROP_SHIM : undefined);\r\n\r\n if (singleBundle) {\r\n console.log(\r\n colors.magenta(\r\n \" Single-bundle mode — one JS file\" +\r\n (esmShim && isEsm ? \" with the ESM interop shim\" : \"\") +\r\n \". Native .node addons are still emitted alongside it.\",\r\n ),\r\n );\r\n }\r\n\r\n\r\n try {\r\n \r\n await esbuild.build({\r\n platform: \"node\",\r\n entryPoints: [entryPoint],\r\n bundle: true,\r\n // Both are DEFAULTS the user can override — they sit before the\r\n // `...this.options` spread deliberately. `singleBundle` moves them,\r\n // an explicit `splitting`/`packages` in warlock.config.ts beats both.\r\n //\r\n // Phase ordering does not depend on `splitting`: it comes from the\r\n // generated app.ts using dynamic `await import(...)` (see\r\n // generateAppEntry above), which esbuild defers to the call site in\r\n // either mode. Splitting only decides one file vs chunks.\r\n splitting: !singleBundle,\r\n packages: singleBundle ? \"bundle\" : \"external\",\r\n minify: this.options!.minify,\r\n sourcemap: this.options!.sourcemap === true ? \"linked\" : this.options!.sourcemap,\r\n format: \"esm\",\r\n // Targeting a concrete Node version (not \"esnext\") so esbuild\r\n // transpiles TC39 stage 3 decorators into helpers — Node does not\r\n // implement them natively yet.\r\n target: [\"node22\"],\r\n outdir: outDir,\r\n entryNames: entryName,\r\n alias,\r\n plugins: [nativeNodeModulesPlugin],\r\n ...(this.options as any),\r\n // AFTER the spread, and intentionally so: `banner` is an object, and\r\n // both the config merge and this spread REPLACE it wholesale rather\r\n // than merging. Left as a default above, any user banner would delete\r\n // the shim; left to the spread, the shim would delete theirs. The\r\n // merge is the only form that keeps both.\r\n ...(banner ? { banner } : {}),\r\n });\r\n } catch (e) {\r\n console.log(e);\r\n throw e;\r\n }\r\n }\r\n\r\n /**\r\n * Build an alias map from tsconfig `paths` so esbuild resolves local\r\n * source aliases (e.g. `@warlock.js/cascade`) to their on-disk source\r\n * folders during bundling. Without this, `packages: \"external\"` would\r\n * leave those bare specifiers as raw imports and Node would fail to\r\n * resolve them at runtime (they aren't installed in node_modules).\r\n *\r\n * Only exact (non-wildcard) aliases are included — esbuild's `alias`\r\n * option doesn't support glob-style mappings.\r\n */\r\n private buildAliasMapFromTsconfig(): Record<string, string> {\r\n tsconfigManager.init();\r\n\r\n const alias: Record<string, string> = {};\r\n const baseUrl = path.resolve(process.cwd(), tsconfigManager.baseUrl);\r\n\r\n for (const [from, to] of Object.entries(tsconfigManager.aliases)) {\r\n if (from.endsWith(\"/*\") || !Array.isArray(to) || to.length === 0) {\r\n continue;\r\n }\r\n\r\n alias[from] = path.resolve(baseUrl, to[0]);\r\n }\r\n\r\n return alias;\r\n }\r\n}\r\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
- import { warlockConfigManager } from "../warlock-config/warlock-config.manager.mjs";
2
1
  import { defaultWarlockConfigurations } from "../warlock-config/default-configurations.mjs";
3
2
  import { normalizeBuildConfig } from "../warlock-config/normalize-build-config.mjs";
3
+ import { warlockConfigManager } from "../warlock-config/warlock-config.manager.mjs";
4
4
  import path from "path";
5
5
 
6
6
  //#region ../core/src/production/resolve-build-config.ts
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-build-config.mjs","names":[],"sources":["../../../../../../../core/src/production/resolve-build-config.ts"],"sourcesContent":["import path from \"path\";\nimport { defaultWarlockConfigurations } from \"../warlock-config/default-configurations\";\nimport { normalizeBuildConfig } from \"../warlock-config/normalize-build-config\";\nimport type { WarlockConfig } from \"../warlock-config/types\";\nimport { warlockConfigManager } from \"../warlock-config/warlock-config.manager\";\n\nexport type ResolvedBuildConfig = Required<\n Omit<NonNullable<WarlockConfig[\"build\"]>, \"outDirectory\">\n> & {\n /** Absolute path to the bundled entry file (`{outdir}/{outFile}`) */\n entryPath: string;\n};\n\n/**\n * Resolve the build config with framework defaults applied.\n *\n * Both the production builder and `warlock start` call this so they\n * agree on where the bundle lives — previously each had its own local\n * fallbacks and they drifted (`.warlock/production` vs `dist`),\n * letting `build` and `start` look at different paths.\n */\nexport function resolveBuildConfig(): ResolvedBuildConfig {\n // Normalised here rather than only in `defineConfig` because a project may\n // export a plain config object that never went through it.\n const userBuild = normalizeBuildConfig(warlockConfigManager.get(\"build\") ?? {});\n const defaults = defaultWarlockConfigurations.build!;\n const merged = { ...defaults, ...userBuild } as ResolvedBuildConfig;\n\n return {\n ...merged,\n entryPath: path.resolve(merged.outdir, merged.outFile),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;AAqBA,SAAgB,qBAA0C;CAGxD,MAAM,YAAY,qBAAqB,qBAAqB,IAAI,OAAO,KAAK,CAAC,CAAC;CAE9E,MAAM,SAAS;EAAE,GADA,6BAA6B;EAChB,GAAG;CAAU;CAE3C,OAAO;EACL,GAAG;EACH,WAAW,KAAK,QAAQ,OAAO,QAAQ,OAAO,OAAO;CACvD;AACF"}
1
+ {"version":3,"file":"resolve-build-config.mjs","names":[],"sources":["../../../../../../../core/src/production/resolve-build-config.ts"],"sourcesContent":["import path from \"path\";\nimport { defaultWarlockConfigurations } from \"../warlock-config/default-configurations\";\nimport { normalizeBuildConfig } from \"../warlock-config/normalize-build-config\";\nimport type { WarlockConfig } from \"../warlock-config/types\";\nimport { warlockConfigManager } from \"../warlock-config/warlock-config.manager\";\n\n/**\n * Keys the builder deletes before handing the options to esbuild — ours\n * (`singleBundle`, `esmShim`), which esbuild would reject as unknown, and\n * `banner`, which is re-merged and re-applied after the user spread.\n *\n * They are optional here for a concrete reason: `Required<…>` makes `delete`\n * a type error (TS2790). Naming exactly these three says which keys are\n * removable, rather than casting at each `delete` — a cast there would also\n * hide a genuine mistake.\n *\n * `outFile` and `entryPath` stay REQUIRED even though the builder deletes\n * them too. They are always present after resolution and callers depend on\n * that; widening them to `string | undefined` pushed the lie downstream into\n * `start-production.command.ts`, which then could not trust its own config.\n */\ntype BuilderStrippedKeys = \"singleBundle\" | \"esmShim\" | \"banner\";\n\nexport type ResolvedBuildConfig = Required<\n Omit<NonNullable<WarlockConfig[\"build\"]>, \"outDirectory\" | BuilderStrippedKeys>\n> &\n Partial<Pick<NonNullable<WarlockConfig[\"build\"]>, BuilderStrippedKeys>> & {\n /** Absolute path to the bundled entry file (`{outdir}/{outFile}`) */\n entryPath: string;\n };\n\n/**\n * Resolve the build config with framework defaults applied.\n *\n * Both the production builder and `warlock start` call this so they\n * agree on where the bundle lives — previously each had its own local\n * fallbacks and they drifted (`.warlock/production` vs `dist`),\n * letting `build` and `start` look at different paths.\n */\nexport function resolveBuildConfig(): ResolvedBuildConfig {\n // Normalised here rather than only in `defineConfig` because a project may\n // export a plain config object that never went through it.\n const userBuild = normalizeBuildConfig(warlockConfigManager.get(\"build\") ?? {});\n const defaults = defaultWarlockConfigurations.build!;\n const merged = { ...defaults, ...userBuild } as ResolvedBuildConfig;\n\n return {\n ...merged,\n entryPath: path.resolve(merged.outdir, merged.outFile),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;AAuCA,SAAgB,qBAA0C;CAGxD,MAAM,YAAY,qBAAqB,qBAAqB,IAAI,OAAO,KAAK,CAAC,CAAC;CAE9E,MAAM,SAAS;EAAE,GADA,6BAA6B;EAChB,GAAG;CAAU;CAE3C,OAAO;EACL,GAAG;EACH,WAAW,KAAK,QAAQ,OAAO,QAAQ,OAAO,OAAO;CACvD;AACF"}
@@ -10,6 +10,15 @@ declare class Router {
10
10
  * Routes list
11
11
  */
12
12
  private routes;
13
+ /**
14
+ * Bumped on every mutation of {@link routes}.
15
+ *
16
+ * The dev dispatcher caches a route registry and needs to know when it is
17
+ * stale. Comparing `routes.length` would miss an HMR reload that replaces a
18
+ * route without changing the count — the registry would then keep matching
19
+ * paths that no longer exist. A version counter cannot miss that.
20
+ */
21
+ private routesVersion;
13
22
  /**
14
23
  * Router Instance
15
24
  */
@@ -1 +1 @@
1
- {"version":3,"file":"router.d.mts","names":[],"sources":["../../../../../../../core/src/router/router.ts"],"mappings":"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"}
1
+ {"version":3,"file":"router.d.mts","names":[],"sources":["../../../../../../../core/src/router/router.ts"],"mappings":"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"}