@warlock.js/core 4.0.30 → 4.0.39

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 (703) hide show
  1. package/esm/cli/index.js +2 -1
  2. package/esm/cli/index.js.map +1 -1
  3. package/esm/cli/start.js +132 -2
  4. package/esm/cli/start.js.map +1 -1
  5. package/esm/index.js +72 -1
  6. package/esm/index.js.map +1 -1
  7. package/package.json +71 -65
  8. package/esm/application.d.ts +0 -27
  9. package/esm/application.d.ts.map +0 -1
  10. package/esm/bootstrap/setup.d.ts +0 -7
  11. package/esm/bootstrap/setup.d.ts.map +0 -1
  12. package/esm/bootstrap/setup.js +0 -38
  13. package/esm/bootstrap/setup.js.map +0 -1
  14. package/esm/bootstrap.d.ts +0 -2
  15. package/esm/bootstrap.d.ts.map +0 -1
  16. package/esm/bootstrap.js +0 -5
  17. package/esm/bootstrap.js.map +0 -1
  18. package/esm/cache/database-cache-driver.d.ts +0 -56
  19. package/esm/cache/database-cache-driver.d.ts.map +0 -1
  20. package/esm/cache/database-cache-driver.js +0 -96
  21. package/esm/cache/database-cache-driver.js.map +0 -1
  22. package/esm/cache/index.d.ts +0 -3
  23. package/esm/cache/index.d.ts.map +0 -1
  24. package/esm/cache/index.js +0 -1
  25. package/esm/cache/index.js.map +0 -1
  26. package/esm/cli/cli-command.d.ts +0 -115
  27. package/esm/cli/cli-command.d.ts.map +0 -1
  28. package/esm/cli/cli-command.js +0 -224
  29. package/esm/cli/cli-command.js.map +0 -1
  30. package/esm/cli/cli-commands.manager.d.ts +0 -71
  31. package/esm/cli/cli-commands.manager.d.ts.map +0 -1
  32. package/esm/cli/cli-commands.manager.js +0 -345
  33. package/esm/cli/cli-commands.manager.js.map +0 -1
  34. package/esm/cli/cli-commands.utils.d.ts +0 -68
  35. package/esm/cli/cli-commands.utils.d.ts.map +0 -1
  36. package/esm/cli/cli-commands.utils.js +0 -182
  37. package/esm/cli/cli-commands.utils.js.map +0 -1
  38. package/esm/cli/commands/build.command.d.ts +0 -2
  39. package/esm/cli/commands/build.command.d.ts.map +0 -1
  40. package/esm/cli/commands/build.command.js +0 -8
  41. package/esm/cli/commands/build.command.js.map +0 -1
  42. package/esm/cli/commands/dev-server.command.d.ts +0 -2
  43. package/esm/cli/commands/dev-server.command.d.ts.map +0 -1
  44. package/esm/cli/commands/dev-server.command.js +0 -16
  45. package/esm/cli/commands/dev-server.command.js.map +0 -1
  46. package/esm/cli/commands/start-production.command.d.ts +0 -2
  47. package/esm/cli/commands/start-production.command.d.ts.map +0 -1
  48. package/esm/cli/commands/start-production.command.js +0 -65
  49. package/esm/cli/commands/start-production.command.js.map +0 -1
  50. package/esm/cli/commands/typings-generator.command.d.ts +0 -2
  51. package/esm/cli/commands/typings-generator.command.d.ts.map +0 -1
  52. package/esm/cli/commands/typings-generator.command.js +0 -40
  53. package/esm/cli/commands/typings-generator.command.js.map +0 -1
  54. package/esm/cli/commands-loader.d.ts +0 -18
  55. package/esm/cli/commands-loader.d.ts.map +0 -1
  56. package/esm/cli/commands-loader.js +0 -45
  57. package/esm/cli/commands-loader.js.map +0 -1
  58. package/esm/cli/framework-cli-commands.d.ts +0 -2
  59. package/esm/cli/framework-cli-commands.d.ts.map +0 -1
  60. package/esm/cli/framework-cli-commands.js +0 -6
  61. package/esm/cli/framework-cli-commands.js.map +0 -1
  62. package/esm/cli/index.d.ts +0 -3
  63. package/esm/cli/index.d.ts.map +0 -1
  64. package/esm/cli/parse-cli-args.d.ts +0 -18
  65. package/esm/cli/parse-cli-args.d.ts.map +0 -1
  66. package/esm/cli/parse-cli-args.js +0 -82
  67. package/esm/cli/parse-cli-args.js.map +0 -1
  68. package/esm/cli/start.d.ts +0 -2
  69. package/esm/cli/start.d.ts.map +0 -1
  70. package/esm/cli/string-similarity.d.ts +0 -44
  71. package/esm/cli/string-similarity.d.ts.map +0 -1
  72. package/esm/cli/string-similarity.js +0 -57
  73. package/esm/cli/string-similarity.js.map +0 -1
  74. package/esm/cli/types.d.ts +0 -201
  75. package/esm/cli/types.d.ts.map +0 -1
  76. package/esm/config/config-getter.d.ts +0 -35
  77. package/esm/config/config-getter.d.ts.map +0 -1
  78. package/esm/config/config-getter.js +0 -21
  79. package/esm/config/config-getter.js.map +0 -1
  80. package/esm/config/config-handlers.d.ts +0 -19
  81. package/esm/config/config-handlers.d.ts.map +0 -1
  82. package/esm/config/config-handlers.js +0 -47
  83. package/esm/config/config-handlers.js.map +0 -1
  84. package/esm/config/config-loader.d.ts +0 -37
  85. package/esm/config/config-loader.d.ts.map +0 -1
  86. package/esm/config/config-loader.js +0 -83
  87. package/esm/config/config-loader.js.map +0 -1
  88. package/esm/config/config-manager.d.ts +0 -22
  89. package/esm/config/config-manager.d.ts.map +0 -1
  90. package/esm/config/config-manager.js +0 -25
  91. package/esm/config/config-manager.js.map +0 -1
  92. package/esm/config/config-special-handlers.d.ts +0 -17
  93. package/esm/config/config-special-handlers.d.ts.map +0 -1
  94. package/esm/config/config-special-handlers.js +0 -23
  95. package/esm/config/config-special-handlers.js.map +0 -1
  96. package/esm/config/index.d.ts +0 -5
  97. package/esm/config/index.d.ts.map +0 -1
  98. package/esm/config/load-config-files.d.ts +0 -6
  99. package/esm/config/load-config-files.d.ts.map +0 -1
  100. package/esm/config/load-config-files.js +0 -19
  101. package/esm/config/load-config-files.js.map +0 -1
  102. package/esm/config/types.d.ts +0 -52
  103. package/esm/config/types.d.ts.map +0 -1
  104. package/esm/database/decorators/index.d.ts +0 -2
  105. package/esm/database/decorators/index.d.ts.map +0 -1
  106. package/esm/database/decorators/sluggable.d.ts +0 -2
  107. package/esm/database/decorators/sluggable.d.ts.map +0 -1
  108. package/esm/database/decorators/sluggable.js +0 -8
  109. package/esm/database/decorators/sluggable.js.map +0 -1
  110. package/esm/database/index.d.ts +0 -3
  111. package/esm/database/index.d.ts.map +0 -1
  112. package/esm/database/models/database-log/database-log.d.ts +0 -13
  113. package/esm/database/models/database-log/database-log.d.ts.map +0 -1
  114. package/esm/database/models/database-log/database-log.js +0 -16
  115. package/esm/database/models/database-log/database-log.js.map +0 -1
  116. package/esm/database/models/database-log/index.d.ts +0 -2
  117. package/esm/database/models/database-log/index.d.ts.map +0 -1
  118. package/esm/dev2-server/config-handlers.d.ts +0 -8
  119. package/esm/dev2-server/config-handlers.d.ts.map +0 -1
  120. package/esm/dev2-server/config-loader.d.ts +0 -61
  121. package/esm/dev2-server/config-loader.d.ts.map +0 -1
  122. package/esm/dev2-server/connectors/base-connector.d.ts +0 -49
  123. package/esm/dev2-server/connectors/base-connector.d.ts.map +0 -1
  124. package/esm/dev2-server/connectors/base-connector.js +0 -48
  125. package/esm/dev2-server/connectors/base-connector.js.map +0 -1
  126. package/esm/dev2-server/connectors/cache-connector.d.ts +0 -23
  127. package/esm/dev2-server/connectors/cache-connector.d.ts.map +0 -1
  128. package/esm/dev2-server/connectors/cache-connector.js +0 -35
  129. package/esm/dev2-server/connectors/cache-connector.js.map +0 -1
  130. package/esm/dev2-server/connectors/connectors-manager.d.ts +0 -38
  131. package/esm/dev2-server/connectors/connectors-manager.d.ts.map +0 -1
  132. package/esm/dev2-server/connectors/connectors-manager.js +0 -80
  133. package/esm/dev2-server/connectors/connectors-manager.js.map +0 -1
  134. package/esm/dev2-server/connectors/database-connector.d.ts +0 -23
  135. package/esm/dev2-server/connectors/database-connector.d.ts.map +0 -1
  136. package/esm/dev2-server/connectors/database-connector.js +0 -42
  137. package/esm/dev2-server/connectors/database-connector.js.map +0 -1
  138. package/esm/dev2-server/connectors/http-connector.d.ts +0 -29
  139. package/esm/dev2-server/connectors/http-connector.d.ts.map +0 -1
  140. package/esm/dev2-server/connectors/http-connector.js +0 -69
  141. package/esm/dev2-server/connectors/http-connector.js.map +0 -1
  142. package/esm/dev2-server/connectors/index.d.ts +0 -11
  143. package/esm/dev2-server/connectors/index.d.ts.map +0 -1
  144. package/esm/dev2-server/connectors/types.d.ts +0 -49
  145. package/esm/dev2-server/connectors/types.d.ts.map +0 -1
  146. package/esm/dev2-server/connectors/types.js +0 -9
  147. package/esm/dev2-server/connectors/types.js.map +0 -1
  148. package/esm/dev2-server/create-worker.d.ts +0 -34
  149. package/esm/dev2-server/create-worker.d.ts.map +0 -1
  150. package/esm/dev2-server/create-worker.js +0 -37
  151. package/esm/dev2-server/create-worker.js.map +0 -1
  152. package/esm/dev2-server/dependency-graph.d.ts +0 -93
  153. package/esm/dev2-server/dependency-graph.d.ts.map +0 -1
  154. package/esm/dev2-server/dependency-graph.js +0 -266
  155. package/esm/dev2-server/dependency-graph.js.map +0 -1
  156. package/esm/dev2-server/dev-logger.d.ts +0 -14
  157. package/esm/dev2-server/dev-logger.d.ts.map +0 -1
  158. package/esm/dev2-server/dev-logger.js +0 -130
  159. package/esm/dev2-server/dev-logger.js.map +0 -1
  160. package/esm/dev2-server/development-server.d.ts +0 -47
  161. package/esm/dev2-server/development-server.d.ts.map +0 -1
  162. package/esm/dev2-server/development-server.js +0 -135
  163. package/esm/dev2-server/development-server.js.map +0 -1
  164. package/esm/dev2-server/events.d.ts +0 -5
  165. package/esm/dev2-server/events.d.ts.map +0 -1
  166. package/esm/dev2-server/events.js +0 -4
  167. package/esm/dev2-server/events.js.map +0 -1
  168. package/esm/dev2-server/file-event-handler.d.ts +0 -156
  169. package/esm/dev2-server/file-event-handler.d.ts.map +0 -1
  170. package/esm/dev2-server/file-event-handler.js +0 -300
  171. package/esm/dev2-server/file-event-handler.js.map +0 -1
  172. package/esm/dev2-server/file-manager.d.ts +0 -385
  173. package/esm/dev2-server/file-manager.d.ts.map +0 -1
  174. package/esm/dev2-server/file-manager.js +0 -580
  175. package/esm/dev2-server/file-manager.js.map +0 -1
  176. package/esm/dev2-server/file-operations.d.ts +0 -203
  177. package/esm/dev2-server/file-operations.d.ts.map +0 -1
  178. package/esm/dev2-server/file-operations.js +0 -365
  179. package/esm/dev2-server/file-operations.js.map +0 -1
  180. package/esm/dev2-server/files-orchestrator.d.ts +0 -146
  181. package/esm/dev2-server/files-orchestrator.d.ts.map +0 -1
  182. package/esm/dev2-server/files-orchestrator.js +0 -314
  183. package/esm/dev2-server/files-orchestrator.js.map +0 -1
  184. package/esm/dev2-server/files-watcher.d.ts +0 -67
  185. package/esm/dev2-server/files-watcher.d.ts.map +0 -1
  186. package/esm/dev2-server/files-watcher.js +0 -95
  187. package/esm/dev2-server/files-watcher.js.map +0 -1
  188. package/esm/dev2-server/flags.d.ts +0 -10
  189. package/esm/dev2-server/flags.d.ts.map +0 -1
  190. package/esm/dev2-server/flags.js +0 -9
  191. package/esm/dev2-server/flags.js.map +0 -1
  192. package/esm/dev2-server/health-checker/checkers/base-health-checker.d.ts +0 -52
  193. package/esm/dev2-server/health-checker/checkers/base-health-checker.d.ts.map +0 -1
  194. package/esm/dev2-server/health-checker/checkers/base-health-checker.js +0 -71
  195. package/esm/dev2-server/health-checker/checkers/base-health-checker.js.map +0 -1
  196. package/esm/dev2-server/health-checker/checkers/eslint-health-checker.d.ts +0 -40
  197. package/esm/dev2-server/health-checker/checkers/eslint-health-checker.d.ts.map +0 -1
  198. package/esm/dev2-server/health-checker/checkers/eslint-health-checker.js +0 -217
  199. package/esm/dev2-server/health-checker/checkers/eslint-health-checker.js.map +0 -1
  200. package/esm/dev2-server/health-checker/checkers/typescript-health-checker.d.ts +0 -56
  201. package/esm/dev2-server/health-checker/checkers/typescript-health-checker.d.ts.map +0 -1
  202. package/esm/dev2-server/health-checker/checkers/typescript-health-checker.js +0 -279
  203. package/esm/dev2-server/health-checker/checkers/typescript-health-checker.js.map +0 -1
  204. package/esm/dev2-server/health-checker/file-health-checker.contract.d.ts +0 -59
  205. package/esm/dev2-server/health-checker/file-health-checker.contract.d.ts.map +0 -1
  206. package/esm/dev2-server/health-checker/file-health-result.d.ts +0 -68
  207. package/esm/dev2-server/health-checker/file-health-result.d.ts.map +0 -1
  208. package/esm/dev2-server/health-checker/file-health-result.js +0 -40
  209. package/esm/dev2-server/health-checker/file-health-result.js.map +0 -1
  210. package/esm/dev2-server/health-checker/files-healthcare.manager.d.ts +0 -115
  211. package/esm/dev2-server/health-checker/files-healthcare.manager.d.ts.map +0 -1
  212. package/esm/dev2-server/health-checker/files-healthcare.manager.js +0 -422
  213. package/esm/dev2-server/health-checker/files-healthcare.manager.js.map +0 -1
  214. package/esm/dev2-server/health-checker/index.d.ts +0 -6
  215. package/esm/dev2-server/health-checker/index.d.ts.map +0 -1
  216. package/esm/dev2-server/health-checker/workers/eslint-health.worker.d.ts +0 -2
  217. package/esm/dev2-server/health-checker/workers/eslint-health.worker.d.ts.map +0 -1
  218. package/esm/dev2-server/health-checker/workers/eslint-health.worker.js +0 -214
  219. package/esm/dev2-server/health-checker/workers/eslint-health.worker.js.map +0 -1
  220. package/esm/dev2-server/health-checker/workers/ts-health.worker.d.ts +0 -2
  221. package/esm/dev2-server/health-checker/workers/ts-health.worker.d.ts.map +0 -1
  222. package/esm/dev2-server/health-checker/workers/ts-health.worker.js +0 -261
  223. package/esm/dev2-server/health-checker/workers/ts-health.worker.js.map +0 -1
  224. package/esm/dev2-server/import-transformer.d.ts +0 -17
  225. package/esm/dev2-server/import-transformer.d.ts.map +0 -1
  226. package/esm/dev2-server/import-transformer.js +0 -236
  227. package/esm/dev2-server/import-transformer.js.map +0 -1
  228. package/esm/dev2-server/index.d.ts +0 -1
  229. package/esm/dev2-server/index.d.ts.map +0 -1
  230. package/esm/dev2-server/layer-executor.d.ts +0 -60
  231. package/esm/dev2-server/layer-executor.d.ts.map +0 -1
  232. package/esm/dev2-server/layer-executor.js +0 -309
  233. package/esm/dev2-server/layer-executor.js.map +0 -1
  234. package/esm/dev2-server/manifest-manager.d.ts +0 -80
  235. package/esm/dev2-server/manifest-manager.d.ts.map +0 -1
  236. package/esm/dev2-server/manifest-manager.js +0 -107
  237. package/esm/dev2-server/manifest-manager.js.map +0 -1
  238. package/esm/dev2-server/module-loader.d.ts +0 -104
  239. package/esm/dev2-server/module-loader.d.ts.map +0 -1
  240. package/esm/dev2-server/module-loader.js +0 -251
  241. package/esm/dev2-server/module-loader.js.map +0 -1
  242. package/esm/dev2-server/package-json-manager.d.ts +0 -16
  243. package/esm/dev2-server/package-json-manager.d.ts.map +0 -1
  244. package/esm/dev2-server/package-json-manager.js +0 -20
  245. package/esm/dev2-server/package-json-manager.js.map +0 -1
  246. package/esm/dev2-server/parse-imports.d.ts +0 -13
  247. package/esm/dev2-server/parse-imports.d.ts.map +0 -1
  248. package/esm/dev2-server/parse-imports.js +0 -329
  249. package/esm/dev2-server/parse-imports.js.map +0 -1
  250. package/esm/dev2-server/path.d.ts +0 -39
  251. package/esm/dev2-server/path.d.ts.map +0 -1
  252. package/esm/dev2-server/path.js +0 -56
  253. package/esm/dev2-server/path.js.map +0 -1
  254. package/esm/dev2-server/runtime-import-helper.d.ts +0 -9
  255. package/esm/dev2-server/runtime-import-helper.d.ts.map +0 -1
  256. package/esm/dev2-server/runtime-import-helper.js +0 -150
  257. package/esm/dev2-server/runtime-import-helper.js.map +0 -1
  258. package/esm/dev2-server/special-files-collector.d.ts +0 -114
  259. package/esm/dev2-server/special-files-collector.d.ts.map +0 -1
  260. package/esm/dev2-server/special-files-collector.js +0 -212
  261. package/esm/dev2-server/special-files-collector.js.map +0 -1
  262. package/esm/dev2-server/start-development-server.d.ts +0 -7
  263. package/esm/dev2-server/start-development-server.d.ts.map +0 -1
  264. package/esm/dev2-server/start-development-server.js +0 -21
  265. package/esm/dev2-server/start-development-server.js.map +0 -1
  266. package/esm/dev2-server/transpile-file.d.ts +0 -11
  267. package/esm/dev2-server/transpile-file.d.ts.map +0 -1
  268. package/esm/dev2-server/transpile-file.js +0 -21
  269. package/esm/dev2-server/transpile-file.js.map +0 -1
  270. package/esm/dev2-server/tsconfig-manager.d.ts +0 -45
  271. package/esm/dev2-server/tsconfig-manager.d.ts.map +0 -1
  272. package/esm/dev2-server/tsconfig-manager.js +0 -107
  273. package/esm/dev2-server/tsconfig-manager.js.map +0 -1
  274. package/esm/dev2-server/type-generator.d.ts +0 -115
  275. package/esm/dev2-server/type-generator.d.ts.map +0 -1
  276. package/esm/dev2-server/type-generator.js +0 -566
  277. package/esm/dev2-server/type-generator.js.map +0 -1
  278. package/esm/dev2-server/types.d.ts +0 -30
  279. package/esm/dev2-server/types.d.ts.map +0 -1
  280. package/esm/dev2-server/utils.d.ts +0 -15
  281. package/esm/dev2-server/utils.d.ts.map +0 -1
  282. package/esm/dev2-server/utils.js +0 -40
  283. package/esm/dev2-server/utils.js.map +0 -1
  284. package/esm/http/config.d.ts +0 -10
  285. package/esm/http/config.d.ts.map +0 -1
  286. package/esm/http/config.js +0 -22
  287. package/esm/http/config.js.map +0 -1
  288. package/esm/http/createHttpApplication.d.ts +0 -3
  289. package/esm/http/createHttpApplication.d.ts.map +0 -1
  290. package/esm/http/createHttpApplication.js +0 -28
  291. package/esm/http/createHttpApplication.js.map +0 -1
  292. package/esm/http/database/RequestLog.d.ts +0 -13
  293. package/esm/http/database/RequestLog.d.ts.map +0 -1
  294. package/esm/http/database/RequestLog.js +0 -25
  295. package/esm/http/database/RequestLog.js.map +0 -1
  296. package/esm/http/errors/index.d.ts +0 -2
  297. package/esm/http/errors/index.d.ts.map +0 -1
  298. package/esm/http/errors/resource-not-found.error.d.ts +0 -21
  299. package/esm/http/errors/resource-not-found.error.d.ts.map +0 -1
  300. package/esm/http/errors/resource-not-found.error.js +0 -40
  301. package/esm/http/errors/resource-not-found.error.js.map +0 -1
  302. package/esm/http/events.d.ts +0 -4
  303. package/esm/http/events.d.ts.map +0 -1
  304. package/esm/http/events.js +0 -26
  305. package/esm/http/events.js.map +0 -1
  306. package/esm/http/index.d.ts +0 -16
  307. package/esm/http/index.d.ts.map +0 -1
  308. package/esm/http/middleware/cache-response-middleware.d.ts +0 -34
  309. package/esm/http/middleware/cache-response-middleware.d.ts.map +0 -1
  310. package/esm/http/middleware/cache-response-middleware.js +0 -45
  311. package/esm/http/middleware/cache-response-middleware.js.map +0 -1
  312. package/esm/http/middleware/index.d.ts +0 -3
  313. package/esm/http/middleware/index.d.ts.map +0 -1
  314. package/esm/http/middleware/inject-request-context.d.ts +0 -35
  315. package/esm/http/middleware/inject-request-context.d.ts.map +0 -1
  316. package/esm/http/middleware/inject-request-context.js +0 -110
  317. package/esm/http/middleware/inject-request-context.js.map +0 -1
  318. package/esm/http/plugins/index.d.ts +0 -3
  319. package/esm/http/plugins/index.d.ts.map +0 -1
  320. package/esm/http/plugins.d.ts +0 -3
  321. package/esm/http/plugins.d.ts.map +0 -1
  322. package/esm/http/plugins.js +0 -39
  323. package/esm/http/plugins.js.map +0 -1
  324. package/esm/http/request-controller.d.ts +0 -11
  325. package/esm/http/request-controller.d.ts.map +0 -1
  326. package/esm/http/request-controller.js +0 -9
  327. package/esm/http/request-controller.js.map +0 -1
  328. package/esm/http/request.d.ts +0 -376
  329. package/esm/http/request.d.ts.map +0 -1
  330. package/esm/http/request.js +0 -729
  331. package/esm/http/request.js.map +0 -1
  332. package/esm/http/response.d.ts +0 -271
  333. package/esm/http/response.d.ts.map +0 -1
  334. package/esm/http/response.js +0 -574
  335. package/esm/http/response.js.map +0 -1
  336. package/esm/http/server.d.ts +0 -8
  337. package/esm/http/server.d.ts.map +0 -1
  338. package/esm/http/server.js +0 -15
  339. package/esm/http/server.js.map +0 -1
  340. package/esm/http/types.d.ts +0 -174
  341. package/esm/http/types.d.ts.map +0 -1
  342. package/esm/http/uploaded-file.d.ts +0 -445
  343. package/esm/http/uploaded-file.d.ts.map +0 -1
  344. package/esm/http/uploaded-file.js +0 -694
  345. package/esm/http/uploaded-file.js.map +0 -1
  346. package/esm/http/uploads-config.d.ts +0 -26
  347. package/esm/http/uploads-config.d.ts.map +0 -1
  348. package/esm/http/uploads-config.js +0 -35
  349. package/esm/http/uploads-config.js.map +0 -1
  350. package/esm/http/uploads-types.d.ts +0 -236
  351. package/esm/http/uploads-types.d.ts.map +0 -1
  352. package/esm/image/image.d.ts +0 -382
  353. package/esm/image/image.d.ts.map +0 -1
  354. package/esm/image/image.js +0 -552
  355. package/esm/image/image.js.map +0 -1
  356. package/esm/image/index.d.ts +0 -2
  357. package/esm/image/index.d.ts.map +0 -1
  358. package/esm/index.d.ts +0 -29
  359. package/esm/index.d.ts.map +0 -1
  360. package/esm/logger/index.d.ts +0 -3
  361. package/esm/logger/index.d.ts.map +0 -1
  362. package/esm/logger/logger.d.ts +0 -3
  363. package/esm/logger/logger.d.ts.map +0 -1
  364. package/esm/logger/logger.js +0 -16
  365. package/esm/logger/logger.js.map +0 -1
  366. package/esm/logger/types.d.ts +0 -39
  367. package/esm/logger/types.d.ts.map +0 -1
  368. package/esm/mail/config.d.ts +0 -83
  369. package/esm/mail/config.d.ts.map +0 -1
  370. package/esm/mail/config.js +0 -152
  371. package/esm/mail/config.js.map +0 -1
  372. package/esm/mail/events.d.ts +0 -96
  373. package/esm/mail/events.d.ts.map +0 -1
  374. package/esm/mail/events.js +0 -123
  375. package/esm/mail/events.js.map +0 -1
  376. package/esm/mail/index.d.ts +0 -10
  377. package/esm/mail/index.d.ts.map +0 -1
  378. package/esm/mail/mail.d.ts +0 -175
  379. package/esm/mail/mail.d.ts.map +0 -1
  380. package/esm/mail/mail.js +0 -286
  381. package/esm/mail/mail.js.map +0 -1
  382. package/esm/mail/mailer-pool.d.ts +0 -26
  383. package/esm/mail/mailer-pool.d.ts.map +0 -1
  384. package/esm/mail/mailer-pool.js +0 -95
  385. package/esm/mail/mailer-pool.js.map +0 -1
  386. package/esm/mail/react-mail.d.ts +0 -6
  387. package/esm/mail/react-mail.d.ts.map +0 -1
  388. package/esm/mail/react-mail.js +0 -25
  389. package/esm/mail/react-mail.js.map +0 -1
  390. package/esm/mail/send-mail.d.ts +0 -33
  391. package/esm/mail/send-mail.d.ts.map +0 -1
  392. package/esm/mail/send-mail.js +0 -309
  393. package/esm/mail/send-mail.js.map +0 -1
  394. package/esm/mail/test-mailbox.d.ts +0 -110
  395. package/esm/mail/test-mailbox.d.ts.map +0 -1
  396. package/esm/mail/test-mailbox.js +0 -143
  397. package/esm/mail/test-mailbox.js.map +0 -1
  398. package/esm/mail/types.d.ts +0 -245
  399. package/esm/mail/types.d.ts.map +0 -1
  400. package/esm/mail/types.js +0 -13
  401. package/esm/mail/types.js.map +0 -1
  402. package/esm/manifest/manifest-manager.d.ts +0 -74
  403. package/esm/manifest/manifest-manager.d.ts.map +0 -1
  404. package/esm/manifest/manifest-manager.js +0 -88
  405. package/esm/manifest/manifest-manager.js.map +0 -1
  406. package/esm/output/index.d.ts +0 -3
  407. package/esm/output/index.d.ts.map +0 -1
  408. package/esm/output/output.d.ts +0 -193
  409. package/esm/output/output.d.ts.map +0 -1
  410. package/esm/output/output.js +0 -599
  411. package/esm/output/output.js.map +0 -1
  412. package/esm/output/types.d.ts +0 -23
  413. package/esm/output/types.d.ts.map +0 -1
  414. package/esm/production/build-app-production.d.ts +0 -6
  415. package/esm/production/build-app-production.d.ts.map +0 -1
  416. package/esm/production/build-app-production.js +0 -8
  417. package/esm/production/build-app-production.js.map +0 -1
  418. package/esm/production/esbuild-plugins.d.ts +0 -5
  419. package/esm/production/esbuild-plugins.d.ts.map +0 -1
  420. package/esm/production/esbuild-plugins.js +0 -23
  421. package/esm/production/esbuild-plugins.js.map +0 -1
  422. package/esm/production/production-builder.d.ts +0 -76
  423. package/esm/production/production-builder.d.ts.map +0 -1
  424. package/esm/production/production-builder.js +0 -245
  425. package/esm/production/production-builder.js.map +0 -1
  426. package/esm/react/index.d.ts +0 -3
  427. package/esm/react/index.d.ts.map +0 -1
  428. package/esm/react/index.js +0 -7
  429. package/esm/react/index.js.map +0 -1
  430. package/esm/repositories/base-repository-manager.d.ts +0 -47
  431. package/esm/repositories/base-repository-manager.d.ts.map +0 -1
  432. package/esm/repositories/base-repository-manager.js +0 -63
  433. package/esm/repositories/base-repository-manager.js.map +0 -1
  434. package/esm/repositories/index.d.ts +0 -8
  435. package/esm/repositories/index.d.ts.map +0 -1
  436. package/esm/repositories/repository-destroyer-manager.d.ts +0 -21
  437. package/esm/repositories/repository-destroyer-manager.d.ts.map +0 -1
  438. package/esm/repositories/repository-destroyer-manager.js +0 -38
  439. package/esm/repositories/repository-destroyer-manager.js.map +0 -1
  440. package/esm/repositories/repository-filler-manager.d.ts +0 -60
  441. package/esm/repositories/repository-filler-manager.d.ts.map +0 -1
  442. package/esm/repositories/repository-filler-manager.js +0 -102
  443. package/esm/repositories/repository-filler-manager.js.map +0 -1
  444. package/esm/repositories/repository-filler.d.ts +0 -26
  445. package/esm/repositories/repository-filler.d.ts.map +0 -1
  446. package/esm/repositories/repository-filler.js +0 -63
  447. package/esm/repositories/repository-filler.js.map +0 -1
  448. package/esm/repositories/repository-list-manager.d.ts +0 -385
  449. package/esm/repositories/repository-list-manager.d.ts.map +0 -1
  450. package/esm/repositories/repository-list-manager.js +0 -812
  451. package/esm/repositories/repository-list-manager.js.map +0 -1
  452. package/esm/repositories/repository-listing.d.ts +0 -82
  453. package/esm/repositories/repository-listing.d.ts.map +0 -1
  454. package/esm/repositories/repository-listing.js +0 -177
  455. package/esm/repositories/repository-listing.js.map +0 -1
  456. package/esm/repositories/repository-manager.d.ts +0 -5
  457. package/esm/repositories/repository-manager.d.ts.map +0 -1
  458. package/esm/repositories/repository-manager.js +0 -2
  459. package/esm/repositories/repository-manager.js.map +0 -1
  460. package/esm/repositories/types.d.ts +0 -114
  461. package/esm/repositories/types.d.ts.map +0 -1
  462. package/esm/repositories/utils.d.ts +0 -3
  463. package/esm/repositories/utils.d.ts.map +0 -1
  464. package/esm/repositories/utils.js +0 -7
  465. package/esm/repositories/utils.js.map +0 -1
  466. package/esm/restful/index.d.ts +0 -2
  467. package/esm/restful/index.d.ts.map +0 -1
  468. package/esm/restful/restful.d.ts +0 -110
  469. package/esm/restful/restful.d.ts.map +0 -1
  470. package/esm/restful/restful.js +0 -317
  471. package/esm/restful/restful.js.map +0 -1
  472. package/esm/router/index.d.ts +0 -4
  473. package/esm/router/index.d.ts.map +0 -1
  474. package/esm/router/route-registry.d.ts +0 -30
  475. package/esm/router/route-registry.d.ts.map +0 -1
  476. package/esm/router/route-registry.js +0 -67
  477. package/esm/router/route-registry.js.map +0 -1
  478. package/esm/router/route.d.ts +0 -34
  479. package/esm/router/route.d.ts.map +0 -1
  480. package/esm/router/router.d.ts +0 -169
  481. package/esm/router/router.d.ts.map +0 -1
  482. package/esm/router/router.js +0 -564
  483. package/esm/router/router.js.map +0 -1
  484. package/esm/router/types.d.ts +0 -258
  485. package/esm/router/types.d.ts.map +0 -1
  486. package/esm/router/utils.d.ts +0 -5
  487. package/esm/router/utils.d.ts.map +0 -1
  488. package/esm/router/utils.js +0 -6
  489. package/esm/router/utils.js.map +0 -1
  490. package/esm/storage/config.d.ts +0 -8
  491. package/esm/storage/config.d.ts.map +0 -1
  492. package/esm/storage/config.js +0 -6
  493. package/esm/storage/config.js.map +0 -1
  494. package/esm/storage/drivers/cloud-driver.d.ts +0 -127
  495. package/esm/storage/drivers/cloud-driver.d.ts.map +0 -1
  496. package/esm/storage/drivers/cloud-driver.js +0 -406
  497. package/esm/storage/drivers/cloud-driver.js.map +0 -1
  498. package/esm/storage/drivers/do-spaces-driver.d.ts +0 -47
  499. package/esm/storage/drivers/do-spaces-driver.d.ts.map +0 -1
  500. package/esm/storage/drivers/do-spaces-driver.js +0 -52
  501. package/esm/storage/drivers/do-spaces-driver.js.map +0 -1
  502. package/esm/storage/drivers/local-driver.d.ts +0 -136
  503. package/esm/storage/drivers/local-driver.d.ts.map +0 -1
  504. package/esm/storage/drivers/local-driver.js +0 -409
  505. package/esm/storage/drivers/local-driver.js.map +0 -1
  506. package/esm/storage/drivers/r2-driver.d.ts +0 -50
  507. package/esm/storage/drivers/r2-driver.d.ts.map +0 -1
  508. package/esm/storage/drivers/r2-driver.js +0 -59
  509. package/esm/storage/drivers/r2-driver.js.map +0 -1
  510. package/esm/storage/drivers/s3-driver.d.ts +0 -32
  511. package/esm/storage/drivers/s3-driver.d.ts.map +0 -1
  512. package/esm/storage/drivers/s3-driver.js +0 -34
  513. package/esm/storage/drivers/s3-driver.js.map +0 -1
  514. package/esm/storage/index.d.ts +0 -12
  515. package/esm/storage/index.d.ts.map +0 -1
  516. package/esm/storage/scoped-storage.d.ts +0 -402
  517. package/esm/storage/scoped-storage.d.ts.map +0 -1
  518. package/esm/storage/scoped-storage.js +0 -488
  519. package/esm/storage/scoped-storage.js.map +0 -1
  520. package/esm/storage/storage-file.d.ts +0 -216
  521. package/esm/storage/storage-file.d.ts.map +0 -1
  522. package/esm/storage/storage-file.js +0 -358
  523. package/esm/storage/storage-file.js.map +0 -1
  524. package/esm/storage/storage.d.ts +0 -582
  525. package/esm/storage/storage.d.ts.map +0 -1
  526. package/esm/storage/storage.js +0 -941
  527. package/esm/storage/storage.js.map +0 -1
  528. package/esm/storage/types.d.ts +0 -728
  529. package/esm/storage/types.d.ts.map +0 -1
  530. package/esm/storage/utils/mime.d.ts +0 -33
  531. package/esm/storage/utils/mime.d.ts.map +0 -1
  532. package/esm/storage/utils/mime.js +0 -45
  533. package/esm/storage/utils/mime.js.map +0 -1
  534. package/esm/store/index.d.ts +0 -25
  535. package/esm/store/index.d.ts.map +0 -1
  536. package/esm/store/index.js +0 -52
  537. package/esm/store/index.js.map +0 -1
  538. package/esm/tests/boot-testing.d.ts +0 -7
  539. package/esm/tests/boot-testing.d.ts.map +0 -1
  540. package/esm/tests/boot-testing.js +0 -23
  541. package/esm/tests/boot-testing.js.map +0 -1
  542. package/esm/tests/create-http-test-application.d.ts +0 -25
  543. package/esm/tests/create-http-test-application.d.ts.map +0 -1
  544. package/esm/tests/create-http-test-application.js +0 -76
  545. package/esm/tests/create-http-test-application.js.map +0 -1
  546. package/esm/tests/http-response-output-test.d.ts +0 -42
  547. package/esm/tests/http-response-output-test.d.ts.map +0 -1
  548. package/esm/tests/http-response-output-test.js +0 -53
  549. package/esm/tests/http-response-output-test.js.map +0 -1
  550. package/esm/tests/http-test-response.d.ts +0 -75
  551. package/esm/tests/http-test-response.d.ts.map +0 -1
  552. package/esm/tests/index.d.ts +0 -4
  553. package/esm/tests/index.d.ts.map +0 -1
  554. package/esm/tests/init-testing.d.ts +0 -7
  555. package/esm/tests/init-testing.d.ts.map +0 -1
  556. package/esm/tests/types.d.ts +0 -10
  557. package/esm/tests/types.d.ts.map +0 -1
  558. package/esm/utils/app-log.d.ts +0 -8
  559. package/esm/utils/app-log.d.ts.map +0 -1
  560. package/esm/utils/app-log.js +0 -7
  561. package/esm/utils/app-log.js.map +0 -1
  562. package/esm/utils/cleanup-temp-files.d.ts +0 -5
  563. package/esm/utils/cleanup-temp-files.d.ts.map +0 -1
  564. package/esm/utils/database-log.d.ts +0 -25
  565. package/esm/utils/database-log.d.ts.map +0 -1
  566. package/esm/utils/database-log.js +0 -44
  567. package/esm/utils/database-log.js.map +0 -1
  568. package/esm/utils/date-output.d.ts +0 -69
  569. package/esm/utils/date-output.d.ts.map +0 -1
  570. package/esm/utils/date-output.js +0 -62
  571. package/esm/utils/date-output.js.map +0 -1
  572. package/esm/utils/date-output.test.d.ts +0 -2
  573. package/esm/utils/date-output.test.d.ts.map +0 -1
  574. package/esm/utils/download-file.d.ts +0 -3
  575. package/esm/utils/download-file.d.ts.map +0 -1
  576. package/esm/utils/environment.d.ts +0 -4
  577. package/esm/utils/environment.d.ts.map +0 -1
  578. package/esm/utils/environment.js +0 -6
  579. package/esm/utils/environment.js.map +0 -1
  580. package/esm/utils/get-localized.d.ts +0 -10
  581. package/esm/utils/get-localized.d.ts.map +0 -1
  582. package/esm/utils/get-localized.js +0 -15
  583. package/esm/utils/get-localized.js.map +0 -1
  584. package/esm/utils/get-localized.test.d.ts +0 -2
  585. package/esm/utils/get-localized.test.d.ts.map +0 -1
  586. package/esm/utils/index.d.ts +0 -13
  587. package/esm/utils/index.d.ts.map +0 -1
  588. package/esm/utils/internal.d.ts +0 -4
  589. package/esm/utils/internal.d.ts.map +0 -1
  590. package/esm/utils/paths.d.ts +0 -55
  591. package/esm/utils/paths.d.ts.map +0 -1
  592. package/esm/utils/paths.js +0 -89
  593. package/esm/utils/paths.js.map +0 -1
  594. package/esm/utils/promise-all-object.d.ts +0 -8
  595. package/esm/utils/promise-all-object.d.ts.map +0 -1
  596. package/esm/utils/promise-all-object.js +0 -12
  597. package/esm/utils/promise-all-object.js.map +0 -1
  598. package/esm/utils/queue.d.ts +0 -49
  599. package/esm/utils/queue.d.ts.map +0 -1
  600. package/esm/utils/queue.js +0 -89
  601. package/esm/utils/queue.js.map +0 -1
  602. package/esm/utils/sleep.d.ts +0 -2
  603. package/esm/utils/sleep.d.ts.map +0 -1
  604. package/esm/utils/sleep.js +0 -3
  605. package/esm/utils/sleep.js.map +0 -1
  606. package/esm/utils/sluggable.d.ts +0 -5
  607. package/esm/utils/sluggable.d.ts.map +0 -1
  608. package/esm/utils/sluggable.js +0 -15
  609. package/esm/utils/sluggable.js.map +0 -1
  610. package/esm/utils/sluggable.test.d.ts +0 -2
  611. package/esm/utils/sluggable.test.d.ts.map +0 -1
  612. package/esm/utils/to-json.d.ts +0 -2
  613. package/esm/utils/to-json.d.ts.map +0 -1
  614. package/esm/utils/to-json.js +0 -26
  615. package/esm/utils/to-json.js.map +0 -1
  616. package/esm/utils/types.d.ts +0 -22
  617. package/esm/utils/types.d.ts.map +0 -1
  618. package/esm/utils/urls.d.ts +0 -21
  619. package/esm/utils/urls.d.ts.map +0 -1
  620. package/esm/utils/urls.js +0 -31
  621. package/esm/utils/urls.js.map +0 -1
  622. package/esm/validation/database/exists-except-current-id.d.ts +0 -7
  623. package/esm/validation/database/exists-except-current-id.d.ts.map +0 -1
  624. package/esm/validation/database/exists-except-current-id.js +0 -23
  625. package/esm/validation/database/exists-except-current-id.js.map +0 -1
  626. package/esm/validation/database/exists-except-current-user.d.ts +0 -7
  627. package/esm/validation/database/exists-except-current-user.d.ts.map +0 -1
  628. package/esm/validation/database/exists-except-current-user.js +0 -25
  629. package/esm/validation/database/exists-except-current-user.js.map +0 -1
  630. package/esm/validation/database/exists.d.ts +0 -7
  631. package/esm/validation/database/exists.d.ts.map +0 -1
  632. package/esm/validation/database/exists.js +0 -21
  633. package/esm/validation/database/exists.js.map +0 -1
  634. package/esm/validation/database/index.d.ts +0 -12
  635. package/esm/validation/database/index.d.ts.map +0 -1
  636. package/esm/validation/database/types.d.ts +0 -68
  637. package/esm/validation/database/types.d.ts.map +0 -1
  638. package/esm/validation/database/unique-except-current-id.d.ts +0 -7
  639. package/esm/validation/database/unique-except-current-id.d.ts.map +0 -1
  640. package/esm/validation/database/unique-except-current-id.js +0 -23
  641. package/esm/validation/database/unique-except-current-id.js.map +0 -1
  642. package/esm/validation/database/unique-except-current-user.d.ts +0 -7
  643. package/esm/validation/database/unique-except-current-user.d.ts.map +0 -1
  644. package/esm/validation/database/unique-except-current-user.js +0 -25
  645. package/esm/validation/database/unique-except-current-user.js.map +0 -1
  646. package/esm/validation/database/unique.d.ts +0 -7
  647. package/esm/validation/database/unique.d.ts.map +0 -1
  648. package/esm/validation/database/unique.js +0 -30
  649. package/esm/validation/database/unique.js.map +0 -1
  650. package/esm/validation/file/file.d.ts +0 -22
  651. package/esm/validation/file/file.d.ts.map +0 -1
  652. package/esm/validation/file/file.js +0 -60
  653. package/esm/validation/file/file.js.map +0 -1
  654. package/esm/validation/file/index.d.ts +0 -6
  655. package/esm/validation/file/index.d.ts.map +0 -1
  656. package/esm/validation/index.d.ts +0 -16
  657. package/esm/validation/index.d.ts.map +0 -1
  658. package/esm/validation/init.d.ts +0 -7
  659. package/esm/validation/init.d.ts.map +0 -1
  660. package/esm/validation/init.js +0 -34
  661. package/esm/validation/init.js.map +0 -1
  662. package/esm/validation/plugins/database-plugin.d.ts +0 -14
  663. package/esm/validation/plugins/database-plugin.d.ts.map +0 -1
  664. package/esm/validation/plugins/database-plugin.js +0 -95
  665. package/esm/validation/plugins/database-plugin.js.map +0 -1
  666. package/esm/validation/plugins/file-plugin.d.ts +0 -11
  667. package/esm/validation/plugins/file-plugin.d.ts.map +0 -1
  668. package/esm/validation/plugins/file-plugin.js +0 -17
  669. package/esm/validation/plugins/file-plugin.js.map +0 -1
  670. package/esm/validation/plugins/index.d.ts +0 -9
  671. package/esm/validation/plugins/index.d.ts.map +0 -1
  672. package/esm/validation/plugins/localized-plugin.d.ts +0 -11
  673. package/esm/validation/plugins/localized-plugin.d.ts.map +0 -1
  674. package/esm/validation/plugins/localized-plugin.js +0 -19
  675. package/esm/validation/plugins/localized-plugin.js.map +0 -1
  676. package/esm/validation/types.d.ts +0 -87
  677. package/esm/validation/types.d.ts.map +0 -1
  678. package/esm/validation/validateAll.d.ts +0 -7
  679. package/esm/validation/validateAll.d.ts.map +0 -1
  680. package/esm/validation/validateAll.js +0 -39
  681. package/esm/validation/validateAll.js.map +0 -1
  682. package/esm/validation/validators/file-validator.d.ts +0 -40
  683. package/esm/validation/validators/file-validator.d.ts.map +0 -1
  684. package/esm/validation/validators/file-validator.js +0 -94
  685. package/esm/validation/validators/file-validator.js.map +0 -1
  686. package/esm/validation/validators/index.d.ts +0 -7
  687. package/esm/validation/validators/index.d.ts.map +0 -1
  688. package/esm/warlock-config/default-configurations.d.ts +0 -3
  689. package/esm/warlock-config/default-configurations.d.ts.map +0 -1
  690. package/esm/warlock-config/default-configurations.js +0 -8
  691. package/esm/warlock-config/default-configurations.js.map +0 -1
  692. package/esm/warlock-config/define-config.d.ts +0 -3
  693. package/esm/warlock-config/define-config.d.ts.map +0 -1
  694. package/esm/warlock-config/define-config.js +0 -3
  695. package/esm/warlock-config/define-config.js.map +0 -1
  696. package/esm/warlock-config/index.d.ts +0 -4
  697. package/esm/warlock-config/index.d.ts.map +0 -1
  698. package/esm/warlock-config/types.d.ts +0 -79
  699. package/esm/warlock-config/types.d.ts.map +0 -1
  700. package/esm/warlock-config/warlock-config.manager.d.ts +0 -83
  701. package/esm/warlock-config/warlock-config.manager.d.ts.map +0 -1
  702. package/esm/warlock-config/warlock-config.manager.js +0 -141
  703. package/esm/warlock-config/warlock-config.manager.js.map +0 -1
package/esm/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
1
+ {"version":3,"sources":["../../../../../../../warlock.js/core/src/config/config-getter.ts","../../../../../../../warlock.js/core/src/utils/app-log.ts","../../../../../../../warlock.js/core/src/database/models/database-log/database-log.ts","../../../../../../../warlock.js/core/src/utils/database-log.ts","../../../../../../../warlock.js/core/src/utils/environment.ts","../../../../../../../warlock.js/core/src/http/context/request-context.ts","../../../../../../../warlock.js/core/src/utils/get-localized.ts","../../../../../../../warlock.js/core/src/utils/paths.ts","../../../../../../../warlock.js/core/src/utils/promise-all-object.ts","../../../../../../../warlock.js/core/src/utils/queue.ts","../../../../../../../warlock.js/core/src/utils/sleep.ts","../../../../../../../warlock.js/core/src/utils/sluggable.ts","../../../../../../../warlock.js/core/src/utils/to-json.ts","../../../../../../../warlock.js/core/src/utils/urls.ts","../../../../../../../warlock.js/core/src/logger/logger.ts","../../../../../../../warlock.js/core/src/mail/config.ts","../../../../../../../warlock.js/core/src/mail/events.ts","../../../../../../../warlock.js/core/src/mail/mailer-pool.ts","../../../../../../../warlock.js/core/src/react/index.ts","../../../../../../../warlock.js/core/src/mail/react-mail.ts","../../../../../../../warlock.js/core/src/mail/test-mailbox.ts","../../../../../../../warlock.js/core/src/mail/types.ts","../../../../../../../warlock.js/core/src/mail/send-mail.ts","../../../../../../../warlock.js/core/src/mail/mail.ts","../../../../../../../warlock.js/core/src/config/config-special-handlers.ts","../../../../../../../warlock.js/core/src/config/config-handlers.ts","../../../../../../../warlock.js/core/src/http/errors/resource-not-found.error.ts","../../../../../../../warlock.js/core/src/http/middleware/inject-request-context.ts","../../../../../../../warlock.js/core/src/validation/database/exists.ts","../../../../../../../warlock.js/core/src/http/config.ts","../../../../../../../warlock.js/core/src/validation/validateAll.ts","../../../../../../../warlock.js/core/src/http/response.ts","../../../../../../../warlock.js/core/src/image/image.ts","../../../../../../../warlock.js/core/src/storage/config.ts","../../../../../../../warlock.js/core/src/storage/storage-file.ts","../../../../../../../warlock.js/core/src/storage/scoped-storage.ts","../../../../../../../warlock.js/core/src/storage/context/storage-driver-context.ts","../../../../../../../warlock.js/core/src/storage/utils/mime.ts","../../../../../../../warlock.js/core/src/storage/drivers/cloud-driver.ts","../../../../../../../warlock.js/core/src/storage/drivers/do-spaces-driver.ts","../../../../../../../warlock.js/core/src/storage/drivers/local-driver.ts","../../../../../../../warlock.js/core/src/storage/drivers/r2-driver.ts","../../../../../../../warlock.js/core/src/storage/drivers/s3-driver.ts","../../../../../../../warlock.js/core/src/storage/storage.ts","../../../../../../../warlock.js/core/src/http/uploads-config.ts","../../../../../../../warlock.js/core/src/http/uploaded-file.ts","../../../../../../../warlock.js/core/src/http/request.ts","../../../../../../../warlock.js/core/src/router/route-registry.ts","../../../../../../../warlock.js/core/src/router/router.ts","../../../../../../../warlock.js/core/src/router/utils.ts","../../../../../../../warlock.js/core/src/http/plugins.ts","../../../../../../../warlock.js/core/src/http/server.ts","../../../../../../../warlock.js/core/src/http/createHttpApplication.ts","../../../../../../../warlock.js/core/src/http/database/RequestLog.ts","../../../../../../../warlock.js/core/src/http/events.ts","../../../../../../../warlock.js/core/src/http/request-controller.ts","../../../../../../../warlock.js/core/src/http/middleware/cache-response-middleware.ts","../../../../../../../warlock.js/core/src/validation/database/exists-except-current-id.ts","../../../../../../../warlock.js/core/src/validation/database/exists-except-current-user.ts","../../../../../../../warlock.js/core/src/validation/database/unique.ts","../../../../../../../warlock.js/core/src/validation/database/unique-except-current-id.ts","../../../../../../../warlock.js/core/src/validation/database/unique-except-current-user.ts","../../../../../../../warlock.js/core/src/validation/plugins/database-plugin.ts","../../../../../../../warlock.js/core/src/validation/file/file.ts","../../../../../../../warlock.js/core/src/validation/validators/file-validator.ts","../../../../../../../warlock.js/core/src/validation/plugins/file-plugin.ts","../../../../../../../warlock.js/core/src/validation/plugins/localized-plugin.ts","../../../../../../../warlock.js/core/src/validation/init.ts","../../../../../../../warlock.js/core/src/bootstrap.ts","../../../../../../../warlock.js/core/src/bootstrap/setup.ts","../../../../../../../warlock.js/core/src/cache/database-cache-driver.ts","../../../../../../../warlock.js/core/src/cache/index.ts","../../../../../../../warlock.js/core/src/cli/cli-command.ts","../../../../../../../warlock.js/core/src/database/seeds/seeder.ts","../../../../../../../warlock.js/core/src/database/utils.ts","../../../../../../../warlock.js/core/src/dev2-server/path.ts","../../../../../../../warlock.js/core/src/dev2-server/connectors/base-connector.ts","../../../../../../../warlock.js/core/src/dev2-server/connectors/types.ts","../../../../../../../warlock.js/core/src/dev2-server/connectors/cache-connector.ts","../../../../../../../warlock.js/core/src/dev2-server/dev-logger.ts","../../../../../../../warlock.js/core/src/dev2-server/connectors/database-connector.ts","../../../../../../../warlock.js/core/src/dev2-server/connectors/http-connector.ts","../../../../../../../warlock.js/core/src/dev2-server/connectors/storage.connector.ts","../../../../../../../warlock.js/core/src/dev2-server/connectors/connectors-manager.ts","../../../../../../../warlock.js/core/src/dev2-server/health-checker/file-health-result.ts","../../../../../../../warlock.js/core/src/dev2-server/health-checker/checkers/base-health-checker.ts","../../../../../../../warlock.js/core/src/dev2-server/health-checker/checkers/eslint-health-checker.ts","../../../../../../../warlock.js/core/src/dev2-server/tsconfig-manager.ts","../../../../../../../warlock.js/core/src/dev2-server/health-checker/checkers/typescript-health-checker.ts","../../../../../../../warlock.js/core/src/dev2-server/health-checker/workers/eslint-health.worker.ts","../../../../../../../warlock.js/core/src/dev2-server/health-checker/workers/ts-health.worker.ts","../../../../../../../warlock.js/core/src/repositories/adapters/cascade/filter-applicator.ts","../../../../../../../warlock.js/core/src/repositories/adapters/cascade/cascade-query-builder.ts","../../../../../../../warlock.js/core/src/repositories/adapters/cascade/cascade-adapter.ts","../../../../../../../warlock.js/core/src/repositories/repository.manager.ts","../../../../../../../warlock.js/core/src/resource/resource-field-builder.ts","../../../../../../../warlock.js/core/src/resource/resource.ts","../../../../../../../warlock.js/core/src/resource/define-resource.ts","../../../../../../../warlock.js/core/src/restful/restful.ts","../../../../../../../warlock.js/core/src/store/index.ts","../../../../../../../warlock.js/core/src/warlock-config/default-configurations.ts","../../../../../../../warlock.js/core/src/warlock-config/define-config.ts","../../../../../../../warlock.js/core/src/dev2-server/transpile-file.ts","../../../../../../../warlock.js/core/src/warlock-config/warlock-config.manager.ts"],"names":["config","key","defaultValue","baseConfig","name","appLog","module","message","log","schema","v","DatabaseLogModel","Model","DatabaseLog","LogChannel","action","level","data","error","environment","setEnvironment","env","RequestContext","Context","payload","requestContext","contextManager","useRequestStore","useRequest","useCurrentUser","getLocalized","values","localeCode","value","rootPath","paths","path","srcPath","storagePath","relativePath","uploadsPath","configPath","publicPath","cachePath","appPath","consolePath","tempPath","invalidCharsRegex","sanitizePath","filePath","warlockPath","promiseAllObject","promises","results","result","index","Queue","executeFn","executeInParallel","executeEvery","batchSize","maxSize","item","itemsToProcess","sleep","ms","resolve","sluggable","generateFrom","slugLocaleCode","model","slug","toJson","isScalar","isIterable","isPlainObject","subValue","baseUrl","setBaseUrl","url","rtrim","ltrim","uploadsUrl","publicUrl","assetsUrl","setLogConfigurations","options","channels","envChannels","defaultChannels","logger","defaultConfigurations","currentMode","mailersConfig","setMailMode","mode","getMailMode","isProductionMode","isDevelopmentMode","isTestMode","setMailConfigurations","getDefaultMailConfig","getMailerConfig","resolveMailConfig","resetMailConfig","generateMailId","Random","MAIL_EVENTS","getMailEventName","mailId","event","mailEvents","eventName","args","events","callback","NODEMAILER_INSTALL_INSTRUCTIONS","moduleExists","nodemailerModule","loadNodemailerModule","mailerPool","createConfigHash","hash","i","char","getMailer","existingTransporter","auth","username","password","requireTLS","tls","transportConfig","transporter","verifyMailer","closeMailer","closeAllMailers","getPoolStats","REACT_INSTALL_INSTRUCTIONS","react","reactDomServer","loadReactModules","renderReact","reactElement","createHtmlPage","html","styles","links","body","match","renderReactMail","element","content","testMailbox","captureMail","mail","getTestMailbox","getLastMail","findMailsTo","email","findMailsBySubject","subject","wasMailSentTo","wasMailSentWithSubject","getMailboxSize","clearTestMailbox","assertMailSent","predicate","assertMailCount","count","MailError","code","originalError","addressToString","address","normalizeRecipients","recipients","normalizeMail","resolveAttachment","attachment","readFile","buildNodemailerOptions","normalized","resolvedAttachments","att","runMailEvent","handler","triggerEvents","globalEventName","globalResults","specificResults","sendMail","mailError","beforeResult","globalBeforeResults","r","mailer","nodemailerOptions","output","errorMessage","Mail","_Mail","recipient","filename","contentType","attachments","resolvedFilename","headers","tags","tag","id","ConfigSpecialHandlers","configName","configSpecialHandlers","registerAppConfig","locales","locale","registerLogConfig","logConfig","registerMailConfig","mailConfig","ResourceNotFoundError","UnAuthorizedError","ForbiddenError","BadRequestError","ServerError","createRequestStore","request","response","httpContextStore","handleRequestError","DatabaseWriterValidationError","t","keyword","placeholders","trans","fromRequest","existsRule","context","query","column","dbQuery","VALID_RULE","invalidRule","defaultHttpConfigurations","httpConfig","get","resolveDataToParse","validating","validatingType","merge","validateAll","validation","ResponseStatus","Response","_Response","route","listener","statusCode","status","isEnded","chunks","text","defaultFilename","cacheControl","ifNoneMatch","disposition","fileExistsAsync","opts","stats","fs","lastModified","etag","ifModifiedSince","modifiedSinceDate","stream","buffer","image","metadata","format","width","height","cacheTime","mime","errors","inputKey","inputError","SHARP_INSTALL_INSTRUCTIONS","sharpFn","loadSharpModule","Image","_Image","axios","operation","sharpenOptions","negateOptions","trimOptions","quality","alpha","alphaPixel","buffers","input","formatOptions","originalFormat","compressionLevel","configs","angle","sigma","mimeType","base64","color","clonedImage","storageConfig","storageConfigurations","StorageFile","_StorageFile","driver","basename","extname","dirname","info","expiresIn","destination","newName","newPath","visibility","storageClass","ScopedStorage","file","location","dataUrl","matches","base64Data","locations","directoryPath","from","to","fromPath","concurrency","filesToCopy","f","copied","batch","filePaths","directory","chunk","prefix","suffix","lastDot","StorageDriverContext","storageDriverContext","getMimeType","MimeTypes","S3Client","S3Storage","S3Presigner","isModuleExists","S3_INSTALL_INSTRUCTIONS","loadS3","CloudDriver","cleanPrefix","cleanLocation","operationName","maxRetries","initialDelayMs","backoffMultiplier","maxDelayMs","lastError","attempt","delayMs","PutObjectCommand","command","Upload","GetObjectCommand","DeleteObjectCommand","DeleteObjectsCommand","prefixedLocations","loc","Key","deleted","hasMore","objects","obj","HeadObjectCommand","getSignedUrl","CopyObjectCommand","headCommand","headResult","ListObjectsV2Command","files","object","PutObjectAclCommand","GetObjectAclCommand","grant","crypto","DOSpacesDriver","LocalDriver","absolutePath","ensureDirectoryAsync","fileBuffer","writeFile","stat","writeStream","createWriteStream","pipeline","createReadStream","unlinkAsync","removeDirectoryAsync","token","exp","sig","json","now","expectedSig","sigBuffer","expectedBuffer","toPath","copyFile","rename","entries","readdir","entry","entryPath","join","entryStats","subFiles","prefixedLocation","R2Driver","S3Driver","Storage","defaultName","contextDriver","drivers","apepndedPath","instance","arrayBuffer","driverName","required","field","resolver","storage","UPLOADS_DEFAULTS","uploadsConfig","fallback","UploadedFile","fileData","dimensions","degrees","allowedMimeTypes","allowedExtensions","fileSize","storageInstance","finalLocation","img","namingStrategy","baseName","length","ext","configPrefix","parts","combined","as","formatted","dayjs","dir","currentExt","Request","transFrom","defaultLocaleCode","selectedInputs","domain","authorization","type","arrayOfObjectValues","isArrayKey","keyParts","keyName","keyNameParts","keyName2","set","middlewareOutput","inputs","only","except","middlewares","middleware","colors","middlewaresList","keys","unset","bodyInputs","heavyInputs","isEmpty","realIp","RouteRegistry","FindMyWay","routes","req","res","params","method","line","Router","_Router","redirectMode","_request","_router","server","proxy","p","concatRoute","prefixName","trim","controller","routeData","resource","baseResourceName","toCamelCase","routeResource","isAcceptableResource","resourceName","sourceFile","methodValidation","validationMethods","requestMethod","requestMethodFunction","baseRequest","reply","directoryOptions","fastifyStatic","wildcardHandler","fastifyRequest","fastifyReply","routeRegistry","methods","fastifyResponse","router","defaultCorsOptions","registerHttpPlugins","corsOptions","fastifyMultipart","startServer","Fastify","getServer","createHttpApplication","port","stopHttpApplication","RequestLog","logResponse","wrapResponseInDataKey","RequestController","defaultCacheOptions","parseCacheOptions","cacheOptions","finalCacheOptions","cacheMiddleware","responseCacheOptions","ttl","omit","cacheKey","cacheDriver","cache","existsExceptCurrentIdRule","exceptCurrentIdColumn","existsExceptCurrentUserRule","exceptCurrentUserColumn","exceptCurrentUserValue","user","uniqueRule","exceptColumnName","exceptValue","exceptVal","uniqueExceptCurrentIdRule","uniqueExceptCurrentUserRule","databasePlugin","ScalarValidator","optionsList","rule","StringValidator","NumberValidator","fileRule","imageRule","fileExtensionRule","extensions","fileTypeRule","mimeTypes","uploadedFileMetadataSchema","FileValidator","BaseValidator","size","minFileSizeRule","resolveFileSize","maxFileSizeRule","minWidthRule","maxWidthRule","minHeightRule","maxHeightRule","relativeDirectory","filePlugin","localizedPlugin","valueValidator","configureSeal","attributes","translateRule","translationKey","translation","attribute","translateAttribute","attributeGroup","registerPlugin","bootstrap","loadEnv","initializeDayjs","captureAnyUnhandledRejection","displayEnvironmentMode","envColor","CacheModel","DatabaseCacheDriver","BaseCacheDriver","namespace","parsedKey","cacheEntry","CLICommand","description","source","isPersistent","alias","option","part","first","second","equalIndex","spaceIndex","commandInstnace","seeder","useHashedPassword","useModelTransformer","isChanged","isNew","authService","useComputedModel","useComputedSlug","scope","slugify","Path","BaseConnector","changedFiles","watchedFile","ConnectorPriority","CacheConnector","cacheConfig","timestamp","devLog","devLogSuccess","devLogError","cleanStack","cleanErrorStack","devLogWarn","devLogInfo","stack","cleanedLine","p1","absolutePathMatch","devServeLog","DatabaseConnector","databaseConfig","connectToDatabase","dataSources","dataSourceRegistry","dataSource","HttpConnector","StorageConnector","ConnectorsManager","connector","a","b","connectorsNames","isShuttingDown","gracefulShutdown","signal","connectorsManager","FileHealthResult","messages","BaseHealthChecker","isHealthy","EslintHealthChecker","flatConfigPath","flatConfigMjsPath","flatConfigCjsPath","ESLint","fileName","errorCount","warningCount","sourceLines","errorMessages","m","icon","ruleId","lineIndex","lineContent","lineNum","errorLength","columnIndex","prefixPadding","columnPadding","underline","warningMessages","warning","warningLength","summary","lintResults","lintResult","warnings","isError","isWarning","TSConfigManager","ts","aliasPattern","aliasTargets","checkingPath","aliasKey","targetPattern","targetBase","relativePart","resolvedPath","tsconfigManager","TypescriptHealthChecker","diagnostic","character","cleanMessage","syntacticDiagnostics","semanticDiagnostics","allDiagnostics","ESLintHealthWorker","lintMessage","worker","parentPort","initResult","workerData","TypeScriptHealthWorker","tsconfigPath","configFile","hasChanges","lineNumber","columnNumber","pos","messageText","defaultHost","FilterApplicator","filters","operator","target","q","col","cols","val","columns","conditions","boolValue","intValue","numValue","floatValue","dateValue","start","end","dates","CascadeQueryBuilder","_CascadeQueryBuilder","fieldOrConditionsOrCallback","operatorOrValue","fieldOrConditions","range","pattern","fields","direction","orderBy","limit","offset","page","cursor","cursorColumn","documents","nextCursor","prevCursor","CascadeAdapter","eventsCallback","modelEvents","filter","records","record","RepositoryManager","adapter","moreOptions","cacheKeyOptions","cachedData","doc","where","ResourceFieldBuilder","condition","isObject","dayjsObject","Resource","_Resource","originalData","outputKey","outputSettings","fieldKey","valueTransformType","inputValue","outputValue","transformedItem","builder","defineResource","Restful","findMethod","responseDocument","listMethod","paginationInfo","beforeCreate","beforeSave","createOutput","saveOutput","beforeOutput","beforeSafe","oldRecord","ids","_response","_record","_oldRecord","stores","createStore","initialData","runCallback","store","AsyncLocalStorage","ops","fn","useStore","defaultWarlockConfigurations","defineConfig","transpile","sourceCode","transpiled","transform","WarlockConfigManager","fileUrl","pathToFileURL","getFileAsync","compiledContent","putFileAsync","warlockConfigManager"],"mappings":"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","file":"index.js","sourcesContent":["import baseConfig from \"@mongez/config\";\nimport type { ConfigKey, ConfigRegistry } from \"./types\";\n\n/**\n * Config accessor interface with typed overloads\n */\ninterface ConfigAccessor {\n /**\n * Get a config value by dot-notation key path.\n */\n key<T = any>(key: ConfigKey | string, defaultValue?: T): T;\n\n /**\n * Get an entire config group by name with type inference.\n * Returns the typed config object for known config names.\n */\n get<K extends keyof ConfigRegistry>(name: K, defaultValue?: ConfigRegistry[K]): ConfigRegistry[K];\n\n /**\n * Get an entire config group by name (dynamic string).\n */\n get<T = any>(name: string, defaultValue?: T): T;\n}\n\n/**\n * Config accessor with typed autocomplete and return type inference.\n *\n * @example\n * ```typescript\n * // Get entire config group - returns the actual config type\n * const db = config.get(\"database\"); // → DatabaseConfigurations\n *\n * // Get specific key with dot notation\n * const host = config.key(\"database.host\");\n * const port = config.key<number>(\"database.port\", 27017);\n * ```\n */\nexport const config: ConfigAccessor = {\n key(key: ConfigKey | string, defaultValue?: any): any {\n return baseConfig.get(key, defaultValue);\n },\n\n get(name: string, defaultValue?: any): any {\n return baseConfig.get(name, defaultValue);\n },\n};\n","import { log } from \"@warlock.js/logger\";\n\nexport const appLog = {\n info: (module: string, message: string) => log.info(\"app\", module, message),\n error: (module: string, message: string) => log.error(\"app\", module, message),\n warn: (module: string, message: string) => log.warn(\"app\", module, message),\n debug: (module: string, message: string) => log.debug(\"app\", module, message),\n success: (module: string, message: string) =>\n log.success(\"app\", module, message),\n};\n","import { Model } from \"@warlock.js/cascade\";\r\nimport { Infer, v } from \"@warlock.js/seal\";\r\n\r\nconst schema = v.object({\r\n module: v.string(),\r\n action: v.string(),\r\n message: v.string(),\r\n trace: v.record(v.any()),\r\n level: v.string(),\r\n});\r\n\r\ntype LogSchema = Infer<typeof schema>;\r\n\r\nexport class DatabaseLogModel extends Model<LogSchema> {\r\n /**\r\n * Table name\r\n */\r\n public static table = \"logs\";\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public static schema = schema;\r\n}\r\n","import type { ChildModel, Model } from \"@warlock.js/cascade\";\r\nimport type { BasicLogConfigurations, LoggingData } from \"@warlock.js/logger\";\r\nimport { LogChannel, type LogContract, type LogMessage } from \"@warlock.js/logger\";\r\nimport { DatabaseLogModel } from \"../database/models/database-log\";\r\n\r\nexport type DatabaseLogOptions = BasicLogConfigurations & {\r\n /**\r\n * Model to use for logging\r\n */\r\n model?: typeof DatabaseLogModel;\r\n};\r\n\r\nexport class DatabaseLog extends LogChannel<DatabaseLogOptions> implements LogContract {\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public name = \"database\";\r\n\r\n /**\r\n * Database model\r\n */\r\n public get model(): ChildModel<Model> {\r\n return this.config(\"model\") ?? DatabaseLogModel;\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public async log(log: LoggingData) {\r\n const { module, action, message, type: level } = log;\r\n\r\n if (!this.model.getDataSource().driver?.isConnected) return;\r\n\r\n if (!this.shouldBeLogged(log)) return;\r\n\r\n const data: LogMessage = {\r\n module,\r\n action,\r\n content: message,\r\n level,\r\n date: new Date().toISOString(),\r\n };\r\n\r\n if (message instanceof Error) {\r\n data.stack = message.stack;\r\n data.content = message.message;\r\n } else {\r\n data.content = message;\r\n data.stack = new Error().stack;\r\n }\r\n\r\n try {\r\n await this.model.create(data);\r\n } catch (error) {\r\n console.log(\"Error\", error);\r\n }\r\n }\r\n}\r\n","export type Environment = \"development\" | \"production\" | \"test\";\r\n\r\nexport function environment(): Environment {\r\n return (process.env.NODE_ENV as Environment) || \"development\";\r\n}\r\n\r\nexport function setEnvironment(env: Environment) {\r\n process.env.NODE_ENV = env;\r\n}\r\n","import type { Model } from \"@warlock.js/cascade\";\nimport { Context, contextManager } from \"@warlock.js/context\";\nimport type { Request } from \"../request\";\nimport type { Response } from \"../response\";\n\n/**\n * Request Context Store\n */\nexport type RequestContextStore<User extends Model = Model> = {\n request: Request<User>;\n response: Response;\n};\n\n/**\n * Request Context\n *\n * Manages request-scoped data (request, response, user) using AsyncLocalStorage.\n * Extends the base Context class for consistent API.\n */\nclass RequestContext<User extends Model = Model> extends Context<RequestContextStore<User>> {\n /**\n * Get the current request\n */\n public getRequest(): Request<User> | undefined {\n return this.get(\"request\");\n }\n\n /**\n * Get the current response\n */\n public getResponse(): Response | undefined {\n return this.get(\"response\");\n }\n\n /**\n * Get the current user\n */\n public getUser(): User | undefined {\n return this.getRequest()?.user;\n }\n\n /**\n * Build the initial request store from HTTP context\n */\n public buildStore(payload?: Record<string, any>): RequestContextStore<User> {\n return {\n request: payload?.request,\n response: payload?.response,\n };\n }\n}\n\n/**\n * Global request context instance\n */\nexport const requestContext = new RequestContext();\n\ncontextManager.register(\"request\", requestContext);\n\n/**\n * Use request store (for backward compatibility)\n */\nexport function useRequestStore<UserType extends Model = Model>() {\n return (requestContext.getStore() || {}) as RequestContextStore<UserType>;\n}\n\nexport function useRequest<UserType extends Model = Model>() {\n return requestContext.getRequest() as Request<UserType>;\n}\n\nexport function useCurrentUser<UserType extends Model = Model>() {\n return requestContext.getUser() as UserType;\n}\n","import { useRequestStore } from \"../http/context/request-context\";\r\n\r\nexport type LocalizedObject = {\r\n localeCode: string;\r\n value: any;\r\n};\r\n\r\n/**\r\n * Get localized value based on the given locale code\r\n * If the locale code is not given and the function is called within a request context, it will get the current locale code\r\n */\r\nexport function getLocalized(values: LocalizedObject[], localeCode?: string, key = \"value\") {\r\n if (!values) return values;\r\n\r\n if (!localeCode) {\r\n localeCode = useRequestStore().request?.getLocaleCode();\r\n }\r\n\r\n if (Array.isArray(values)) {\r\n return values.find((value) => value.localeCode === localeCode)?.[key as keyof LocalizedObject];\r\n }\r\n\r\n return values;\r\n}\r\n","import config from \"@mongez/config\";\r\nimport path from \"path\";\r\n\r\n/**\r\n * Get root path or join the given paths to the root path\r\n */\r\nexport function rootPath(...paths: string[]) {\r\n return path.resolve(process.cwd(), ...paths);\r\n}\r\n\r\n/**\r\n * Get src directory path or join the given paths to the src directory path\r\n */\r\nexport function srcPath(...paths: string[]) {\r\n return rootPath(\"src\", ...paths);\r\n}\r\n\r\n/**\r\n * Get the absolute path to the storage folder to the given path\r\n *\r\n * If no path is given, it will return the absolute path to the storage folder\r\n */\r\nexport function storagePath(relativePath = \"\") {\r\n return rootPath(\"storage\", relativePath);\r\n}\r\n\r\n/**\r\n * Get the absolute path to the uploads folder to the given path\r\n *\r\n * If no path is given, it will return the absolute path to the uploads folder\r\n */\r\nexport function uploadsPath(relativePath = \"\") {\r\n const configPath = config.get(\"uploads.root\");\r\n if (!configPath) {\r\n return rootPath(\"storage\", \"uploads\", relativePath);\r\n }\r\n\r\n return typeof configPath === \"function\"\r\n ? configPath(relativePath)\r\n : path.resolve(configPath, relativePath);\r\n}\r\n\r\n/**\r\n * Get the absolute path to the public folder to the given path\r\n *\r\n * If no path is given, it will return the absolute path to the public folder\r\n */\r\nexport function publicPath(relativePath = \"\") {\r\n return rootPath(\"public\", relativePath);\r\n}\r\n\r\n/**\r\n * Get the absolute path to the cache folder to the given path\r\n *\r\n * If no path is given, it will return the absolute path to the cache folder\r\n */\r\nexport function cachePath(relativePath = \"\") {\r\n return rootPath(\"storage\", \"cache\", relativePath);\r\n}\r\n\r\n/**\r\n * App path\r\n */\r\nexport function appPath(relativePath = \"\") {\r\n return rootPath(\"src/app\", relativePath);\r\n}\r\n\r\n/**\r\n * Console path\r\n */\r\nexport function consolePath(relativePath = \"\") {\r\n return rootPath(\"src/console\", relativePath);\r\n}\r\n\r\n/**\r\n * Get a temp path\r\n */\r\nexport function tempPath(relativePath = \"\") {\r\n return rootPath(\"storage/temp\", relativePath);\r\n}\r\n\r\n/**\r\n * Remove any invalid characters from the file path using regex\r\n * It should accept any language character, numbers, and the following characters: _ - .\r\n */\r\nconst invalidCharsRegex = /[<>:\"/\\\\|?*]/g; // Regex to match invalid characters\r\nexport function sanitizePath(filePath: string) {\r\n return filePath.replace(invalidCharsRegex, \"\"); // Replace invalid characters with an empty string\r\n}\r\n\r\n/**\r\n * Warlock path\r\n * PLEASE DO NOT add any files in this directory as it may be deleted\r\n */\r\nexport function warlockPath(...path: string[]) {\r\n return rootPath(\".warlock\", ...path);\r\n}\r\n\r\n/**\r\n * Get config directory path\r\n */\r\nexport function configPath(...path: string[]) {\r\n return rootPath(\"src/config\", ...path);\r\n}\r\n","/**\r\n * Resolve all of the given promises in the object and return the results as an object.\r\n * This is more convenient than using `Promise.all` and then mapping the results back to the keys.\r\n */\r\nexport async function promiseAllObject<T extends Record<string, Promise<any>>>(\r\n promises: T,\r\n): Promise<{ [K in keyof T]: T[K] extends Promise<infer U> ? U : never }> {\r\n const results = await Promise.all(Object.values(promises));\r\n const keys = Object.keys(promises);\r\n\r\n return keys.reduce(\r\n (result, key, index) => {\r\n (result as any)[key] = results[index];\r\n return result;\r\n },\r\n {} as { [K in keyof T]: T[K] extends Promise<infer U> ? U : never },\r\n );\r\n}\r\n","/**\n * A utility class for managing a queue of operations.\n * Allows enqueuing values and executing a function when the queue reaches a certain size or after a specified interval.\n * Supports both parallel and sequential execution of the queued operations.\n */\nexport class Queue<T> {\n /** The items currently in the queue. */\n private items: T[] = [];\n\n /** The maximum size of the queue before triggering execution. */\n private readonly maxSize?: number;\n\n /** The interval in milliseconds after which the queue will be executed if not already triggered by size. */\n private readonly interval: number;\n\n /** The function to execute with the items in the queue. */\n private readonly executeFn: (items: T[]) => Promise<void>;\n\n /** Timer for managing the interval-based execution. */\n private timer: NodeJS.Timeout | null = null;\n\n /** Flag to determine if execution should be parallel or sequential. */\n private readonly executeInParallel: boolean;\n\n /** The batch size for processing items. */\n private readonly batchSize: number;\n\n /** Whether the current queue is busy executing */\n private isExecuting = false;\n\n /**\n * Constructs a new Queue instance.\n * @param executeFn - The function to execute with the items in the queue.\n * @param maxSize - The maximum number of items before the queue is executed.\n * @param executeEvery - The time in milliseconds after which the queue is executed if not already triggered.\n * @param executeInParallel - Whether to execute the function in parallel or sequentially.\n * @param batchSize - The number of items to process in each batch.\n */\n public constructor(\n executeFn: (items: T[]) => Promise<void>,\n executeInParallel: boolean = true,\n executeEvery: number = 5000,\n batchSize: number,\n maxSize?: number,\n ) {\n this.executeFn = executeFn;\n this.maxSize = maxSize;\n this.interval = executeEvery;\n this.executeInParallel = executeInParallel;\n this.batchSize = batchSize;\n }\n\n /**\n * Adds an item to the queue.\n * Triggers execution if the queue reaches the maximum size.\n * Starts a timer if not already running.\n * @param item - The item to add to the queue.\n */\n public enqueue(item: T): void {\n this.items.push(item);\n if (this.maxSize && this.items.length >= this.maxSize) {\n this.execute();\n }\n\n if (!this.timer) {\n this.startTimer();\n }\n }\n\n /**\n * Starts a timer to execute the queue after the specified interval.\n */\n private startTimer(): void {\n this.timer = setInterval(() => {\n if (this.items.length > 0) {\n this.execute();\n }\n }, this.interval);\n }\n\n /**\n * Executes the function with the current items in the queue.\n * Processes items in batches and resets the timer.\n */\n private async execute(): Promise<void> {\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = null;\n }\n\n this.isExecuting = true;\n\n // Now there are couple scenarios:\n // 1. Batch size has value, we need to check if its going to be executed in parallel or sequentially\n // 2. Batch size is not provided, we will execute all items in a single call\n if (this.batchSize) {\n const itemsToProcess = this.items.splice(0, this.batchSize);\n if (this.executeInParallel) {\n await Promise.all(itemsToProcess.map(item => this.executeFn([item])));\n } else {\n for (const item of itemsToProcess) {\n await this.executeFn([item]);\n }\n }\n }\n\n this.isExecuting = false;\n }\n}\n","export function sleep(ms: number) {\r\n return new Promise(resolve => setTimeout(resolve, ms));\r\n}\r\n","import slug from \"@mongez/slug\";\r\nimport type { Model } from \"@warlock.js/cascade\";\r\n\r\n/**\r\n * Used for model castings\r\n */\r\nexport function sluggable(generateFrom: string, slugLocaleCode = \"en\") {\r\n return (model: Model) => {\r\n let value = model.get(generateFrom);\r\n\r\n if (!value) return \"\";\r\n\r\n if (Array.isArray(value)) {\r\n value = (value as any[]).find((value) => value.localeCode === slugLocaleCode)?.value;\r\n }\r\n\r\n const slugFunction = (slug as any).default || slug;\r\n\r\n return slugFunction(String(value));\r\n };\r\n}\r\n","import { isIterable, isPlainObject, isScalar } from \"@mongez/supportive-is\";\r\n\r\nexport async function toJson(value: any): Promise<any> {\r\n // if it is a falsy value, return it\r\n if (!value || isScalar(value)) return value;\r\n\r\n // if it has a `toJSON` method, call it and await the result then return it\r\n if (value.toJSON) {\r\n return await value.toJSON();\r\n }\r\n\r\n // if it is iterable, an array or array-like object then parse each item\r\n if (isIterable(value)) {\r\n const values = Array.from(value);\r\n\r\n return Promise.all(\r\n values.map(async (item: any) => {\r\n return await toJson(item);\r\n }),\r\n );\r\n }\r\n\r\n // if not plain object, then return it\r\n if (!isPlainObject(value)) {\r\n return value;\r\n }\r\n\r\n // loop over the object and check if the value and call `parse` on it\r\n for (const key in value) {\r\n const subValue = value[key];\r\n\r\n value[key] = await toJson(subValue);\r\n }\r\n\r\n return value;\r\n}\r\n","import { ltrim, rtrim } from \"@mongez/reinforcements\";\r\n\r\nlet baseUrl = \"\";\r\n\r\n/**\r\n * Set base url\r\n */\r\nexport function setBaseUrl(url: string) {\r\n baseUrl = url;\r\n}\r\n\r\n/**\r\n * Get full path for the given path\r\n */\r\nexport function url(path = \"\") {\r\n return rtrim(baseUrl, \"/\") + \"/\" + ltrim(path, \"/\");\r\n}\r\n\r\n/**\r\n * Get uploads url\r\n */\r\nexport function uploadsUrl(path = \"\") {\r\n return url(\"/uploads/\" + ltrim(path, \"/\"));\r\n}\r\n\r\n/**\r\n * Get full path for the given path related to public route\r\n */\r\nexport function publicUrl(path = \"\") {\r\n return url(\"/public/\" + ltrim(path, \"/\"));\r\n}\r\n\r\n/**\r\n * Assets url\r\n */\r\nexport function assetsUrl(path = \"\") {\r\n return publicUrl(\"/assets/\" + ltrim(path, \"/\"));\r\n}\r\n","import type { LogChannel } from \"@warlock.js/logger\";\r\nimport { logger } from \"@warlock.js/logger\";\r\nimport { environment } from \"../utils\";\r\nimport type { LogConfigurations } from \"./types\";\r\n\r\nexport function setLogConfigurations(options: LogConfigurations) {\r\n // log configurations\r\n const channels: LogChannel[] = [];\r\n\r\n const env = environment();\r\n\r\n const envChannels = options[env as \"development\" | \"production\"]?.channels;\r\n const defaultChannels = options.channels;\r\n\r\n if (defaultChannels) {\r\n channels.push(...defaultChannels);\r\n }\r\n\r\n if (envChannels) {\r\n channels.push(...envChannels);\r\n }\r\n\r\n logger.configure({\r\n channels,\r\n });\r\n}\r\n","import type { MailConfigurations, MailersConfig, MailMode } from \"./types\";\r\n\r\n/**\r\n * Default mail configurations\r\n */\r\nconst defaultConfigurations: Partial<MailConfigurations> = {\r\n secure: true,\r\n tls: true,\r\n};\r\n\r\n/**\r\n * Current mail mode\r\n */\r\nlet currentMode: MailMode = \"production\";\r\n\r\n/**\r\n * Registered mailers configuration\r\n */\r\nlet mailersConfig: MailersConfig = {};\r\n\r\n/**\r\n * Set the mail mode\r\n *\r\n * @param mode \"production\" | \"development\" | \"test\"\r\n *\r\n * - **production**: Actually sends emails via SMTP\r\n * - **development**: Logs emails to console without sending\r\n * - **test**: Captures emails to test mailbox for assertions\r\n *\r\n * @example\r\n * ```typescript\r\n * // In test setup\r\n * setMailMode(\"test\");\r\n *\r\n * // In development\r\n * setMailMode(\"development\");\r\n * ```\r\n */\r\nexport function setMailMode(mode: MailMode): void {\r\n currentMode = mode;\r\n}\r\n\r\n/**\r\n * Get the current mail mode\r\n */\r\nexport function getMailMode(): MailMode {\r\n return currentMode;\r\n}\r\n\r\n/**\r\n * Check if in production mode\r\n */\r\nexport function isProductionMode(): boolean {\r\n return currentMode === \"production\";\r\n}\r\n\r\n/**\r\n * Check if in development mode\r\n */\r\nexport function isDevelopmentMode(): boolean {\r\n return currentMode === \"development\";\r\n}\r\n\r\n/**\r\n * Check if in test mode\r\n */\r\nexport function isTestMode(): boolean {\r\n return currentMode === \"test\";\r\n}\r\n\r\n/**\r\n * Set mail configurations\r\n *\r\n * Supports both simple config and named mailers.\r\n *\r\n * @example\r\n * ```typescript\r\n * // Simple config (sets as default)\r\n * setMailConfigurations({\r\n * host: \"smtp.gmail.com\",\r\n * port: 587,\r\n * username: \"...\",\r\n * password: \"...\",\r\n * });\r\n *\r\n * // Named mailers\r\n * setMailConfigurations({\r\n * default: { host: \"smtp.sendgrid.net\", ... },\r\n * mailers: {\r\n * marketing: { host: \"smtp.mailchimp.com\", ... },\r\n * transactional: { host: \"smtp.postmark.com\", ... },\r\n * },\r\n * });\r\n * ```\r\n */\r\nexport function setMailConfigurations(config: MailConfigurations | MailersConfig): void {\r\n // Check if it's a MailersConfig (has 'default' or 'mailers' key)\r\n if (\"default\" in config || \"mailers\" in config) {\r\n mailersConfig = config as MailersConfig;\r\n } else {\r\n // Simple config - set as default\r\n mailersConfig = {\r\n default: config as MailConfigurations,\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Get the default mail configuration\r\n */\r\nexport function getDefaultMailConfig(): MailConfigurations {\r\n return {\r\n ...defaultConfigurations,\r\n ...mailersConfig.default,\r\n };\r\n}\r\n\r\n/**\r\n * Get a named mailer configuration\r\n */\r\nexport function getMailerConfig(name: string): MailConfigurations | undefined {\r\n if (name === \"default\") {\r\n return getDefaultMailConfig();\r\n }\r\n\r\n const config = mailersConfig.mailers?.[name];\r\n if (!config) {\r\n return undefined;\r\n }\r\n\r\n return {\r\n ...defaultConfigurations,\r\n ...config,\r\n };\r\n}\r\n\r\n/**\r\n * Resolve configuration from options\r\n * Priority: config > mailer > default\r\n */\r\nexport function resolveMailConfig(options: {\r\n config?: MailConfigurations;\r\n mailer?: string;\r\n}): MailConfigurations {\r\n // Direct config takes highest priority\r\n if (options.config) {\r\n return {\r\n ...defaultConfigurations,\r\n ...options.config,\r\n };\r\n }\r\n\r\n // Named mailer\r\n if (options.mailer) {\r\n const config = getMailerConfig(options.mailer);\r\n if (!config) {\r\n throw new Error(`Mailer \"${options.mailer}\" not found in configuration`);\r\n }\r\n return config;\r\n }\r\n\r\n // Default\r\n return getDefaultMailConfig();\r\n}\r\n\r\n/**\r\n * Reset all configurations (useful for testing)\r\n */\r\nexport function resetMailConfig(): void {\r\n currentMode = \"production\";\r\n mailersConfig = {};\r\n}\r\n","import events from \"@mongez/events\";\r\nimport { Random } from \"@mongez/reinforcements\";\r\n\r\n/**\r\n * Generate a unique mail ID for event namespacing\r\n */\r\nexport function generateMailId(): string {\r\n return \"M\" + Random.int(32);\r\n}\r\n\r\n/**\r\n * Mail event names (global events)\r\n */\r\nexport const MAIL_EVENTS = {\r\n BEFORE_SENDING: \"mail.beforeSending\",\r\n SENT: \"mail.sent\",\r\n SUCCESS: \"mail.success\",\r\n ERROR: \"mail.error\",\r\n} as const;\r\n\r\n/**\r\n * Get namespaced event name for a specific mail\r\n * @param mailId Unique mail identifier\r\n * @param event Event type\r\n * @returns Namespaced event name (e.g., \"mail.abc123.success\")\r\n */\r\nexport function getMailEventName(\r\n mailId: string,\r\n event: \"beforeSending\" | \"sent\" | \"success\" | \"error\",\r\n): string {\r\n return `mail.${mailId}.${event}`;\r\n}\r\n\r\n/**\r\n * Mail events wrapper\r\n *\r\n * Supports two event patterns:\r\n * 1. Global events: `mail.success` - fires for ALL emails\r\n * 2. Specific events: `mail.$mailId.success` - fires for ONE email\r\n *\r\n * ## Usage\r\n *\r\n * ```typescript\r\n * // Global listener - all emails\r\n * mailEvents.onSuccess((mail, result) => {\r\n * console.log(\"Any mail sent:\", result.messageId);\r\n * });\r\n *\r\n * // Specific listener - one email by ID\r\n * const mailId = generateMailId();\r\n * mailEvents.onMailSuccess(mailId, (mail, result) => {\r\n * console.log(\"This specific mail sent:\", result.messageId);\r\n * });\r\n *\r\n * await sendMail({\r\n * id: mailId, // Use the same ID\r\n * to: \"user@example.com\",\r\n * subject: \"Hello\",\r\n * html: \"<p>World</p>\",\r\n * });\r\n * ```\r\n */\r\nexport const mailEvents = {\r\n /**\r\n * Trigger a global mail event\r\n */\r\n trigger: (eventName: keyof typeof MAIL_EVENTS, ...args: any[]) => {\r\n return events.trigger(MAIL_EVENTS[eventName], ...args);\r\n },\r\n\r\n /**\r\n * Trigger a specific mail event (by mail ID)\r\n */\r\n triggerForMail: (\r\n mailId: string,\r\n event: \"beforeSending\" | \"sent\" | \"success\" | \"error\",\r\n ...args: any[]\r\n ) => {\r\n return events.trigger(getMailEventName(mailId, event), ...args);\r\n },\r\n\r\n /**\r\n * Subscribe to global mail events\r\n */\r\n on: (eventName: keyof typeof MAIL_EVENTS, callback: (...args: any[]) => void) => {\r\n return events.subscribe(MAIL_EVENTS[eventName], callback);\r\n },\r\n\r\n // === GLOBAL EVENT HELPERS ===\r\n\r\n /**\r\n * Subscribe to beforeSending event (all mails)\r\n */\r\n onBeforeSending: (callback: (mail: any) => void | Promise<void> | false | Promise<false>) => {\r\n return events.subscribe(MAIL_EVENTS.BEFORE_SENDING, callback);\r\n },\r\n\r\n /**\r\n * Subscribe to sent event (all mails, after attempt)\r\n */\r\n onSent: (callback: (mail: any, result: any, error: any) => void | Promise<void>) => {\r\n return events.subscribe(MAIL_EVENTS.SENT, callback);\r\n },\r\n\r\n /**\r\n * Subscribe to success event (all mails)\r\n */\r\n onSuccess: (callback: (mail: any, result: any) => void | Promise<void>) => {\r\n return events.subscribe(MAIL_EVENTS.SUCCESS, callback);\r\n },\r\n\r\n /**\r\n * Subscribe to error event (all mails)\r\n */\r\n onError: (callback: (mail: any, error: any) => void | Promise<void>) => {\r\n return events.subscribe(MAIL_EVENTS.ERROR, callback);\r\n },\r\n\r\n // === SPECIFIC MAIL EVENT HELPERS ===\r\n\r\n /**\r\n * Subscribe to beforeSending event for a specific mail\r\n */\r\n onMailBeforeSending: (\r\n mailId: string,\r\n callback: (mail: any) => void | Promise<void> | false | Promise<false>,\r\n ) => {\r\n return events.subscribe(getMailEventName(mailId, \"beforeSending\"), callback);\r\n },\r\n\r\n /**\r\n * Subscribe to sent event for a specific mail\r\n */\r\n onMailSent: (\r\n mailId: string,\r\n callback: (mail: any, result: any, error: any) => void | Promise<void>,\r\n ) => {\r\n return events.subscribe(getMailEventName(mailId, \"sent\"), callback);\r\n },\r\n\r\n /**\r\n * Subscribe to success event for a specific mail\r\n */\r\n onMailSuccess: (mailId: string, callback: (mail: any, result: any) => void | Promise<void>) => {\r\n return events.subscribe(getMailEventName(mailId, \"success\"), callback);\r\n },\r\n\r\n /**\r\n * Subscribe to error event for a specific mail\r\n */\r\n onMailError: (mailId: string, callback: (mail: any, error: any) => void | Promise<void>) => {\r\n return events.subscribe(getMailEventName(mailId, \"error\"), callback);\r\n },\r\n};\r\n","import { log } from \"@warlock.js/logger\";\r\nimport type nodemailer from \"nodemailer\";\r\nimport type { Transporter } from \"nodemailer\";\r\nimport type { MailConfigurations } from \"./types\";\r\n\r\n// ============================================================\r\n// Eager-loaded Nodemailer Module\r\n// ============================================================\r\n\r\n/**\r\n * Installation instructions for nodemailer\r\n */\r\nconst NODEMAILER_INSTALL_INSTRUCTIONS = `\r\nEmail functionality requires the nodemailer package.\r\nInstall it with:\r\n\r\n warlock add mailer\r\n\r\nOr manually:\r\n\r\n npm install nodemailer\r\n pnpm add nodemailer\r\n yarn add nodemailer\r\n`.trim();\r\n\r\n/**\r\n * Module availability flag\r\n */\r\nlet moduleExists: boolean | null = null;\r\n\r\n/**\r\n * Cached nodemailer module (loaded at import time)\r\n */\r\nlet nodemailerModule: typeof nodemailer;\r\n\r\n/**\r\n * Eagerly load nodemailer module at import time\r\n */\r\nasync function loadNodemailerModule() {\r\n try {\r\n const module = await import(\"nodemailer\");\r\n nodemailerModule = module.default;\r\n moduleExists = true;\r\n } catch {\r\n moduleExists = false;\r\n }\r\n}\r\n\r\n// Kick off eager loading immediately\r\nloadNodemailerModule();\r\n\r\n// ============================================================\r\n// Mailer Pool\r\n// ============================================================\r\n\r\n/**\r\n * Mailer pool for connection reuse\r\n * Maps config hash to transporter instance\r\n */\r\nconst mailerPool = new Map<string, Transporter>();\r\n\r\n/**\r\n * Create a hash from mail configuration for pooling\r\n */\r\nfunction createConfigHash(config: MailConfigurations): string {\r\n const key = JSON.stringify({\r\n host: config.host,\r\n port: config.port,\r\n secure: config.secure,\r\n auth: config.auth,\r\n username: config.username,\r\n password: config.password,\r\n });\r\n\r\n // Simple hash function\r\n let hash = 0;\r\n for (let i = 0; i < key.length; i++) {\r\n const char = key.charCodeAt(i);\r\n hash = (hash << 5) - hash + char;\r\n hash = hash & hash;\r\n }\r\n\r\n return `mailer_${hash}`;\r\n}\r\n\r\n/**\r\n * Get or create a mailer transporter from the pool\r\n * Nodemailer is eagerly loaded at import time\r\n */\r\nexport function getMailer(config: MailConfigurations): Transporter {\r\n if (moduleExists === false) {\r\n throw new Error(`nodemailer is not installed.\\n\\n${NODEMAILER_INSTALL_INSTRUCTIONS}`);\r\n }\r\n\r\n const hash = createConfigHash(config);\r\n\r\n // Return existing transporter if available\r\n const existingTransporter = mailerPool.get(hash);\r\n\r\n if (existingTransporter) {\r\n return existingTransporter;\r\n }\r\n\r\n // Create new transporter\r\n log.info(\"mail\", \"pool\", `Creating new mailer transport (pool size: ${mailerPool.size + 1})`);\r\n\r\n const { auth, username, password, requireTLS, tls, ...transportConfig } = config;\r\n\r\n const transporter = nodemailerModule.createTransport({\r\n requireTLS: requireTLS ?? tls,\r\n auth: auth ?? {\r\n user: username,\r\n pass: password,\r\n },\r\n ...transportConfig,\r\n });\r\n\r\n // Store in pool\r\n mailerPool.set(hash, transporter);\r\n\r\n return transporter;\r\n}\r\n\r\n/**\r\n * Verify a mailer connection\r\n */\r\nexport async function verifyMailer(config: MailConfigurations): Promise<boolean> {\r\n const transporter = getMailer(config);\r\n\r\n try {\r\n await transporter.verify();\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Close a specific mailer connection\r\n */\r\nexport function closeMailer(config: MailConfigurations): void {\r\n const hash = createConfigHash(config);\r\n const transporter = mailerPool.get(hash);\r\n\r\n if (transporter) {\r\n transporter.close();\r\n mailerPool.delete(hash);\r\n log.info(\"mail\", \"pool\", `Closed mailer transport (pool size: ${mailerPool.size})`);\r\n }\r\n}\r\n\r\n/**\r\n * Close all mailer connections\r\n */\r\nexport function closeAllMailers(): void {\r\n for (const [hash, transporter] of mailerPool) {\r\n transporter.close();\r\n mailerPool.delete(hash);\r\n }\r\n\r\n log.info(\"mail\", \"pool\", \"Closed all mailer transports\");\r\n}\r\n\r\n/**\r\n * Get pool statistics\r\n */\r\nexport function getPoolStats(): { size: number; hashes: string[] } {\r\n return {\r\n size: mailerPool.size,\r\n hashes: Array.from(mailerPool.keys()),\r\n };\r\n}\r\n","import type { ComponentType, ReactElement, ReactNode } from \"react\";\n\n// ============================================================\n// Eager-loaded React Modules\n// ============================================================\n\n/**\n * Installation instructions for React\n */\nconst REACT_INSTALL_INSTRUCTIONS = `\nReact SSR functionality requires React packages.\nInstall them with:\n\n warlock add react\n\nOr manually:\n\n npm install react react-dom\n pnpm add react react-dom\n yarn add react react-dom\n`.trim();\n\n/**\n * Module availability flag\n */\nlet moduleExists: boolean | null = null;\n\n/**\n * Cached React modules (loaded at import time)\n */\nlet react: typeof import(\"react\");\nlet reactDomServer: typeof import(\"react-dom/server\");\n\n/**\n * Eagerly load React modules at import time\n */\nasync function loadReactModules() {\n try {\n react = await import(\"react\");\n reactDomServer = await import(\"react-dom/server\");\n moduleExists = true;\n } catch {\n moduleExists = false;\n }\n}\n\n// Kick off eager loading immediately\nloadReactModules();\n\n// ============================================================\n// Render Function\n// ============================================================\n\n/**\n * Render a React element/component to HTML string\n *\n * **Important:** This function requires React packages to be installed.\n * Install them with: `warlock add react` or `yarn add react react-dom`\n *\n * @example\n * ```typescript\n * const html = renderReact(<WelcomeEmail name=\"John\" />);\n * ```\n */\nexport function renderReact(reactElement: ReactElement | ComponentType | ReactNode): string {\n if (moduleExists === false) {\n throw new Error(`react is not installed.\\n\\n${REACT_INSTALL_INSTRUCTIONS}`);\n }\n\n if (typeof reactElement === \"function\") {\n reactElement = react.createElement(reactElement);\n }\n\n return reactDomServer.renderToString(reactElement);\n}\n","import type React from \"react\";\r\nimport { renderReact } from \"../react\";\r\n\r\n/**\r\n * Create a complete HTML page from rendered content\r\n */\r\nfunction createHtmlPage(html: string): string {\r\n const styles: string[] = [];\r\n const links: string[] = [];\r\n\r\n const body = html.replace(/<style.*?<\\/style>|<link.*?>/gims, (match: string) => {\r\n if (match.startsWith(\"<style\")) {\r\n styles.push(match);\r\n } else {\r\n links.push(match);\r\n }\r\n return \"\";\r\n });\r\n\r\n const head = `<head>${links.join(\"\")}${styles.join(\"\")}</head>`;\r\n\r\n return `<!doctype html><html>${head}<body>${body}</body></html>`;\r\n}\r\n\r\n/**\r\n * Render a React element to HTML for email\r\n *\r\n * **Note:** This function requires React packages to be installed.\r\n * Install them with: `warlock add react` or `npm install react react-dom`\r\n */\r\nexport function renderReactMail(element: React.ReactElement | React.ComponentType): string {\r\n const content = renderReact(element);\r\n\r\n return createHtmlPage(content);\r\n}\r\n","/**\r\n * Test Mailbox for Mail v2\r\n *\r\n * Provides utilities for capturing and asserting sent emails in test mode.\r\n *\r\n * ## Setup\r\n *\r\n * ```typescript\r\n * import { setMailMode, clearTestMailbox } from \"@warlock.js/core/mail/v2\";\r\n *\r\n * beforeEach(() => {\r\n * setMailMode(\"test\");\r\n * clearTestMailbox();\r\n * });\r\n * ```\r\n *\r\n * ## Usage\r\n *\r\n * ```typescript\r\n * import { sendMail, getTestMailbox, findMailsTo } from \"@warlock.js/core/mail/v2\";\r\n *\r\n * // Send email in test mode\r\n * await sendMail({\r\n * to: \"user@example.com\",\r\n * subject: \"Welcome!\",\r\n * html: \"<p>Hello</p>\",\r\n * });\r\n *\r\n * // Get all captured mails\r\n * const mails = getTestMailbox();\r\n * expect(mails).toHaveLength(1);\r\n * expect(mails[0].options.subject).toBe(\"Welcome!\");\r\n *\r\n * // Find specific mails\r\n * const userMails = findMailsTo(\"user@example.com\");\r\n * expect(userMails).toHaveLength(1);\r\n *\r\n * // Check if mail was sent\r\n * expect(wasMailSentTo(\"user@example.com\")).toBe(true);\r\n * expect(wasMailSentWithSubject(\"Welcome!\")).toBe(true);\r\n * ```\r\n *\r\n * ## Assertion Helpers\r\n *\r\n * ```typescript\r\n * // Assert a mail matching a predicate was sent\r\n * const mail = assertMailSent(m => m.options.to === \"user@example.com\");\r\n * expect(mail.options.subject).toBe(\"Welcome!\");\r\n *\r\n * // Assert exact count\r\n * assertMailCount(2); // throws if count doesn't match\r\n * ```\r\n *\r\n * ## Captured Mail Structure\r\n *\r\n * Each captured mail contains:\r\n * - `options` - Original MailOptions passed to sendMail\r\n * - `normalized` - Normalized mail data (arrays, addresses resolved)\r\n * - `timestamp` - When the mail was captured\r\n * - `result` - MailResult (in test mode, always success)\r\n * - `error` - MailError if sending failed (null in test mode)\r\n *\r\n * @module test-mailbox\r\n */\r\n\r\nimport type { CapturedMail } from \"./types\";\r\n\r\n/**\r\n * Test mailbox for capturing sent emails in test mode\r\n */\r\nlet testMailbox: CapturedMail[] = [];\r\n\r\n/**\r\n * Add a mail to the test mailbox\r\n */\r\nexport function captureMail(mail: CapturedMail): void {\r\n testMailbox.push(mail);\r\n}\r\n\r\n/**\r\n * Get all captured mails\r\n */\r\nexport function getTestMailbox(): CapturedMail[] {\r\n return [...testMailbox];\r\n}\r\n\r\n/**\r\n * Get the last captured mail\r\n */\r\nexport function getLastMail(): CapturedMail | undefined {\r\n return testMailbox[testMailbox.length - 1];\r\n}\r\n\r\n/**\r\n * Find mails by recipient\r\n */\r\nexport function findMailsTo(email: string): CapturedMail[] {\r\n return testMailbox.filter((mail) => {\r\n const to = Array.isArray(mail.options.to) ? mail.options.to : [mail.options.to];\r\n return to.includes(email);\r\n });\r\n}\r\n\r\n/**\r\n * Find mails by subject (partial match)\r\n */\r\nexport function findMailsBySubject(subject: string): CapturedMail[] {\r\n return testMailbox.filter((mail) => mail.options.subject.includes(subject));\r\n}\r\n\r\n/**\r\n * Check if a mail was sent to a specific recipient\r\n */\r\nexport function wasMailSentTo(email: string): boolean {\r\n return findMailsTo(email).length > 0;\r\n}\r\n\r\n/**\r\n * Check if a mail with specific subject was sent\r\n */\r\nexport function wasMailSentWithSubject(subject: string): boolean {\r\n return testMailbox.some((mail) => mail.options.subject === subject);\r\n}\r\n\r\n/**\r\n * Get mailbox size\r\n */\r\nexport function getMailboxSize(): number {\r\n return testMailbox.length;\r\n}\r\n\r\n/**\r\n * Clear the test mailbox\r\n */\r\nexport function clearTestMailbox(): void {\r\n testMailbox = [];\r\n}\r\n\r\n/**\r\n * Assert helper for testing\r\n */\r\nexport function assertMailSent(predicate: (mail: CapturedMail) => boolean): CapturedMail {\r\n const mail = testMailbox.find(predicate);\r\n\r\n if (!mail) {\r\n throw new Error(\"No mail matching the predicate was found in the test mailbox\");\r\n }\r\n\r\n return mail;\r\n}\r\n\r\n/**\r\n * Assert that a specific number of mails were sent\r\n */\r\nexport function assertMailCount(count: number): void {\r\n if (testMailbox.length !== count) {\r\n throw new Error(`Expected ${count} mails to be sent, but found ${testMailbox.length}`);\r\n }\r\n}\r\n","import type SMTPTransport from \"nodemailer/lib/smtp-transport\";\r\nimport type React from \"react\";\r\n\r\n/**\r\n * Mail mode determines how emails are handled\r\n */\r\nexport type MailMode = \"production\" | \"development\" | \"test\";\r\n\r\n/**\r\n * Mail priority levels\r\n */\r\nexport type MailPriority = \"high\" | \"normal\" | \"low\";\r\n\r\n/**\r\n * Email address with optional name\r\n */\r\nexport type MailAddress =\r\n | string\r\n | {\r\n name: string;\r\n address: string;\r\n };\r\n\r\n/**\r\n * Mail attachment\r\n * Supports both buffer/string content and file paths\r\n */\r\nexport type MailAttachment = {\r\n filename: string;\r\n contentType?: string;\r\n encoding?: \"base64\" | \"binary\" | \"hex\";\r\n cid?: string; // Content-ID for inline attachments\r\n} & (\r\n | {\r\n content: Buffer | string;\r\n path?: never;\r\n }\r\n | {\r\n content?: never;\r\n path: string; // File path - will be read automatically\r\n }\r\n);\r\n\r\n/**\r\n * Mail configuration for SMTP transport\r\n *\r\n * ## Basic Configuration\r\n *\r\n * ```typescript\r\n * setMailConfigurations({\r\n * host: \"smtp.gmail.com\",\r\n * port: 587,\r\n * secure: false, // true for 465, false for other ports\r\n * tls: true, // Use STARTTLS\r\n * username: \"user@gmail.com\",\r\n * password: \"app-password\",\r\n * from: { name: \"My App\", address: \"noreply@myapp.com\" },\r\n * });\r\n * ```\r\n *\r\n * ## Configuration Options\r\n *\r\n * | Option | Type | Default | Description |\r\n * |--------|------|---------|-------------|\r\n * | `host` | `string` | - | SMTP server hostname (e.g., \"smtp.gmail.com\") |\r\n * | `port` | `number` | 587 | SMTP port. Common: 25, 465 (SSL), 587 (TLS) |\r\n * | `secure` | `boolean` | false | Use SSL/TLS. Set `true` for port 465 |\r\n * | `tls` | `boolean` | true | Enable STARTTLS upgrade. For port 587 |\r\n * | `requireTLS` | `boolean` | - | Fail if STARTTLS upgrade fails |\r\n * | `username` | `string` | - | SMTP auth username (convenience alias) |\r\n * | `password` | `string` | - | SMTP auth password (convenience alias) |\r\n * | `auth` | `object` | - | Full auth object: `{ user, pass, type }` |\r\n * | `from` | `MailAddress` | - | Default sender for all emails |\r\n *\r\n * ## Provider Examples\r\n *\r\n * ### Gmail\r\n * ```typescript\r\n * { host: \"smtp.gmail.com\", port: 587, tls: true, username: \"...\", password: \"...\" }\r\n * ```\r\n *\r\n * ### SendGrid\r\n * ```typescript\r\n * { host: \"smtp.sendgrid.net\", port: 587, username: \"apikey\", password: \"SG.xxx\" }\r\n * ```\r\n *\r\n * ### AWS SES\r\n * ```typescript\r\n * { host: \"email-smtp.us-east-1.amazonaws.com\", port: 587, username: \"...\", password: \"...\" }\r\n * ```\r\n *\r\n * ### Mailgun\r\n * ```typescript\r\n * { host: \"smtp.mailgun.org\", port: 587, username: \"postmaster@...\", password: \"...\" }\r\n * ```\r\n *\r\n * ## Multi-tenant Usage\r\n *\r\n * For multi-tenant apps, pass config per-mail instead of globally:\r\n * ```typescript\r\n * await sendMail({\r\n * config: tenant.mailSettings, // Tenant-specific config\r\n * to: \"user@example.com\",\r\n * subject: \"Hello\",\r\n * html: \"<p>World</p>\",\r\n * });\r\n * ```\r\n */\r\nexport type MailConfigurations = SMTPTransport.Options & {\r\n /**\r\n * Enable STARTTLS upgrade (alias for requireTLS)\r\n * Set to `true` for port 587\r\n */\r\n tls?: boolean;\r\n /**\r\n * SMTP authentication username\r\n * Convenience alias - can also use `auth.user`\r\n */\r\n username?: string;\r\n /**\r\n * SMTP authentication password\r\n * Convenience alias - can also use `auth.pass`\r\n */\r\n password?: string;\r\n /**\r\n * Default sender for all emails\r\n * Can be string (\"noreply@app.com\") or object ({ name, address })\r\n */\r\n from?: MailAddress;\r\n};\r\n\r\n/**\r\n * Named mailers configuration\r\n */\r\nexport type MailersConfig = {\r\n /**\r\n * Default mailer configuration\r\n */\r\n default?: MailConfigurations;\r\n /**\r\n * Named mailer configurations\r\n */\r\n mailers?: Record<string, MailConfigurations>;\r\n};\r\n\r\n/**\r\n * Mail result after sending\r\n */\r\nexport type MailResult = {\r\n success: boolean;\r\n messageId?: string;\r\n accepted: string[];\r\n rejected: string[];\r\n response?: string;\r\n envelope?: {\r\n from: string;\r\n to: string[];\r\n };\r\n};\r\n\r\n/**\r\n * Error codes for mail operations\r\n */\r\nexport type MailErrorCode =\r\n | \"CONNECTION_ERROR\"\r\n | \"AUTH_ERROR\"\r\n | \"RATE_LIMIT\"\r\n | \"INVALID_ADDRESS\"\r\n | \"REJECTED\"\r\n | \"TIMEOUT\"\r\n | \"RENDER_ERROR\"\r\n | \"CONFIG_ERROR\"\r\n | \"UNKNOWN\";\r\n\r\n/**\r\n * Mail event callbacks (per-mail)\r\n * For global events, use mailEvents.on() from events.ts\r\n */\r\nexport type MailEvents = {\r\n /**\r\n * Called before sending the email\r\n * Can be used to modify the mail or cancel sending\r\n */\r\n beforeSending?: (mail: MailOptions) => void | Promise<void> | false | Promise<false>;\r\n /**\r\n * Called after send attempt (success or failure)\r\n */\r\n onSent?: (\r\n mail: MailOptions,\r\n result: MailResult | null,\r\n error: MailError | null,\r\n ) => void | Promise<void>;\r\n /**\r\n * Called only on successful send\r\n */\r\n onSuccess?: (mail: MailOptions, result: MailResult) => void | Promise<void>;\r\n /**\r\n * Called only on error\r\n */\r\n onError?: (mail: MailOptions, error: MailError) => void | Promise<void>;\r\n};\r\n\r\n/**\r\n * Mail options for sending\r\n */\r\nexport type MailOptions = {\r\n /**\r\n * Unique mail ID for event namespacing\r\n * If not provided, one will be auto-generated\r\n *\r\n * Use this to subscribe to events for a specific mail:\r\n * ```typescript\r\n * const mailId = generateMailId();\r\n * mailEvents.onMailSuccess(mailId, (mail, result) => { ... });\r\n * await sendMail({ id: mailId, to: \"...\", subject: \"...\", html: \"...\" });\r\n * ```\r\n */\r\n id?: string;\r\n\r\n // Recipients\r\n to: string | string[];\r\n cc?: string | string[];\r\n bcc?: string | string[];\r\n replyTo?: string;\r\n\r\n // Content\r\n subject: string;\r\n html?: string;\r\n text?: string;\r\n component?: React.ReactElement;\r\n\r\n // Configuration\r\n config?: MailConfigurations;\r\n mailer?: string;\r\n from?: MailAddress;\r\n\r\n // Attachments\r\n attachments?: MailAttachment[];\r\n\r\n // Options\r\n priority?: MailPriority;\r\n headers?: Record<string, string>;\r\n tags?: string[];\r\n\r\n // Meta\r\n correlationId?: string;\r\n} & MailEvents;\r\n\r\n/**\r\n * Internal normalized mail data\r\n */\r\nexport type NormalizedMail = {\r\n to: string[];\r\n cc: string[];\r\n bcc: string[];\r\n replyTo?: string;\r\n from: MailAddress;\r\n subject: string;\r\n html?: string;\r\n text?: string;\r\n attachments: MailAttachment[];\r\n priority: MailPriority;\r\n headers: Record<string, string>;\r\n tags: string[];\r\n correlationId?: string;\r\n};\r\n\r\n/**\r\n * Captured mail for test mode\r\n */\r\nexport type CapturedMail = {\r\n options: MailOptions;\r\n normalized: NormalizedMail;\r\n timestamp: Date;\r\n result?: MailResult;\r\n error?: MailError;\r\n};\r\n\r\n/**\r\n * Mail error class\r\n */\r\nexport class MailError extends Error {\r\n public readonly code: MailErrorCode;\r\n public readonly originalError?: Error;\r\n\r\n public constructor(message: string, code: MailErrorCode, originalError?: Error) {\r\n super(message);\r\n this.name = \"MailError\";\r\n this.code = code;\r\n this.originalError = originalError;\r\n }\r\n}\r\n","import { log } from \"@warlock.js/logger\";\r\nimport { readFile } from \"node:fs/promises\";\r\nimport type { Options as NodemailerOptions } from \"nodemailer/lib/mailer\";\r\nimport { isDevelopmentMode, isTestMode, resolveMailConfig } from \"./config\";\r\nimport { MAIL_EVENTS, generateMailId, mailEvents } from \"./events\";\r\nimport { getMailer } from \"./mailer-pool\";\r\nimport { renderReactMail } from \"./react-mail\";\r\nimport { captureMail } from \"./test-mailbox\";\r\nimport {\r\n MailError,\r\n type CapturedMail,\r\n type MailAddress,\r\n type MailAttachment,\r\n type MailOptions,\r\n type MailPriority,\r\n type MailResult,\r\n type NormalizedMail,\r\n} from \"./types\";\r\n\r\n/**\r\n * Normalize email address to string\r\n */\r\nfunction addressToString(address: MailAddress): string {\r\n if (typeof address === \"string\") {\r\n return address;\r\n }\r\n\r\n return `\"${address.name}\" <${address.address}>`;\r\n}\r\n\r\n/**\r\n * Normalize recipients to array\r\n */\r\nfunction normalizeRecipients(recipients: string | string[] | undefined): string[] {\r\n if (!recipients) {\r\n return [];\r\n }\r\n\r\n return Array.isArray(recipients) ? recipients : [recipients];\r\n}\r\n\r\n/**\r\n * Map priority to nodemailer format\r\n */\r\nfunction mapPriority(priority: MailPriority): \"high\" | \"normal\" | \"low\" {\r\n return priority;\r\n}\r\n\r\n/**\r\n * Normalize mail options to internal format\r\n */\r\nfunction normalizeMail(options: MailOptions): NormalizedMail {\r\n const config = resolveMailConfig(options);\r\n\r\n return {\r\n to: normalizeRecipients(options.to),\r\n cc: normalizeRecipients(options.cc),\r\n bcc: normalizeRecipients(options.bcc),\r\n replyTo: options.replyTo,\r\n from: options.from || config.from || { name: \"No Reply\", address: \"noreply@localhost\" },\r\n subject: options.subject,\r\n html: options.html,\r\n text: options.text,\r\n attachments: options.attachments || [],\r\n priority: options.priority || \"normal\",\r\n headers: options.headers || {},\r\n tags: options.tags || [],\r\n correlationId: options.correlationId,\r\n };\r\n}\r\n\r\n/**\r\n * Resolve attachment - read file if path is provided\r\n */\r\nasync function resolveAttachment(attachment: MailAttachment): Promise<{\r\n filename: string;\r\n content: Buffer | string;\r\n contentType?: string;\r\n encoding?: string;\r\n cid?: string;\r\n}> {\r\n // If path is provided, read the file\r\n if (attachment.path) {\r\n try {\r\n const content = await readFile(attachment.path);\r\n return {\r\n filename: attachment.filename,\r\n content,\r\n contentType: attachment.contentType,\r\n encoding: attachment.encoding,\r\n cid: attachment.cid,\r\n };\r\n } catch (error) {\r\n throw new MailError(\r\n `Failed to read attachment file \"${attachment.path}\": ${error instanceof Error ? error.message : \"Unknown error\"}`,\r\n \"CONFIG_ERROR\",\r\n error instanceof Error ? error : undefined,\r\n );\r\n }\r\n }\r\n\r\n // Already has content\r\n return {\r\n filename: attachment.filename,\r\n content: attachment.content!,\r\n contentType: attachment.contentType,\r\n encoding: attachment.encoding,\r\n cid: attachment.cid,\r\n };\r\n}\r\n\r\n/**\r\n * Build nodemailer options from normalized mail\r\n */\r\nasync function buildNodemailerOptions(normalized: NormalizedMail): Promise<NodemailerOptions> {\r\n const options: NodemailerOptions = {\r\n to: normalized.to,\r\n from: addressToString(normalized.from),\r\n subject: normalized.subject,\r\n priority: mapPriority(normalized.priority),\r\n };\r\n\r\n if (normalized.cc.length > 0) {\r\n options.cc = normalized.cc;\r\n }\r\n\r\n if (normalized.bcc.length > 0) {\r\n options.bcc = normalized.bcc;\r\n }\r\n\r\n if (normalized.replyTo) {\r\n options.replyTo = normalized.replyTo;\r\n }\r\n\r\n if (normalized.html) {\r\n options.html = normalized.html;\r\n }\r\n\r\n if (normalized.text) {\r\n options.text = normalized.text;\r\n }\r\n\r\n if (normalized.attachments.length > 0) {\r\n // Resolve all attachments (read files if needed)\r\n const resolvedAttachments = await Promise.all(\r\n normalized.attachments.map((att) => resolveAttachment(att as MailAttachment)),\r\n );\r\n\r\n options.attachments = resolvedAttachments.map((att) => ({\r\n filename: att.filename,\r\n content: att.content,\r\n contentType: att.contentType,\r\n encoding: att.encoding,\r\n cid: att.cid,\r\n }));\r\n }\r\n\r\n if (Object.keys(normalized.headers).length > 0) {\r\n options.headers = normalized.headers;\r\n }\r\n\r\n return options;\r\n}\r\n\r\n/**\r\n * Run per-mail event handler\r\n */\r\nasync function runMailEvent<T extends (...args: any[]) => any>(\r\n handler: T | undefined,\r\n ...args: Parameters<T>\r\n): Promise<ReturnType<T> | undefined> {\r\n if (!handler) {\r\n return undefined;\r\n }\r\n\r\n try {\r\n return await handler(...args);\r\n } catch (error) {\r\n log.error(\"mail\", \"event\", `Per-mail event handler error: ${error}`);\r\n return undefined;\r\n }\r\n}\r\n\r\n/**\r\n * Trigger both global and mail-specific events\r\n */\r\nasync function triggerEvents(\r\n mailId: string,\r\n event: \"beforeSending\" | \"sent\" | \"success\" | \"error\",\r\n ...args: any[]\r\n): Promise<any[]> {\r\n try {\r\n // Trigger global event (e.g., mail.success)\r\n const globalEventName =\r\n event === \"beforeSending\"\r\n ? \"BEFORE_SENDING\"\r\n : event === \"sent\"\r\n ? \"SENT\"\r\n : event === \"success\"\r\n ? \"SUCCESS\"\r\n : \"ERROR\";\r\n\r\n const globalResults = await mailEvents.trigger(\r\n globalEventName as keyof typeof MAIL_EVENTS,\r\n ...args,\r\n );\r\n\r\n // Trigger mail-specific event (e.g., mail.$id.success)\r\n const specificResults = await mailEvents.triggerForMail(mailId, event, ...args);\r\n\r\n return [...globalResults, ...specificResults];\r\n } catch (error) {\r\n log.error(\"mail\", \"event\", `Event handler error: ${error}`);\r\n return [];\r\n }\r\n}\r\n\r\n/**\r\n * Send an email\r\n *\r\n * @param options Mail options including recipients, content, and configuration\r\n * @returns Result containing success status, message ID, and accepted/rejected recipients\r\n *\r\n * @example\r\n * ```typescript\r\n * // Basic usage\r\n * await sendMail({\r\n * to: \"user@example.com\",\r\n * subject: \"Hello\",\r\n * html: \"<p>World</p>\",\r\n * });\r\n *\r\n * // With React component\r\n * await sendMail({\r\n * to: \"user@example.com\",\r\n * subject: \"Welcome!\",\r\n * component: <WelcomeEmail name=\"John\" />,\r\n * });\r\n *\r\n * // Track specific mail with events\r\n * const mailId = generateMailId();\r\n * mailEvents.onMailSuccess(mailId, (mail, result) => {\r\n * console.log(\"This specific mail was sent!\");\r\n * });\r\n * await sendMail({ id: mailId, to: \"...\", subject: \"...\", html: \"...\" });\r\n * ```\r\n */\r\nexport async function sendMail(options: MailOptions): Promise<MailResult> {\r\n // Generate or use provided mail ID\r\n const mailId = options.id || generateMailId();\r\n\r\n // Render React component if provided\r\n if (options.component) {\r\n try {\r\n options.html = renderReactMail(options.component);\r\n } catch (error) {\r\n const mailError = new MailError(\r\n `Failed to render React component: ${error instanceof Error ? error.message : \"Unknown error\"}`,\r\n \"RENDER_ERROR\",\r\n error instanceof Error ? error : undefined,\r\n );\r\n\r\n await runMailEvent(options.onError, options, mailError);\r\n await triggerEvents(mailId, \"error\", options, mailError);\r\n\r\n throw mailError;\r\n }\r\n }\r\n\r\n // Normalize mail\r\n const normalized = normalizeMail(options);\r\n\r\n // Run beforeSending event (per-mail, global, and mail-specific)\r\n const beforeResult = await runMailEvent(options.beforeSending, options);\r\n const globalBeforeResults = await triggerEvents(mailId, \"beforeSending\", options);\r\n\r\n // If any returns false, cancel sending\r\n if (beforeResult === false || globalBeforeResults.some((r) => r === false)) {\r\n log.info(\"mail\", \"cancelled\", \"Mail sending cancelled by beforeSending event\");\r\n\r\n const result: MailResult = {\r\n success: false,\r\n accepted: [],\r\n rejected: normalized.to,\r\n response: \"Cancelled by beforeSending event\",\r\n };\r\n\r\n return result;\r\n }\r\n\r\n // Test mode - capture without sending\r\n if (isTestMode()) {\r\n log.info(\"mail\", \"test\", `[TEST MODE] Captured mail to: ${normalized.to.join(\", \")}`);\r\n\r\n const result: MailResult = {\r\n success: true,\r\n messageId: `test-${mailId}@localhost`,\r\n accepted: normalized.to,\r\n rejected: [],\r\n response: \"Test mode - mail captured\",\r\n };\r\n\r\n const captured: CapturedMail = {\r\n options,\r\n normalized,\r\n timestamp: new Date(),\r\n result,\r\n };\r\n\r\n captureMail(captured);\r\n\r\n await runMailEvent(options.onSuccess, options, result);\r\n await triggerEvents(mailId, \"success\", options, result);\r\n await runMailEvent(options.onSent, options, result, null);\r\n await triggerEvents(mailId, \"sent\", options, result, null);\r\n\r\n return result;\r\n }\r\n\r\n // Development mode - log without sending\r\n if (isDevelopmentMode()) {\r\n log.info(\"mail\", \"dev\", `[DEV MODE] Would send mail to: ${normalized.to.join(\", \")}`);\r\n log.info(\"mail\", \"dev\", `Subject: ${normalized.subject}`);\r\n\r\n if (normalized.html) {\r\n log.info(\"mail\", \"dev\", `HTML length: ${normalized.html.length} chars`);\r\n }\r\n\r\n const result: MailResult = {\r\n success: true,\r\n messageId: `dev-${mailId}@localhost`,\r\n accepted: normalized.to,\r\n rejected: [],\r\n response: \"Development mode - mail logged\",\r\n };\r\n\r\n await runMailEvent(options.onSuccess, options, result);\r\n await triggerEvents(mailId, \"success\", options, result);\r\n await runMailEvent(options.onSent, options, result, null);\r\n await triggerEvents(mailId, \"sent\", options, result, null);\r\n\r\n return result;\r\n }\r\n\r\n // Production mode - actually send\r\n try {\r\n const config = resolveMailConfig(options);\r\n const mailer = getMailer(config);\r\n const nodemailerOptions = await buildNodemailerOptions(normalized);\r\n\r\n log.info(\"mail\", \"send\", `Sending mail to: ${normalized.to.join(\", \")}`);\r\n\r\n const output = await mailer.sendMail(nodemailerOptions);\r\n\r\n const result: MailResult = {\r\n success: output.accepted.length > 0,\r\n messageId: output.messageId,\r\n accepted: output.accepted as string[],\r\n rejected: output.rejected as string[],\r\n response: output.response,\r\n envelope: output.envelope,\r\n };\r\n\r\n if (result.success) {\r\n log.success(\"mail\", \"sent\", `Mail sent successfully (ID: ${result.messageId})`);\r\n await runMailEvent(options.onSuccess, options, result);\r\n await triggerEvents(mailId, \"success\", options, result);\r\n } else {\r\n log.warn(\"mail\", \"partial\", `Mail partially rejected: ${result.rejected.join(\", \")}`);\r\n }\r\n\r\n await runMailEvent(options.onSent, options, result, null);\r\n await triggerEvents(mailId, \"sent\", options, result, null);\r\n\r\n return result;\r\n } catch (error) {\r\n const errorMessage = error instanceof Error ? error.message : \"Unknown error\";\r\n let code: MailError[\"code\"] = \"UNKNOWN\";\r\n\r\n // Detect error type\r\n if (errorMessage.includes(\"ECONNREFUSED\") || errorMessage.includes(\"ENOTFOUND\")) {\r\n code = \"CONNECTION_ERROR\";\r\n } else if (errorMessage.includes(\"authentication\") || errorMessage.includes(\"auth\")) {\r\n code = \"AUTH_ERROR\";\r\n } else if (errorMessage.includes(\"timeout\") || errorMessage.includes(\"ETIMEDOUT\")) {\r\n code = \"TIMEOUT\";\r\n } else if (errorMessage.includes(\"rate\") || errorMessage.includes(\"limit\")) {\r\n code = \"RATE_LIMIT\";\r\n }\r\n\r\n const mailError = new MailError(\r\n `Failed to send mail: ${errorMessage}`,\r\n code,\r\n error instanceof Error ? error : undefined,\r\n );\r\n\r\n log.error(\"mail\", \"error\", mailError.message);\r\n\r\n await runMailEvent(options.onError, options, mailError);\r\n await triggerEvents(mailId, \"error\", options, mailError);\r\n await runMailEvent(options.onSent, options, null, mailError);\r\n await triggerEvents(mailId, \"sent\", options, null, mailError);\r\n\r\n throw mailError;\r\n }\r\n}\r\n","import type React from \"react\";\r\nimport { sendMail } from \"./send-mail\";\r\nimport type {\r\n MailAddress,\r\n MailAttachment,\r\n MailConfigurations,\r\n MailEvents,\r\n MailOptions,\r\n MailPriority,\r\n MailResult,\r\n} from \"./types\";\r\n\r\n/**\r\n * Fluent Mail Builder\r\n *\r\n * Provides a chainable API for building and sending emails.\r\n *\r\n * @example\r\n * ```typescript\r\n * await Mail.to(\"user@example.com\")\r\n * .subject(\"Welcome!\")\r\n * .component(<WelcomeEmail name=\"John\" />)\r\n * .send();\r\n *\r\n * // With attachments\r\n * await Mail.to(\"user@example.com\")\r\n * .cc(\"manager@example.com\")\r\n * .subject(\"Invoice\")\r\n * .component(<InvoiceEmail order={order} />)\r\n * .attach(pdfBuffer, \"invoice.pdf\")\r\n * .send();\r\n *\r\n * // Multi-tenant\r\n * await Mail.config(tenant.mailSettings)\r\n * .to(\"user@example.com\")\r\n * .subject(\"Hello\")\r\n * .html(\"<p>World</p>\")\r\n * .send();\r\n * ```\r\n */\r\nexport class Mail {\r\n private options: Partial<MailOptions> = {};\r\n\r\n /**\r\n * Private constructor - use static factory methods\r\n */\r\n private constructor() {}\r\n\r\n /**\r\n * Create a new mail with recipient\r\n */\r\n public static to(recipient: string | string[]): Mail {\r\n const mail = new Mail();\r\n mail.options.to = recipient;\r\n\r\n return mail;\r\n }\r\n\r\n /**\r\n * Create a new mail with custom configuration (multi-tenant)\r\n */\r\n public static config(config: MailConfigurations): Mail {\r\n const mail = new Mail();\r\n mail.options.config = config;\r\n\r\n return mail;\r\n }\r\n\r\n /**\r\n * Create a new mail with named mailer\r\n */\r\n public static mailer(name: string): Mail {\r\n const mail = new Mail();\r\n mail.options.mailer = name;\r\n\r\n return mail;\r\n }\r\n\r\n /**\r\n * Set recipient(s)\r\n */\r\n public to(recipient: string | string[]): this {\r\n this.options.to = recipient;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Set CC recipient(s)\r\n */\r\n public cc(recipient: string | string[]): this {\r\n this.options.cc = recipient;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Set BCC recipient(s)\r\n */\r\n public bcc(recipient: string | string[]): this {\r\n this.options.bcc = recipient;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Set reply-to address\r\n */\r\n public replyTo(address: string): this {\r\n this.options.replyTo = address;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Set from address\r\n */\r\n public from(address: MailAddress): this {\r\n this.options.from = address;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Set subject\r\n */\r\n public subject(subject: string): this {\r\n this.options.subject = subject;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Set HTML content\r\n */\r\n public html(content: string): this {\r\n this.options.html = content;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Set plain text content\r\n */\r\n public text(content: string): this {\r\n this.options.text = content;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Set React component as content\r\n */\r\n public component(element: React.ReactElement): this {\r\n this.options.component = element;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Add attachment\r\n */\r\n public attach(content: Buffer | string, filename: string, contentType?: string): this {\r\n if (!this.options.attachments) {\r\n this.options.attachments = [];\r\n }\r\n\r\n this.options.attachments.push({\r\n filename,\r\n content,\r\n contentType,\r\n });\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Add multiple attachments\r\n */\r\n public attachments(attachments: MailAttachment[]): this {\r\n this.options.attachments = [...(this.options.attachments || []), ...attachments];\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Attach a file by path\r\n *\r\n * The file will be read automatically when the email is sent.\r\n *\r\n * @param path Path to the file\r\n * @param filename Optional custom filename (defaults to basename of path)\r\n * @param contentType Optional MIME type\r\n *\r\n * @example\r\n * ```typescript\r\n * Mail.to(\"user@example.com\")\r\n * .subject(\"Invoice\")\r\n * .html(\"<p>Please see attached</p>\")\r\n * .attachFile(\"./invoices/2024-001.pdf\")\r\n * .attachFile(\"./terms.pdf\", \"terms-and-conditions.pdf\")\r\n * .send();\r\n * ```\r\n */\r\n public attachFile(path: string, filename?: string, contentType?: string): this {\r\n if (!this.options.attachments) {\r\n this.options.attachments = [];\r\n }\r\n\r\n // Extract filename from path if not provided\r\n const resolvedFilename = filename || path.split(/[/\\\\]/).pop() || \"attachment\";\r\n\r\n this.options.attachments.push({\r\n path,\r\n filename: resolvedFilename,\r\n contentType,\r\n });\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Set priority\r\n */\r\n public priority(level: MailPriority): this {\r\n this.options.priority = level;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Set custom headers\r\n */\r\n public headers(headers: Record<string, string>): this {\r\n this.options.headers = { ...this.options.headers, ...headers };\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Add a custom header\r\n */\r\n public header(name: string, value: string): this {\r\n this.options.headers = { ...this.options.headers, [name]: value };\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Set tags for categorization\r\n */\r\n public tags(tags: string[]): this {\r\n this.options.tags = tags;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Add a tag\r\n */\r\n public tag(tag: string): this {\r\n this.options.tags = [...(this.options.tags || []), tag];\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Set correlation ID for tracking\r\n */\r\n public correlationId(id: string): this {\r\n this.options.correlationId = id;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Set configuration (multi-tenant)\r\n */\r\n public withConfig(config: MailConfigurations): this {\r\n this.options.config = config;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Set named mailer\r\n */\r\n public withMailer(name: string): this {\r\n this.options.mailer = name;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Set beforeSending event handler\r\n */\r\n public beforeSending(handler: MailEvents[\"beforeSending\"]): this {\r\n this.options.beforeSending = handler;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Set onSent event handler\r\n */\r\n public onSent(handler: MailEvents[\"onSent\"]): this {\r\n this.options.onSent = handler;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Set onSuccess event handler\r\n */\r\n public onSuccess(handler: MailEvents[\"onSuccess\"]): this {\r\n this.options.onSuccess = handler;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Set onError event handler\r\n */\r\n public onError(handler: MailEvents[\"onError\"]): this {\r\n this.options.onError = handler;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Get the built options (for debugging)\r\n */\r\n public getOptions(): Partial<MailOptions> {\r\n return { ...this.options };\r\n }\r\n\r\n /**\r\n * Validate the mail before sending\r\n */\r\n private validate(): void {\r\n if (!this.options.to) {\r\n throw new Error(\"Mail recipient (to) is required\");\r\n }\r\n\r\n if (!this.options.subject) {\r\n throw new Error(\"Mail subject is required\");\r\n }\r\n\r\n if (!this.options.html && !this.options.text && !this.options.component) {\r\n throw new Error(\"Mail content (html, text, or component) is required\");\r\n }\r\n }\r\n\r\n /**\r\n * Send the email\r\n */\r\n public async send(): Promise<MailResult> {\r\n this.validate();\r\n\r\n return sendMail(this.options as MailOptions);\r\n }\r\n}\r\n","import { SpecialConfigHandler } from \"./config-loader\";\n\nexport class ConfigSpecialHandlers {\n /**\n * Handlers\n */\n protected handlers: Map<string, SpecialConfigHandler> = new Map();\n\n /**\n * Register a new handler\n */\n public register(configName: string, handler: SpecialConfigHandler) {\n this.handlers.set(configName, handler);\n }\n\n /**\n * Execute handler for the given config name\n */\n public async execute(configName: string, config: any) {\n const handler = this.handlers.get(configName);\n if (!handler) {\n return; // do nothing\n }\n\n return handler(config);\n }\n}\n\nexport const configSpecialHandlers = new ConfigSpecialHandlers();\n","import { LogConfigurations, setLogConfigurations } from \"../logger\";\r\nimport { MailConfigurations, setMailConfigurations } from \"../mail\";\r\nimport { AppConfigurations } from \"../utils/types\";\r\nimport { configSpecialHandlers } from \"./config-special-handlers\";\r\n\r\n/**\r\n * App Config Handler\r\n * Handles locale loading for dayjs\r\n */\r\nexport const registerAppConfig = async (config: AppConfigurations) => {\r\n // Load dayjs locales based on app.localeCodes\r\n const locales = config.locales || [\"en\"];\r\n\r\n for (const locale of locales) {\r\n if (locale === \"en\") continue; // English is default\r\n\r\n try {\r\n await import(`dayjs/locale/${locale}.js`);\r\n } catch (error) {\r\n console.warn(` ⚠️ Failed to load dayjs locale: ${locale}`);\r\n }\r\n }\r\n};\r\n\r\nconfigSpecialHandlers.register(\"app\", registerAppConfig);\r\n\r\n/**\r\n * Log Config Handler\r\n * Sets log configurations in @warlock.js/core\r\n */\r\nexport const registerLogConfig = async (logConfig: LogConfigurations) => {\r\n try {\r\n setLogConfigurations(logConfig);\r\n } catch (error) {\r\n // @warlock.js/core might not be available in all projects\r\n console.warn(\" ⚠️ Could not set log configurations\");\r\n }\r\n};\r\n\r\nconfigSpecialHandlers.register(\"log\", registerLogConfig);\r\n\r\n/**\r\n * Mail Config Handler\r\n * Sets mail configurations in @warlock.js/core\r\n */\r\nexport const registerMailConfig = async (mailConfig: MailConfigurations) => {\r\n try {\r\n setMailConfigurations(mailConfig);\r\n } catch (error) {\r\n // @warlock.js/core might not be available in all projects\r\n console.warn(\" ⚠️ Could not set mail configurations\");\r\n }\r\n};\r\n\r\nconfigSpecialHandlers.register(\"mail\", registerMailConfig);\r\n","export class ResourceNotFoundError extends Error {\r\n public constructor(\r\n message: string,\r\n public payload?: any,\r\n ) {\r\n super(message);\r\n this.name = \"ResourceNotFoundError\";\r\n }\r\n}\r\n\r\nexport class UnAuthorizedError extends Error {\r\n public constructor(\r\n message: string,\r\n public payload?: any,\r\n ) {\r\n super(message);\r\n this.name = \"UnAuthorizedError\";\r\n }\r\n}\r\n\r\nexport class ForbiddenError extends Error {\r\n public constructor(\r\n message: string,\r\n public payload?: any,\r\n ) {\r\n super(message);\r\n this.name = \"ForbiddenError\";\r\n }\r\n}\r\n\r\nexport class BadRequestError extends Error {\r\n public constructor(\r\n message: string,\r\n public payload?: any,\r\n ) {\r\n super(message);\r\n this.name = \"BadRequestError\";\r\n }\r\n}\r\n\r\nexport class ServerError extends Error {\r\n public constructor(\r\n message: string,\r\n public payload?: any,\r\n ) {\r\n super(message);\r\n this.name = \"ServerError\";\r\n }\r\n}\r\n","/**\r\n * Request Context Middleware\r\n *\r\n * Creates a unified context for each request using the ContextManager.\r\n * All framework contexts (request, storage, database) are available throughout the request lifecycle.\r\n */\r\nimport { trans } from \"@mongez/localization\";\r\nimport { DatabaseWriterValidationError } from \"@warlock.js/cascade\";\r\nimport { contextManager } from \"@warlock.js/context\";\r\nimport {\r\n requestContext as requestContextInstance,\r\n useRequestStore,\r\n} from \"../context/request-context\";\r\nimport {\r\n BadRequestError,\r\n ForbiddenError,\r\n ResourceNotFoundError,\r\n ServerError,\r\n UnAuthorizedError,\r\n} from \"../errors\";\r\nimport { type Request } from \"../request\";\r\nimport { type Response } from \"../response\";\r\nimport { type ReturnedResponse } from \"./../types\";\r\n\r\n// Contexts are now registered in core/context/init-contexts.ts via initializeContexts()\r\n\r\n/**\r\n * Create request store and execute middleware + handler\r\n *\r\n * Runs all registered contexts together using ContextManager.\r\n */\r\nexport function createRequestStore(\r\n request: Request<any>,\r\n response: Response,\r\n): Promise<ReturnedResponse> {\r\n // Build all context stores using the immutable API\r\n // Each context defines its own store initialization via buildStore()\r\n const httpContextStore = contextManager.buildStores({ request, response });\r\n\r\n // Run all contexts together!\r\n return contextManager.runAll(httpContextStore, async () => {\r\n try {\r\n // Run middleware chain\r\n const result = await request.runMiddleware();\r\n\r\n if (result) {\r\n return result as ReturnedResponse;\r\n }\r\n\r\n // Execute route handler\r\n request.trigger(\"executingAction\", request.route);\r\n\r\n const handler = request.getHandler();\r\n\r\n request.log(\"Executing Handler\", \"info\");\r\n\r\n const output = await handler(request, response);\r\n\r\n request.log(\"Handler Executed Successfully\", \"success\");\r\n\r\n request.trigger(\"executedAction\", request.route);\r\n\r\n return output as ReturnedResponse;\r\n } catch (error: any) {\r\n return handleRequestError(error, response);\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Handle request errors\r\n * @internal\r\n */\r\nfunction handleRequestError(error: any, response: Response): ReturnedResponse {\r\n if (error instanceof ResourceNotFoundError) {\r\n return response.notFound({\r\n error: error.message,\r\n ...error.payload,\r\n });\r\n }\r\n\r\n if (error instanceof UnAuthorizedError) {\r\n return response.unauthorized({\r\n error: error.message,\r\n ...error.payload,\r\n });\r\n }\r\n\r\n if (error instanceof ForbiddenError) {\r\n return response.forbidden({\r\n error: error.message,\r\n ...error.payload,\r\n });\r\n }\r\n\r\n if (error instanceof BadRequestError) {\r\n return response.badRequest({\r\n error: error.message,\r\n ...error.payload,\r\n });\r\n }\r\n\r\n if (error instanceof DatabaseWriterValidationError) {\r\n return response.badRequest({\r\n errors: error.errors,\r\n });\r\n }\r\n\r\n if (error instanceof ServerError) {\r\n return response.serverError({\r\n error: error.message,\r\n ...error.payload,\r\n });\r\n }\r\n\r\n console.log(error);\r\n\r\n return response.badRequest({\r\n error: error.message,\r\n ...error.payload,\r\n });\r\n}\r\n\r\n/**\r\n * Translate a keyword (uses request context for locale)\r\n */\r\nexport function t(keyword: string, placeholders?: any) {\r\n return requestContextInstance.getRequest()?.trans(keyword, placeholders) || trans(keyword);\r\n}\r\n\r\n/**\r\n * Get or compute a value from the request cache\r\n *\r\n * If the value exists in request, return it.\r\n * Otherwise, execute callback, store result in request, and return it.\r\n */\r\nexport async function fromRequest<T>(\r\n key: string,\r\n callback: (request?: Request) => Promise<T>,\r\n): Promise<T> {\r\n const { request } = useRequestStore();\r\n\r\n if (!request) return await callback();\r\n\r\n if (request[key]) return request[key];\r\n\r\n request[key] = await callback(request);\r\n\r\n return request[key];\r\n}\r\n","import { invalidRule, VALID_RULE, type SchemaRule } from \"@warlock.js/seal\";\r\nimport type { ExistsRuleOptions } from \"../types\";\r\n\r\n/**\r\n * Exists rule - validates record exists in database\r\n */\r\nexport const existsRule: SchemaRule<ExistsRuleOptions> = {\r\n name: \"exists\",\r\n defaultErrorMessage: \"The :input must exist\",\r\n async validate(value: any, context) {\r\n const { Model, query, column = context.key } = this.context.options;\r\n\r\n const dbQuery = Model.query();\r\n\r\n dbQuery.where(column, value);\r\n\r\n if (query) {\r\n await query({\r\n query: dbQuery,\r\n value,\r\n allValues: context.allValues,\r\n });\r\n }\r\n\r\n const document = await dbQuery.first();\r\n return document ? VALID_RULE : invalidRule(this, context);\r\n },\r\n};\r\n","import config from \"@mongez/config\";\r\nimport { get } from \"@mongez/reinforcements\";\r\nimport type { HttpConfigurations } from \"./types\";\r\n\r\n/**\r\n * Default http configurations\r\n */\r\nexport const defaultHttpConfigurations: HttpConfigurations = {\r\n port: 3000,\r\n host: \"0.0.0.0\",\r\n middleware: {\r\n all: [],\r\n only: {\r\n middleware: [],\r\n },\r\n except: {\r\n middleware: [],\r\n },\r\n },\r\n};\r\n\r\n/**\r\n * Get http configurations for the given key\r\n */\r\nexport function httpConfig(key: string): any {\r\n return config.get(`http.${key}`, get(defaultHttpConfigurations, key));\r\n}\r\n","import config from \"@mongez/config\";\r\nimport { merge } from \"@mongez/reinforcements\";\r\nimport { log } from \"@warlock.js/logger\";\r\nimport { v } from \"@warlock.js/seal\";\r\nimport type { Request, Response } from \"../http\";\r\nimport type { Route, RouteHandlerValidation } from \"../router\";\r\n\r\nfunction resolveDataToParse(validating: RouteHandlerValidation[\"validating\"], request: Request) {\r\n if (!validating || validating.length === 0) return request.allExceptParams();\r\n\r\n let data: any = {};\r\n\r\n for (const validatingType of validating) {\r\n if (validatingType === \"body\") {\r\n data = merge(data, request.body);\r\n }\r\n\r\n if (validatingType === \"query\") {\r\n data = merge(data, request.query);\r\n }\r\n\r\n if (validatingType === \"params\") {\r\n data = merge(data, request.params);\r\n }\r\n\r\n if (validatingType === \"headers\") {\r\n data = merge(data, request.headers);\r\n }\r\n }\r\n\r\n return data;\r\n}\r\n\r\n/**\r\n * Validate the request route\r\n */\r\nexport async function validateAll(\r\n validation: Route[\"handler\"][\"validation\"],\r\n request: Request,\r\n response: Response,\r\n) {\r\n if (!validation) return;\r\n\r\n log.info(\"validation\", \"started\", \"Start validating the request\");\r\n\r\n if (validation.schema) {\r\n log.info(\"validation\", \"schema\", \"Validating request schema\");\r\n try {\r\n const data = resolveDataToParse(validation.validating, request);\r\n const result = await v.validate(validation.schema, data);\r\n\r\n if (result.data && result.isValid) {\r\n request.setValidatedData(result.data);\r\n }\r\n\r\n if (!result.isValid) {\r\n log.warn(\"validation\", \"schema\", \"Schema Validation failed\");\r\n return response.failedSchema(result);\r\n }\r\n\r\n log.success(\"validation\", \"schema\", \"Schema Validation passed\");\r\n } catch (error) {\r\n log.warn(\"app.validation\", \"error\", error);\r\n throw error;\r\n }\r\n }\r\n\r\n if (validation.validate) {\r\n const result = await validation.validate(request, response);\r\n\r\n // if there is a result, it means it failed\r\n if (result) {\r\n // check if there is no response status code, then set it to config value or 400 as default\r\n if (!response.statusCode) {\r\n response.setStatusCode(config.get(\"validation.responseStatus\", 400));\r\n }\r\n\r\n log.info(\"validation\", \"failed\", \"Validation failed\");\r\n\r\n return result;\r\n }\r\n\r\n log.info(\"validation\", \"passed\", \"Validation passed\");\r\n }\r\n}\r\n","import config from \"@mongez/config\";\nimport type { EventSubscription } from \"@mongez/events\";\nimport events from \"@mongez/events\";\nimport { fileExistsAsync } from \"@mongez/fs\";\nimport { isIterable, isPlainObject, isScalar } from \"@mongez/supportive-is\";\nimport type { LogLevel } from \"@warlock.js/logger\";\nimport { log } from \"@warlock.js/logger\";\nimport type { ValidationResult } from \"@warlock.js/seal\";\nimport type { FastifyReply } from \"fastify\";\nimport fs from \"fs\";\nimport mime from \"mime\";\nimport path from \"path\";\nimport type React from \"react\";\nimport { type ReactNode } from \"react\";\nimport type { Route } from \"../router\";\nimport { renderReact } from \"./../react\";\nimport type { Request } from \"./request\";\nimport type { ResponseEvent } from \"./types\";\n\nexport enum ResponseStatus {\n OK = 200,\n CREATED = 201,\n ACCEPTED = 202,\n MOVED_PERMANENTLY = 301,\n FOUND = 302,\n SEE_OTHER = 303,\n NOT_MODIFIED = 304,\n TEMPORARY_REDIRECT = 307,\n PERMANENT_REDIRECT = 308,\n NO_CONTENT = 204,\n BAD_REQUEST = 400,\n UNAUTHORIZED = 401,\n FORBIDDEN = 403,\n NOT_FOUND = 404,\n METHOD_NOT_ALLOWED = 405,\n CONFLICT = 409,\n TOO_MANY_REQUESTS = 429,\n INTERNAL_SERVER_ERROR = 500,\n SERVICE_UNAVAILABLE = 503,\n}\n\n/**\n * Options for sending files\n */\nexport type SendFileOptions = {\n cacheTime?: number;\n immutable?: boolean;\n inline?: boolean;\n filename?: string;\n};\n\n/**\n * Options for sending buffers\n */\nexport type SendBufferOptions = SendFileOptions & {\n contentType?: string;\n etag?: string;\n};\n\nexport class Response {\n /**\n * Current route\n */\n protected route!: Route;\n\n /**\n * Fastify response object\n */\n public baseResponse!: FastifyReply;\n\n /**\n * Current status code\n */\n protected currentStatusCode = 200;\n\n /**\n * Current response body\n */\n protected currentBody: any;\n\n /**\n * A flag to determine if response is being sent\n */\n protected isSending = false;\n\n /**\n * Request object\n */\n public request!: Request;\n\n /**\n * Internal events related to this particular response object\n */\n protected events = new Map<string, any[]>();\n\n /**\n * Parsed body\n * This will return the parsed body of the response\n * Please note that if this property is called before the response is sent, it will return undefined\n */\n public parsedBody: any;\n\n /**\n * Get Current response body\n */\n public get body() {\n return this.currentBody;\n }\n\n /**\n * Set response body\n */\n public set body(body: any) {\n this.currentBody = body;\n }\n\n /**\n * Add event on sending response\n */\n public onSending(callback: any) {\n this.events.set(\"sending\", [...(this.events.get(\"sending\") || []), callback]);\n\n return this;\n }\n\n /**\n * Add event on sent response\n */\n public onSent(callback: any) {\n this.events.set(\"sent\", [...(this.events.get(\"sent\") || []), callback]);\n\n return this;\n }\n\n /**\n * Set the Fastify response object\n */\n public setResponse(response: FastifyReply) {\n this.baseResponse = response;\n\n return this;\n }\n\n /**\n * Reset the response state\n */\n public reset() {\n this.route = {} as Route;\n this.currentBody = null;\n this.currentStatusCode = 200;\n }\n\n /**\n * Set current route\n */\n public setRoute(route: Route) {\n this.route = route;\n\n return this;\n }\n\n /**\n * Get the content type\n */\n public get contentType() {\n return this.baseResponse.getHeader(\"Content-Type\");\n }\n\n /**\n * Set the content type\n */\n public setContentType(contentType: string) {\n this.baseResponse.header(\"Content-Type\", contentType);\n\n return this;\n }\n\n /**\n * Get the status code\n */\n public get statusCode(): number {\n return this.currentStatusCode ?? this.baseResponse.statusCode;\n }\n\n /**\n * Check if response status is ok\n */\n public get isOk() {\n return this.currentStatusCode >= 200 && this.currentStatusCode < 300;\n }\n\n /**\n * Check if the response has been sent\n */\n public get sent() {\n return this.baseResponse.sent;\n }\n\n /**\n * Add a listener to the response event\n */\n public static on(\n event: ResponseEvent,\n listener: (response: Response) => void,\n ): EventSubscription {\n return events.subscribe(`response.${event}`, listener);\n }\n\n /**\n * Trigger the response event\n */\n protected static async trigger(event: ResponseEvent, ...args: any[]) {\n // make a timeout to make sure the request events is executed first\n return new Promise((resolve) => {\n setTimeout(async () => {\n await events.triggerAllAsync(`response.${event}`, ...args);\n resolve(true);\n }, 0);\n });\n }\n\n /**\n * Parse body\n */\n protected async parseBody() {\n return await this.parse(this.currentBody);\n }\n\n /**\n * Parse the given value\n */\n public async parse(value: any): Promise<any> {\n // if it is a falsy value, return it\n if (!value || isScalar(value)) return value;\n\n // if it has a `toJSON` method, call it and await the result then return it\n if (value.toJSON) {\n value.request = this.request;\n return await value.toJSON();\n }\n\n // if it is iterable, an array or array-like object then parse each item\n if (isIterable(value)) {\n const values = Array.from(value);\n\n return Promise.all(\n values.map(async (item: any) => {\n return await this.parse(item);\n }),\n );\n }\n\n // if not plain object, then return it\n if (!isPlainObject(value)) {\n return value;\n }\n\n // loop over the object and check if the value and call `parse` on it\n for (const key in value) {\n const subValue = value[key];\n\n value[key] = await this.parse(subValue);\n }\n\n return value;\n }\n\n /**\n * Make a log message\n */\n public log(message: string, level: LogLevel = \"info\") {\n if (!config.get(\"http.log\")) return;\n\n log({\n module: \"response\",\n action: this.route.method + \" \" + this.route.path.replace(\"/*\", \"\") + `:${this.request.id}`,\n message,\n type: level,\n context: {\n request: this.request,\n response: this,\n },\n });\n }\n\n /**\n * Check if returning response is json\n */\n public get isJson() {\n return this.getHeader(\"Content-Type\") === \"application/json\";\n }\n\n /**\n * Send the response\n * @param data - Response data\n * @param statusCode - HTTP status code\n * @param triggerEvents - Whether to trigger response events (default: true)\n */\n public async send(data?: any, statusCode?: number, triggerEvents = true): Promise<Response> {\n if (statusCode) {\n this.currentStatusCode = statusCode;\n }\n\n if (data === this) return this;\n\n if (data) {\n this.currentBody = data;\n }\n\n if (!this.currentStatusCode) {\n this.currentStatusCode = 200;\n }\n\n this.log(\"Sending response\");\n // trigger the sending event\n if (Array.isArray(this.currentBody) || isPlainObject(this.currentBody)) {\n this.setContentType(\"application/json\");\n }\n\n if (triggerEvents) {\n await Response.trigger(\"sending\", this);\n\n for (const callback of this.events.get(\"sending\") || []) {\n await callback(this);\n }\n\n if (this.isJson) {\n await Response.trigger(\"sendingJson\", this);\n for (const callback of this.events.get(\"sendingJson\") || []) {\n await callback(this);\n }\n\n if (this.isOk) {\n await Response.trigger(\"sendingSuccessJson\", this);\n for (const callback of this.events.get(\"sendingSuccessJson\") || []) {\n await callback(this);\n }\n }\n }\n }\n\n // parse the body and make sure it is transformed to sync data instead of async data\n if (typeof this.currentBody !== \"string\") {\n this.parsedBody = await this.parseBody();\n } else {\n this.parsedBody = data;\n }\n\n // Set the status first\n this.baseResponse.status(this.currentStatusCode);\n\n // Then send the response with the parsed body\n await this.baseResponse.send(this.parsedBody);\n\n this.log(\"Response sent\");\n\n if (triggerEvents) {\n // trigger the sent event\n Response.trigger(\"sent\", this);\n\n for (const callback of this.events.get(\"sent\") || []) {\n callback(this);\n }\n\n // trigger the success event if the status code is 2xx\n if (this.currentStatusCode >= 200 && this.currentStatusCode < 300) {\n Response.trigger(\"success\", this);\n }\n\n // trigger the successCreate event if the status code is 201\n if (this.currentStatusCode === 201) {\n Response.trigger(\"successCreate\", this);\n }\n\n // trigger the badRequest event if the status code is 400\n if (this.currentStatusCode === 400) {\n Response.trigger(\"badRequest\", this);\n }\n\n // trigger the unauthorized event if the status code is 401\n if (this.currentStatusCode === 401) {\n Response.trigger(\"unauthorized\", this);\n }\n\n // trigger the forbidden event if the status code is 403\n if (this.currentStatusCode === 403) {\n Response.trigger(\"forbidden\", this);\n }\n\n // trigger the notFound event if the status code is 404\n if (this.currentStatusCode === 404) {\n Response.trigger(\"notFound\", this);\n }\n\n // trigger the throttled event if the status code is 429\n if (this.currentStatusCode === 429) {\n Response.trigger(\"throttled\", this);\n }\n\n // trigger the serverError event if the status code is 500\n if (this.currentStatusCode === 500) {\n Response.trigger(\"serverError\", this);\n }\n\n // trigger the error event if the status code is 4xx or 5xx\n if (this.currentStatusCode >= 400) {\n Response.trigger(\"error\", this);\n }\n }\n\n return this;\n }\n\n /**\n * Send html response\n */\n public html(data: string, statusCode?: number) {\n return this.setContentType(\"text/html\").send(data, statusCode);\n }\n\n /**\n * Render the given react component\n */\n public render(element: React.ReactElement | React.ComponentType, status = 200) {\n return this.setStatusCode(status).html(renderReact(element));\n }\n\n /**\n * Send xml response\n */\n public xml(data: string, statusCode?: number) {\n return this.setContentType(\"text/xml\").send(data, statusCode);\n }\n\n /**\n * Send plain text response\n */\n public text(data: string, statusCode?: number) {\n return this.setContentType(\"text/plain\").send(data, statusCode);\n }\n\n /**\n * Create a streaming response for progressive/chunked data sending\n *\n * This method allows you to send data in chunks and control when the response ends.\n * Perfect for Server-Sent Events (SSE), progressive rendering, or streaming large responses.\n *\n * @example\n * ```ts\n * const stream = response.stream(\"text/html\");\n * stream.send(\"<html><body>\");\n * stream.send(\"<h1>Hello</h1>\");\n * stream.render(<MyComponent />);\n * stream.send(\"</body></html>\");\n * stream.end();\n * ```\n *\n * @param contentType - The content type for the stream (default: \"text/plain\")\n * @returns Stream controller with send(), render(), and end() methods\n */\n public stream(contentType = \"text/plain\") {\n // Set headers using the response API\n this.setContentType(contentType);\n this.header(\"Transfer-Encoding\", \"chunked\");\n this.header(\"Cache-Control\", \"no-cache\");\n this.header(\"Connection\", \"keep-alive\");\n this.header(\"X-Content-Type-Options\", \"nosniff\");\n\n // Trigger sending events\n Response.trigger(\"sending\", this);\n for (const callback of this.events.get(\"sending\") || []) {\n callback(this);\n }\n\n this.log(\"Starting stream\");\n\n // Track stream state\n let isEnded = false;\n const chunks: any[] = [];\n\n // Write headers to start the stream\n // Note: We use raw here because we need chunked encoding control\n // This is the only valid use case for bypassing Fastify's abstraction\n this.baseResponse.raw.writeHead(this.statusCode, this.getHeaders() as any);\n\n return {\n /**\n * Send a chunk of data to the client\n * @param data - Data to send (string, Buffer, or any serializable data)\n */\n send: (data: any) => {\n if (isEnded) {\n throw new Error(\"Cannot send data: stream has already ended\");\n }\n\n this.baseResponse.raw.write(data);\n\n return this;\n },\n\n /**\n * Render a React component and send it as a chunk\n * @param element - React element or component to render\n */\n render: (element: ReactNode) => {\n if (isEnded) {\n throw new Error(\"Cannot render: stream has already ended\");\n }\n\n const html = renderReact(element);\n chunks.push(html);\n this.baseResponse.raw.write(html);\n\n return this;\n },\n\n /**\n * End the stream and trigger completion events\n */\n end: () => {\n if (isEnded) {\n return this;\n }\n\n isEnded = true;\n\n // Store the streamed content for logging/debugging\n this.currentBody = chunks;\n this.parsedBody = chunks;\n\n // End the response\n this.baseResponse.raw.end();\n\n this.log(\"Stream ended\");\n\n // Trigger sent events\n Response.trigger(\"sent\", this);\n for (const callback of this.events.get(\"sent\") || []) {\n callback(this);\n }\n\n // Trigger success event if status is 2xx\n if (this.isOk) {\n Response.trigger(\"success\", this);\n }\n\n // Trigger status-specific events\n if (this.currentStatusCode === 201) {\n Response.trigger(\"successCreate\", this);\n }\n\n return this;\n },\n\n /**\n * Check if the stream has ended\n */\n get ended() {\n return isEnded;\n },\n };\n }\n\n /**\n * Create a Server-Sent Events (SSE) stream\n *\n * SSE is a standard for pushing real-time updates from server to client.\n * Perfect for live notifications, progress updates, or real-time data feeds.\n *\n * @example\n * ```ts\n * const sse = response.sse();\n *\n * // Send events\n * sse.send(\"message\", { text: \"Hello!\" });\n * sse.send(\"notification\", { type: \"info\", message: \"Update available\" }, \"msg-123\");\n *\n * // Keep connection alive\n * const keepAlive = setInterval(() => sse.comment(\"ping\"), 30000);\n *\n * // Clean up when done\n * clearInterval(keepAlive);\n * sse.end();\n * ```\n *\n * @returns SSE controller with send(), comment(), and end() methods\n */\n public sse() {\n // Set SSE-specific headers\n this.setContentType(\"text/event-stream\");\n this.header(\"Cache-Control\", \"no-cache, no-store, must-revalidate\");\n this.header(\"Connection\", \"keep-alive\");\n this.header(\"X-Accel-Buffering\", \"no\"); // Disable nginx buffering\n\n // Trigger sending events\n Response.trigger(\"sending\", this);\n for (const callback of this.events.get(\"sending\") || []) {\n callback(this);\n }\n\n this.log(\"Starting SSE stream\");\n\n // Track stream state\n let isEnded = false;\n const events: any[] = [];\n\n // Write headers to start the stream\n this.baseResponse.raw.writeHead(this.statusCode, this.getHeaders() as any);\n\n return {\n /**\n * Send an SSE event\n * @param event - Event name (e.g., \"message\", \"notification\")\n * @param data - Event data (will be JSON stringified)\n * @param id - Optional event ID for client-side tracking\n */\n send: (event: string, data: any, id?: string) => {\n if (isEnded) {\n throw new Error(\"Cannot send event: SSE stream has already ended\");\n }\n\n let message = \"\";\n if (id) message += `id: ${id}\\n`;\n message += `event: ${event}\\n`;\n message += `data: ${JSON.stringify(data)}\\n\\n`;\n\n events.push({ event, data, id });\n this.baseResponse.raw.write(message);\n\n return this;\n },\n\n /**\n * Send a comment (keeps connection alive, invisible to client)\n * Useful for preventing timeout on long-lived connections\n * @param text - Comment text\n */\n comment: (text: string) => {\n if (isEnded) {\n throw new Error(\"Cannot send comment: SSE stream has already ended\");\n }\n\n this.baseResponse.raw.write(`: ${text}\\n\\n`);\n\n return this;\n },\n\n /**\n * End the SSE stream and trigger completion events\n */\n end: () => {\n if (isEnded) {\n return;\n }\n\n isEnded = true;\n\n // Store the events for logging/debugging\n this.currentBody = events;\n this.parsedBody = events;\n\n // End the response\n this.baseResponse.raw.end();\n\n this.log(\"SSE stream ended\");\n\n // Trigger sent events\n Response.trigger(\"sent\", this);\n for (const callback of this.events.get(\"sent\") || []) {\n callback(this);\n }\n\n // Trigger success event if status is 2xx\n if (this.isOk) {\n Response.trigger(\"success\", this);\n }\n },\n\n /**\n * Check if the stream has ended\n */\n get ended() {\n return isEnded;\n },\n };\n }\n\n /**\n * Set the status code\n */\n public setStatusCode(statusCode: number) {\n this.currentStatusCode = statusCode;\n\n return this;\n }\n\n /**\n * Redirect the user to another route\n */\n public redirect(url: string, statusCode = 302) {\n this.baseResponse.redirect(url, statusCode);\n\n return this;\n }\n\n /**\n * Permanent redirect\n */\n public permanentRedirect(url: string) {\n this.baseResponse.redirect(url, 301);\n\n return this;\n }\n\n /**\n * Get the response time\n */\n public getResponseTime() {\n return this.baseResponse.elapsedTime;\n }\n\n /**\n * Remove a specific header\n */\n public removeHeader(key: string) {\n this.baseResponse.removeHeader(key);\n\n return this;\n }\n\n /**\n * Get a specific header\n */\n public getHeader(key: string) {\n return this.baseResponse.getHeader(key);\n }\n\n /**\n * Get the response headers\n */\n public getHeaders() {\n return this.baseResponse.getHeaders();\n }\n\n /**\n * Set multiple headers\n */\n public headers(headers: Record<string, string>) {\n this.baseResponse.headers(headers);\n\n return this;\n }\n\n /**\n * Set the response header\n */\n public header(key: string, value: any) {\n this.baseResponse.header(key, value);\n\n return this;\n }\n\n /**\n * Alias to header method\n */\n public setHeader(key: string, value: any) {\n return this.header(key, value);\n }\n\n /**\n * Send an error response with status code 500\n */\n public serverError(data: any) {\n return this.send(data, 500);\n }\n\n /**\n * Send a forbidden response with status code 403\n */\n public forbidden(\n data: any = {\n error: \"You are not allowed to access this resource, FORBIDDEN\",\n },\n ) {\n return this.send(data, 403);\n }\n\n /**\n * Send a service unavailable response with status code 503\n */\n public serviceUnavailable(data: any) {\n return this.send(data, 503);\n }\n\n /**\n * Send an unauthorized response with status code 401\n */\n public unauthorized(\n data: any = {\n error: \"unauthorized\",\n },\n ) {\n return this.send(data, 401);\n }\n\n /**\n * Send a not found response with status code 404\n */\n public notFound(\n data: any = {\n error: \"notFound\",\n },\n ) {\n return this.send(data, 404);\n }\n\n /**\n * Send a bad request response with status code 400\n */\n public badRequest(data: any) {\n return this.send(data, 400);\n }\n\n /**\n * Send a success response with status code 201\n */\n public successCreate(data: any) {\n return this.send(data, 201);\n }\n\n /**\n * Send a success response\n */\n public success(data: any = { success: true }) {\n return this.send(data);\n }\n\n /**\n * Send a no content response with status code 204\n */\n public noContent() {\n return this.baseResponse.status(204).send();\n }\n\n /**\n * Send an accepted response with status code 202\n * Used for async operations that have been accepted but not yet processed\n */\n public accepted(data: any = { message: \"Request accepted for processing\" }) {\n return this.send(data, 202);\n }\n\n /**\n * Send a conflict response with status code 409\n */\n public conflict(data: any = { error: \"Resource conflict\" }) {\n return this.send(data, 409);\n }\n\n /**\n * Send an unprocessable entity response with status code 422\n * Used for semantic validation errors\n */\n public unprocessableEntity(data: any) {\n return this.send(data, 422);\n }\n\n /**\n * Apply response options (cache, disposition, etag)\n * Shared helper for sendFile and sendBuffer\n */\n private applyResponseOptions(options: SendBufferOptions, defaultFilename?: string): boolean {\n // Set content type if provided\n if (options.contentType) {\n this.baseResponse.type(options.contentType);\n }\n\n // Set cache headers if specified\n if (options.cacheTime) {\n const cacheControl = options.immutable\n ? `public, max-age=${options.cacheTime}, immutable`\n : `public, max-age=${options.cacheTime}`;\n this.header(\"Cache-Control\", cacheControl);\n this.header(\"Expires\", new Date(Date.now() + options.cacheTime * 1000).toUTCString());\n }\n\n // Set ETag if provided (for conditional requests)\n if (options.etag) {\n this.header(\"ETag\", options.etag);\n\n // Check If-None-Match for conditional request\n const ifNoneMatch = this.request.header(\"if-none-match\");\n if (ifNoneMatch && ifNoneMatch === options.etag) {\n this.log(\"Content not modified (ETag match), sending 304\");\n this.baseResponse.status(304).send();\n return true; // Indicates 304 was sent\n }\n }\n\n // Set Content-Disposition if inline or filename is specified\n if (options.inline !== undefined || options.filename) {\n const disposition = options.inline ? \"inline\" : \"attachment\";\n const filename = options.filename || defaultFilename || \"file\";\n this.header(\"Content-Disposition\", `${disposition}; filename=\\\"${filename}\\\"`);\n }\n\n return false; // No 304 sent\n }\n\n /**\n * Send a file as a response\n */\n public async sendFile(filePath: string, options?: number | SendFileOptions) {\n this.log(`Sending file: ${filePath}`);\n\n // Check if file exists first\n if (!(await fileExistsAsync(filePath))) {\n return this.notFound({\n error: \"File Not Found\",\n });\n }\n\n try {\n // Normalize options to object format\n const opts = typeof options === \"number\" ? { cacheTime: options } : options || {};\n\n // Get file stats for ETag and Last-Modified\n const stats = await fs.promises.stat(filePath);\n const lastModified = stats.mtime;\n\n // Generate ETag based on file size and modification time\n const etag = `\"${stats.size}-${stats.mtime.getTime()}\"`;\n\n // Set Last-Modified header\n this.header(\"Last-Modified\", lastModified.toUTCString());\n this.header(\"ETag\", etag);\n\n // Set content type\n const contentType = this.getFileContentType(filePath);\n this.baseResponse.type(contentType);\n\n // Apply common response options (cache, disposition)\n const defaultFilename = path.basename(filePath);\n const sent304 = this.applyResponseOptions({ ...opts, etag, contentType }, defaultFilename);\n if (sent304) return this.baseResponse;\n\n // Check conditional request headers\n const ifNoneMatch = this.request.header(\"if-none-match\");\n const ifModifiedSince = this.request.header(\"if-modified-since\");\n\n // Handle If-None-Match (ETag validation)\n if (ifNoneMatch && ifNoneMatch === etag) {\n this.log(\"File not modified (ETag match), sending 304\");\n return this.baseResponse.status(304).send();\n }\n\n // Handle If-Modified-Since (Last-Modified validation)\n if (ifModifiedSince) {\n const modifiedSinceDate = new Date(ifModifiedSince);\n if (lastModified.getTime() <= modifiedSinceDate.getTime()) {\n this.log(\"File not modified (Last-Modified check), sending 304\");\n return this.baseResponse.status(304).send();\n }\n }\n\n // Use streaming for efficient file sending\n const stream = fs.createReadStream(filePath);\n\n // Handle stream errors\n stream.on(\"error\", (error) => {\n this.log(`Error reading file: ${error.message}`, \"error\");\n if (!this.baseResponse.sent) {\n this.serverError({\n error: \"Error reading file\",\n message: error.message,\n });\n }\n });\n\n // Send the stream\n return this.baseResponse.send(stream);\n } catch (error: any) {\n this.log(`Error sending file: ${error.message}`, \"error\");\n return this.serverError({\n error: \"Error sending file\",\n message: error.message,\n });\n }\n }\n\n /**\n * Send buffer as a response\n * Useful for dynamically generated content (e.g., resized images, generated PDFs)\n */\n public sendBuffer(buffer: Buffer, options?: number | SendBufferOptions) {\n this.log(\"Sending buffer\");\n\n // Normalize options to object format\n const opts = typeof options === \"number\" ? { cacheTime: options } : options || {};\n\n // Apply common response options (cache, disposition, etag)\n const sent304 = this.applyResponseOptions(opts);\n if (sent304) return this.baseResponse;\n\n return this.baseResponse.send(buffer);\n }\n\n /**\n * Send an Image instance as a response\n * Automatically detects image format and sets content type\n */\n public async sendImage(\n image: any, // Type as 'any' to avoid circular dependency with Image class\n options?: number | (Omit<SendBufferOptions, \"contentType\"> & { contentType?: string }),\n ) {\n this.log(\"Sending image\");\n\n // Normalize options to object format\n const opts = typeof options === \"number\" ? { cacheTime: options } : options || {};\n\n // Get image metadata to determine format\n const metadata = await image.metadata();\n const format = metadata.format || \"jpeg\";\n\n // Convert image to buffer\n const buffer = await image.toBuffer();\n\n // Auto-set content type if not provided\n const contentType = opts.contentType || `image/${format}`;\n\n // Auto-generate ETag if not provided\n // Format: \"format-widthxheight-size\" (e.g., \"jpeg-800x600-45231\")\n // This catches changes in dimensions, quality, filters, and format\n if (!opts.etag) {\n const width = metadata.width || 0;\n const height = metadata.height || 0;\n opts.etag = `\"${format}-${width}x${height}-${buffer.length}\"`;\n }\n\n // Apply common response options with auto-detected content type\n const sent304 = this.applyResponseOptions({ ...opts, contentType });\n if (sent304) return this.baseResponse;\n\n return this.baseResponse.send(buffer);\n }\n\n /**\n * Send file and cache it\n * Cache time in seconds\n * Cache time will be one year\n */\n public sendCachedFile(path: string, cacheTime = 31536000) {\n return this.sendFile(path, cacheTime);\n }\n\n /**\n * Download the given file path\n */\n public download(path: string, filename?: string) {\n return this.downloadFile(path, filename);\n }\n\n /**\n * Download the given file path\n */\n public async downloadFile(filePath: string, filename?: string) {\n // Check if file exists first\n if (!(await fileExistsAsync(filePath))) {\n return this.notFound({\n error: \"File Not Found\",\n });\n }\n\n try {\n if (!filename) {\n filename = path.basename(filePath);\n }\n\n this.baseResponse.header(\"Content-Disposition\", `attachment; filename=\"${filename}\"`);\n\n // this.baseResponse.header(\"Content-Type\", this.getFileContentType(filePath));\n this.baseResponse.header(\"Content-Type\", \"application/octet-stream\");\n\n const stream = fs.createReadStream(filePath);\n\n // Handle stream errors\n stream.on(\"error\", (error) => {\n this.log(`Error reading file for download: ${error.message}`, \"error\");\n if (!this.baseResponse.sent) {\n this.serverError({\n error: \"Error reading file\",\n message: error.message,\n });\n }\n });\n\n return this.baseResponse.send(stream);\n } catch (error: any) {\n this.log(`Error downloading file: ${error.message}`, \"error\");\n return this.serverError({\n error: \"Error downloading file\",\n message: error.message,\n });\n }\n }\n\n /**\n * Get content type of the given path\n */\n public getFileContentType(filePath: string) {\n const type = mime.getType(filePath) || \"application/octet-stream\";\n return type;\n }\n\n /**\n * Mark the response as failed\n */\n public failedSchema(result: ValidationResult) {\n const { errors, inputKey, inputError, status } = config.get(\"validation.response\", {\n errors: \"errors\",\n inputKey: \"input\",\n inputError: \"error\",\n status: 400,\n });\n\n log.error(\"request\", \"validation\", `${this.request.id} - Validation failed`);\n\n return this.send(\n {\n [errors]: result.errors.map((error) => ({\n [inputKey]: error.input,\n [inputError]: error.error,\n })),\n },\n status,\n );\n }\n}\n","import axios from \"axios\";\nimport type sharp from \"sharp\";\nimport type { FormatEnum } from \"sharp\";\n\n// ============================================================\n// Eager-loaded Sharp Module\n// ============================================================\n\n/**\n * Installation instructions for sharp\n */\nconst SHARP_INSTALL_INSTRUCTIONS = `\nImage processing requires the sharp package.\nInstall it with:\n\n warlock add image\n\nOr manually:\n\n npm install sharp\n pnpm add sharp\n yarn add sharp\n`.trim();\n\n/**\n * Module availability flag\n */\nlet moduleExists: boolean | null = null;\n\n/**\n * Cached sharp function (loaded at import time)\n */\nlet sharpFn: typeof sharp;\n\n/**\n * Eagerly load sharp module at import time\n */\nasync function loadSharpModule() {\n try {\n const module = await import(\"sharp\");\n sharpFn = module.default;\n moduleExists = true;\n } catch {\n moduleExists = false;\n }\n}\n\n// Kick off eager loading immediately\nloadSharpModule();\n\n// ============================================================\n// Types\n// ============================================================\n\nexport type ImageFormat = keyof FormatEnum;\n\nexport type ImageInput = string | Buffer | Uint8Array | ArrayBuffer;\n\n/**\n * Watermark configuration for deferred execution\n */\nexport type WatermarkConfig = {\n image: ImageInput | Image;\n options: sharp.OverlayOptions;\n};\n\n/**\n * Operation descriptor for deferred pipeline execution.\n * All operations are stored and executed at save/toBuffer time.\n */\ntype ImageOperation =\n | { type: \"resize\"; options: sharp.ResizeOptions }\n | { type: \"crop\"; options: sharp.Region }\n | { type: \"rotate\"; angle: number }\n | { type: \"flip\" }\n | { type: \"flop\" }\n | { type: \"blur\"; sigma: number }\n | { type: \"sharpen\"; options?: sharp.SharpenOptions }\n | { type: \"blackAndWhite\" }\n | { type: \"opacity\"; value: number }\n | { type: \"negate\"; options?: sharp.NegateOptions }\n | { type: \"tint\"; color: sharp.Color }\n | { type: \"trim\"; options?: sharp.TrimOptions }\n | { type: \"watermark\"; config: WatermarkConfig }\n | { type: \"watermarks\"; configs: WatermarkConfig[] };\n\n/**\n * Transformation options that can be applied in batch via `apply()` method.\n *\n * **Execution Order (when using apply()):**\n * 1. resize - Resize first to work with correct dimensions\n * 2. crop - Crop after resize to extract the desired region\n * 3. rotate - Rotation after sizing\n * 4. flip/flop - Mirror operations\n * 5. blackAndWhite/grayscale - Color space conversion\n * 6. blur - Blur effect\n * 7. sharpen - Sharpen effect\n * 8. tint - Color overlay\n * 9. negate - Invert colors\n * 10. opacity - Transparency (applied via composite)\n * 11. format/quality - Applied on save/export\n */\nexport type ImageTransformOptions = {\n /**\n * Output quality (1-100), applied based on final format\n */\n quality?: number;\n /**\n * Output format (jpeg, png, webp, avif, etc.)\n */\n format?: ImageFormat;\n /**\n * Resize options\n */\n resize?: sharp.ResizeOptions;\n /**\n * Crop/extract region\n */\n crop?: sharp.Region;\n /**\n * Rotation angle in degrees\n */\n rotate?: number;\n /**\n * Flip vertically (top to bottom)\n */\n flip?: boolean;\n /**\n * Flop horizontally (left to right)\n */\n flop?: boolean;\n /**\n * Convert to black and white\n */\n blackAndWhite?: boolean;\n /**\n * Alias for blackAndWhite\n */\n grayscale?: boolean;\n /**\n * Blur sigma (must be >= 0.3)\n */\n blur?: number;\n /**\n * Sharpen options\n */\n sharpen?: sharp.SharpenOptions | boolean;\n /**\n * Tint color\n */\n tint?: sharp.Color;\n /**\n * Negate/invert colors\n */\n negate?: sharp.NegateOptions | boolean;\n /**\n * Opacity (0-100)\n */\n opacity?: number;\n /**\n * Trim options\n */\n trim?: sharp.TrimOptions | boolean;\n /**\n * Single watermark\n */\n watermark?: WatermarkConfig;\n /**\n * Multiple watermarks\n */\n watermarks?: WatermarkConfig[];\n};\n\n/**\n * Internal options stored for deferred application\n */\ntype InternalOptions = {\n quality?: number;\n format?: ImageFormat;\n};\n\n/**\n * Image manipulation class with deferred pipeline execution.\n *\n * **Important:** This class requires the `sharp` package to be installed.\n * Install it with: `warlock add image` or `npm install sharp`\n *\n * Sharp is lazy-loaded on the first async operation (save, toBuffer, etc.),\n * so the constructor and all chainable methods remain synchronous.\n *\n * All operations are synchronous and stored as descriptors.\n * The pipeline is executed only when calling output methods:\n * - `save()` - Save to file\n * - `toBuffer()` - Get as buffer\n * - `toBase64()` - Get as base64 string\n * - `toDataUrl()` - Get as data URL\n *\n * @example\n * ```typescript\n * // All chaining is synchronous - single await at the end\n * await new Image(\"photo.jpg\")\n * .resize({ width: 800 })\n * .watermark(\"logo.png\", { gravity: \"southeast\" })\n * .quality(85)\n * .save(\"output.jpg\");\n * ```\n */\nexport class Image {\n /**\n * Image options that will be applied on save/export\n */\n protected options: InternalOptions = {};\n\n /**\n * Deferred operations pipeline\n */\n protected operations: ImageOperation[] = [];\n\n /**\n * Cached metadata to avoid repeated async calls\n */\n protected cachedMetadata: sharp.Metadata | null = null;\n\n /**\n * Whether the pipeline has been executed\n */\n protected pipelineExecuted = false;\n\n /**\n * Sharp image object\n */\n public readonly image: sharp.Sharp;\n\n /**\n * Formats that support quality option\n */\n protected static readonly QUALITY_FORMATS = [\"jpeg\", \"jpg\", \"webp\", \"avif\", \"tiff\", \"heif\"];\n\n /**\n * Constructor\n */\n public constructor(image: ImageInput | sharp.Sharp) {\n if (moduleExists === false) {\n throw new Error(`sharp is not installed.\\n\\n${SHARP_INSTALL_INSTRUCTIONS}`);\n }\n\n // Check if it's already a sharp instance\n if (image instanceof Object && \"clone\" in image && typeof image.clone === \"function\") {\n this.image = image as sharp.Sharp;\n } else {\n this.image = sharpFn(image as ImageInput);\n }\n }\n\n /**\n * Create image instance from file path\n */\n public static fromFile(path: string): Image {\n return new Image(path);\n }\n\n /**\n * Create image instance from buffer\n */\n public static fromBuffer(buffer: Buffer): Image {\n return new Image(buffer);\n }\n\n /**\n * Create image instance from url\n */\n public static async fromUrl(url: string): Promise<Image> {\n try {\n const response = await axios.get(url, {\n responseType: \"arraybuffer\",\n });\n\n if (!response.data) {\n throw new Error(\"Empty response received\");\n }\n\n const buffer = Buffer.from(response.data, \"binary\");\n\n return new Image(buffer);\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n throw new Error(`Failed to load image from URL \"${url}\": ${message}`);\n }\n }\n\n /**\n * Add an operation to the deferred pipeline\n */\n protected addOperation(operation: ImageOperation): this {\n this.operations.push(operation);\n\n return this;\n }\n\n /**\n * Apply multiple transformations at once with a predefined execution order.\n *\n * This method ensures transformations are applied in a logical order:\n * resize → crop → rotate → flip/flop → colorspace → effects → opacity → format\n *\n * For custom ordering, use individual chained methods instead.\n */\n public apply(options: ImageTransformOptions): this {\n // 1. Resize first to work with correct dimensions\n if (options.resize) {\n this.resize(options.resize);\n }\n\n // 2. Crop after resize\n if (options.crop) {\n this.crop(options.crop);\n }\n\n // 3. Rotation\n if (options.rotate !== undefined) {\n this.rotate(options.rotate);\n }\n\n // 4. Mirror operations\n if (options.flip) {\n this.flip();\n }\n\n if (options.flop) {\n this.flop();\n }\n\n // 5. Color space conversion\n if (options.blackAndWhite || options.grayscale) {\n this.blackAndWhite();\n }\n\n // 6. Blur effect\n if (options.blur !== undefined) {\n this.blur(options.blur);\n }\n\n // 7. Sharpen effect\n if (options.sharpen) {\n const sharpenOptions = typeof options.sharpen === \"boolean\" ? undefined : options.sharpen;\n this.sharpen(sharpenOptions);\n }\n\n // 8. Tint color\n if (options.tint) {\n this.tint(options.tint);\n }\n\n // 9. Negate/invert\n if (options.negate) {\n const negateOptions = typeof options.negate === \"boolean\" ? undefined : options.negate;\n this.negate(negateOptions);\n }\n\n // 10. Trim edges\n if (options.trim) {\n const trimOptions = typeof options.trim === \"boolean\" ? undefined : options.trim;\n this.trim(trimOptions);\n }\n\n // 11. Watermarks\n if (options.watermark) {\n this.watermark(options.watermark.image, options.watermark.options);\n }\n\n if (options.watermarks) {\n this.watermarks(options.watermarks);\n }\n\n // 12. Opacity (applied via composite)\n if (options.opacity !== undefined) {\n this.opacity(options.opacity);\n }\n\n // 13. Store format/quality for deferred application\n if (options.format) {\n this.format(options.format);\n }\n\n if (options.quality !== undefined) {\n this.quality(options.quality);\n }\n\n return this;\n }\n\n /**\n * Set image opacity (0-100)\n */\n public opacity(value: number): this {\n if (value < 0 || value > 100) {\n throw new Error(\"Opacity must be between 0 and 100\");\n }\n\n return this.addOperation({ type: \"opacity\", value });\n }\n\n /**\n * Convert image to black and white\n */\n public blackAndWhite(): this {\n return this.addOperation({ type: \"blackAndWhite\" });\n }\n\n /**\n * Alias for blackAndWhite\n */\n public grayscale(): this {\n return this.blackAndWhite();\n }\n\n /**\n * Get image dimensions (cached after first call)\n */\n public async dimensions(): Promise<{\n width: number | undefined;\n height: number | undefined;\n }> {\n const metadata = await this.metadata();\n\n return { width: metadata.width, height: metadata.height };\n }\n\n /**\n * Get image metadata (cached after first call)\n *\n * The metadata is cached to avoid repeated async operations.\n * Use `refreshMetadata()` to force a fresh fetch.\n */\n public async metadata(): Promise<sharp.Metadata> {\n if (!this.cachedMetadata) {\n this.cachedMetadata = await this.image.metadata();\n }\n\n return this.cachedMetadata;\n }\n\n /**\n * Force refresh of cached metadata\n *\n * Call this after transformations if you need updated metadata.\n */\n public async refreshMetadata(): Promise<sharp.Metadata> {\n this.cachedMetadata = await this.image.metadata();\n\n return this.cachedMetadata;\n }\n\n /**\n * Clear cached metadata\n */\n public clearMetadataCache(): this {\n this.cachedMetadata = null;\n\n return this;\n }\n\n /**\n * Resize image\n */\n public resize(options: sharp.ResizeOptions): this {\n return this.addOperation({ type: \"resize\", options });\n }\n\n /**\n * Crop/extract a region from the image\n */\n public crop(options: sharp.Region): this {\n return this.addOperation({ type: \"crop\", options });\n }\n\n /**\n * Set image quality (1-100)\n * Quality is stored and applied when saving/exporting\n * based on the final format.\n */\n public quality(quality: number): this {\n if (quality < 1 || quality > 100) {\n throw new Error(\"Quality must be between 1 and 100\");\n }\n\n this.options.quality = quality;\n\n return this;\n }\n\n /**\n * Execute the deferred pipeline - apply all stored operations\n */\n protected async executePipeline(): Promise<sharp.Sharp> {\n if (this.pipelineExecuted) {\n return this.image;\n }\n\n for (const operation of this.operations) {\n await this.executeOperation(this.image, operation);\n }\n\n await this.applyFormatAndQuality(this.image);\n\n this.pipelineExecuted = true;\n\n return this.image;\n }\n\n /**\n * Execute a single operation\n */\n protected async executeOperation(image: sharp.Sharp, operation: ImageOperation): Promise<void> {\n switch (operation.type) {\n case \"resize\":\n image.resize(operation.options);\n break;\n\n case \"crop\":\n image.extract(operation.options);\n break;\n\n case \"rotate\":\n image.rotate(operation.angle);\n break;\n\n case \"flip\":\n image.flip();\n break;\n\n case \"flop\":\n image.flop();\n break;\n\n case \"blur\":\n image.blur(operation.sigma);\n break;\n\n case \"sharpen\":\n image.sharpen(operation.options);\n break;\n\n case \"blackAndWhite\":\n image.toColourspace(\"b-w\");\n break;\n\n case \"opacity\": {\n const alpha = Math.round((operation.value / 100) * 255);\n const alphaPixel = Buffer.from([255, 255, 255, alpha]);\n image.composite([\n {\n blend: \"dest-in\",\n input: alphaPixel,\n },\n ]);\n break;\n }\n\n case \"negate\":\n image.negate(operation.options);\n break;\n\n case \"tint\":\n image.tint(operation.color);\n break;\n\n case \"trim\":\n image.trim(operation.options);\n break;\n\n case \"watermark\": {\n const buffer = await this.resolveImageBuffer(operation.config.image);\n image.composite([\n {\n input: buffer,\n ...operation.config.options,\n },\n ]);\n break;\n }\n\n case \"watermarks\": {\n const buffers = await Promise.all(\n operation.configs.map((config) => this.resolveImageBuffer(config.image)),\n );\n image.composite(\n operation.configs.map((config, index) => ({\n input: buffers[index],\n ...config.options,\n })),\n );\n break;\n }\n }\n }\n\n /**\n * Resolve an image input to a buffer\n */\n protected async resolveImageBuffer(input: ImageInput | Image): Promise<Buffer> {\n if (input instanceof Image) {\n // For Image instances, get buffer without applying options (raw buffer)\n return input.image.toBuffer();\n }\n\n // For other inputs (path, buffer, etc.), create temp sharp instance\n const tempImage = sharpFn(input);\n\n return tempImage.toBuffer();\n }\n\n /**\n * Apply format and quality options.\n * If no format is explicitly set, preserves the original format and applies\n * quality appropriately based on the format type.\n */\n protected async applyFormatAndQuality(image: sharp.Sharp): Promise<void> {\n const { quality, format } = this.options;\n\n if (format) {\n // Explicit format specified\n const formatOptions = quality ? { quality } : undefined;\n image.toFormat(format, formatOptions);\n return;\n }\n\n if (quality === undefined) {\n // No quality or format set, nothing to apply\n return;\n }\n\n // Quality is set but no format specified - detect original format\n const metadata = await this.metadata();\n const originalFormat = metadata.format;\n\n if (!originalFormat) {\n // Cannot detect format, default to webp with quality\n image.webp({ quality });\n return;\n }\n\n // Apply quality based on original format\n if (Image.QUALITY_FORMATS.includes(originalFormat)) {\n // Format supports quality option\n image.toFormat(originalFormat as ImageFormat, { quality });\n } else if (originalFormat === \"png\") {\n // PNG uses compressionLevel (0-9) instead of quality\n // Map quality 1-100 to compressionLevel 9-0 (higher quality = lower compression)\n const compressionLevel = Math.round(9 - (quality / 100) * 9);\n image.png({ compressionLevel });\n } else if (originalFormat === \"gif\") {\n // GIF doesn't support quality, just preserve format\n image.gif();\n }\n // Unknown format: preserve as-is (no quality applied)\n }\n\n /**\n * Save to file\n */\n public async save(path: string): Promise<sharp.OutputInfo> {\n const image = await this.executePipeline();\n\n return image.toFile(path);\n }\n\n /**\n * Convert to webp and save to file\n */\n public async saveAsWebp(path: string): Promise<sharp.OutputInfo> {\n // Override format to webp\n this.options.format = \"webp\";\n const image = await this.executePipeline();\n\n return image.toFile(path);\n }\n\n /**\n * Change the file format\n */\n public format(format: ImageFormat): this {\n this.options.format = format;\n\n return this;\n }\n\n /**\n * Add watermark (deferred - executed at save time)\n */\n public watermark(image: ImageInput | Image, options: sharp.OverlayOptions = {}): this {\n return this.addOperation({\n type: \"watermark\",\n config: { image, options },\n });\n }\n\n /**\n * Add multiple watermarks (deferred - executed at save time)\n */\n public watermarks(configs: WatermarkConfig[]): this {\n return this.addOperation({\n type: \"watermarks\",\n configs,\n });\n }\n\n /**\n * Rotate image\n */\n public rotate(angle: number): this {\n return this.addOperation({ type: \"rotate\", angle });\n }\n\n /**\n * Flip image vertically (top to bottom)\n */\n public flip(): this {\n return this.addOperation({ type: \"flip\" });\n }\n\n /**\n * Flop image horizontally (left to right)\n */\n public flop(): this {\n return this.addOperation({ type: \"flop\" });\n }\n\n /**\n * Blur image\n */\n public blur(sigma: number): this {\n if (sigma < 0.3) {\n throw new Error(\"Blur sigma must be at least 0.3\");\n }\n\n return this.addOperation({ type: \"blur\", sigma });\n }\n\n /**\n * Convert to base64\n */\n public async toBase64(): Promise<string> {\n const image = await this.executePipeline();\n const buffer = await image.toBuffer();\n\n return buffer.toString(\"base64\");\n }\n\n /**\n * Convert to data URL (base64 with mime type prefix)\n */\n public async toDataUrl(): Promise<string> {\n const metadata = await this.metadata();\n const format = this.options.format || metadata.format || \"png\";\n const mimeType = `image/${format === \"jpg\" ? \"jpeg\" : format}`;\n const base64 = await this.toBase64();\n\n return `data:${mimeType};base64,${base64}`;\n }\n\n /**\n * Sharpen image\n */\n public sharpen(options?: sharp.SharpenOptions): this {\n return this.addOperation({ type: \"sharpen\", options });\n }\n\n /**\n * Negate/invert image colors\n */\n public negate(options?: sharp.NegateOptions): this {\n return this.addOperation({ type: \"negate\", options });\n }\n\n /**\n * Tint image with a color\n */\n public tint(color: sharp.Color): this {\n return this.addOperation({ type: \"tint\", color });\n }\n\n /**\n * Trim edges from the image\n */\n public trim(options?: sharp.TrimOptions): this {\n return this.addOperation({ type: \"trim\", options });\n }\n\n /**\n * Convert to buffer\n */\n public async toBuffer(): Promise<Buffer> {\n const image = await this.executePipeline();\n\n return image.toBuffer();\n }\n\n /**\n * Clone the image for separate transformations\n */\n public clone(): Image {\n const clonedImage = new Image(this.image.clone());\n clonedImage.options = { ...this.options };\n clonedImage.operations = [...this.operations];\n clonedImage.cachedMetadata = this.cachedMetadata ? { ...this.cachedMetadata } : null;\n\n return clonedImage;\n }\n\n /**\n * Get the current stored options\n */\n public getOptions(): Readonly<InternalOptions> {\n return { ...this.options };\n }\n\n /**\n * Get the pending operations count\n */\n public getPendingOperationsCount(): number {\n return this.operations.length;\n }\n\n /**\n * Reset all stored options\n */\n public resetOptions(): this {\n this.options = {};\n\n return this;\n }\n\n /**\n * Clear all pending operations\n */\n public clearOperations(): this {\n this.operations = [];\n this.pipelineExecuted = false;\n\n return this;\n }\n\n /**\n * Reset the image to its initial state (clear operations and options)\n */\n public reset(): this {\n this.operations = [];\n this.options = {};\n this.pipelineExecuted = false;\n this.cachedMetadata = null;\n\n return this;\n }\n}\n","import { S3ClientConfig } from \"@aws-sdk/client-s3\";\r\nimport { config } from \"../config\";\r\nimport type {\r\n CloudStorageDriverOptions,\r\n LocalStorageDriverOptions,\r\n R2StorageDriverOptions,\r\n StorageConfigurations,\r\n StorageDriverConfig,\r\n} from \"./types\";\r\n\r\n/**\r\n * Get storage configuration\r\n */\r\nexport function storageConfig(): StorageConfigurations;\r\nexport function storageConfig<T = any>(key: string): T;\r\nexport function storageConfig<T = any>(key: string, defaultValue: T): T;\r\nexport function storageConfig(key?: string, defaultValue?: any): any {\r\n if (!key) {\r\n return config.get(\"storage\");\r\n }\r\n\r\n return config.get(`storage.${key}`, defaultValue);\r\n}\r\n\r\nexport const storageConfigurations = {\r\n local: (options: LocalStorageDriverOptions): StorageDriverConfig => {\r\n return {\r\n driver: \"local\",\r\n ...options,\r\n };\r\n },\r\n aws: (options: CloudStorageDriverOptions & S3ClientConfig): StorageDriverConfig => {\r\n return {\r\n driver: \"s3\",\r\n ...options,\r\n };\r\n },\r\n r2: (options: R2StorageDriverOptions & S3ClientConfig): StorageDriverConfig => {\r\n return {\r\n driver: \"r2\",\r\n ...options,\r\n };\r\n },\r\n spaces: (options: CloudStorageDriverOptions & S3ClientConfig): StorageDriverConfig => {\r\n return {\r\n driver: \"spaces\",\r\n ...options,\r\n };\r\n },\r\n};\r\n","import { basename, dirname, extname } from \"path\";\r\nimport type { Readable } from \"stream\";\r\nimport type {\r\n CloudStorageDriverContract,\r\n FileVisibility,\r\n StorageDriverContract,\r\n StorageFileData,\r\n} from \"./types\";\r\n\r\n/**\r\n * StorageFile class - OOP wrapper for storage file operations\r\n *\r\n * Provides a fluent interface for working with files in storage,\r\n * wrapping the underlying driver operations.\r\n *\r\n * @example\r\n * ```typescript\r\n * const file = await storage.put(buffer, \"uploads/image.jpg\");\r\n *\r\n * // Properties (sync, from cached data)\r\n * file.name // \"image.jpg\"\r\n * file.extension // \"jpg\"\r\n * file.path // \"uploads/image.jpg\"\r\n * file.hash // \"sha256:abc123...\"\r\n *\r\n * // Operations\r\n * await file.copy(\"uploads/backup.jpg\")\r\n * await file.move(\"archive/image.jpg\")\r\n * await file.delete()\r\n *\r\n * // Content\r\n * const buffer = await file.contents();\r\n * const stream = await file.stream();\r\n * ```\r\n */\r\nexport class StorageFile {\r\n /**\r\n * Relative file path\r\n */\r\n protected _path: string;\r\n\r\n /**\r\n * The driver instance\r\n */\r\n protected _driver: StorageDriverContract;\r\n\r\n /**\r\n * Cached file data (from put operations or lazy loaded)\r\n */\r\n protected _data?: StorageFileData;\r\n\r\n /**\r\n * Whether the file has been deleted\r\n */\r\n protected _deleted = false;\r\n\r\n /**\r\n * Create a new StorageFile instance\r\n *\r\n * @param path - Relative file path\r\n * @param driver - Driver instance\r\n * @param data - Optional initial data from put/copy operations\r\n */\r\n public constructor(path: string, driver: StorageDriverContract, data?: StorageFileData) {\r\n this._path = path;\r\n this._driver = driver;\r\n this._data = data;\r\n }\r\n\r\n // ============================================================\r\n // Properties\r\n // ============================================================\r\n\r\n /**\r\n * Get the relative file path\r\n */\r\n public get path(): string {\r\n return this._path;\r\n }\r\n\r\n /**\r\n * Get the file name (with extension)\r\n */\r\n public get name(): string {\r\n return basename(this._path);\r\n }\r\n\r\n /**\r\n * Get the file extension (without dot)\r\n */\r\n public get extension(): string {\r\n return extname(this._path).slice(1).toLowerCase();\r\n }\r\n\r\n /**\r\n * Get the directory path\r\n */\r\n public get directory(): string {\r\n return dirname(this._path);\r\n }\r\n\r\n /**\r\n * Get the driver name\r\n */\r\n public get driver(): string {\r\n return this._driver.name;\r\n }\r\n\r\n /**\r\n * Check if file has been deleted\r\n */\r\n public get isDeleted(): boolean {\r\n return this._deleted;\r\n }\r\n\r\n /**\r\n * Get public URL (sync if data cached, otherwise computed)\r\n */\r\n public get url(): string {\r\n this.ensureNotDeleted();\r\n return this._data?.url || this._driver.url(this._path);\r\n }\r\n\r\n /**\r\n * Get the absolute filesystem path (local driver only)\r\n */\r\n public get absolutePath(): string | undefined {\r\n this.ensureNotDeleted();\r\n if (\"path\" in this._driver && typeof this._driver.path === \"function\") {\r\n return this._driver.path(this._path);\r\n }\r\n return undefined;\r\n }\r\n\r\n /**\r\n * Get file hash (SHA-256, available from put operations)\r\n */\r\n public get hash(): string | undefined {\r\n return this._data?.hash;\r\n }\r\n\r\n // ============================================================\r\n // Data Methods (Lazy Loaded)\r\n // ============================================================\r\n\r\n /**\r\n * Get cached file data, or fetch it if not available\r\n */\r\n public async data(): Promise<StorageFileData> {\r\n this.ensureNotDeleted();\r\n if (!this._data) {\r\n // Fetch info and construct data\r\n const info = await this._driver.getInfo(this._path);\r\n this._data = {\r\n path: info.path,\r\n url: this._driver.url(this._path),\r\n size: info.size,\r\n hash: \"\", // Not available from getInfo\r\n mimeType: info.mimeType || \"application/octet-stream\",\r\n driver: this._driver.name,\r\n };\r\n }\r\n return this._data;\r\n }\r\n\r\n /**\r\n * Get file size in bytes\r\n */\r\n public async size(): Promise<number> {\r\n const data = await this.data();\r\n return data.size;\r\n }\r\n\r\n /**\r\n * Get MIME type\r\n */\r\n public async mimeType(): Promise<string> {\r\n const data = await this.data();\r\n return data.mimeType;\r\n }\r\n\r\n /**\r\n * Get last modified date (fetches from driver)\r\n */\r\n public async lastModified(): Promise<Date | undefined> {\r\n this.ensureNotDeleted();\r\n const info = await this._driver.getInfo(this._path);\r\n return info.lastModified;\r\n }\r\n\r\n /**\r\n * Get ETag (cloud drivers, fetches from driver)\r\n */\r\n public async etag(): Promise<string | undefined> {\r\n this.ensureNotDeleted();\r\n const info = await this._driver.getInfo(this._path);\r\n return info.etag;\r\n }\r\n\r\n // ============================================================\r\n // Content Methods\r\n // ============================================================\r\n\r\n /**\r\n * Get file contents as Buffer\r\n */\r\n public async contents(): Promise<Buffer> {\r\n this.ensureNotDeleted();\r\n return this._driver.get(this._path);\r\n }\r\n\r\n /**\r\n * Get file contents as readable stream\r\n */\r\n public async stream(): Promise<Readable> {\r\n this.ensureNotDeleted();\r\n return this._driver.getStream(this._path);\r\n }\r\n\r\n /**\r\n * Get file contents as UTF-8 text\r\n */\r\n public async text(): Promise<string> {\r\n const buffer = await this.contents();\r\n return buffer.toString(\"utf-8\");\r\n }\r\n\r\n /**\r\n * Get file contents as base64 string\r\n */\r\n public async base64(): Promise<string> {\r\n const buffer = await this.contents();\r\n return buffer.toString(\"base64\");\r\n }\r\n\r\n /**\r\n * Get file contents as data URL\r\n */\r\n public async dataUrl(): Promise<string> {\r\n const [buffer, data] = await Promise.all([this.contents(), this.data()]);\r\n return `data:${data.mimeType};base64,${buffer.toString(\"base64\")}`;\r\n }\r\n\r\n // ============================================================\r\n // URL Methods\r\n // ============================================================\r\n\r\n /**\r\n * Get a temporary signed URL\r\n *\r\n * @param expiresIn - Seconds until expiration (default: 3600)\r\n */\r\n public async temporaryUrl(expiresIn = 3600): Promise<string> {\r\n this.ensureNotDeleted();\r\n return this._driver.temporaryUrl(this._path, expiresIn);\r\n }\r\n\r\n // ============================================================\r\n // File Operations\r\n // ============================================================\r\n\r\n /**\r\n * Check if the file exists\r\n */\r\n public async exists(): Promise<boolean> {\r\n if (this._deleted) return false;\r\n return this._driver.exists(this._path);\r\n }\r\n\r\n /**\r\n * Copy the file to a new location\r\n *\r\n * @param destination - Destination path\r\n * @returns New StorageFile instance at destination\r\n */\r\n public async copy(destination: string): Promise<StorageFile> {\r\n this.ensureNotDeleted();\r\n const result = await this._driver.copy(this._path, destination);\r\n return new StorageFile(destination, this._driver, result);\r\n }\r\n\r\n /**\r\n * Move the file to a new location\r\n *\r\n * @param destination - Destination path\r\n * @returns This StorageFile instance with updated path\r\n */\r\n public async move(destination: string): Promise<this> {\r\n this.ensureNotDeleted();\r\n const result = await this._driver.move(this._path, destination);\r\n this._path = destination;\r\n this._data = result; // Update cached data\r\n return this;\r\n }\r\n\r\n /**\r\n * Rename the file (move within same directory)\r\n *\r\n * @param newName - New file name\r\n * @returns This StorageFile instance with updated path\r\n */\r\n public async rename(newName: string): Promise<this> {\r\n const newPath = this.directory === \".\" ? newName : `${this.directory}/${newName}`;\r\n return this.move(newPath);\r\n }\r\n\r\n /**\r\n * Delete the file\r\n *\r\n * @returns true if deleted, false if not found\r\n */\r\n public async delete(): Promise<boolean> {\r\n this.ensureNotDeleted();\r\n const result = await this._driver.delete(this._path);\r\n this._deleted = true;\r\n return result;\r\n }\r\n\r\n // ============================================================\r\n // Cloud-Specific Methods\r\n // ============================================================\r\n\r\n /**\r\n * Set file visibility (cloud drivers only)\r\n *\r\n * @param visibility - \"public\" or \"private\"\r\n * @throws Error if driver doesn't support visibility\r\n */\r\n public async setVisibility(visibility: FileVisibility): Promise<this> {\r\n this.ensureNotDeleted();\r\n\r\n if (!(\"setVisibility\" in this._driver)) {\r\n throw new Error(\"setVisibility is only available for cloud storage drivers\");\r\n }\r\n\r\n await (this._driver as CloudStorageDriverContract).setVisibility(this._path, visibility);\r\n return this;\r\n }\r\n\r\n /**\r\n * Get file visibility (cloud drivers only)\r\n *\r\n * @throws Error if driver doesn't support visibility\r\n */\r\n public async getVisibility(): Promise<FileVisibility> {\r\n this.ensureNotDeleted();\r\n\r\n if (!(\"getVisibility\" in this._driver)) {\r\n throw new Error(\"getVisibility is only available for cloud storage drivers\");\r\n }\r\n\r\n return (this._driver as CloudStorageDriverContract).getVisibility(this._path);\r\n }\r\n\r\n /**\r\n * Set storage class (cloud drivers only)\r\n *\r\n * @param storageClass - Storage class (e.g., \"STANDARD\", \"GLACIER\")\r\n * @throws Error if driver doesn't support storage class\r\n */\r\n public async setStorageClass(storageClass: string): Promise<this> {\r\n this.ensureNotDeleted();\r\n\r\n if (!(\"setStorageClass\" in this._driver)) {\r\n throw new Error(\"setStorageClass is only available for cloud storage drivers\");\r\n }\r\n\r\n await (this._driver as CloudStorageDriverContract).setStorageClass(this._path, storageClass);\r\n return this;\r\n }\r\n\r\n // ============================================================\r\n // Utilities\r\n // ============================================================\r\n\r\n /**\r\n * Ensure the file has not been deleted\r\n */\r\n protected ensureNotDeleted(): void {\r\n if (this._deleted) {\r\n throw new Error(`File \"${this._path}\" has been deleted`);\r\n }\r\n }\r\n\r\n /**\r\n * Create a StorageFile instance from StorageFileData\r\n *\r\n * @param data - Storage file data from put/copy/move operations\r\n * @param driver - Driver instance\r\n */\r\n public static fromData(data: StorageFileData, driver: StorageDriverContract): StorageFile {\r\n return new StorageFile(data.path, driver, data);\r\n }\r\n\r\n /**\r\n * Convert to plain object (returns cached data or constructs it)\r\n */\r\n public toJSON(): {\r\n path: string;\r\n name: string;\r\n extension: string;\r\n driver: string;\r\n url: string;\r\n hash?: string;\r\n } {\r\n return {\r\n path: this._path,\r\n name: this.name,\r\n extension: this.extension,\r\n driver: this._driver.name,\r\n url: this._deleted ? \"\" : this.url,\r\n hash: this._data?.hash,\r\n };\r\n }\r\n\r\n /**\r\n * String representation\r\n */\r\n public toString(): string {\r\n return this._path;\r\n }\r\n}\r\n","import { fileExistsAsync } from \"@mongez/fs\";\nimport fs from \"fs/promises\";\nimport type { Readable } from \"stream\";\nimport type { UploadedFile } from \"../http\";\nimport { StorageFile } from \"./storage-file\";\nimport type {\n DeleteManyResult,\n ListOptions,\n PutOptions,\n StorageDriverContract,\n StorageDriverType,\n StorageFileInfo,\n} from \"./types\";\n\n/**\n * ScopedStorage - Base class for storage operations\n *\n * Wraps a storage driver and provides a consistent, developer-friendly API\n * that returns `StorageFile` instances instead of raw data objects.\n *\n * This class serves as the base for both direct driver usage and the\n * full `Storage` manager class.\n *\n * @example\n * ```typescript\n * // Using via storage.use()\n * const s3Storage = storage.use(\"s3\");\n * const file = await s3Storage.put(buffer, \"images/photo.jpg\");\n *\n * // file is a StorageFile instance with rich API\n * console.log(file.name); // \"photo.jpg\"\n * console.log(file.url); // \"https://...\"\n * await file.copy(\"backup/photo.jpg\");\n * ```\n */\nexport class ScopedStorage {\n /**\n * The underlying storage driver instance\n * @internal\n */\n protected _driver: StorageDriverContract;\n\n /**\n * Create a new ScopedStorage instance\n *\n * @param driver - The storage driver to wrap\n */\n public constructor(driver: StorageDriverContract) {\n this._driver = driver;\n }\n\n // ============================================================\n // Properties\n // ============================================================\n\n /**\n * Get the driver name\n *\n * @returns The name identifier of the underlying driver (e.g., \"local\", \"s3\", \"r2\")\n */\n public get name(): StorageDriverType {\n return this.activeDriver.name;\n }\n\n /**\n * Get the default driver instance\n *\n * Use this for advanced operations that require direct driver access.\n *\n * @returns The raw storage driver\n */\n public get defaultDriver(): StorageDriverContract {\n return this._driver;\n }\n\n /**\n * Get the currently active driver\n *\n * Returns the driver being used for storage operations.\n * Can be overridden in subclasses for dynamic driver resolution (e.g., multi-tenant contexts).\n *\n * @returns The active storage driver\n */\n public get activeDriver(): StorageDriverContract {\n return this._driver;\n }\n\n // ============================================================\n // File Operations\n // ============================================================\n\n /**\n * Store a file in storage\n *\n * Accepts multiple input types and stores the file at the specified location.\n * Returns a `StorageFile` instance for further operations.\n *\n * @param file - File content as Buffer, string path, UploadedFile, or Readable stream\n * @param location - Destination path in storage (e.g., \"uploads/images/photo.jpg\")\n * @param options - Optional storage options\n * @returns StorageFile instance with cached metadata\n *\n * @example\n * ```typescript\n * // From buffer\n * const file = await storage.put(buffer, \"documents/report.pdf\");\n *\n * // From uploaded file\n * const file = await storage.put(uploadedFile, \"avatars/user-123.jpg\");\n *\n * // With options\n * const file = await storage.put(buffer, \"images/photo.jpg\", {\n * mimeType: \"image/jpeg\",\n * cacheControl: \"max-age=31536000\"\n * });\n * ```\n */\n public async put(\n file: UploadedFile | Buffer | string | Readable,\n location: string,\n options?: PutOptions,\n ): Promise<StorageFile> {\n const buffer = await this.toBuffer(file);\n const data = await this.activeDriver.put(buffer, location, options);\n return StorageFile.fromData(data, this.activeDriver);\n }\n\n /**\n * Store a file from a readable stream\n *\n * Optimized for large files - streams data directly without full buffering.\n * Ideal for file uploads, remote file fetching, or processing pipelines.\n *\n * @param stream - Readable stream of file content\n * @param location - Destination path in storage\n * @param options - Optional storage options\n * @returns StorageFile instance with cached metadata\n *\n * @example\n * ```typescript\n * import { createReadStream } from \"fs\";\n *\n * const stream = createReadStream(\"./large-video.mp4\");\n * const file = await storage.putStream(stream, \"videos/upload.mp4\");\n * ```\n */\n public async putStream(\n stream: Readable,\n location: string,\n options?: PutOptions,\n ): Promise<StorageFile> {\n const data = await this.activeDriver.putStream(stream, location, options);\n return StorageFile.fromData(data, this.activeDriver);\n }\n\n /**\n * Store a file from a URL\n *\n * Downloads the file from the URL and stores it.\n *\n * @param url - URL to download from\n * @param location - Destination path in storage\n * @param options - Optional storage options\n * @returns StorageFile instance\n *\n * @example\n * ```typescript\n * const file = await storage.putFromUrl(\n * \"https://example.com/image.jpg\",\n * \"images/downloaded.jpg\"\n * );\n * ```\n */\n public async putFromUrl(\n url: string,\n location: string,\n options?: PutOptions,\n ): Promise<StorageFile> {\n const response = await fetch(url);\n\n if (!response.ok) {\n throw new Error(`Failed to fetch file from ${url}: ${response.statusText}`);\n }\n\n const buffer = Buffer.from(await response.arrayBuffer());\n return this.put(buffer, location, options);\n }\n\n /**\n * Store a file from base64 data URL\n *\n * @param dataUrl - Data URL (data:image/png;base64,iVBORw0KG...)\n * @param location - Destination path in storage\n * @param options - Optional storage options\n * @returns StorageFile instance\n *\n * @example\n * ```typescript\n * const file = await storage.putFromBase64(\n * \"data:image/png;base64,iVBORw0KGgoAAAANS...\",\n * \"images/upload.png\"\n * );\n * ```\n */\n public async putFromBase64(\n dataUrl: string,\n location: string,\n options?: PutOptions,\n ): Promise<StorageFile> {\n // Parse data URL: data:image/png;base64,iVBORw0KG...\n const matches = dataUrl.match(/^data:([^;]+);base64,(.+)$/);\n\n if (!matches) {\n throw new Error(\"Invalid base64 data URL format. Expected: data:mime/type;base64,<data>\");\n }\n\n const [, mimeType, base64Data] = matches;\n const buffer = Buffer.from(base64Data, \"base64\");\n\n return this.put(buffer, location, {\n ...options,\n mimeType: options?.mimeType || mimeType,\n });\n }\n\n /**\n * Retrieve file contents as a Buffer\n *\n * Downloads the entire file into memory. For large files,\n * consider using `getStream()` instead.\n *\n * @param location - Path to the file in storage\n * @returns Buffer containing file contents\n * @throws Error if file not found\n *\n * @example\n * ```typescript\n * const buffer = await storage.get(\"documents/report.pdf\");\n * const content = buffer.toString(\"utf-8\");\n * ```\n */\n public async get(location: string): Promise<Buffer> {\n return this.activeDriver.get(location);\n }\n\n /**\n * Retrieve file contents as a readable stream\n *\n * Streams file data without loading entire file into memory.\n * Ideal for large files or when piping to a response.\n *\n * @param location - Path to the file in storage\n * @returns Readable stream of file contents\n * @throws Error if file not found\n *\n * @example\n * ```typescript\n * const stream = await storage.getStream(\"videos/large.mp4\");\n * stream.pipe(response.raw);\n * ```\n */\n public async getStream(location: string): Promise<Readable> {\n return this.activeDriver.getStream(location);\n }\n\n /**\n * Delete a file from storage\n *\n * @param location - Path to the file, or a StorageFile instance\n * @returns `true` if deleted, `false` if file not found\n *\n * @example\n * ```typescript\n * // By path\n * await storage.delete(\"temp/old-file.txt\");\n *\n * // From StorageFile instance\n * const file = await storage.put(buffer, \"temp/file.txt\");\n * await storage.delete(file);\n * ```\n */\n public async delete(location: string | StorageFile): Promise<boolean> {\n const path = typeof location === \"string\" ? location : location.path;\n return this.activeDriver.delete(path);\n }\n\n /**\n * Delete multiple files at once\n *\n * Performs batch deletion for efficiency. Returns results for each file\n * including success/failure status.\n *\n * @param locations - Array of file paths to delete\n * @returns Array of delete results with status for each file\n *\n * @example\n * ```typescript\n * const results = await storage.deleteMany([\n * \"temp/file1.txt\",\n * \"temp/file2.txt\",\n * \"temp/file3.txt\"\n * ]);\n *\n * for (const result of results) {\n * console.log(`${result.location}: ${result.deleted ? \"deleted\" : result.error}`);\n * }\n * ```\n */\n public async deleteMany(locations: string[]): Promise<DeleteManyResult[]> {\n return this.activeDriver.deleteMany(locations);\n }\n\n /**\n * Delete a directory\n *\n * @param directoryPath - Path to the directory\n */\n public async deleteDirectory(directoryPath: string): Promise<boolean> {\n return await this.activeDriver.deleteDirectory(directoryPath);\n }\n\n /**\n * Check if a file exists in storage\n *\n * @param location - Path to check\n * @returns `true` if file exists, `false` otherwise\n *\n * @example\n * ```typescript\n * if (await storage.exists(\"config/settings.json\")) {\n * const config = await storage.get(\"config/settings.json\");\n * }\n * ```\n */\n public async exists(location: string): Promise<boolean> {\n return this.activeDriver.exists(location);\n }\n\n /**\n * Copy a file to a new location\n *\n * Creates a copy of the file at the destination path.\n * The original file remains unchanged.\n *\n * @param from - Source path or StorageFile instance\n * @param to - Destination path\n * @returns StorageFile instance at the new location\n *\n * @example\n * ```typescript\n * // Copy by path\n * const backup = await storage.copy(\"documents/report.pdf\", \"backups/report.pdf\");\n *\n * // Copy from StorageFile\n * const original = await storage.file(\"documents/report.pdf\");\n * const backup = await storage.copy(original, \"backups/report.pdf\");\n * ```\n */\n public async copy(from: string | StorageFile, to: string): Promise<StorageFile> {\n const fromPath = typeof from === \"string\" ? from : from.path;\n const data = await this.activeDriver.copy(fromPath, to);\n return StorageFile.fromData(data, this.activeDriver);\n }\n\n /**\n * Move a file to a new location\n *\n * Moves the file to the destination path. The original file\n * is deleted after successful copy.\n *\n * @param from - Source path or StorageFile instance\n * @param to - Destination path\n * @returns StorageFile instance at the new location\n *\n * @example\n * ```typescript\n * // Move by path\n * const file = await storage.move(\"uploads/temp.jpg\", \"images/photo.jpg\");\n *\n * // Move from StorageFile\n * const temp = await storage.file(\"uploads/temp.jpg\");\n * const final = await storage.move(temp, \"images/photo.jpg\");\n * ```\n */\n public async move(from: string | StorageFile, to: string): Promise<StorageFile> {\n const fromPath = typeof from === \"string\" ? from : from.path;\n const data = await this.activeDriver.move(fromPath, to);\n return StorageFile.fromData(data, this.activeDriver);\n }\n\n /**\n * Copy an entire directory recursively\n *\n * Copies all files from the source directory to the destination directory,\n * preserving the directory structure.\n *\n * @param from - Source directory path\n * @param to - Destination directory path\n * @param options - Optional concurrency control\n * @returns Number of files copied\n *\n * @example\n * ```typescript\n * // Copy entire directory\n * const count = await storage.copyDirectory(\"uploads/temp\", \"uploads/final\");\n * console.log(`Copied ${count} files`);\n *\n * // With concurrency limit\n * const count = await storage.copyDirectory(\"large-dir\", \"backup\", {\n * concurrency: 10\n * });\n * ```\n */\n public async copyDirectory(\n from: string,\n to: string,\n options?: { concurrency?: number },\n ): Promise<number> {\n const concurrency = options?.concurrency || 5;\n\n // List all files recursively\n const files = await this.list(from, { recursive: true });\n const filesToCopy = files.filter((f) => !f.isDirectory);\n\n // Copy files in batches for efficiency\n let copied = 0;\n for (let i = 0; i < filesToCopy.length; i += concurrency) {\n const batch = filesToCopy.slice(i, i + concurrency);\n await Promise.all(\n batch.map(async (file) => {\n // Calculate relative path and new destination\n const relativePath = file.path.substring(from.length).replace(/^\\//, \"\");\n const newPath = `${to}/${relativePath}`;\n await this.copy(file.path, newPath);\n copied++;\n }),\n );\n }\n\n return copied;\n }\n\n /**\n * Move an entire directory recursively\n *\n * Moves all files from the source directory to the destination directory,\n * then deletes the source directory.\n *\n * @param from - Source directory path\n * @param to - Destination directory path\n * @param options - Optional concurrency control\n * @returns Number of files moved\n *\n * @example\n * ```typescript\n * const count = await storage.moveDirectory(\"uploads/temp\", \"uploads/final\");\n * console.log(`Moved ${count} files`);\n * ```\n */\n public async moveDirectory(\n from: string,\n to: string,\n options?: { concurrency?: number },\n ): Promise<number> {\n // Copy all files first\n const count = await this.copyDirectory(from, to, options);\n\n // Delete source directory\n await this.deleteDirectory(from);\n\n return count;\n }\n\n /**\n * Empty a directory without deleting the directory itself\n *\n * Deletes all files within the directory but preserves the directory structure.\n *\n * @param path - Directory path to empty\n * @returns Number of files deleted\n *\n * @example\n * ```typescript\n * const count = await storage.emptyDirectory(\"uploads/temp\");\n * console.log(`Deleted ${count} files`);\n * ```\n */\n public async emptyDirectory(path: string): Promise<number> {\n // List all files in directory\n const files = await this.list(path, { recursive: true });\n const filePaths = files.filter((f) => !f.isDirectory).map((f) => f.path);\n\n if (filePaths.length === 0) {\n return 0;\n }\n\n // Delete all files\n await this.deleteMany(filePaths);\n\n return filePaths.length;\n }\n\n /**\n * List files in a directory\n *\n * Returns file information for all files in the specified directory.\n * Supports recursive listing and pagination.\n *\n * @param directory - Directory path (defaults to root)\n * @param options - List options (recursive, limit, cursor)\n * @returns Array of file information objects\n *\n * @example\n * ```typescript\n * // List all files in uploads\n * const files = await storage.list(\"uploads\");\n *\n * // Recursive listing with limit\n * const files = await storage.list(\"uploads\", {\n * recursive: true,\n * limit: 100\n * });\n * ```\n */\n public async list(directory?: string, options?: ListOptions): Promise<StorageFileInfo[]> {\n return this.activeDriver.list(directory || \"\", options);\n }\n\n // ============================================================\n // URL Operations\n // ============================================================\n\n /**\n * Get the public URL for a file\n *\n * Returns the URL where the file can be accessed. For local storage,\n * this is typically a path prefix. For cloud storage, this is the\n * bucket URL or CDN URL.\n *\n * @param location - File path\n * @returns Public URL string\n *\n * @example\n * ```typescript\n * const url = storage.url(\"images/photo.jpg\");\n * // Local: \"/uploads/images/photo.jpg\"\n * // S3: \"https://bucket.s3.amazonaws.com/images/photo.jpg\"\n * ```\n */\n public url(location: string): string {\n return this.activeDriver.url(location);\n }\n\n /**\n * Get a temporary signed URL with expiration\n *\n * Creates a URL that provides temporary access to the file.\n * For cloud storage, this uses presigned URLs.\n * For local storage, this uses HMAC-signed tokens.\n *\n * @param location - File path\n * @param expiresIn - Seconds until URL expires (default: 3600)\n * @returns Signed URL string\n *\n * @example\n * ```typescript\n * // URL valid for 1 hour\n * const url = await storage.temporaryUrl(\"private/document.pdf\");\n *\n * // URL valid for 24 hours\n * const url = await storage.temporaryUrl(\"private/document.pdf\", 86400);\n * ```\n */\n public async temporaryUrl(location: string, expiresIn?: number): Promise<string> {\n return this.activeDriver.temporaryUrl(location, expiresIn);\n }\n\n // ============================================================\n // Metadata Operations\n // ============================================================\n\n /**\n * Get file metadata without downloading the file\n *\n * Retrieves information about a file including size, last modified date,\n * and MIME type without downloading the file contents.\n *\n * @param location - File path\n * @returns File information object\n * @throws Error if file not found\n *\n * @example\n * ```typescript\n * const info = await storage.getInfo(\"documents/report.pdf\");\n * console.log(`Size: ${info.size} bytes`);\n * console.log(`Type: ${info.mimeType}`);\n * console.log(`Modified: ${info.lastModified}`);\n * ```\n */\n public async getInfo(location: string): Promise<StorageFileInfo> {\n return this.activeDriver.getInfo(location);\n }\n\n /**\n * Get file size in bytes\n *\n * Shortcut for `getInfo(location).size`.\n *\n * @param location - File path\n * @returns File size in bytes\n * @throws Error if file not found\n */\n public async size(location: string): Promise<number> {\n return this.activeDriver.size(location);\n }\n\n /**\n * Get a StorageFile instance for OOP-style operations\n *\n * Creates a `StorageFile` wrapper for the specified path,\n * allowing fluent method chaining for file operations.\n *\n * @param location - File path\n * @returns StorageFile instance\n *\n * @example\n * ```typescript\n * const file = await storage.file(\"uploads/image.jpg\");\n *\n * // Properties\n * console.log(file.name); // \"image.jpg\"\n * console.log(file.extension); // \"jpg\"\n *\n * // Operations\n * await file.copy(\"backup/image.jpg\");\n * await file.delete();\n * ```\n */\n public async file(location: string): Promise<StorageFile> {\n return new StorageFile(location, this.activeDriver);\n }\n\n // ============================================================\n // Utilities\n // ============================================================\n\n /**\n * Convert various input types to Buffer\n *\n * @param file - Input file in various formats\n * @returns Buffer containing file contents\n * @internal\n */\n protected async toBuffer(file: UploadedFile | Buffer | string | Readable): Promise<Buffer> {\n // Already a buffer\n if (Buffer.isBuffer(file)) {\n return file;\n }\n\n // Readable stream - collect into buffer\n if (this.isReadable(file)) {\n return this.streamToBuffer(file as Readable);\n }\n\n // String content\n if (typeof file === \"string\") {\n if (await fileExistsAsync(file)) {\n return fs.readFile(file);\n }\n\n return Buffer.from(file);\n }\n\n // UploadedFile\n return (file as UploadedFile).buffer();\n }\n\n /**\n * Check if value is a Readable stream\n *\n * @param value - Value to check\n * @returns True if value is a Readable stream\n * @internal\n */\n protected isReadable(value: unknown): value is Readable {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"pipe\" in value &&\n typeof (value as Readable).pipe === \"function\"\n );\n }\n\n /**\n * Convert a Readable stream to Buffer\n *\n * @param stream - Readable stream\n * @returns Buffer containing stream contents\n * @internal\n */\n protected async streamToBuffer(stream: Readable): Promise<Buffer> {\n const chunks: Buffer[] = [];\n for await (const chunk of stream) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n }\n return Buffer.concat(chunks as unknown as Uint8Array[]);\n }\n\n /**\n * Prepend a prefix to a location path\n *\n * Useful for organizing files into directories.\n *\n * @param prefix - Prefix to add (e.g., \"uploads\")\n * @param location - Original location path\n * @returns Combined path with prefix\n *\n * @example\n * ```typescript\n * storage.prepend(\"uploads\", \"image.jpg\"); // \"uploads/image.jpg\"\n * storage.prepend(\"uploads/\", \"/image.jpg\"); // \"uploads/image.jpg\"\n * ```\n */\n public prepend(prefix: string, location: string): string {\n return `${prefix.replace(/\\/$/, \"\")}/${location.replace(/^\\//, \"\")}`;\n }\n\n /**\n * Append a suffix to a location path (before extension)\n *\n * Useful for creating variants of files (thumbnails, etc.).\n *\n * @param location - Original location path\n * @param suffix - Suffix to add before extension\n * @returns Path with suffix added before extension\n *\n * @example\n * ```typescript\n * storage.append(\"image.jpg\", \"_thumb\"); // \"image_thumb.jpg\"\n * storage.append(\"document.pdf\", \"_v2\"); // \"document_v2.pdf\"\n * ```\n */\n public append(location: string, suffix: string): string {\n const lastDot = location.lastIndexOf(\".\");\n if (lastDot === -1) {\n return `${location}${suffix}`;\n }\n return `${location.substring(0, lastDot)}${suffix}${location.substring(lastDot)}`;\n }\n}\n","import { Context, contextManager } from \"@warlock.js/context\";\nimport type { StorageDriverContract } from \"../types\";\n\nexport type StorageDriverContextStore = {\n driver?: StorageDriverContract;\n prefix?: string;\n metadata?: Record<string, any>;\n};\n\n/**\n * Storage Driver Context\n *\n * Manages the active storage driver and path prefix using AsyncLocalStorage.\n * Allows multi-tenant applications to switch drivers and isolate storage paths per request context.\n *\n * @example\n * ```typescript\n * // Set driver with tenant-specific prefix\n * storageDriverContext.setDriver(storage.getDriver(\"s3\"), {\n * prefix: \"tenant-123\",\n * metadata: { tenantId: \"123\" }\n * });\n *\n * // Or just set prefix for same driver\n * storageDriverContext.setPrefix(\"tenant-456\");\n * ```\n */\nclass StorageDriverContext extends Context<StorageDriverContextStore> {\n /**\n * Get the current storage driver\n */\n public getDriver(): StorageDriverContract | undefined {\n return this.get(\"driver\");\n }\n\n /**\n * Get the current path prefix (e.g., tenant-specific path)\n */\n public getPrefix(): string | undefined {\n return this.get(\"prefix\");\n }\n\n /**\n * Get context metadata (e.g., tenantId)\n */\n public getMetadata(): Record<string, any> | undefined {\n return this.get(\"metadata\");\n }\n\n /**\n * Set the active driver with optional prefix and metadata\n *\n * @param driver - Storage driver to use\n * @param options - Optional prefix and metadata\n */\n public setDriver(\n driver: StorageDriverContract,\n options?: { prefix?: string; metadata?: Record<string, any> },\n ): void {\n this.update({\n driver,\n prefix: options?.prefix,\n metadata: options?.metadata,\n });\n }\n\n /**\n * Set only the path prefix (keeps current driver)\n *\n * Useful for multi-tenant scenarios where you want to isolate\n * storage paths without changing the driver.\n *\n * @param prefix - Path prefix to prepend to all operations\n */\n public setPrefix(prefix: string): void {\n this.update({ prefix });\n }\n\n /**\n * Clear the prefix\n */\n public clearPrefix(): void {\n this.update({ prefix: undefined });\n }\n\n /**\n * Build the initial storage store with defaults\n */\n public buildStore(): StorageDriverContextStore {\n return {\n driver: undefined,\n prefix: undefined,\n metadata: undefined,\n };\n }\n}\n\nexport const storageDriverContext = new StorageDriverContext();\n\ncontextManager.register(\"storage\", storageDriverContext);\n","/**\r\n * MIME type utilities\r\n *\r\n * This module wraps the mime package to avoid type conflicts\r\n * with @types/send which has its own @types/mime dependency.\r\n */\r\nimport mime from \"mime\";\r\n\r\n/**\r\n * Get MIME type from file path or extension\r\n *\r\n * @param path - File path or extension\r\n * @returns MIME type or \"application/octet-stream\" if unknown\r\n */\r\nexport function getMimeType(path: string): string {\r\n return mime.getType(path) || \"application/octet-stream\";\r\n}\r\n\r\n/**\r\n * Common MIME type constants\r\n */\r\nexport const MimeTypes = {\r\n // Images\r\n jpeg: \"image/jpeg\",\r\n png: \"image/png\",\r\n gif: \"image/gif\",\r\n webp: \"image/webp\",\r\n svg: \"image/svg+xml\",\r\n ico: \"image/x-icon\",\r\n\r\n // Documents\r\n pdf: \"application/pdf\",\r\n txt: \"text/plain\",\r\n html: \"text/html\",\r\n css: \"text/css\",\r\n js: \"application/javascript\",\r\n json: \"application/json\",\r\n xml: \"application/xml\",\r\n\r\n // Archives\r\n zip: \"application/zip\",\r\n gzip: \"application/gzip\",\r\n\r\n // Media\r\n mp3: \"audio/mpeg\",\r\n mp4: \"video/mp4\",\r\n webm: \"video/webm\",\r\n ogg: \"audio/ogg\",\r\n\r\n // Binary\r\n binary: \"application/octet-stream\",\r\n} as const;\r\n","import crypto from \"crypto\";\nimport type { Readable } from \"stream\";\nimport { storageDriverContext } from \"../context/storage-driver-context\";\nimport type {\n CloudStorageDriverContract,\n CloudStorageDriverOptions,\n CloudStorageFileData,\n DeleteManyResult,\n FileVisibility,\n ListOptions,\n PresignedOptions,\n PresignedUploadOptions,\n PutOptions,\n StorageDriverType,\n StorageFileInfo,\n} from \"../types\";\nimport { getMimeType } from \"../utils/mime\";\n\n// ============================================================\n// Lazy-loaded S3 SDK Types\n// ============================================================\n\n/**\n * Cached S3 SDK modules (loaded once, reused)\n */\nlet S3Client: typeof import(\"@aws-sdk/client-s3\");\nlet S3Storage: typeof import(\"@aws-sdk/lib-storage\");\nlet S3Presigner: typeof import(\"@aws-sdk/s3-request-presigner\");\n\nlet isModuleExists: boolean | null = null;\n\n/**\n * Installation instructions for S3 SDK packages\n */\nconst S3_INSTALL_INSTRUCTIONS = `\nCloud storage requires the AWS S3 SDK packages.\nInstall them with:\n\n npm install @aws-sdk/client-s3 @aws-sdk/lib-storage @aws-sdk/s3-request-presigner\n\nOr with your preferred package manager:\n\n pnpm add @aws-sdk/client-s3 @aws-sdk/lib-storage @aws-sdk/s3-request-presigner\n yarn add @aws-sdk/client-s3 @aws-sdk/lib-storage @aws-sdk/s3-request-presigner\n`.trim();\n\n/**\n */\nasync function loadS3() {\n try {\n // load @aws-sdk/client-s3\n S3Client = await import(\"@aws-sdk/client-s3\");\n // load @aws-sdk/lib-storage\n S3Storage = await import(\"@aws-sdk/lib-storage\");\n // load @aws-sdk/s3-request-presigner\n S3Presigner = await import(\"@aws-sdk/s3-request-presigner\");\n\n isModuleExists = true;\n } catch {\n isModuleExists = false;\n }\n}\n\nloadS3();\n\n// ============================================================\n// CloudDriver Base Class\n// ============================================================\n\n/**\n * Base abstract class for all S3-compatible cloud storage drivers\n *\n * This class contains all shared logic for S3-compatible storage services\n * including AWS S3, Cloudflare R2, DigitalOcean Spaces, and others.\n *\n * **Important:** S3 SDK packages are lazy-loaded on first use.\n * Users must install them separately:\n * ```\n * npm install @aws-sdk/client-s3 @aws-sdk/lib-storage @aws-sdk/s3-request-presigner\n * ```\n *\n * Subclasses must implement:\n * - `name`: Driver identifier (e.g., \"s3\", \"r2\", \"spaces\")\n * - `url()`: Returns the public URL for a file (provider-specific format)\n */\nexport abstract class CloudDriver<\n TOptions extends Partial<CloudStorageDriverOptions> = CloudStorageDriverOptions,\n> implements CloudStorageDriverContract {\n /**\n * S3-compatible client (lazy-loaded)\n */\n protected client!: InstanceType<typeof import(\"@aws-sdk/client-s3\").S3Client>;\n\n /**\n * Retry configuration\n */\n protected retryConfig: {\n maxRetries: number;\n initialDelayMs: number;\n maxDelayMs: number;\n backoffMultiplier: number;\n };\n\n public constructor(public options: TOptions) {\n if (!isModuleExists) {\n throw new Error(S3_INSTALL_INSTRUCTIONS);\n }\n\n this.client = new S3Client.S3Client({\n region: this.options.region!,\n credentials: {\n accessKeyId: this.options.accessKeyId!,\n secretAccessKey: this.options.secretAccessKey!,\n },\n ...(this.getEndpoint() && { endpoint: this.getEndpoint() }),\n });\n\n // Initialize retry configuration\n this.retryConfig = {\n maxRetries: this.options.retry?.maxRetries ?? 3,\n initialDelayMs: this.options.retry?.initialDelayMs ?? 1000,\n maxDelayMs: this.options.retry?.maxDelayMs ?? 10000,\n backoffMultiplier: this.options.retry?.backoffMultiplier ?? 2,\n };\n }\n\n /**\n * Driver name identifier\n */\n public abstract readonly name: StorageDriverType;\n\n /**\n * Get public URL for file\n * Must be implemented by subclasses with provider-specific format\n */\n public abstract url(location: string): string;\n\n /**\n * Get endpoint URL\n * Can be overridden by subclasses for provider-specific endpoints\n */\n protected getEndpoint(): string | undefined {\n return this.options.endpoint;\n }\n\n // ============================================================\n // Helper Methods\n // ============================================================\n\n /**\n * Apply prefix to location path\n *\n * Priority: context prefix > driver options prefix > no prefix\n * This allows multi-tenant scenarios where context overrides driver config.\n *\n * @param location - Original location path\n * @returns Location with prefix applied if one exists\n */\n public applyPrefix(location: string): string {\n // Check context prefix first (highest priority)\n const contextPrefix = storageDriverContext.getPrefix();\n const prefix = contextPrefix || this.options.prefix;\n\n if (!prefix) {\n return location;\n }\n\n const cleanPrefix = prefix.replace(/\\/+$/, \"\");\n const cleanLocation = location.replace(/^\\/+/, \"\");\n\n // Avoid double-prefixing\n if (cleanLocation.startsWith(cleanPrefix + \"/\") || cleanLocation === cleanPrefix) {\n return cleanLocation;\n }\n\n return `${cleanPrefix}/${cleanLocation}`;\n }\n\n /**\n * Normalize storage path (remove double slashes, sanitize)\n * @internal\n */\n protected normalizePath(path: string): string {\n return path\n .replace(/\\/+/g, \"/\") // Remove multiple slashes\n .replace(/^\\//, \"\") // Remove leading slash\n .trim();\n }\n\n /**\n * Execute an operation with retry logic\n *\n * Retries on transient errors with exponential backoff.\n *\n * @param operation - Async operation to execute\n * @param operationName - Name for logging\n * @returns Result of the operation\n * @internal\n */\n protected async withRetry<T>(\n operation: () => Promise<T>,\n operationName: string = \"operation\",\n ): Promise<T> {\n const { maxRetries, initialDelayMs, backoffMultiplier, maxDelayMs } = this.retryConfig;\n\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt < maxRetries; attempt++) {\n try {\n return await operation();\n } catch (error) {\n lastError = error as Error;\n\n // Don't retry on the last attempt\n if (attempt === maxRetries - 1) {\n break;\n }\n\n // Check if error is retryable\n if (!this.isRetryableError(error)) {\n throw error; // Non-retryable error, fail immediately\n }\n\n // Calculate delay with exponential backoff\n const delayMs = Math.min(initialDelayMs * Math.pow(backoffMultiplier, attempt), maxDelayMs);\n\n // Wait before retrying\n await new Promise((resolve) => setTimeout(resolve, delayMs));\n }\n }\n\n throw new Error(`${operationName} failed after ${maxRetries} attempts: ${lastError?.message}`);\n }\n\n /**\n * Check if an error is retryable\n *\n * Retries on:\n * - Network errors\n * - 5xx server errors\n * - Rate limiting (429)\n * - Timeout errors\n *\n * Does NOT retry on:\n * - 4xx client errors (except 429)\n * - Authentication errors\n * - Not found errors\n *\n * @param error - Error to check\n * @returns true if error is retryable\n * @internal\n */\n protected isRetryableError(error: any): boolean {\n // Network errors\n if (error.code === \"ECONNRESET\" || error.code === \"ETIMEDOUT\" || error.code === \"ENOTFOUND\") {\n return true;\n }\n\n // S3 SDK errors\n if (error.name === \"NetworkingError\" || error.name === \"TimeoutError\") {\n return true;\n }\n\n // HTTP status codes\n const statusCode = error.$metadata?.httpStatusCode || error.statusCode;\n if (statusCode) {\n // 5xx server errors are retryable\n if (statusCode >= 500 && statusCode < 600) {\n return true;\n }\n\n // 429 Too Many Requests is retryable\n if (statusCode === 429) {\n return true;\n }\n }\n\n return false;\n }\n\n // ============================================================\n // Core File Operations\n // ============================================================\n\n /**\n * Put file to cloud storage\n */\n public async put(\n file: Buffer,\n location: string,\n options?: PutOptions,\n ): Promise<CloudStorageFileData> {\n return this.withRetry(async () => {\n const { PutObjectCommand } = S3Client;\n\n // Apply storage prefix\n location = this.applyPrefix(location);\n\n const hash = this.calculateHash(file);\n const mimeType = options?.mimeType || this.guessMimeType(location);\n\n const command = new PutObjectCommand({\n Bucket: this.options.bucket,\n Key: location,\n Body: file,\n ContentType: mimeType,\n CacheControl: options?.cacheControl,\n ContentDisposition: options?.contentDisposition,\n Metadata: options?.metadata,\n ACL: options?.visibility === \"public\" ? \"public-read\" : undefined,\n });\n\n const result = await this.client.send(command);\n\n return {\n path: location,\n url: this.url(location),\n size: file.length,\n hash,\n mimeType,\n driver: this.name,\n bucket: this.options.bucket!,\n region: this.options.region!,\n etag: result.ETag,\n versionId: result.VersionId,\n };\n }, \"put\");\n }\n\n /**\n * Put file from a readable stream (for large files)\n * Uses S3 multipart upload for efficient streaming\n */\n public async putStream(\n stream: Readable,\n location: string,\n options?: PutOptions,\n ): Promise<CloudStorageFileData> {\n return this.withRetry(async () => {\n const { Upload } = S3Storage;\n\n // Apply storage prefix\n location = this.applyPrefix(location);\n\n const mimeType = options?.mimeType || this.guessMimeType(location);\n\n const upload = new Upload({\n client: this.client,\n params: {\n Bucket: this.options.bucket,\n Key: location,\n Body: stream,\n ContentType: mimeType,\n CacheControl: options?.cacheControl,\n ContentDisposition: options?.contentDisposition,\n Metadata: options?.metadata,\n ACL: options?.visibility === \"public\" ? \"public-read\" : undefined,\n },\n });\n\n const result = await upload.done();\n\n // Get file info for size and hash\n const info = await this.getInfo(location);\n\n return {\n path: location,\n url: this.url(location),\n size: info.size,\n hash: info.etag?.replace(/\"/g, \"\") || \"\",\n mimeType,\n driver: this.name,\n bucket: this.options.bucket!,\n region: this.options.region!,\n etag: result.ETag,\n versionId: result.VersionId,\n };\n }, \"putStream\");\n }\n\n /**\n * Get file contents as Buffer\n */\n public async get(location: string): Promise<Buffer> {\n return this.withRetry(async () => {\n const { GetObjectCommand } = S3Client;\n\n // Apply storage prefix\n location = this.applyPrefix(location);\n\n const command = new GetObjectCommand({\n Bucket: this.options.bucket,\n Key: location,\n });\n\n const result = await this.client.send(command);\n\n if (!result.Body) {\n throw new Error(`File not found: ${location}`);\n }\n\n return Buffer.from(await result.Body.transformToByteArray());\n }, \"get\");\n }\n\n /**\n * Get file as a readable stream (for large files)\n */\n public async getStream(location: string): Promise<Readable> {\n return this.withRetry(async () => {\n const { GetObjectCommand } = S3Client;\n\n // Apply storage prefix\n location = this.applyPrefix(location);\n\n const command = new GetObjectCommand({\n Bucket: this.options.bucket,\n Key: location,\n });\n\n const result = await this.client.send(command);\n\n if (!result.Body) {\n throw new Error(`File not found: ${location}`);\n }\n\n return result.Body as Readable;\n }, \"getStream\");\n }\n\n /**\n * Delete a file\n */\n public async delete(location: string): Promise<boolean> {\n return this.withRetry(async () => {\n const { DeleteObjectCommand } = S3Client;\n\n // Apply storage prefix\n location = this.applyPrefix(location);\n\n const command = new DeleteObjectCommand({\n Bucket: this.options.bucket,\n Key: location,\n });\n\n await this.client.send(command);\n\n return true;\n }, \"delete\");\n }\n\n /**\n * Delete multiple files at once (uses batch delete for efficiency)\n */\n public async deleteMany(locations: string[]): Promise<DeleteManyResult[]> {\n if (locations.length === 0) {\n return [];\n }\n\n return this.withRetry(async () => {\n const { DeleteObjectsCommand } = S3Client;\n\n // Apply storage prefix to all locations\n const prefixedLocations = locations.map((loc) => this.applyPrefix(loc));\n\n const command = new DeleteObjectsCommand({\n Bucket: this.options.bucket,\n Delete: {\n Objects: prefixedLocations.map((Key) => ({ Key })),\n Quiet: false,\n },\n });\n\n const result = await this.client.send(command);\n const results: DeleteManyResult[] = [];\n\n // Process successful deletes\n for (const deleted of result.Deleted || []) {\n if (deleted.Key) {\n results.push({ location: deleted.Key, deleted: true });\n }\n }\n\n // Process errors\n for (const error of result.Errors || []) {\n if (error.Key) {\n results.push({\n location: error.Key,\n deleted: false,\n error: error.Message || \"Unknown error\",\n });\n }\n }\n\n return results;\n }, \"deleteMany\");\n }\n\n /**\n * Delete directory (recursively deletes all objects with matching prefix)\n *\n * S3/R2 doesn't have true directories - only key prefixes.\n * This method lists all objects with the prefix and deletes them in batches.\n *\n * @param directoryPath - Directory prefix to delete\n * @returns true when all objects are deleted\n */\n public async deleteDirectory(directoryPath: string): Promise<boolean> {\n // Apply storage prefix\n directoryPath = this.applyPrefix(directoryPath);\n\n // Ensure directory path ends with / for proper prefix matching\n const prefix = directoryPath.endsWith(\"/\") ? directoryPath : `${directoryPath}/`;\n\n let hasMore = true;\n\n while (hasMore) {\n // List up to 1000 objects (S3/R2 max per request)\n const objects = await this.list(prefix, {\n limit: 1000,\n recursive: true,\n });\n\n if (objects.length === 0) {\n break;\n }\n\n // Filter out directories (we only delete files)\n const filePaths = objects.filter((obj) => !obj.isDirectory).map((obj) => obj.path);\n\n if (filePaths.length === 0) {\n break;\n }\n\n // Delete batch (deleteMany already has prefix applied, so paths already have it)\n // Note: We pass the paths as-is since they already include the prefix from list()\n const results = await this.deleteMany(filePaths);\n\n // Continue if we got full batch (might be more)\n hasMore = objects.length >= 1000;\n }\n\n return true;\n }\n\n /**\n * Check if file exists\n */\n public async exists(location: string): Promise<boolean> {\n // No retry for exists - it should be fast and failure means non-existent\n try {\n const { HeadObjectCommand } = S3Client;\n\n // Apply storage prefix\n location = this.applyPrefix(location);\n\n const command = new HeadObjectCommand({\n Bucket: this.options.bucket,\n Key: location,\n });\n\n await this.client.send(command);\n return true;\n } catch {\n return false;\n }\n }\n\n // ============================================================\n // URL Operations\n // ============================================================\n\n /**\n * Get a temporary presigned URL (alias for getPresignedUrl)\n */\n public async temporaryUrl(location: string, expiresIn = 3600): Promise<string> {\n return this.getPresignedUrl(location, { expiresIn });\n }\n\n /**\n * Get presigned URL for downloading\n */\n public async getPresignedUrl(location: string, options?: PresignedOptions): Promise<string> {\n return this.withRetry(async () => {\n const { GetObjectCommand } = S3Client;\n const { getSignedUrl } = S3Presigner;\n\n // Apply storage prefix\n location = this.applyPrefix(location);\n\n const command = new GetObjectCommand({\n Bucket: this.options.bucket,\n Key: location,\n });\n\n return getSignedUrl(this.client, command, {\n expiresIn: options?.expiresIn || 3600,\n });\n }, \"getPresignedUrl\");\n }\n\n /**\n * Get presigned URL for uploading\n */\n public async getPresignedUploadUrl(\n location: string,\n options?: PresignedUploadOptions,\n ): Promise<string> {\n return this.withRetry(async () => {\n const { PutObjectCommand } = S3Client;\n const { getSignedUrl } = S3Presigner;\n\n // Apply storage prefix\n location = this.applyPrefix(location);\n\n const command = new PutObjectCommand({\n Bucket: this.options.bucket,\n Key: location,\n ContentType: options?.contentType,\n Metadata: options?.metadata,\n });\n\n return getSignedUrl(this.client, command, {\n expiresIn: options?.expiresIn || 3600,\n });\n }, \"getPresignedUploadUrl\");\n }\n\n // ============================================================\n // Metadata Operations\n // ============================================================\n\n /**\n * Get file info/metadata without downloading\n */\n public async getInfo(location: string): Promise<StorageFileInfo> {\n return this.withRetry(async () => {\n const { HeadObjectCommand } = S3Client;\n\n // Apply storage prefix\n location = this.applyPrefix(location);\n\n const command = new HeadObjectCommand({\n Bucket: this.options.bucket,\n Key: location,\n });\n\n const result = await this.client.send(command);\n const name = location.split(\"/\").pop() || \"\";\n\n return {\n path: location,\n name,\n size: result.ContentLength || 0,\n isDirectory: false,\n lastModified: result.LastModified,\n mimeType: result.ContentType || this.guessMimeType(location),\n etag: result.ETag,\n storageClass: result.StorageClass,\n };\n }, \"getInfo\");\n }\n\n /**\n * Get file size in bytes (shortcut for getInfo().size)\n */\n public async size(location: string): Promise<number> {\n const info = await this.getInfo(location);\n return info.size;\n }\n\n // ============================================================\n // File Operations\n // ============================================================\n\n /**\n * Copy file to a new location\n */\n public async copy(from: string, to: string): Promise<CloudStorageFileData> {\n return this.withRetry(async () => {\n const { CopyObjectCommand, HeadObjectCommand } = S3Client;\n\n // Apply storage prefix to both paths\n from = this.applyPrefix(from);\n to = this.applyPrefix(to);\n\n const command = new CopyObjectCommand({\n Bucket: this.options.bucket,\n CopySource: `${this.options.bucket}/${from}`,\n Key: to,\n });\n\n const result = await this.client.send(command);\n\n // Get file metadata\n const headCommand = new HeadObjectCommand({\n Bucket: this.options.bucket,\n Key: to,\n });\n const headResult = await this.client.send(headCommand);\n\n return {\n path: to,\n url: this.url(to),\n size: headResult.ContentLength || 0,\n hash: headResult.ETag?.replace(/\"/g, \"\") || \"\",\n mimeType: headResult.ContentType || this.guessMimeType(to),\n driver: this.name,\n bucket: this.options.bucket!,\n region: this.options.region!,\n etag: result.CopyObjectResult?.ETag,\n versionId: result.VersionId,\n };\n }, \"copy\");\n }\n\n /**\n * Move file to a new location\n */\n public async move(from: string, to: string): Promise<CloudStorageFileData> {\n const file = await this.copy(from, to);\n await this.delete(from);\n return file;\n }\n\n /**\n * List files in a directory\n */\n public async list(directory: string, options?: ListOptions): Promise<StorageFileInfo[]> {\n return this.withRetry(async () => {\n const { ListObjectsV2Command } = S3Client;\n\n // Apply storage prefix\n directory = this.applyPrefix(directory);\n\n const command = new ListObjectsV2Command({\n Bucket: this.options.bucket,\n Prefix: directory,\n MaxKeys: options?.limit,\n ContinuationToken: options?.cursor,\n Delimiter: options?.recursive ? undefined : \"/\",\n });\n\n const result = await this.client.send(command);\n const files: StorageFileInfo[] = [];\n\n // Add files\n for (const object of result.Contents || []) {\n if (!object.Key) continue;\n\n files.push({\n path: object.Key,\n name: object.Key.split(\"/\").pop() || \"\",\n size: object.Size || 0,\n isDirectory: false,\n lastModified: object.LastModified,\n etag: object.ETag,\n storageClass: object.StorageClass,\n });\n }\n\n // Add directories\n for (const prefix of result.CommonPrefixes || []) {\n if (!prefix.Prefix) continue;\n\n files.push({\n path: prefix.Prefix,\n name: prefix.Prefix.split(\"/\").filter(Boolean).pop() || \"\",\n size: 0,\n isDirectory: true,\n });\n }\n\n return files;\n }, \"list\");\n }\n\n // ============================================================\n // Cloud-Specific Operations\n // ============================================================\n\n /**\n * Get bucket name\n */\n public getBucket(): string {\n return this.options.bucket!;\n }\n\n /**\n * Get region\n */\n public getRegion(): string {\n return this.options.region!;\n }\n\n /**\n * Set storage class (e.g., STANDARD, GLACIER, etc.)\n */\n public async setStorageClass(location: string, storageClass: string): Promise<void> {\n return this.withRetry(async () => {\n const { CopyObjectCommand } = S3Client;\n\n // Apply storage prefix\n location = this.applyPrefix(location);\n\n const command = new CopyObjectCommand({\n Bucket: this.options.bucket,\n CopySource: `${this.options.bucket}/${location}`,\n Key: location,\n StorageClass: storageClass as any,\n MetadataDirective: \"COPY\",\n });\n\n await this.client.send(command);\n }, \"setStorageClass\");\n }\n\n /**\n * Set file visibility (public or private)\n */\n public async setVisibility(location: string, visibility: FileVisibility): Promise<void> {\n return this.withRetry(async () => {\n const { PutObjectAclCommand } = S3Client;\n\n // Apply storage prefix\n location = this.applyPrefix(location);\n\n const command = new PutObjectAclCommand({\n Bucket: this.options.bucket,\n Key: location,\n ACL: visibility === \"public\" ? \"public-read\" : \"private\",\n });\n\n await this.client.send(command);\n }, \"setVisibility\");\n }\n\n /**\n * Get file visibility\n */\n public async getVisibility(location: string): Promise<FileVisibility> {\n return this.withRetry(async () => {\n const { GetObjectAclCommand } = S3Client;\n\n // Apply storage prefix\n location = this.applyPrefix(location);\n\n const command = new GetObjectAclCommand({\n Bucket: this.options.bucket,\n Key: location,\n });\n\n const result = await this.client.send(command);\n\n // Check if any grant allows public read\n const hasPublicRead = result.Grants?.some(\n (grant) =>\n grant.Grantee?.URI === \"http://acs.amazonaws.com/groups/global/AllUsers\" &&\n grant.Permission === \"READ\",\n );\n\n return hasPublicRead ? \"public\" : \"private\";\n }, \"getVisibility\");\n }\n\n // ============================================================\n // Utilities\n // ============================================================\n\n /**\n * Calculate SHA-256 hash\n */\n protected calculateHash(buffer: Buffer): string {\n return crypto.createHash(\"sha256\").update(new Uint8Array(buffer)).digest(\"hex\");\n }\n\n /**\n * Guess MIME type from file extension\n */\n protected guessMimeType(location: string): string {\n return getMimeType(location);\n }\n}\n","import type { CloudStorageDriverOptions } from \"../types\";\r\nimport { CloudDriver } from \"./cloud-driver\";\r\n\r\n/**\r\n * DigitalOcean Spaces Storage Driver\r\n *\r\n * Spaces is S3-compatible with a different URL structure.\r\n *\r\n * URL Patterns:\r\n * - With urlPrefix: {urlPrefix}/{key}\r\n * - CDN URL: https://{bucket}.{region}.cdn.digitaloceanspaces.com/{key}\r\n * - Origin URL: https://{bucket}.{region}.digitaloceanspaces.com/{key}\r\n *\r\n * Regions: nyc3, sfo3, ams3, sgp1, fra1, etc.\r\n *\r\n * @example\r\n * ```typescript\r\n * const driver = new DOSpacesDriver({\r\n * bucket: \"my-space\",\r\n * region: \"nyc3\",\r\n * accessKeyId: process.env.DO_SPACES_KEY,\r\n * secretAccessKey: process.env.DO_SPACES_SECRET,\r\n * });\r\n * ```\r\n */\r\nexport class DOSpacesDriver extends CloudDriver<CloudStorageDriverOptions> {\r\n /**\r\n * Driver name\r\n */\r\n public readonly name = \"spaces\";\r\n\r\n /**\r\n * Get Spaces endpoint URL\r\n *\r\n * Spaces endpoint format: https://{region}.digitaloceanspaces.com\r\n */\r\n protected getEndpoint(): string {\r\n return this.options.endpoint || `https://${this.options.region}.digitaloceanspaces.com`;\r\n }\r\n\r\n /**\r\n * Get public URL for file\r\n *\r\n * Note: DO Spaces includes automatic CDN with the `.cdn.` subdomain\r\n */\r\n public url(location: string): string {\r\n // 1. Use urlPrefix if configured\r\n if (this.options.urlPrefix) {\r\n const prefix = this.options.urlPrefix.replace(/\\/+$/, \"\");\r\n return `${prefix}/${location}`;\r\n }\r\n\r\n // 2. Default Spaces CDN URL\r\n return `https://${this.options.bucket}.${this.options.region}.cdn.digitaloceanspaces.com/${location}`;\r\n }\r\n}\r\n","import {\n ensureDirectoryAsync,\n fileExistsAsync,\n removeDirectoryAsync,\n unlinkAsync,\n} from \"@mongez/fs\";\nimport { ltrim } from \"@mongez/reinforcements\";\nimport crypto from \"crypto\";\nimport { createReadStream, createWriteStream } from \"fs\";\nimport { copyFile, readFile, readdir, rename, stat, writeFile } from \"fs/promises\";\nimport { dirname, join } from \"path\";\nimport type { Readable } from \"stream\";\nimport { pipeline } from \"stream/promises\";\nimport { UploadedFile } from \"../../http\";\nimport { storagePath } from \"../../utils/paths\";\nimport { url } from \"../../utils/urls\";\nimport { storageDriverContext } from \"../context/storage-driver-context\";\nimport type {\n DeleteManyResult,\n ListOptions,\n LocalStorageDriverOptions,\n PutOptions,\n StorageDriverContract,\n StorageDriverType,\n StorageFileData,\n StorageFileInfo,\n TemporaryTokenPayload,\n TemporaryTokenValidation,\n} from \"../types\";\nimport { getMimeType } from \"../utils/mime\";\n\n/**\n * Local filesystem storage driver\n *\n * Stores files on the local filesystem with support for:\n * - File operations (put, get, delete, copy, move)\n * - Stream operations for large files\n * - Batch operations\n * - Signed temporary URLs\n */\nexport class LocalDriver implements StorageDriverContract {\n /**\n * Driver name\n */\n public readonly name: StorageDriverType = \"local\";\n\n /**\n * Root path for storage\n */\n protected root: string;\n\n /**\n * URL prefix for file URLs\n */\n protected urlPrefix: string = \"\";\n\n /**\n * URL prefix for temporary file URLs\n */\n protected temporaryUrlPrefix: string;\n\n /**\n * Secret key for signing temporary URLs\n */\n protected signatureKey?: string;\n\n public constructor(public options: LocalStorageDriverOptions = {}) {\n this.root = options.root || storagePath();\n if (options.urlPrefix) {\n this.urlPrefix = options.urlPrefix;\n }\n\n this.temporaryUrlPrefix = options.temporaryUrlPrefix || \"/temp-files\";\n this.signatureKey = options.signatureKey;\n }\n\n // ============================================================\n // Prefix Operations\n // ============================================================\n\n /**\n * Apply prefix to location path\n *\n * Priority: context prefix > driver options prefix > no prefix\n * This allows multi-tenant scenarios where context overrides driver config.\n *\n * @param location - Original location path\n * @returns Location with prefix applied if one exists\n */\n public applyPrefix(location: string): string {\n // Check context prefix first (highest priority)\n const contextPrefix = storageDriverContext.getPrefix();\n const prefix = contextPrefix || this.options.prefix;\n\n if (!prefix) {\n return location;\n }\n\n const cleanPrefix = prefix.replace(/\\/+$/, \"\");\n const cleanLocation = location.replace(/^\\/+/, \"\");\n\n // Avoid double-prefixing\n if (cleanLocation.startsWith(cleanPrefix + \"/\") || cleanLocation === cleanPrefix) {\n return cleanLocation;\n }\n\n return `${cleanPrefix}/${cleanLocation}`;\n }\n\n // ============================================================\n // Core File Operations\n // ============================================================\n\n /**\n * Put file to local storage\n */\n public async put(\n file: Buffer | string | UploadedFile,\n location: string,\n options?: PutOptions,\n ): Promise<StorageFileData> {\n const absolutePath = this.getAbsolutePath(location);\n\n await ensureDirectoryAsync(dirname(absolutePath));\n\n const fileBuffer = await this.toBuffer(file);\n const hash = this.calculateHash(fileBuffer);\n\n await writeFile(absolutePath, new Uint8Array(fileBuffer));\n\n const stats = await stat(absolutePath);\n const mimeType = options?.mimeType || this.guessMimeType(location);\n\n return {\n path: location,\n url: this.url(location),\n size: stats.size,\n hash,\n mimeType,\n driver: this.name,\n };\n }\n\n /**\n * Put file from a readable stream (for large files)\n */\n public async putStream(\n stream: Readable,\n location: string,\n options?: PutOptions,\n ): Promise<StorageFileData> {\n const absolutePath = this.getAbsolutePath(location);\n\n await ensureDirectoryAsync(dirname(absolutePath));\n\n // Create write stream and pipe\n const writeStream = createWriteStream(absolutePath);\n await pipeline(stream, writeStream);\n\n // Calculate hash and get stats\n const fileBuffer = await readFile(absolutePath);\n const hash = this.calculateHash(fileBuffer);\n const stats = await stat(absolutePath);\n const mimeType = options?.mimeType || this.guessMimeType(location);\n\n return {\n path: location,\n url: this.url(location),\n size: stats.size,\n hash,\n mimeType,\n driver: this.name,\n };\n }\n\n /**\n * Get file contents as Buffer\n */\n public async get(location: string): Promise<Buffer> {\n const absolutePath = this.getAbsolutePath(location);\n\n if (!(await fileExistsAsync(absolutePath))) {\n throw new Error(`File not found: ${location}`);\n }\n\n return readFile(absolutePath);\n }\n\n /**\n * Get file as a readable stream (for large files)\n */\n public async getStream(location: string): Promise<Readable> {\n const absolutePath = this.getAbsolutePath(location);\n\n if (!(await fileExistsAsync(absolutePath))) {\n throw new Error(`File not found: ${location}`);\n }\n\n return createReadStream(absolutePath);\n }\n\n /**\n * Delete a file\n */\n public async delete(location: string): Promise<boolean> {\n const absolutePath = this.getAbsolutePath(location);\n\n if (!(await fileExistsAsync(absolutePath))) {\n return false;\n }\n\n await unlinkAsync(absolutePath);\n return true;\n }\n\n /**\n * Delete multiple files at once\n */\n public async deleteMany(locations: string[]): Promise<DeleteManyResult[]> {\n const results: DeleteManyResult[] = [];\n\n for (const location of locations) {\n try {\n const deleted = await this.delete(location);\n results.push({ location, deleted });\n } catch (error) {\n results.push({\n location,\n deleted: false,\n error: error instanceof Error ? error.message : \"Unknown error\",\n });\n }\n }\n\n return results;\n }\n\n /**\n * Delete directory\n */\n public async deleteDirectory(directoryPath: string) {\n await removeDirectoryAsync(directoryPath);\n\n return true;\n }\n\n /**\n * Check if file exists\n */\n public async exists(location: string): Promise<boolean> {\n const absolutePath = this.getAbsolutePath(location);\n return Boolean(await fileExistsAsync(absolutePath));\n }\n\n // ============================================================\n // URL Operations\n // ============================================================\n\n /**\n * Get public URL for file\n */\n public url(location: string): string {\n return url(this.urlPrefix + \"/\" + ltrim(location, \"/\"));\n }\n\n /**\n * Get a temporary signed URL that expires\n * Returns a clean URL with encoded token: {temporaryUrlPrefix}/{token}\n *\n * @param location - File path\n * @param expiresIn - Seconds until expiration (default: 3600)\n */\n public async temporaryUrl(location: string, expiresIn = 3600): Promise<string> {\n if (!this.signatureKey) {\n throw new Error(\n \"Temporary URLs require a signatureKey in LocalDriver options. \" +\n \"Configure storage.drivers.local.signatureKey in your config.\",\n );\n }\n\n const token = this.encodeTemporaryToken(location, expiresIn);\n return `${this.temporaryUrlPrefix}/${token}`;\n }\n\n /**\n * Encode a temporary token containing path, expiry, and signature\n *\n * @param location - File path\n * @param expiresIn - Seconds until expiration\n */\n public encodeTemporaryToken(location: string, expiresIn: number): string {\n if (!this.signatureKey) {\n throw new Error(\"Temporary tokens require a signatureKey\");\n }\n\n const exp = Math.floor(Date.now() / 1000) + expiresIn;\n const sig = crypto\n .createHmac(\"sha256\", this.signatureKey)\n .update(`${location}:${exp}`)\n .digest(\"hex\");\n\n const payload: TemporaryTokenPayload = { path: location, exp, sig };\n const json = JSON.stringify(payload);\n\n // Use base64url encoding (URL-safe base64)\n return Buffer.from(json).toString(\"base64url\");\n }\n\n /**\n * Validate a temporary URL token\n * Returns a result object with validation status, file info, and convenience methods\n *\n * @param token - The token from the URL\n */\n public async validateTemporaryToken(token: string): Promise<TemporaryTokenValidation> {\n // Check signature key\n if (!this.signatureKey) {\n return { valid: false, error: \"missing_key\" };\n }\n\n // Decode token\n let payload: TemporaryTokenPayload;\n try {\n const json = Buffer.from(token, \"base64url\").toString(\"utf-8\");\n payload = JSON.parse(json);\n } catch {\n return { valid: false, error: \"invalid_token\" };\n }\n\n // Validate payload structure\n if (!payload.path || !payload.exp || !payload.sig) {\n return { valid: false, error: \"invalid_token\" };\n }\n\n // Check expiration\n const now = Math.floor(Date.now() / 1000);\n if (payload.exp < now) {\n return { valid: false, error: \"expired\" };\n }\n\n // Verify signature\n const expectedSig = crypto\n .createHmac(\"sha256\", this.signatureKey)\n .update(`${payload.path}:${payload.exp}`)\n .digest(\"hex\");\n\n const sigBuffer = Buffer.from(payload.sig, \"hex\");\n const expectedBuffer = Buffer.from(expectedSig, \"hex\");\n\n if (sigBuffer.length !== expectedBuffer.length) {\n return { valid: false, error: \"invalid_signature\" };\n }\n\n const isValidSig = crypto.timingSafeEqual(\n new Uint8Array(sigBuffer),\n new Uint8Array(expectedBuffer),\n );\n\n if (!isValidSig) {\n return { valid: false, error: \"invalid_signature\" };\n }\n\n // Check file exists\n const absolutePath = this.getAbsolutePath(payload.path);\n if (!(await fileExistsAsync(absolutePath))) {\n return { valid: false, error: \"file_not_found\" };\n }\n\n // Build successful result with convenience methods\n const result: TemporaryTokenValidation = {\n valid: true,\n path: payload.path,\n absolutePath,\n expiresAt: new Date(payload.exp * 1000),\n mimeType: this.guessMimeType(payload.path),\n driver: this,\n getFile: () => this.get(payload.path),\n getStream: () => this.getStream(payload.path),\n };\n\n return result;\n }\n\n // ============================================================\n // Metadata Operations\n // ============================================================\n\n /**\n * Get file info/metadata without downloading\n */\n public async getInfo(location: string): Promise<StorageFileInfo> {\n const absolutePath = this.getAbsolutePath(location);\n\n if (!(await fileExistsAsync(absolutePath))) {\n throw new Error(`File not found: ${location}`);\n }\n\n const stats = await stat(absolutePath);\n const name = location.split(\"/\").pop() || \"\";\n\n return {\n path: location,\n name,\n size: stats.size,\n isDirectory: stats.isDirectory(),\n lastModified: stats.mtime,\n mimeType: this.guessMimeType(location),\n };\n }\n\n /**\n * Get file size in bytes (shortcut for getInfo().size)\n */\n public async size(location: string): Promise<number> {\n const absolutePath = this.getAbsolutePath(location);\n\n if (!(await fileExistsAsync(absolutePath))) {\n throw new Error(`File not found: ${location}`);\n }\n\n const stats = await stat(absolutePath);\n return stats.size;\n }\n\n // ============================================================\n // File Operations\n // ============================================================\n\n /**\n * Copy file to a new location\n */\n public async copy(from: string, to: string): Promise<StorageFileData> {\n const fromPath = this.getAbsolutePath(from);\n const toPath = this.getAbsolutePath(to);\n\n if (!(await fileExistsAsync(fromPath))) {\n throw new Error(`Source file not found: ${from}`);\n }\n\n await ensureDirectoryAsync(dirname(toPath));\n await copyFile(fromPath, toPath);\n\n const fileBuffer = await readFile(toPath);\n const hash = this.calculateHash(fileBuffer);\n const stats = await stat(toPath);\n\n return {\n path: to,\n url: this.url(to),\n size: stats.size,\n hash,\n mimeType: this.guessMimeType(to),\n driver: this.name,\n };\n }\n\n /**\n * Move file to a new location\n */\n public async move(from: string, to: string): Promise<StorageFileData> {\n const fromPath = this.getAbsolutePath(from);\n const toPath = this.getAbsolutePath(to);\n\n if (!(await fileExistsAsync(fromPath))) {\n throw new Error(`Source file not found: ${from}`);\n }\n\n await ensureDirectoryAsync(dirname(toPath));\n await rename(fromPath, toPath);\n\n const fileBuffer = await readFile(toPath);\n const hash = this.calculateHash(fileBuffer);\n const stats = await stat(toPath);\n\n return {\n path: to,\n url: this.url(to),\n size: stats.size,\n hash,\n mimeType: this.guessMimeType(to),\n driver: this.name,\n };\n }\n\n /**\n * List files in a directory\n */\n public async list(directory: string, options?: ListOptions): Promise<StorageFileInfo[]> {\n const absolutePath = this.getAbsolutePath(directory);\n const files: StorageFileInfo[] = [];\n\n if (!(await fileExistsAsync(absolutePath))) {\n return files;\n }\n\n const entries = await readdir(absolutePath, { withFileTypes: true });\n\n for (const entry of entries) {\n const entryPath = join(directory, entry.name);\n const entryStats = await stat(this.getAbsolutePath(entryPath));\n\n files.push({\n path: entryPath,\n name: entry.name,\n size: entryStats.size,\n isDirectory: entry.isDirectory(),\n lastModified: entryStats.mtime,\n mimeType: entry.isFile() ? this.guessMimeType(entry.name) : undefined,\n });\n\n // Recursively list subdirectories if requested\n if (options?.recursive && entry.isDirectory()) {\n const subFiles = await this.list(entryPath, options);\n files.push(...subFiles);\n }\n\n // Respect limit\n if (options?.limit && files.length >= options.limit) {\n break;\n }\n }\n\n return files;\n }\n\n // ============================================================\n // Path Operations\n // ============================================================\n\n /**\n * Get absolute filesystem path for a location\n */\n public path(location: string): string {\n return this.getAbsolutePath(location);\n }\n\n /**\n * Get the storage root directory\n */\n public getRoot(): string {\n return this.root;\n }\n\n // ============================================================\n // Utilities\n // ============================================================\n\n /**\n * Get absolute file path\n */\n protected getAbsolutePath(location: string): string {\n const prefixedLocation = this.applyPrefix(location);\n return join(this.root, prefixedLocation);\n }\n\n /**\n * Convert various input types to Buffer\n */\n protected async toBuffer(file: Buffer | string | UploadedFile): Promise<Buffer> {\n if (Buffer.isBuffer(file)) {\n return file;\n }\n\n if (typeof file === \"string\") {\n return readFile(file);\n }\n\n return file.buffer();\n }\n\n /**\n * Calculate SHA-256 hash\n */\n protected calculateHash(buffer: Buffer): string {\n return crypto.createHash(\"sha256\").update(new Uint8Array(buffer)).digest(\"hex\");\n }\n\n /**\n * Guess MIME type from file extension\n */\n protected guessMimeType(location: string): string {\n return getMimeType(location);\n }\n}\n","import type { R2StorageDriverOptions } from \"../types\";\r\nimport { CloudDriver } from \"./cloud-driver\";\r\n\r\n/**\r\n * Cloudflare R2 Storage Driver\r\n *\r\n * R2 is S3-compatible but uses a different URL structure and doesn't require regions.\r\n *\r\n * URL Patterns:\r\n * - With publicDomain: https://{publicDomain}/{key}\r\n * - With urlPrefix: {urlPrefix}/{key}\r\n * - Default public bucket: https://pub-{accountId}.r2.dev/{key}\r\n *\r\n * @example\r\n * ```typescript\r\n * const driver = new R2Driver({\r\n * bucket: \"my-bucket\",\r\n * region: \"auto\", // R2 doesn't use traditional regions\r\n * accessKeyId: process.env.R2_ACCESS_KEY_ID,\r\n * secretAccessKey: process.env.R2_SECRET_ACCESS_KEY,\r\n * accountId: process.env.R2_ACCOUNT_ID,\r\n * publicDomain: \"assets.example.com\", // Optional custom domain\r\n * });\r\n * ```\r\n */\r\nexport class R2Driver extends CloudDriver<R2StorageDriverOptions> {\r\n /**\r\n * Driver name\r\n */\r\n public readonly name = \"r2\";\r\n\r\n /**\r\n * Get R2 endpoint URL\r\n *\r\n * R2 endpoint format: https://{accountId}.r2.cloudflarestorage.com\r\n */\r\n protected getEndpoint(): string {\r\n return this.options.endpoint || `https://${this.options.accountId}.r2.cloudflarestorage.com`;\r\n }\r\n\r\n /**\r\n * Get public URL for file\r\n *\r\n * Priority: urlPrefix > publicDomain > default R2 URL\r\n *\r\n * Note: For R2 public access, you typically need to:\r\n * - Enable public access on the bucket\r\n * - Or use a custom domain through Cloudflare\r\n */\r\n public url(location: string): string {\r\n // 1. Use urlPrefix if configured\r\n if (this.options.urlPrefix) {\r\n const prefix = this.options.urlPrefix.replace(/\\/+$/, \"\");\r\n return `${prefix}/${location}`;\r\n }\r\n\r\n // 2. Use publicDomain if configured\r\n if (this.options.publicDomain) {\r\n const domain = this.options.publicDomain.replace(/\\/+$/, \"\");\r\n return `${domain}/${location}`;\r\n }\r\n\r\n // 3. Fallback to R2 public bucket URL\r\n // Note: Public access must be enabled on the bucket for this to work\r\n return `https://pub-${this.options.accountId}.r2.dev/${location}`;\r\n }\r\n}\r\n","import type { CloudStorageDriverOptions } from \"../types\";\r\nimport { CloudDriver } from \"./cloud-driver\";\r\n\r\n/**\r\n * AWS S3 Storage Driver\r\n *\r\n * URL Pattern: https://{bucket}.s3.{region}.amazonaws.com/{key}\r\n *\r\n * @example\r\n * ```typescript\r\n * const driver = new S3Driver({\r\n * bucket: \"my-bucket\",\r\n * region: \"us-east-1\",\r\n * accessKeyId: process.env.AWS_ACCESS_KEY_ID,\r\n * secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,\r\n * });\r\n * ```\r\n */\r\nexport class S3Driver extends CloudDriver<CloudStorageDriverOptions> {\r\n /**\r\n * Driver name\r\n */\r\n public readonly name = \"s3\";\r\n\r\n /**\r\n * Get public URL for file\r\n *\r\n * URL formats:\r\n * - With urlPrefix: {urlPrefix}/{key}\r\n * - Default: https://{bucket}.s3.{region}.amazonaws.com/{key}\r\n */\r\n public url(location: string): string {\r\n // 1. Use urlPrefix if configured\r\n if (this.options.urlPrefix) {\r\n const prefix = this.options.urlPrefix.replace(/\\/+$/, \"\");\r\n return `${prefix}/${location}`;\r\n }\r\n\r\n // 2. Default S3 URL\r\n return `https://${this.options.bucket}.s3.${this.options.region}.amazonaws.com/${location}`;\r\n }\r\n}\r\n","import events, { type EventSubscription } from \"@mongez/events\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport type { Readable } from \"stream\";\nimport type { UploadedFile } from \"../http\";\nimport { storageConfig } from \"./config\";\nimport { storageDriverContext } from \"./context/storage-driver-context\";\nimport { DOSpacesDriver } from \"./drivers/do-spaces-driver\";\nimport { LocalDriver } from \"./drivers/local-driver\";\nimport { R2Driver } from \"./drivers/r2-driver\";\nimport { S3Driver } from \"./drivers/s3-driver\";\nimport { ScopedStorage } from \"./scoped-storage\";\nimport { StorageFile } from \"./storage-file\";\nimport type {\n CloudStorageDriverContract,\n CloudStorageDriverOptions,\n DeleteManyResult,\n FileVisibility,\n ListOptions,\n LocalStorageDriverOptions,\n PresignedOptions,\n PresignedUploadOptions,\n PutOptions,\n R2StorageDriverOptions,\n StorageCopyEventPayload,\n StorageDriverConfig,\n StorageDriverContract,\n StorageDriverName,\n StorageEventHandler,\n StorageEventPayload,\n StorageEventType,\n StorageFileInfo,\n StorageManagerContract,\n StoragePutEventPayload,\n TemporaryTokenValidation,\n} from \"./types\";\n\n/**\n * Storage Manager\n *\n * Provides a unified interface for file storage operations across multiple\n * drivers (local, S3, R2, DigitalOcean Spaces). Extends `ScopedStorage` to\n * inherit all base operations while adding driver management and events.\n *\n * All operations return `StorageFile` instances for a consistent, rich DX.\n *\n * @example\n * ```typescript\n * // Basic usage (uses default driver)\n * const file = await storage.put(buffer, \"uploads/image.jpg\");\n *\n * // With options\n * const file = await storage.put(buffer, \"uploads/image.jpg\", {\n * mimeType: \"image/jpeg\",\n * cacheControl: \"max-age=31536000\"\n * });\n *\n * // Using specific driver (also returns StorageFile)\n * const file = await storage.use(\"s3\").put(buffer, \"path/to/file\");\n *\n * // Get raw driver for advanced use\n * const driver = storage.driver(\"s3\");\n * const data = await driver.put(buffer, \"path/to/file\"); // Returns StorageFileData\n *\n * // Stream operations for large files\n * const stream = await storage.getStream(\"large-file.zip\");\n * await storage.putStream(readableStream, \"output/file.zip\");\n *\n * // Batch operations\n * const results = await storage.deleteMany([\"file1.txt\", \"file2.txt\"]);\n *\n * // Event hooks\n * storage.on(\"afterPut\", ({ location, file }) => {\n * console.log(`Uploaded ${location}`);\n * });\n * ```\n */\nexport class Storage extends ScopedStorage implements StorageManagerContract {\n /**\n * Registered drivers (cached instances)\n * @internal\n */\n protected drivers = new Map<string, StorageDriverContract>();\n\n /**\n * Driver configurations\n * @internal\n */\n protected configs = new Map<string, StorageDriverConfig>();\n\n /**\n * Default driver name\n * @internal\n */\n protected defaultDriverName!: StorageDriverName;\n\n /**\n * Whether the storage has been initialized\n * @internal\n */\n private initialized = false;\n\n /**\n * Create a new Storage manager instance\n *\n * Uses lazy initialization - driver is resolved on first access.\n */\n public constructor() {\n // Temp placeholder - will be replaced on first access\n super(null as unknown as StorageDriverContract);\n }\n\n /**\n * Ensure storage is initialized (lazy initialization)\n *\n * Called automatically on first driver access.\n */\n public async init(): Promise<void> {\n if (this.initialized) return;\n\n // Mark as initialized FIRST to prevent infinite recursion\n this.initialized = true;\n\n // Get default driver name from config\n\n const defaultName = storageConfig(\"default\", \"local\");\n\n this.defaultDriverName = defaultName as StorageDriverName;\n this.loadDriversFromConfig();\n\n // Now set the actual driver\n this._driver = this.resolveDriver(this.defaultDriverName);\n }\n\n /**\n * Reset storage defaults\n */\n public reset(): void {\n this.initialized = false;\n this.drivers.clear();\n this.configs.clear();\n this.defaultDriverName = null as unknown as StorageDriverName;\n this._driver = null as unknown as StorageDriverContract;\n }\n\n /**\n * Get the currently active driver (context-aware in future)\n *\n * Currently returns the default driver.\n * Will be enhanced to check AsyncLocalStorage context for multi-tenant support.\n *\n * @returns The active storage driver\n */\n public override get activeDriver(): StorageDriverContract {\n // Check context for tenant-specific driver\n const contextDriver = storageDriverContext.getDriver();\n\n if (contextDriver) return contextDriver;\n\n return this._driver;\n }\n\n // ============================================================\n // Driver Management\n // ============================================================\n\n /**\n * Load drivers from configuration\n * @internal\n */\n protected loadDriversFromConfig(): void {\n const drivers = storageConfig<Record<string, StorageDriverConfig>>(\"drivers\", {});\n\n for (const [name, config] of Object.entries(drivers)) {\n this.configs.set(name, config);\n }\n }\n\n /**\n * Get a scoped storage for a specific driver\n *\n * Returns a `ScopedStorage` instance that wraps the specified driver.\n * Operations on the returned instance also return `StorageFile` objects.\n *\n * @param name - Driver name as defined in configuration\n * @returns ScopedStorage instance for the specified driver\n *\n * @example\n * ```typescript\n * // Upload to S3\n * const s3File = await storage.use(\"s3\").put(buffer, \"images/photo.jpg\");\n *\n * // Upload to local\n * const localFile = await storage.use(\"local\").put(buffer, \"temp/file.txt\");\n *\n * // Both return StorageFile with identical API\n * console.log(s3File.url);\n * console.log(localFile.url);\n * ```\n */\n public use(name: StorageDriverName): ScopedStorage {\n return new ScopedStorage(this.getDriver(name));\n }\n\n /**\n * Get a raw driver instance\n *\n * Returns the underlying driver directly for advanced use cases.\n * Unlike `use()`, calling methods on the raw driver returns\n * `StorageFileData` instead of `StorageFile`.\n *\n * @param name - Driver name as defined in configuration\n * @returns Raw driver instance implementing StorageDriverContract\n *\n * @example\n * ```typescript\n * const driver = storage.getDriver(\"s3\");\n * const data = await driver.put(buffer, \"path/to/file\");\n * // data is StorageFileData, not StorageFile\n * ```\n */\n public getDriver(name: StorageDriverName): StorageDriverContract {\n return this.resolveDriver(name);\n }\n\n /**\n * Get root directory of current driver\n */\n public root(apepndedPath?: string): string {\n const rootPath = this.activeDriver.options?.root || \"\";\n\n return path.join(rootPath, apepndedPath || \"\");\n }\n\n /**\n * Use a cloud storage driver with extended cloud capabilities\n *\n * @param name - Cloud driver name (s3, r2, spaces)\n * @returns Driver instance implementing CloudStorageDriverContract\n * @throws Error if driver doesn't support cloud operations\n *\n * @example\n * ```typescript\n * const cloudDriver = storage.useCloud(\"s3\");\n * const presignedUrl = await cloudDriver.getPresignedUrl(\"private/doc.pdf\");\n * ```\n */\n public useCloud(name: StorageDriverName): CloudStorageDriverContract {\n const instance = this.getDriver(name);\n\n if (!this.isCloudDriver(instance)) {\n throw new Error(`Driver \"${name}\" does not support cloud operations`);\n }\n\n return instance as CloudStorageDriverContract;\n }\n\n /**\n * Register a new driver configuration at runtime\n *\n * Allows dynamic driver registration for multi-tenancy or\n * runtime configuration scenarios.\n *\n * @param name - Unique driver name\n * @param config - Driver configuration\n * @returns This instance for chaining\n *\n * @example\n * ```typescript\n * storage.register(\"tenant-s3\", {\n * driver: \"s3\",\n * bucket: \"tenant-bucket\",\n * region: \"us-east-1\",\n * accessKeyId: process.env.TENANT_AWS_KEY,\n * secretAccessKey: process.env.TENANT_AWS_SECRET\n * });\n *\n * await storage.use(\"tenant-s3\").put(buffer, \"file.txt\");\n * ```\n */\n public register(name: StorageDriverName, config: StorageDriverConfig): this {\n this.configs.set(name, config);\n this.drivers.delete(name); // Clear cached instance\n return this;\n }\n\n /**\n * Set the default driver name\n *\n * @param name - Driver name to use as default\n * @returns This instance for chaining\n *\n * @example\n * ```typescript\n * storage.setDefault(\"s3\");\n * await storage.put(buffer, \"file.txt\"); // Now uses S3\n * ```\n */\n public setDefault(name: StorageDriverName): this {\n this.defaultDriverName = name;\n this._driver = this.getDriver(name);\n return this;\n }\n\n /**\n * Check if current driver is a cloud driver\n *\n * @returns Promise resolving to true if the current driver supports cloud operations\n */\n public async isCloud(): Promise<boolean> {\n return this.isCloudDriver(this.activeDriver);\n }\n\n /**\n * Check if a driver instance supports cloud operations\n * @internal\n */\n protected isCloudDriver(driver: StorageDriverContract): driver is CloudStorageDriverContract {\n return \"getPresignedUrl\" in driver;\n }\n\n // ============================================================\n // Event System\n // ============================================================\n\n /**\n * Register an event handler\n *\n * Subscribe to storage events for logging, analytics, or side effects.\n *\n * @param event - Event type to listen for\n * @param handler - Handler function\n * @returns Event subscription for unsubscribing\n *\n * @example\n * ```typescript\n * // Log all uploads\n * storage.on(\"afterPut\", ({ location, file }) => {\n * console.log(`Uploaded ${file?.size} bytes to ${location}`);\n * });\n *\n * // Track deletions\n * storage.on(\"afterDelete\", ({ location }) => {\n * analytics.track(\"file_deleted\", { path: location });\n * });\n * ```\n */\n public on<T extends StorageEventPayload = StorageEventPayload>(\n event: StorageEventType,\n handler: StorageEventHandler<T>,\n ): EventSubscription {\n return events.subscribe(`storage.${event}`, handler);\n }\n\n /**\n * Remove all handlers for an event type\n *\n * @param event - Event type to remove handlers for\n * @returns This instance for chaining\n *\n * @example\n * ```typescript\n * storage.off(\"afterPut\"); // Remove all afterPut handlers\n * ```\n */\n public off(event: StorageEventType): this {\n events.off(`storage.${event}`);\n return this;\n }\n\n /**\n * Emit an event to all registered handlers\n * @internal\n */\n protected async emit<T extends StorageEventPayload>(\n event: StorageEventType,\n payload: T,\n ): Promise<void> {\n await events.triggerAll(`storage.${event}`, payload);\n }\n\n // ============================================================\n // Overridden Operations with Events\n // ============================================================\n\n /**\n * Store a file in storage\n *\n * Extends base `put()` with event emission for beforePut/afterPut hooks.\n *\n * @param file - File content as Buffer, string, UploadedFile, or Readable stream\n * @param location - Destination path\n * @param options - Storage options (mimeType, cacheControl, etc.)\n * @returns StorageFile instance with cached metadata\n */\n public override async put(\n file: UploadedFile | Buffer | string | Readable,\n location: string,\n options?: PutOptions,\n ): Promise<StorageFile> {\n const driver = this.activeDriver;\n const buffer = await this.toBuffer(file);\n\n await this.emit<StoragePutEventPayload>(\"beforePut\", {\n driver: driver.name,\n location,\n timestamp: new Date(),\n size: buffer.length,\n });\n\n const result = await driver.put(buffer, location, options);\n\n await this.emit<StoragePutEventPayload>(\"afterPut\", {\n driver: driver.name,\n location,\n timestamp: new Date(),\n file: result,\n });\n\n return StorageFile.fromData(result, driver);\n }\n\n /**\n * Store a file from a readable stream (for large files)\n *\n * Extends base `putStream()` with event emission.\n *\n * @param stream - Readable stream\n * @param location - Destination path\n * @param options - Storage options\n * @returns StorageFile instance with cached metadata\n */\n public override async putStream(\n stream: Readable | string,\n location: string,\n options?: PutOptions,\n ): Promise<StorageFile> {\n const driver = this.activeDriver;\n\n await this.emit<StoragePutEventPayload>(\"beforePut\", {\n driver: driver.name,\n location,\n timestamp: new Date(),\n });\n\n if (typeof stream === \"string\") {\n stream = fs.createReadStream(stream);\n }\n\n const result = await driver.putStream(stream, location, options);\n\n await this.emit<StoragePutEventPayload>(\"afterPut\", {\n driver: driver.name,\n location,\n timestamp: new Date(),\n file: result,\n });\n\n return StorageFile.fromData(result, driver);\n }\n\n /**\n * Store a file from a URL\n *\n * Downloads content from the URL and stores it at the specified location.\n *\n * @param url - Source URL to download from\n * @param location - Destination path\n * @param options - Storage options\n * @returns StorageFile instance with cached metadata\n *\n * @example\n * ```typescript\n * const file = await storage.putFromUrl(\n * \"https://example.com/image.jpg\",\n * \"downloads/image.jpg\"\n * );\n * ```\n */\n public async putFromUrl(\n url: string,\n location: string,\n options?: PutOptions,\n ): Promise<StorageFile> {\n const response = await fetch(url);\n\n if (!response.ok) {\n throw new Error(`Failed to fetch file from URL: ${response.statusText}`);\n }\n\n const arrayBuffer = await response.arrayBuffer();\n const buffer = Buffer.from(arrayBuffer);\n const mimeType = options?.mimeType || response.headers.get(\"content-type\") || undefined;\n\n return this.put(buffer, location, { ...options, mimeType });\n }\n\n /**\n * Store a file from base64 encoded string\n *\n * Decodes base64 content (with optional data URL prefix) and stores it.\n *\n * @param base64 - Base64 encoded file content (or data URL)\n * @param location - Destination path\n * @param options - Storage options\n * @returns StorageFile instance with cached metadata\n *\n * @example\n * ```typescript\n * // From plain base64\n * const file = await storage.putFromBase64(base64String, \"images/photo.jpg\");\n *\n * // From data URL (auto-extracts MIME type)\n * const file = await storage.putFromBase64(\n * \"data:image/png;base64,iVBORw0KGgo...\",\n * \"images/photo.png\"\n * );\n * ```\n */\n public async putFromBase64(\n base64: string,\n location: string,\n options?: PutOptions,\n ): Promise<StorageFile> {\n let data = base64;\n let mimeType = options?.mimeType;\n\n if (base64.startsWith(\"data:\")) {\n const match = base64.match(/^data:([^;]+);base64,(.+)$/);\n if (match) {\n mimeType = mimeType || match[1];\n data = match[2];\n }\n }\n\n const buffer = Buffer.from(data, \"base64\");\n return this.put(buffer, location, { ...options, mimeType });\n }\n\n /**\n * Retrieve file contents as Buffer\n *\n * Uses the current driver (with async resolution).\n *\n * @param location - File path\n * @returns Buffer containing file contents\n */\n public override async get(location: string): Promise<Buffer> {\n return this.activeDriver.get(location);\n }\n\n /**\n * Get JSON content from a file\n *\n * Downloads and parses JSON file content.\n *\n * @param location - File path\n * @returns Parsed JSON content\n *\n * @example\n * ```typescript\n * const config = await storage.getJson(\"config/settings.json\");\n * console.log(config.apiKey);\n * ```\n */\n public async getJson(location: string): Promise<any> {\n const buffer = await this.get(location);\n return JSON.parse(buffer.toString());\n }\n\n /**\n * Retrieve a file as a readable stream (for large files)\n *\n * @param location - File path\n * @returns Readable stream of file contents\n */\n public override async getStream(location: string): Promise<Readable> {\n return this.activeDriver.getStream(location);\n }\n\n /**\n * Delete a file\n *\n * Extends base `delete()` with event emission.\n *\n * @param location - File path or StorageFile\n * @returns true if deleted, false if not found\n */\n public override async delete(location: string | StorageFile): Promise<boolean> {\n const driver = this.activeDriver;\n const path = typeof location === \"string\" ? location : location.path;\n\n await this.emit<StorageEventPayload>(\"beforeDelete\", {\n driver: driver.name,\n location: path,\n timestamp: new Date(),\n });\n\n const result = await driver.delete(path);\n\n await this.emit<StorageEventPayload>(\"afterDelete\", {\n driver: driver.name,\n location: path,\n timestamp: new Date(),\n });\n\n return result;\n }\n\n /**\n * Delete multiple files at once\n *\n * @param locations - Array of file paths\n * @returns Array of delete results with status for each file\n */\n public override async deleteMany(locations: string[]): Promise<DeleteManyResult[]> {\n return this.activeDriver.deleteMany(locations);\n }\n\n /**\n * Check if a file exists\n *\n * @param location - File path\n * @returns true if file exists\n */\n public override async exists(location: string): Promise<boolean> {\n return this.activeDriver.exists(location);\n }\n\n /**\n * Copy a file to a new location\n *\n * Extends base `copy()` with event emission.\n *\n * @param from - Source path or StorageFile\n * @param to - Destination path\n * @returns StorageFile instance at destination\n */\n public override async copy(from: string | StorageFile, to: string): Promise<StorageFile> {\n const driver = this.activeDriver;\n const fromPath = typeof from === \"string\" ? from : from.path;\n\n await this.emit<StorageCopyEventPayload>(\"beforeCopy\", {\n driver: driver.name,\n location: to,\n from: fromPath,\n to,\n timestamp: new Date(),\n });\n\n const result = await driver.copy(fromPath, to);\n\n await this.emit<StorageCopyEventPayload>(\"afterCopy\", {\n driver: driver.name,\n location: to,\n from: fromPath,\n to,\n timestamp: new Date(),\n file: result,\n });\n\n return StorageFile.fromData(result, driver);\n }\n\n /**\n * Move a file to a new location\n *\n * Extends base `move()` with event emission.\n *\n * @param from - Source path or StorageFile\n * @param to - Destination path\n * @returns StorageFile instance at destination\n */\n public override async move(from: string | StorageFile, to: string): Promise<StorageFile> {\n const driver = this.activeDriver;\n const fromPath = typeof from === \"string\" ? from : from.path;\n\n await this.emit<StorageCopyEventPayload>(\"beforeMove\", {\n driver: driver.name,\n location: to,\n from: fromPath,\n to,\n timestamp: new Date(),\n });\n\n const result = await driver.move(fromPath, to);\n\n await this.emit<StorageCopyEventPayload>(\"afterMove\", {\n driver: driver.name,\n location: to,\n from: fromPath,\n to,\n timestamp: new Date(),\n file: result,\n });\n\n return StorageFile.fromData(result, driver);\n }\n\n /**\n * List files in a directory\n *\n * @param directory - Directory path (defaults to root)\n * @param options - List options (recursive, limit, etc.)\n * @returns Array of file information objects\n */\n public override async list(\n directory?: string,\n options?: ListOptions,\n ): Promise<StorageFileInfo[]> {\n return this.activeDriver.list(directory || \"\", options);\n }\n\n // ============================================================\n // Metadata Operations\n // ============================================================\n\n /**\n * Get file metadata without downloading\n *\n * @param location - File path\n * @returns File information object\n */\n public override async getInfo(location: string): Promise<StorageFileInfo> {\n return this.activeDriver.getInfo(location);\n }\n\n /**\n * Get file size in bytes\n *\n * @param location - File path\n * @returns File size in bytes\n */\n public override async size(location: string): Promise<number> {\n return this.activeDriver.size(location);\n }\n\n /**\n * Get a StorageFile instance for OOP-style operations\n *\n * @param location - File path\n * @returns StorageFile instance\n */\n public override async file(location: string): Promise<StorageFile> {\n return new StorageFile(location, this.activeDriver);\n }\n\n // ============================================================\n // Path Operations (Local Driver Only)\n // ============================================================\n\n /**\n * Get the absolute filesystem path for a location\n *\n * Only available for local driver.\n *\n * @param location - File path\n * @throws Error if current driver is not a local driver\n * @returns Absolute filesystem path\n */\n public async path(location: string): Promise<string> {\n const driver = this.activeDriver;\n\n if (!(\"path\" in driver) || typeof driver.path !== \"function\") {\n throw new Error(\"path() is only available for local storage drivers\");\n }\n\n return driver.path(location);\n }\n\n // ============================================================\n // Cloud-Specific Operations\n // ============================================================\n\n /**\n * Get a presigned URL for downloading a file\n *\n * Only available for cloud drivers.\n *\n * @param location - File path\n * @param options - Presigned URL options (expiresIn)\n * @throws Error if current driver is not a cloud driver\n * @returns Presigned download URL\n *\n * @example\n * ```typescript\n * const url = await storage.getPresignedUrl(\"private/document.pdf\", {\n * expiresIn: 3600 // 1 hour\n * });\n * ```\n */\n public async getPresignedUrl(location: string, options?: PresignedOptions): Promise<string> {\n const driver = this.activeDriver;\n\n if (!this.isCloudDriver(driver)) {\n throw new Error(\"Presigned URLs are only available for cloud storage drivers\");\n }\n\n return driver.getPresignedUrl(location, options);\n }\n\n /**\n * Get a presigned URL for uploading a file directly to cloud storage\n *\n * Only available for cloud drivers.\n *\n * @param location - Destination path\n * @param options - Upload options (expiresIn, contentType, maxSize)\n * @throws Error if current driver is not a cloud driver\n * @returns Presigned upload URL\n *\n * @example\n * ```typescript\n * const uploadUrl = await storage.getPresignedUploadUrl(\"uploads/file.pdf\", {\n * expiresIn: 3600,\n * contentType: \"application/pdf\"\n * });\n *\n * // Client can PUT directly to this URL\n * ```\n */\n public async getPresignedUploadUrl(\n location: string,\n options?: PresignedUploadOptions,\n ): Promise<string> {\n const driver = this.activeDriver;\n\n if (!this.isCloudDriver(driver)) {\n throw new Error(\"Presigned upload URLs are only available for cloud storage drivers\");\n }\n\n return driver.getPresignedUploadUrl(location, options);\n }\n\n /**\n * Get the bucket name for cloud storage\n *\n * Only available for cloud drivers.\n *\n * @throws Error if current driver is not a cloud driver\n * @returns Bucket name\n */\n public async getBucket(): Promise<string> {\n const driver = this.activeDriver;\n\n if (!this.isCloudDriver(driver)) {\n throw new Error(\"Bucket information is only available for cloud storage drivers\");\n }\n\n return driver.getBucket();\n }\n\n /**\n * Get the region for cloud storage\n *\n * Only available for cloud drivers.\n *\n * @throws Error if current driver is not a cloud driver\n * @returns Region name\n */\n public async getRegion(): Promise<string> {\n const driver = this.activeDriver;\n\n if (!this.isCloudDriver(driver)) {\n throw new Error(\"Region information is only available for cloud storage drivers\");\n }\n\n return driver.getRegion();\n }\n\n /**\n * Set storage class for a file (e.g., STANDARD, GLACIER, etc.)\n *\n * Only available for cloud drivers.\n *\n * @param location - File path\n * @param storageClass - Target storage class\n * @throws Error if current driver is not a cloud driver\n */\n public async setStorageClass(location: string, storageClass: string): Promise<void> {\n const driver = this.activeDriver;\n\n if (!this.isCloudDriver(driver)) {\n throw new Error(\"Storage class is only available for cloud storage drivers\");\n }\n\n return driver.setStorageClass(location, storageClass);\n }\n\n /**\n * Set file visibility (public or private)\n *\n * Only available for cloud drivers.\n *\n * @param location - File path\n * @param visibility - \"public\" or \"private\"\n * @throws Error if current driver is not a cloud driver\n */\n public async setVisibility(location: string, visibility: FileVisibility): Promise<void> {\n const driver = this.activeDriver;\n\n if (!this.isCloudDriver(driver)) {\n throw new Error(\"Visibility is only available for cloud storage drivers\");\n }\n\n return driver.setVisibility(location, visibility);\n }\n\n /**\n * Get file visibility\n *\n * Only available for cloud drivers.\n *\n * @param location - File path\n * @throws Error if current driver is not a cloud driver\n * @returns Current visibility setting\n */\n public async getVisibility(location: string): Promise<FileVisibility> {\n const driver = this.activeDriver;\n\n if (!this.isCloudDriver(driver)) {\n throw new Error(\"Visibility is only available for cloud storage drivers\");\n }\n\n return driver.getVisibility(location);\n }\n\n /**\n * Get a temporary signed URL\n *\n * Creates a URL that provides temporary access to the file.\n *\n * @param location - File path\n * @param expiresIn - Seconds until expiration (default: 3600)\n * @returns Signed URL string\n */\n public override async temporaryUrl(location: string, expiresIn?: number): Promise<string> {\n return this.activeDriver.temporaryUrl(location, expiresIn);\n }\n\n /**\n * Validate a temporary URL token\n *\n * For local driver: validates HMAC-signed tokens\n * For cloud drivers: returns invalid (cloud validates via presigned URL)\n *\n * @param token - The token from the temporary URL\n * @returns Validation result with file info and convenience methods\n *\n * @example\n * ```typescript\n * const result = await storage.validateTemporaryToken(token);\n *\n * if (!result.valid) {\n * return response.status(403).send(result.error);\n * }\n *\n * // For local driver - use sendFile for efficiency\n * if (result.absolutePath) {\n * return response.sendFile(result.absolutePath);\n * }\n *\n * // For cloud driver - stream the file\n * const stream = await result.getStream!();\n * stream.pipe(response.raw);\n * ```\n */\n public async validateTemporaryToken(token: string): Promise<TemporaryTokenValidation> {\n // Check if driver supports token validation\n if (\n !(\"validateTemporaryToken\" in this.activeDriver) ||\n typeof this.activeDriver.validateTemporaryToken !== \"function\"\n ) {\n // For cloud drivers, temporary URLs are presigned and validated by the cloud provider\n return {\n valid: false,\n error: \"invalid_token\",\n };\n }\n\n return this.activeDriver.validateTemporaryToken(token);\n }\n\n // ============================================================\n // Configuration Parsing\n // ============================================================\n\n /**\n * Parse config into driver-specific options\n * @internal\n */\n protected parseOptions(\n config: StorageDriverConfig,\n ): LocalStorageDriverOptions | CloudStorageDriverOptions | R2StorageDriverOptions {\n const { driver, ...options } = config;\n\n switch (driver) {\n case \"local\":\n return {\n root: options.root,\n urlPrefix: options.urlPrefix,\n signatureKey: options.signatureKey,\n } satisfies LocalStorageDriverOptions;\n\n case \"s3\":\n this.validateCloudConfig(config, \"s3\");\n return {\n ...options,\n bucket: options.bucket!,\n region: options.region!,\n accessKeyId: options.accessKeyId!,\n secretAccessKey: options.secretAccessKey!,\n endpoint: options.endpoint,\n urlPrefix: options.urlPrefix,\n } satisfies CloudStorageDriverOptions;\n\n case \"r2\":\n this.validateCloudConfig(config, \"r2\");\n if (!options.accountId) {\n throw new Error('R2 driver requires \"accountId\" configuration');\n }\n\n return {\n ...options,\n region: options.region || \"auto\",\n bucket: options.bucket!,\n accessKeyId: options.accessKeyId!,\n secretAccessKey: options.secretAccessKey!,\n endpoint: options.endpoint,\n urlPrefix: options.urlPrefix,\n accountId: options.accountId,\n publicDomain: options.publicDomain,\n } satisfies R2StorageDriverOptions;\n\n case \"spaces\":\n this.validateCloudConfig(config, \"spaces\");\n return {\n ...options,\n bucket: options.bucket!,\n region: options.region!,\n accessKeyId: options.accessKeyId!,\n secretAccessKey: options.secretAccessKey!,\n endpoint: options.endpoint,\n urlPrefix: options.urlPrefix,\n } satisfies CloudStorageDriverOptions;\n\n default:\n throw new Error(`Unknown driver type: ${driver}`);\n }\n }\n\n /**\n * Validate cloud driver configuration has required fields\n * @internal\n */\n protected validateCloudConfig(config: StorageDriverConfig, driverName: string): void {\n const required = [\"bucket\", \"accessKeyId\", \"secretAccessKey\"];\n\n if (driverName !== \"r2\") {\n required.push(\"region\");\n }\n\n for (const field of required) {\n if (!config[field as keyof StorageDriverConfig]) {\n throw new Error(`${driverName.toUpperCase()} driver requires \"${field}\" configuration`);\n }\n }\n }\n\n /**\n * Get or create driver instance from cache\n * @internal\n */\n protected resolveDriver(name: string): StorageDriverContract {\n // Ensure configs are loaded\n\n if (this.drivers.has(name)) {\n return this.drivers.get(name)!;\n }\n\n const config = this.configs.get(name);\n\n if (!config) {\n throw new Error(`Storage driver \"${name}\" is not configured`);\n }\n\n const options = this.parseOptions(config);\n let driver: StorageDriverContract;\n\n switch (config.driver) {\n case \"local\":\n driver = new LocalDriver(options as LocalStorageDriverOptions);\n break;\n case \"s3\":\n driver = new S3Driver(options as CloudStorageDriverOptions);\n break;\n case \"r2\":\n driver = new R2Driver(options as R2StorageDriverOptions);\n break;\n case \"spaces\":\n driver = new DOSpacesDriver(options as CloudStorageDriverOptions);\n break;\n default:\n throw new Error(`Unknown storage driver type: ${config.driver}`);\n }\n\n this.drivers.set(name, driver);\n return driver;\n }\n\n /**\n * Resolve the default driver name (supports async resolver for multi-tenancy)\n * @internal\n */\n protected async resolveDefaultDriver(): Promise<StorageDriverName> {\n const resolver = storageConfig(\"resolver\");\n\n if (resolver) {\n const resolved = await resolver();\n return resolved || this.defaultDriverName;\n }\n\n return this.defaultDriverName;\n }\n}\n\n/**\n * Singleton storage instance\n *\n * Pre-configured storage manager ready for use throughout the application.\n *\n * @example\n * ```typescript\n * import { storage } from \"@warlock.js/core\";\n *\n * const file = await storage.put(buffer, \"uploads/file.txt\");\n * ```\n */\nexport const storage = new Storage();\n","import { config } from \"../config\";\nimport type { UploadsConfigurations } from \"./uploads-types\";\n\n/**\n * Default uploads configuration values\n *\n * These defaults are used when no configuration is provided\n * or when specific keys are missing from the app config.\n */\nexport const UPLOADS_DEFAULTS: UploadsConfigurations = {\n name: \"random\",\n randomLength: 32,\n prefix: {\n as: \"directory\",\n format: \"DD-MM-YYYY\",\n },\n // defaultPrefixFormat: \"DD-MM-YYYY-HH-II-SS\",\n};\n\n/**\n * Get uploads configuration value\n *\n * Retrieves a configuration value from the `uploads` section of app config,\n * falling back to the provided default or the built-in default.\n *\n * @param key - Configuration key to retrieve\n * @param defaultValue - Optional default value if not found\n * @returns The configuration value\n *\n * @example\n * ```typescript\n * const naming = uploadsConfig(\"name\"); // \"random\" or \"original\"\n * const length = uploadsConfig(\"randomLength\", 32);\n * ```\n */\nexport function uploadsConfig<K extends keyof UploadsConfigurations>(\n key: K,\n defaultValue?: UploadsConfigurations[K],\n): UploadsConfigurations[K] {\n const fallback = defaultValue ?? UPLOADS_DEFAULTS[key];\n return config.key(`uploads.${key}`, fallback);\n}\n","import type { MultipartFile } from \"@fastify/multipart\";\r\nimport { Random } from \"@mongez/reinforcements\";\r\nimport dayjs from \"dayjs\";\r\nimport path from \"path\";\r\nimport { Image, type ImageFormat, type ImageTransformOptions } from \"../image\";\r\nimport { storage, type ScopedStorage, type StorageDriverName, type StorageFile } from \"../storage\";\r\nimport { sanitizePath } from \"../utils/paths\";\r\nimport { uploadsConfig } from \"./uploads-config\";\r\nimport type {\r\n FileNamingStrategy,\r\n ImageTransformCallback,\r\n PrefixConfig,\r\n SaveAsOptions,\r\n SaveOptions,\r\n UploadedFileImageOptions,\r\n} from \"./uploads-types\";\r\n\r\ntype UploadedFileMetadata = {\r\n name: string;\r\n mimeType: string;\r\n extension: string;\r\n size: number;\r\n width?: number;\r\n height?: number;\r\n};\r\n\r\n/**\r\n * Options for validating file before saving\r\n */\r\nexport type FileValidationOptions = {\r\n /**\r\n * List of allowed MIME types\r\n *\r\n * @example [\"image/jpeg\", \"image/png\", \"image/webp\"]\r\n */\r\n allowedMimeTypes?: string[];\r\n\r\n /**\r\n * List of allowed file extensions (without dot)\r\n *\r\n * @example [\"jpg\", \"jpeg\", \"png\", \"webp\"]\r\n */\r\n allowedExtensions?: string[];\r\n\r\n /**\r\n * Maximum file size in bytes\r\n *\r\n * @example 5 * 1024 * 1024 // 5MB\r\n */\r\n maxSize?: number;\r\n};\r\n\r\n/**\r\n * UploadedFile - Handles multipart file uploads with storage and image integration\r\n *\r\n * Provides a fluent API for validating, transforming, and saving uploaded files\r\n * to various storage drivers (local, S3, R2, etc.).\r\n *\r\n * @example\r\n * ```typescript\r\n * // Simple save with random name\r\n * const file = await uploadedFile.save(\"avatars\");\r\n *\r\n * // Original name with date prefix\r\n * const file = await uploadedFile.save(\"avatars\", {\r\n * name: \"original\",\r\n * prefix: { format: \"yyyy/mm/dd\", as: \"directory\" }\r\n * });\r\n *\r\n * // With image transformations\r\n * const file = await uploadedFile\r\n * .resize(800, 600)\r\n * .quality(85)\r\n * .format(\"webp\")\r\n * .save(\"avatars\");\r\n *\r\n * // Different storage driver\r\n * const file = await uploadedFile.use(\"s3\").save(\"avatars\");\r\n * ```\r\n */\r\nexport class UploadedFile {\r\n /**\r\n * File buffered content\r\n * @internal\r\n */\r\n protected bufferedFileContent?: Buffer;\r\n\r\n /**\r\n * Upload file hash (SHA-256)\r\n *\r\n * Populated after file is saved.\r\n */\r\n public hash = \"\";\r\n\r\n /**\r\n * Selected storage driver\r\n * @internal\r\n */\r\n protected _storage: ScopedStorage = storage;\r\n\r\n /**\r\n * Saved StorageFile reference\r\n * @internal\r\n */\r\n protected _storageFile?: StorageFile;\r\n\r\n /**\r\n * Queued image options (high-level API)\r\n * @internal\r\n */\r\n protected _imageOptions: UploadedFileImageOptions = {};\r\n\r\n /**\r\n * Full transform options or callback\r\n * @internal\r\n */\r\n protected _transformConfig?: ImageTransformOptions | ImageTransformCallback;\r\n\r\n /**\r\n * Create a new UploadedFile instance\r\n *\r\n * @param fileData - Multipart file data from Fastify\r\n * @throws Error if file data is invalid\r\n */\r\n public constructor(protected readonly fileData: MultipartFile) {\r\n if (!fileData?.filename) {\r\n throw new Error(\"Invalid file data: filename is required\");\r\n }\r\n }\r\n\r\n // ============================================================\r\n // File Properties\r\n // ============================================================\r\n\r\n /**\r\n * Get file name (sanitized)\r\n *\r\n * Returns the original filename with special characters removed/replaced.\r\n */\r\n public get name(): string {\r\n return sanitizePath(this.fileData.filename);\r\n }\r\n\r\n /**\r\n * Get file MIME type\r\n *\r\n * @example \"image/jpeg\", \"application/pdf\"\r\n */\r\n public get mimeType(): string {\r\n return this.fileData.mimetype;\r\n }\r\n\r\n /**\r\n * Get file extension (lowercase, without dot)\r\n *\r\n * @example \"jpg\", \"png\", \"pdf\"\r\n */\r\n public get extension(): string {\r\n return path.extname(this.fileData.filename).replace(\".\", \"\").toLowerCase();\r\n }\r\n\r\n /**\r\n * Get file metadata\r\n */\r\n public async metadata(): Promise<UploadedFileMetadata> {\r\n const data: UploadedFileMetadata = {\r\n name: this.name,\r\n mimeType: this.mimeType,\r\n extension: this.extension,\r\n size: await this.size(),\r\n };\r\n\r\n if (this.isImage) {\r\n const dimensions = await this.dimensions();\r\n data.width = dimensions.width;\r\n data.height = dimensions.height;\r\n }\r\n\r\n return data;\r\n }\r\n\r\n /**\r\n * Get file size in bytes\r\n *\r\n * Buffers the file content if not already buffered.\r\n */\r\n public async size(): Promise<number> {\r\n const file = await this.buffer();\r\n return file.length;\r\n }\r\n\r\n /**\r\n * Get file buffer\r\n *\r\n * Caches the buffer after first call for efficiency.\r\n */\r\n public async buffer(): Promise<Buffer> {\r\n if (this.bufferedFileContent) {\r\n return this.bufferedFileContent;\r\n }\r\n\r\n this.bufferedFileContent = await this.fileData.toBuffer();\r\n return this.bufferedFileContent;\r\n }\r\n\r\n // ============================================================\r\n // File Type Checks\r\n // ============================================================\r\n\r\n /**\r\n * Check if file is an image based on MIME type\r\n */\r\n public get isImage(): boolean {\r\n return this.mimeType.startsWith(\"image\");\r\n }\r\n\r\n /**\r\n * Check if file is a video based on MIME type\r\n */\r\n public get isVideo(): boolean {\r\n return this.mimeType.startsWith(\"video\");\r\n }\r\n\r\n /**\r\n * Check if file is an audio based on MIME type\r\n */\r\n public get isAudio(): boolean {\r\n return this.mimeType.startsWith(\"audio\");\r\n }\r\n\r\n // ============================================================\r\n // Storage Driver Selection\r\n // ============================================================\r\n\r\n /**\r\n * Select a specific storage driver for this upload\r\n *\r\n * Returns this instance for chaining. The driver is used\r\n * when `save()` or `saveAs()` is called.\r\n *\r\n * @param driver - Driver name from storage configuration\r\n * @returns This instance for chaining\r\n *\r\n * @example\r\n * ```typescript\r\n * await file.use(\"s3\").save(\"avatars\");\r\n * await file.use(\"r2\").save(\"cdn/images\");\r\n * ```\r\n */\r\n public use(driver: StorageDriverName): this {\r\n this._storage = storage.use(driver);\r\n return this;\r\n }\r\n\r\n // ============================================================\r\n // High-Level Image Transform API\r\n // ============================================================\r\n\r\n /**\r\n * Resize the image before saving\r\n *\r\n * Only applies to image files. Non-image files ignore this.\r\n *\r\n * @param width - Target width in pixels\r\n * @param height - Optional target height (maintains aspect ratio if omitted)\r\n * @returns This instance for chaining\r\n *\r\n * @example\r\n * ```typescript\r\n * await file.resize(800).save(\"thumbnails\");\r\n * await file.resize(400, 400).save(\"avatars\");\r\n * ```\r\n */\r\n public resize(width: number, height?: number): this {\r\n this._imageOptions.resize = { width, height };\r\n return this;\r\n }\r\n\r\n /**\r\n * Set image output quality\r\n *\r\n * Quality affects file size and visual fidelity.\r\n * Only applies to formats that support quality (JPEG, WebP, AVIF).\r\n *\r\n * @param value - Quality value (1-100)\r\n * @returns This instance for chaining\r\n *\r\n * @example\r\n * ```typescript\r\n * await file.quality(85).save(\"images\");\r\n * ```\r\n */\r\n public quality(value: number): this {\r\n if (value < 1 || value > 100) {\r\n throw new Error(\"Quality must be between 1 and 100\");\r\n }\r\n this._imageOptions.quality = value;\r\n return this;\r\n }\r\n\r\n /**\r\n * Convert image to a specific format\r\n *\r\n * Changes the output format and updates the file extension accordingly.\r\n *\r\n * @param format - Target image format (jpeg, png, webp, avif, etc.)\r\n * @returns This instance for chaining\r\n *\r\n * @example\r\n * ```typescript\r\n * await file.format(\"webp\").save(\"images\");\r\n * await file.resize(800).format(\"avif\").quality(80).save(\"optimized\");\r\n * ```\r\n */\r\n public format(format: ImageFormat): this {\r\n this._imageOptions.format = format;\r\n return this;\r\n }\r\n\r\n /**\r\n * Rotate the image\r\n *\r\n * @param degrees - Rotation angle in degrees (positive = clockwise)\r\n * @returns This instance for chaining\r\n *\r\n * @example\r\n * ```typescript\r\n * await file.rotate(90).save(\"rotated\");\r\n * ```\r\n */\r\n public rotate(degrees: number): this {\r\n this._imageOptions.rotate = degrees;\r\n return this;\r\n }\r\n\r\n /**\r\n * Apply blur effect to the image\r\n *\r\n * @param sigma - Blur intensity (default: 3, minimum: 0.3)\r\n * @returns This instance for chaining\r\n *\r\n * @example\r\n * ```typescript\r\n * await file.blur(5).save(\"blurred\");\r\n * ```\r\n */\r\n public blur(sigma = 3): this {\r\n if (sigma < 0.3) {\r\n throw new Error(\"Blur sigma must be at least 0.3\");\r\n }\r\n this._imageOptions.blur = sigma;\r\n return this;\r\n }\r\n\r\n /**\r\n * Convert image to grayscale (black and white)\r\n *\r\n * @returns This instance for chaining\r\n *\r\n * @example\r\n * ```typescript\r\n * await file.grayscale().save(\"bw-images\");\r\n * ```\r\n */\r\n public grayscale(): this {\r\n this._imageOptions.grayscale = true;\r\n return this;\r\n }\r\n\r\n // ============================================================\r\n // Full Transform Control\r\n // ============================================================\r\n\r\n /**\r\n * Apply full image transformations\r\n *\r\n * Provides complete control over image processing. Can be used with:\r\n * - An options object for predefined transforms\r\n * - A callback function for chained operations\r\n *\r\n * @param config - Transform options or callback function\r\n * @returns This instance for chaining\r\n *\r\n * @example\r\n * ```typescript\r\n * // Using options object\r\n * await file.transform({\r\n * resize: { width: 800, fit: \"inside\" },\r\n * quality: 85\r\n * }).save(\"images\");\r\n *\r\n * // Using callback for full control\r\n * await file.transform(img =>\r\n * img.resize({ width: 800 })\r\n * .watermark(\"logo.png\", { gravity: \"southeast\" })\r\n * .sharpen()\r\n * ).save(\"products\");\r\n * ```\r\n */\r\n public transform(config: ImageTransformOptions | ImageTransformCallback): this {\r\n this._transformConfig = config;\r\n return this;\r\n }\r\n\r\n /**\r\n * Get an Image instance for advanced manipulation\r\n *\r\n * Returns an Image instance from the file buffer for manual processing.\r\n * Use this when you need operations not covered by the fluent API.\r\n *\r\n * @returns Promise resolving to Image instance\r\n *\r\n * @example\r\n * ```typescript\r\n * const img = await file.toImage();\r\n * await img\r\n * .resize({ width: 800 })\r\n * .watermark(\"logo.png\", { gravity: \"southeast\" })\r\n * .save(\"path/to/output.jpg\");\r\n * ```\r\n */\r\n public async toImage(): Promise<Image> {\r\n return new Image(await this.buffer());\r\n }\r\n\r\n // ============================================================\r\n // Image Metadata\r\n // ============================================================\r\n\r\n /**\r\n * Get file width and height (only for images)\r\n *\r\n * @returns Dimensions object, or empty object if not an image\r\n */\r\n public async dimensions(): Promise<{ width?: number; height?: number }> {\r\n if (!this.isImage) {\r\n return {};\r\n }\r\n\r\n return new Image(await this.buffer()).dimensions();\r\n }\r\n\r\n // ============================================================\r\n // Validation\r\n // ============================================================\r\n\r\n /**\r\n * Validate file against the given options\r\n *\r\n * @param options - Validation rules\r\n * @throws Error if validation fails\r\n *\r\n * @example\r\n * ```typescript\r\n * await file.validate({\r\n * allowedMimeTypes: [\"image/jpeg\", \"image/png\"],\r\n * maxSize: 5 * 1024 * 1024 // 5MB\r\n * });\r\n * ```\r\n */\r\n public async validate(options: FileValidationOptions): Promise<void> {\r\n const { allowedMimeTypes, allowedExtensions, maxSize } = options;\r\n\r\n if (allowedMimeTypes && !allowedMimeTypes.includes(this.mimeType)) {\r\n throw new Error(\r\n `Invalid file type: ${this.mimeType}. Allowed types: ${allowedMimeTypes.join(\", \")}`,\r\n );\r\n }\r\n\r\n if (allowedExtensions && !allowedExtensions.includes(this.extension)) {\r\n throw new Error(\r\n `Invalid file extension: ${this.extension}. Allowed extensions: ${allowedExtensions.join(\", \")}`,\r\n );\r\n }\r\n\r\n if (maxSize) {\r\n const fileSize = await this.size();\r\n if (fileSize > maxSize) {\r\n throw new Error(`File too large: ${fileSize} bytes. Maximum allowed: ${maxSize} bytes`);\r\n }\r\n }\r\n }\r\n\r\n // ============================================================\r\n // Save Operations\r\n // ============================================================\r\n\r\n /**\r\n * Save the file to a directory with automatic naming\r\n * Keep in mind to use only relative path to the root of storage\r\n * If you are using local driver\r\n * Uses the configured naming strategy and prefix options to generate\r\n * the final path. Returns a StorageFile for accessing file metadata.\r\n *\r\n * @param directory - Target directory path\r\n * @param options - Save options (name, prefix, driver, validate)\r\n * @returns StorageFile instance with file metadata and operations\r\n *\r\n * @example\r\n * ```typescript\r\n * // Random name (default)\r\n * await file.save(\"avatars\");\r\n * // → avatars/x7k9m2p4.jpg\r\n *\r\n * // Original name\r\n * await file.save(\"avatars\", { name: \"original\" });\r\n * // → avatars/photo.jpg\r\n *\r\n * // With date directory\r\n * await file.save(\"avatars\", {\r\n * prefix: { format: \"yyyy/mm/dd\", as: \"directory\" }\r\n * });\r\n * // → avatars/2025/12/21/x7k9m2p4.jpg\r\n *\r\n * // Original name with datetime prefix\r\n * await file.save(\"avatars\", { name: \"original\", prefix: true });\r\n * // → avatars/21-12-2025-16-45-30-photo.jpg\r\n * ```\r\n */\r\n public async save(directory: string, options?: SaveOptions): Promise<StorageFile> {\r\n // Validate if requested\r\n if (options?.validate) {\r\n await this.validate(options.validate);\r\n }\r\n\r\n // Resolve filename and prefix\r\n const filename = this.resolveFilename(options);\r\n const prefix = this.resolvePrefix(options?.prefix);\r\n const location = this.buildLocation(directory, prefix, filename);\r\n\r\n return this.saveToLocation(location, options?.driver);\r\n }\r\n\r\n /**\r\n * Save the file to an explicit path\r\n *\r\n * Unlike `save()`, this method uses the exact path you provide.\r\n * No automatic naming or prefix is applied.\r\n *\r\n * @param location - Full file path (directory + filename)\r\n * @param options - Save options (driver, validate)\r\n * @returns StorageFile instance with file metadata\r\n *\r\n * @example\r\n * ```typescript\r\n * await file.saveAs(\"avatars/profile-123.png\");\r\n * await file.saveAs(\"products/2025/featured-image.webp\");\r\n * ```\r\n */\r\n public async saveAs(location: string, options?: SaveAsOptions): Promise<StorageFile> {\r\n // Validate if requested\r\n if (options?.validate) {\r\n await this.validate(options.validate);\r\n }\r\n\r\n return this.saveToLocation(location, options?.driver);\r\n }\r\n\r\n /**\r\n * Get the StorageFile reference if file has been saved\r\n *\r\n * Returns undefined if file hasn't been saved yet.\r\n */\r\n public get storageFile(): StorageFile | undefined {\r\n return this._storageFile;\r\n }\r\n\r\n // ============================================================\r\n // Internal Helpers\r\n // ============================================================\r\n\r\n /**\r\n * Execute save to the specified location\r\n * @internal\r\n */\r\n protected async saveToLocation(\r\n location: string,\r\n driver?: StorageDriverName,\r\n ): Promise<StorageFile> {\r\n // Get file content (apply transforms if image)\r\n const content = await this.getProcessedContent();\r\n\r\n // Select storage\r\n const storageInstance = this.resolveStorage(driver);\r\n\r\n // Determine final location (adjust extension if format changed)\r\n const finalLocation = this.adjustLocationForFormat(location);\r\n\r\n // Save to storage\r\n this._storageFile = await storageInstance.put(content, finalLocation, {\r\n mimeType: this.getFinalMimeType(),\r\n });\r\n\r\n // Store hash from StorageFile\r\n const info = await this._storageFile.data();\r\n this.hash = info.hash || \"\";\r\n\r\n return this._storageFile;\r\n }\r\n\r\n /**\r\n * Get processed content (with transforms applied if applicable)\r\n * @internal\r\n */\r\n protected async getProcessedContent(): Promise<Buffer> {\r\n const content = await this.buffer();\r\n\r\n // If not an image or no transforms, return as-is\r\n if (!this.isImage || !this.hasTransforms()) {\r\n return content;\r\n }\r\n\r\n // Create Image and apply transforms\r\n let img = new Image(content);\r\n\r\n // Apply transform callback or options\r\n if (typeof this._transformConfig === \"function\") {\r\n img = this._transformConfig(img);\r\n } else if (this._transformConfig) {\r\n img = img.apply(this._transformConfig);\r\n }\r\n\r\n // Apply high-level options on top\r\n img = this.applyImageOptions(img);\r\n\r\n return img.toBuffer();\r\n }\r\n\r\n /**\r\n * Apply high-level image options\r\n * @internal\r\n */\r\n protected applyImageOptions(img: Image): Image {\r\n const opts = this._imageOptions;\r\n\r\n if (opts.resize) {\r\n img = img.resize({ width: opts.resize.width, height: opts.resize.height });\r\n }\r\n\r\n if (opts.rotate !== undefined) {\r\n img = img.rotate(opts.rotate);\r\n }\r\n\r\n if (opts.blur !== undefined) {\r\n img = img.blur(opts.blur);\r\n }\r\n\r\n if (opts.grayscale) {\r\n img = img.grayscale();\r\n }\r\n\r\n if (opts.quality !== undefined) {\r\n img = img.quality(opts.quality);\r\n }\r\n\r\n if (opts.format) {\r\n img = img.format(opts.format);\r\n }\r\n\r\n return img;\r\n }\r\n\r\n /**\r\n * Check if any transforms are queued\r\n * @internal\r\n */\r\n protected hasTransforms(): boolean {\r\n return this._transformConfig !== undefined || Object.keys(this._imageOptions).length > 0;\r\n }\r\n\r\n /**\r\n * Resolve storage instance to use\r\n * @internal\r\n */\r\n protected resolveStorage(driver?: StorageDriverName): ScopedStorage | typeof storage {\r\n if (driver) {\r\n return storage.use(driver);\r\n }\r\n\r\n return this._storage || storage;\r\n }\r\n\r\n /**\r\n * Resolve the filename based on options and config\r\n * @internal\r\n */\r\n protected resolveFilename(options?: SaveOptions): string {\r\n const namingStrategy: FileNamingStrategy = options?.name ?? uploadsConfig(\"name\") ?? \"random\";\r\n let baseName: string;\r\n\r\n if (namingStrategy === \"original\") {\r\n baseName = path.basename(this.name, path.extname(this.name));\r\n } else if (namingStrategy === \"random\") {\r\n const length = uploadsConfig(\"randomLength\");\r\n baseName = Random.string(length);\r\n } else {\r\n // Custom name - strip extension if provided, we'll add it\r\n baseName = path.basename(namingStrategy, path.extname(namingStrategy));\r\n }\r\n\r\n // Get extension (may be changed by format transform)\r\n const ext = this.getFinalExtension();\r\n\r\n return `${baseName}.${ext}`;\r\n }\r\n\r\n /**\r\n * Resolve prefix based on options and config\r\n * @internal\r\n */\r\n protected resolvePrefix(prefix?: PrefixConfig): string {\r\n // No prefix\r\n if (prefix === false || prefix === undefined) {\r\n const configPrefix = uploadsConfig(\"prefix\");\r\n if (!configPrefix) {\r\n return \"\";\r\n }\r\n // Use config prefix if no explicit prefix provided\r\n prefix = configPrefix;\r\n }\r\n\r\n // Boolean true = use default format\r\n if (prefix === true) {\r\n const format = uploadsConfig(\"defaultPrefixFormat\")!;\r\n return this.formatDatePrefix(format, \"file\");\r\n }\r\n\r\n // String = static prefix\r\n if (typeof prefix === \"string\") {\r\n return prefix;\r\n }\r\n\r\n // PrefixOptions object\r\n const parts: string[] = [];\r\n\r\n // Add date format if specified\r\n if (prefix.format) {\r\n parts.push(this.formatDate(prefix.format));\r\n }\r\n\r\n // Add random string if specified\r\n if (prefix.randomLength) {\r\n parts.push(Random.string(prefix.randomLength));\r\n }\r\n\r\n const combined = parts.join(\"-\");\r\n const as = prefix.as ?? \"file\";\r\n\r\n if (as === \"directory\") {\r\n return combined ? `${combined}/` : \"\";\r\n }\r\n\r\n return combined ? `${combined}-` : \"\";\r\n }\r\n\r\n /**\r\n * Format a date prefix with the given format\r\n * @internal\r\n */\r\n protected formatDatePrefix(format: string, as: \"file\" | \"directory\"): string {\r\n const formatted = this.formatDate(format);\r\n return as === \"directory\" ? `${formatted}/` : `${formatted}-`;\r\n }\r\n\r\n /**\r\n * Format current date using token-based format string\r\n * @internal\r\n */\r\n protected formatDate(format: string): string {\r\n return dayjs().format(format);\r\n }\r\n\r\n /**\r\n * Build final location from directory, prefix, and filename\r\n * @internal\r\n */\r\n protected buildLocation(directory: string, prefix: string, filename: string): string {\r\n // Clean up directory (remove trailing slash)\r\n const dir = directory.replace(/\\/$/, \"\");\r\n\r\n // If prefix ends with /, it's a directory\r\n if (prefix.endsWith(\"/\")) {\r\n return `${dir}/${prefix}${filename}`;\r\n }\r\n\r\n // Otherwise prefix is part of filename\r\n return `${dir}/${prefix}${filename}`;\r\n }\r\n\r\n /**\r\n * Get final extension (accounting for format changes)\r\n * @internal\r\n */\r\n protected getFinalExtension(): string {\r\n if (this._imageOptions.format) {\r\n // Map formats to extensions\r\n const format = this._imageOptions.format;\r\n\r\n if (format === \"jpeg\") return \"jpg\";\r\n\r\n return format;\r\n }\r\n\r\n return this.extension;\r\n }\r\n\r\n /**\r\n * Get final MIME type (accounting for format changes)\r\n * @internal\r\n */\r\n protected getFinalMimeType(): string {\r\n if (this._imageOptions.format) {\r\n const format = this._imageOptions.format;\r\n\r\n if (format === \"jpeg\" || format === \"jpg\") return \"image/jpeg\";\r\n\r\n return `image/${format}`;\r\n }\r\n\r\n return this.mimeType;\r\n }\r\n\r\n /**\r\n * Adjust location to use correct extension if format changed\r\n * @internal\r\n */\r\n protected adjustLocationForFormat(location: string): string {\r\n if (!this._imageOptions.format) {\r\n return location;\r\n }\r\n\r\n const ext = this.getFinalExtension();\r\n const currentExt = path.extname(location);\r\n\r\n if (currentExt) {\r\n return location.replace(currentExt, `.${ext}`);\r\n }\r\n\r\n return `${location}.${ext}`;\r\n }\r\n\r\n // ============================================================\r\n // Serialization\r\n // ============================================================\r\n\r\n /**\r\n * Convert to JSON representation\r\n *\r\n * Includes file metadata and base64 content for serialization.\r\n */\r\n public async toJSON() {\r\n return {\r\n name: this.name,\r\n mimeType: this.mimeType,\r\n extension: this.extension,\r\n size: await this.size(),\r\n isImage: this.isImage,\r\n isVideo: this.isVideo,\r\n isAudio: this.isAudio,\r\n dimensions: this.isImage ? await this.dimensions() : undefined,\r\n base64: (await this.buffer()).toString(\"base64\"),\r\n };\r\n }\r\n}\r\n","import { colors } from \"@mongez/copper\";\r\nimport events from \"@mongez/events\";\r\nimport { trans, transFrom } from \"@mongez/localization\";\r\nimport { Random, except, get, only, rtrim, set, unset } from \"@mongez/reinforcements\";\r\nimport { isEmpty } from \"@mongez/supportive-is\";\r\nimport type { LogLevel } from \"@warlock.js/logger\";\r\nimport { log } from \"@warlock.js/logger\";\r\nimport { BaseValidator, v } from \"@warlock.js/seal\";\r\nimport type { FastifyRequest } from \"fastify\";\r\nimport { type IncomingHttpHeaders } from \"node:http2\";\r\nimport { config } from \"../config/config-getter\";\r\nimport type { Middleware, Route } from \"../router\";\r\nimport { validateAll } from \"../validation/validateAll\";\r\nimport { createRequestStore } from \"./middleware/inject-request-context\";\r\nimport { Response } from \"./response\";\r\nimport type { RequestEvent } from \"./types\";\r\nimport { UploadedFile } from \"./uploaded-file\";\r\n\r\ntype StandardHeaders = {\r\n // copy every declared property from http.IncomingHttpHeaders\r\n // but remove index signatures\r\n [K in keyof IncomingHttpHeaders as string extends K\r\n ? never\r\n : number extends K\r\n ? never\r\n : K]: IncomingHttpHeaders[K];\r\n};\r\n\r\ntype HeaderKeys = keyof StandardHeaders;\r\n\r\nexport class Request<User = any, RequestValidation = any> {\r\n /**\r\n * Fastify Request object\r\n */\r\n public baseRequest!: FastifyRequest;\r\n\r\n /**\r\n * Response Object\r\n */\r\n public response!: Response;\r\n\r\n /**\r\n * Route Object\r\n */\r\n public route!: Route;\r\n\r\n /**\r\n * Parsed Request Payload\r\n */\r\n protected payload: any = {};\r\n\r\n /**\r\n * Current user\r\n */\r\n public user?: User;\r\n\r\n /**\r\n * Decoded access token payload (set by auth middleware)\r\n */\r\n public decodedAccessToken?: any;\r\n\r\n /**\r\n * Current request instance\r\n */\r\n public static current: Request;\r\n\r\n /**\r\n * Translation method\r\n * Type of it is the same as the type of trans function\r\n */\r\n public trans: ReturnType<typeof trans> = trans;\r\n\r\n /**\r\n * Alias to trans method\r\n */\r\n public t: ReturnType<typeof trans> = trans;\r\n\r\n /**\r\n * Dynamic properties index signature\r\n *\r\n * This allows attaching custom properties to the request instance,\r\n * commonly used during validation middleware to attach fetched models.\r\n *\r\n * @example\r\n * // In validation middleware:\r\n * const post = await Post.find(request.int(\"id\"));\r\n * if (!post) return response.notFound();\r\n * request.post = post; // Attach the model to the request\r\n *\r\n * // In route handler:\r\n * const post = request.post;\r\n * // Work with the pre-fetched model\r\n */\r\n [key: string]: any;\r\n\r\n /**\r\n * Locale code\r\n */\r\n protected _locale = \"\";\r\n\r\n /**\r\n * Validated data\r\n */\r\n protected validatedData?: RequestValidation;\r\n\r\n /**\r\n * Request id\r\n */\r\n public id = Random.string(32);\r\n\r\n /**\r\n * Set request handler\r\n */\r\n public setRequest(request: FastifyRequest) {\r\n this.baseRequest = request;\r\n\r\n this.parsePayload();\r\n\r\n const localeCode = this.getLocaleCode();\r\n\r\n this.trans = this.t = transFrom.bind(null, localeCode);\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Translate from the given locale code\r\n */\r\n public transFrom(localeCode: string, keyword: string, placeholders?: any) {\r\n return transFrom(localeCode, keyword, placeholders);\r\n }\r\n\r\n /**\r\n * Get current locale code\r\n */\r\n public get locale() {\r\n if (this._locale) return this._locale;\r\n\r\n return this.header(\"translation-locale-code\") || this.localized;\r\n }\r\n\r\n /**\r\n * Set locale code\r\n */\r\n public set locale(localeCode: string) {\r\n this._locale = localeCode;\r\n }\r\n\r\n /**\r\n * Get locale code that will be used for translation\r\n */\r\n public get localized() {\r\n if (this._locale) return this._locale;\r\n\r\n return (this._locale =\r\n this.header(\"locale-code\") ||\r\n this.header(\"locale\") ||\r\n this.query[\"locale\"] ||\r\n this.query[\"locale-code\"]);\r\n }\r\n\r\n /**\r\n * Set locale code\r\n */\r\n public setLocaleCode(localeCode: string) {\r\n this._locale = localeCode;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Get current locale code or return default locale code\r\n */\r\n public getLocaleCode(defaultLocaleCode: string = config.key(\"app.localeCode\") || \"en\") {\r\n return this.locale || defaultLocaleCode;\r\n }\r\n\r\n /**\r\n * Get http protocol\r\n */\r\n public get protocol() {\r\n return this.baseRequest.protocol;\r\n }\r\n\r\n /**\r\n * Validate the given validation schema\r\n */\r\n public async validate(validation: BaseValidator, selectedInputs?: string[]) {\r\n return await v.validate(validation, selectedInputs ? this.only(selectedInputs) : this.all());\r\n }\r\n\r\n /**\r\n * Clear current user\r\n */\r\n public clearCurrentUser() {\r\n this.user = undefined;\r\n }\r\n\r\n /**\r\n * Get value of the given header\r\n */\r\n public header<TCustomHeader extends string = HeaderKeys>(\r\n name: TCustomHeader | HeaderKeys,\r\n defaultValue: any = null,\r\n ) {\r\n return this.baseRequest.headers[name.toLocaleLowerCase()] ?? defaultValue;\r\n }\r\n\r\n /**\r\n * Get the current request domain\r\n */\r\n public get domain() {\r\n return this.baseRequest.hostname.replace(/^www\\./, \"\");\r\n }\r\n\r\n /**\r\n * Get hostname\r\n */\r\n public get hostname() {\r\n return this.domain;\r\n }\r\n\r\n /**\r\n * Get request origin\r\n */\r\n public get origin() {\r\n return this.baseRequest.headers.origin as string;\r\n }\r\n\r\n /**\r\n * Get the domain of the origin\r\n */\r\n public get originDomain() {\r\n const domain = this.origin ? new URL(this.origin).hostname : null;\r\n\r\n if (domain?.startsWith(\"www.\")) {\r\n return domain.replace(/^www\\./, \"\");\r\n }\r\n\r\n return domain;\r\n }\r\n\r\n /**\r\n * Get authorization header value\r\n */\r\n public get authorizationValue(): string {\r\n const authorization = this.header(\"authorization\");\r\n\r\n if (!authorization) return \"\";\r\n\r\n const [type, value] = authorization.split(\" \");\r\n\r\n if (![\"bearer\", \"key\"].includes(type.toLowerCase())) return \"\";\r\n\r\n return value || \"\";\r\n }\r\n\r\n /**\r\n * Get access token from Authorization header\r\n *\r\n * If the Authorization header does not start with `Bearer` value then return null\r\n */\r\n public get accessToken(): string | undefined {\r\n const authorization = this.header(\"authorization\");\r\n\r\n if (!authorization) return;\r\n\r\n const [type, value] = authorization.split(\" \");\r\n\r\n if (type.toLowerCase() !== \"bearer\") return;\r\n\r\n return value;\r\n }\r\n\r\n /**\r\n * Get the authorization header\r\n */\r\n public get authorization() {\r\n return this.header(\"authorization\");\r\n }\r\n\r\n /**\r\n * Get current request method\r\n */\r\n public get method(): string {\r\n return this.baseRequest.method;\r\n }\r\n\r\n /**\r\n * Parse the payload and merge it from the request body, params and query string\r\n */\r\n protected parsePayload() {\r\n this.payload.body = this.parseBody(this.baseRequest.body);\r\n\r\n this.payload.query = this.parseBody(this.baseRequest.query);\r\n this.payload.params = { ...(this.baseRequest.params || {}) };\r\n this.payload.all = {\r\n ...this.payload.body,\r\n ...this.payload.query,\r\n ...this.payload.params,\r\n };\r\n }\r\n\r\n /**\r\n * Parse body payload\r\n */\r\n protected parseBody(data: any) {\r\n try {\r\n if (!data) return {};\r\n\r\n const body: any = {};\r\n\r\n const arrayOfObjectValues: any = {};\r\n\r\n for (let key in data) {\r\n const value = data[key];\r\n\r\n let isArrayKey = false;\r\n\r\n if (key.endsWith(\"[]\")) {\r\n isArrayKey = true;\r\n }\r\n\r\n key = rtrim(key, \"[]\");\r\n\r\n // check if the key is has a square brackets, then convert it into object\r\n // i.e user[email] => user: {email: \"value\"}\r\n // also check if its an array of objects\r\n\r\n if (key.includes(\"[\")) {\r\n // check if its an array of objects\r\n if (key.includes(\"][\")) {\r\n const keyParts = key.split(\"[\");\r\n\r\n const keyName = keyParts[0];\r\n if (!arrayOfObjectValues[keyName]) {\r\n arrayOfObjectValues[keyName] = [];\r\n }\r\n\r\n const keyNameParts = keyParts[1].split(\"]\");\r\n\r\n const index = Number(keyNameParts[0]);\r\n\r\n if (!arrayOfObjectValues[keyName][index]) {\r\n arrayOfObjectValues[keyName][index] = {};\r\n }\r\n\r\n // now get the key after the index\r\n const keyNameParts2 = keyParts[2].split(\"]\");\r\n const keyName2 = keyNameParts2[0];\r\n\r\n arrayOfObjectValues[keyName][index][keyName2] = this.parseValue(value);\r\n\r\n continue;\r\n }\r\n\r\n const keyParts = key.split(\"[\");\r\n const keyName = keyParts[0];\r\n const keyNameParts = keyParts[1].split(\"]\");\r\n\r\n set(\r\n body,\r\n keyName + \".\" + keyNameParts[0],\r\n Array.isArray(value) ? value.map(this.parseValue.bind(this)) : this.parseValue(value),\r\n );\r\n\r\n continue;\r\n }\r\n\r\n if (Array.isArray(value)) {\r\n set(body, key, value.map(this.parseValue.bind(this)));\r\n } else if (isArrayKey) {\r\n if (body[key]) {\r\n body[key].push(this.parseValue(value));\r\n } else {\r\n body[key] = [this.parseValue(value)];\r\n\r\n continue;\r\n }\r\n } else {\r\n set(body, key, this.parseValue(value));\r\n }\r\n }\r\n\r\n // now merge the array of objects into the body\r\n for (const key in arrayOfObjectValues) {\r\n body[key] = arrayOfObjectValues[key];\r\n }\r\n\r\n return body;\r\n } catch (error) {\r\n console.log(error);\r\n this.log(error, \"error\");\r\n }\r\n }\r\n\r\n /**\r\n * Parse the given data\r\n */\r\n protected parseValue(data: any) {\r\n // data.value appears only in the multipart form data\r\n // if it json, then just return the data\r\n if (data?.file) return new UploadedFile(data);\r\n if (data?.value !== undefined && data?.fields && data?.type) {\r\n data = data.value;\r\n }\r\n\r\n if (data === \"false\") return false;\r\n\r\n if (data === \"true\") return true;\r\n\r\n if (data === \"null\") return null;\r\n\r\n if (typeof data === \"string\") return data.trim();\r\n\r\n return data;\r\n }\r\n\r\n /**\r\n * Set route handler\r\n */\r\n public setRoute(route: Route) {\r\n this.route = route;\r\n\r\n // pass the route to the response object\r\n this.response.setRoute(route);\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Trigger an http event\r\n */\r\n public trigger(eventName: RequestEvent, ...args: any[]) {\r\n return events.trigger(`request.${eventName}`, ...args, this);\r\n }\r\n\r\n /**\r\n * Listen to the given event\r\n */\r\n public on(eventName: RequestEvent, callback: any) {\r\n return this.subscribe(eventName, callback);\r\n }\r\n\r\n /**\r\n * Make a log message\r\n */\r\n public log(message: any, level: LogLevel = \"info\") {\r\n if (!config.key(\"http.log\")) return;\r\n\r\n log({\r\n module: \"request\",\r\n action: this.route.method + \" \" + this.route.path.replace(\"/*\", \"\") + `:${this.id}`,\r\n message,\r\n type: level,\r\n context: {\r\n request: this,\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Get current request path\r\n */\r\n public get path() {\r\n return this.baseRequest.url;\r\n }\r\n\r\n /**\r\n * {@alias}\r\n */\r\n public get url() {\r\n return this.baseRequest.url;\r\n }\r\n\r\n /**\r\n * Get full url\r\n */\r\n public get fullUrl() {\r\n return this.protocol + \"://\" + this.hostname + this.path;\r\n }\r\n\r\n /**\r\n * Run middleware\r\n */\r\n public async runMiddleware() {\r\n // measure request time\r\n // check for middleware first\r\n const middlewareOutput = await this.executeMiddleware();\r\n\r\n if (middlewareOutput !== undefined) {\r\n // 👇🏻 make sure first its not a response instance\r\n if (middlewareOutput instanceof Response) return middlewareOutput;\r\n // 👇🏻 send the response\r\n return this.response.send(middlewareOutput);\r\n }\r\n\r\n const handler = this.route.handler;\r\n\r\n if (!handler.validation) return;\r\n\r\n // 👇🏻 check for validation using validateAll helper function\r\n const validationOutput = await validateAll(handler.validation, this, this.response);\r\n\r\n return validationOutput;\r\n }\r\n\r\n /**\r\n * Get route handler\r\n */\r\n public getHandler() {\r\n return this.route.handler;\r\n }\r\n\r\n /**\r\n * Get inputs that has been validated only\r\n * You can also pass an array of inputs to get only the validated inputs\r\n */\r\n public validated<Output = RequestValidation>(inputs?: string[]): Output {\r\n if (this.validatedData) {\r\n return inputs ? only(this.validatedData as Output, inputs) : (this.validatedData as Output);\r\n }\r\n\r\n return {} as Output;\r\n }\r\n\r\n /**\r\n * Get inputs that has been validated except the given inputs\r\n */\r\n public validatedExcept(...inputs: string[]): RequestValidation {\r\n return except(this.validated(), inputs);\r\n }\r\n\r\n /**\r\n * Set validated data\r\n */\r\n public setValidatedData(data: RequestValidation) {\r\n this.validatedData = data;\r\n }\r\n\r\n /**\r\n * Execute the request\r\n */\r\n public async execute() {\r\n try {\r\n // call executingAction event\r\n\r\n this.log(\"Executing the request\");\r\n\r\n return await createRequestStore(this, this.response);\r\n } catch (error) {\r\n this.log(error, \"error\");\r\n\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Execute middleware list of current route\r\n */\r\n protected async executeMiddleware() {\r\n // collect all middlewares for current route\r\n const middlewares = this.collectMiddlewares();\r\n\r\n // check if there are no middlewares, then return\r\n if (middlewares.length === 0) return;\r\n\r\n this.log(\"About to execute request middlewares\");\r\n\r\n // trigger the executingMiddleware event\r\n this.trigger(\"executingMiddleware\", middlewares, this.route);\r\n\r\n for (const middleware of middlewares) {\r\n this.log(\"Executing middleware \" + colors.yellowBright(middleware.name));\r\n const output = await middleware(this, this.response);\r\n this.log(\"Executed middleware \" + colors.yellowBright(middleware.name), \"success\");\r\n\r\n if (output !== undefined) {\r\n this.log(\r\n colors.yellow(\"request intercepted by middleware \") + colors.cyanBright(middleware.name),\r\n \"warn\",\r\n );\r\n\r\n this.trigger(\"executedMiddleware\");\r\n\r\n this.log(\"Request middlewares executed\", \"success\");\r\n\r\n return output;\r\n }\r\n }\r\n\r\n this.log(\"Request middlewares executed\", \"success\");\r\n\r\n // trigger the executedMiddleware event\r\n this.trigger(\"executedMiddleware\", middlewares, this.route);\r\n }\r\n\r\n /**\r\n * Collect middlewares for current route\r\n */\r\n protected collectMiddlewares(): Middleware[] {\r\n const middlewaresList: Middleware[] = [];\r\n\r\n // collect route middlewares\r\n if (this.route.middleware) {\r\n middlewaresList.push(...this.route.middleware);\r\n }\r\n\r\n return middlewaresList;\r\n }\r\n\r\n /**\r\n * Get request input value from query string, params or body\r\n */\r\n public input(key: string, defaultValue?: any) {\r\n return get(this.payload.all, key, defaultValue);\r\n }\r\n\r\n /**\r\n * Get email input value, this will lowercase the value\r\n */\r\n public email(key: string = \"email\", defaultValue: string = \"\"): string {\r\n return this.input(key, defaultValue)?.toLowerCase() || defaultValue;\r\n }\r\n\r\n /**\r\n * @alias input\r\n */\r\n public get(key: string, defaultValue?: any) {\r\n return this.input(key, defaultValue);\r\n }\r\n\r\n /**\r\n * Determine if request has input value\r\n */\r\n public has(key: string) {\r\n return get(this.payload.all, key, undefined) !== undefined;\r\n }\r\n\r\n /**\r\n * Set request input value\r\n */\r\n public set(key: string, value: any) {\r\n set(this.payload.all, key, value);\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Set the given value if the request does not have the input\r\n */\r\n public setDefault(key: string, value: any) {\r\n if (this.has(key)) return this;\r\n\r\n set(this.payload.all, key, value);\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Unset request payload keys\r\n */\r\n public unset(...keys: string[]) {\r\n this.payload.all = unset(this.payload.all, keys);\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Get request body\r\n */\r\n public get body() {\r\n return this.payload.body;\r\n }\r\n\r\n /**\r\n * Set request body value\r\n */\r\n public setBody(key: string, value: any) {\r\n set(this.payload.body, key, value);\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Get body inputs except files\r\n */\r\n public get bodyInputs() {\r\n const inputs = this.payload.body;\r\n\r\n const bodyInputs: any = {};\r\n\r\n for (const key in inputs) {\r\n const value = inputs[key];\r\n\r\n if (value.file && value.fieldname) continue;\r\n\r\n bodyInputs[key] = value;\r\n }\r\n\r\n return bodyInputs;\r\n }\r\n\r\n /**\r\n * Get request file in UploadedFile instance\r\n */\r\n public file(key: string): UploadedFile | undefined {\r\n const file = this.input(key);\r\n\r\n return file;\r\n }\r\n\r\n /**\r\n * Get uploaded files from the request for the given name\r\n * If the given name is not present in the request, return an empty array\r\n */\r\n public files(name: string): UploadedFile[] {\r\n return this.input(name) || [];\r\n }\r\n\r\n /**\r\n * Get request params\r\n */\r\n public get params() {\r\n return this.payload.params;\r\n }\r\n\r\n /**\r\n * Set request params value\r\n */\r\n public setParam(key: string, value: any) {\r\n set(this.payload.params, key, value);\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Get request query\r\n */\r\n public get query() {\r\n return this.payload.query;\r\n }\r\n\r\n /**\r\n * Set request query value\r\n */\r\n public setQuery(key: string, value: any) {\r\n set(this.payload.query, key, value);\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Get all inputs\r\n */\r\n public all() {\r\n return this.payload.all;\r\n }\r\n\r\n /**\r\n * Get all inputs except params\r\n */\r\n public allExceptParams() {\r\n return {\r\n ...this.payload.query,\r\n ...this.payload.body,\r\n };\r\n }\r\n\r\n /**\r\n * Get all heavy inputs except params\r\n */\r\n public heavyExceptParams() {\r\n const inputs = this.allExceptParams();\r\n\r\n const heavyInputs: any = {};\r\n\r\n for (const key in inputs) {\r\n const value = inputs[key];\r\n\r\n if (isEmpty(value) && value !== null) continue;\r\n\r\n heavyInputs[key] = value;\r\n }\r\n\r\n return heavyInputs;\r\n }\r\n\r\n /**\r\n * Get only heavy inputs, the input with a value\r\n */\r\n public heavy() {\r\n const inputs = this.all();\r\n\r\n const heavyInputs: any = {};\r\n\r\n for (const key in inputs) {\r\n const value = inputs[key];\r\n\r\n if (isEmpty(value) && value !== null) continue;\r\n\r\n heavyInputs[key] = value;\r\n }\r\n\r\n return heavyInputs;\r\n }\r\n\r\n /**\r\n * Get only the given keys from the request data\r\n */\r\n public only(keys: string[]) {\r\n return only(this.all(), keys);\r\n }\r\n\r\n /**\r\n * Pluck the given keys from the request data\r\n */\r\n public pluck(keys: string[]) {\r\n const data = this.only(keys);\r\n\r\n this.unset(...keys);\r\n\r\n return data;\r\n }\r\n\r\n /**\r\n * Get all request inputs except the given keys\r\n */\r\n public except(keys: string[]) {\r\n return except(this.all(), keys);\r\n }\r\n\r\n /**\r\n * Get boolean input value\r\n */\r\n public bool(key: string, defaultValue = false) {\r\n const value = this.input(key, defaultValue);\r\n\r\n if (value === \"true\") {\r\n return true;\r\n }\r\n\r\n if (value === \"false\") {\r\n return false;\r\n }\r\n\r\n if (value === 0) {\r\n return false;\r\n }\r\n\r\n return Boolean(value);\r\n }\r\n\r\n /**\r\n * Get integer input value\r\n */\r\n public int(key: string, defaultValue: number = 0): number {\r\n const value = this.input(key, defaultValue);\r\n\r\n return parseInt(value);\r\n }\r\n\r\n /**\r\n * Shorthand getter to get id param\r\n */\r\n public get idParam() {\r\n return this.int(\"id\");\r\n }\r\n\r\n /**\r\n * Get string input value\r\n */\r\n public string(key: string, defaultValue: string = \"\"): string {\r\n const value = this.input(key, defaultValue);\r\n\r\n return String(value);\r\n }\r\n\r\n /**\r\n * Get float input value\r\n */\r\n public float(key: string, defaultValue: number = 0): number {\r\n const value = this.input(key, defaultValue);\r\n\r\n return parseFloat(value) || 0;\r\n }\r\n\r\n /**\r\n * Get number input value\r\n */\r\n public number(key: string, defaultValue: number = 0): number {\r\n const value = Number(this.input(key, defaultValue));\r\n\r\n return isNaN(value) ? defaultValue : value;\r\n }\r\n\r\n /**\r\n * Get request ip\r\n */\r\n public get ip() {\r\n return this.baseRequest.ip;\r\n }\r\n\r\n /**\r\n * Detect proper ip\r\n */\r\n public detectIp() {\r\n // as the server maybe used behind a proxy\r\n // then we need to check first if there is a forwarded ip\r\n // check for the real-ip header\r\n\r\n const realIp = this.header(\"x-real-ip\");\r\n\r\n if (realIp) return realIp;\r\n\r\n const forwardedIp = this.header(\"x-forwarded-for\");\r\n\r\n return forwardedIp || this.baseRequest.ip;\r\n }\r\n\r\n /**\r\n * An alias to detectIp\r\n */\r\n public get realIp() {\r\n return this.detectIp();\r\n }\r\n\r\n /**\r\n * Get request ips\r\n */\r\n public get ips() {\r\n return this.baseRequest.ips;\r\n }\r\n\r\n /**\r\n * Get request referer\r\n */\r\n public get referer() {\r\n return this.baseRequest.headers.referer;\r\n }\r\n\r\n /**\r\n * Get user agent\r\n */\r\n public get userAgent() {\r\n return this.baseRequest.headers[\"user-agent\"];\r\n }\r\n\r\n /**\r\n * Get request headers\r\n */\r\n public get headers() {\r\n return this.baseRequest.headers;\r\n }\r\n}\r\n","import FindMyWay, { type HTTPMethod, type Instance } from \"find-my-way\";\r\nimport type { Route } from \"./types\";\r\n\r\n/**\r\n * Route Registry\r\n * Manages dynamic route matching using find-my-way for HMR support\r\n */\r\nexport class RouteRegistry {\r\n private router: Instance<any>;\r\n\r\n public constructor() {\r\n this.router = FindMyWay({\r\n ignoreTrailingSlash: true,\r\n caseSensitive: false,\r\n });\r\n }\r\n\r\n /**\r\n * Register all routes from the router's internal list\r\n */\r\n public register(routes: Route[]): void {\r\n // Register each route\r\n for (const route of routes) {\r\n if (route.method === \"all\") {\r\n this.registerRoute({\r\n ...route,\r\n method: \"GET\",\r\n });\r\n\r\n this.registerRoute({\r\n ...route,\r\n method: \"POST\",\r\n });\r\n } else {\r\n this.registerRoute(route);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Register a single route\r\n */\r\n public registerRoute(route: Route): void {\r\n this.router.on(route.method as HTTPMethod, route.path, (req, res, params) => {\r\n // Store the route and params for later use\r\n return { route, params };\r\n });\r\n }\r\n\r\n /**\r\n * Find a matching route for the given method and URL\r\n * @returns Matched route with extracted params, or null if no match\r\n */\r\n public find(\r\n method: string,\r\n url: string,\r\n ): { route: Route; params: Record<string, string> } | null {\r\n // Strip query string from URL (find-my-way expects just the path)\r\n const path = url.split(\"?\")[0];\r\n\r\n const match = this.router.find(method as HTTPMethod, path);\r\n\r\n if (!match) {\r\n return null;\r\n }\r\n\r\n // find-my-way handler expects (req, res, params, store, searchParams)\r\n // We only care about the return value which contains { route, params }\r\n return match.handler(null as any, null as any, match.params, match.store, {});\r\n }\r\n\r\n /**\r\n * Get all registered routes count (for debugging)\r\n */\r\n public getRouteCount(): number {\r\n return this.router\r\n .prettyPrint()\r\n .split(\"\\n\")\r\n .filter((line) => line.trim()).length;\r\n }\r\n}\r\n","import proxy, { type FastifyHttpProxyOptions } from \"@fastify/http-proxy\";\nimport fastifyStatic, { type FastifyStaticOptions } from \"@fastify/static\";\nimport concatRoute from \"@mongez/concat-route\";\nimport { ltrim, merge, toCamelCase, trim } from \"@mongez/reinforcements\";\nimport { isEmpty } from \"@mongez/supportive-is\";\nimport { log } from \"@warlock.js/logger\";\nimport type { FastifyReply, FastifyRequest } from \"fastify\";\nimport { Request } from \"../http/request\";\nimport { Response } from \"../http/response\";\nimport { type FastifyInstance } from \"../http/server\";\nimport { RouteRegistry } from \"./route-registry\";\nimport type {\n GroupedRoutesOptions,\n ResourceMethod,\n Route,\n RouteHandler,\n RouteHandlerType,\n RouteHandlerValidation,\n RouteOptions,\n RouteResource,\n RouterGroupCallback,\n RouterStacks,\n} from \"./types\";\n\nexport class Router {\n /**\n * Routes list\n */\n private routes: Route[] = [];\n\n /**\n * Router Instance\n */\n private static instance: Router;\n\n /**\n * Static paths\n */\n protected staticDirectories: FastifyStaticOptions[] = [];\n\n /**\n * Event listeners\n */\n protected eventListeners: Record<string, ((router: Router, server: FastifyInstance) => void)[]> =\n {};\n\n /**\n * Stacks\n * Stacks will be used for grouping routes to add prefix, name or middleware\n */\n protected stacks: RouterStacks = {\n prefix: [],\n name: [],\n middleware: [],\n };\n\n /**\n * Get router instance\n */\n public static getInstance() {\n if (!Router.instance) {\n Router.instance = new Router();\n }\n\n return Router.instance;\n }\n\n private constructor() {\n //\n }\n\n /**\n * Listen to router before scan\n */\n public beforeScanning(callback: (router: Router, server: FastifyInstance) => void) {\n this.eventListeners.beforeScan = [...(this.eventListeners.beforeScan || []), callback];\n\n return this;\n }\n\n /**\n * Listen to router after scanning\n */\n public afterScanning(callback: (router: Router, server: FastifyInstance) => void) {\n this.eventListeners.afterScanning = [...(this.eventListeners.afterScanning || []), callback];\n\n return this;\n }\n\n /**\n * Redirect path to another path\n */\n public redirect(from: string, to: string, redirectMode: \"temporary\" | \"permanent\" = \"temporary\") {\n return this.get(from, (_request, response) => {\n response.redirect(to, redirectMode === \"temporary\" ? 302 : 301);\n });\n }\n\n /**\n * Server static folder\n */\n public directory(options: FastifyStaticOptions) {\n this.staticDirectories.push(options);\n\n return this;\n }\n\n /**\n * Serve file\n */\n public file(path: string, location: string, cacheTime?: number) {\n return this.get(path, (_request, response) => {\n response.sendFile(location, cacheTime);\n });\n }\n\n /**\n * Serve cached file, it will cache the file to 1 year by default\n */\n public cachedFile(path: string, location: string, cacheTime?: number) {\n return this.get(path, (_request, response) => {\n response.sendCachedFile(location, cacheTime);\n });\n }\n\n /**\n * Serve list of files\n */\n public files(files: Record<string, string>, cacheTime?: number) {\n for (const [path, location] of Object.entries(files)) {\n this.get(path, (_request, response) => {\n response.sendFile(location, cacheTime);\n });\n }\n }\n\n /**\n * Serve list of cached files, it will cache the file to 1 year by default\n */\n public cachedFiles(files: Record<string, string>, cacheTime?: number) {\n for (const [path, location] of Object.entries(files)) {\n this.get(path, (_request, response) => {\n response.sendCachedFile(location, cacheTime);\n });\n }\n }\n\n /**\n * Add proxy route\n */\n public proxy(options: FastifyHttpProxyOptions) {\n this.beforeScanning((_router, server) => {\n server.register(proxy, options);\n });\n\n return this;\n }\n\n /**\n * Add route to routes list\n */\n public add(\n method: Route[\"method\"],\n path: string | string[],\n handler: RouteHandlerType,\n options: RouteOptions = {},\n ) {\n if (Array.isArray(path)) {\n path.forEach((p) => this.add(method, p, handler, options));\n return this;\n }\n\n const prefix = this.stacks.prefix.reduce((path, prefix) => {\n return concatRoute(path, prefix);\n }, \"\");\n\n const name = this.stacks.name.reduceRight(\n (name, prefixName) => {\n return trim(prefixName + \".\" + name, \".\");\n },\n options.name || trim(path.replace(/\\//g, \".\"), \".\"),\n );\n\n path = concatRoute(prefix, path);\n\n const middlewarePrecedence = options.middlewarePrecedence || \"after\";\n\n if (middlewarePrecedence === \"before\") {\n options.middleware = [...(options.middleware || []), ...this.stacks.middleware];\n } else {\n options.middleware = [...this.stacks.middleware, ...(options.middleware || [])];\n }\n\n if (Array.isArray(handler)) {\n const [controller, action] = handler;\n\n if (typeof controller[action] !== \"function\") {\n throw new Error(\n `Invalid controller action \"${action}\" for controller \"${controller.constructor.name}\"`,\n );\n }\n\n handler = controller[action].bind(controller) as RouteHandler;\n\n if (!handler.validation) {\n handler.validation = {};\n if (controller[`${action}ValidationSchema`]) {\n handler.validation.schema = controller[`${action}ValidationSchema`]();\n }\n\n if (controller[`${action}Validate`]) {\n handler.validation.validate = controller[`${action}Validate`];\n }\n }\n }\n\n const routeData: Route = {\n method,\n path,\n handler,\n ...options,\n name,\n rateLimit: options.rateLimit,\n $prefix: prefix || \"/\",\n // it must be a new array to avoid modifying the original array\n $prefixStack: [...this.stacks.prefix],\n // Inject source file from stacks if set\n sourceFile: this.stacks.sourceFile || \"\",\n };\n\n if (routeData.name) {\n // check if the name exists\n const route = this.routes.find((route) => route.name === routeData.name);\n\n if (route) {\n // check again if the route name exists with the same method\n if (route.method === routeData.method) {\n throw new Error(`Route name \"${routeData.name}\" already exists`);\n } else {\n routeData.name += `.${routeData.method.toLowerCase()}`;\n }\n }\n }\n\n this.routes.push(routeData);\n\n return this;\n }\n\n /**\n * Add a request that accepts all methods\n */\n public any(path: string, handler: RouteHandlerType, options: RouteOptions = {}) {\n return this.add(\"all\" as Route[\"method\"], path, handler, options);\n }\n\n /**\n * Add get request method\n */\n public get(path: string, handler: RouteHandlerType, options: RouteOptions = {}) {\n return this.add(\"GET\", path, handler, options);\n }\n\n /**\n * Add post request method\n */\n public post(path: string | string[], handler: RouteHandlerType, options: RouteOptions = {}) {\n return this.add(\"POST\", path, handler, options);\n }\n\n /**\n * Add put request method\n */\n public put(path: string, handler: RouteHandlerType, options: RouteOptions = {}) {\n return this.add(\"PUT\", path, handler, options);\n }\n\n /**\n * Add delete request method\n */\n public delete(path: string | string[], handler: RouteHandlerType, options: RouteOptions = {}) {\n return this.add(\"DELETE\", path, handler, options);\n }\n\n /**\n * Add patch request method\n */\n public patch(path: string, handler: RouteHandlerType, options: RouteOptions = {}) {\n return this.add(\"PATCH\", path, handler, options);\n }\n\n /**\n * Add head request method\n */\n public head(path: string, handler: RouteHandlerType, options: RouteOptions = {}) {\n return this.add(\"HEAD\", path, handler, options);\n }\n\n /**\n * Add options request method\n */\n public options(path: string, handler: RouteHandlerType, options: RouteOptions = {}) {\n return this.add(\"OPTIONS\", path, handler, options);\n }\n\n /**\n * Add full restful resource routes\n * This method will generate the following routes:\n * 1. GET /path: list all resources\n * 2. GET /path/:id: get a single resource\n * 3. POST /path: create a new resource\n * 4. PUT /path/:id: update a resource\n * 5. DELETE /path/:id: delete a resource\n * 6. PATCH /path/:id: update a resource partially\n */\n public restfulResource(\n path: string,\n resource: RouteResource,\n options: RouteOptions & {\n only?: ResourceMethod[];\n except?: ResourceMethod[];\n replace?: Partial<Record<ResourceMethod, RouteHandler>> & {\n bulkDelete?: RouteHandler;\n };\n } = {},\n ) {\n return this.prefix(path, () => {\n path = \"\";\n // get base resource name\n const baseResourceName = options.name || toCamelCase(ltrim(path, \"/\"));\n\n // clone the resource so we don't mess up with it\n const routeResource = resource;\n\n const isAcceptableResource = (type: ResourceMethod) => {\n return Boolean(\n // check if the route is not excluded\n (!options.except || !options.except.includes(type)) &&\n // check if the only option is set and the route is included\n (!options.only || options.only.includes(type)),\n );\n };\n\n if (routeResource.list && isAcceptableResource(\"list\")) {\n const resourceName = baseResourceName + \".list\";\n this.get(path, options.replace?.list || routeResource.list.bind(routeResource), {\n ...options,\n name: resourceName,\n restful: true,\n });\n }\n\n if (routeResource.get && isAcceptableResource(\"get\")) {\n const resourceName = baseResourceName + \".single\";\n\n this.get(path + \"/:id\", options.replace?.get || routeResource.get.bind(routeResource), {\n ...options,\n name: resourceName,\n restful: true,\n });\n }\n\n if (routeResource.create && isAcceptableResource(\"create\")) {\n const resourceName = baseResourceName + \".create\";\n\n const handler = options.replace?.create || this.manageValidation(routeResource, \"create\");\n\n this.post(path, handler, {\n ...options,\n name: resourceName,\n restful: true,\n });\n }\n\n if (routeResource.update && isAcceptableResource(\"update\")) {\n const resourceName = baseResourceName + \".update\";\n\n const handler = options.replace?.update || this.manageValidation(routeResource, \"update\");\n\n this.put(path + \"/:id\", handler, {\n ...options,\n name: resourceName,\n restful: true,\n });\n }\n\n if (routeResource.patch && isAcceptableResource(\"patch\")) {\n const resourceName = baseResourceName + \".patch\";\n\n const handler = options.replace?.patch || this.manageValidation(routeResource, \"patch\");\n\n this.patch(path + \"/:id\", handler, {\n ...options,\n name: resourceName,\n restful: true,\n });\n }\n\n if (routeResource.delete && isAcceptableResource(\"delete\")) {\n const resourceName = baseResourceName + \".delete\";\n\n this.delete(\n path + \"/:id\",\n options.replace?.delete || routeResource.delete.bind(routeResource),\n {\n ...options,\n name: resourceName,\n restful: true,\n },\n );\n }\n\n if (routeResource.bulkDelete && isAcceptableResource(\"delete\")) {\n const resourceName = baseResourceName + \".bulkDelete\";\n\n this.delete(\n path,\n options.replace?.bulkDelete || routeResource.bulkDelete.bind(routeResource),\n {\n ...options,\n name: resourceName,\n restful: true,\n },\n );\n }\n\n return this;\n });\n }\n\n /**\n * Group routes with options\n */\n public group(options: GroupedRoutesOptions, callback: RouterGroupCallback) {\n const {\n prefix,\n // name must always be defined because\n // if there are multiple groups without name\n // they might generate the same route name\n // thus causing an error\n // in this case we need always to make sure that\n // the name is always defined.\n name = prefix ? trim(prefix.replace(/\\//g, \".\"), \".\") : undefined,\n middleware,\n } = options;\n\n if (prefix) {\n this.stacks.prefix.push(prefix);\n }\n\n if (name) {\n this.stacks.name.push(name);\n }\n\n if (middleware) {\n this.stacks.middleware.push(...middleware);\n }\n\n callback();\n\n if (prefix) {\n this.stacks.prefix.pop();\n }\n\n if (name) {\n this.stacks.name.pop();\n }\n\n if (middleware) {\n this.stacks.middleware.splice(\n this.stacks.middleware.length - middleware.length,\n middleware.length,\n );\n }\n\n return this;\n }\n\n /**\n * Add prefix to all routes in the given callback\n */\n public prefix(prefix: string, callback: () => void) {\n return this.group({ prefix }, callback);\n }\n\n /**\n * Wrap route additions with a source file path\n * Used for tracking which routes come from which file (for HMR)\n * @param sourceFile Relative path to the source file (e.g., \"src/app/users/routes.ts\")\n * @param callback Function that adds routes (will have sourceFile injected)\n */\n public async withSourceFile<T = any>(\n sourceFile: string,\n callback: () => T | Promise<T>,\n ): Promise<T | undefined> {\n // Set source file in stacks\n this.stacks.sourceFile = sourceFile;\n\n try {\n // Execute callback (routes added here will have sourceFile injected)\n return await callback();\n } catch (error) {\n console.log(\"Error in withSourceFile\", error);\n } finally {\n // Always clear source file from stacks\n delete this.stacks.sourceFile;\n }\n }\n\n /**\n * Remove all routes that belong to a specific source file\n * Used when reloading routes files via HMR\n * @param sourceFile Relative path to the source file\n */\n public removeRoutesBySourceFile(sourceFile: string): void {\n this.routes = this.routes.filter((route) => route.sourceFile !== sourceFile);\n }\n\n /**\n * Manage validation system for the given resource\n */\n private manageValidation(resource: RouteResource, method: \"create\" | \"update\" | \"patch\") {\n const handler = resource[method]?.bind(resource) as RouteHandler;\n\n const methodValidation = resource?.validation?.[method];\n\n if (method === \"patch\") {\n handler.validation = methodValidation;\n\n if (handler.validation?.validate) {\n handler.validation.validate = handler.validation.validate.bind(resource);\n }\n\n if (resource.validation?.patch) {\n handler.validation = merge(resource.validation.patch, handler.validation);\n }\n\n return handler;\n }\n\n if (!resource.validation || (!methodValidation && !resource.validation.all)) return handler;\n\n if (resource.validation.all) {\n const validationMethods = {\n all: resource?.validation?.all?.validate,\n [method]: methodValidation?.validate,\n };\n\n const validation: RouteHandlerValidation = {};\n\n if (resource.validation.all.schema || methodValidation?.schema) {\n if (!methodValidation?.schema && resource.validation.all.schema) {\n // Case 2: Only all.schema exists - clone it for this method\n validation.schema = resource.validation.all.schema;\n } else if (methodValidation?.schema && resource.validation.all.schema) {\n // Case 3: Both exist - merge them (all is base, method overrides)\n validation.schema = resource.validation.all.schema.merge(methodValidation.schema);\n } else if (methodValidation?.schema && !resource.validation.all.schema) {\n // Case 1: Only method schema exists - use it directly\n validation.schema = methodValidation.schema;\n }\n // Case 4: Neither exists - handled by outer if being false\n }\n\n if (validationMethods.all || validationMethods[method]) {\n validation.validate = async (request: Request, response: Response) => {\n if (validationMethods.all) {\n const output = await validationMethods.all.call(resource, request, response);\n\n if (output) return output;\n }\n\n if (validationMethods[method]) {\n return await validationMethods[method]?.call(resource, request, response);\n }\n\n return;\n };\n }\n\n if (!isEmpty(validation)) {\n handler.validation = validation;\n }\n } else {\n handler.validation = resource.validation[method];\n\n if (handler.validation?.validate) {\n handler.validation.validate = handler.validation.validate.bind(resource);\n }\n }\n\n return handler;\n }\n\n /**\n * Get all routes list\n */\n public list() {\n return this.routes;\n }\n\n /**\n * Register routes to the server\n */\n public scan(server: FastifyInstance) {\n this.eventListeners.beforeScan?.forEach((callback) => callback(this, server));\n\n this.routes.forEach((route) => {\n const requestMethod = route.method.toLowerCase();\n const requestMethodFunction = server[requestMethod].bind(server);\n\n const options = {\n ...route.serverOptions,\n config: {\n ...route.serverOptions?.config,\n ...(route.rateLimit && { rateLimit: route.rateLimit }),\n },\n };\n\n requestMethodFunction(\n route.path,\n options,\n async (baseRequest: FastifyRequest, reply: FastifyReply) => {\n const { output, response } = await this.handleRoute(route)(baseRequest, reply);\n\n return output || response.baseResponse;\n },\n );\n });\n\n for (const directoryOptions of this.staticDirectories) {\n server.register(fastifyStatic, {\n ...directoryOptions,\n decorateReply: false,\n });\n }\n\n this.eventListeners.afterScanning?.forEach((callback) => callback(this, server));\n }\n\n /**\n * Scan routes for the development server\n * Uses wildcard routing with find-my-way for HMR support\n */\n public scanDevServer(server: FastifyInstance) {\n this.eventListeners.beforeScan?.forEach((callback) => callback(this, server));\n\n // Shared handler for wildcard routing\n const wildcardHandler = async (fastifyRequest: FastifyRequest, fastifyReply: FastifyReply) => {\n // Initialize route registry once (will be rebuilt on HMR via rebuildRouteRegistry)\n const routeRegistry = new RouteRegistry();\n\n routeRegistry.register(this.routes);\n // Find matching route using find-my-way\n const match = routeRegistry.find(fastifyRequest.method, fastifyRequest.url);\n\n // No match found - return 404\n if (!match) {\n return fastifyReply.code(404).send({\n error: \"Route not found\",\n path: fastifyRequest.url,\n method: fastifyRequest.method,\n });\n }\n\n // Inject extracted params into the request\n fastifyRequest.params = match.params;\n\n try {\n // Call the matched route handler\n const { output, response } = await this.handleRoute(match.route)(\n fastifyRequest,\n fastifyReply,\n );\n\n return output || response.baseResponse;\n } catch (error) {\n console.log(error);\n throw error;\n }\n };\n\n // Register wildcard route for all methods EXCEPT OPTIONS (to avoid conflict with CORS)\n // OPTIONS is handled by @fastify/cors plugin for preflight requests\n const methods = [\"GET\", \"POST\", \"PUT\", \"DELETE\", \"PATCH\"] as const;\n for (const method of methods) {\n server.route({\n method,\n url: \"*\",\n handler: wildcardHandler,\n });\n }\n\n // Register static directories\n for (const directoryOptions of this.staticDirectories) {\n server.register(fastifyStatic, {\n ...directoryOptions,\n decorateReply: false,\n });\n }\n\n this.eventListeners.afterScanning?.forEach((callback) => callback(this, server));\n }\n\n /**\n * Get the route path for the given route name\n */\n public route(name: string, params: any = {}) {\n const route = this.routes.find((route) => route.name === name);\n\n if (!route) {\n throw new Error(`Route name \"${name}\" not found`);\n }\n\n let path = route.path;\n\n if (route.path.includes(\":\")) {\n Object.keys(params).forEach((key) => {\n path = path.replace(\":\" + key, params[key]);\n });\n }\n\n return path;\n }\n\n /**\n * Handle the given route\n */\n private handleRoute(route: Route) {\n return async (fastifyRequest: FastifyRequest, fastifyResponse: FastifyReply) => {\n const request = new Request();\n const response = new Response();\n response.setResponse(fastifyResponse);\n request.response = response;\n\n response.request = request;\n\n request.setRequest(fastifyRequest).setRoute(route);\n\n Request.current = request;\n\n log.info({\n module: \"route\",\n action: route.method + \" \" + route.path.replace(\"/*\", \"\"),\n message: `Starting Request: ${request.id}`,\n context: {\n request,\n response,\n },\n });\n\n const result = await request.execute();\n\n return {\n output: result,\n response,\n request,\n };\n };\n }\n}\n\nexport const router = Router.getInstance();\n","import { url } from \"../utils/urls\";\r\nimport { router } from \"./router\";\r\n\r\n/**\r\n * Generate a url for the given route name\r\n */\r\nexport function route(name: string, params: any = {}) {\r\n return url(router.route(name, params));\r\n}\r\n","import type { FastifyCorsOptions } from \"@fastify/cors\";\r\nimport fastifyMultipart from \"@fastify/multipart\";\r\nimport config from \"@mongez/config\";\r\nimport { rootPath } from \"../utils\";\r\nimport type { FastifyInstance } from \"./server\";\r\n\r\nconst defaultCorsOptions: FastifyCorsOptions = {\r\n origin: \"*\",\r\n methods: \"*\",\r\n};\r\n\r\nexport async function registerHttpPlugins(server: FastifyInstance) {\r\n // 👇🏻 register rate-limit plugin\r\n server.register(import(\"@fastify/rate-limit\"), {\r\n // max requests per time window\r\n max: config.get(\"http.rateLimit.max\", 60),\r\n // maximum time that is will allow max requests\r\n timeWindow: config.get(\"http.rateLimit.duration\", 60 * 1000),\r\n });\r\n\r\n // 👇🏻 register cors plugin\r\n const corsOptions: FastifyCorsOptions | undefined = {\r\n ...config.get(\"http.cors\", {}),\r\n ...defaultCorsOptions,\r\n };\r\n\r\n server.register(import(\"@fastify/cors\"), corsOptions);\r\n\r\n // 👇🏻 import multipart plugin\r\n server.register(fastifyMultipart, {\r\n attachFieldsToBody: true,\r\n limits: {\r\n // file size could be up to 10MB\r\n fileSize: config.get(\"http.fileUploadLimit\", 10 * 1024 * 1024),\r\n },\r\n });\r\n\r\n server.register(import(\"@fastify/static\"), {\r\n root: rootPath(\"public\"),\r\n prefix: \"/public/\",\r\n });\r\n}\r\n","import Fastify 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 startServer() {\r\n return (server = Fastify({\r\n trustProxy: true,\r\n // logger: true,\r\n bodyLimit: 200 * 1024 * 1024 * 1024, // 200GB\r\n }));\r\n}\r\n\r\n/**\r\n * Expose the server to be publicly accessible\r\n */\r\nexport function getServer() {\r\n return server;\r\n}\r\n","import config from \"@mongez/config\";\r\nimport { log } from \"@warlock.js/logger\";\r\nimport { router } from \"../router\";\r\nimport { setBaseUrl } from \"../utils/urls\";\r\nimport { httpConfig } from \"./config\";\r\nimport { registerHttpPlugins } from \"./plugins\";\r\nimport { getServer, startServer } from \"./server\";\r\n\r\nexport async function createHttpApplication() {\r\n const server = startServer();\r\n\r\n await registerHttpPlugins(server);\r\n\r\n router.scan(server);\r\n\r\n const port = httpConfig(\"port\");\r\n\r\n try {\r\n log.info(\"http\", \"server\", \"Connecting to the server\");\r\n // 👇🏻 We can use the url of the server\r\n await server.listen({\r\n port,\r\n host: httpConfig(\"host\"),\r\n });\r\n\r\n const baseUrl = config.get(\"app.baseUrl\");\r\n\r\n // update base url\r\n setBaseUrl(baseUrl);\r\n\r\n log.success(\"http\", \"server\", `Server is listening on ${baseUrl}`);\r\n } catch (error) {\r\n log.error(\"http\", \"server\", error);\r\n\r\n process.exit(1); // stop the process, exit with error\r\n }\r\n}\r\n\r\nexport async function stopHttpApplication() {\r\n log.info(\"http\", \"server\", \"Stopping the server\");\r\n const server = getServer();\r\n\r\n await server?.close();\r\n\r\n log.success(\"http\", \"server\", \"Server is stopped\");\r\n}\r\n","import { Model } from \"@warlock.js/cascade\";\r\nimport { type Infer, v } from \"@warlock.js/seal\";\r\n\r\nconst schema = v.object({\r\n statusCode: v.number(),\r\n responseTime: v.number(),\r\n responseSize: v.number(),\r\n responseBody: v.record(v.any()),\r\n responseHeaders: v.record(v.any()),\r\n ip: v.string(),\r\n method: v.string(),\r\n route: v.string(),\r\n requestHeaders: v.record(v.any()),\r\n userAgent: v.string(),\r\n referer: v.string(),\r\n requestBody: v.record(v.any()),\r\n requestParams: v.record(v.any()),\r\n requestQuery: v.record(v.any()),\r\n});\r\n\r\ntype RequestLogSchema = Infer<typeof schema>;\r\n\r\nexport class RequestLog extends Model<RequestLogSchema> {\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public static table = \"request_logs\";\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public static schema = schema;\r\n}\r\n","import { RequestLog } from \"./database/RequestLog\";\r\nimport type { Response } from \"./response\";\r\n\r\nexport function logResponse(response: Response) {\r\n const request = response.request;\r\n RequestLog.create({\r\n statusCode: response.statusCode,\r\n responseTime: response.getResponseTime(),\r\n responseSize: response.getHeader(\"Content-Length\"),\r\n responseBody: response.body,\r\n responseHeaders: response.getHeaders(),\r\n ip: request.ip,\r\n method: request.route.method,\r\n route: request.route.path,\r\n requestHeaders: request.headers,\r\n userAgent: request.userAgent,\r\n referer: request.referer,\r\n // requestBody: request.bodyInputs,\r\n requestParams: request.params,\r\n requestQuery: request.query,\r\n });\r\n}\r\n\r\nexport function wrapResponseInDataKey(response: Response) {\r\n if (typeof response.body === \"string\") return;\r\n\r\n if (response.body) {\r\n response.body = { data: response.body };\r\n }\r\n}\r\n","import type { RequestControllerContract } from \"./../router/types\";\r\nimport type { Request } from \"./request\";\r\nimport type { Response } from \"./response\";\r\nimport type { ReturnedResponse } from \"./types\";\r\n\r\nexport abstract class RequestController implements RequestControllerContract {\r\n public constructor(\r\n public readonly request: Request,\r\n public readonly response: Response,\r\n ) {\r\n //\r\n }\r\n\r\n public abstract execute(): Promise<ReturnedResponse>;\r\n}\r\n","import { except } from \"@mongez/reinforcements\";\r\nimport { cache } from \"@warlock.js/cache\";\r\nimport type { Request } from \"./../request\";\r\nimport type { Response } from \"./../response\";\r\n\r\n// TODO: Add option to determine whether to cache the response or not\r\n// TODO: add option to determine what to be cached from the response\r\n// TODO: add cache middleware config options for example to set the default driver, ttl, etc\r\n\r\nexport type CacheMiddlewareOptions = {\r\n /**\r\n * Cache key\r\n */\r\n cacheKey:\r\n | string\r\n | ((request: Request) => string)\r\n | ((request: Request) => Promise<string>);\r\n /**\r\n * If true, then the response will be cached based on the current locale code\r\n * This is useful when you have a multi-language website, and you want to cache the response based on the current locale\r\n *\r\n * @default true\r\n */\r\n withLocale?: boolean;\r\n /**\r\n * List of keys from the response object to omit from the cached response\r\n *\r\n * @default ['user']\r\n */\r\n omit?: string[];\r\n /**\r\n * Expires after number of seconds\r\n */\r\n ttl?: number;\r\n /**\r\n * Cache driver\r\n *\r\n * @see config/cache.ts: drivers object\r\n * @default cache manager\r\n */\r\n driver?: string;\r\n};\r\n\r\nconst defaultCacheOptions: Partial<CacheMiddlewareOptions> = {\r\n withLocale: true,\r\n};\r\n\r\ntype ParsedCacheOptions = Required<CacheMiddlewareOptions> & {\r\n cacheKey: string;\r\n};\r\n\r\nasync function parseCacheOptions(\r\n cacheOptions: CacheMiddlewareOptions | string,\r\n request: Request,\r\n) {\r\n if (typeof cacheOptions === \"string\") {\r\n cacheOptions = {\r\n cacheKey: cacheOptions,\r\n };\r\n }\r\n\r\n if (typeof cacheOptions.cacheKey === \"function\") {\r\n cacheOptions.cacheKey = await cacheOptions.cacheKey(request);\r\n }\r\n\r\n const finalCacheOptions = {\r\n ...defaultCacheOptions,\r\n ...cacheOptions,\r\n } as ParsedCacheOptions;\r\n\r\n if (finalCacheOptions.withLocale) {\r\n const locale = request.getLocaleCode();\r\n\r\n finalCacheOptions.cacheKey = `${finalCacheOptions.cacheKey}:${locale}`;\r\n }\r\n\r\n if (!finalCacheOptions.omit) {\r\n finalCacheOptions.omit = [\"user\", \"settings\"];\r\n }\r\n\r\n return finalCacheOptions;\r\n}\r\n\r\nexport function cacheMiddleware(\r\n responseCacheOptions: CacheMiddlewareOptions | string,\r\n) {\r\n return async function (request: Request, response: Response) {\r\n const { ttl, omit, cacheKey, driver } = await parseCacheOptions(\r\n responseCacheOptions,\r\n request,\r\n );\r\n const cacheDriver = driver ? await cache.use(driver) : cache;\r\n\r\n const content = await cacheDriver.get(cacheKey);\r\n\r\n if (content) {\r\n const output = content.data;\r\n\r\n return response.baseResponse.send(output);\r\n }\r\n\r\n response.onSent((response: Response) => {\r\n if (!response.isOk || response.request.path !== request.path) {\r\n return;\r\n }\r\n\r\n const content = {\r\n data: except(response.parsedBody, omit),\r\n };\r\n\r\n cacheDriver.set(cacheKey, content, ttl);\r\n });\r\n };\r\n}\r\n","import { invalidRule, VALID_RULE, type SchemaRule } from \"@warlock.js/seal\";\r\nimport { useRequestStore } from \"../../http\";\r\nimport type { ExistsExceptCurrentIdRuleOptions } from \"../types\";\r\n\r\n/**\r\n * Exists except current ID rule\r\n */\r\nexport const existsExceptCurrentIdRule: SchemaRule<ExistsExceptCurrentIdRuleOptions> = {\r\n name: \"existsExceptCurrentId\",\r\n defaultErrorMessage: \"The :input must exist\",\r\n async validate(value: any, context) {\r\n const {\r\n Model,\r\n query,\r\n column = context.key,\r\n exceptCurrentIdColumn = \"id\",\r\n } = this.context.options;\r\n\r\n const { request } = useRequestStore();\r\n\r\n const dbQuery = Model.query();\r\n\r\n dbQuery.where(column, value);\r\n dbQuery.where(exceptCurrentIdColumn, \"!=\", request.int(\"id\"));\r\n\r\n if (query) {\r\n await query({\r\n query: dbQuery,\r\n value,\r\n allValues: context.allValues,\r\n });\r\n }\r\n\r\n const document = await dbQuery.first();\r\n return document ? VALID_RULE : invalidRule(this, context);\r\n },\r\n};\r\n","import { invalidRule, VALID_RULE, type SchemaRule } from \"@warlock.js/seal\";\r\nimport { useRequestStore } from \"../../http\";\r\nimport type { ExistsExceptCurrentUserRuleOptions } from \"../types\";\r\n\r\n/**\r\n * Exists except current user rule\r\n */\r\nexport const existsExceptCurrentUserRule: SchemaRule<ExistsExceptCurrentUserRuleOptions> = {\r\n name: \"existsExceptCurrentUser\",\r\n defaultErrorMessage: \"The :input must exist\",\r\n async validate(value: any, context) {\r\n const {\r\n Model,\r\n query,\r\n column = context.key,\r\n exceptCurrentUserColumn = \"id\",\r\n exceptCurrentUserValue = \"id\",\r\n } = this.context.options;\r\n\r\n const { user } = useRequestStore();\r\n\r\n const dbQuery = Model.query();\r\n\r\n dbQuery.where(column, value);\r\n\r\n if (user) {\r\n dbQuery.where(exceptCurrentUserColumn, \"!=\", user.get(exceptCurrentUserValue));\r\n }\r\n\r\n if (query) {\r\n await query({\r\n query: dbQuery,\r\n value,\r\n allValues: context.allValues,\r\n });\r\n }\r\n\r\n const document = await dbQuery.first();\r\n return document ? VALID_RULE : invalidRule(this, context);\r\n },\r\n};\r\n","import { get } from \"@mongez/reinforcements\";\r\nimport { invalidRule, VALID_RULE, type SchemaRule } from \"@warlock.js/seal\";\r\nimport type { UniqueRuleOptions } from \"../types\";\r\n\r\n/**\r\n * Unique rule - validates value is unique in database\r\n */\r\nexport const uniqueRule: SchemaRule<UniqueRuleOptions> = {\r\n name: \"unique\",\r\n defaultErrorMessage: \"The :input must be unique\",\r\n async validate(value: any, context) {\r\n const {\r\n Model,\r\n except,\r\n column = context.key,\r\n exceptColumnName,\r\n exceptValue,\r\n query,\r\n } = this.context.options;\r\n\r\n const dbQuery = Model.query();\r\n\r\n dbQuery.where(column, value);\r\n\r\n if (except) {\r\n const exceptVal = get(context.allValues, except);\r\n if (exceptVal !== undefined) {\r\n dbQuery.where(except, \"!=\", exceptVal);\r\n }\r\n }\r\n\r\n if (exceptColumnName !== undefined) {\r\n dbQuery.where(exceptColumnName, \"!=\", exceptValue);\r\n }\r\n\r\n if (query) {\r\n await query({\r\n query: dbQuery,\r\n value,\r\n allValues: context.allValues,\r\n });\r\n }\r\n\r\n const document = await dbQuery.first();\r\n\r\n return document ? invalidRule(this, context) : VALID_RULE;\r\n },\r\n};\r\n","import { invalidRule, VALID_RULE, type SchemaRule } from \"@warlock.js/seal\";\r\nimport { useRequestStore } from \"../../http\";\r\nimport type { UniqueExceptCurrentIdRuleOptions } from \"../types\";\r\n/**\r\n * Unique except current ID rule\r\n */\r\nexport const uniqueExceptCurrentIdRule: SchemaRule<UniqueExceptCurrentIdRuleOptions> = {\r\n name: \"uniqueExceptCurrentId\",\r\n defaultErrorMessage: \"The :input must be unique\",\r\n async validate(value: any, context) {\r\n const {\r\n Model,\r\n column = context.key,\r\n exceptCurrentIdColumn = \"id\",\r\n query,\r\n } = this.context.options;\r\n\r\n const { request } = useRequestStore();\r\n\r\n const dbQuery = Model.query();\r\n\r\n dbQuery.where(column, value);\r\n dbQuery.where(exceptCurrentIdColumn, \"!=\", request.int(\"id\"));\r\n\r\n if (query) {\r\n await query({\r\n query: dbQuery,\r\n value,\r\n allValues: context.allValues,\r\n });\r\n }\r\n\r\n const document = await dbQuery.first();\r\n return document ? invalidRule(this, context) : VALID_RULE;\r\n },\r\n};\r\n","import { invalidRule, VALID_RULE, type SchemaRule } from \"@warlock.js/seal\";\r\nimport { useRequestStore } from \"../../http\";\r\nimport type { UniqueExceptCurrentUserRuleOptions } from \"../types\";\r\n\r\n/**\r\n * Unique except current user rule\r\n */\r\nexport const uniqueExceptCurrentUserRule: SchemaRule<UniqueExceptCurrentUserRuleOptions> = {\r\n name: \"uniqueExceptCurrentUser\",\r\n defaultErrorMessage: \"The :input must be unique\",\r\n async validate(value: any, context) {\r\n const {\r\n Model,\r\n column = context.key,\r\n exceptCurrentUserColumn = \"id\",\r\n exceptCurrentUserValue = \"id\",\r\n query,\r\n } = this.context.options;\r\n\r\n const { user } = useRequestStore();\r\n\r\n const dbQuery = Model.query();\r\n\r\n dbQuery.where(column, value);\r\n\r\n if (user) {\r\n dbQuery.where(exceptCurrentUserColumn, \"!=\", user.get(exceptCurrentUserValue));\r\n }\r\n\r\n if (query) {\r\n await query({\r\n query: dbQuery,\r\n value,\r\n allValues: context.allValues,\r\n });\r\n }\r\n\r\n const document = await dbQuery.first();\r\n return document ? invalidRule(this, context) : VALID_RULE;\r\n },\r\n};\r\n","/**\r\n * Database Validation Plugin\r\n *\r\n * Adds database validation methods to Seal validators:\r\n * - unique() - Check uniqueness in database\r\n * - exists() - Verify record exists\r\n * - And variants (exceptCurrentUser, exceptCurrentId)\r\n */\r\n\r\nimport type { ChildModel, Model } from \"@warlock.js/cascade\";\r\nimport type { SealPlugin } from \"@warlock.js/seal\";\r\nimport { NumberValidator, ScalarValidator, StringValidator } from \"@warlock.js/seal\";\r\nimport type {\r\n ExistsExceptCurrentIdRuleOptions,\r\n ExistsExceptCurrentUserRuleOptions,\r\n ExistsRuleOptions,\r\n UniqueExceptCurrentIdRuleOptions,\r\n UniqueExceptCurrentUserRuleOptions,\r\n UniqueRuleOptions,\r\n} from \"../database\";\r\nimport {\r\n existsExceptCurrentIdRule,\r\n existsExceptCurrentUserRule,\r\n existsRule,\r\n uniqueExceptCurrentIdRule,\r\n uniqueExceptCurrentUserRule,\r\n uniqueRule,\r\n} from \"../database\";\r\n\r\n/**\r\n * Database validation plugin for Seal\r\n */\r\nexport const databasePlugin: SealPlugin = {\r\n name: \"database\",\r\n version: \"1.0.0\",\r\n description: \"Adds database validation methods (unique, exists) to validators\",\r\n\r\n install() {\r\n // Inject database methods into ScalarValidator\r\n Object.assign(ScalarValidator.prototype, {\r\n /** Value must be unique in database */\r\n unique(\r\n this: ScalarValidator,\r\n model: ChildModel<Model>,\r\n optionsList?: Partial<UniqueRuleOptions> & {\r\n errorMessage?: string;\r\n },\r\n ) {\r\n const { errorMessage, ...options } = optionsList || {};\r\n const rule = this.addRule(uniqueRule, errorMessage);\r\n rule.context.options = {\r\n ...options,\r\n Model: model,\r\n };\r\n return this;\r\n },\r\n\r\n /** Value must be unique in database except current user */\r\n uniqueExceptCurrentUser(\r\n this: ScalarValidator,\r\n model: ChildModel<Model>,\r\n optionsList?: Partial<UniqueExceptCurrentUserRuleOptions> & {\r\n errorMessage?: string;\r\n },\r\n ) {\r\n const { errorMessage, ...options } = optionsList || {};\r\n const rule = this.addRule(uniqueExceptCurrentUserRule, errorMessage);\r\n rule.context.options = {\r\n ...options,\r\n Model: model,\r\n };\r\n return this;\r\n },\r\n\r\n /** Value must be unique in database except current id */\r\n uniqueExceptCurrentId(\r\n this: ScalarValidator,\r\n model: ChildModel<Model>,\r\n optionsList?: Partial<UniqueExceptCurrentIdRuleOptions> & {\r\n errorMessage?: string;\r\n },\r\n ) {\r\n const { errorMessage, ...options } = optionsList || {};\r\n const rule = this.addRule(uniqueExceptCurrentIdRule, errorMessage);\r\n rule.context.options = {\r\n ...options,\r\n Model: model,\r\n };\r\n return this;\r\n },\r\n\r\n /** Value must exist in database */\r\n exists(\r\n this: ScalarValidator,\r\n model: ChildModel<Model>,\r\n optionsList?: Partial<ExistsRuleOptions> & {\r\n errorMessage?: string;\r\n },\r\n ) {\r\n const { errorMessage, ...options } = optionsList || {};\r\n const rule = this.addRule(existsRule, errorMessage);\r\n rule.context.options = {\r\n ...options,\r\n Model: model,\r\n };\r\n return this;\r\n },\r\n\r\n /** Value must exist in database except current user */\r\n existsExceptCurrentUser(\r\n this: ScalarValidator,\r\n model: ChildModel<Model>,\r\n optionsList?: Partial<ExistsExceptCurrentUserRuleOptions> & {\r\n errorMessage?: string;\r\n },\r\n ) {\r\n const { errorMessage, ...options } = optionsList || {};\r\n const rule = this.addRule(existsExceptCurrentUserRule, errorMessage);\r\n rule.context.options = {\r\n ...options,\r\n Model: model,\r\n };\r\n return this;\r\n },\r\n\r\n /** Value must exists in database except current id */\r\n existsExceptCurrentId(\r\n this: ScalarValidator,\r\n model: ChildModel<Model>,\r\n optionsList?: Partial<ExistsExceptCurrentIdRuleOptions> & {\r\n errorMessage?: string;\r\n },\r\n ) {\r\n const { errorMessage, ...options } = optionsList || {};\r\n const rule = this.addRule(existsExceptCurrentIdRule, errorMessage);\r\n rule.context.options = {\r\n ...options,\r\n Model: model,\r\n };\r\n return this;\r\n },\r\n });\r\n\r\n // Inject database methods into StringValidator\r\n Object.assign(StringValidator.prototype, {\r\n unique: ScalarValidator.prototype.unique,\r\n uniqueExceptCurrentUser: ScalarValidator.prototype.uniqueExceptCurrentUser,\r\n uniqueExceptCurrentId: ScalarValidator.prototype.uniqueExceptCurrentId,\r\n exists: ScalarValidator.prototype.exists,\r\n existsExceptCurrentUser: ScalarValidator.prototype.existsExceptCurrentUser,\r\n existsExceptCurrentId: ScalarValidator.prototype.existsExceptCurrentId,\r\n });\r\n\r\n // Inject database methods into NumberValidator\r\n Object.assign(NumberValidator.prototype, {\r\n unique: ScalarValidator.prototype.unique,\r\n exists: ScalarValidator.prototype.exists,\r\n });\r\n },\r\n};\r\n","import { invalidRule, VALID_RULE, type SchemaRule } from \"@warlock.js/seal\";\r\nimport { UploadedFile } from \"../../http\";\r\n\r\n/**\r\n * File rule - validates uploaded file\r\n */\r\nexport const fileRule: SchemaRule = {\r\n name: \"file\",\r\n defaultErrorMessage: \"The :input must be a file\",\r\n async validate(value: any, context) {\r\n if (value instanceof UploadedFile) {\r\n return VALID_RULE;\r\n }\r\n return invalidRule(this, context);\r\n },\r\n};\r\n\r\n/**\r\n * Image rule - validates uploaded image\r\n */\r\nexport const imageRule: SchemaRule = {\r\n name: \"image\",\r\n defaultErrorMessage: \"The :input must be an image\",\r\n async validate(value: any, context) {\r\n if (value instanceof UploadedFile && value.isImage) {\r\n return VALID_RULE;\r\n }\r\n\r\n return invalidRule(this, context);\r\n },\r\n};\r\n\r\n/**\r\n * File extension rule - validates file extension\r\n */\r\nexport const fileExtensionRule: SchemaRule<{\r\n extensions: string | string[];\r\n}> = {\r\n name: \"fileExtension\",\r\n errorMessage: \"The :input must have one of the following extensions: :extensions\",\r\n async validate(value: any, context) {\r\n let extensions = this.context.options.extensions;\r\n\r\n if (typeof extensions === \"string\") {\r\n extensions = [extensions];\r\n }\r\n\r\n if (extensions.includes(value.extension)) {\r\n return VALID_RULE;\r\n }\r\n\r\n return invalidRule(this, context);\r\n },\r\n};\r\n\r\n/**\r\n * File type rule - validates MIME type\r\n */\r\nexport const fileTypeRule: SchemaRule<{ mimeTypes: string | string[] }> = {\r\n name: \"fileType\",\r\n defaultErrorMessage: \"The :input must be a :types file\",\r\n async validate(value: any, context) {\r\n let mimeTypes = this.context.options.mimeTypes;\r\n\r\n if (typeof mimeTypes === \"string\") {\r\n mimeTypes = [mimeTypes];\r\n }\r\n\r\n if (mimeTypes.includes(value.mimeType)) {\r\n return VALID_RULE;\r\n }\r\n\r\n return invalidRule(this, context);\r\n },\r\n};\r\n","import type { FileSizeOption } from \"@warlock.js/seal\";\r\nimport {\r\n BaseValidator,\r\n maxFileSizeRule,\r\n maxHeightRule,\r\n maxWidthRule,\r\n minFileSizeRule,\r\n minHeightRule,\r\n minWidthRule,\r\n resolveFileSize,\r\n v,\r\n} from \"@warlock.js/seal\";\r\nimport { UploadedFile } from \"../../http\";\r\nimport { fileExtensionRule, fileRule, fileTypeRule, imageRule } from \"../file\";\r\n\r\nexport const uploadedFileMetadataSchema = v.object({\r\n location: v.string().oneOf([\"local\", \"cloud\"]),\r\n width: v.int().positive(),\r\n height: v.int().positive(),\r\n size: v.int().positive(),\r\n mimeType: v.string(),\r\n extension: v.string(),\r\n name: v.string(),\r\n});\r\n\r\n/**\r\n * File validator class\r\n */\r\nexport class FileValidator extends BaseValidator {\r\n public constructor(errorMessage?: string) {\r\n super();\r\n this.addRule(fileRule, errorMessage);\r\n }\r\n\r\n /**\r\n * Check if value is a File type\r\n */\r\n public matchesType(value: any): boolean {\r\n return value instanceof UploadedFile;\r\n }\r\n\r\n /** Value must be an image */\r\n public image(errorMessage?: string) {\r\n this.addRule(imageRule, errorMessage);\r\n return this;\r\n }\r\n\r\n /** Accept specific file extensions */\r\n public accept(extensions: string | string[], errorMessage?: string) {\r\n const rule = this.addRule(fileExtensionRule, errorMessage);\r\n rule.context.options.extensions = extensions;\r\n return this;\r\n }\r\n\r\n /** Allow specific MIME types */\r\n public mimeType(mimeTypes: string | string[], errorMessage?: string) {\r\n const rule = this.addRule(fileTypeRule, errorMessage);\r\n rule.context.options.mimeTypes = mimeTypes;\r\n return this;\r\n }\r\n\r\n /** Allow only pdf files */\r\n public pdf(errorMessage?: string) {\r\n return this.mimeType(\"application/pdf\", errorMessage);\r\n }\r\n\r\n /** Allow only excel files */\r\n public excel(errorMessage?: string) {\r\n return this.mimeType(\r\n [\r\n \"application/vnd.ms-excel\",\r\n \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\r\n ],\r\n errorMessage,\r\n );\r\n }\r\n\r\n /** Allow only word files */\r\n public word(errorMessage?: string) {\r\n return this.mimeType(\r\n [\r\n \"application/msword\",\r\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\r\n ],\r\n errorMessage,\r\n );\r\n }\r\n\r\n /** Minimum file size */\r\n public minSize(size: number | FileSizeOption, errorMessage?: string) {\r\n const rule = this.addRule(minFileSizeRule, errorMessage);\r\n rule.context.options.minSize = resolveFileSize(size);\r\n return this;\r\n }\r\n\r\n /** @alias minSize */\r\n public min(size: number | FileSizeOption, errorMessage?: string) {\r\n return this.minSize(size, errorMessage);\r\n }\r\n\r\n /** Maximum file size */\r\n public maxSize(size: number | FileSizeOption, errorMessage?: string) {\r\n const rule = this.addRule(maxFileSizeRule, errorMessage);\r\n rule.context.options.maxSize = resolveFileSize(size);\r\n return this;\r\n }\r\n\r\n /** @alias maxSize */\r\n public max(size: number, errorMessage?: string) {\r\n return this.maxSize(size, errorMessage);\r\n }\r\n\r\n /** Minimum image width */\r\n public minWidth(width: number, errorMessage?: string) {\r\n const rule = this.addRule(minWidthRule, errorMessage);\r\n rule.context.options.minWidth = width;\r\n return this;\r\n }\r\n\r\n /** Maximum image width */\r\n public maxWidth(width: number, errorMessage?: string) {\r\n const rule = this.addRule(maxWidthRule, errorMessage);\r\n rule.context.options.maxWidth = width;\r\n return this;\r\n }\r\n\r\n /** Minimum image height */\r\n public minHeight(height: number, errorMessage?: string) {\r\n const rule = this.addRule(minHeightRule, errorMessage);\r\n rule.context.options.minHeight = height;\r\n return this;\r\n }\r\n\r\n /** Maximum image height */\r\n public maxHeight(height: number, errorMessage?: string) {\r\n const rule = this.addRule(maxHeightRule, errorMessage);\r\n rule.context.options.maxHeight = height;\r\n return this;\r\n }\r\n\r\n /**\r\n * Save the file and return it as a string\r\n */\r\n public saveTo(relativeDirectory: string) {\r\n return this.addTransformer(async (file: UploadedFile) => {\r\n const output = await file.save(relativeDirectory);\r\n\r\n return output.path;\r\n });\r\n }\r\n}\r\n","/**\r\n * File Validator Plugin\r\n *\r\n * Adds file validation to Seal v factory\r\n */\r\n\r\nimport type { SealPlugin } from \"@warlock.js/seal\";\r\nimport { v } from \"@warlock.js/seal\";\r\nimport { FileValidator } from \"../validators\";\r\n\r\n/**\r\n * File validation plugin for Seal\r\n */\r\nexport const filePlugin: SealPlugin = {\r\n name: \"file\",\r\n version: \"1.0.0\",\r\n description: \"Adds file upload validation (v.file())\",\r\n\r\n install() {\r\n // Inject file() method into v factory\r\n v.file = (errorMessage?: string) => new FileValidator(errorMessage);\r\n },\r\n};\r\n","/**\r\n * Localized Validator Plugin\r\n *\r\n * Adds localized() method to Seal v factory\r\n */\r\n\r\nimport type {\r\n ArrayValidator,\r\n BaseValidator,\r\n SealPlugin,\r\n} from \"@warlock.js/seal\";\r\nimport { v } from \"@warlock.js/seal\";\r\n\r\ntype LocalizedReturn = ArrayValidator & {\r\n validator: BaseValidator;\r\n};\r\n\r\n/**\r\n * Localized validation plugin for Seal\r\n */\r\nexport const localizedPlugin: SealPlugin = {\r\n name: \"localized\",\r\n version: \"1.0.0\",\r\n description: \"Adds localized validation (v.localized())\",\r\n\r\n install() {\r\n v.localized = (\r\n valueValidator?: BaseValidator,\r\n errorMessage?: string,\r\n ): LocalizedReturn =>\r\n v.array(\r\n v.object({\r\n localeCode: v.string().required(),\r\n value: valueValidator || v.scalar(),\r\n }),\r\n errorMessage,\r\n ) as LocalizedReturn;\r\n },\r\n};\r\n","/**\r\n * Initialize Seal with Warlock Framework Settings\r\n *\r\n * This file configures Seal to use Warlock's localization system\r\n */\r\n\r\n// Auto-register framework plugins\r\nimport { configureSeal, registerPlugin } from \"@warlock.js/seal\";\r\nimport { config } from \"../config\";\r\nimport { t } from \"../http/middleware/inject-request-context\";\r\nimport { databasePlugin, filePlugin, localizedPlugin } from \"./plugins\";\r\n\r\n// Configure Seal to use Warlock's localization\r\nconfigureSeal({\r\n firstErrorOnly: config.key(\"validation.firstErrorOnly\", true),\r\n translateRule({ rule, attributes }) {\r\n const translateRule = config.key(\"validation.translateRule\");\r\n if (translateRule) {\r\n return translateRule({ rule, attributes });\r\n }\r\n\r\n const translationGroup = config.key(\"validation.translationGroup\", \"validation\");\r\n\r\n const translationKey = `${translationGroup}.${rule.name}`;\r\n const translation = t(translationKey, attributes);\r\n\r\n return translation === translationKey\r\n ? rule.errorMessage || rule.defaultErrorMessage\r\n : translation;\r\n },\r\n\r\n translateAttribute({ attribute, context, rule }) {\r\n const translateAttribute = config.key(\"validation.translateAttribute\");\r\n\r\n if (translateAttribute) {\r\n return translateAttribute({ attribute, context, rule });\r\n }\r\n\r\n const attributeGroup = config.key(\"validation.attributeGroup\") ?? \"attributes\";\r\n\r\n const translationKey = `${attributeGroup ? attributeGroup + \".\" : \"\"}${attribute}`;\r\n\r\n const output = t(translationKey, context.allValues);\r\n return output === translationKey ? attribute : output;\r\n },\r\n});\r\n\r\n// Register plugins to inject methods\r\nregisterPlugin(databasePlugin);\r\nregisterPlugin(filePlugin);\r\nregisterPlugin(localizedPlugin);\r\n","import { loadEnv } from \"@mongez/dotenv\";\nimport { initializeDayjs } from \"@mongez/time-wizard\";\nimport { captureAnyUnhandledRejection } from \"@warlock.js/logger\";\n\nexport async function bootstrap() {\n await loadEnv();\n\n initializeDayjs();\n captureAnyUnhandledRejection();\n}\n","import { colors } from \"@mongez/copper\";\r\nimport { environment } from \"../utils\";\r\n\r\nexport function displayEnvironmentMode() {\r\n const env = environment();\r\n\r\n const envColor = (env: string) => {\r\n switch (env) {\r\n case \"development\":\r\n return colors.yellow(env);\r\n case \"production\":\r\n return colors.green(env);\r\n case \"test\":\r\n return colors.magentaBright(env);\r\n }\r\n };\r\n\r\n console.log(\r\n colors.blueBright(\"ℹ\"),\r\n colors.yellow(`(${new Date().toISOString()})`),\r\n colors.orange(\"[warlock]\"),\r\n colors.magenta(`bootstrap`),\r\n colors.blueBright(`Starting application in ${envColor(env)} mode`),\r\n );\r\n}\r\n","import {\r\n BaseCacheDriver,\r\n type CacheData,\r\n type CacheDriver,\r\n type CacheKey,\r\n} from \"@warlock.js/cache\";\r\nimport { Model } from \"@warlock.js/cascade\";\r\n\r\nexport type DatabaseCacheOptions = {\r\n /**\r\n * Database model class\r\n */\r\n model?: typeof CacheModel;\r\n /**\r\n * Global prefix for the cache key\r\n */\r\n globalPrefix?: string | (() => string);\r\n /**\r\n * The default TTL for the cache in seconds\r\n *\r\n * @default Infinity\r\n */\r\n ttl?: number;\r\n};\r\n\r\nexport class CacheModel extends Model {\r\n public static table = \"cache\";\r\n}\r\n\r\nexport class DatabaseCacheDriver\r\n extends BaseCacheDriver<DatabaseCacheDriver, DatabaseCacheOptions>\r\n implements CacheDriver<DatabaseCacheDriver, DatabaseCacheOptions>\r\n{\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public name = \"database\";\r\n\r\n /**\r\n * Database model class\r\n */\r\n public model!: typeof CacheModel;\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public setOptions(options: DatabaseCacheOptions) {\r\n super.setOptions(options);\r\n\r\n this.model = options.model ?? CacheModel;\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public async removeNamespace(namespace: string) {\r\n this.log(\"clearing\", namespace);\r\n\r\n namespace = this.parseKey(namespace);\r\n\r\n await this.model.delete({\r\n namespace,\r\n });\r\n\r\n this.log(\"cleared\", namespace);\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public async set(key: CacheKey, value: any, ttl?: number) {\r\n const parsedKey = this.parseKey(key);\r\n\r\n this.log(\"caching\", parsedKey);\r\n\r\n if (ttl === undefined) {\r\n ttl = this.ttl;\r\n }\r\n\r\n // Extract namespace: all parts except the last (e.g., \"users.id.1\" -> \"users.id\")\r\n const keyParts = parsedKey.split(\".\");\r\n const namespace = keyParts.slice(0, -1).join(\".\") || parsedKey;\r\n\r\n // Find existing cache entry or create new one (upsert pattern)\r\n let cacheEntry = await this.model.first({ key: parsedKey });\r\n\r\n if (cacheEntry) {\r\n // Update existing entry\r\n cacheEntry.set(\"namespace\", namespace);\r\n cacheEntry.set(\"data\", value);\r\n cacheEntry.set(\"ttl\", ttl);\r\n cacheEntry.set(\"expiresAt\", this.getExpiresAt(ttl) || null);\r\n await cacheEntry.save();\r\n } else {\r\n // Create new entry\r\n await this.model.create({\r\n key: parsedKey,\r\n namespace,\r\n data: value,\r\n ttl,\r\n expiresAt: this.getExpiresAt(ttl) || null,\r\n });\r\n }\r\n\r\n this.log(\"cached\", parsedKey);\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public async get(key: CacheKey) {\r\n const parsedKey = this.parseKey(key);\r\n\r\n this.log(\"fetching\", parsedKey);\r\n\r\n const model = await this.model.first({\r\n key: parsedKey,\r\n });\r\n\r\n if (!model) {\r\n this.log(\"notFound\", parsedKey);\r\n return null;\r\n }\r\n\r\n const data: CacheData = {\r\n data: model.get(\"data\"),\r\n expiresAt: model.get(\"expiresAt\") as number | undefined,\r\n ttl: model.get(\"ttl\") as number | undefined,\r\n };\r\n\r\n return this.parseCachedData(parsedKey, data);\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public async remove(key: CacheKey) {\r\n const parsedKey = this.parseKey(key);\r\n\r\n this.log(\"removing\", parsedKey);\r\n\r\n await this.model.delete({\r\n key: parsedKey,\r\n });\r\n\r\n this.log(\"removed\", parsedKey);\r\n }\r\n\r\n /**\r\n * {@inheritdoc}\r\n */\r\n public async flush() {\r\n this.log(\"flushing\");\r\n if (this.options.globalPrefix) {\r\n this.removeNamespace(\"\");\r\n } else {\r\n await this.model.delete();\r\n }\r\n\r\n this.log(\"flushed\");\r\n }\r\n}\r\n","export { DatabaseCacheDriver } from \"./database-cache-driver\";\r\nexport type { DatabaseCacheOptions } from \"./database-cache-driver\";\r\n\r\n// Auto-register database cache driver\r\nimport { cache } from \"@warlock.js/cache\";\r\nimport { DatabaseCacheDriver } from \"./database-cache-driver\";\r\n\r\ncache.registerDriver(\"database\", DatabaseCacheDriver);\r\n","import type {\r\n CLICommandAction,\r\n CLICommandOption,\r\n CLICommandOptions,\r\n CLICommandPreload,\r\n CLICommandSource,\r\n CommandActionData,\r\n ResolvedCLICommandOption,\r\n} from \"./types\";\r\n\r\nexport class CLICommand {\r\n /**\r\n * Command source\r\n */\r\n public commandSource?: CLICommandSource;\r\n\r\n /**\r\n * Command action\r\n */\r\n public commandAction?: CLICommandAction;\r\n\r\n /**\r\n * Command pre action\r\n * This will be executed before loading preloaders\r\n */\r\n public commandPreAction?: CLICommandAction;\r\n\r\n /**\r\n * Command preload\r\n */\r\n public commandPreload?: CLICommandPreload;\r\n\r\n /**\r\n * Command description\r\n */\r\n public commandDescription?: string;\r\n\r\n /**\r\n * Command options\r\n */\r\n public commandOptions: ResolvedCLICommandOption[] = [];\r\n\r\n /**\r\n * Command relative path\r\n * Available only for project commands\r\n * Auto injected by the framework itself\r\n */\r\n public commandRelativePath?: string;\r\n\r\n /**\r\n * Determine if the command is persistent\r\n */\r\n public isPersistent: boolean = false;\r\n\r\n /**\r\n * Command alias (short name)\r\n */\r\n public commandAlias?: string;\r\n\r\n /**\r\n * Constructor\r\n */\r\n public constructor(\r\n public name: string,\r\n description?: string,\r\n ) {\r\n if (description) {\r\n this.commandDescription = description;\r\n }\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Add command source\r\n */\r\n public source(source: CLICommandSource): this {\r\n this.commandSource = source;\r\n return this;\r\n }\r\n\r\n /**\r\n * Set command description\r\n */\r\n public description(description: string): this {\r\n this.commandDescription = description;\r\n return this;\r\n }\r\n\r\n /**\r\n * Determine if the command is persistent\r\n */\r\n public persistent(isPersistent = true): this {\r\n this.isPersistent = isPersistent;\r\n return this;\r\n }\r\n\r\n /**\r\n * Set command alias (short name)\r\n * @example .alias(\"m\") for \"migrate\"\r\n */\r\n public alias(alias: string): this {\r\n this.commandAlias = alias;\r\n return this;\r\n }\r\n\r\n /**\r\n * Command action\r\n */\r\n public action(action: CLICommandAction): this {\r\n this.commandAction = action;\r\n return this;\r\n }\r\n\r\n /**\r\n * Command pre action\r\n * This will be executed before loading preloaders\r\n */\r\n public preAction(action: CLICommandAction): this {\r\n this.commandPreAction = action;\r\n return this;\r\n }\r\n\r\n /**\r\n * Add command options\r\n */\r\n public options(options: CLICommandOption[]): this {\r\n options.map((option) => this.option(option));\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Add command relative path\r\n */\r\n public $relativePath(relativePath: string) {\r\n this.commandRelativePath = relativePath;\r\n return this;\r\n }\r\n\r\n /**\r\n * Add command option\r\n */\r\n public option(option: CLICommandOption): this;\r\n public option(name: string, description?: string, options?: Omit<CLICommandOption, \"name\">): this;\r\n public option(\r\n ...args: [CLICommandOption] | [string, string?, Omit<CLICommandOption, \"name\">?]\r\n ): this {\r\n let option: CLICommandOption;\r\n if (args.length === 1) {\r\n option = args[0] as CLICommandOption;\r\n } else {\r\n option = {\r\n text: args[0],\r\n description: args[1],\r\n ...args[2],\r\n name: \"\",\r\n };\r\n }\r\n\r\n this.commandOptions.push(this.parseOption(option));\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Parse option name and alias if exists\r\n *\r\n * Supports formats:\r\n * - \"--port, -p\" → name: \"port\", alias: \"p\"\r\n * - \"-p, --port\" → name: \"port\", alias: \"p\"\r\n * - \"--port\" → name: \"port\", alias: undefined\r\n * - \"-p\" → name: \"p\", alias: undefined\r\n */\r\n protected parseOption(option: CLICommandOption): ResolvedCLICommandOption {\r\n const text = option.text.trim();\r\n\r\n // Split by comma to check for alias\r\n const parts = text.split(\",\").map((part) => part.trim());\r\n\r\n let name = \"\";\r\n let alias = \"\";\r\n\r\n if (parts.length === 1) {\r\n // Single option: \"--port\" or \"-p\"\r\n name = this.extractOptionName(parts[0]);\r\n } else if (parts.length === 2) {\r\n // Two options: \"--port, -p\" or \"-p, --port\"\r\n const first = parts[0];\r\n const second = parts[1];\r\n\r\n // Determine which is the long form (name) and which is short (alias)\r\n if (first.startsWith(\"--\")) {\r\n name = this.extractOptionName(first);\r\n alias = this.extractOptionName(second);\r\n } else {\r\n name = this.extractOptionName(second);\r\n alias = this.extractOptionName(first);\r\n }\r\n }\r\n\r\n if (alias === \"h\" || name === \"help\") {\r\n throw new Error(\"Help option is not allowed, it's reserved for displaying command help\");\r\n }\r\n\r\n return {\r\n ...option,\r\n name,\r\n alias,\r\n };\r\n }\r\n\r\n /**\r\n * Extract option name from text (removes -- or -)\r\n *\r\n * @example\r\n * extractOptionName(\"--port\") → \"port\"\r\n * extractOptionName(\"-p\") → \"p\"\r\n * extractOptionName(\"--port=3000\") → \"port\"\r\n */\r\n private extractOptionName(text: string): string {\r\n // Remove leading dashes\r\n let name = text.replace(/^-+/, \"\");\r\n\r\n // Remove value assignment if exists (e.g., \"--port=3000\" → \"port\")\r\n const equalIndex = name.indexOf(\"=\");\r\n if (equalIndex !== -1) {\r\n name = name.slice(0, equalIndex);\r\n }\r\n\r\n // Remove angle brackets if exists (e.g., \"--port <number>\" → \"port\")\r\n const spaceIndex = name.indexOf(\" \");\r\n if (spaceIndex !== -1) {\r\n name = name.slice(0, spaceIndex);\r\n }\r\n\r\n return name.trim();\r\n }\r\n\r\n /**\r\n * Command preload\r\n */\r\n public preload(options: CLICommandPreload) {\r\n this.commandPreload = options;\r\n return this;\r\n }\r\n\r\n /**\r\n * Execute the command\r\n */\r\n public async execute(data: CommandActionData) {\r\n if (!this.commandAction) {\r\n throw new Error(`Command \"${this.name}\" has no action defined`);\r\n }\r\n\r\n await this.commandAction(data);\r\n }\r\n}\r\n\r\nexport function command(options: CLICommandOptions) {\r\n const commandInstnace = new CLICommand(options.name, options.description);\r\n\r\n if (options.preload) {\r\n commandInstnace.preload(options.preload);\r\n }\r\n\r\n if (options.persistent) {\r\n commandInstnace.persistent(options.persistent);\r\n }\r\n\r\n if (options.alias) {\r\n commandInstnace.alias(options.alias);\r\n }\r\n\r\n commandInstnace.action(options.action);\r\n\r\n if (options.options) {\r\n commandInstnace.options(options.options);\r\n }\r\n\r\n if (options.preAction) {\r\n commandInstnace.preAction(options.preAction);\r\n }\r\n\r\n return commandInstnace;\r\n}\r\n","import { SeedResult } from \"./types\";\n\nexport type Seeder = {\n /**\n * Seed name\n */\n name: string;\n /**\n * Seed description\n */\n description?: string;\n /**\n * List of dependent seeds to run first\n */\n dependsOn?: string[];\n /**\n * Whether to run it once\n */\n once?: boolean;\n /**\n * Seed execution order\n */\n order?: number;\n /**\n * Batch size\n */\n batchSize?: number;\n /**\n * Run seed\n */\n run(): Promise<SeedResult | void>;\n};\n\n/**\n * Create a new seeder\n */\nexport function seeder(seeder: Seeder) {\n return seeder;\n}\n","import { get } from \"@mongez/reinforcements\";\nimport { slugify } from \"@mongez/slug\";\nimport { authService } from \"@warlock.js/auth\";\nimport { Model, useModelTransformer } from \"@warlock.js/cascade\";\nimport { ComputedCallback, SchemaContext } from \"@warlock.js/seal\";\n\ntype PasswordTransformOptiosn = {\n // TODO: Nothing yet\n};\n\n/**\n * Hash password on saving if password changes\n */\nexport const useHashedPassword = (options?: PasswordTransformOptiosn) =>\n useModelTransformer(({ value, isChanged, isNew }) => {\n if (!value) return value;\n\n if (!isNew && !isChanged) return value;\n\n return authService.hashPassword(value);\n });\n\ntype ComputedCallbackModel = (\n data: any,\n model: Model,\n context: SchemaContext,\n) => any | Promise<any>;\n\n/**\n * Generate computed value based on other fields\n */\nexport function useComputedModel(callback: ComputedCallbackModel) {\n const computedCallback: ComputedCallback = (data, context) => {\n return callback(data, context.rootContext!.model, context);\n };\n\n return computedCallback;\n}\n\n/**\n * Generate slug based on a field on saving\n */\nexport function useComputedSlug(field = \"title\", scope: \"global\" | \"sibling\" = \"sibling\") {\n return useComputedModel((data, model, context) => {\n const value = scope === \"sibling\" ? data[field] : get(context.allValues, field);\n\n if (!value) return model.get(field);\n\n return slugify(value);\n });\n}\n","import path from \"node:path\";\n\nexport class Path {\n /**\n * Convert the given absolute path to a relative path\n */\n public static toRelative(absolutePath: string) {\n return this.normalize(path.relative(process.cwd(), absolutePath));\n }\n\n /**\n * Get relative path of the given path\n */\n public static relative(relativePath: string) {\n return this.normalize(path.relative(process.cwd(), relativePath));\n }\n\n /**\n * Get normalized absolute path of the given path\n */\n public static toNormalizedAbsolute(relativePath: string) {\n return this.normalize(path.resolve(process.cwd(), relativePath));\n }\n\n /**\n * Get absolute path of the given path\n */\n public static toAbsolute(relativePath: string) {\n return this.normalize(path.resolve(process.cwd(), relativePath));\n }\n\n /**\n * Normalize the given path (convert backslashes to forward slashes)\n */\n public static normalize(filePath: string) {\n return filePath.replace(/\\\\/g, \"/\");\n }\n\n /**\n * Join paths and normalize\n */\n public static join(...paths: string[]) {\n return this.normalize(path.join(...paths));\n }\n\n /**\n * Get directory name of a path\n */\n public static dirname(filePath: string) {\n return this.normalize(path.dirname(filePath));\n }\n\n /**\n * Get base name of a path\n */\n public static basename(filePath: string, ext?: string) {\n return path.basename(filePath, ext);\n }\n\n /**\n * Get extension of a path\n */\n public static extname(filePath: string) {\n return path.extname(filePath);\n }\n}\n","import { Path } from \"../path\";\r\nimport type { Connector } from \"./types\";\r\n\r\n/**\r\n * Base Connector Class\r\n * Provides common functionality for all connectors\r\n */\r\nexport abstract class BaseConnector implements Connector {\r\n /**\r\n * Connector name\r\n */\r\n public abstract readonly name: string;\r\n\r\n /**\r\n * Initialization priority\r\n */\r\n public abstract readonly priority: number;\r\n\r\n /**\r\n * Files that trigger restart when changed\r\n * Use relative paths\r\n */\r\n protected abstract readonly watchedFiles: string[];\r\n\r\n /**\r\n * Whether the connector is currently active\r\n */\r\n protected active: boolean = false;\r\n\r\n /**\r\n * Check if connector is active\r\n */\r\n public isActive(): boolean {\r\n return this.active;\r\n }\r\n\r\n /**\r\n * Initialize the connector\r\n */\r\n public abstract start(): Promise<void>;\r\n\r\n /**\r\n * Restart the connector\r\n */\r\n public async restart(): Promise<void> {\r\n await this.shutdown();\r\n await this.start();\r\n }\r\n\r\n /**\r\n * Shutdown the connector\r\n */\r\n public abstract shutdown(): Promise<void>;\r\n\r\n /**\r\n * Determine if connector should restart based on changed files\r\n */\r\n public shouldRestart(changedFiles: string[]): boolean {\r\n // Check if any changed file matches watched files\r\n return changedFiles.some(file => this.isWatchedFile(file));\r\n }\r\n\r\n /**\r\n * Check if a file is watched by this connector\r\n */\r\n protected isWatchedFile(file: string): boolean {\r\n const relativePath = Path.toRelative(file);\r\n\r\n return this.watchedFiles.some(watchedFile => {\r\n // Exact match\r\n if (watchedFile === relativePath) {\r\n return true;\r\n }\r\n\r\n // Pattern match (e.g., \"config/*.ts\")\r\n if (watchedFile.includes(\"*\")) {\r\n const pattern = new RegExp(\r\n \"^\" + watchedFile.replace(/\\*/g, \".*\") + \"$\",\r\n );\r\n return pattern.test(relativePath);\r\n }\r\n\r\n return false;\r\n });\r\n }\r\n}\r\n","/**\r\n * Connector Interface\r\n * All service connectors (Database, HTTP, Cache, etc.) must implement this interface\r\n */\r\nexport interface Connector {\r\n /**\r\n * Unique name of the connector\r\n */\r\n readonly name: ConnectorName;\r\n\r\n /**\r\n * Priority for initialization order\r\n * Lower numbers initialize first (e.g., Database: 1, HTTP: 3)\r\n */\r\n readonly priority: number;\r\n\r\n /**\r\n * Whether the connector is currently active/connected\r\n */\r\n isActive(): boolean;\r\n\r\n /**\r\n * Initialize the connector\r\n * Called during server startup\r\n */\r\n start(): Promise<void>;\r\n\r\n /**\r\n * Restart the connector\r\n * Called when watched files change\r\n */\r\n restart(): Promise<void>;\r\n\r\n /**\r\n * Gracefully shutdown the connector\r\n * Called during server shutdown\r\n */\r\n shutdown(): Promise<void>;\r\n\r\n /**\r\n * Determine if this connector needs restart based on changed files\r\n * @param changedFiles Array of relative file paths that changed\r\n * @returns true if connector should restart\r\n */\r\n shouldRestart(changedFiles: string[]): boolean;\r\n}\r\n\r\nexport type ConnectorName = \"http\" | \"database\" | \"cache\" | \"storage\";\r\n\r\n/**\r\n * Connector priority constants\r\n */\r\nexport enum ConnectorPriority {\r\n DATABASE = 1,\r\n CACHE = 2,\r\n HTTP = 3,\r\n STORAGE = 4,\r\n}\r\n","import config from \"@mongez/config\";\r\nimport { cache } from \"@warlock.js/cache\";\r\nimport { BaseConnector } from \"./base-connector\";\r\nimport { ConnectorPriority } from \"./types\";\r\n\r\n/**\r\n * Cache Connector\r\n * Manages cache engine connection lifecycle\r\n */\r\nexport class CacheConnector extends BaseConnector {\r\n public readonly name = \"cache\";\r\n public readonly priority = ConnectorPriority.CACHE;\r\n\r\n /**\r\n * Files that trigger cache restart\r\n */\r\n protected readonly watchedFiles = [\".env\", \"src/config/cache.ts\", \"src/config/cache.tsx\"];\r\n\r\n /**\r\n * Initialize cache connection\r\n */\r\n public async start(): Promise<void> {\r\n const cacheConfig = config.get(\"cache\");\r\n\r\n if (!cacheConfig) return;\r\n\r\n cache.setCacheConfigurations(cacheConfig);\r\n\r\n await cache.init();\r\n\r\n this.active = true;\r\n }\r\n\r\n /**\r\n * Shutdown cache connection\r\n */\r\n public async shutdown(): Promise<void> {\r\n if (!this.active) {\r\n return;\r\n }\r\n\r\n // TODO: Implement actual cache disconnection\r\n // - Close all active connections\r\n // - Clean up resources\r\n\r\n this.active = false;\r\n }\r\n}\r\n","import { colors } from \"@mongez/copper\";\r\nimport dayjs from \"dayjs\";\r\nimport { Path } from \"./path\";\r\n\r\n/**\r\n * Dev server logger with Vite-like formatting\r\n */\r\n\r\n// Timestamp formatter\r\nfunction timestamp(): string {\r\n return colors.dim(`${dayjs().format(\"HH:mm:ss A\")}`);\r\n}\r\n\r\n// Main log function\r\nexport function devLog(message: string) {\r\n console.log(`${timestamp()} ${message}`);\r\n}\r\n\r\n// Success log (green checkmark)\r\nexport function devLogSuccess(message: string) {\r\n console.log(`${timestamp()} ${colors.green(\"✓\")} ${colors.green(message)}`);\r\n}\r\n\r\n// Error log (red X)\r\nexport function devLogError(message: string, error?: any) {\r\n console.log(`${timestamp()} ${colors.red(\"✗\")} ${colors.red(message)}`);\r\n if (error && error.stack) {\r\n // Clean up error stack to show relative paths\r\n const cleanStack = cleanErrorStack(error.stack);\r\n console.log(colors.dim(cleanStack));\r\n }\r\n}\r\n\r\n// Warning log (yellow)\r\nexport function devLogWarn(message: string) {\r\n console.log(`${timestamp()} ${colors.yellow(\"⚠\")} ${colors.yellow(message)}`);\r\n}\r\n\r\n// Info log (cyan)\r\nexport function devLogInfo(message: string) {\r\n console.log(`${timestamp()} ${colors.cyan(message)}`);\r\n}\r\n\r\n// Dim log (for less important info)\r\nexport function devLogDim(message: string) {\r\n console.log(`${timestamp()} ${colors.dim(message)}`);\r\n}\r\n\r\n// HMR update log (like Vite)\r\nexport function devLogHMR(file: string, dependents?: number) {\r\n const relativePath = Path.toRelative(file);\r\n const depInfo = dependents\r\n ? colors.dim(` +${dependents} module${dependents > 1 ? \"s\" : \"\"}`)\r\n : \"\";\r\n // console.log(`${timestamp()} ✨ ${colors.green(\"hmr update\")}✨ ${colors.dim(relativePath)}${depInfo}`);\r\n console.log(\r\n `${timestamp()} 🔥 ${colors.green(\"hmr update\")} ${colors.dim(relativePath)}${depInfo}`,\r\n );\r\n}\r\n\r\n// FSR log\r\nexport function devLogFSR(reason: string) {\r\n console.log(`${timestamp()} ${colors.yellow(\"full restart\")} ${colors.dim(reason)}`);\r\n}\r\n\r\n// Config reload log\r\nexport function devLogConfig(file: string, connectors?: string[]) {\r\n const relativePath = Path.toRelative(file);\r\n const connectorInfo =\r\n connectors && connectors.length > 0 ? colors.dim(` → restarting ${connectors.join(\", \")}`) : \"\";\r\n console.log(\r\n `${timestamp()} ${colors.cyan(\"config reload\")} ${colors.dim(relativePath)}${connectorInfo}`,\r\n );\r\n}\r\n\r\n// Ready log (like Vite's ready message)\r\nexport function devLogReady(message: string) {\r\n console.log(`\\n${timestamp()} ${colors.green(\"➜\")} ${colors.bold(message)}`);\r\n}\r\n\r\n// Section header\r\nexport function devLogSection(title: string) {\r\n console.log(`\\n${timestamp()} ${colors.bold(colors.cyan(title))}`);\r\n}\r\n\r\n// Clean error stack to show relative paths instead of absolute cache paths\r\nfunction cleanErrorStack(stack: string): string {\r\n const lines = stack.split(\"\\n\");\r\n const cleaned = lines.map((line) => {\r\n // Replace absolute cache paths with relative source paths\r\n // Pattern: D:\\...\\dev-server\\.warlock\\cache\\src-app-users-main.js\r\n // Replace with: src/app/users/main.ts\r\n\r\n let cleanedLine = line;\r\n\r\n // Remove cache directory references\r\n cleanedLine = cleanedLine.replace(/\\.warlock[\\\\\\/]cache[\\\\\\/]/g, \"\");\r\n\r\n // Convert cache file names back to source paths\r\n // src-app-users-main.js → src/app/users/main.ts\r\n cleanedLine = cleanedLine.replace(/([a-zA-Z0-9_-]+(?:-[a-zA-Z0-9_-]+)+)\\.js/g, (match, p1) => {\r\n const sourcePath = p1.replace(/-/g, \"/\") + \".ts\";\r\n return sourcePath;\r\n });\r\n\r\n // Make paths relative\r\n try {\r\n const absolutePathMatch = cleanedLine.match(/([A-Z]:\\\\[^:]+|\\/[^:]+)(?=:|\\))/);\r\n if (absolutePathMatch) {\r\n const absolutePath = absolutePathMatch[1];\r\n const relativePath = Path.toRelative(absolutePath);\r\n cleanedLine = cleanedLine.replace(absolutePath, relativePath);\r\n }\r\n } catch {\r\n // If path conversion fails, keep original\r\n }\r\n\r\n return cleanedLine;\r\n });\r\n\r\n return cleaned.join(\"\\n\");\r\n}\r\n\r\n// Format module not found errors with enhanced context\r\nexport function formatModuleNotFoundError(error: Error, suggestions?: string[]): string {\r\n const message = error.message;\r\n\r\n // Extract paths from error message\r\n // Pattern: Cannot find module 'D:\\...\\cache\\src-app-users-utils.js' imported from 'D:\\...\\main.js'\r\n const match = message.match(/Cannot find module '([^']+)' imported from '([^']+)'/);\r\n\r\n if (match) {\r\n const [, modulePath, importerPath] = match;\r\n\r\n // Convert cache paths to source paths\r\n const cleanModulePath = modulePath\r\n .replace(/\\.warlock[\\\\\\/]cache[\\\\\\/]/, \"\")\r\n .replace(\r\n /([a-zA-Z0-9_-]+(?:-[a-zA-Z0-9_-]+)+)\\.js/,\r\n (m, p1) => p1.replace(/-/g, \"/\") + \".ts\",\r\n );\r\n\r\n const cleanImporterPath = importerPath\r\n .replace(/\\.warlock[\\\\\\/]cache[\\\\\\/]/, \"\")\r\n .replace(\r\n /([a-zA-Z0-9_-]+(?:-[a-zA-Z0-9_-]+)+)\\.js/,\r\n (m, p1) => p1.replace(/-/g, \"/\") + \".ts\",\r\n );\r\n\r\n // Make paths relative\r\n const relativeModule = Path.toRelative(cleanModulePath);\r\n const relativeImporter = Path.toRelative(cleanImporterPath);\r\n\r\n // Build formatted message\r\n const lines: string[] = [\r\n \"\",\r\n `${colors.red(\"❌ MODULE NOT FOUND\")}`,\r\n \"\",\r\n `${colors.dim(\"Cannot find:\")} ${colors.cyan(relativeModule)}`,\r\n \"\",\r\n `${colors.dim(\"Imported by:\")}`,\r\n ` ${colors.yellow(\"→\")} ${colors.white(relativeImporter)}`,\r\n ];\r\n\r\n // Add suggestions if provided\r\n if (suggestions && suggestions.length > 0) {\r\n lines.push(\"\");\r\n lines.push(`${colors.dim(\"Did you mean?\")}`);\r\n suggestions.forEach((s) => {\r\n lines.push(` ${colors.cyan(\"→\")} ${colors.green(s)}`);\r\n });\r\n }\r\n\r\n lines.push(\"\");\r\n\r\n return lines.join(\"\\n\");\r\n }\r\n\r\n return message;\r\n}\r\n\r\n// Legacy function for backward compatibility\r\nexport function devServeLog(message: string) {\r\n devLog(message);\r\n}\r\n","import config from \"@mongez/config\";\r\nimport { connectToDatabase, dataSourceRegistry } from \"@warlock.js/cascade\";\r\nimport { BaseConnector } from \"./base-connector\";\r\nimport { ConnectorPriority } from \"./types\";\r\n\r\n/**\r\n * Database Connector\r\n * Manages database connection lifecycle using @warlock.js/cascade\r\n */\r\nexport class DatabaseConnector extends BaseConnector {\r\n public readonly name = \"database\";\r\n public readonly priority = ConnectorPriority.DATABASE;\r\n\r\n /**\r\n * Files that trigger database restart\r\n */\r\n protected readonly watchedFiles = [\".env\", \"src/config/database.ts\", \"src/config/database.tsx\"];\r\n\r\n /**\r\n * Initialize database connection\r\n */\r\n public async start(): Promise<void> {\r\n const databaseConfig = config.get(\"database\");\r\n\r\n if (!databaseConfig) {\r\n return;\r\n }\r\n\r\n try {\r\n await connectToDatabase(databaseConfig);\r\n this.active = true;\r\n } catch (error) {\r\n console.error(\"Failed to connect to database:\", error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Shutdown database connection\r\n */\r\n public async shutdown(): Promise<void> {\r\n if (!this.active) {\r\n return;\r\n }\r\n\r\n try {\r\n // Disconnect all registered data sources\r\n const dataSources = dataSourceRegistry.getAllDataSources();\r\n\r\n for (const dataSource of dataSources) {\r\n if (dataSource.driver.isConnected) {\r\n await dataSource.driver.disconnect();\r\n }\r\n }\r\n\r\n this.active = false;\r\n } catch (error) {\r\n console.error(\"Failed to disconnect from database:\", error);\r\n throw error;\r\n }\r\n }\r\n}\r\n","import config from \"@mongez/config\";\r\nimport { registerHttpPlugins } from \"../../http/plugins\";\r\nimport { getServer, startServer } from \"../../http/server\";\r\nimport { router } from \"../../router/router\";\r\nimport { environment } from \"../../utils\";\r\nimport { setBaseUrl } from \"../../utils/urls\";\r\nimport { devLogError, devLogInfo, devLogSuccess } from \"../dev-logger\";\r\nimport { BaseConnector } from \"./base-connector\";\r\nimport { ConnectorPriority } from \"./types\";\r\n\r\n/**\r\n * HTTP Connector\r\n * Manages HTTP server (Fastify) lifecycle\r\n */\r\nexport class HttpConnector extends BaseConnector {\r\n public readonly name = \"http\";\r\n public readonly priority = ConnectorPriority.HTTP;\r\n\r\n /**\r\n * Files that trigger HTTP server restart\r\n * Note: routes.ts changes will be handled by HMR with wildcard routing\r\n */\r\n protected readonly watchedFiles = [\"src/config/http.ts\", \"src/config/http.tsx\"];\r\n\r\n /**\r\n * Initialize HTTP server\r\n */\r\n public async start(): Promise<void> {\r\n const httpConfig = config.get(\"http\");\r\n\r\n if (!httpConfig) return;\r\n\r\n const port = httpConfig.port;\r\n devLogInfo(\"Starting http server on port \" + port);\r\n\r\n const server = startServer();\r\n\r\n await registerHttpPlugins(server);\r\n\r\n if (environment() === \"development\") {\r\n router.scanDevServer(server);\r\n } else {\r\n router.scan(server);\r\n }\r\n\r\n try {\r\n // 👇🏻 We can use the url of the server\r\n await server.listen({\r\n port,\r\n host: httpConfig.host || \"localhost\",\r\n });\r\n\r\n const baseUrl = config.get(\"app.baseUrl\");\r\n\r\n // update base url\r\n setBaseUrl(baseUrl);\r\n\r\n devLogSuccess(`Server is listening on ${baseUrl}`);\r\n } catch (error) {\r\n devLogError(\"Error while starting http server\", error);\r\n\r\n process.exit(1); // stop the process, exit with error\r\n }\r\n\r\n this.active = true;\r\n }\r\n\r\n /**\r\n * Shutdown HTTP server\r\n */\r\n public async shutdown(): Promise<void> {\r\n if (!this.active) {\r\n return;\r\n }\r\n\r\n const server = getServer();\r\n\r\n server?.close();\r\n\r\n this.active = false;\r\n }\r\n\r\n /**\r\n * Override shouldRestart to handle routes.ts specially\r\n * routes.ts changes should NOT restart the server (use HMR instead)\r\n */\r\n public shouldRestart(changedFiles: string[]): boolean {\r\n // Only restart for config changes, not routes\r\n return changedFiles.some((file) => {\r\n const relativePath = file.replace(/\\\\/g, \"/\");\r\n return relativePath === \"src/config/http.ts\" || relativePath === \"src/config/http.tsx\";\r\n });\r\n }\r\n}\r\n","import { storage } from \"../../storage\";\nimport { BaseConnector } from \"./base-connector\";\nimport { ConnectorPriority } from \"./types\";\n\n/**\n * Cache Connector\n * Manages cache engine connection lifecycle\n */\nexport class StorageConnector extends BaseConnector {\n public readonly name = \"storage\";\n public readonly priority = ConnectorPriority.STORAGE;\n\n /**\n * Files that trigger cache restart\n */\n protected readonly watchedFiles = [\".env\", \"src/config/storage.ts\", \"src/config/storage.tsx\"];\n\n /**\n * Initialize cache connection\n */\n public async start(): Promise<void> {\n await storage.init();\n\n this.active = true;\n }\n\n /**\n * Shutdown cache connection\n */\n public async shutdown(): Promise<void> {\n if (!this.active) {\n return;\n }\n\n storage.reset();\n\n this.active = false;\n }\n}\n","import { colors } from \"@mongez/copper\";\r\nimport { devServeLog } from \"../dev-logger\";\r\nimport { CacheConnector } from \"./cache-connector\";\r\nimport { DatabaseConnector } from \"./database-connector\";\r\nimport { HttpConnector } from \"./http-connector\";\r\nimport { StorageConnector } from \"./storage.connector\";\r\nimport type { Connector, ConnectorName } from \"./types\";\r\n\r\nexport class ConnectorsManager {\r\n /**\r\n * Connectors lsit\r\n */\r\n private readonly connectors: Connector[] = [];\r\n\r\n /**\r\n * Constructor\r\n */\r\n public constructor() {\r\n this.register(new HttpConnector());\r\n this.register(new DatabaseConnector());\r\n this.register(new CacheConnector());\r\n this.register(new StorageConnector());\r\n }\r\n\r\n /**\r\n * Register a connector\r\n */\r\n public register(connector: Connector): void {\r\n this.connectors.push(connector);\r\n // sort connectors by priority\r\n this.connectors.sort((a, b) => a.priority - b.priority);\r\n }\r\n\r\n /**\r\n * Get all connectors\r\n */\r\n public list(): Connector[] {\r\n return this.connectors;\r\n }\r\n\r\n /**\r\n * start all connectors\r\n */\r\n public async start(connectorsNames?: ConnectorName[]): Promise<void> {\r\n for (const connector of this.connectors) {\r\n if (connectorsNames && !connectorsNames.includes(connector.name)) continue;\r\n\r\n await connector.start();\r\n }\r\n }\r\n\r\n /**\r\n * Shutdown all connectors\r\n */\r\n public async shutdown(): Promise<void> {\r\n for (const connector of this.connectors) {\r\n try {\r\n await connector.shutdown();\r\n } catch (error) {\r\n devServeLog(colors.redBright(`❌ Failed to shutdown ${connector.name}: ${error}`));\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Shutdown connectors on process kill\r\n *\r\n * Handles graceful shutdown for both Unix and Windows:\r\n * - SIGINT: Ctrl+C on Unix, also caught on Windows but unreliable in child processes\r\n * - SIGTERM: Termination signal (Unix primarily)\r\n * - beforeExit: Fires when Node.js empties its event loop (more reliable on Windows)\r\n */\r\n public shutdownOnProcessKill(): void {\r\n let isShuttingDown = false;\r\n\r\n const gracefulShutdown = async (signal: string) => {\r\n if (isShuttingDown) return;\r\n isShuttingDown = true;\r\n\r\n console.log(`\\nExiting...`);\r\n await this.shutdown();\r\n process.exit(0);\r\n };\r\n\r\n // Unix signals\r\n process.on(\"SIGINT\", () => gracefulShutdown(\"SIGINT\"));\r\n process.on(\"SIGTERM\", () => gracefulShutdown(\"SIGTERM\"));\r\n\r\n // Windows-specific: handle when process is about to exit\r\n // This is more reliable on Windows for spawned child processes\r\n if (process.platform === \"win32\") {\r\n // Handle Ctrl+C on Windows specifically\r\n process.on(\"SIGHUP\", () => gracefulShutdown(\"SIGHUP\"));\r\n }\r\n }\r\n}\r\n\r\nexport const connectorsManager = new ConnectorsManager();\r\n","type FileHealthStats = {\r\n /**\r\n * File Health State\r\n */\r\n state: \"healthy\" | \"defective\";\r\n /**\r\n * Number of errors\r\n */\r\n errors: number;\r\n /**\r\n * Number of warnings\r\n */\r\n warnings: number;\r\n};\r\n\r\ntype FileHealthMessage = {\r\n /**\r\n * Message\r\n */\r\n message: string;\r\n /**\r\n * Type of the message\r\n */\r\n type: \"error\" | \"warning\";\r\n /**\r\n * Line number\r\n */\r\n lineNumber: number;\r\n /**\r\n * Column number\r\n */\r\n columnNumber: number;\r\n /**\r\n * Length of the error/warning span\r\n */\r\n length?: number;\r\n /**\r\n * Rule ID (for ESLint)\r\n */\r\n ruleId?: string;\r\n};\r\n\r\nexport class FileHealthResult {\r\n /**\r\n * Result of the health check\r\n */\r\n public result: \"healthy\" | \"defective\" = \"healthy\";\r\n\r\n /**\r\n * Messages list (either for errors or warnings)\r\n */\r\n public messages: FileHealthMessage[] = [];\r\n\r\n /**\r\n * Mark as healthy\r\n */\r\n public markAsHealthy(): void {\r\n this.result = \"healthy\";\r\n }\r\n\r\n /**\r\n * Add errors\r\n */\r\n public addErrors(messages: FileHealthMessage[]): void {\r\n this.result = \"defective\";\r\n this.messages.push(...messages);\r\n }\r\n\r\n /**\r\n * Add warnings\r\n */\r\n public addWarnings(messages: FileHealthMessage[]): void {\r\n this.result = \"defective\";\r\n this.messages.push(...messages);\r\n }\r\n\r\n /**\r\n * Get file health stats\r\n */\r\n public getStats(): FileHealthStats {\r\n return {\r\n state: this.result,\r\n errors: this.messages.filter((message) => message.type === \"error\").length,\r\n warnings: this.messages.filter((message) => message.type === \"warning\").length,\r\n };\r\n }\r\n}\r\n","import type { FileManager } from \"../../file-manager\";\r\nimport type {\r\n FileHealthCheckerContract,\r\n HealthCheckerFilesStats,\r\n} from \"../file-health-checker.contract\";\r\nimport { FileHealthResult } from \"../file-health-result\";\r\n\r\ntype CheckerFile = {\r\n file: FileManager;\r\n healthResult: FileHealthResult;\r\n};\r\n\r\nexport abstract class BaseHealthChecker implements FileHealthCheckerContract {\r\n /**\r\n * List of checked files\r\n */\r\n protected files: Map<string, CheckerFile> = new Map();\r\n\r\n /**\r\n * Health checker name (unique identifier)\r\n */\r\n public abstract name: string;\r\n\r\n /**\r\n * Path to worker file (without extension)\r\n *\r\n * If provided, the checker runs in a dedicated worker thread.\r\n * If undefined, the checker runs in the main thread.\r\n *\r\n * @see FileHealthCheckerContract.workerPath\r\n */\r\n public workerPath?: string;\r\n\r\n /**\r\n * Initialize the health checker\r\n */\r\n public abstract initialize(): void;\r\n\r\n /**\r\n * Detect when files are changed\r\n */\r\n public async onFileChanges(files: FileManager[]): Promise<void> {\r\n //\r\n }\r\n\r\n /**\r\n * Remove the given file from the checker\r\n */\r\n public removeFile(file: FileManager): BaseHealthChecker {\r\n this.files.delete(file.relativePath);\r\n return this;\r\n }\r\n\r\n /**\r\n * Validate the health of the file\r\n */\r\n public async check(file: FileManager): Promise<FileHealthResult> {\r\n const result = new FileHealthResult();\r\n\r\n this.files.set(file.relativePath, {\r\n file,\r\n healthResult: result,\r\n });\r\n\r\n return await this.validate(file, result);\r\n }\r\n\r\n /**\r\n * Validate the health of the file\r\n */\r\n public abstract validate(file: FileManager, result: FileHealthResult): Promise<FileHealthResult>;\r\n\r\n /**\r\n * Get the stats of the health checker\r\n */\r\n public async stats(): Promise<HealthCheckerFilesStats> {\r\n const result: HealthCheckerFilesStats = {\r\n name: this.name,\r\n files: {\r\n healthy: 0,\r\n defective: 0,\r\n },\r\n warnings: {\r\n total: 0,\r\n totalFiles: 0,\r\n },\r\n errors: {\r\n total: 0,\r\n totalFiles: 0,\r\n },\r\n };\r\n\r\n for (const file of this.files.values()) {\r\n const healthResult = file.healthResult;\r\n const stats = healthResult.getStats();\r\n const isHealthy = stats.state === \"healthy\";\r\n result.files.healthy += isHealthy ? 1 : 0;\r\n result.files.defective += !isHealthy ? 1 : 0;\r\n result.warnings.total += stats.warnings;\r\n result.warnings.totalFiles += stats.warnings > 0 ? 1 : 0;\r\n result.errors.total += stats.errors;\r\n result.errors.totalFiles += stats.errors > 0 ? 1 : 0;\r\n }\r\n\r\n return result;\r\n }\r\n}\r\n","import { colors } from \"@mongez/copper\";\r\nimport { ESLint } from \"eslint\";\r\nimport fs from \"fs\";\r\nimport path from \"path\";\r\nimport { FileManager } from \"../../file-manager\";\r\nimport { FileHealthCheckerContract } from \"../file-health-checker.contract\";\r\nimport { FileHealthResult } from \"../file-health-result\";\r\nimport { BaseHealthChecker } from \"./base-health-checker\";\r\n\r\nexport class EslintHealthChecker extends BaseHealthChecker implements FileHealthCheckerContract {\r\n /**\r\n * ESLint instance (using new ESLint v9 API with flat config)\r\n */\r\n private eslint: ESLint | null = null;\r\n\r\n /**\r\n * Health checker name\r\n */\r\n public name: string = \"ESLint\";\r\n\r\n /**\r\n * Path to dedicated worker file for ESLint checking\r\n * Runs in a separate thread to avoid blocking the main dev server\r\n */\r\n public workerPath: string = \"./workers/eslint-health.worker\";\r\n\r\n /**\r\n * Whether checker is initialized\r\n */\r\n private initialized: boolean = false;\r\n\r\n /**\r\n * Check if file is a lintable file\r\n */\r\n private isLintableFile(filePath: string): boolean {\r\n const ext = filePath.toLowerCase();\r\n return (\r\n ext.endsWith(\".ts\") || ext.endsWith(\".tsx\") || ext.endsWith(\".js\") || ext.endsWith(\".jsx\")\r\n );\r\n }\r\n\r\n /**\r\n * Initialize the health checker\r\n */\r\n public initialize(): EslintHealthChecker {\r\n try {\r\n // Check if eslint.config.js exists (new flat config format)\r\n const flatConfigPath = path.join(process.cwd(), \"eslint.config.js\");\r\n const flatConfigMjsPath = path.join(process.cwd(), \"eslint.config.mjs\");\r\n const flatConfigCjsPath = path.join(process.cwd(), \"eslint.config.cjs\");\r\n\r\n const hasFlatConfig =\r\n fs.existsSync(flatConfigPath) ||\r\n fs.existsSync(flatConfigMjsPath) ||\r\n fs.existsSync(flatConfigCjsPath);\r\n\r\n if (!hasFlatConfig) {\r\n // No flat config found, skip initialization\r\n this.initialized = true;\r\n return this;\r\n }\r\n\r\n // Use new ESLint v9 API with flat config\r\n // ESLint will automatically find eslint.config.js in the project root\r\n this.eslint = new ESLint({\r\n cwd: process.cwd(),\r\n });\r\n\r\n this.initialized = true;\r\n } catch (error) {\r\n // Handle any errors during initialization gracefully\r\n console.warn(\"ESLint Health Checker: Failed to initialize:\", error);\r\n this.initialized = true; // Mark as initialized to prevent retries\r\n }\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Display health check results in a pretty format\r\n */\r\n private displayResults(file: FileManager, result: FileHealthResult): void {\r\n const stats = result.getStats();\r\n\r\n // Only display if there are errors or warnings\r\n if (stats.errors === 0 && stats.warnings === 0) {\r\n return;\r\n }\r\n\r\n const fileName = file.relativePath.replace(/\\\\/g, \"/\");\r\n const errorCount = stats.errors;\r\n const warningCount = stats.warnings;\r\n const sourceLines = file.source ? file.source.split(\"\\n\") : [];\r\n\r\n // Display errors\r\n if (errorCount > 0) {\r\n const errorMessages = result.messages.filter((m) => m.type === \"error\");\r\n for (const error of errorMessages) {\r\n const icon = colors.redBright(\"✖\");\r\n const level = colors.redBright(colors.bold(\"ERROR\"));\r\n console.log(\r\n `\\n${icon} ${level} ${colors.dim(\"in\")} ${colors.cyanBright(fileName)}${colors.dim(`(${error.lineNumber},${error.columnNumber})`)}`,\r\n );\r\n // Get rule ID from the error if available\r\n const ruleId = error.ruleId || \"eslint\";\r\n console.log(\r\n ` ${colors.magentaBright(ruleId)} ${colors.dim(\"→\")} ${colors.red(error.message)}`,\r\n );\r\n\r\n // Display code line with underline indicator\r\n if (\r\n sourceLines.length > 0 &&\r\n error.lineNumber > 0 &&\r\n error.lineNumber <= sourceLines.length\r\n ) {\r\n const lineIndex = error.lineNumber - 1; // Convert to 0-based index\r\n const lineContent = sourceLines[lineIndex];\r\n const lineNum = error.lineNumber.toString().padStart(4, \" \");\r\n const errorLength = error.length || 1;\r\n const columnIndex = error.columnNumber - 1; // Convert to 0-based index\r\n\r\n // Display the line with normal color (not all red)\r\n console.log(` ${colors.dim(lineNum)} ${colors.dim(\"│\")} ${lineContent || \"\"}`);\r\n\r\n // Display underline indicator\r\n // Padding accounts for: lineNum.length + 1 space + 1 (│) + 1 space = lineNum.length + 3\r\n // (The initial 2 spaces indent is already in the console.log)\r\n const prefixPadding = lineNum.length + 3;\r\n const columnPadding = \" \".repeat(columnIndex);\r\n const underline = colors.redBright(\"~\".repeat(Math.max(1, errorLength)));\r\n console.log(` ${colors.dim(\" \".repeat(prefixPadding))}${columnPadding}${underline}`);\r\n }\r\n }\r\n }\r\n\r\n // Display warnings\r\n if (warningCount > 0) {\r\n const warningMessages = result.messages.filter((m) => m.type === \"warning\");\r\n for (const warning of warningMessages) {\r\n const icon = colors.yellowBright(\"⚠\");\r\n const level = colors.yellowBright(colors.bold(\"WARNING\"));\r\n console.log(\r\n `\\n${icon} ${level} ${colors.dim(\"in\")} ${colors.cyanBright(fileName)}${colors.dim(`(${warning.lineNumber},${warning.columnNumber})`)}`,\r\n );\r\n // Get rule ID from the warning if available\r\n const ruleId = warning.ruleId || \"eslint\";\r\n console.log(\r\n ` ${colors.magentaBright(ruleId)} ${colors.dim(\"→\")} ${colors.yellow(warning.message)}`,\r\n );\r\n\r\n // Display code line with underline indicator\r\n if (\r\n sourceLines.length > 0 &&\r\n warning.lineNumber > 0 &&\r\n warning.lineNumber <= sourceLines.length\r\n ) {\r\n const lineIndex = warning.lineNumber - 1; // Convert to 0-based index\r\n const lineContent = sourceLines[lineIndex];\r\n const lineNum = warning.lineNumber.toString().padStart(4, \" \");\r\n const warningLength = warning.length || 1;\r\n const columnIndex = warning.columnNumber - 1; // Convert to 0-based index\r\n\r\n // Display the line with normal color (not all yellow)\r\n console.log(` ${colors.dim(lineNum)} ${colors.dim(\"│\")} ${lineContent || \"\"}`);\r\n\r\n // Display underline indicator\r\n // Padding accounts for: lineNum.length + 1 space + 1 (│) + 1 space = lineNum.length + 3\r\n // (The initial 2 spaces indent is already in the console.log)\r\n const prefixPadding = lineNum.length + 3;\r\n const columnPadding = \" \".repeat(columnIndex);\r\n const underline = colors.yellowBright(\"~\".repeat(Math.max(1, warningLength)));\r\n console.log(` ${colors.dim(\" \".repeat(prefixPadding))}${columnPadding}${underline}`);\r\n }\r\n }\r\n }\r\n\r\n // Display summary\r\n const summary = [];\r\n if (errorCount > 0) {\r\n summary.push(colors.red(`${errorCount} error${errorCount > 1 ? \"s\" : \"\"}`));\r\n }\r\n if (warningCount > 0) {\r\n summary.push(colors.yellow(`${warningCount} warning${warningCount > 1 ? \"s\" : \"\"}`));\r\n }\r\n }\r\n\r\n /**\r\n * Validate the health of the file\r\n */\r\n public async validate(file: FileManager, result: FileHealthResult): Promise<FileHealthResult> {\r\n // Early exit: skip non-lintable files\r\n if (!this.isLintableFile(file.absolutePath)) {\r\n result.markAsHealthy();\r\n return result;\r\n }\r\n\r\n // Early exit: check if ESLint is available\r\n if (!this.eslint) {\r\n result.markAsHealthy();\r\n return result;\r\n }\r\n\r\n try {\r\n // Use lintText to lint the source code directly from FileManager\r\n // This ensures we always use the latest content\r\n const lintResults = await this.eslint.lintText(file.source, {\r\n filePath: file.absolutePath,\r\n });\r\n\r\n if (lintResults.length === 0) {\r\n console.log(\"No lint results\", file.relativePath);\r\n result.markAsHealthy();\r\n return result;\r\n }\r\n\r\n const lintResult = lintResults[0];\r\n\r\n // Convert ESLint messages to FileHealthResult format\r\n const errors: Array<{\r\n message: string;\r\n type: \"error\";\r\n lineNumber: number;\r\n columnNumber: number;\r\n length: number;\r\n ruleId?: string;\r\n }> = [];\r\n const warnings: Array<{\r\n message: string;\r\n type: \"warning\";\r\n lineNumber: number;\r\n columnNumber: number;\r\n length: number;\r\n ruleId?: string;\r\n }> = [];\r\n\r\n for (const message of lintResult.messages) {\r\n const isError = message.severity === 2;\r\n const isWarning = message.severity === 1;\r\n\r\n if (isError) {\r\n errors.push({\r\n message: message.message,\r\n type: \"error\",\r\n lineNumber: message.line || 1,\r\n columnNumber: message.column || 1,\r\n length: message.endColumn && message.column ? message.endColumn - message.column : 1,\r\n ruleId: message.ruleId || undefined,\r\n });\r\n } else if (isWarning) {\r\n warnings.push({\r\n message: message.message,\r\n type: \"warning\",\r\n lineNumber: message.line || 1,\r\n columnNumber: message.column || 1,\r\n length: message.endColumn && message.column ? message.endColumn - message.column : 1,\r\n ruleId: message.ruleId || undefined,\r\n });\r\n }\r\n }\r\n\r\n // Add errors and warnings to result\r\n if (errors.length > 0) {\r\n result.addErrors(errors);\r\n }\r\n\r\n if (warnings.length > 0) {\r\n result.addWarnings(warnings);\r\n }\r\n\r\n // If no errors or warnings, mark as healthy\r\n if (errors.length === 0 && warnings.length === 0) {\r\n result.markAsHealthy();\r\n } else {\r\n // Display results if there are errors or warnings\r\n this.displayResults(file, result);\r\n }\r\n } catch (error) {\r\n // Handle any errors during validation gracefully\r\n console.log(\"ESlint Error:\", error);\r\n result.markAsHealthy(); // Return healthy on error to avoid blocking\r\n }\r\n\r\n return result;\r\n }\r\n}\r\n","import path from \"node:path\";\nimport ts from \"typescript\";\nimport { Path } from \"./path\";\n\nexport class TSConfigManager {\n /**\n * Aliases list (from tsconfig paths)\n */\n public aliases: Record<string, string[]> = {};\n\n /**\n * Base URL for resolving paths\n */\n public baseUrl: string = \".\";\n\n /**\n * TSConfig\n */\n public tsconfig: any;\n\n public init() {\n if (this.tsconfig) return;\n\n // use typescript to load the tsconfig.json file\n const output = ts.readConfigFile(Path.toAbsolute(\"tsconfig.json\"), ts.sys.readFile);\n\n this.tsconfig = output.config!;\n\n this.aliases = output.config?.compilerOptions?.paths || {};\n\n this.baseUrl = output.config?.compilerOptions?.baseUrl || \".\";\n }\n\n /**\n * Check if the given path is an alias\n * This checks if it's a REAL path alias (not an external package alias)\n *\n * Real aliases map to local paths (e.g., app/* -> src/app/*, src/* -> src/*)\n * External package aliases map to themselves with @ prefix (e.g., @warlock.js/core -> @warlock.js/core)\n */\n public isAlias(path: string) {\n if (!this.tsconfig) {\n this.init();\n }\n\n return Object.keys(this.aliases).some((alias) => {\n // Remove /* from alias pattern for matching\n const aliasPattern = alias.replace(\"/*\", \"\");\n\n if (!path.startsWith(aliasPattern)) {\n return false;\n }\n\n // Check if this is a real alias or just an external package mapping\n const aliasTargets = this.aliases[alias];\n if (!Array.isArray(aliasTargets) || aliasTargets.length === 0) {\n return false;\n }\n\n // If the alias starts with @, it's likely an external package alias\n // Example: \"@warlock.js/core\" -> \"@warlock.js/core\" (external package)\n if (aliasPattern.startsWith(\"@\")) {\n return false;\n }\n\n // Otherwise, it's a real path alias (including self-referencing ones like src/* -> src/*)\n // Example: \"app/*\" -> \"src/app/*\" (real alias)\n // Example: \"src/*\" -> \"src/*\" (self-referencing alias, still valid)\n return true;\n });\n }\n\n /**\n * Get the alias key that matches the given import path\n */\n public getMatchingAlias(path: string): string | null {\n const aliasKey = Object.keys(this.aliases).find((alias) => {\n const aliasPattern = alias.replace(\"/*\", \"\");\n return path.startsWith(aliasPattern);\n });\n\n return aliasKey || null;\n }\n\n /**\n * Resolve an alias import path to a relative path based on tsconfig paths\n * Example: \"app/users/services/get-users.service\" -> \"src/app/users/services/get-users.service\"\n *\n * @param path - The import path with alias (e.g., \"app/users/services/get-users.service\")\n * @returns The resolved relative path or null if alias not found\n */\n public resolveAliasPath(checkingPath: string): string | null {\n // Find matching alias from tsconfig paths\n const aliasKey = this.getMatchingAlias(checkingPath);\n\n if (!aliasKey) return null;\n\n const aliasTargets = this.aliases[aliasKey];\n if (!Array.isArray(aliasTargets) || aliasTargets.length === 0) {\n return null;\n }\n\n // Get the first target path (usually there's only one)\n const targetPattern = aliasTargets[0];\n\n // Replace alias pattern with target pattern\n const aliasPattern = aliasKey.replace(\"/*\", \"\");\n const targetBase = targetPattern.replace(\"/*\", \"\");\n // Remove any leading slash so path.join does not drop the base\n const relativePart = checkingPath.substring(aliasPattern.length).replace(/^[/\\\\]/, \"\");\n\n // Join the target base with the relative part\n const resolvedPath = path.join(targetBase, relativePart);\n\n return Path.normalize(resolvedPath);\n }\n\n /**\n * Resolve an alias import path to an absolute path\n * Example: \"app/users/services/get-users.service\" -> \"/absolute/path/to/src/app/users/services/get-users.service\"\n *\n * @param path - The import path with alias\n * @returns The resolved absolute path or null if alias not found\n */\n public resolveAliasToAbsolute(path: string): string | null {\n const relativePath = this.resolveAliasPath(path);\n\n if (!relativePath) return null;\n\n return Path.normalize(Path.toAbsolute(relativePath));\n }\n}\n\nexport const tsconfigManager = new TSConfigManager();\n","import { colors } from \"@mongez/copper\";\r\nimport ts from \"typescript\";\r\nimport { FileManager } from \"../../file-manager\";\r\nimport { tsconfigManager } from \"../../tsconfig-manager\";\r\nimport { FileHealthCheckerContract } from \"../file-health-checker.contract\";\r\nimport { FileHealthResult } from \"../file-health-result\";\r\nimport { BaseHealthChecker } from \"./base-health-checker\";\r\n\r\nexport class TypescriptHealthChecker\r\n extends BaseHealthChecker\r\n implements FileHealthCheckerContract\r\n{\r\n /**\r\n * Cached TypeScript program instance\r\n */\r\n private program: ts.Program | null = null;\r\n\r\n /**\r\n * Cached parsed TypeScript configuration\r\n */\r\n private parsedConfig: ts.ParsedCommandLine | null = null;\r\n\r\n /**\r\n * Health checker name\r\n */\r\n public name: string = \"TypeScript\";\r\n\r\n /**\r\n * Path to dedicated worker file for TypeScript checking\r\n * Runs in a separate thread to avoid blocking the main dev server\r\n */\r\n public workerPath: string = \"./workers/ts-health.worker\";\r\n\r\n /**\r\n * Whether checker is initialized\r\n */\r\n private initialized: boolean = false;\r\n\r\n /**\r\n * Check if file is a TypeScript file\r\n */\r\n private isTypeScriptFile(filePath: string): boolean {\r\n const ext = filePath.toLowerCase();\r\n return ext.endsWith(\".ts\") || ext.endsWith(\".tsx\");\r\n }\r\n\r\n /**\r\n * Extract line and column from diagnostic location\r\n */\r\n private getDiagnosticLocation(diagnostic: ts.Diagnostic): {\r\n lineNumber: number;\r\n columnNumber: number;\r\n } {\r\n if (diagnostic.file && diagnostic.start !== undefined) {\r\n const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);\r\n return {\r\n lineNumber: line + 1, // TypeScript uses 0-based, we use 1-based\r\n columnNumber: character + 1,\r\n };\r\n }\r\n return {\r\n lineNumber: 1,\r\n columnNumber: 1,\r\n };\r\n }\r\n\r\n /**\r\n * Format diagnostic message\r\n */\r\n private formatDiagnosticMessage(diagnostic: ts.Diagnostic): string {\r\n if (diagnostic.file && diagnostic.start !== undefined) {\r\n return ts.formatDiagnostic(diagnostic, {\r\n getCurrentDirectory: () => process.cwd(),\r\n getCanonicalFileName: (fileName) => fileName,\r\n getNewLine: () => \"\\n\",\r\n });\r\n }\r\n return diagnostic.messageText.toString();\r\n }\r\n\r\n /**\r\n * Display health check results in a pretty format\r\n */\r\n private displayResults(file: FileManager, result: FileHealthResult): void {\r\n const stats = result.getStats();\r\n\r\n // Only display if there are errors or warnings\r\n if (stats.errors === 0 && stats.warnings === 0) {\r\n return;\r\n }\r\n\r\n const fileName = file.relativePath.replace(/\\\\/g, \"/\");\r\n const errorCount = stats.errors;\r\n const warningCount = stats.warnings;\r\n const sourceLines = file.source ? file.source.split(\"\\n\") : [];\r\n\r\n // Display header\r\n // console.log(\r\n // `\\n${colors.dim(\"╭─\")} ${colors.bold(colors.cyanBright(\"TypeScript Health\"))} ${colors.dim(\"→\")} ${colors.cyan(fileName)}`,\r\n // );\r\n\r\n // Display errors\r\n if (errorCount > 0) {\r\n const errorMessages = result.messages.filter((m) => m.type === \"error\");\r\n for (const error of errorMessages) {\r\n const icon = colors.redBright(\"✖\");\r\n const level = colors.redBright(colors.bold(\"ERROR\"));\r\n console.log(\r\n `\\n${icon} ${level} ${colors.dim(\"in\")} ${colors.cyanBright(fileName)}${colors.dim(`(${error.lineNumber},${error.columnNumber})`)}`,\r\n );\r\n // Extract just the message text (remove file path prefix if present)\r\n const messageLines = error.message.split(\"\\n\");\r\n const cleanMessage = messageLines\r\n .map((line) => line.replace(/^[^:]+:\\d+:\\d+ - /, \"\").trim())\r\n .filter((line) => line.length > 0)\r\n .join(\"\\n\");\r\n console.log(` ${colors.dim(\"→\")} ${colors.red(cleanMessage)}`);\r\n\r\n // Display code line with underline indicator\r\n if (\r\n sourceLines.length > 0 &&\r\n error.lineNumber > 0 &&\r\n error.lineNumber <= sourceLines.length\r\n ) {\r\n const lineIndex = error.lineNumber - 1; // Convert to 0-based index\r\n const lineContent = sourceLines[lineIndex];\r\n const lineNum = error.lineNumber.toString().padStart(4, \" \");\r\n const errorLength = error.length || 1;\r\n const columnIndex = error.columnNumber - 1; // Convert to 0-based index\r\n\r\n // Display the line with normal color (not all red)\r\n console.log(` ${colors.dim(lineNum)} ${colors.dim(\"│\")} ${lineContent || \"\"}`);\r\n\r\n // Display underline indicator\r\n // Padding accounts for: lineNum.length + 1 space + 1 (│) + 1 space = lineNum.length + 3\r\n // (The initial 2 spaces indent is already in the console.log)\r\n const prefixPadding = lineNum.length + 3;\r\n const columnPadding = \" \".repeat(columnIndex);\r\n const underline = colors.redBright(\"~\".repeat(Math.max(1, errorLength)));\r\n console.log(` ${colors.dim(\" \".repeat(prefixPadding))}${columnPadding}${underline}`);\r\n }\r\n }\r\n }\r\n\r\n // Display warnings\r\n if (warningCount > 0) {\r\n const warningMessages = result.messages.filter((m) => m.type === \"warning\");\r\n for (const warning of warningMessages) {\r\n const icon = colors.yellowBright(\"⚠\");\r\n const level = colors.yellowBright(colors.bold(\"WARNING\"));\r\n console.log(\r\n `\\n${icon} ${level} ${colors.dim(\"in\")} ${colors.cyanBright(fileName)}${colors.dim(`(${warning.lineNumber},${warning.columnNumber})`)}`,\r\n );\r\n // Extract just the message text (remove file path prefix if present)\r\n const messageLines = warning.message.split(\"\\n\");\r\n const cleanMessage = messageLines\r\n .map((line) => line.replace(/^[^:]+:\\d+:\\d+ - /, \"\").trim())\r\n .filter((line) => line.length > 0)\r\n .join(\"\\n\");\r\n console.log(` ${colors.dim(\"→\")} ${colors.yellow(cleanMessage)}`);\r\n\r\n // Display code line with underline indicator\r\n if (\r\n sourceLines.length > 0 &&\r\n warning.lineNumber > 0 &&\r\n warning.lineNumber <= sourceLines.length\r\n ) {\r\n const lineIndex = warning.lineNumber - 1; // Convert to 0-based index\r\n const lineContent = sourceLines[lineIndex];\r\n const lineNum = warning.lineNumber.toString().padStart(4, \" \");\r\n const warningLength = warning.length || 1;\r\n const columnIndex = warning.columnNumber - 1; // Convert to 0-based index\r\n\r\n // Display the line with normal color (not all yellow)\r\n console.log(` ${colors.dim(lineNum)} ${colors.dim(\"│\")} ${lineContent || \"\"}`);\r\n\r\n // Display underline indicator\r\n // Padding accounts for: lineNum.length + 1 space + 1 (│) + 1 space = lineNum.length + 3\r\n // (The initial 2 spaces indent is already in the console.log)\r\n const prefixPadding = lineNum.length + 3;\r\n const columnPadding = \" \".repeat(columnIndex);\r\n const underline = colors.yellowBright(\"~\".repeat(Math.max(1, warningLength)));\r\n console.log(` ${colors.dim(\" \".repeat(prefixPadding))}${columnPadding}${underline}`);\r\n }\r\n }\r\n }\r\n\r\n // Display summary\r\n const summary = [];\r\n if (errorCount > 0) {\r\n summary.push(colors.red(`${errorCount} error${errorCount > 1 ? \"s\" : \"\"}`));\r\n }\r\n if (warningCount > 0) {\r\n summary.push(colors.yellow(`${warningCount} warning${warningCount > 1 ? \"s\" : \"\"}`));\r\n }\r\n\r\n // console.log(\r\n // `\\n${colors.dim(\"╰─\")} ${colors.bold(\"TypeScript\")} ${colors.dim(\"→\")} ${summary.join(colors.dim(\" and \"))}`,\r\n // );\r\n }\r\n\r\n /**\r\n * Detect when files are changed\r\n */\r\n public async onFileChanges(files: FileManager[]): Promise<void> {\r\n // recreate an incremental program\r\n if (!this.parsedConfig) {\r\n return;\r\n }\r\n\r\n this.program = ts.createProgram(\r\n files.map((file) => file.absolutePath),\r\n {\r\n ...this.parsedConfig.options,\r\n incremental: true,\r\n },\r\n undefined,\r\n this.program!,\r\n );\r\n }\r\n\r\n /**\r\n * Initialize the health checker\r\n */\r\n public initialize(): TypescriptHealthChecker {\r\n try {\r\n // Verify tsconfigManager is initialized and has config\r\n if (!tsconfigManager.tsconfig || Object.keys(tsconfigManager.tsconfig).length === 0) {\r\n this.initialized = true;\r\n return this;\r\n }\r\n\r\n // Parse the config using tsconfigManager's cached config\r\n this.parsedConfig = ts.parseJsonConfigFileContent(\r\n tsconfigManager.tsconfig,\r\n ts.sys,\r\n process.cwd(),\r\n );\r\n\r\n // Check for config errors\r\n if (this.parsedConfig.errors.length > 0) {\r\n // Log config errors but continue (will skip validation)\r\n console.warn(\r\n \"TypeScript Health Checker: tsconfig.json has errors:\",\r\n this.parsedConfig.errors.map((e) => ts.formatDiagnostic(e, ts.createCompilerHost({}))),\r\n );\r\n }\r\n\r\n this.program = ts.createProgram(this.parsedConfig.fileNames, this.parsedConfig.options);\r\n\r\n this.initialized = true;\r\n } catch (error) {\r\n // Handle any errors during initialization gracefully\r\n console.warn(\"TypeScript Health Checker: Failed to initialize:\", error);\r\n this.initialized = true; // Mark as initialized to prevent retries\r\n }\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Validate the health of the file\r\n */\r\n public async validate(file: FileManager, result: FileHealthResult): Promise<FileHealthResult> {\r\n // Early exit: skip non-TypeScript files\r\n if (!this.isTypeScriptFile(file.absolutePath)) {\r\n result.markAsHealthy();\r\n return result;\r\n }\r\n\r\n // Early exit: check if parsed config is available\r\n if (!this.parsedConfig) {\r\n result.markAsHealthy();\r\n return result;\r\n }\r\n\r\n try {\r\n // Lazy-load program on first validation if not already created\r\n if (!this.program) {\r\n // Create program with all project files from parsed config (for proper type checking)\r\n this.program = ts.createProgram(this.parsedConfig.fileNames, this.parsedConfig.options);\r\n }\r\n\r\n // Get source file from program\r\n const sourceFile = this.program.getSourceFile(file.absolutePath);\r\n\r\n // If file is not in the program, return healthy (might be excluded)\r\n if (!sourceFile) {\r\n result.markAsHealthy();\r\n return result;\r\n }\r\n\r\n // Get diagnostics for the specific file only\r\n const syntacticDiagnostics = this.program.getSyntacticDiagnostics(sourceFile);\r\n const semanticDiagnostics = this.program.getSemanticDiagnostics(sourceFile);\r\n\r\n // Combine all diagnostics\r\n const allDiagnostics = [...syntacticDiagnostics, ...semanticDiagnostics];\r\n\r\n // Convert TypeScript diagnostics to FileHealthResult format\r\n const errors: Array<{\r\n message: string;\r\n type: \"error\";\r\n lineNumber: number;\r\n columnNumber: number;\r\n length: number;\r\n }> = [];\r\n const warnings: Array<{\r\n message: string;\r\n type: \"warning\";\r\n lineNumber: number;\r\n columnNumber: number;\r\n length: number;\r\n }> = [];\r\n\r\n for (const diagnostic of allDiagnostics) {\r\n const location = this.getDiagnosticLocation(diagnostic);\r\n const message = this.formatDiagnosticMessage(diagnostic);\r\n const errorLength = diagnostic.length || 1;\r\n\r\n if (diagnostic.category === ts.DiagnosticCategory.Error) {\r\n errors.push({\r\n message,\r\n type: \"error\",\r\n lineNumber: location.lineNumber,\r\n columnNumber: location.columnNumber,\r\n length: errorLength,\r\n });\r\n } else if (diagnostic.category === ts.DiagnosticCategory.Warning) {\r\n warnings.push({\r\n message,\r\n type: \"warning\",\r\n lineNumber: location.lineNumber,\r\n columnNumber: location.columnNumber,\r\n length: errorLength,\r\n });\r\n }\r\n }\r\n\r\n // Add errors and warnings to result\r\n if (errors.length > 0) {\r\n result.addErrors(errors);\r\n }\r\n if (warnings.length > 0) {\r\n result.addWarnings(warnings);\r\n }\r\n\r\n // If no errors or warnings, mark as healthy\r\n if (errors.length === 0 && warnings.length === 0) {\r\n result.markAsHealthy();\r\n } else {\r\n // Display results if there are errors or warnings\r\n this.displayResults(file, result);\r\n }\r\n } catch (error) {\r\n // Handle any errors during validation gracefully\r\n console.warn(`TypeScript Health Checker: Error validating file ${file.relativePath}:`, error);\r\n result.markAsHealthy(); // Return healthy on error to avoid blocking\r\n }\r\n\r\n return result;\r\n }\r\n}\r\n","/**\n * ESLint Health Check Worker\n *\n * This worker runs in a dedicated thread to perform ESLint linting\n * without blocking the main dev server thread. It maintains a persistent\n * ESLint instance for efficient linting.\n *\n * Communication:\n * - Receives: { type: 'init' | 'check' | 'shutdown', ... }\n * - Sends: { type: 'results' | 'initialized' | 'error', ... }\n */\nimport { ESLint } from \"eslint\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport { parentPort, workerData } from \"worker_threads\";\n\n/**\n * Serialized file data received from main thread\n */\ntype SerializedFile = {\n /** Absolute file path */\n path: string;\n /** File content (source code) */\n content: string;\n /** Relative path for display */\n relativePath: string;\n};\n\n/**\n * Lint message sent back to main thread\n */\ntype LintMessage = {\n type: \"error\" | \"warning\";\n message: string;\n lineNumber: number;\n columnNumber: number;\n length: number;\n filePath: string;\n relativePath: string;\n ruleId?: string;\n};\n\n/**\n * Health check result for a single file\n */\ntype FileCheckResult = {\n path: string;\n relativePath: string;\n healthy: boolean;\n errors: LintMessage[];\n warnings: LintMessage[];\n};\n\n/**\n * Messages received from main thread\n */\n/**\n * Deleted file info\n */\ntype DeletedFile = {\n path: string;\n relativePath: string;\n};\n\n/**\n * Messages received from main thread\n */\ntype WorkerMessage =\n | { type: \"init\"; config: { cwd: string } }\n | { type: \"check\"; files: SerializedFile[] }\n | { type: \"filesDeleted\"; files: DeletedFile[] }\n | { type: \"shutdown\" };\n\n/**\n * Messages sent to main thread\n */\ntype WorkerResponse =\n | { type: \"initialized\"; success: boolean; hasConfig: boolean; error?: string }\n | { type: \"results\"; results: FileCheckResult[] }\n | { type: \"error\"; message: string };\n\n/**\n * ESLint Health Worker class\n * Maintains persistent ESLint instance for efficient linting\n */\nclass ESLintHealthWorker {\n /**\n * ESLint instance\n */\n private eslint: ESLint | null = null;\n\n /**\n * Whether the worker is initialized\n */\n private initialized = false;\n\n /**\n * Whether ESLint config was found\n */\n private hasConfig = false;\n\n /**\n * Current working directory\n */\n private cwd: string = process.cwd();\n\n /**\n * Initialize the worker with ESLint configuration\n */\n public initialize(config: { cwd: string }): { success: boolean; hasConfig: boolean } {\n try {\n this.cwd = config.cwd || process.cwd();\n\n // Check if ESLint flat config exists\n const flatConfigPath = path.join(this.cwd, \"eslint.config.js\");\n const flatConfigMjsPath = path.join(this.cwd, \"eslint.config.mjs\");\n const flatConfigCjsPath = path.join(this.cwd, \"eslint.config.cjs\");\n\n this.hasConfig =\n fs.existsSync(flatConfigPath) ||\n fs.existsSync(flatConfigMjsPath) ||\n fs.existsSync(flatConfigCjsPath);\n\n if (!this.hasConfig) {\n this.initialized = true;\n return { success: true, hasConfig: false };\n }\n\n // Create ESLint instance with flat config\n this.eslint = new ESLint({\n cwd: this.cwd,\n });\n\n this.initialized = true;\n return { success: true, hasConfig: true };\n } catch (error) {\n console.error(\"ESLint Worker: Failed to initialize:\", error);\n this.initialized = true;\n return { success: false, hasConfig: false };\n }\n }\n\n /**\n * Check files for ESLint errors\n */\n public async checkFiles(files: SerializedFile[]): Promise<FileCheckResult[]> {\n if (!this.eslint || !this.hasConfig) {\n // No ESLint config, return all files as healthy\n return files.map((file) => ({\n path: file.path,\n relativePath: file.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n }));\n }\n\n const results: FileCheckResult[] = [];\n\n for (const file of files) {\n // Only lint lintable files\n if (!this.isLintableFile(file.path)) {\n results.push({\n path: file.path,\n relativePath: file.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n });\n continue;\n }\n\n try {\n const result = await this.checkSingleFile(file);\n results.push(result);\n } catch (error) {\n // On error, mark as healthy to avoid blocking\n results.push({\n path: file.path,\n relativePath: file.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n });\n }\n }\n\n return results;\n }\n\n /**\n * Check a single file for lint issues\n */\n private async checkSingleFile(file: SerializedFile): Promise<FileCheckResult> {\n if (!this.eslint) {\n return {\n path: file.path,\n relativePath: file.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n };\n }\n\n // Use lintText to lint from memory (not disk)\n const lintResults = await this.eslint.lintText(file.content, {\n filePath: file.path,\n });\n\n if (lintResults.length === 0) {\n return {\n path: file.path,\n relativePath: file.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n };\n }\n\n const lintResult = lintResults[0];\n const errors: LintMessage[] = [];\n const warnings: LintMessage[] = [];\n\n for (const message of lintResult.messages) {\n const lintMessage: LintMessage = {\n type: message.severity === 2 ? \"error\" : \"warning\",\n message: message.message,\n lineNumber: message.line || 1,\n columnNumber: message.column || 1,\n length: message.endColumn && message.column ? message.endColumn - message.column : 1,\n filePath: file.path,\n relativePath: file.relativePath,\n ruleId: message.ruleId || undefined,\n };\n\n if (message.severity === 2) {\n errors.push(lintMessage);\n } else if (message.severity === 1) {\n warnings.push(lintMessage);\n }\n }\n\n return {\n path: file.path,\n relativePath: file.relativePath,\n healthy: errors.length === 0 && warnings.length === 0,\n errors,\n warnings,\n };\n }\n\n /**\n * Check if file is a lintable file\n */\n private isLintableFile(filePath: string): boolean {\n const ext = filePath.toLowerCase();\n return (\n ext.endsWith(\".ts\") || ext.endsWith(\".tsx\") || ext.endsWith(\".js\") || ext.endsWith(\".jsx\")\n );\n }\n}\n\n// Create worker instance\nconst worker = new ESLintHealthWorker();\n\n// Handle messages from main thread\nparentPort?.on(\"message\", async (message: WorkerMessage) => {\n try {\n switch (message.type) {\n case \"init\": {\n const initResult = worker.initialize(message.config);\n const response: WorkerResponse = {\n type: \"initialized\",\n success: initResult.success,\n hasConfig: initResult.hasConfig,\n };\n parentPort?.postMessage(response);\n break;\n }\n\n case \"check\": {\n const results = await worker.checkFiles(message.files);\n const response: WorkerResponse = { type: \"results\", results };\n parentPort?.postMessage(response);\n break;\n }\n\n case \"filesDeleted\": {\n // ESLint doesn't maintain internal file cache (lints from memory)\n // No cleanup needed, just acknowledge\n break;\n }\n\n case \"shutdown\": {\n process.exit(0);\n }\n }\n } catch (error) {\n const response: WorkerResponse = {\n type: \"error\",\n message: error instanceof Error ? error.message : String(error),\n };\n parentPort?.postMessage(response);\n }\n});\n\n// Handle initialization from workerData if provided\nif (workerData?.autoInit) {\n worker.initialize({ cwd: workerData.cwd || process.cwd() });\n}\n","/**\n * TypeScript Health Check Worker\n *\n * This worker runs in a dedicated thread to perform TypeScript type checking\n * without blocking the main dev server thread. It maintains a persistent\n * ts.Program instance for fast incremental type checking.\n *\n * Communication:\n * - Receives: { type: 'init' | 'check' | 'fileChanges' | 'shutdown', ... }\n * - Sends: { type: 'results' | 'initialized' | 'error', ... }\n */\nimport ts from \"typescript\";\nimport { parentPort, workerData } from \"worker_threads\";\n\n/**\n * Serialized file data received from main thread\n */\ntype SerializedFile = {\n /** Absolute file path */\n path: string;\n /** File content (source code) */\n content: string;\n /** Relative path for display */\n relativePath: string;\n};\n\n/**\n * Diagnostic message sent back to main thread\n */\ntype DiagnosticMessage = {\n type: \"error\" | \"warning\";\n message: string;\n lineNumber: number;\n columnNumber: number;\n length: number;\n filePath: string;\n relativePath: string;\n};\n\n/**\n * Health check result for a single file\n */\ntype FileCheckResult = {\n path: string;\n relativePath: string;\n healthy: boolean;\n errors: DiagnosticMessage[];\n warnings: DiagnosticMessage[];\n};\n\n/**\n * Messages received from main thread\n */\n/**\n * Deleted file info\n */\ntype DeletedFile = {\n path: string;\n relativePath: string;\n};\n\n/**\n * Messages received from main thread\n */\ntype WorkerMessage =\n | { type: \"init\"; config: { cwd: string; tsconfigPath?: string } }\n | { type: \"check\"; files: SerializedFile[] }\n | { type: \"fileChanges\"; files: SerializedFile[] }\n | { type: \"filesDeleted\"; files: DeletedFile[] }\n | { type: \"shutdown\" };\n\n/**\n * Messages sent to main thread\n */\ntype WorkerResponse =\n | { type: \"initialized\"; success: boolean; error?: string }\n | { type: \"results\"; results: FileCheckResult[] }\n | { type: \"error\"; message: string };\n\n/**\n * TypeScript Health Worker class\n * Maintains persistent ts.Program for incremental type checking\n */\nclass TypeScriptHealthWorker {\n /**\n * Cached TypeScript program instance\n */\n private program: ts.Program | null = null;\n\n /**\n * Parsed TypeScript configuration\n */\n private parsedConfig: ts.ParsedCommandLine | null = null;\n\n /**\n * In-memory file contents cache\n */\n private fileContents = new Map<string, string>();\n\n /**\n * Whether the worker is initialized\n */\n private initialized = false;\n\n /**\n * Current working directory\n */\n private cwd: string = process.cwd();\n\n /**\n * Initialize the worker with TypeScript configuration\n */\n public initialize(config: { cwd: string; tsconfigPath?: string }): boolean {\n try {\n this.cwd = config.cwd || process.cwd();\n\n // Try to load tsconfig.json\n const tsconfigPath = config.tsconfigPath || ts.findConfigFile(this.cwd, ts.sys.fileExists);\n\n if (!tsconfigPath) {\n this.initialized = true;\n return true; // No tsconfig, will skip type checking\n }\n\n const configFile = ts.readConfigFile(tsconfigPath, ts.sys.readFile);\n\n if (configFile.error) {\n console.warn(\"TypeScript Worker: Error reading tsconfig:\", configFile.error);\n this.initialized = true;\n return true;\n }\n\n this.parsedConfig = ts.parseJsonConfigFileContent(configFile.config, ts.sys, this.cwd);\n\n if (this.parsedConfig.errors.length > 0) {\n console.warn(\"TypeScript Worker: tsconfig has errors:\", this.parsedConfig.errors);\n }\n\n this.initialized = true;\n return true;\n } catch (error) {\n console.error(\"TypeScript Worker: Failed to initialize:\", error);\n this.initialized = true;\n return false;\n }\n }\n\n /**\n * Check files for TypeScript errors\n */\n public checkFiles(files: SerializedFile[]): FileCheckResult[] {\n if (!this.parsedConfig) {\n // No config, return all files as healthy\n return files.map((file) => ({\n path: file.path,\n relativePath: file.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n }));\n }\n\n // Update in-memory file cache\n for (const file of files) {\n this.fileContents.set(file.path, file.content);\n }\n\n // Create or update the program (incremental)\n this.program = ts.createProgram(\n Array.from(this.fileContents.keys()),\n this.parsedConfig.options,\n this.createCompilerHost(),\n this.program || undefined, // Pass old program for incremental compilation\n );\n\n // Check each file\n const results: FileCheckResult[] = [];\n\n for (const file of files) {\n const result = this.checkSingleFile(file);\n results.push(result);\n }\n\n return results;\n }\n\n /**\n * Handle file changes (update program incrementally)\n */\n public handleFileChanges(files: SerializedFile[]): void {\n for (const file of files) {\n this.fileContents.set(file.path, file.content);\n }\n\n // Recreate program with new file contents\n if (this.parsedConfig && this.program) {\n this.program = ts.createProgram(\n Array.from(this.fileContents.keys()),\n this.parsedConfig.options,\n this.createCompilerHost(),\n this.program || undefined,\n );\n }\n }\n\n /**\n * Handle deleted files (remove from cache)\n */\n public handleFilesDeleted(files: DeletedFile[]): void {\n let hasChanges = false;\n\n for (const file of files) {\n if (this.fileContents.has(file.path)) {\n this.fileContents.delete(file.path);\n hasChanges = true;\n }\n }\n\n // Recreate program without deleted files\n if (hasChanges && this.parsedConfig) {\n this.program = ts.createProgram(\n Array.from(this.fileContents.keys()),\n this.parsedConfig.options,\n this.createCompilerHost(),\n this.program || undefined,\n );\n }\n }\n\n /**\n * Check a single file for diagnostics\n */\n private checkSingleFile(file: SerializedFile): FileCheckResult {\n if (!this.program) {\n return {\n path: file.path,\n relativePath: file.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n };\n }\n\n const sourceFile = this.program.getSourceFile(file.path);\n\n if (!sourceFile) {\n return {\n path: file.path,\n relativePath: file.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n };\n }\n\n const syntacticDiagnostics = this.program.getSyntacticDiagnostics(sourceFile);\n const semanticDiagnostics = this.program.getSemanticDiagnostics(sourceFile);\n const allDiagnostics = [...syntacticDiagnostics, ...semanticDiagnostics];\n\n const errors: DiagnosticMessage[] = [];\n const warnings: DiagnosticMessage[] = [];\n\n for (const diagnostic of allDiagnostics) {\n const message = this.formatDiagnostic(diagnostic, file);\n\n if (diagnostic.category === ts.DiagnosticCategory.Error) {\n errors.push(message);\n } else if (diagnostic.category === ts.DiagnosticCategory.Warning) {\n warnings.push(message);\n }\n }\n\n return {\n path: file.path,\n relativePath: file.relativePath,\n healthy: errors.length === 0 && warnings.length === 0,\n errors,\n warnings,\n };\n }\n\n /**\n * Format a TypeScript diagnostic into our message format\n */\n private formatDiagnostic(diagnostic: ts.Diagnostic, file: SerializedFile): DiagnosticMessage {\n let lineNumber = 1;\n let columnNumber = 1;\n let length = 1;\n\n if (diagnostic.file && diagnostic.start !== undefined) {\n const pos = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);\n lineNumber = pos.line + 1;\n columnNumber = pos.character + 1;\n length = diagnostic.length || 1;\n }\n\n const messageText =\n typeof diagnostic.messageText === \"string\"\n ? diagnostic.messageText\n : diagnostic.messageText.messageText;\n\n return {\n type: diagnostic.category === ts.DiagnosticCategory.Error ? \"error\" : \"warning\",\n message: messageText,\n lineNumber,\n columnNumber,\n length,\n filePath: file.path,\n relativePath: file.relativePath,\n };\n }\n\n /**\n * Create a custom compiler host that reads from in-memory cache\n */\n private createCompilerHost(): ts.CompilerHost {\n const defaultHost = ts.createCompilerHost(this.parsedConfig?.options || {});\n\n return {\n ...defaultHost,\n readFile: (fileName: string) => {\n // Check in-memory cache first\n if (this.fileContents.has(fileName)) {\n return this.fileContents.get(fileName);\n }\n // Fall back to disk\n return defaultHost.readFile(fileName);\n },\n fileExists: (fileName: string) => {\n if (this.fileContents.has(fileName)) {\n return true;\n }\n return defaultHost.fileExists(fileName);\n },\n };\n }\n}\n\n// Create worker instance\nconst worker = new TypeScriptHealthWorker();\n\n// Handle messages from main thread\nparentPort?.on(\"message\", (message: WorkerMessage) => {\n try {\n switch (message.type) {\n case \"init\": {\n const success = worker.initialize(message.config);\n const response: WorkerResponse = { type: \"initialized\", success };\n parentPort?.postMessage(response);\n break;\n }\n\n case \"check\": {\n const results = worker.checkFiles(message.files);\n const response: WorkerResponse = { type: \"results\", results };\n parentPort?.postMessage(response);\n break;\n }\n\n case \"fileChanges\": {\n worker.handleFileChanges(message.files);\n break;\n }\n\n case \"filesDeleted\": {\n worker.handleFilesDeleted(message.files);\n break;\n }\n\n case \"shutdown\": {\n process.exit(0);\n }\n }\n } catch (error) {\n const response: WorkerResponse = {\n type: \"error\",\n message: error instanceof Error ? error.message : String(error),\n };\n parentPort?.postMessage(response);\n }\n});\n\n// Handle initialization from workerData if provided\nif (workerData?.autoInit) {\n worker.initialize({ cwd: workerData.cwd || process.cwd() });\n}\n","import { isEmpty } from \"@mongez/supportive-is\";\nimport type {\n QueryBuilderContract as CascadeQueryBuilder,\n QueryBuilderContract,\n} from \"@warlock.js/cascade\";\nimport type { FilterOptions, FilterRule, FilterRules } from \"../../contracts\";\n\n/**\n * Applies repository filters to a Cascade-Next query builder\n * Translates repository filter rules into Cascade query builder method calls\n */\nexport class FilterApplicator {\n /**\n * Apply filters to a Cascade query builder\n *\n * @param query - Cascade query builder instance\n * @param filters - Filter structure defining how to filter\n * @param data - Data containing filter values\n * @param options - Additional filter options (date formats, etc.)\n */\n public apply(\n query: CascadeQueryBuilder<any>,\n filters: FilterRules,\n data: any,\n options: FilterOptions,\n ): void {\n for (const key in filters) {\n const value = data[key];\n if (value === undefined) continue;\n\n const rule = this.parseFilterRule(key, filters[key]);\n this.applyFilterRule(query, rule, value, data, options);\n }\n }\n\n /**\n * Parse a filter rule into a structured format\n */\n private parseFilterRule(key: string, rule: FilterRule) {\n // Handle custom function\n if (typeof rule === \"function\") {\n return { type: \"function\", fn: rule, column: key };\n }\n\n // Handle array format: [\"operator\"] or [\"operator\", \"column\"] or [\"operator\", [\"col1\", \"col2\"]]\n if (Array.isArray(rule)) {\n const [operator, target] = rule;\n\n if (target === undefined) {\n return { type: operator, column: key, columns: undefined };\n }\n\n if (Array.isArray(target)) {\n return { type: operator, column: undefined, columns: target };\n }\n\n return { type: operator, column: target, columns: undefined };\n }\n\n // Handle simple operator string\n return { type: rule, column: key, columns: undefined };\n }\n\n /**\n * Apply a single filter rule to the query\n */\n private applyFilterRule(\n query: CascadeQueryBuilder<any>,\n rule: any,\n value: any,\n data: any,\n options: FilterOptions,\n ): void {\n // 1. Custom function filter\n if (rule.type === \"function\") {\n rule.fn(value, query, data);\n return;\n }\n\n // 2. Predefined filter types\n const handler = this.getFilterHandler(rule.type);\n if (handler) {\n handler.call(this, query, rule.column, rule.columns, value, options);\n return;\n }\n\n // 3. Standard where operators\n this.applyWhereOperator(query, rule.type, rule.column, rule.columns, value);\n }\n\n /**\n * Get filter handler for predefined types\n */\n private getFilterHandler(type: string): Function | undefined {\n const handlers: Record<string, Function> = {\n // Boolean filters\n bool: this.handleBoolean,\n boolean: this.handleBoolean,\n\n // Numeric filters\n int: this.handleInt,\n integer: this.handleInt,\n \"!int\": this.handleNotInt,\n \"int>\": (q: any, col: any, cols: any, val: any) =>\n this.handleIntComparison(q, col, cols, val, \">\"),\n \"int>=\": (q: any, col: any, cols: any, val: any) =>\n this.handleIntComparison(q, col, cols, val, \">=\"),\n \"int<\": (q: any, col: any, cols: any, val: any) =>\n this.handleIntComparison(q, col, cols, val, \"<\"),\n \"int<=\": (q: any, col: any, cols: any, val: any) =>\n this.handleIntComparison(q, col, cols, val, \"<=\"),\n inInt: this.handleInInt,\n number: this.handleNumber,\n inNumber: this.handleInNumber,\n float: this.handleFloat,\n double: this.handleFloat,\n inFloat: this.handleInNumber,\n\n // Null filters\n null: this.handleNull,\n notNull: this.handleNotNull,\n \"!null\": this.handleNotNull,\n\n // Date filters\n date: this.handleDate,\n \"date>\": (q: any, col: any, cols: any, val: any, opts: any) =>\n this.handleDateComparison(q, col, cols, val, opts, \">\"),\n \"date>=\": (q: any, col: any, cols: any, val: any, opts: any) =>\n this.handleDateComparison(q, col, cols, val, opts, \">=\"),\n \"date<\": (q: any, col: any, cols: any, val: any, opts: any) =>\n this.handleDateComparison(q, col, cols, val, opts, \"<\"),\n \"date<=\": (q: any, col: any, cols: any, val: any, opts: any) =>\n this.handleDateComparison(q, col, cols, val, opts, \"<=\"),\n dateBetween: this.handleDateBetween,\n inDate: this.handleInDate,\n\n // DateTime filters\n dateTime: this.handleDateTime,\n \"dateTime>\": (q: any, col: any, cols: any, val: any, opts: any) =>\n this.handleDateTimeComparison(q, col, cols, val, opts, \">\"),\n \"dateTime>=\": (q: any, col: any, cols: any, val: any, opts: any) =>\n this.handleDateTimeComparison(q, col, cols, val, opts, \">=\"),\n \"dateTime<\": (q: any, col: any, cols: any, val: any, opts: any) =>\n this.handleDateTimeComparison(q, col, cols, val, opts, \"<\"),\n \"dateTime<=\": (q: any, col: any, cols: any, val: any, opts: any) =>\n this.handleDateTimeComparison(q, col, cols, val, opts, \"<=\"),\n dateTimeBetween: this.handleDateTimeBetween,\n inDateTime: this.handleInDateTime,\n };\n\n return handlers[type];\n }\n\n /**\n * Apply standard where operators\n */\n private applyWhereOperator(\n query: QueryBuilderContract,\n operator: string,\n column?: string,\n columns?: string[],\n value?: any,\n ): void {\n // Handle \"in\" prefix for array values\n if (operator.startsWith(\"in\") && operator !== \"int\" && !Array.isArray(value)) {\n value = [value];\n }\n\n // Single column\n if (column) {\n switch (operator) {\n case \"=\":\n query.where(column, value);\n break;\n case \"!=\":\n case \"<>\":\n query.where(column, \"!=\", value);\n break;\n case \">\":\n case \">=\":\n case \"<\":\n case \"<=\":\n query.where(column, operator, value);\n break;\n case \"in\":\n query.whereIn(column, Array.isArray(value) ? value : [value]);\n break;\n case \"not in\":\n query.whereNotIn(column, Array.isArray(value) ? value : [value]);\n break;\n case \"like\":\n query.whereLike(column, value);\n break;\n case \"not like\":\n query.whereNotLike(column, value);\n break;\n case \"between\":\n query.whereBetween(column, value);\n break;\n case \"not between\":\n query.whereNotBetween(column, value);\n break;\n }\n }\n // Multiple columns (OR condition)\n else if (columns) {\n const conditions: any = {};\n for (const col of columns) {\n conditions[col] = value;\n }\n query.orWhere(conditions);\n }\n }\n\n // ============================================================================\n // BOOLEAN FILTERS\n // ============================================================================\n\n private handleBoolean(\n query: QueryBuilderContract,\n column?: string,\n columns?: string[],\n value?: any,\n ) {\n const boolValue =\n value === \"true\" || value === true || value === 1 || value === \"1\" || !isEmpty(value);\n if (column) {\n query.where(column, boolValue);\n } else if (columns) {\n const conditions: any = {};\n for (const col of columns) {\n conditions[col] = boolValue;\n }\n\n query.orWhere(conditions);\n }\n }\n\n // ============================================================================\n // NUMERIC FILTERS\n // ============================================================================\n private handleInt(query: QueryBuilderContract, column?: string, columns?: string[], value?: any) {\n const intValue = parseInt(value);\n if (column) {\n query.where(column, intValue);\n } else if (columns) {\n const conditions: any = {};\n for (const col of columns) {\n conditions[col] = intValue;\n }\n\n query.orWhere(conditions);\n }\n }\n\n private handleNotInt(\n query: QueryBuilderContract,\n column?: string,\n columns?: string[],\n value?: any,\n ) {\n const intValue = parseInt(value);\n if (column) {\n query.where(column, \"!=\", intValue);\n } else if (columns) {\n // Use multiple orWhere calls for OR logic across columns\n for (const col of columns) {\n query.orWhere(col, \"!=\", intValue);\n }\n }\n }\n\n private handleIntComparison(\n query: QueryBuilderContract,\n column: any,\n columns: any,\n value: any,\n operator: string,\n ) {\n const intValue = parseInt(value);\n if (column) {\n query.where(column, operator, intValue);\n } else if (columns) {\n for (const col of columns) {\n query.orWhere(col, operator, intValue);\n }\n }\n }\n\n private handleInInt(\n query: QueryBuilderContract,\n column?: string,\n columns?: string[],\n value?: any,\n ) {\n const values = (Array.isArray(value) ? value : [value]).map((v: any) => parseInt(v));\n if (column) {\n query.whereIn(column, values);\n } else if (columns) {\n // Use multiple orWhere calls with whereIn for each column\n for (const col of columns) {\n query.orWhere((q: any) => q.whereIn(col, values));\n }\n }\n }\n\n private handleNumber(\n query: QueryBuilderContract,\n column?: string,\n columns?: string[],\n value?: any,\n ) {\n const numValue = Number(value);\n if (column) {\n query.where(column, numValue);\n } else if (columns) {\n const conditions: any = {};\n for (const col of columns) {\n conditions[col] = numValue;\n }\n\n query.orWhere(conditions);\n }\n }\n\n private handleInNumber(\n query: QueryBuilderContract,\n column?: string,\n columns?: string[],\n value?: any,\n ) {\n const values = (Array.isArray(value) ? value : [value]).map((v: any) => Number(v));\n if (column) {\n query.whereIn(column, values);\n } else if (columns) {\n // Use multiple orWhere calls with whereIn for each column\n for (const col of columns) {\n query.orWhere((q: any) => q.whereIn(col, values));\n }\n }\n }\n\n private handleFloat(\n query: QueryBuilderContract,\n column?: string,\n columns?: string[],\n value?: any,\n ) {\n const floatValue = parseFloat(value);\n if (column) {\n query.where(column, floatValue);\n } else if (columns) {\n const conditions: any = {};\n for (const col of columns) {\n conditions[col] = floatValue;\n }\n\n query.orWhere(conditions);\n }\n }\n\n // ============================================================================\n // NULL FILTERS\n // ============================================================================\n\n private handleNull(query: QueryBuilderContract, column?: string, columns?: string[]) {\n if (column) {\n query.whereNull(column);\n } else if (columns) {\n for (const col of columns) {\n query.orWhere({ [col]: null });\n }\n }\n }\n\n private handleNotNull(query: QueryBuilderContract, column?: string, columns?: string[]) {\n if (column) {\n query.whereNotNull(column);\n } else if (columns) {\n // Use whereNotNull for each column\n for (const col of columns) {\n query.orWhere((q: any) => q.whereNotNull(col));\n }\n }\n }\n\n // ============================================================================\n // DATE FILTERS\n // ============================================================================\n\n private handleDate(\n query: QueryBuilderContract,\n column?: string,\n columns?: string[],\n value?: any,\n options?: FilterOptions,\n ) {\n const dateValue = this.parseDate(value, options?.dateFormat);\n if (column) {\n query.whereDate(column, dateValue);\n } else if (columns) {\n for (const col of columns) {\n query.orWhere((q: any) => q.whereDate(col, dateValue));\n }\n }\n }\n\n private handleDateComparison(\n query: QueryBuilderContract,\n column: any,\n columns: any,\n value: any,\n options: any,\n operator: string,\n ) {\n const dateValue = this.parseDate(value, options?.dateFormat);\n if (column) {\n if (operator === \">\" || operator === \">=\") {\n query.whereDateAfter(column, dateValue);\n } else {\n query.whereDateBefore(column, dateValue);\n }\n } else if (columns) {\n for (const col of columns) {\n if (operator === \">\" || operator === \">=\") {\n query.orWhere((q: any) => q.whereDateAfter(col, dateValue));\n } else {\n query.orWhere((q: any) => q.whereDateBefore(col, dateValue));\n }\n }\n }\n }\n\n private handleDateBetween(\n query: QueryBuilderContract,\n column?: string,\n columns?: string[],\n value?: any,\n options?: FilterOptions,\n ) {\n if (!Array.isArray(value) || value.length !== 2) return;\n const [start, end] = value.map((v: any) => this.parseDate(v, options?.dateFormat));\n if (column) {\n query.whereDateBetween(column, [start, end]);\n } else if (columns) {\n for (const col of columns) {\n query.orWhere((q: any) => q.whereDateBetween(col, [start, end]));\n }\n }\n }\n\n private handleInDate(\n query: QueryBuilderContract,\n column?: string,\n columns?: string[],\n value?: any,\n options?: FilterOptions,\n ) {\n const dates = (Array.isArray(value) ? value : [value]).map((v: any) =>\n this.parseDate(v, options?.dateFormat),\n );\n if (column) {\n query.whereIn(column, dates);\n } else if (columns) {\n // Use multiple orWhere calls with whereIn for each column\n for (const col of columns) {\n query.orWhere((q: any) => q.whereIn(col, dates));\n }\n }\n }\n\n // ============================================================================\n // DATETIME FILTERS\n // ============================================================================\n\n private handleDateTime(\n query: QueryBuilderContract,\n column?: string,\n columns?: string[],\n value?: any,\n options?: FilterOptions,\n ) {\n const dateValue = this.parseDateTime(value, options?.dateTimeFormat);\n if (column) {\n query.where(column, dateValue);\n } else if (columns) {\n const conditions: any = {};\n for (const col of columns) {\n conditions[col] = dateValue;\n }\n\n query.orWhere(conditions);\n }\n }\n\n private handleDateTimeComparison(\n query: QueryBuilderContract,\n column: any,\n columns: any,\n value: any,\n options: any,\n operator: string,\n ) {\n const dateValue = this.parseDateTime(value, options?.dateTimeFormat);\n if (column) {\n query.where(column, operator, dateValue);\n } else if (columns) {\n for (const col of columns) {\n query.orWhere(col, operator, dateValue);\n }\n }\n }\n\n private handleDateTimeBetween(\n query: QueryBuilderContract,\n column?: string,\n columns?: string[],\n value?: any,\n options?: FilterOptions,\n ) {\n if (!Array.isArray(value) || value.length !== 2) return;\n const [start, end] = value.map((v: any) => this.parseDateTime(v, options?.dateTimeFormat));\n if (column) {\n query.whereBetween(column, [start, end]);\n } else if (columns) {\n for (const col of columns) {\n query.orWhere((q: any) => q.whereBetween(col, [start, end]));\n }\n }\n }\n\n private handleInDateTime(\n query: QueryBuilderContract,\n column?: string,\n columns?: string[],\n value?: any,\n options?: FilterOptions,\n ) {\n const dates = (Array.isArray(value) ? value : [value]).map((v: any) =>\n this.parseDateTime(v, options?.dateTimeFormat),\n );\n if (column) {\n query.whereIn(column, dates);\n } else if (columns) {\n // Use multiple orWhere calls with whereIn for each column\n for (const col of columns) {\n query.orWhere((q: any) => q.whereIn(col, dates));\n }\n }\n }\n\n // ============================================================================\n // DATE PARSING UTILITIES\n // ============================================================================\n\n /**\n * Parse date string to Date object\n * TODO: Implement proper date parsing with format support\n */\n private parseDate(value: any, format?: string): Date {\n if (value instanceof Date) return value;\n return new Date(value);\n }\n\n /**\n * Parse datetime string to Date object\n * TODO: Implement proper datetime parsing with format support\n */\n private parseDateTime(value: any, format?: string): Date {\n if (value instanceof Date) return value;\n return new Date(value);\n }\n}\n","import type {\n QueryBuilderContract as CascadeQueryBuilderContract,\n Model,\n} from \"@warlock.js/cascade\";\nimport type {\n ChunkCallback,\n CursorPaginationOptions,\n CursorPaginationResult,\n FilterOptions,\n FilterRules,\n PaginationResult,\n QueryBuilderContract,\n WhereOperator,\n} from \"../../contracts\";\nimport { FilterApplicator } from \"./filter-applicator\";\n\n/**\n * Cascade query builder wrapper\n * Wraps Cascade-Next's ModelAggregate to implement QueryBuilderContract\n *\n * @template T - The model instance type\n */\nexport class CascadeQueryBuilder<T extends Model> implements QueryBuilderContract<T> {\n /**\n * Constructor\n * @param query - Cascade-Next QueryBuilder instance\n */\n public constructor(private query: CascadeQueryBuilderContract<T>) {}\n\n // ============================================================================\n // WHERE CLAUSES\n // ============================================================================\n\n /**\n * {@inheritDoc QueryBuilderContract.where}\n */\n public where(field: string, value: any): this;\n public where(field: string, operator: WhereOperator, value: any): this;\n public where(conditions: Record<string, any>): this;\n public where(callback: (query: this) => void): this;\n public where(\n fieldOrConditionsOrCallback: string | Record<string, any> | ((query: this) => void),\n operatorOrValue?: WhereOperator | any,\n value?: any,\n ): this {\n if (typeof fieldOrConditionsOrCallback === \"function\") {\n // Callback\n fieldOrConditionsOrCallback(this);\n } else if (typeof fieldOrConditionsOrCallback === \"object\") {\n // Object conditions\n this.query.where(fieldOrConditionsOrCallback);\n } else if (value !== undefined) {\n // Field, operator, value\n this.query.where(fieldOrConditionsOrCallback, operatorOrValue, value);\n } else {\n // Field, value\n this.query.where(fieldOrConditionsOrCallback, operatorOrValue);\n }\n\n return this;\n }\n\n /**\n * Pretty display the query in terminal\n */\n public pretty() {\n return this.query.pretty();\n }\n\n /**\n * {@inheritDoc QueryBuilderContract.orWhere}\n */\n public orWhere(field: string, value: any): this;\n public orWhere(field: string, operator: WhereOperator, value: any): this;\n public orWhere(conditions: Record<string, any>): this;\n public orWhere(\n fieldOrConditions: string | Record<string, any>,\n operatorOrValue?: WhereOperator | any,\n value?: any,\n ): this {\n if (typeof fieldOrConditions === \"object\") {\n this.query.orWhere(fieldOrConditions);\n } else if (value !== undefined) {\n this.query.orWhere(fieldOrConditions, operatorOrValue, value);\n } else {\n this.query.orWhere(fieldOrConditions, operatorOrValue);\n }\n\n return this;\n }\n\n /**\n * {@inheritDoc QueryBuilderContract.whereIn}\n */\n public whereIn(field: string, values: any[]): this {\n this.query.whereIn(field, values);\n return this;\n }\n\n /**\n * {@inheritDoc QueryBuilderContract.whereNotIn}\n */\n public whereNotIn(field: string, values: any[]): this {\n this.query.whereNotIn(field, values);\n return this;\n }\n\n /**\n * {@inheritDoc QueryBuilderContract.whereNull}\n */\n public whereNull(field: string): this {\n this.query.whereNull(field);\n return this;\n }\n\n /**\n * {@inheritDoc QueryBuilderContract.whereNotNull}\n */\n public whereNotNull(field: string): this {\n this.query.whereNotNull(field);\n return this;\n }\n\n /**\n * {@inheritDoc QueryBuilderContract.whereBetween}\n */\n public whereBetween(field: string, range: [any, any]): this {\n this.query.whereBetween(field, range);\n return this;\n }\n\n /**\n * {@inheritDoc QueryBuilderContract.whereLike}\n */\n public whereLike(field: string, pattern: string): this {\n this.query.whereLike(field, pattern);\n return this;\n }\n\n // ============================================================================\n // SELECT / PROJECTION\n // ============================================================================\n\n /**\n * {@inheritDoc QueryBuilderContract.select}\n */\n public select(fields: string[]): this;\n public select(...fields: string[]): this;\n public select(...fields: any[]): this {\n if (Array.isArray(fields[0])) {\n this.query.select(fields[0]);\n } else {\n this.query.select(fields);\n }\n return this;\n }\n\n /**\n * {@inheritDoc QueryBuilderContract.deselect}\n */\n public deselect(fields: string[]): this;\n public deselect(...fields: string[]): this;\n public deselect(...fields: any[]): this {\n if (Array.isArray(fields[0])) {\n this.query.deselect(fields[0]);\n } else {\n this.query.deselect(fields);\n }\n return this;\n }\n\n // ============================================================================\n // ORDERING\n // ============================================================================\n\n /**\n * {@inheritDoc QueryBuilderContract.orderBy}\n */\n public orderBy(field: string, direction: \"asc\" | \"desc\" = \"asc\"): this {\n this.query.orderBy(field, direction);\n return this;\n }\n\n /**\n * {@inheritDoc QueryBuilderContract.sortBy}\n */\n public sortBy(orderBy: Record<string, \"asc\" | \"desc\">): this {\n // Apply each order clause individually\n for (const [field, direction] of Object.entries(orderBy)) {\n this.query.orderBy(field, direction);\n }\n return this;\n }\n\n /**\n * {@inheritDoc QueryBuilderContract.random}\n */\n public random(limit: number): this {\n this.query.orderByRandom(limit);\n return this;\n }\n\n // ============================================================================\n // LIMITING\n // ============================================================================\n\n /**\n * {@inheritDoc QueryBuilderContract.limit}\n */\n public limit(limit: number): this {\n this.query.limit(limit);\n return this;\n }\n\n /**\n * {@inheritDoc QueryBuilderContract.offset}\n */\n public offset(offset: number): this {\n this.query.offset(offset);\n return this;\n }\n\n /**\n * {@inheritDoc QueryBuilderContract.skip}\n */\n public skip(count: number): this {\n return this.offset(count);\n }\n\n // ============================================================================\n // FILTERING (Repository-specific)\n // ============================================================================\n\n /**\n * {@inheritDoc QueryBuilderContract.applyFilters}\n */\n public applyFilters(filters: FilterRules<this>, data: any, options: FilterOptions): this {\n const applicator = new FilterApplicator();\n applicator.apply(this.query as any, filters, data, options);\n return this;\n }\n\n // ============================================================================\n // EXECUTION\n // ============================================================================\n\n /**\n * {@inheritDoc QueryBuilderContract.get}\n */\n public async get(): Promise<T[]> {\n return this.query.get();\n }\n\n /**\n * {@inheritDoc QueryBuilderContract.first}\n */\n public async first(): Promise<T | null> {\n return this.query.first();\n }\n\n /**\n * {@inheritDoc QueryBuilderContract.count}\n */\n public async count(): Promise<number> {\n return this.query.count();\n }\n\n /**\n * {@inheritDoc QueryBuilderContract.paginate}\n */\n public async paginate(page: number, limit: number): Promise<PaginationResult<T>> {\n const result = await this.query.paginate({ limit, page });\n\n // Convert Cascade-Next pagination to repository format\n return {\n data: result.data,\n pagination: {\n ...result.pagination,\n result: result.data.length,\n },\n };\n }\n\n /**\n * {@inheritDoc QueryBuilderContract.cursorPaginate}\n */\n public async cursorPaginate(\n options: CursorPaginationOptions,\n ): Promise<CursorPaginationResult<T>> {\n // Cascade-Next doesn't have built-in cursor pagination yet\n // Implement it manually\n const { limit, cursor, direction = \"forward\", cursorColumn = \"id\" } = options;\n\n // Apply cursor condition\n if (cursor) {\n if (direction === \"forward\") {\n this.where(cursorColumn, \">\", cursor);\n } else {\n this.where(cursorColumn, \"<\", cursor);\n }\n }\n\n // Fetch limit + 1 to check if there are more results\n this.limit(limit + 1);\n\n // Apply ordering\n if (direction === \"forward\") {\n this.orderBy(cursorColumn, \"asc\");\n } else {\n this.orderBy(cursorColumn, \"desc\");\n }\n\n const results = await this.get();\n const hasMore = results.length > limit;\n\n // Remove the extra record\n const documents = hasMore ? results.slice(0, limit) : results;\n\n // Determine cursors\n const nextCursor = hasMore ? (documents[documents.length - 1] as any)[cursorColumn] : undefined;\n const prevCursor = cursor;\n\n return {\n documents,\n pagination: {\n limit,\n result: documents.length,\n hasMore,\n nextCursor,\n prevCursor,\n },\n };\n }\n\n /**\n * {@inheritDoc QueryBuilderContract.chunk}\n */\n public async chunk(size: number, callback: ChunkCallback<T>): Promise<void> {\n return this.query.chunk(size, callback);\n }\n\n // ============================================================================\n // UTILITIES\n // ============================================================================\n\n /**\n * {@inheritDoc QueryBuilderContract.clone}\n */\n public clone(): this {\n return new CascadeQueryBuilder(this.query.clone()) as this;\n }\n}\n","import { type ChildModel, Model } from \"@warlock.js/cascade\";\nimport type {\n ChunkCallback,\n CursorPaginationOptions,\n CursorPaginationResult,\n PaginationResult,\n QueryBuilderContract,\n RepositoryAdapterContract,\n} from \"../../contracts\";\nimport { CascadeQueryBuilder } from \"./cascade-query-builder\";\n\n/**\n * Cascade adapter for Cascade-Next ORM\n * Implements RepositoryAdapterContract for @warlock.js/cascade\n *\n * @template T - The model instance type\n */\nexport class CascadeAdapter<T extends Model<any>> implements RepositoryAdapterContract<T> {\n /**\n * Constructor\n * @param model - Cascade-Next Model class\n */\n public constructor(private model: ChildModel<T>) {}\n\n // ============================================================================\n // QUERY BUILDING\n // ============================================================================\n\n /**\n * {@inheritDoc RepositoryAdapterContract.query}\n */\n public query(): QueryBuilderContract<T> {\n return new CascadeQueryBuilder<T>(this.model.query());\n }\n\n /**\n * Register all events\n */\n public registerEvents(eventsCallback: any): any[] {\n const events: any[] = [];\n\n const modelEvents = this.model.events();\n\n events.push(\n modelEvents.onCreated((model) => {\n eventsCallback(model);\n }),\n modelEvents.onUpdated((model) => {\n eventsCallback(model);\n }),\n modelEvents.onDeleted((model) => {\n eventsCallback(model);\n }),\n );\n\n return events;\n }\n\n // ============================================================================\n // CRUD OPERATIONS\n // ============================================================================\n\n /**\n * {@inheritDoc RepositoryAdapterContract.find}\n */\n public async find(id: any): Promise<T | null> {\n return await this.model.find(id);\n }\n\n /**\n * {@inheritDoc RepositoryAdapterContract.findBy}\n */\n public async findBy(column: string, value: any): Promise<T | null> {\n return (await this.query().where(column, value).first()) as T | null;\n }\n\n /**\n * {@inheritDoc RepositoryAdapterContract.serializeModel}\n */\n public serializeModel(model: T): any {\n return model.serialize?.() || model.toJSON();\n }\n\n /**\n * {@inheritDoc RepositoryAdapterContract.deserializeModel}\n */\n public deserializeModel(data: any): T {\n return this.model.deserialize(data);\n }\n\n /**\n * {@inheritDoc RepositoryAdapterContract.resolveRepositoryName}\n */\n public resolveRepositoryName(): string {\n return this.model.table;\n }\n\n /**\n * {@inheritDoc RepositoryAdapterContract.create}\n */\n public async create(data: any): Promise<T> {\n return this.model.create(data);\n }\n\n /**\n * {@inheritDoc RepositoryAdapterContract.update}\n */\n public async update(id: any, data: any): Promise<T> {\n const model = id instanceof Model ? id : await this.model.find(id);\n if (!model) {\n throw new Error(`Model not found with id ${id}`);\n }\n\n await model.save({ merge: data });\n return model as T;\n }\n\n /**\n * {@inheritDoc RepositoryAdapterContract.delete}\n */\n public async delete(id: any): Promise<void> {\n await this.model.delete({ id });\n }\n\n // ============================================================================\n // BULK OPERATIONS\n // ============================================================================\n\n /**\n * {@inheritDoc RepositoryAdapterContract.updateMany}\n */\n public async updateMany(filter: any, data: any): Promise<number> {\n const query = this.query();\n\n // Apply filter\n if (typeof filter === \"object\") {\n query.where(filter);\n }\n\n // Get matching records\n const records = await query.get();\n\n // Update each record\n for (const record of records) {\n await this.update(record.id, data);\n }\n\n return records.length;\n }\n\n /**\n * {@inheritDoc RepositoryAdapterContract.deleteMany}\n */\n public async deleteMany(filter: any): Promise<number> {\n const query = this.query();\n\n // Apply filter\n if (typeof filter === \"object\") {\n query.where(filter);\n }\n\n // Get matching records\n const records = await query.get();\n\n // Delete each record\n for (const record of records) {\n await record.destroy();\n }\n\n return records.length;\n }\n\n // ============================================================================\n // COUNTING\n // ============================================================================\n\n /**\n * {@inheritDoc RepositoryAdapterContract.count}\n */\n public async count(filter?: any): Promise<number> {\n const query = this.query();\n\n if (filter && typeof filter === \"object\") {\n query.where(filter);\n }\n\n return query.count();\n }\n\n // ============================================================================\n // PAGINATION\n // ============================================================================\n\n /**\n * {@inheritDoc RepositoryAdapterContract.paginate}\n */\n public async paginate(page: number, limit: number): Promise<PaginationResult<T>> {\n return this.query().paginate(page, limit);\n }\n\n /**\n * {@inheritDoc RepositoryAdapterContract.cursorPaginate}\n */\n public async cursorPaginate(\n options: CursorPaginationOptions,\n ): Promise<CursorPaginationResult<T>> {\n return this.query().cursorPaginate(options);\n }\n\n // ============================================================================\n // CHUNKING\n // ============================================================================\n\n /**\n * {@inheritDoc RepositoryAdapterContract.chunk}\n */\n public async chunk(size: number, callback: ChunkCallback<T>): Promise<void> {\n return this.query().chunk(size, callback);\n }\n\n // ============================================================================\n // MODEL CREATION\n // ============================================================================\n\n /**\n * {@inheritDoc RepositoryAdapterContract.createModel}\n */\n public createModel(data: any): T {\n return new (this.model as any)(data) as T;\n }\n}\n","import { cache, type CacheDriver } from \"@warlock.js/cache\";\nimport { config } from \"../config\";\nimport { CascadeAdapter } from \"./adapters/cascade\";\nimport type {\n AllRepositoryOptions,\n ChunkCallback,\n CursorPaginationResult,\n FilterRules,\n PaginationResult,\n QueryBuilderContract,\n RepositoryAdapterContract,\n RepositoryOptions,\n RepositoryOptionsWithCursor,\n RepositoryOptionsWithPages,\n SaveMode,\n} from \"./contracts\";\n\n/**\n * Base repository manager class\n * Provides ORM-agnostic data access layer with support for listing, filtering,\n * caching, pagination, and CRUD operations\n *\n * @template T - The type of records managed by this repository\n *\n * @example\n * // Extend with source\n * class UserRepository extends RepositoryManager<User> {\n * protected source = User;\n * protected filterBy = { email: \"=\", role: [\"in\", \"role\"] };\n * }\n *\n * @example\n * // Direct instantiation with adapter\n * const userRepo = new RepositoryManager<User>(new PrismaAdapter(prisma.user));\n */\nexport class RepositoryManager<T = unknown> {\n /**\n * Adapter instance (lazy-loaded)\n * @private\n */\n protected _adapter?: RepositoryAdapterContract<T>;\n\n /**\n * Data source reference (Model, Prisma client, table name, etc.)\n * Used by createDefaultAdapter to instantiate the appropriate adapter\n * @protected\n */\n protected source?: any;\n\n /**\n * Get adapter instance (lazy-loaded)\n * Resolution order:\n * 1. Use injected adapter from constructor\n * 2. Use config-based resolver if available\n * 3. Use createDefaultAdapter\n *\n * @returns Adapter instance\n * @protected\n */\n protected get adapter(): RepositoryAdapterContract<T> {\n if (this._adapter) {\n return this._adapter;\n }\n\n // Try config-based resolver\n const resolver = config.key(\"repository.adapterResolver\");\n\n if (resolver) {\n this._adapter = resolver(this);\n } else {\n this._adapter = config.get(\"repository.defaultAdapter\") || this.createDefaultAdapter();\n }\n\n // Adapter is guaranteed to be set at this point\n return this._adapter!;\n }\n\n // ============================================================================\n // CONFIGURATION PROPERTIES\n // ============================================================================\n\n /**\n * Filter definitions\n * Maps filter keys to filter rules\n * @protected\n */\n protected filterBy: FilterRules = {};\n\n /**\n * Default repository options\n * @protected\n */\n protected defaultOptions: Partial<RepositoryOptions> = {};\n\n /**\n * Simple select columns (used with simple filter)\n * @protected\n */\n protected simpleSelectColumns: string[] = [];\n\n /**\n * Active column name\n * @default \"isActive\"\n * @protected\n */\n protected isActiveColumn = \"isActive\";\n\n /**\n * Active column value\n * @default true\n * @protected\n */\n protected isActiveValue: any = true;\n\n /**\n * Repository name (for events)\n * @protected\n */\n protected name?: string;\n\n /**\n * Whether caching is enabled\n * @default true\n * @protected\n */\n protected isCacheable = true;\n\n /**\n * Cache driver instance\n * @protected\n */\n protected cacheDriver!: CacheDriver<any, any>;\n\n /**\n * List of all events callbacks\n */\n protected eventsCallbacks: any[] = [];\n\n /**\n * Constructor\n * @param adapter - Optional adapter instance for direct injection\n */\n public constructor(adapter?: RepositoryAdapterContract<T>) {\n if (adapter) {\n this._adapter = adapter;\n }\n\n if (!this.cacheDriver) {\n this.cacheDriver = config.key(\"repository.cacheDriver\") || cache;\n }\n\n // Wait for constructor to finish and all properties are properly registered\n // specially for adapter to get instanciated\n setTimeout(() => {\n this.registerEvents();\n }, 0);\n }\n\n /**\n * Register events\n */\n public registerEvents() {\n this.eventsCallbacks.push(...this.adapter.registerEvents(this.clearCache.bind(this)));\n }\n\n /**\n * Unregister events\n */\n public cleanuEvents() {\n this.eventsCallbacks.forEach((callback) => {\n callback();\n });\n this.eventsCallbacks = [];\n }\n\n /**\n * Create default adapter instance\n * Override this method to provide custom adapter creation logic\n *\n * @returns Adapter instance\n * @throws Error if no source is configured\n * @protected\n */\n protected createDefaultAdapter(): RepositoryAdapterContract<T> {\n if (!this.source) {\n throw new Error(\n \"No adapter or source configured. Either pass an adapter to the constructor, \" +\n \"set the 'source' property, or configure 'repository.adapterResolver' in config.\",\n );\n }\n\n // Default: assume source is a Cascade Model\n if (typeof this.source === \"function\") {\n // Lazy import to avoid circular dependencies\n return new CascadeAdapter(this.source) as unknown as RepositoryAdapterContract<T>;\n }\n\n throw new Error(\n \"Cannot create default adapter for this source type. \" +\n \"Please provide an adapter or configure repository.adapterResolver.\",\n );\n }\n\n // ============================================================================\n // UTILITY METHODS\n // ============================================================================\n\n /**\n * Get repository name\n * @returns Repository name\n * @public\n */\n public getName(): string {\n if (this.name) {\n return this.name;\n }\n\n // Try to get collection name from source\n this.name = this.adapter.resolveRepositoryName() || \"unknown\";\n\n return this.name;\n }\n\n /**\n * Create new query builder instance\n * @returns Query builder\n * @public\n */\n public newQuery() {\n return this.adapter.query();\n }\n\n /**\n * Create new model instance\n * @param data - Model data\n * @returns Model instance\n * @public\n */\n public newModel(data?: any): T {\n return this.adapter.createModel(data);\n }\n\n /**\n * Get active filter object\n * @returns Filter object for active records\n * @protected\n */\n protected getIsActiveFilter() {\n return {\n [this.isActiveColumn]: this.isActiveValue,\n };\n }\n\n // ============================================================================\n // FINDING METHODS\n // ============================================================================\n\n /**\n * Find a record by ID\n * @param id - Record ID or model instance\n * @returns Promise resolving to record or null\n * @public\n */\n public async find(id: string | number | T): Promise<T | null> {\n return this.adapter.find(id);\n }\n\n /**\n * Find a record by column value\n * @param column - Column name\n * @param value - Value to search for\n * @returns Promise resolving to record or null\n * @public\n */\n public async findBy(column: string, value: any): Promise<T | null> {\n return this.adapter.findBy(column, value);\n }\n\n /**\n * Find active record by ID\n * @param id - Record ID or model instance\n * @returns Promise resolving to active record or null\n * @public\n */\n public async findActive(id: string | number | T): Promise<T | null> {\n return this.newQuery()\n .where({\n id,\n ...this.getIsActiveFilter(),\n })\n .first();\n }\n\n /**\n * Find active record by column value\n * @param column - Column name\n * @param value - Value to search for\n * @returns Promise resolving to active record or null\n * @public\n */\n public async findByActive(column: string, value: any): Promise<T | null> {\n return this.newQuery()\n .where({\n [column]: value,\n ...this.getIsActiveFilter(),\n })\n .first();\n }\n\n /**\n * Get first record matching options\n * @param options - Repository options\n * @returns Promise resolving to first record or null\n * @public\n */\n public async first(options?: RepositoryOptions): Promise<T | null> {\n const query = this.newQuery();\n const opts = this.prepareOptions(options);\n\n this.applyOptionsToQuery(query, opts);\n\n return query.limit(1).first();\n }\n\n /**\n * Get first active record\n * @param options - Repository options\n * @returns Promise resolving to first active record or null\n * @public\n */\n public async firstActive(options?: RepositoryOptions): Promise<T | null> {\n return this.first({\n ...this.getIsActiveFilter(),\n ...options,\n });\n }\n\n /**\n * Get last record matching options\n * @param options - Repository options\n * @returns Promise resolving to last record or null\n * @public\n */\n public async last(options?: RepositoryOptions): Promise<T | null> {\n return this.first({\n orderBy: {\n id: \"desc\",\n },\n ...options,\n });\n }\n\n /**\n * Get last active record\n * @param options - Repository options\n * @returns Promise resolving to last active record or null\n * @public\n */\n public async lastActive(options?: RepositoryOptions): Promise<T | null> {\n return this.last({\n ...this.getIsActiveFilter(),\n ...options,\n });\n }\n\n // ============================================================================\n // LISTING METHODS\n // ============================================================================\n\n /**\n * List records with pagination\n * Supports both traditional page-based and cursor-based pagination\n *\n * @param options - Repository options\n * @returns Promise resolving to pagination result\n *\n * @example\n * // Traditional pagination (default)\n * const result = await repo.list({ page: 2, limit: 10 });\n *\n * @example\n * // Cursor pagination\n * const result = await repo.list({\n * paginationMode: \"cursor\",\n * limit: 20,\n * cursor: lastId,\n * direction: \"next\"\n * });\n *\n * @public\n */\n public async list(options?: RepositoryOptionsWithPages): Promise<PaginationResult<T>>;\n public async list(options: RepositoryOptionsWithCursor): Promise<CursorPaginationResult<T>>;\n public async list(\n options?: RepositoryOptions,\n ): Promise<PaginationResult<T> | CursorPaginationResult<T>> {\n return this._listImpl(options);\n }\n\n /**\n * Internal list implementation - no overloads, handles union type\n * @param options - Repository options\n * @returns Promise resolving to pagination result\n * @private\n */\n private async _listImpl(\n options?: RepositoryOptions,\n ): Promise<PaginationResult<T> | CursorPaginationResult<T>> {\n const query = this.newQuery();\n\n const opts = this.prepareOptions(options);\n\n // Apply options (filters, select, orderBy, etc.)\n this.applyOptionsToQuery(query, opts);\n\n const paginationMode = opts.paginationMode || \"pages\";\n\n if (paginationMode === \"cursor\") {\n // Cursor pagination\n return query.cursorPaginate({\n limit: opts.limit || opts.defaultLimit || 15,\n cursor: opts.cursor,\n direction: opts.direction,\n cursorColumn: opts.cursorColumn,\n });\n }\n\n // Traditional page-based pagination (default)\n const page = opts.page || 1;\n const limit = opts.limit || opts.defaultLimit || 15;\n\n return query.paginate(page, limit);\n }\n\n /**\n * List all records without pagination\n * @param options - Repository options\n * @returns Promise resolving to array of records\n * @public\n */\n public async all(options?: AllRepositoryOptions): Promise<T[]> {\n const query = this.newQuery();\n\n // Apply options\n const opts = this.prepareOptions(options);\n this.applyOptionsToQuery(query, opts);\n\n return query.get();\n }\n\n /**\n * List active records with pagination\n * Supports both page-based and cursor-based pagination\n *\n * @param options - Repository options\n * @returns Promise resolving to pagination result\n * @public\n */\n public async listActive(options?: RepositoryOptionsWithPages): Promise<PaginationResult<T>>;\n public async listActive(options: RepositoryOptionsWithCursor): Promise<CursorPaginationResult<T>>;\n public async listActive(\n options?: RepositoryOptions,\n ): Promise<PaginationResult<T> | CursorPaginationResult<T>> {\n return this._listImpl({\n ...this.getIsActiveFilter(),\n ...options,\n });\n }\n\n /**\n * List all active records without pagination\n * @param options - Repository options\n * @returns Promise resolving to array of active records\n * @public\n */\n public async allActive(options?: AllRepositoryOptions): Promise<T[]> {\n return this.all({\n ...this.getIsActiveFilter(),\n ...options,\n });\n }\n\n // ============================================================================\n // EXISTENCE CHECKS\n // ============================================================================\n\n /**\n * Check if record exists matching filter\n * @param filter - Repository options\n * @returns Promise resolving to true if exists\n * @public\n */\n public async exists(filter?: RepositoryOptions): Promise<boolean> {\n return !!(await this.first(filter));\n }\n\n /**\n * Check if active record exists matching filter\n * @param filter - Repository options\n * @returns Promise resolving to true if active record exists\n * @public\n */\n public async existsActive(filter?: RepositoryOptions): Promise<boolean> {\n return !!(await this.firstActive(filter));\n }\n\n /**\n * Check if record exists by ID\n * @param id - Record ID\n * @returns Promise resolving to true if exists\n * @public\n */\n public async idExists(id: number | string): Promise<boolean> {\n return !!(await this.find(id));\n }\n\n /**\n * Check if active record exists by ID\n * @param id - Record ID\n * @returns Promise resolving to true if active record exists\n * @public\n */\n public async idExistsActive(id: number | string): Promise<boolean> {\n return !!(await this.findActive(id));\n }\n\n /**\n * Prepare options\n */\n protected prepareOptions(options?: RepositoryOptions): RepositoryOptions {\n return { ...(this.defaultOptions || {}), ...(options || {}) };\n }\n\n // ============================================================================\n // HELPER METHODS\n // ============================================================================\n\n /**\n * Apply repository options to query\n * @param query - Query builder instance\n * @param options - Repository options\n * @protected\n */\n protected applyOptionsToQuery(\n query: QueryBuilderContract<T>,\n options: RepositoryOptions,\n ): RepositoryOptions {\n // Apply filters\n if (this.filterBy && Object.keys(this.filterBy).length > 0) {\n query.applyFilters(this.filterBy, options, {\n dateFormat: \"DD-MM-YYYY\",\n dateTimeFormat: \"DD-MM-YYYY HH:mm:ss\",\n });\n }\n\n // Apply select\n if (options.select) {\n query.select(options.select);\n }\n\n // Apply deselect\n if (options.deselect) {\n query.deselect(options.deselect);\n }\n\n if (options.simpleSelect && this.simpleSelectColumns.length > 0) {\n query.select(this.simpleSelectColumns);\n }\n\n // Apply ordering\n if (options.orderBy) {\n if (options.orderBy === \"random\") {\n query.random();\n } else if (Array.isArray(options.orderBy)) {\n query.orderBy(options.orderBy[0], options.orderBy[1]);\n } else if (typeof options.orderBy === \"object\") {\n query.sortBy(options.orderBy);\n }\n }\n\n // Apply limit (for non-paginated queries)\n if (options.limit && options.paginate === false) {\n query.limit(options.limit);\n }\n\n // Apply custom perform function\n if (options?.perform) {\n options.perform(query, options);\n }\n\n return options;\n }\n\n // ============================================================================\n // CRUD OPERATIONS\n // ============================================================================\n\n /**\n * Create a new record\n * @param data - Record data\n * @returns Promise resolving to created record\n * @public\n */\n public async create(data: any): Promise<T> {\n return this.adapter.create(data);\n }\n\n /**\n * Update a record by ID\n * @param id - Record ID\n * @param data - Updated data\n * @returns Promise resolving to updated record\n * @public\n */\n public async update(id: string | number | any, data: any): Promise<T> {\n return this.adapter.update(id, data);\n }\n\n /**\n * Delete a record by ID\n * @param id - Record ID\n * @returns Promise that resolves when deletion is complete\n * @public\n */\n public async delete(id: string | number): Promise<void> {\n return this.adapter.delete(id);\n }\n\n // ============================================================================\n // BULK OPERATIONS\n // ============================================================================\n\n /**\n * Update multiple records matching filter\n * @param filter - Filter criteria\n * @param data - Updated data\n * @returns Promise resolving to number of updated records\n * @public\n */\n public async updateMany(filter: any, data: any): Promise<number> {\n return this.adapter.updateMany(filter, data);\n }\n\n /**\n * Delete multiple records matching filter\n * @param filter - Filter criteria\n * @returns Promise resolving to number of deleted records\n * @public\n */\n public async deleteMany(filter: any): Promise<number> {\n return this.adapter.deleteMany(filter);\n }\n\n // ============================================================================\n // CHUNKING\n // ============================================================================\n\n /**\n * Process records in chunks\n * @param size - Chunk size\n * @param callback - Function called for each chunk\n * @param options - Repository options\n * @returns Promise that resolves when chunking is complete\n * @public\n */\n public async chunk(\n size: number,\n callback: ChunkCallback<T>,\n options?: RepositoryOptions,\n ): Promise<void> {\n const query = this.newQuery();\n const opts = this.prepareOptions(options);\n\n this.applyOptionsToQuery(query, opts);\n\n return query.chunk(size, callback);\n }\n\n /**\n * Process active records in chunks\n * @param size - Chunk size\n * @param callback - Function called for each chunk\n * @param options - Repository options\n * @returns Promise that resolves when chunking is complete\n * @public\n */\n public async chunkActive(\n size: number,\n callback: ChunkCallback<T>,\n options?: RepositoryOptions,\n ): Promise<void> {\n return this.chunk(size, callback, {\n ...this.getIsActiveFilter(),\n ...options,\n });\n }\n\n // ============================================================================\n // CONVENIENCE METHODS\n // ============================================================================\n\n /**\n * Get latest records (ordered by ID descending)\n * Supports both pagination modes\n *\n * @param options - Repository options\n * @returns Promise resolving to pagination result\n * @public\n */\n public async latest(options?: RepositoryOptionsWithPages): Promise<PaginationResult<T>>;\n public async latest(options: RepositoryOptionsWithCursor): Promise<CursorPaginationResult<T>>;\n public async latest(\n options?: RepositoryOptions,\n ): Promise<PaginationResult<T> | CursorPaginationResult<T>> {\n return this._listImpl({\n orderBy: [\"id\", \"desc\"],\n ...options,\n });\n }\n\n /**\n * Get oldest records (ordered by ID ascending)\n * Supports both pagination modes\n *\n * @param options - Repository options\n * @returns Promise resolving to pagination result\n * @public\n */\n public async oldest(options?: RepositoryOptionsWithPages): Promise<PaginationResult<T>>;\n public async oldest(options: RepositoryOptionsWithCursor): Promise<CursorPaginationResult<T>>;\n public async oldest(\n options?: RepositoryOptions,\n ): Promise<PaginationResult<T> | CursorPaginationResult<T>> {\n return this._listImpl({\n orderBy: [\"id\", \"asc\"],\n ...options,\n });\n }\n\n /**\n * Get latest active records\n * Supports both pagination modes\n *\n * @param options - Repository options\n * @returns Promise resolving to pagination result\n * @public\n */\n public async latestActive(options?: RepositoryOptionsWithPages): Promise<PaginationResult<T>>;\n public async latestActive(\n options: RepositoryOptionsWithCursor,\n ): Promise<CursorPaginationResult<T>>;\n public async latestActive(\n options?: RepositoryOptions,\n ): Promise<PaginationResult<T> | CursorPaginationResult<T>> {\n return this._listImpl({\n orderBy: [\"id\", \"desc\"],\n ...this.getIsActiveFilter(),\n ...options,\n });\n }\n\n /**\n * Get oldest active records\n * Supports both pagination modes\n *\n * @param options - Repository options\n * @returns Promise resolving to pagination result\n * @public\n */\n public async oldestActive(options?: RepositoryOptionsWithPages): Promise<PaginationResult<T>>;\n public async oldestActive(\n options: RepositoryOptionsWithCursor,\n ): Promise<CursorPaginationResult<T>>;\n public async oldestActive(\n options?: RepositoryOptions,\n ): Promise<PaginationResult<T> | CursorPaginationResult<T>> {\n return this._listImpl({\n orderBy: [\"id\", \"asc\"],\n ...this.getIsActiveFilter(),\n ...options,\n });\n }\n\n // ============================================================================\n // LIFECYCLE HOOKS (Override these in child classes)\n // ============================================================================\n\n /**\n * Called before listing records\n * @param options - Repository options\n * @protected\n */\n protected async beforeListing(options: any): Promise<void> {\n // Override in child class\n }\n\n /**\n * Called after listing records\n * @param result - Pagination result\n * @param options - Repository options\n * @protected\n */\n protected async onList(result: PaginationResult<T>, options: any): Promise<void> {\n // Override in child class\n }\n\n /**\n * Called before creating a record\n * @param data - Record data\n * @protected\n */\n protected async onCreating(data: any): Promise<void> {\n // Override in child class\n }\n\n /**\n * Called after creating a record\n * @param record - Created record\n * @param data - Original data\n * @protected\n */\n protected async onCreate(record: T, data: any): Promise<void> {\n // Override in child class\n }\n\n /**\n * Called before updating a record\n * @param id - Record ID\n * @param data - Updated data\n * @protected\n */\n protected async onUpdating(id: string | number, data: any): Promise<void> {\n // Override in child class\n }\n\n /**\n * Called after updating a record\n * @param record - Updated record\n * @param data - Original data\n * @protected\n */\n protected async onUpdate(record: T, data: any): Promise<void> {\n // Override in child class\n }\n\n /**\n * Called before saving a record (create or update)\n * @param data - Record data\n * @param mode - Save mode\n * @protected\n */\n protected async onSaving(data: any, mode: SaveMode): Promise<void> {\n // Override in child class\n }\n\n /**\n * Called after saving a record (create or update)\n * @param record - Saved record\n * @param data - Original data\n * @param mode - Save mode\n * @protected\n */\n protected async onSave(record: T, data: any, mode: SaveMode): Promise<void> {\n // Override in child class\n }\n\n /**\n * Called before deleting a record\n * @param id - Record ID\n * @protected\n */\n protected async onDeleting(id: string | number): Promise<void> {\n // Override in child class\n }\n\n /**\n * Called after deleting a record\n * @param id - Record ID\n * @protected\n */\n protected async onDelete(id: string | number): Promise<void> {\n // Override in child class\n }\n\n // ============================================================================\n // COUNT METHODS\n // ============================================================================\n\n /**\n * Count total records matching options\n * @param options - Repository options\n * @returns Promise resolving to count\n * @public\n */\n public async count(options?: RepositoryOptions): Promise<number> {\n const query = this.newQuery();\n const opts = this.prepareOptions(options);\n\n this.applyOptionsToQuery(query, opts);\n\n return await query.count();\n }\n\n /**\n * Count total active records\n * @param options - Repository options\n * @returns Promise resolving to count of active records\n * @public\n */\n public async countActive(options?: RepositoryOptions): Promise<number> {\n return await this.count({\n ...this.getIsActiveFilter(),\n ...options,\n });\n }\n\n /**\n * Count records with caching\n * @param options - Repository options\n * @returns Promise resolving to cached count\n * @public\n */\n public async countCached(options?: RepositoryOptions): Promise<number> {\n if (!this.isCacheable || !this.cacheDriver) {\n return await this.count(options);\n }\n\n const opts = this.prepareOptions(options);\n\n const cacheKey = this.cacheKey(\"count\", opts);\n let count = await this.cacheDriver.get(cacheKey);\n\n if (count !== undefined) return count;\n\n count = await this.count(options);\n await this.cache(cacheKey, count);\n return count;\n }\n\n /**\n * Count active records with caching\n * @param options - Repository options\n * @returns Promise resolving to cached count of active records\n * @public\n */\n public async countActiveCached(options?: RepositoryOptions): Promise<number> {\n return await this.countCached({\n ...this.getIsActiveFilter(),\n ...options,\n });\n }\n\n // ============================================================================\n // CACHING METHODS\n // ============================================================================\n\n /**\n * Set cache driver\n * @param driver - Cache driver instance\n * @returns This repository for chaining\n * @public\n */\n public setCacheDriver(driver: any): this {\n this.cacheDriver = driver;\n return this;\n }\n\n /**\n * Get cache driver\n * @returns Cache driver instance\n * @public\n */\n public getCacheDriver(): any {\n return this.cacheDriver;\n }\n\n /**\n * Generate cache key\n * @param key - Base key or object\n * @param moreOptions - Additional options for key\n * @returns Generated cache key\n * @protected\n */\n protected cacheKey(key: string | Record<string, any>, moreOptions?: Record<string, any>): string {\n let cacheKey = `repositories.${this.getName()}`;\n\n if (key) {\n cacheKey += \".\" + (typeof key === \"string\" ? key : JSON.stringify(key));\n }\n\n if (moreOptions) {\n cacheKey += \".\" + JSON.stringify(moreOptions);\n }\n\n return cacheKey;\n }\n\n /**\n * Cache a value\n * @param key - Cache key\n * @param value - Value to cache\n * @protected\n */\n protected async cache(key: string, value: any): Promise<void> {\n if (!this.isCacheable || !this.cacheDriver) return;\n await this.cacheDriver.set(key, value);\n }\n\n /**\n * Get cached record by ID\n * @param id - Record ID\n * @returns Promise resolving to cached record or null\n * @public\n */\n public async getCached(id: string | number): Promise<T | null> {\n return await this.getCachedBy(\"id\", Number(id));\n }\n\n /**\n * Get cached record by column value\n * @param column - Column name\n * @param value - Column value\n * @param cacheKeyOptions - Additional cache key options\n * @returns Promise resolving to cached record or undefined\n * @public\n */\n public async getCachedBy(\n column: string,\n value: any,\n cacheKeyOptions?: Record<string, any>,\n ): Promise<T | null> {\n if (!this.isCacheable || !this.cacheDriver) {\n return await this.findBy(column, value);\n }\n\n const cacheKey = this.cacheKey(`data.${column}.${value}`, cacheKeyOptions);\n const cachedData = await this.cacheDriver.get(cacheKey);\n\n if (cachedData) {\n return this.newModel(cachedData);\n }\n\n const model = await this.findBy(column, value);\n if (!model) return null;\n\n await this.cache(cacheKey, this.adapter.serializeModel(model));\n return model;\n }\n\n /**\n * Get all cached records\n * @param options - Repository options\n * @returns Promise resolving to array of cached records\n * @public\n */\n public async allCached(options?: AllRepositoryOptions): Promise<T[]> {\n if (!this.isCacheable || !this.cacheDriver) {\n return await this.all(options);\n }\n\n const opts = this.prepareOptions(options);\n\n const cacheKey = this.cacheKey(\"all\", opts);\n const cachedData: T[] = await this.cacheDriver.get(cacheKey);\n\n if (cachedData) {\n return cachedData.map((record) => this.adapter.deserializeModel(record));\n }\n\n const records = await this.all(options);\n await this.cache(\n cacheKey,\n records.map((record) => this.adapter.serializeModel(record)),\n );\n return records;\n }\n\n /**\n * Get all active cached records\n * @param options - Repository options\n * @returns Promise resolving to array of cached active records\n * @public\n */\n public async allActiveCached(options?: AllRepositoryOptions): Promise<T[]> {\n return await this.allCached({\n ...this.getIsActiveFilter(),\n ...options,\n });\n }\n\n /**\n * List cached records with pagination\n * @param options - Repository options\n * @returns Promise resolving to cached pagination result\n * @public\n */\n public async listCached(options?: RepositoryOptions): Promise<PaginationResult<T>> {\n if (!this.isCacheable || !this.cacheDriver) {\n return (await this._listImpl(options)) as PaginationResult<T>;\n }\n\n const opts = this.prepareOptions(options);\n\n const cacheKey = this.cacheKey(\"list\", opts);\n const cachedData = await this.cacheDriver.get(cacheKey);\n\n if (cachedData) {\n return {\n data: (cachedData?.data || []).map((record: T) => this.adapter.deserializeModel(record)),\n pagination: cachedData.pagination,\n };\n }\n\n const result = (await this._listImpl(options)) as PaginationResult<T>;\n await this.cache(cacheKey, {\n data: result.data.map((record) => this.adapter.serializeModel(record)),\n pagination: result.pagination,\n });\n return result;\n }\n\n /**\n * List active cached records with pagination\n * @param options - Repository options\n * @returns Promise resolving to cached pagination result of active records\n * @public\n */\n public async listActiveCached(options?: RepositoryOptions): Promise<PaginationResult<T>> {\n return await this.listCached({\n ...this.getIsActiveFilter(),\n ...options,\n });\n }\n\n /**\n * Get active cached record by ID\n * @param id - Record ID\n * @returns Promise resolving to cached active record or undefined\n * @public\n */\n public async getActiveCached(id: string | number): Promise<T | undefined> {\n const model = await this.getCached(id);\n if (!model) return undefined;\n\n // Check if model is active\n const isActive = (model as any)[this.isActiveColumn] === this.isActiveValue;\n return isActive ? model : undefined;\n }\n\n /**\n * Cache a model\n * @param model - Model to cache\n * @public\n */\n public async cacheModel(model: T): Promise<void> {\n if (!this.isCacheable || !this.cacheDriver) return;\n\n const id = (model as any).id;\n if (!id) return;\n\n const cacheKey = this.cacheKey(`id.${id}`);\n await this.cache(cacheKey, this.adapter.serializeModel(model));\n }\n\n /**\n * Cleanup all events and cache as well\n * Please note this is mostly used with development server to be\n * exported as cleanup\n *\n * @example\n * ```typescript\n */\n public cleanup() {\n this.clearCache();\n this.cleanuEvents();\n }\n\n /**\n * Cleanup all events and cache as well\n * Please note this is mostly used with development server to be\n * exported as cleanup\n * export const cleanup = usersRepository.cleanup.bind(usersRepository);\n */\n public $cleanup() {\n this.cleanup();\n this.cacheDriver.flush();\n }\n\n /**\n * Clear all cache for this repository\n * @public\n */\n public async clearCache(): Promise<void> {\n if (!this.isCacheable || !this.cacheDriver) return;\n\n await this.cacheDriver.removeNamespace(this.cacheKey(\"\"));\n }\n\n /**\n * Clear cache for specific model\n * @param model - Model to clear cache for\n * @public\n */\n public async clearModelCache(model: T): Promise<void> {\n if (!this.isCacheable || !this.cacheDriver) return;\n\n const id = (model as any).id;\n if (!id) return;\n\n const cacheKey = this.cacheKey(`id.${id}`);\n await this.cacheDriver.remove(cacheKey);\n }\n\n /**\n * Map documents to models\n * @param documents - Array of document data\n * @returns Array of model instances\n * @protected\n */\n protected mapModels(documents: any[]): T[] {\n return documents.map((doc) => this.newModel(doc));\n }\n\n // ============================================================================\n // CONVENIENCE METHODS\n // ============================================================================\n\n /**\n * Find or create a record\n * @param where - Conditions to find by\n * @param data - Data to create if not found\n * @returns Promise resolving to found or created record\n * @public\n */\n public async findOrCreate(where: Record<string, any>, data: Record<string, any>): Promise<T> {\n const model = await this.first(where);\n return model || (await this.create(data));\n }\n\n /**\n * Update or create a record\n * @param where - Conditions to find by\n * @param data - Data to update or create\n * @returns Promise resolving to updated or created record\n * @public\n */\n public async updateOrCreate(where: Record<string, any>, data: Record<string, any>): Promise<T> {\n const model = await this.first(where);\n if (model) {\n return await this.update(model, data);\n }\n return await this.create(data);\n }\n}\n","import { isObject } from \"@mongez/supportive-is\";\nimport dayjs from \"dayjs\";\nimport { storage } from \"../storage\";\nimport { uploadsUrl, url } from \"../utils/urls\";\nimport { type LocalizedObject } from \"./../utils/get-localized\";\nimport { ResourceFieldBuilderDateOutputOptions, type ResourceOutputValueCastType } from \"./types\";\n\nexport class ResourceFieldBuilder {\n /**\n * Field value\n */\n protected fieldValue?: unknown;\n\n /**\n * Whether the value is nullable\n * If set to false and value is null, it will be returned as undefined\n */\n protected isNullable = false;\n\n /**\n * Default value\n */\n protected defaultValue?: unknown;\n\n /**\n * Date format\n */\n protected dateFormat = \"DD-MM-YYYY hh:mm:ss A\";\n\n /**\n * Input key\n */\n protected inputKeyToUse?: string;\n\n /**\n * Add a condition before transforming the value\n */\n protected condition?: () => boolean;\n\n /**\n * Define how date fields are returned\n * If type of the date options is string then it will be returned as a string\n * otherwise it will be returned as an object contains the date options\n */\n protected dateOptionsInput: ResourceFieldBuilderDateOutputOptions = {\n format: true,\n timestamp: true,\n timezone: false,\n locale: false,\n offset: false,\n human: true,\n };\n\n /**\n * Constructor\n */\n public constructor(protected readonly type: ResourceOutputValueCastType) {\n //\n }\n\n /**\n * Set input key\n * Will be used in transformation if provided\n */\n public setInputKey(key: string) {\n this.inputKeyToUse = key;\n\n return this;\n }\n\n /**\n * Add a condition before transforming the value\n */\n public when(condition: () => boolean) {\n this.condition = condition;\n return this;\n }\n\n /**\n * Set whether the value is nullable\n */\n public nullable() {\n this.isNullable = true;\n return this;\n }\n\n /**\n * Get input key\n */\n public getInputKey() {\n return this.inputKeyToUse;\n }\n\n /**\n * Set default value\n */\n public default(value: unknown) {\n this.defaultValue = value;\n\n return this;\n }\n\n /**\n * Set field format\n */\n public format(format: string) {\n this.dateFormat = format;\n\n return this;\n }\n\n /**\n * Set date options\n * This will override current date options\n */\n public dateOptions(options: ResourceFieldBuilderDateOutputOptions) {\n this.dateOptionsInput = options;\n\n return this;\n }\n\n /**\n * Transform the value\n */\n public transform(value: any, locale?: string) {\n if (value === undefined) return this.defaultValue;\n\n if (this.condition && !this.condition()) return this.defaultValue;\n\n if (value === null) {\n return this.isNullable ? null : this.defaultValue;\n }\n\n switch (this.type) {\n case \"string\":\n return String(value);\n case \"number\":\n return Number(value);\n case \"boolean\":\n return Boolean(value);\n case \"float\":\n return parseFloat(value);\n case \"int\":\n return parseInt(value);\n case \"date\":\n return this.transformDate(value as string | Date, locale);\n case \"localized\":\n return this.transformLocalized(value as LocalizedObject[], locale);\n case \"url\":\n return url(value as string);\n case \"uploadsUrl\":\n return uploadsUrl(value as string);\n case \"storageUrl\":\n return storage.url(value as string);\n case \"object\":\n return isObject(value) && !Array.isArray(value) ? value : undefined;\n case \"array\":\n return Array.isArray(value) ? value : undefined;\n }\n }\n\n /**\n * Transform date value\n */\n protected transformDate(value: string | Date, locale?: string) {\n if (typeof this.dateOptionsInput === \"string\") {\n if (this.dateOptionsInput === \"format\") {\n return dayjs(value).format(this.dateFormat);\n }\n\n if (this.dateOptionsInput === \"timestamp\") {\n return dayjs(value).valueOf();\n }\n\n if (this.dateOptionsInput === \"human\") {\n return (dayjs as any)(value).fromNow();\n }\n\n if (this.dateOptionsInput === \"locale\") {\n if (!locale) {\n return dayjs(value).format(this.dateFormat);\n }\n\n return dayjs(value).locale(locale).format(this.dateFormat);\n }\n }\n\n // now manage it as an object based on date options what's marked as true\n const output: {\n format?: string;\n timestamp?: number;\n human?: string;\n locale?: string;\n } = {};\n\n let dayjsObject = dayjs(value);\n\n if (locale) {\n dayjsObject = dayjsObject.locale(locale);\n }\n\n if (this.dateOptionsInput.format) {\n output.format = dayjsObject.format(this.dateFormat);\n }\n\n if (this.dateOptionsInput.timestamp) {\n output.timestamp = dayjsObject.valueOf();\n }\n\n if (this.dateOptionsInput.human) {\n output.human = (dayjsObject as any).fromNow();\n }\n\n if (this.dateOptionsInput.locale) {\n output.locale = dayjsObject.format(this.dateFormat);\n }\n\n return output;\n }\n\n /**\n * Transform localized value\n */\n protected transformLocalized(value: LocalizedObject[] | string, locale?: string) {\n if (typeof value === \"string\") {\n return value;\n }\n\n if (!locale) {\n return value[0]?.value || value;\n }\n\n return value.find((item) => item.localeCode === locale)?.value;\n }\n}\n","import { get, set, type GenericObject } from \"@mongez/reinforcements\";\nimport { Model } from \"@warlock.js/cascade\";\nimport { useRequestStore } from \"../http/context/request-context\";\nimport { ResourceFieldBuilder } from \"./resource-field-builder\";\nimport {\n ResourceArraySchema,\n ResourceFieldConfig,\n ResourceOutputValueCastType,\n ResourceSchema,\n} from \"./types\";\n\nexport class Resource {\n /**\n * Resource data\n */\n public resource: GenericObject = {};\n\n /**\n * Resource final output\n */\n public data: GenericObject = {};\n\n /**\n * Output shape\n */\n public schema: ResourceSchema = {};\n\n /**\n * Constructor\n */\n public constructor(protected originalData: GenericObject | Resource | Model) {\n if (this.originalData instanceof Model) {\n this.resource = this.originalData.data;\n } else if (this.originalData instanceof Resource) {\n this.resource = this.originalData.data;\n } else {\n this.resource = this.originalData;\n }\n }\n\n /**\n * Convert resource to JSON\n */\n public toJSON() {\n this.boot();\n this.transformOutput();\n this.extend();\n\n return this.data;\n }\n\n /**\n * Boot method\n * Called before transforming the resource\n */\n protected boot() {\n //\n }\n\n /**\n * Transform resource to output\n */\n protected transformOutput() {\n const localeCode = useRequestStore()?.request?.locale;\n for (const [outputKey, outputSettings] of Object.entries(this.schema)) {\n let fieldKey = outputKey;\n let valueTransformType = outputSettings as ResourceFieldConfig;\n\n if (Array.isArray(outputSettings)) {\n fieldKey = outputSettings[0];\n valueTransformType = outputSettings[1];\n }\n\n const inputValue = this.get(fieldKey);\n let outputValue: any;\n\n if (Array.isArray(inputValue)) {\n outputValue = inputValue\n .map((item) => {\n const outputValue = this.transformValue(item, valueTransformType, localeCode);\n if (outputValue !== undefined) {\n return outputValue;\n }\n })\n .filter((value) => value !== undefined);\n } else {\n outputValue = this.transformValue(inputValue, valueTransformType, localeCode);\n }\n\n if (outputValue !== undefined) {\n this.set(outputKey, outputValue);\n }\n }\n }\n\n /**\n * Transform the given value with given type\n */\n public transform(value: any, type: ResourceOutputValueCastType, locale?: string) {\n return new ResourceFieldBuilder(type).transform(value, locale);\n }\n\n /**\n * Transform the given value for the given output\n */\n protected transformValue(value: any, outputSettings: ResourceFieldConfig, locale?: string) {\n let outputValue: any;\n\n // now check the value transform type\n // if it's prototype instanceof Resource, then it's a nested resource\n // if it's a function (but not a Resource class), then it's a resolver function\n // if it's an instance of ResourceFieldBuilder, then it's a field builder\n // if it's a ResourceArraySchema, then it's an array schema\n // if it's a string, then it's a field cast type\n if (typeof outputSettings === \"function\" && outputSettings.prototype instanceof Resource) {\n outputValue = new (outputSettings as typeof Resource)(value).toJSON();\n } else if (typeof outputSettings === \"function\") {\n // Handle resolver function - bind to Resource instance for access to this.get(), etc.\n outputValue = (outputSettings as Function).call(this, value, this);\n } else if (outputSettings instanceof ResourceFieldBuilder) {\n const inputKey = outputSettings.getInputKey();\n outputValue = outputSettings.transform(inputKey ? this.get(inputKey) : value, locale);\n } else if (\n typeof outputSettings === \"object\" &&\n outputSettings !== null &&\n \"__type\" in outputSettings &&\n outputSettings.__type === \"arrayOf\"\n ) {\n // Handle array schema - value here is a single array item, not the whole array\n // The parent transformOutput already handles the array mapping\n outputValue = this.transformArrayItem(value, outputSettings.schema, locale);\n } else if (typeof outputSettings === \"string\") {\n outputValue = new ResourceFieldBuilder(\n outputSettings as ResourceOutputValueCastType,\n ).transform(value, locale);\n }\n\n return outputValue;\n }\n\n /**\n * Extend the resource output\n */\n protected extend() {\n //\n }\n\n /**\n * Transform a single array item according to the given schema\n */\n protected transformArrayItem(\n item: any,\n schema: Record<string, ResourceFieldConfig>,\n locale?: string,\n ) {\n const transformedItem: GenericObject = {};\n\n for (const [outputKey, outputSettings] of Object.entries(schema)) {\n let fieldKey = outputKey;\n let valueTransformType = outputSettings as ResourceFieldConfig;\n\n if (Array.isArray(outputSettings)) {\n fieldKey = outputSettings[0];\n valueTransformType = outputSettings[1];\n }\n\n const inputValue = get(item, fieldKey);\n const outputValue = this.transformValue(inputValue, valueTransformType, locale);\n\n if (outputValue !== undefined) {\n set(transformedItem, outputKey, outputValue);\n }\n }\n\n return transformedItem;\n }\n\n /**\n * Get a input value for the given key\n */\n public get(key: string, defaultValue?: any) {\n return get(this.resource, key, defaultValue);\n }\n\n /**\n * Set the given value for the given field\n */\n public set(key: string, value: any) {\n set(this.data, key, value);\n\n return this;\n }\n\n /**\n * Create an array schema for transforming array items\n */\n public arrayOf(schema: Record<string, ResourceFieldConfig>): ResourceArraySchema {\n return {\n __type: \"arrayOf\",\n schema,\n };\n }\n\n /**\n * Get a string field builder\n */\n public string(inputKey?: string) {\n return this.fieldBuilder(\"string\", inputKey);\n }\n\n /**\n * Get a date field builder\n */\n public date(inputKey?: string) {\n return this.fieldBuilder(\"date\", inputKey);\n }\n\n /**\n * Get a localized field builder\n */\n public localized(inputKey?: string) {\n return this.fieldBuilder(\"localized\", inputKey);\n }\n\n /**\n * Get a url field builder\n */\n public url(inputKey?: string) {\n return this.fieldBuilder(\"url\", inputKey);\n }\n\n /**\n * Get a uploadsUrl field builder\n */\n public uploadsUrl(inputKey?: string) {\n return this.fieldBuilder(\"uploadsUrl\", inputKey);\n }\n\n /**\n * Get a number field builder\n */\n public number(inputKey?: string) {\n return this.fieldBuilder(\"number\", inputKey);\n }\n\n /**\n * Get a boolean field builder\n */\n public boolean(inputKey?: string) {\n return this.fieldBuilder(\"boolean\", inputKey);\n }\n\n /**\n * Get a float field builder\n */\n public float(inputKey?: string) {\n return this.fieldBuilder(\"float\", inputKey);\n }\n\n /**\n * Get a int field builder\n */\n public int(inputKey?: string) {\n return this.fieldBuilder(\"int\", inputKey);\n }\n\n /**\n * New field builder\n */\n protected fieldBuilder(type: ResourceOutputValueCastType, inputKey?: string) {\n const builder = new ResourceFieldBuilder(type);\n\n if (inputKey) {\n builder.setInputKey(inputKey);\n }\n\n return builder;\n }\n}\n","import { Resource } from \"./resource\";\nimport type { ResourceSchema } from \"./types\";\n\n/**\n * Options for defining a resource\n */\nexport type DefineResourceOptions = {\n /**\n * Resource schema - field mapping configuration\n */\n schema: ResourceSchema;\n\n /**\n * Optional: Boot hook - called before transformation\n */\n boot?: (resource?: Resource) => void;\n\n /**\n * Optional: Extend hook - called after transformation\n */\n extend?: (resource?: Resource) => void;\n\n /**\n * Optional: Transform hook - modify final output\n */\n transform?: (data: Record<string, any>, resource: Resource) => Record<string, any>;\n};\n\n/**\n * Define a resource with a clean, shorthand API.\n *\n * This utility creates a Resource class without the boilerplate,\n * perfect for simple use cases.\n *\n * @param options - Resource configuration\n * @returns A Resource class\n *\n * @example\n * ```typescript\n * // Simple resource\n * export const UserResource = defineResource({\n * schema: {\n * id: \"number\",\n * name: \"string\",\n * email: \"string\",\n * },\n * });\n *\n * // With hooks\n * export const CategoryResource = defineResource({\n * schema: {\n * id: \"number\",\n * name: \"localized\",\n * children: CategoryResource,\n * },\n * transform: (data) => {\n * // Filter inactive children\n * if (data.children) {\n * data.children = data.children.filter(c => c.isActive);\n * }\n * return data;\n * },\n * });\n *\n * // Usage\n * const json = new UserResource(user).toJSON();\n * ```\n */\nexport function defineResource(options: DefineResourceOptions) {\n return class AnonymousResource extends Resource {\n public schema = options.schema;\n\n protected boot() {\n if (options.boot) {\n options.boot.call(this, this as unknown as Resource);\n }\n }\n\n protected extend() {\n if (options.extend) {\n options.extend.call(this, this as unknown as Resource);\n }\n\n if (options.transform) {\n options.transform.call(this, this.data, this);\n }\n }\n };\n}\n","import type { GenericObject } from \"@mongez/reinforcements\";\r\nimport type { Model } from \"@warlock.js/cascade\";\r\nimport { log } from \"@warlock.js/logger\";\r\nimport type { Request, Response } from \"../http\";\r\nimport type { RepositoryManager } from \"../repositories\";\r\nimport type { RestfulMiddleware, RouteResource } from \"../router\";\r\n\r\nexport abstract class Restful<T extends Model> implements RouteResource {\r\n /**\r\n * Middleware for each method\r\n */\r\n protected middleware: RestfulMiddleware = {};\r\n\r\n /**\r\n * Record name\r\n */\r\n protected recordName = \"record\";\r\n\r\n /**\r\n * Records list name\r\n */\r\n protected recordsListName = \"records\";\r\n\r\n /**\r\n * Repository\r\n */\r\n protected abstract repository: RepositoryManager<T>;\r\n\r\n /**\r\n * Define what to be returned when a record is created|updated|deleted|patched\r\n */\r\n protected returnOn: Record<string, \"record\" | \"records\"> = {\r\n create: \"record\",\r\n update: \"record\",\r\n delete: \"record\",\r\n patch: \"record\",\r\n };\r\n\r\n /**\r\n * Enable fetching cache\r\n *\r\n * @default true\r\n */\r\n public cache = true;\r\n\r\n /**\r\n * Find record instance by id\r\n */\r\n public async find(id: number) {\r\n const findMethod = this.cache ? \"getCached\" : \"find\";\r\n return this.repository[findMethod](id);\r\n }\r\n\r\n /**\r\n * List records\r\n */\r\n public async list(request: Request, response: Response) {\r\n try {\r\n if (await this.callMiddleware(\"list\", request, response)) return;\r\n\r\n const responseDocument: GenericObject = {};\r\n\r\n const data = request.heavy();\r\n\r\n if (data.paginate === \"false\") {\r\n data.paginate = false;\r\n }\r\n\r\n const listMethod = this.cache ? \"listCached\" : \"list\";\r\n\r\n const { documents, paginationInfo } = await this.repository[listMethod](data);\r\n\r\n responseDocument[this.recordsListName] = documents;\r\n\r\n if (paginationInfo) {\r\n responseDocument.paginationInfo = paginationInfo;\r\n }\r\n\r\n return response.success(responseDocument);\r\n } catch (error: any) {\r\n log.error(\"restful\", \"list\", error);\r\n return response.serverError(error);\r\n }\r\n }\r\n\r\n /**\r\n * Get single record\r\n */\r\n public async get(request: Request, response: Response) {\r\n try {\r\n if (await this.callMiddleware(\"get\", request, response)) return;\r\n\r\n const record = await this.find(request.int(\"id\"));\r\n\r\n if (!record) {\r\n return response.notFound();\r\n }\r\n\r\n return response.success({\r\n [this.recordName]: record,\r\n });\r\n } catch (error) {\r\n log.error(\"restful\", \"get\", error);\r\n }\r\n }\r\n\r\n /**\r\n * Create a new record\r\n */\r\n public async create(request: Request, response: Response) {\r\n try {\r\n const model = this.repository.newModel();\r\n const beforeCreate = await this.beforeCreate(request, response, model);\r\n\r\n if (beforeCreate) {\r\n return beforeCreate;\r\n }\r\n\r\n const beforeSave = await this.beforeSave(request, response, model);\r\n\r\n if (beforeSave) {\r\n return beforeSave;\r\n }\r\n\r\n const record = await this.repository.create(request.all(), model);\r\n\r\n const createOutput = await this.onCreate(request, response, record);\r\n\r\n if (createOutput) {\r\n return createOutput;\r\n }\r\n\r\n const saveOutput = await this.onSave(request, response, record);\r\n\r\n if (saveOutput) {\r\n return saveOutput;\r\n }\r\n\r\n if (this.returnOn.create === \"records\") {\r\n return this.list(request, response);\r\n }\r\n\r\n return response.successCreate({\r\n [this.recordName]: record,\r\n });\r\n } catch (error: Error | any) {\r\n log.error(\"restful\", \"create\", error);\r\n\r\n return response.badRequest({\r\n error: error.message,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Update record\r\n */\r\n public async update(request: Request, response: Response) {\r\n try {\r\n // Find record\r\n const record = await this.find(request.int(\"id\"));\r\n\r\n if (!record) {\r\n return response.notFound({\r\n error: \"Record not found\",\r\n });\r\n }\r\n\r\n const beforeOutput = await this.beforeUpdate(request, response, record);\r\n if (beforeOutput) {\r\n return beforeOutput;\r\n }\r\n\r\n const beforeSafe = await this.beforeSave(request, response, record);\r\n\r\n if (beforeSafe) {\r\n return beforeSafe;\r\n }\r\n\r\n const oldRecord = record.clone();\r\n\r\n await record.save(request.allExceptParams());\r\n\r\n this.onUpdate(request, response, record, oldRecord);\r\n this.onSave(request, response, record, oldRecord);\r\n\r\n if (this.returnOn.update === \"records\") {\r\n return this.list(request, response);\r\n }\r\n\r\n return response.success({\r\n [this.recordName]: record,\r\n });\r\n } catch (error) {\r\n log.error(\"restful\", \"update\", error);\r\n }\r\n }\r\n\r\n /**\r\n * Patch record\r\n */\r\n public async patch(request: Request, response: Response) {\r\n try {\r\n const record = await this.find(request.int(\"id\"));\r\n\r\n if (!record) {\r\n return response.notFound({\r\n error: \"Record not found\",\r\n });\r\n }\r\n\r\n const oldRecord = record.clone();\r\n\r\n await this.beforePatch(request, response, record, oldRecord);\r\n await this.beforeSave(request, response, record, oldRecord);\r\n\r\n await record.save(request.heavyExceptParams());\r\n\r\n this.onPatch(request, response, record, oldRecord);\r\n this.onSave(request, response, record, oldRecord);\r\n\r\n if (this.returnOn.patch === \"records\") {\r\n return this.list(request, response);\r\n }\r\n\r\n return response.success({\r\n [this.recordName]: record,\r\n });\r\n } catch (error) {\r\n log.error(\"restful\", \"patch\", error);\r\n }\r\n }\r\n\r\n /**\r\n * Delete record\r\n */\r\n public async delete(request: Request, response: Response) {\r\n try {\r\n const record = await this.find(request.int(\"id\"));\r\n\r\n if (!record) {\r\n return response.notFound();\r\n }\r\n\r\n if (await this.callMiddleware(\"delete\", request, response, record)) return;\r\n\r\n await this.beforeDelete(request, response, record);\r\n\r\n await record.destroy();\r\n\r\n this.onDelete(request, response, record);\r\n\r\n if (this.returnOn.delete === \"records\") {\r\n return this.list(request, response);\r\n }\r\n\r\n return response.success();\r\n } catch (error: Error | any) {\r\n log.error(\"restful\", \"delete\", error);\r\n\r\n return response.badRequest({\r\n error: error.message,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Bulk delete records\r\n */\r\n public async bulkDelete(request: Request, response: Response) {\r\n try {\r\n const ids = request.input(\"id\");\r\n\r\n if (!Array.isArray(ids)) {\r\n return response.badRequest({\r\n error: \"id must be an array\",\r\n });\r\n }\r\n\r\n const records = await this.repository.all({\r\n perform: (query) =>\r\n query.whereIn(\r\n \"id\",\r\n ids.map((id) => parseInt(id)),\r\n ),\r\n });\r\n\r\n await Promise.all(\r\n records.map(async (record) => {\r\n if (await this.callMiddleware(\"delete\", request, response, record)) {\r\n return;\r\n }\r\n\r\n await this.beforeDelete(request, response, record);\r\n await record.destroy();\r\n this.onDelete(request, response, record);\r\n }),\r\n );\r\n\r\n if (this.returnOn.delete === \"records\") {\r\n return this.list(request, response);\r\n }\r\n\r\n return response.success({\r\n deleted: records.length,\r\n });\r\n } catch (error: Error | any) {\r\n log.error(\"restful\", \"bulkDelete\", error);\r\n return response.badRequest({\r\n error: error.message,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Before create\r\n */\r\n protected async beforeCreate(_request: Request, _response: Response, _record: T): Promise<any> {\r\n //\r\n }\r\n\r\n /**\r\n * On create\r\n */\r\n protected async onCreate(_request: Request, _response: Response, _record: T): Promise<any> {\r\n //\r\n }\r\n\r\n /**\r\n * Before update\r\n */\r\n protected async beforeUpdate(\r\n _request: Request,\r\n _response: Response,\r\n _record: T,\r\n _oldRecord?: T,\r\n ): Promise<any> {\r\n //\r\n }\r\n\r\n /**\r\n * On update\r\n */\r\n protected async onUpdate(\r\n _request: Request,\r\n _response: Response,\r\n _record: T,\r\n _oldRecord: T,\r\n ): Promise<any> {\r\n //\r\n }\r\n\r\n /**\r\n * Before delete\r\n */\r\n protected async beforeDelete(_request: Request, _response: Response, _record: T): Promise<any> {\r\n //\r\n }\r\n\r\n /**\r\n * On delete\r\n */\r\n protected async onDelete(_request: Request, _response: Response, _record: T): Promise<any> {\r\n //\r\n }\r\n\r\n /**\r\n * Before patch\r\n */\r\n protected async beforePatch(\r\n _request: Request,\r\n _response: Response,\r\n _record: T,\r\n _oldRecord?: T,\r\n ): Promise<any> {\r\n //\r\n }\r\n\r\n /**\r\n * On patch\r\n */\r\n protected async onPatch(\r\n _request: Request,\r\n _response: Response,\r\n _record: T,\r\n _oldRecord: T,\r\n ): Promise<any> {\r\n //\r\n }\r\n\r\n /**\r\n * Before save\r\n */\r\n protected async beforeSave(\r\n _request: Request,\r\n _response: Response,\r\n _record?: T,\r\n _oldRecord?: T,\r\n ): Promise<any> {\r\n //\r\n }\r\n\r\n /**\r\n * On save\r\n */\r\n protected async onSave(\r\n _request: Request,\r\n _response: Response,\r\n _record: T,\r\n _oldRecord?: T,\r\n ): Promise<any> {\r\n //\r\n }\r\n\r\n /**\r\n * Call middleware for the given method\r\n *\r\n */\r\n protected async callMiddleware(\r\n method: string,\r\n request: Request,\r\n response: Response,\r\n _record?: any,\r\n ) {\r\n if (!this.middleware[method]) return;\r\n\r\n for (const middleware of this.middleware[method]) {\r\n const output = await middleware(request, response);\r\n\r\n if (output) {\r\n return output;\r\n }\r\n }\r\n\r\n return;\r\n }\r\n}\r\n","import type { GenericObject } from \"@mongez/reinforcements\";\r\nimport { AsyncLocalStorage } from \"async_hooks\";\r\n\r\nconst stores: Map<string, AsyncLocalStorage<any>> = new Map();\r\n\r\nexport type StoreRunCallback<T> = (store: T) => void;\r\n\r\n/**\r\n * Create a new store\r\n * @param {string} name: The name of the store, will be used to access the store\r\n * @param {T} initialData: The initial data of the store\r\n * @param {StoreRunCallback?} runCallback: If passed, the callback will be executed when the store is created\r\n * @returns {object.run}: A function to run the store\r\n * @returns {object.destroy}: A function to destroy the store\r\n * @returns {object.store}: The store data\r\n * @returns {object.storage}: The store storage\r\n */\r\nexport function createStore<T extends GenericObject>(\r\n name: string,\r\n initialData: T,\r\n runCallback?: StoreRunCallback<T>,\r\n) {\r\n const store = new AsyncLocalStorage<T>();\r\n\r\n stores.set(name, store);\r\n\r\n const ops = {\r\n store: initialData,\r\n storage: store,\r\n async run(fn: (store: T) => void) {\r\n try {\r\n await store.run(initialData, fn.bind(null, initialData));\r\n } catch (error) {\r\n console.error(`Error running store ${name}:`, error);\r\n // Handle specific rollback or cleanup here if necessary\r\n } finally {\r\n // Ensure the store is always deleted after use\r\n console.log(\"Deleting store\", name);\r\n\r\n // stores.delete(name);\r\n // store.disable();\r\n }\r\n },\r\n destroy() {\r\n stores.delete(name);\r\n store.disable();\r\n },\r\n };\r\n\r\n if (runCallback) {\r\n ops.run(async () => await runCallback(initialData));\r\n }\r\n\r\n return ops;\r\n}\r\n\r\n/**\r\n * Get store by name\r\n */\r\nexport function useStore<T>(name: string): T | null {\r\n const store = stores.get(name);\r\n\r\n if (!store) {\r\n return null;\r\n }\r\n\r\n return store.getStore();\r\n}\r\n","import { WarlockConfig } from \"./types\";\r\n\r\nexport const defaultWarlockConfigurations: WarlockConfig = {\r\n build: {\r\n outDirectory: process.cwd() + \"/dist\",\r\n outFile: \"app.js\",\r\n sourcemap: true,\r\n minify: true,\r\n },\r\n};\r\n","import { merge } from \"@mongez/reinforcements\";\r\nimport { defaultWarlockConfigurations } from \"./default-configurations\";\r\nimport type { WarlockConfig } from \"./types\";\r\n\r\nexport function defineConfig(options: WarlockConfig) {\r\n return merge(defaultWarlockConfigurations, options);\r\n}\r\n","import { transform } from \"esbuild\";\nimport type { FileManager } from \"./file-manager\";\nimport { tsconfigManager } from \"./tsconfig-manager\";\n\n/**\n * Using esbuild to transpile the given code\n * Uses external sourcemaps for better performance:\n * - Inline sourcemaps double file size and require base64 parsing on every import\n * - External sourcemaps keep files small and fast to parse\n * - Sourcemap files are written separately and only loaded when debugging\n */\nexport async function transpileFile(fileManager: FileManager) {\n return transpile(fileManager.source, fileManager.absolutePath);\n}\n\nexport async function transpile(sourceCode: string, filePath: string) {\n const { code: transpiled } = await transform(sourceCode, {\n loader: filePath.endsWith(\".tsx\") ? \"tsx\" : \"ts\",\n format: \"esm\",\n sourcemap: \"inline\",\n target: \"es2022\",\n sourcefile: filePath,\n tsconfigRaw: tsconfigManager.tsconfig,\n });\n\n return transpiled;\n}\n","import { fileExistsAsync, getFileAsync, putFileAsync } from \"@mongez/fs\";\r\nimport { get } from \"@mongez/reinforcements\";\r\nimport { pathToFileURL } from \"url\";\r\nimport { devLogWarn } from \"../dev2-server/dev-logger\";\r\nimport { rootPath, warlockPath } from \"../utils\";\r\nimport { transpile } from \"./../dev2-server/transpile-file\";\r\nimport { WarlockConfig } from \"./types\";\r\n\r\n/**\r\n * Warlock Config Manager\r\n *\r\n * Manages lazy loading of the pre-compiled warlock.config.js file\r\n * from the .warlock/cache directory.\r\n */\r\nexport class WarlockConfigManager {\r\n /**\r\n * Cached config instance\r\n */\r\n private config?: WarlockConfig;\r\n\r\n /**\r\n * Loading promise to prevent duplicate loads\r\n */\r\n private loading?: Promise<WarlockConfig | undefined>;\r\n\r\n /**\r\n * Load warlock.config.js (cached after first load)\r\n *\r\n * @returns The resolved Warlock configuration\r\n */\r\n public async load(): Promise<WarlockConfig | undefined> {\r\n // Already loaded\r\n if (this.config) {\r\n return this.config;\r\n }\r\n\r\n // Currently loading (prevent duplicate loads)\r\n if (this.loading) {\r\n return this.loading;\r\n }\r\n\r\n // Start loading\r\n this.loading = this.doLoad();\r\n this.config = await this.loading;\r\n this.loading = undefined;\r\n\r\n return this.config;\r\n }\r\n\r\n /**\r\n * Internal load implementation\r\n */\r\n private async doLoad(): Promise<WarlockConfig | undefined> {\r\n const configPath = warlockPath(\"cache/warlock-config.js\");\r\n\r\n if (!(await fileExistsAsync(configPath))) {\r\n const result = await this.compile();\r\n\r\n if (!result) {\r\n devLogWarn(\r\n \"warlock.config.ts is missing, it's highly recommended to create it, run warlock init to create it\",\r\n );\r\n return;\r\n }\r\n }\r\n\r\n const fileUrl = pathToFileURL(configPath).href;\r\n try {\r\n const configModule = await import(fileUrl);\r\n\r\n return configModule.default;\r\n } catch (error) {\r\n throw new Error(\r\n `Failed to load warlock.config.js from ${fileUrl}. ` +\r\n `Make sure the config has been compiled. Error: ${error}`,\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Compile warlock.config.ts file\r\n */\r\n protected async compile() {\r\n const configPath = rootPath(\"warlock.config.ts\");\r\n if (!(await fileExistsAsync(configPath))) {\r\n return false;\r\n }\r\n\r\n const content = await getFileAsync(configPath);\r\n const compiledContent = await transpile(content, configPath);\r\n await putFileAsync(warlockPath(\"cache/warlock-config.js\"), compiledContent);\r\n return true;\r\n }\r\n\r\n /**\r\n * Get config value by key (dot notation supported)\r\n *\r\n * @example\r\n * config.get(\"server.port\") // Returns 3000\r\n * config.get(\"cli.commands\") // Returns array of commands\r\n *\r\n * @param key - Config key (supports dot notation), autocompletes for first level only\r\n * @returns The config value\r\n * @throws Error if config is not loaded\r\n */\r\n public get<Key extends keyof WarlockConfig>(\r\n key: Key,\r\n defaultValue?: WarlockConfig[Key],\r\n ): WarlockConfig[Key] {\r\n if (!this.config) {\r\n throw new Error(\"WarlockConfig not loaded. Call load() first or use lazyGet().\");\r\n }\r\n\r\n return get(this.config, key as string, defaultValue);\r\n }\r\n\r\n /**\r\n * Lazy get - loads config if not already loaded\r\n *\r\n * @example\r\n * const port = await config.lazyGet(\"server\");\r\n *\r\n * @param key - Config key (supports dot notation), autocompletes for first level only\r\n * @param defaultValue - Default value if config key is undefined\r\n * @returns The config value\r\n */\r\n async lazyGet<Key extends keyof WarlockConfig>(\r\n key: Key,\r\n defaultValue?: WarlockConfig[Key],\r\n ): Promise<WarlockConfig[Key]> {\r\n await this.load();\r\n return this.get(key, defaultValue);\r\n }\r\n\r\n /**\r\n * Check if config is loaded\r\n */\r\n public get isLoaded(): boolean {\r\n return this.config !== undefined;\r\n }\r\n\r\n /**\r\n * Get the entire config object\r\n *\r\n * @throws Error if config is not loaded\r\n */\r\n public getAll(): WarlockConfig {\r\n if (!this.config) {\r\n throw new Error(\"WarlockConfig not loaded. Call load() first or use lazyGet().\");\r\n }\r\n\r\n return this.config;\r\n }\r\n\r\n /**\r\n * Reload config (useful for HMR/development)\r\n */\r\n public async reload(): Promise<void> {\r\n this.config = undefined;\r\n this.loading = undefined;\r\n await this.load();\r\n }\r\n}\r\n\r\n/**\r\n * Exported singleton instance\r\n *\r\n * @example\r\n * import { warlockConfig } from \"@warlock.js/core\";\r\n *\r\n * // Lazy load and get value\r\n * const port = await warlockConfig.lazyGet(\"server.port\");\r\n *\r\n * // Or load first, then get\r\n * await warlockConfig.load();\r\n * const commands = warlockConfig.get(\"cli.commands\");\r\n */\r\nexport const warlockConfigManager = new WarlockConfigManager();\r\n"]}