@zintrust/core 0.1.40 → 0.1.42

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 (590) hide show
  1. package/bin/zintrust-main.d.ts.map +1 -1
  2. package/bin/zintrust-main.js +22 -1
  3. package/package.json +24 -4
  4. package/public/error-pages/404.html +2 -2
  5. package/src/auth/Auth.js +1 -1
  6. package/src/boot/Application.d.ts +1 -16
  7. package/src/boot/Application.d.ts.map +1 -1
  8. package/src/boot/Application.js +2 -290
  9. package/src/boot/Server.d.ts +1 -1
  10. package/src/boot/Server.d.ts.map +1 -1
  11. package/src/boot/bootstrap.js +50 -16
  12. package/src/boot/registry/registerRoute.d.ts +6 -0
  13. package/src/boot/registry/registerRoute.d.ts.map +1 -0
  14. package/src/boot/registry/registerRoute.js +96 -0
  15. package/src/boot/registry/runtime.d.ts +15 -0
  16. package/src/boot/registry/runtime.d.ts.map +1 -0
  17. package/src/boot/registry/runtime.js +364 -0
  18. package/src/boot/registry/type.d.ts +25 -0
  19. package/src/boot/registry/type.d.ts.map +1 -0
  20. package/src/boot/registry/type.js +1 -0
  21. package/src/boot/registry/worker.d.ts +6 -0
  22. package/src/boot/registry/worker.d.ts.map +1 -0
  23. package/src/boot/registry/worker.js +35 -0
  24. package/src/cache/drivers/KVRemoteDriver.d.ts.map +1 -1
  25. package/src/cache/drivers/KVRemoteDriver.js +14 -1
  26. package/src/cli/CLI.d.ts.map +1 -1
  27. package/src/cli/CLI.js +94 -34
  28. package/src/cli/ErrorHandler.js +1 -1
  29. package/src/cli/commands/ConfigCommand.d.ts.map +1 -1
  30. package/src/cli/commands/ConfigCommand.js +3 -5
  31. package/src/cli/commands/ContainerProxiesCommand.d.ts +5 -0
  32. package/src/cli/commands/ContainerProxiesCommand.d.ts.map +1 -0
  33. package/src/cli/commands/ContainerProxiesCommand.js +77 -0
  34. package/src/cli/commands/ContainerWorkersCommand.d.ts +5 -0
  35. package/src/cli/commands/ContainerWorkersCommand.d.ts.map +1 -0
  36. package/src/cli/commands/ContainerWorkersCommand.js +57 -0
  37. package/src/cli/commands/D1LearnCommand.d.ts +9 -0
  38. package/src/cli/commands/D1LearnCommand.d.ts.map +1 -0
  39. package/src/cli/commands/D1LearnCommand.js +143 -0
  40. package/src/cli/commands/D1MigrateCommand.d.ts.map +1 -1
  41. package/src/cli/commands/D1MigrateCommand.js +55 -16
  42. package/src/cli/commands/DeployCommand.d.ts +16 -0
  43. package/src/cli/commands/DeployCommand.d.ts.map +1 -0
  44. package/src/cli/commands/DeployCommand.js +110 -0
  45. package/src/cli/commands/DeployContainerProxiesCommand.d.ts +5 -0
  46. package/src/cli/commands/DeployContainerProxiesCommand.d.ts.map +1 -0
  47. package/src/cli/commands/DeployContainerProxiesCommand.js +27 -0
  48. package/src/cli/commands/DeployContainerWorkersCommand.d.ts +5 -0
  49. package/src/cli/commands/DeployContainerWorkersCommand.d.ts.map +1 -0
  50. package/src/cli/commands/DeployContainerWorkersCommand.js +27 -0
  51. package/src/cli/commands/DockerComposeCommandUtils.d.ts +3 -0
  52. package/src/cli/commands/DockerComposeCommandUtils.d.ts.map +1 -0
  53. package/src/cli/commands/DockerComposeCommandUtils.js +34 -0
  54. package/src/cli/commands/DoctorArchitectureCommand.d.ts +5 -0
  55. package/src/cli/commands/DoctorArchitectureCommand.d.ts.map +1 -0
  56. package/src/cli/commands/DoctorArchitectureCommand.js +54 -0
  57. package/src/cli/commands/InitContainerCommand.d.ts +5 -0
  58. package/src/cli/commands/InitContainerCommand.d.ts.map +1 -0
  59. package/src/cli/commands/InitContainerCommand.js +231 -0
  60. package/src/cli/commands/InitEcosystemCommand.d.ts +6 -0
  61. package/src/cli/commands/InitEcosystemCommand.d.ts.map +1 -0
  62. package/src/cli/commands/InitEcosystemCommand.js +51 -0
  63. package/src/cli/commands/InitProducerCommand.d.ts +5 -0
  64. package/src/cli/commands/InitProducerCommand.d.ts.map +1 -0
  65. package/src/cli/commands/InitProducerCommand.js +47 -0
  66. package/src/cli/commands/InitProxyCommand.d.ts +5 -0
  67. package/src/cli/commands/InitProxyCommand.d.ts.map +1 -0
  68. package/src/cli/commands/InitProxyCommand.js +442 -0
  69. package/src/cli/commands/MigrateCommand.d.ts.map +1 -1
  70. package/src/cli/commands/MigrateCommand.js +78 -36
  71. package/src/cli/commands/MigrateWorkerCommand.d.ts.map +1 -1
  72. package/src/cli/commands/MigrateWorkerCommand.js +36 -2
  73. package/src/cli/commands/MongoDBProxyCommand.d.ts +5 -0
  74. package/src/cli/commands/MongoDBProxyCommand.d.ts.map +1 -0
  75. package/src/cli/commands/MongoDBProxyCommand.js +98 -0
  76. package/src/cli/commands/MySqlProxyCommand.d.ts +6 -0
  77. package/src/cli/commands/MySqlProxyCommand.d.ts.map +1 -0
  78. package/src/cli/commands/MySqlProxyCommand.js +32 -0
  79. package/src/cli/commands/PostgresProxyCommand.d.ts +6 -0
  80. package/src/cli/commands/PostgresProxyCommand.d.ts.map +1 -0
  81. package/src/cli/commands/PostgresProxyCommand.js +32 -0
  82. package/src/cli/commands/ProxyCommand.d.ts +12 -0
  83. package/src/cli/commands/ProxyCommand.d.ts.map +1 -0
  84. package/src/cli/commands/ProxyCommand.js +80 -0
  85. package/src/cli/commands/ProxyCommandUtils.d.ts +6 -0
  86. package/src/cli/commands/ProxyCommandUtils.d.ts.map +1 -0
  87. package/src/cli/commands/ProxyCommandUtils.js +38 -0
  88. package/src/cli/commands/PutCommand.d.ts +6 -0
  89. package/src/cli/commands/PutCommand.d.ts.map +1 -0
  90. package/src/cli/commands/PutCommand.js +173 -0
  91. package/src/cli/commands/QueueRecoveryCommand.d.ts +6 -0
  92. package/src/cli/commands/QueueRecoveryCommand.d.ts.map +1 -0
  93. package/src/cli/commands/QueueRecoveryCommand.js +612 -0
  94. package/src/cli/commands/RedisProxyCommand.d.ts +6 -0
  95. package/src/cli/commands/RedisProxyCommand.d.ts.map +1 -0
  96. package/src/cli/commands/RedisProxyCommand.js +53 -0
  97. package/src/cli/commands/ScheduleListCommand.d.ts +6 -0
  98. package/src/cli/commands/ScheduleListCommand.d.ts.map +1 -0
  99. package/src/cli/commands/ScheduleListCommand.js +62 -0
  100. package/src/cli/commands/ScheduleRunCommand.d.ts +6 -0
  101. package/src/cli/commands/ScheduleRunCommand.d.ts.map +1 -0
  102. package/src/cli/commands/ScheduleRunCommand.js +32 -0
  103. package/src/cli/commands/ScheduleStartCommand.d.ts +6 -0
  104. package/src/cli/commands/ScheduleStartCommand.d.ts.map +1 -0
  105. package/src/cli/commands/ScheduleStartCommand.js +40 -0
  106. package/src/cli/commands/SecretsCommand.d.ts.map +1 -1
  107. package/src/cli/commands/SecretsCommand.js +2 -2
  108. package/src/cli/commands/SmtpProxyCommand.d.ts +6 -0
  109. package/src/cli/commands/SmtpProxyCommand.d.ts.map +1 -0
  110. package/src/cli/commands/SmtpProxyCommand.js +56 -0
  111. package/src/cli/commands/SqlProxyCommandUtils.d.ts +46 -0
  112. package/src/cli/commands/SqlProxyCommandUtils.d.ts.map +1 -0
  113. package/src/cli/commands/SqlProxyCommandUtils.js +48 -0
  114. package/src/cli/commands/SqlServerProxyCommand.d.ts +5 -0
  115. package/src/cli/commands/SqlServerProxyCommand.d.ts.map +1 -0
  116. package/src/cli/commands/SqlServerProxyCommand.js +85 -0
  117. package/src/cli/commands/StartCommand.d.ts.map +1 -1
  118. package/src/cli/commands/StartCommand.js +132 -17
  119. package/src/cli/commands/WorkerCommands.d.ts +1 -0
  120. package/src/cli/commands/WorkerCommands.d.ts.map +1 -1
  121. package/src/cli/commands/WorkerCommands.js +140 -6
  122. package/src/cli/commands/index.d.ts +2 -0
  123. package/src/cli/commands/index.d.ts.map +1 -1
  124. package/src/cli/commands/index.js +2 -0
  125. package/src/cli/commands/runner/index.d.ts +2 -2
  126. package/src/cli/commands/runner/index.d.ts.map +1 -1
  127. package/src/cli/commands/runner/index.js +15 -4
  128. package/src/cli/commands/schedule/ScheduleCliSupport.d.ts +6 -0
  129. package/src/cli/commands/schedule/ScheduleCliSupport.d.ts.map +1 -0
  130. package/src/cli/commands/schedule/ScheduleCliSupport.js +55 -0
  131. package/src/cli/config/ConfigManager.d.ts.map +1 -1
  132. package/src/cli/config/ConfigManager.js +8 -1
  133. package/src/cli/d1/D1SqlMigrations.d.ts.map +1 -1
  134. package/src/cli/d1/D1SqlMigrations.js +14 -1
  135. package/src/cli/d1/WranglerConfig.d.ts.map +1 -1
  136. package/src/cli/d1/WranglerConfig.js +34 -2
  137. package/src/cli/index.d.ts +4 -0
  138. package/src/cli/index.d.ts.map +1 -1
  139. package/src/cli/index.js +4 -0
  140. package/src/cli/scaffolding/ProjectScaffolder.d.ts.map +1 -1
  141. package/src/cli/scaffolding/ProjectScaffolder.js +2 -0
  142. package/src/cli/scaffolding/ServiceScaffolder.d.ts.map +1 -1
  143. package/src/cli/scaffolding/ServiceScaffolder.js +1 -0
  144. package/src/cli/services/VersionChecker.d.ts.map +1 -1
  145. package/src/cli/services/VersionChecker.js +5 -1
  146. package/src/cli/utils/DatabaseCliUtils.d.ts.map +1 -1
  147. package/src/cli/utils/DatabaseCliUtils.js +6 -1
  148. package/src/cli/utils/EnvFileLoader.d.ts.map +1 -1
  149. package/src/cli/utils/EnvFileLoader.js +35 -15
  150. package/src/cli/workers/QueueWorkRunner.js +1 -1
  151. package/src/cli.d.ts +5 -0
  152. package/src/cli.d.ts.map +1 -0
  153. package/src/cli.js +4 -0
  154. package/src/collections/index.d.ts +2 -2
  155. package/src/collections/index.d.ts.map +1 -1
  156. package/src/collections/index.js +1 -1
  157. package/src/common/HealthRoutes.d.ts.map +1 -1
  158. package/src/common/HealthRoutes.js +50 -2
  159. package/src/common/RemoteSignedJson.d.ts +1 -0
  160. package/src/common/RemoteSignedJson.d.ts.map +1 -1
  161. package/src/common/RemoteSignedJson.js +81 -29
  162. package/src/common/index.d.ts +1 -0
  163. package/src/common/index.d.ts.map +1 -1
  164. package/src/common/index.js +12 -1
  165. package/src/common/utility.d.ts.map +1 -1
  166. package/src/common/utility.js +2 -6
  167. package/src/config/FileLogWriter.d.ts.map +1 -1
  168. package/src/config/FileLogWriter.js +21 -6
  169. package/src/config/app.d.ts +4 -0
  170. package/src/config/app.d.ts.map +1 -1
  171. package/src/config/app.js +4 -0
  172. package/src/config/cache.d.ts.map +1 -1
  173. package/src/config/cache.js +22 -2
  174. package/src/config/cloudflare.d.ts +5 -1
  175. package/src/config/cloudflare.d.ts.map +1 -1
  176. package/src/config/cloudflare.js +67 -8
  177. package/src/config/database.d.ts.map +1 -1
  178. package/src/config/database.js +48 -13
  179. package/src/config/env.d.ts +87 -2
  180. package/src/config/env.d.ts.map +1 -1
  181. package/src/config/env.js +158 -19
  182. package/src/config/index.d.ts +1 -0
  183. package/src/config/index.d.ts.map +1 -1
  184. package/src/config/mail.d.ts.map +1 -1
  185. package/src/config/mail.js +16 -10
  186. package/src/config/middleware.d.ts +5 -0
  187. package/src/config/middleware.d.ts.map +1 -1
  188. package/src/config/middleware.js +19 -1
  189. package/src/config/queue.d.ts.map +1 -1
  190. package/src/config/queue.js +70 -9
  191. package/src/config/redis.d.ts.map +1 -1
  192. package/src/config/redis.js +48 -13
  193. package/src/config/storage.d.ts.map +1 -1
  194. package/src/config/storage.js +1 -0
  195. package/src/config/type.d.ts +18 -0
  196. package/src/config/type.d.ts.map +1 -1
  197. package/src/config/workers.d.ts.map +1 -1
  198. package/src/config/workers.js +122 -16
  199. package/src/functions/cloudflare.d.ts.map +1 -1
  200. package/src/functions/cloudflare.js +55 -1
  201. package/src/health/StartupHealthChecks.js +1 -1
  202. package/src/helper/index.d.ts +225 -0
  203. package/src/helper/index.d.ts.map +1 -0
  204. package/src/helper/index.js +347 -0
  205. package/src/http/FileUpload.d.ts +3 -2
  206. package/src/http/FileUpload.d.ts.map +1 -1
  207. package/src/http/Kernel.d.ts.map +1 -1
  208. package/src/http/Kernel.js +2 -1
  209. package/src/http/error-pages/ErrorPageRenderer.d.ts +4 -0
  210. package/src/http/error-pages/ErrorPageRenderer.d.ts.map +1 -1
  211. package/src/http/error-pages/ErrorPageRenderer.js +141 -1
  212. package/src/http/middleware/BodyParsingMiddleware.d.ts.map +1 -1
  213. package/src/http/middleware/BodyParsingMiddleware.js +33 -6
  214. package/src/index.d.ts +26 -57
  215. package/src/index.d.ts.map +1 -1
  216. package/src/index.js +32 -18
  217. package/src/microservices/ServiceAuthMiddleware.d.ts.map +1 -1
  218. package/src/microservices/ServiceAuthMiddleware.js +12 -4
  219. package/src/middleware/CsrfMiddleware.d.ts.map +1 -1
  220. package/src/middleware/CsrfMiddleware.js +30 -16
  221. package/src/middleware/ErrorHandlerMiddleware.d.ts.map +1 -1
  222. package/src/middleware/ErrorHandlerMiddleware.js +2 -1
  223. package/src/migrations/MigrationDiscovery.d.ts.map +1 -1
  224. package/src/migrations/MigrationDiscovery.js +2 -1
  225. package/src/migrations/MigrationLoader.js +1 -1
  226. package/src/migrations/schema/SchemaCompiler.d.ts.map +1 -1
  227. package/src/migrations/schema/SchemaCompiler.js +6 -3
  228. package/src/node-singletons/crypto.d.ts +1 -1
  229. package/src/node-singletons/crypto.d.ts.map +1 -1
  230. package/src/node-singletons/crypto.js +1 -1
  231. package/src/node-singletons/fs.d.ts +1 -1
  232. package/src/node-singletons/fs.d.ts.map +1 -1
  233. package/src/node-singletons/path.d.ts +1 -1
  234. package/src/node-singletons/path.d.ts.map +1 -1
  235. package/src/node-singletons/path.js +1 -1
  236. package/src/node-singletons/stream.d.ts +11 -0
  237. package/src/node-singletons/stream.d.ts.map +1 -0
  238. package/src/node-singletons/stream.js +8 -0
  239. package/src/observability/OpenTelemetry.d.ts +7 -0
  240. package/src/observability/OpenTelemetry.d.ts.map +1 -1
  241. package/src/observability/OpenTelemetry.js +49 -2
  242. package/src/orm/Database.d.ts +4 -0
  243. package/src/orm/Database.d.ts.map +1 -1
  244. package/src/orm/Database.js +80 -9
  245. package/src/orm/DatabaseAdapter.d.ts +1 -0
  246. package/src/orm/DatabaseAdapter.d.ts.map +1 -1
  247. package/src/orm/DatabaseRuntimeRegistration.d.ts.map +1 -1
  248. package/src/orm/DatabaseRuntimeRegistration.js +2 -0
  249. package/src/orm/QueryBuilder.d.ts +1 -0
  250. package/src/orm/QueryBuilder.d.ts.map +1 -1
  251. package/src/orm/QueryBuilder.js +33 -3
  252. package/src/orm/SchemaCompiler.d.ts.map +1 -1
  253. package/src/orm/SchemaCompiler.js +6 -3
  254. package/src/orm/SchemaStatemenWriter.d.ts +15 -0
  255. package/src/orm/SchemaStatemenWriter.d.ts.map +1 -0
  256. package/src/orm/SchemaStatemenWriter.js +78 -0
  257. package/src/orm/adapters/D1Adapter.d.ts.map +1 -1
  258. package/src/orm/adapters/D1Adapter.js +52 -2
  259. package/src/orm/adapters/D1RemoteAdapter.d.ts.map +1 -1
  260. package/src/orm/adapters/D1RemoteAdapter.js +150 -89
  261. package/src/orm/adapters/MongoDBProxyAdapter.d.ts +3 -0
  262. package/src/orm/adapters/MongoDBProxyAdapter.d.ts.map +1 -0
  263. package/src/orm/adapters/MongoDBProxyAdapter.js +128 -0
  264. package/src/orm/adapters/MySQLProxyAdapter.d.ts +11 -0
  265. package/src/orm/adapters/MySQLProxyAdapter.d.ts.map +1 -0
  266. package/src/orm/adapters/MySQLProxyAdapter.js +162 -0
  267. package/src/orm/adapters/PostgreSQLProxyAdapter.d.ts +11 -0
  268. package/src/orm/adapters/PostgreSQLProxyAdapter.d.ts.map +1 -0
  269. package/src/orm/adapters/PostgreSQLProxyAdapter.js +163 -0
  270. package/src/orm/adapters/ProxyCache.d.ts +9 -0
  271. package/src/orm/adapters/ProxyCache.d.ts.map +1 -0
  272. package/src/orm/adapters/ProxyCache.js +24 -0
  273. package/src/orm/adapters/ProxySignedRequest.d.ts +11 -0
  274. package/src/orm/adapters/ProxySignedRequest.d.ts.map +1 -0
  275. package/src/orm/adapters/ProxySignedRequest.js +30 -0
  276. package/src/orm/adapters/ProxySigningPath.d.ts +3 -0
  277. package/src/orm/adapters/ProxySigningPath.d.ts.map +1 -0
  278. package/src/orm/adapters/ProxySigningPath.js +25 -0
  279. package/src/orm/adapters/SqlProxyAdapterUtils.d.ts +19 -0
  280. package/src/orm/adapters/SqlProxyAdapterUtils.d.ts.map +1 -0
  281. package/src/orm/adapters/SqlProxyAdapterUtils.js +36 -0
  282. package/src/orm/adapters/SqlProxyRegistryMode.d.ts +12 -0
  283. package/src/orm/adapters/SqlProxyRegistryMode.d.ts.map +1 -0
  284. package/src/orm/adapters/SqlProxyRegistryMode.js +24 -0
  285. package/src/orm/adapters/SqlServerProxyAdapter.d.ts +6 -0
  286. package/src/orm/adapters/SqlServerProxyAdapter.d.ts.map +1 -0
  287. package/src/orm/adapters/SqlServerProxyAdapter.js +154 -0
  288. package/src/orm/migrations/MigrationStore.js +1 -1
  289. package/src/performance/Optimizer.d.ts +1 -0
  290. package/src/performance/Optimizer.d.ts.map +1 -1
  291. package/src/performance/Optimizer.js +21 -8
  292. package/src/proxy/ErrorHandler.d.ts +11 -0
  293. package/src/proxy/ErrorHandler.d.ts.map +1 -0
  294. package/src/proxy/ErrorHandler.js +7 -0
  295. package/src/proxy/PoolManager.d.ts +8 -0
  296. package/src/proxy/PoolManager.d.ts.map +1 -0
  297. package/src/proxy/PoolManager.js +18 -0
  298. package/src/proxy/ProxyBackend.d.ts +18 -0
  299. package/src/proxy/ProxyBackend.d.ts.map +1 -0
  300. package/src/proxy/ProxyBackend.js +1 -0
  301. package/src/proxy/ProxyConfig.d.ts +12 -0
  302. package/src/proxy/ProxyConfig.d.ts.map +1 -0
  303. package/src/proxy/ProxyConfig.js +1 -0
  304. package/src/proxy/ProxyRegistry.d.ts +10 -0
  305. package/src/proxy/ProxyRegistry.d.ts.map +1 -0
  306. package/src/proxy/ProxyRegistry.js +11 -0
  307. package/src/proxy/ProxyRequestParsing.d.ts +9 -0
  308. package/src/proxy/ProxyRequestParsing.d.ts.map +1 -0
  309. package/src/proxy/ProxyRequestParsing.js +16 -0
  310. package/src/proxy/ProxyServer.d.ts +21 -0
  311. package/src/proxy/ProxyServer.d.ts.map +1 -0
  312. package/src/proxy/ProxyServer.js +84 -0
  313. package/src/proxy/ProxyServerUtils.d.ts +37 -0
  314. package/src/proxy/ProxyServerUtils.d.ts.map +1 -0
  315. package/src/proxy/ProxyServerUtils.js +42 -0
  316. package/src/proxy/ProxySigningConfigResolver.d.ts +22 -0
  317. package/src/proxy/ProxySigningConfigResolver.d.ts.map +1 -0
  318. package/src/proxy/ProxySigningConfigResolver.js +24 -0
  319. package/src/proxy/ProxySigningRequest.d.ts +12 -0
  320. package/src/proxy/ProxySigningRequest.d.ts.map +1 -0
  321. package/src/proxy/ProxySigningRequest.js +31 -0
  322. package/src/proxy/RequestValidator.d.ts +15 -0
  323. package/src/proxy/RequestValidator.d.ts.map +1 -0
  324. package/src/proxy/RequestValidator.js +26 -0
  325. package/src/proxy/SigningService.d.ts +39 -0
  326. package/src/proxy/SigningService.d.ts.map +1 -0
  327. package/src/proxy/SigningService.js +107 -0
  328. package/src/proxy/SqlPayloadValidator.d.ts +13 -0
  329. package/src/proxy/SqlPayloadValidator.d.ts.map +1 -0
  330. package/src/proxy/SqlPayloadValidator.js +14 -0
  331. package/src/proxy/SqlProxyDbOverrides.d.ts +17 -0
  332. package/src/proxy/SqlProxyDbOverrides.d.ts.map +1 -0
  333. package/src/proxy/SqlProxyDbOverrides.js +1 -0
  334. package/src/proxy/SqlProxyServerDeps.d.ts +12 -0
  335. package/src/proxy/SqlProxyServerDeps.d.ts.map +1 -0
  336. package/src/proxy/SqlProxyServerDeps.js +9 -0
  337. package/src/proxy/StatementPayloadValidator.d.ts +13 -0
  338. package/src/proxy/StatementPayloadValidator.d.ts.map +1 -0
  339. package/src/proxy/StatementPayloadValidator.js +18 -0
  340. package/src/proxy/StatementRegistryLoader.d.ts +2 -0
  341. package/src/proxy/StatementRegistryLoader.d.ts.map +1 -0
  342. package/src/proxy/StatementRegistryLoader.js +36 -0
  343. package/src/proxy/StatementRegistryResolver.d.ts +15 -0
  344. package/src/proxy/StatementRegistryResolver.d.ts.map +1 -0
  345. package/src/proxy/StatementRegistryResolver.js +34 -0
  346. package/src/proxy/d1/ZintrustD1Proxy.d.ts +3 -0
  347. package/src/proxy/d1/ZintrustD1Proxy.d.ts.map +1 -0
  348. package/src/proxy/d1/ZintrustD1Proxy.js +2 -0
  349. package/src/proxy/d1/register.d.ts +2 -0
  350. package/src/proxy/d1/register.d.ts.map +1 -0
  351. package/src/proxy/d1/register.js +5 -0
  352. package/src/proxy/isMutatingSql.d.ts +2 -0
  353. package/src/proxy/isMutatingSql.d.ts.map +1 -0
  354. package/src/proxy/isMutatingSql.js +12 -0
  355. package/src/proxy/kv/ZintrustKvProxy.d.ts +3 -0
  356. package/src/proxy/kv/ZintrustKvProxy.d.ts.map +1 -0
  357. package/src/proxy/kv/ZintrustKvProxy.js +2 -0
  358. package/src/proxy/kv/register.d.ts +2 -0
  359. package/src/proxy/kv/register.d.ts.map +1 -0
  360. package/src/proxy/kv/register.js +5 -0
  361. package/src/proxy/mongodb/MongoDBProxyServer.d.ts +33 -0
  362. package/src/proxy/mongodb/MongoDBProxyServer.d.ts.map +1 -0
  363. package/src/proxy/mongodb/MongoDBProxyServer.js +202 -0
  364. package/src/proxy/mongodb/register.d.ts +2 -0
  365. package/src/proxy/mongodb/register.d.ts.map +1 -0
  366. package/src/proxy/mongodb/register.js +5 -0
  367. package/src/proxy/mysql/MySqlProxyServer.d.ts +8 -0
  368. package/src/proxy/mysql/MySqlProxyServer.d.ts.map +1 -0
  369. package/src/proxy/mysql/MySqlProxyServer.js +202 -0
  370. package/src/proxy/mysql/register.d.ts +2 -0
  371. package/src/proxy/mysql/register.d.ts.map +1 -0
  372. package/src/proxy/mysql/register.js +5 -0
  373. package/src/proxy/postgres/PostgresProxyServer.d.ts +8 -0
  374. package/src/proxy/postgres/PostgresProxyServer.d.ts.map +1 -0
  375. package/src/proxy/postgres/PostgresProxyServer.js +178 -0
  376. package/src/proxy/postgres/register.d.ts +2 -0
  377. package/src/proxy/postgres/register.d.ts.map +1 -0
  378. package/src/proxy/postgres/register.js +5 -0
  379. package/src/proxy/redis/RedisProxyServer.d.ts +12 -0
  380. package/src/proxy/redis/RedisProxyServer.d.ts.map +1 -0
  381. package/src/proxy/redis/RedisProxyServer.js +192 -0
  382. package/src/proxy/redis/register.d.ts +2 -0
  383. package/src/proxy/redis/register.d.ts.map +1 -0
  384. package/src/proxy/redis/register.js +5 -0
  385. package/src/proxy/smtp/SmtpProxyServer.d.ts +19 -0
  386. package/src/proxy/smtp/SmtpProxyServer.d.ts.map +1 -0
  387. package/src/proxy/smtp/SmtpProxyServer.js +290 -0
  388. package/src/proxy/smtp/register.d.ts +2 -0
  389. package/src/proxy/smtp/register.d.ts.map +1 -0
  390. package/src/proxy/smtp/register.js +5 -0
  391. package/src/proxy/sqlserver/SqlServerProxyServer.d.ts +8 -0
  392. package/src/proxy/sqlserver/SqlServerProxyServer.d.ts.map +1 -0
  393. package/src/proxy/sqlserver/SqlServerProxyServer.js +203 -0
  394. package/src/proxy/sqlserver/register.d.ts +2 -0
  395. package/src/proxy/sqlserver/register.d.ts.map +1 -0
  396. package/src/proxy/sqlserver/register.js +5 -0
  397. package/src/proxy.d.ts +4 -0
  398. package/src/proxy.d.ts.map +1 -0
  399. package/src/proxy.js +3 -0
  400. package/src/routes/doc.d.ts.map +1 -1
  401. package/src/routes/doc.js +16 -2
  402. package/src/routes/error.d.ts +5 -4
  403. package/src/routes/error.d.ts.map +1 -1
  404. package/src/routes/error.js +15 -13
  405. package/src/routes/errorPages.d.ts +2 -0
  406. package/src/routes/errorPages.d.ts.map +1 -1
  407. package/src/routes/errorPages.js +144 -4
  408. package/src/runtime/PluginAutoImports.d.ts +1 -0
  409. package/src/runtime/PluginAutoImports.d.ts.map +1 -1
  410. package/src/runtime/PluginAutoImports.js +94 -9
  411. package/src/runtime/RuntimeAdapter.d.ts +8 -9
  412. package/src/runtime/RuntimeAdapter.d.ts.map +1 -1
  413. package/src/runtime/RuntimeAdapter.js +120 -34
  414. package/src/runtime/RuntimeServices.d.ts +47 -0
  415. package/src/runtime/RuntimeServices.d.ts.map +1 -0
  416. package/src/runtime/RuntimeServices.js +164 -0
  417. package/src/runtime/StartupConfigFileRegistry.d.ts +4 -4
  418. package/src/runtime/StartupConfigFileRegistry.d.ts.map +1 -1
  419. package/src/runtime/StartupConfigFileRegistry.js +12 -0
  420. package/src/runtime/WorkerAdapterImports.d.ts +5 -0
  421. package/src/runtime/WorkerAdapterImports.d.ts.map +1 -0
  422. package/src/runtime/WorkerAdapterImports.js +17 -0
  423. package/src/runtime/WorkersModule.d.ts +6 -0
  424. package/src/runtime/WorkersModule.d.ts.map +1 -0
  425. package/src/runtime/WorkersModule.js +278 -0
  426. package/src/runtime/adapters/CloudflareAdapter.d.ts.map +1 -1
  427. package/src/runtime/adapters/CloudflareAdapter.js +19 -2
  428. package/src/runtime/adapters/DenoAdapter.js +1 -0
  429. package/src/runtime/adapters/FargateAdapter.js +1 -1
  430. package/src/runtime/adapters/LambdaAdapter.js +1 -1
  431. package/src/runtime/adapters/NodeServerAdapter.js +1 -1
  432. package/src/runtime/detectRuntime.d.ts +10 -0
  433. package/src/runtime/detectRuntime.d.ts.map +1 -0
  434. package/src/runtime/detectRuntime.js +57 -0
  435. package/src/runtime/useFileLoader.d.ts.map +1 -1
  436. package/src/runtime/useFileLoader.js +16 -0
  437. package/src/scheduler/Schedule.d.ts +36 -0
  438. package/src/scheduler/Schedule.d.ts.map +1 -0
  439. package/src/scheduler/Schedule.js +197 -0
  440. package/src/scheduler/ScheduleHttpGateway.d.ts +8 -0
  441. package/src/scheduler/ScheduleHttpGateway.d.ts.map +1 -0
  442. package/src/scheduler/ScheduleHttpGateway.js +196 -0
  443. package/src/scheduler/ScheduleRunner.d.ts +6 -0
  444. package/src/scheduler/ScheduleRunner.d.ts.map +1 -1
  445. package/src/scheduler/ScheduleRunner.js +166 -29
  446. package/src/scheduler/SchedulerRuntime.d.ts +15 -0
  447. package/src/scheduler/SchedulerRuntime.d.ts.map +1 -0
  448. package/src/scheduler/SchedulerRuntime.js +79 -0
  449. package/src/scheduler/cron/Cron.d.ts +19 -0
  450. package/src/scheduler/cron/Cron.d.ts.map +1 -0
  451. package/src/scheduler/cron/Cron.js +200 -0
  452. package/src/scheduler/leader/SchedulerLeader.d.ts +14 -0
  453. package/src/scheduler/leader/SchedulerLeader.d.ts.map +1 -0
  454. package/src/scheduler/leader/SchedulerLeader.js +187 -0
  455. package/src/scheduler/state/ScheduleStateStore.d.ts +27 -0
  456. package/src/scheduler/state/ScheduleStateStore.d.ts.map +1 -0
  457. package/src/scheduler/state/ScheduleStateStore.js +27 -0
  458. package/src/scheduler/types.d.ts +10 -0
  459. package/src/scheduler/types.d.ts.map +1 -1
  460. package/src/schedules/index.d.ts +1 -0
  461. package/src/schedules/index.d.ts.map +1 -1
  462. package/src/schedules/index.js +1 -0
  463. package/src/schedules/job-tracking-cleanup.d.ts +4 -0
  464. package/src/schedules/job-tracking-cleanup.d.ts.map +1 -0
  465. package/src/schedules/job-tracking-cleanup.js +116 -0
  466. package/src/schedules/log-cleanup.d.ts +1 -2
  467. package/src/schedules/log-cleanup.d.ts.map +1 -1
  468. package/src/schedules/log-cleanup.js +12 -15
  469. package/src/scripts/TemplateImportsCheck.js +2 -2
  470. package/src/scripts/TemplateSync.js +3 -4
  471. package/src/security/CsrfTokenManager.d.ts.map +1 -1
  472. package/src/security/CsrfTokenManager.js +12 -0
  473. package/src/security/Hash.d.ts +1 -1
  474. package/src/security/Hash.d.ts.map +1 -1
  475. package/src/security/Hash.js +31 -36
  476. package/src/security/Sanitizer.d.ts.map +1 -1
  477. package/src/security/Sanitizer.js +1 -9
  478. package/src/security/SignedRequest.d.ts.map +1 -1
  479. package/src/security/SignedRequest.js +2 -2
  480. package/src/seeders/SeederLoader.js +1 -1
  481. package/src/session/SessionManager.d.ts +3 -0
  482. package/src/session/SessionManager.d.ts.map +1 -1
  483. package/src/session/SessionManager.js +49 -10
  484. package/src/sockets/CloudflareSocket.d.ts +24 -0
  485. package/src/sockets/CloudflareSocket.d.ts.map +1 -0
  486. package/src/sockets/CloudflareSocket.js +259 -0
  487. package/src/start.d.ts.map +1 -1
  488. package/src/start.js +1 -8
  489. package/src/templates/docker/docker-compose.ecosystem.yml.tpl +301 -0
  490. package/src/templates/docker/docker-compose.schedules.yml.tpl +84 -0
  491. package/src/templates/project/basic/app/Schedules/index.ts.tpl +0 -0
  492. package/src/templates/project/basic/config/database.ts.tpl +1 -1
  493. package/src/templates/project/basic/src/zintrust.plugins.wg.ts.tpl +8 -0
  494. package/src/toolkit/Secrets/Manifest.d.ts.map +1 -1
  495. package/src/toolkit/Secrets/Manifest.js +5 -7
  496. package/src/tools/mail/drivers/Smtp.d.ts.map +1 -1
  497. package/src/tools/mail/drivers/Smtp.js +229 -18
  498. package/src/tools/mail/index.d.ts.map +1 -1
  499. package/src/tools/mail/index.js +5 -4
  500. package/src/tools/mail/template-loader.d.ts.map +1 -1
  501. package/src/tools/mail/template-loader.js +197 -29
  502. package/src/tools/mail/templates/auth-password-reset.d.ts +3 -0
  503. package/src/tools/mail/templates/auth-password-reset.d.ts.map +1 -0
  504. package/src/tools/mail/templates/auth-password-reset.js +231 -0
  505. package/src/tools/mail/templates/auth-welcome.d.ts +3 -0
  506. package/src/tools/mail/templates/auth-welcome.d.ts.map +1 -0
  507. package/src/tools/mail/templates/auth-welcome.js +236 -0
  508. package/src/tools/mail/templates/general.d.ts +3 -0
  509. package/src/tools/mail/templates/general.d.ts.map +1 -0
  510. package/src/tools/mail/templates/general.js +109 -0
  511. package/src/tools/mail/templates/index.js +2 -2
  512. package/src/tools/mail/templates/job-completed.d.ts +3 -0
  513. package/src/tools/mail/templates/job-completed.d.ts.map +1 -0
  514. package/src/tools/mail/templates/job-completed.js +188 -0
  515. package/src/tools/mail/templates/notifications-new-comment.d.ts +3 -0
  516. package/src/tools/mail/templates/notifications-new-comment.d.ts.map +1 -0
  517. package/src/tools/mail/templates/notifications-new-comment.js +228 -0
  518. package/src/tools/mail/templates/password-reset.d.ts +3 -0
  519. package/src/tools/mail/templates/password-reset.d.ts.map +1 -0
  520. package/src/tools/mail/templates/password-reset.js +221 -0
  521. package/src/tools/mail/templates/performance-report.d.ts +3 -0
  522. package/src/tools/mail/templates/performance-report.d.ts.map +1 -0
  523. package/src/tools/mail/templates/performance-report.js +258 -0
  524. package/src/tools/mail/templates/welcome.d.ts +3 -0
  525. package/src/tools/mail/templates/welcome.d.ts.map +1 -0
  526. package/src/tools/mail/templates/welcome.js +187 -0
  527. package/src/tools/mail/templates/worker-alert.d.ts +3 -0
  528. package/src/tools/mail/templates/worker-alert.d.ts.map +1 -0
  529. package/src/tools/mail/templates/worker-alert.js +229 -0
  530. package/src/tools/notification/Notification.js +1 -1
  531. package/src/tools/notification/testingHelpers.js +6 -5
  532. package/src/tools/queue/AdvancedQueue.js +2 -6
  533. package/src/tools/queue/IdempotencyManager.d.ts +6 -0
  534. package/src/tools/queue/IdempotencyManager.d.ts.map +1 -0
  535. package/src/tools/queue/IdempotencyManager.js +36 -0
  536. package/src/tools/queue/JobHeartbeatStore.d.ts +16 -0
  537. package/src/tools/queue/JobHeartbeatStore.d.ts.map +1 -0
  538. package/src/tools/queue/JobHeartbeatStore.js +67 -0
  539. package/src/tools/queue/JobReconciliationRunner.d.ts +16 -0
  540. package/src/tools/queue/JobReconciliationRunner.d.ts.map +1 -0
  541. package/src/tools/queue/JobReconciliationRunner.js +56 -0
  542. package/src/tools/queue/JobRecoveryDaemon.d.ts +27 -0
  543. package/src/tools/queue/JobRecoveryDaemon.d.ts.map +1 -0
  544. package/src/tools/queue/JobRecoveryDaemon.js +303 -0
  545. package/src/tools/queue/JobStateTracker.d.ts +140 -0
  546. package/src/tools/queue/JobStateTracker.d.ts.map +1 -0
  547. package/src/tools/queue/JobStateTracker.js +409 -0
  548. package/src/tools/queue/JobStateTrackerDbPersistence.d.ts +12 -0
  549. package/src/tools/queue/JobStateTrackerDbPersistence.d.ts.map +1 -0
  550. package/src/tools/queue/JobStateTrackerDbPersistence.js +239 -0
  551. package/src/tools/queue/Queue.d.ts.map +1 -1
  552. package/src/tools/queue/Queue.js +160 -16
  553. package/src/tools/queue/QueueDataRedactor.d.ts +6 -0
  554. package/src/tools/queue/QueueDataRedactor.d.ts.map +1 -0
  555. package/src/tools/queue/QueueDataRedactor.js +45 -0
  556. package/src/tools/queue/QueueExtensions.d.ts.map +1 -1
  557. package/src/tools/queue/QueueExtensions.js +2 -1
  558. package/src/tools/queue/QueueReliabilityMetrics.d.ts +38 -0
  559. package/src/tools/queue/QueueReliabilityMetrics.d.ts.map +1 -0
  560. package/src/tools/queue/QueueReliabilityMetrics.js +131 -0
  561. package/src/tools/queue/QueueReliabilityOrchestrator.d.ts +7 -0
  562. package/src/tools/queue/QueueReliabilityOrchestrator.d.ts.map +1 -0
  563. package/src/tools/queue/QueueReliabilityOrchestrator.js +59 -0
  564. package/src/tools/queue/QueueRuntimeRegistration.d.ts +1 -9
  565. package/src/tools/queue/QueueRuntimeRegistration.d.ts.map +1 -1
  566. package/src/tools/queue/QueueRuntimeRegistration.js +75 -4
  567. package/src/tools/queue/QueueTracing.d.ts +32 -0
  568. package/src/tools/queue/QueueTracing.d.ts.map +1 -0
  569. package/src/tools/queue/QueueTracing.js +151 -0
  570. package/src/tools/queue/StalledJobMonitor.d.ts +5 -0
  571. package/src/tools/queue/StalledJobMonitor.d.ts.map +1 -0
  572. package/src/tools/queue/StalledJobMonitor.js +21 -0
  573. package/src/tools/queue/TimeoutManager.d.ts +14 -0
  574. package/src/tools/queue/TimeoutManager.d.ts.map +1 -0
  575. package/src/tools/queue/TimeoutManager.js +77 -0
  576. package/src/tools/queue/drivers/Redis.d.ts +1 -0
  577. package/src/tools/queue/drivers/Redis.d.ts.map +1 -1
  578. package/src/tools/queue/drivers/Redis.js +1 -0
  579. package/src/tools/queue/index.d.ts +10 -0
  580. package/src/tools/queue/index.d.ts.map +1 -1
  581. package/src/tools/queue/index.js +10 -0
  582. package/src/tools/storage/drivers/R2.d.ts +13 -0
  583. package/src/tools/storage/drivers/R2.d.ts.map +1 -1
  584. package/src/tools/storage/drivers/R2.js +29 -0
  585. package/src/zintrust.plugins.d.ts +9 -0
  586. package/src/zintrust.plugins.d.ts.map +1 -0
  587. package/src/zintrust.plugins.js +7 -0
  588. package/src/zintrust.plugins.wg.d.ts +9 -0
  589. package/src/zintrust.plugins.wg.d.ts.map +1 -0
  590. package/src/zintrust.plugins.wg.js +7 -0
@@ -1,13 +1,31 @@
1
1
  import { generateUuid } from '../../../common/utility.js';
2
+ import { RemoteSignedJson } from '../../../common/RemoteSignedJson.js';
3
+ import { Cloudflare } from '../../../config/cloudflare.js';
4
+ import { Env } from '../../../config/env.js';
5
+ import { Logger } from '../../../config/logger.js';
2
6
  import { ErrorFactory } from '../../../exceptions/ZintrustError.js';
3
7
  import * as net from '../../../node-singletons/net.js';
4
8
  import * as tls from '../../../node-singletons/tls.js';
9
+ import { normalizeSigningCredentials } from '../../../proxy/SigningService.js';
10
+ const resolveSigningPrefix = (baseUrl) => {
11
+ try {
12
+ const parsed = new URL(baseUrl);
13
+ const path = parsed.pathname.endsWith('/') ? parsed.pathname.slice(0, -1) : parsed.pathname;
14
+ if (path === '' || path === '/')
15
+ return undefined;
16
+ return path;
17
+ }
18
+ catch {
19
+ return undefined;
20
+ }
21
+ };
5
22
  const normalizeRecipients = (to) => (Array.isArray(to) ? to : [to]);
6
23
  const toBase64 = (value) => Buffer.from(value, 'utf8').toString('base64');
7
24
  const isNodeRuntime = () => typeof process !== 'undefined' && typeof process.versions?.node === 'string';
25
+ const isWorkersRuntime = () => Cloudflare.getWorkersEnv() !== null;
8
26
  const validateConfig = (config) => {
9
- if (!isNodeRuntime()) {
10
- throw ErrorFactory.createConfigError('SMTP driver requires Node.js runtime');
27
+ if (!isNodeRuntime() && !isWorkersRuntime()) {
28
+ throw ErrorFactory.createConfigError('SMTP driver requires Node.js or Workers runtime');
11
29
  }
12
30
  if (config.host.trim() === '') {
13
31
  throw ErrorFactory.createConfigError('SMTP: missing MAIL_HOST');
@@ -16,7 +34,101 @@ const validateConfig = (config) => {
16
34
  throw ErrorFactory.createConfigError('SMTP: invalid MAIL_PORT');
17
35
  }
18
36
  };
19
- const createSocket = async (config, implicitTls) => {
37
+ const resolveProxyBaseUrl = () => {
38
+ const explicit = Env.SMTP_PROXY_URL.trim();
39
+ if (explicit !== '')
40
+ return explicit;
41
+ const host = Env.SMTP_PROXY_HOST || '127.0.0.1';
42
+ const port = Env.SMTP_PROXY_PORT;
43
+ return `http://${host}:${port}`;
44
+ };
45
+ const buildProxySettings = () => {
46
+ const baseUrl = resolveProxyBaseUrl();
47
+ const keyId = Env.SMTP_PROXY_KEY_ID ?? '';
48
+ const secret = Env.SMTP_PROXY_SECRET ?? '';
49
+ const timeoutMs = Env.SMTP_PROXY_TIMEOUT_MS;
50
+ return { baseUrl, keyId, secret, timeoutMs };
51
+ };
52
+ const buildSignedSettings = (settings) => {
53
+ const creds = normalizeSigningCredentials({
54
+ keyId: settings.keyId ?? '',
55
+ secret: settings.secret ?? '',
56
+ });
57
+ return {
58
+ baseUrl: settings.baseUrl,
59
+ keyId: creds.keyId,
60
+ secret: creds.secret,
61
+ timeoutMs: settings.timeoutMs,
62
+ signaturePathPrefixToStrip: resolveSigningPrefix(settings.baseUrl),
63
+ missingUrlMessage: 'SMTP proxy URL is missing (SMTP_PROXY_URL)',
64
+ missingCredentialsMessage: 'SMTP proxy signing credentials are missing (SMTP_PROXY_KEY_ID / SMTP_PROXY_SECRET)',
65
+ messages: {
66
+ unauthorized: 'SMTP proxy unauthorized',
67
+ forbidden: 'SMTP proxy forbidden',
68
+ rateLimited: 'SMTP proxy rate limited',
69
+ rejected: 'SMTP proxy rejected request',
70
+ error: 'SMTP proxy error',
71
+ timedOut: 'SMTP proxy request timed out',
72
+ },
73
+ };
74
+ };
75
+ const ensureSignedSettings = (settings) => {
76
+ const signedSettings = buildSignedSettings(settings);
77
+ if (signedSettings.baseUrl.trim() === '') {
78
+ throw ErrorFactory.createConfigError('SMTP proxy URL is missing (SMTP_PROXY_URL)');
79
+ }
80
+ if (signedSettings.keyId.trim() === '' || signedSettings.secret.trim() === '') {
81
+ throw ErrorFactory.createConfigError('SMTP proxy signing credentials are missing (SMTP_PROXY_KEY_ID / SMTP_PROXY_SECRET)');
82
+ }
83
+ return signedSettings;
84
+ };
85
+ const shouldUseProxy = () => {
86
+ if (Env.USE_SMTP_PROXY === true)
87
+ return true;
88
+ // In Cloudflare Workers, SMTP requires TCP sockets; if sockets are disabled,
89
+ // we must use the HTTP SMTP proxy transport when a URL is configured.
90
+ if (isWorkersRuntime() && Cloudflare.isCloudflareSocketsEnabled() === false) {
91
+ return Env.SMTP_PROXY_URL.trim() !== '';
92
+ }
93
+ // Default: do not use proxy unless explicitly enabled.
94
+ return false;
95
+ };
96
+ const serializeMessage = (message) => {
97
+ const attachments = message.attachments?.map((attachment) => {
98
+ const raw = Buffer.isBuffer(attachment.content)
99
+ ? attachment.content
100
+ : Buffer.from(attachment.content);
101
+ return {
102
+ filename: attachment.filename,
103
+ contentBase64: raw.toString('base64'),
104
+ };
105
+ });
106
+ return {
107
+ to: message.to,
108
+ from: message.from,
109
+ subject: message.subject,
110
+ text: message.text,
111
+ html: message.html,
112
+ attachments: attachments && attachments.length > 0 ? attachments : undefined,
113
+ };
114
+ };
115
+ const sendViaProxy = async (message) => {
116
+ const settings = buildProxySettings();
117
+ const signedSettings = ensureSignedSettings(settings);
118
+ return RemoteSignedJson.request(signedSettings, '/zin/smtp/send', {
119
+ message: serializeMessage(message),
120
+ });
121
+ };
122
+ const loadCloudflareSocketFactory = async () => {
123
+ const mod = (await import('../../../sockets/CloudflareSocket.js'));
124
+ const record = mod;
125
+ const socketFactory = record.CloudflareSocket;
126
+ if (!socketFactory || typeof socketFactory.create !== 'function') {
127
+ throw ErrorFactory.createConnectionError('Cloudflare socket factory unavailable');
128
+ }
129
+ return socketFactory;
130
+ };
131
+ const createNodeSocket = async (config, implicitTls) => {
20
132
  validateConfig(config);
21
133
  return new Promise((resolve, reject) => {
22
134
  const onError = (err) => {
@@ -34,6 +146,16 @@ const createSocket = async (config, implicitTls) => {
34
146
  servername: config.host,
35
147
  })
36
148
  : net.connect({ host: config.host, port: config.port });
149
+ if (typeof socket.setTimeout === 'function') {
150
+ socket.setTimeout(10000);
151
+ }
152
+ socket.once('timeout', () => {
153
+ socket.destroy();
154
+ reject(ErrorFactory.createConnectionError('SMTP connection timed out', {
155
+ host: config.host,
156
+ port: config.port,
157
+ }));
158
+ });
37
159
  if (implicitTls) {
38
160
  socket.once('secureConnect', () => resolve(socket));
39
161
  }
@@ -43,9 +165,67 @@ const createSocket = async (config, implicitTls) => {
43
165
  socket.once('error', onError);
44
166
  });
45
167
  };
168
+ const createWorkersSocket = async (config, implicitTls) => {
169
+ validateConfig(config);
170
+ return new Promise((resolve, reject) => {
171
+ let cleanup = () => undefined;
172
+ const onError = (err) => {
173
+ cleanup();
174
+ reject(ErrorFactory.createConnectionError('SMTP connection failed', {
175
+ host: config.host,
176
+ port: config.port,
177
+ secure: implicitTls,
178
+ error: err,
179
+ }));
180
+ };
181
+ const socketFactoryPromise = loadCloudflareSocketFactory();
182
+ socketFactoryPromise
183
+ .then((socketFactory) => {
184
+ const socket = socketFactory.create(config.host, config.port, {
185
+ tls: implicitTls,
186
+ });
187
+ if (!socket) {
188
+ reject(ErrorFactory.createConnectionError('SMTP socket initialization failed'));
189
+ return;
190
+ }
191
+ const onConnect = () => {
192
+ cleanup(socket);
193
+ resolve(socket);
194
+ };
195
+ cleanup = (target) => {
196
+ if (!target)
197
+ return;
198
+ if (typeof target.off === 'function') {
199
+ target.off('connect', onConnect);
200
+ target.off('error', onError);
201
+ }
202
+ else if (typeof target.removeListener === 'function') {
203
+ target.removeListener('connect', onConnect);
204
+ target.removeListener('error', onError);
205
+ }
206
+ };
207
+ socket.once('connect', onConnect);
208
+ socket.once('error', onError);
209
+ })
210
+ .catch((err) => {
211
+ reject(ErrorFactory.createConnectionError('SMTP socket initialization failed', {
212
+ error: err,
213
+ }));
214
+ });
215
+ });
216
+ };
217
+ const createSocket = async (config, implicitTls) => {
218
+ if (isWorkersRuntime())
219
+ return createWorkersSocket(config, implicitTls);
220
+ return createNodeSocket(config, implicitTls);
221
+ };
46
222
  const upgradeToStartTls = async (socket, host) => {
223
+ if (typeof socket.startTls === 'function') {
224
+ await socket.startTls();
225
+ return socket;
226
+ }
47
227
  return new Promise((resolve, reject) => {
48
- const tlsSocket = tls.connect({ socket, servername: host });
228
+ const tlsSocket = tls.connect({ socket: socket, servername: host });
49
229
  tlsSocket.once('secureConnect', () => {
50
230
  resolve(tlsSocket);
51
231
  });
@@ -68,7 +248,8 @@ const createLineReader = (socket) => {
68
248
  }
69
249
  };
70
250
  const onData = (data) => {
71
- buffer += data.toString('utf8');
251
+ const chunk = data instanceof Uint8Array ? data : Buffer.from(String(data));
252
+ buffer += Buffer.from(chunk).toString('utf8');
72
253
  wake();
73
254
  };
74
255
  socket.on('data', onData);
@@ -84,7 +265,19 @@ const createLineReader = (socket) => {
84
265
  const immediate = tryReadLineFromBuffer();
85
266
  if (typeof immediate === 'string')
86
267
  return immediate;
87
- await new Promise((resolve) => waiters.push(resolve));
268
+ await new Promise((resolve, reject) => {
269
+ let fired = false;
270
+ const timer = globalThis.setTimeout(() => {
271
+ fired = true;
272
+ reject(ErrorFactory.createConnectionError('SMTP read timeout'));
273
+ }, 30000);
274
+ waiters.push(() => {
275
+ if (fired)
276
+ return;
277
+ clearTimeout(timer);
278
+ resolve();
279
+ });
280
+ });
88
281
  return readLine();
89
282
  };
90
283
  const readMultiline = async (code, message) => {
@@ -112,20 +305,39 @@ const createLineReader = (socket) => {
112
305
  return { code, message };
113
306
  };
114
307
  const close = () => {
115
- socket.off('data', onData);
308
+ if (typeof socket.off === 'function') {
309
+ socket.off('data', onData);
310
+ }
116
311
  };
117
312
  return { readResponse, close };
118
313
  };
119
- const writeLine = async (socket, line) => {
314
+ const writeRaw = async (socket, data) => {
120
315
  return new Promise((resolve, reject) => {
121
- socket.write(`${line}\r\n`, (err) => {
316
+ let settled = false;
317
+ const finish = (err) => {
318
+ if (settled)
319
+ return;
320
+ settled = true;
122
321
  if (err)
123
322
  reject(err);
124
323
  else
125
324
  resolve();
126
- });
325
+ };
326
+ try {
327
+ const writer = socket;
328
+ writer.write(data, (err) => finish(err));
329
+ if (writer.write.length < 2) {
330
+ finish();
331
+ }
332
+ }
333
+ catch (err) {
334
+ finish(err);
335
+ }
127
336
  });
128
337
  };
338
+ const writeLine = async (socket, line) => {
339
+ return writeRaw(socket, `${line}\r\n`);
340
+ };
129
341
  const assertCode = (res, expected, context) => {
130
342
  const allowed = Array.isArray(expected) ? expected : [expected];
131
343
  if (!allowed.includes(res.code)) {
@@ -213,14 +425,7 @@ const doData = async (socket, reader, message) => {
213
425
  assertCode(dataRes, 354, 'DATA');
214
426
  const raw = buildRfc2822Message(message);
215
427
  const stuffed = dotStuff(raw);
216
- await new Promise((resolve, reject) => {
217
- socket.write(`${stuffed}\r\n.\r\n`, (err) => {
218
- if (err)
219
- reject(err);
220
- else
221
- resolve();
222
- });
223
- });
428
+ await writeRaw(socket, `${stuffed}\r\n.\r\n`);
224
429
  const queued = await reader.readResponse();
225
430
  assertCode(queued, 250, 'message body');
226
431
  };
@@ -304,6 +509,12 @@ export const SmtpDriver = Object.freeze({
304
509
  * - `secure='starttls'` performs STARTTLS after EHLO.
305
510
  */
306
511
  async send(config, message) {
512
+ if (shouldUseProxy()) {
513
+ const proxyUrl = Env.SMTP_PROXY_URL;
514
+ Logger.debug('[SmtpDriver] Using SmtpProxy', { proxyUrl });
515
+ const result = await sendViaProxy(message);
516
+ return { ok: Boolean(result.ok), provider: 'smtp', messageId: result.messageId };
517
+ }
307
518
  let mode = 'none';
308
519
  if (config.secure === true)
309
520
  mode = 'tls';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/tools/mail/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAsB,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAI7E,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE;QACL,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,WAAW,CAAC,EAAE,eAAe,EAAE,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,UAAU,GAAG,UAAU,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,GAAG,YAAY,CAAC;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAoJF,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAcD,eAAO,MAAM,IAAI;IACf;;OAEG;kBACiB,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC;IAIrD,sBAAsB;gBACJ,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC;IAGnD;;;;OAIG;iBACU,MAAM;cA5Db,CAAC,KAAK,EAAE,aAAa,KAAK,OAAO,CAAC,cAAc,CAAC;;gBAgErC,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;EAGzD,CAAC;AAEH,eAAe,IAAI,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/tools/mail/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAsB,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAI7E,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE;QACL,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,WAAW,CAAC,EAAE,eAAe,EAAE,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,UAAU,GAAG,UAAU,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,GAAG,YAAY,CAAC;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAgJF,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAsBD,eAAO,MAAM,IAAI;IACf;;OAEG;kBACiB,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC;IAIrD,sBAAsB;gBACJ,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC;IAGnD;;;;OAIG;iBACU,MAAM;cAnEb,CAAC,KAAK,EAAE,aAAa,KAAK,OAAO,CAAC,cAAc,CAAC;;gBAuErC,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;EAGzD,CAAC;AAEH,eAAe,IAAI,CAAC"}
@@ -70,10 +70,7 @@ const sendWithDriver = async (driver, message) => {
70
70
  throw ErrorFactory.createConfigError(`Mail driver not registered: ${driver.driver} (run \`zin add mail:${driver.driver}\` / \`npm i @zintrust/mail-${driver.driver}\`)`);
71
71
  }
72
72
  // Config exists for future drivers, but implementations are intentionally CLI/runtime-safe and added incrementally.
73
- {
74
- const err = ErrorFactory.createConfigError(`Mail driver not implemented: ${mailConfig.default}`);
75
- throw err;
76
- }
73
+ throw ErrorFactory.createConfigError(`Mail driver not registered: ${mailConfig.default}. Available drivers: ses, sendgrid, mailgun, smtp. Run \`zin add mail:${mailConfig.default}\` to install.`);
77
74
  };
78
75
  const createMailer = (name) => Object.freeze({
79
76
  async send(input) {
@@ -95,10 +92,14 @@ const createMailer = (name) => Object.freeze({
95
92
  });
96
93
  },
97
94
  });
95
+ const looksLikeHtml = (value) => /<\s*html\b|<!doctype\b|<\s*body\b/i.test(value);
98
96
  async function renderTemplateToHtml(input) {
99
97
  const { template, variables } = input;
100
98
  // Import lazily to avoid circular deps
101
99
  const { loadTemplate } = await import('./template-loader.js');
100
+ if (looksLikeHtml(template)) {
101
+ return loadTemplate(template, (variables ?? {}));
102
+ }
102
103
  // template-loader expects full filename
103
104
  const fileName = template.endsWith('.html') ? template : `${template}.html`;
104
105
  return loadTemplate(fileName, (variables ?? {}));
@@ -1 +1 @@
1
- {"version":3,"file":"template-loader.d.ts","sourceRoot":"","sources":["../../../../src/tools/mail/template-loader.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAG9D;;GAEG;AACH,wBAAsB,YAAY,CAChC,YAAY,EAAE,MAAM,EACpB,SAAS,GAAE,iBAAsB,GAChC,OAAO,CAAC,MAAM,CAAC,CA6CjB;AAuDD;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,EAAE,CAShD"}
1
+ {"version":3,"file":"template-loader.d.ts","sourceRoot":"","sources":["../../../../src/tools/mail/template-loader.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAoM9D;;GAEG;AACH,wBAAsB,YAAY,CAChC,YAAY,EAAE,MAAM,EACpB,SAAS,GAAE,iBAAsB,GAChC,OAAO,CAAC,MAAM,CAAC,CAwBjB;AA2FD;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,EAAE,CAShD"}
@@ -1,37 +1,173 @@
1
1
  import { ErrorFactory } from '../../exceptions/ZintrustError.js';
2
2
  import { readFile } from '../../node-singletons/fs.js';
3
3
  import { dirname, join } from '../../node-singletons/path.js';
4
- import { fileURLToPath } from '../../node-singletons/url.js';
4
+ import { fileURLToPath, pathToFileURL } from '../../node-singletons/url.js';
5
5
  import { Env } from '../../config/env.js';
6
6
  import { interpolate } from './template-utils.js';
7
+ const looksLikeHtml = (value) => /<\s*html\b|<!doctype\b|<\s*body\b/i.test(value);
8
+ const builtinTemplateLoaders = Object.freeze({
9
+ 'auth-password-reset': async () => import('./templates/auth-password-reset.js'),
10
+ 'auth-welcome': async () => import('./templates/auth-welcome.js'),
11
+ general: async () => import('./templates/general.js'),
12
+ 'job-completed': async () => import('./templates/job-completed.js'),
13
+ 'notifications-new-comment': async () => import('./templates/notifications-new-comment.js'),
14
+ 'password-reset': async () => import('./templates/password-reset.js'),
15
+ 'performance-report': async () => import('./templates/performance-report.js'),
16
+ welcome: async () => import('./templates/welcome.js'),
17
+ 'worker-alert': async () => import('./templates/worker-alert.js'),
18
+ });
19
+ const getSafeCwd = () => {
20
+ try {
21
+ if (typeof process !== 'undefined' && typeof process.cwd === 'function') {
22
+ const cwd = process.cwd();
23
+ if (typeof cwd === 'string' && cwd.trim() !== '')
24
+ return cwd;
25
+ }
26
+ }
27
+ catch {
28
+ return '';
29
+ }
30
+ return '';
31
+ };
7
32
  /**
8
- * Load and render email template with variable substitution
33
+ * Get the base directory for templates.
34
+ * In Cloudflare Workers, import.meta.url may be undefined, so we handle that case.
9
35
  */
10
- export async function loadTemplate(templateName, variables = {}) {
36
+ function getBaseDir() {
11
37
  try {
12
- const baseDir = dirname(fileURLToPath(import.meta.url));
13
- const isPath = templateName.includes('/') || templateName.endsWith('.html');
14
- let templatePath;
15
- if (isPath) {
16
- if (templateName.startsWith('/')) {
17
- templatePath = templateName;
18
- }
19
- else {
20
- templatePath = join(process.cwd(), templateName);
21
- }
38
+ // Check if import.meta.url is available (Node.js, Deno, modern bundlers)
39
+ if (typeof import.meta.url === 'string' && import.meta.url.trim() !== '') {
40
+ return dirname(fileURLToPath(import.meta.url));
41
+ }
42
+ }
43
+ catch {
44
+ // Fallback for environments where fileURLToPath fails
45
+ }
46
+ // Fallback: use cwd if available
47
+ const cwd = getSafeCwd();
48
+ if (cwd.trim() !== '') {
49
+ return join(cwd, 'src', 'tools', 'mail');
50
+ }
51
+ // Last resort: return a relative path that might work
52
+ return './src/tools/mail';
53
+ }
54
+ function resolveTemplatePath(templateName) {
55
+ const baseDir = getBaseDir();
56
+ const isPath = templateName.includes('/') || templateName.endsWith('.html');
57
+ if (!isPath) {
58
+ return join(baseDir, 'templates', `${templateName}.html`);
59
+ }
60
+ if (templateName.startsWith('/')) {
61
+ return templateName;
62
+ }
63
+ const cwd = getSafeCwd();
64
+ return cwd.trim() === '' ? join(baseDir, templateName) : join(cwd, templateName);
65
+ }
66
+ function normalizeTemplateName(templateName) {
67
+ return {
68
+ normalizedTemplate: templateName.endsWith('.html') ? templateName : `${templateName}.html`,
69
+ normalizedModuleName: templateName.endsWith('.html') ? templateName.slice(0, -5) : templateName,
70
+ };
71
+ }
72
+ async function tryBuiltinLoader(normalizedModuleName) {
73
+ const builtinLoader = builtinTemplateLoaders[normalizedModuleName];
74
+ if (builtinLoader === undefined) {
75
+ return null;
76
+ }
77
+ try {
78
+ const imported = (await builtinLoader());
79
+ if (typeof imported.default === 'string' && imported.default.trim() !== '') {
80
+ return imported.default;
81
+ }
82
+ }
83
+ catch {
84
+ // Fall through to filesystem/module path probes.
85
+ }
86
+ return null;
87
+ }
88
+ function getFileCandidates(templatePath, normalizedTemplate) {
89
+ const cwd = getSafeCwd();
90
+ const baseDir = getBaseDir();
91
+ return [
92
+ templatePath,
93
+ join(baseDir, 'templates', normalizedTemplate),
94
+ join(cwd, 'dist', 'src', 'tools', 'mail', 'templates', normalizedTemplate),
95
+ join(cwd, 'src', 'tools', 'mail', 'templates', normalizedTemplate),
96
+ ].filter((path, index, arr) => path.trim() !== '' && arr.indexOf(path) === index);
97
+ }
98
+ function getModuleCandidates(normalizedModuleName) {
99
+ const cwd = getSafeCwd();
100
+ const baseDir = getBaseDir();
101
+ return [
102
+ join(cwd, 'dist', 'src', 'tools', 'mail', 'templates', `${normalizedModuleName}.js`),
103
+ join(cwd, 'src', 'tools', 'mail', 'templates', `${normalizedModuleName}.ts`),
104
+ join(baseDir, 'templates', `${normalizedModuleName}.js`),
105
+ join(baseDir, 'templates', `${normalizedModuleName}.ts`),
106
+ ].filter((path, index, arr) => path.trim() !== '' && arr.indexOf(path) === index);
107
+ }
108
+ async function tryReadFromCandidates(candidates) {
109
+ let lastError;
110
+ for (const candidate of candidates) {
111
+ try {
112
+ // eslint-disable-next-line no-await-in-loop
113
+ const content = await readFile(candidate, 'utf-8');
114
+ return { content };
22
115
  }
23
- else {
24
- templatePath = join(baseDir, 'templates', `${templateName}.html`);
116
+ catch (error) {
117
+ lastError = error;
25
118
  }
26
- let template;
119
+ }
120
+ return { error: lastError };
121
+ }
122
+ async function tryImportFromCandidates(moduleCandidates) {
123
+ let lastError;
124
+ for (const modulePath of moduleCandidates) {
27
125
  try {
28
- template = await readFile(templatePath, 'utf-8');
126
+ // eslint-disable-next-line no-await-in-loop
127
+ const imported = (await import(pathToFileURL(modulePath).href));
128
+ if (typeof imported.default === 'string' && imported.default.trim() !== '') {
129
+ return { content: imported.default };
130
+ }
29
131
  }
30
- catch {
31
- // Fallback to built-in directory if the supplied name looked like a file but wasn't found
32
- const fallbackPath = join(baseDir, 'templates', templateName.endsWith('.html') ? templateName : `${templateName}.html`);
33
- template = await readFile(fallbackPath, 'utf-8');
132
+ catch (error) {
133
+ lastError = error;
34
134
  }
135
+ }
136
+ return { error: lastError };
137
+ }
138
+ async function loadTemplateContent(templateName) {
139
+ const templatePath = resolveTemplatePath(templateName);
140
+ const { normalizedTemplate, normalizedModuleName } = normalizeTemplateName(templateName);
141
+ // Try builtin loader first
142
+ const builtinResult = await tryBuiltinLoader(normalizedModuleName);
143
+ if (builtinResult !== null && typeof builtinResult === 'string') {
144
+ return builtinResult;
145
+ }
146
+ // Try file system candidates
147
+ const fileCandidates = getFileCandidates(templatePath, normalizedTemplate);
148
+ const fileResult = await tryReadFromCandidates(fileCandidates);
149
+ if (fileResult.content !== undefined) {
150
+ return fileResult.content;
151
+ }
152
+ // Try module candidates
153
+ const moduleCandidates = getModuleCandidates(normalizedModuleName);
154
+ const moduleResult = await tryImportFromCandidates(moduleCandidates);
155
+ if (moduleResult.content !== undefined) {
156
+ return moduleResult.content;
157
+ }
158
+ // Extract last error from failed attempts
159
+ const lastError = fileResult.error ?? moduleResult.error;
160
+ throw ErrorFactory.createConfigError(`Failed to load template from known paths: ${[...fileCandidates, ...moduleCandidates].join(', ')}` +
161
+ (lastError === undefined ? '' : `. Last error: ${String(lastError)}`));
162
+ }
163
+ /**
164
+ * Load and render email template with variable substitution
165
+ */
166
+ export async function loadTemplate(templateName, variables = {}) {
167
+ try {
168
+ const template = looksLikeHtml(templateName)
169
+ ? templateName
170
+ : await loadTemplateContent(templateName);
35
171
  // Replace variables using shared interpolate util
36
172
  const mergedVars = {
37
173
  year: new Date().getFullYear().toString(),
@@ -53,21 +189,16 @@ export async function loadTemplate(templateName, variables = {}) {
53
189
  * Render conditional blocks {{#if_condition}}...{{/if_condition}}
54
190
  */
55
191
  function renderConditionals(template, variables) {
56
- const conditionalRegex = /{{#if_(\w+)}}(.+?){{\/if_\1}}/gs;
57
- return template.replaceAll(conditionalRegex, (_fullMatch, condition, content) => {
192
+ return renderBlockTags(template, 'if', (condition, content) => {
58
193
  const value = variables[condition];
59
- if (value === true || value === 'true') {
60
- return content;
61
- }
62
- return '';
194
+ return value === true || value === 'true' ? content : '';
63
195
  });
64
196
  }
65
197
  /**
66
198
  * Render loop blocks {{#each_array}}...{{/each_array}}
67
199
  */
68
200
  function renderLoops(template, variables) {
69
- const loopRegex = /{{#each_(\w+)}}(.+?){{\/each_\1}}/gs;
70
- return template.replaceAll(loopRegex, (_fullMatch, arrayName, content) => {
201
+ return renderBlockTags(template, 'each', (arrayName, content) => {
71
202
  const array = variables[arrayName];
72
203
  if (!Array.isArray(array)) {
73
204
  return '';
@@ -86,6 +217,43 @@ function renderLoops(template, variables) {
86
217
  .join('');
87
218
  });
88
219
  }
220
+ const isSafeBlockName = (value) => /^\w+$/.test(value);
221
+ const renderBlockTags = (template, tagPrefix, resolver) => {
222
+ const openPrefix = `{{#${tagPrefix}_`;
223
+ let cursor = 0;
224
+ let output = '';
225
+ while (cursor < template.length) {
226
+ const openIndex = template.indexOf(openPrefix, cursor);
227
+ if (openIndex < 0) {
228
+ output += template.slice(cursor);
229
+ break;
230
+ }
231
+ output += template.slice(cursor, openIndex);
232
+ const nameStart = openIndex + openPrefix.length;
233
+ const openEnd = template.indexOf('}}', nameStart);
234
+ if (openEnd < 0) {
235
+ output += template.slice(openIndex);
236
+ break;
237
+ }
238
+ const name = template.slice(nameStart, openEnd);
239
+ if (!isSafeBlockName(name)) {
240
+ output += template.slice(openIndex, openEnd + 2);
241
+ cursor = openEnd + 2;
242
+ continue;
243
+ }
244
+ const closeToken = `{{/${tagPrefix}_${name}}}`;
245
+ const contentStart = openEnd + 2;
246
+ const closeIndex = template.indexOf(closeToken, contentStart);
247
+ if (closeIndex < 0) {
248
+ output += template.slice(openIndex);
249
+ break;
250
+ }
251
+ const content = template.slice(contentStart, closeIndex);
252
+ output += resolver(name, content);
253
+ cursor = closeIndex + closeToken.length;
254
+ }
255
+ return output;
256
+ };
89
257
  /**
90
258
  * Get list of available templates
91
259
  */
@@ -0,0 +1,3 @@
1
+ declare const _default: "<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n <title>Password Reset Request</title>\n <style>\n body {\n margin: 0;\n padding: 0;\n background-color: #0b1220;\n color: #e2e8f0;\n font-family:\n -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n }\n\n .email-container {\n max-width: 600px;\n margin: 40px auto;\n background-color: #0f172a;\n border: 1px solid #334155;\n border-radius: 12px;\n overflow: hidden;\n }\n\n .header {\n padding: 40px 40px 30px;\n text-align: center;\n background: linear-gradient(180deg, rgba(239, 68, 68, 0.15), rgba(220, 38, 38, 0.08));\n border-bottom: 1px solid #334155;\n }\n\n .icon {\n width: 48px;\n height: 48px;\n margin: 0 auto 20px;\n border-radius: 12px;\n border: 1px solid rgba(239, 68, 68, 0.35);\n background: linear-gradient(180deg, rgba(239, 68, 68, 0.2), rgba(220, 38, 38, 0.1));\n display: inline-flex;\n align-items: center;\n justify-content: center;\n }\n\n .title {\n margin: 0 0 8px;\n font-size: 28px;\n font-weight: 700;\n color: #e2e8f0;\n line-height: 1.2;\n }\n\n .subtitle {\n margin: 0;\n font-size: 16px;\n color: #e2e8f0;\n line-height: 1.5;\n }\n\n .content {\n padding: 40px;\n }\n\n .greeting {\n margin: 0 0 24px;\n font-size: 15px;\n color: #f1f5f9;\n line-height: 1.6;\n }\n\n .message {\n margin: 0 0 24px;\n font-size: 15px;\n color: #f1f5f9;\n line-height: 1.6;\n }\n\n .button-container {\n margin-bottom: 30px;\n text-align: center;\n }\n\n .reset-button {\n display: inline-block;\n padding: 14px 32px;\n background: linear-gradient(135deg, #ef4444, #dc2626);\n color: #ffffff;\n text-decoration: none;\n border-radius: 8px;\n font-weight: 600;\n font-size: 15px;\n border: 1px solid rgba(217, 82, 82, 0.8);\n }\n\n .security-notice {\n padding: 16px;\n background: rgba(251, 191, 36, 0.08);\n border-left: 3px solid #fbbf24;\n border-radius: 6px;\n margin-bottom: 30px;\n }\n\n .security-notice p {\n margin: 0;\n font-size: 14px;\n color: #e2e8f0;\n line-height: 1.6;\n }\n\n .security-notice strong {\n color: #fbbf24;\n }\n\n .expiry {\n margin: 0 0 16px;\n font-size: 14px;\n color: #e2e8f0;\n line-height: 1.6;\n }\n\n .expiry strong {\n color: #e2e8f0;\n }\n\n .alternative-link {\n margin: 0;\n font-size: 13px;\n color: #e2e8f0;\n line-height: 1.6;\n }\n\n .alternative-link a {\n color: #bae6fd;\n text-decoration: none;\n word-break: break-all;\n }\n\n .divider {\n margin: 30px 0;\n border-top: 1px solid #334155;\n }\n\n .support {\n margin: 0;\n font-size: 14px;\n color: #e2e8f0;\n line-height: 1.6;\n }\n\n .support a {\n color: #bae6fd;\n text-decoration: none;\n }\n\n .footer {\n padding: 30px 40px;\n background: rgba(15, 23, 42, 0.65);\n border-top: 1px solid #334155;\n text-align: center;\n }\n\n .footer p {\n margin: 0;\n font-size: 12px;\n color: #64748b;\n }\n </style>\n </head>\n <body>\n <div class=\"email-container\">\n <!-- Header -->\n <div class=\"header\">\n <div class=\"icon\">\n <span style=\"font-size: 24px\">\uD83D\uDD12</span>\n </div>\n <h1 class=\"title\">Password Reset Request</h1>\n <p class=\"subtitle\">We received a request to reset your password</p>\n </div>\n\n <!-- Main Content -->\n <div class=\"content\">\n <p class=\"greeting\">Hi <strong style=\"color: #e2e8f0\">{{name}}</strong>,</p>\n\n <p class=\"message\">\n Someone requested a password reset for your {{APP_NAME}} account (<strong\n style=\"color: #e2e8f0\"\n >{{email}}</strong\n >). If this was you, click the button below to reset your password:\n </p>\n\n <!-- CTA Button -->\n <div class=\"button-container\">\n <a href=\"{{reset_url}}\" class=\"reset-button\">Reset Password</a>\n </div>\n\n <!-- Security Notice -->\n <div class=\"security-notice\">\n <p>\n <strong>\u26A0 Security Notice</strong><br />\n If you didn't request this password reset, please ignore this email. Your password will\n remain unchanged.\n </p>\n </div>\n\n <p class=\"expiry\">\n For security reasons, this link will expire in <strong>{{expiryMinutes}} minutes</strong>.\n </p>\n\n <!-- Alternative Link -->\n <p class=\"alternative-link\">\n If the button above doesn't work, copy and paste this link into your browser:<br />\n <a href=\"{{reset_url}}\">{{reset_url}}</a>\n </p>\n\n <!-- Divider -->\n <div class=\"divider\"></div>\n\n <p class=\"support\">\n If you continue to have problems, please contact our\n <a href=\"{{support_url}}\">support team</a>.\n </p>\n </div>\n\n <!-- Footer -->\n <div class=\"footer\">\n <p>&copy; {{year}} {{APP_NAME}}. All rights reserved.</p>\n </div>\n </div>\n </body>\n</html>";
2
+ export default _default;
3
+ //# sourceMappingURL=auth-password-reset.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-password-reset.d.ts","sourceRoot":"","sources":["../../../../../src/tools/mail/templates/auth-password-reset.ts"],"names":[],"mappings":";AAAA,wBAsOS"}