@zintrust/core 0.1.0 → 0.1.2

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 (518) hide show
  1. package/README.md +214 -0
  2. package/bin/zintrust.d.ts.map +1 -1
  3. package/bin/zintrust.js +18 -1
  4. package/package.json +4 -34
  5. package/public/index.html +535 -0
  6. package/src/boot/Application.d.ts.map +1 -1
  7. package/src/boot/Application.js +46 -3
  8. package/src/boot/Server.d.ts.map +1 -1
  9. package/src/boot/Server.js +3 -4
  10. package/src/boot/bootstrap.js +77 -6
  11. package/src/builder/BundleOptimizer.d.ts.map +1 -1
  12. package/src/builder/BundleOptimizer.js +25 -29
  13. package/src/cache/Cache.d.ts.map +1 -1
  14. package/src/cache/Cache.js +4 -2
  15. package/src/cache/drivers/KVDriver.d.ts.map +1 -1
  16. package/src/cache/drivers/KVDriver.js +8 -7
  17. package/src/cache/drivers/MemoryDriver.d.ts.map +1 -1
  18. package/src/cache/drivers/MemoryDriver.js +5 -0
  19. package/src/cache/drivers/RedisDriver.js +1 -1
  20. package/src/cli/BaseCommand.d.ts +2 -2
  21. package/src/cli/BaseCommand.d.ts.map +1 -1
  22. package/src/cli/BaseCommand.js +2 -1
  23. package/src/cli/CLI.d.ts.map +1 -1
  24. package/src/cli/CLI.js +22 -18
  25. package/src/cli/ErrorHandler.d.ts.map +1 -1
  26. package/src/cli/ErrorHandler.js +2 -4
  27. package/src/cli/commands/AddCommand.d.ts +81 -0
  28. package/src/cli/commands/AddCommand.d.ts.map +1 -1
  29. package/src/cli/commands/AddCommand.js +24 -5
  30. package/src/cli/commands/ConfigCommand.d.ts.map +1 -1
  31. package/src/cli/commands/ConfigCommand.js +59 -25
  32. package/src/cli/commands/D1MigrateCommand.d.ts +4 -0
  33. package/src/cli/commands/D1MigrateCommand.d.ts.map +1 -1
  34. package/src/cli/commands/D1MigrateCommand.js +6 -4
  35. package/src/cli/commands/FixCommand.d.ts.map +1 -1
  36. package/src/cli/commands/FixCommand.js +3 -15
  37. package/src/cli/commands/LogsCleanupCommand.d.ts +6 -0
  38. package/src/cli/commands/LogsCleanupCommand.d.ts.map +1 -0
  39. package/src/cli/commands/LogsCleanupCommand.js +20 -0
  40. package/src/cli/commands/LogsCommand.d.ts.map +1 -1
  41. package/src/cli/commands/LogsCommand.js +4 -6
  42. package/src/cli/commands/MakeMailTemplateCommand.d.ts +10 -0
  43. package/src/cli/commands/MakeMailTemplateCommand.d.ts.map +1 -0
  44. package/src/cli/commands/MakeMailTemplateCommand.js +74 -0
  45. package/src/cli/commands/MakeNotificationTemplateCommand.d.ts +10 -0
  46. package/src/cli/commands/MakeNotificationTemplateCommand.d.ts.map +1 -0
  47. package/src/cli/commands/MakeNotificationTemplateCommand.js +113 -0
  48. package/src/cli/commands/MigrateCommand.d.ts.map +1 -1
  49. package/src/cli/commands/MigrateCommand.js +3 -3
  50. package/src/cli/commands/NewCommand.d.ts +4 -0
  51. package/src/cli/commands/NewCommand.d.ts.map +1 -1
  52. package/src/cli/commands/NewCommand.js +34 -19
  53. package/src/cli/commands/PluginCommand.d.ts.map +1 -1
  54. package/src/cli/commands/PluginCommand.js +8 -4
  55. package/src/cli/commands/PrepareCommand.d.ts.map +1 -1
  56. package/src/cli/commands/PrepareCommand.js +1 -1
  57. package/src/cli/commands/QACommand.d.ts.map +1 -1
  58. package/src/cli/commands/QACommand.js +16 -26
  59. package/src/cli/commands/SecretsCommand.d.ts +16 -0
  60. package/src/cli/commands/SecretsCommand.d.ts.map +1 -0
  61. package/src/cli/commands/SecretsCommand.js +91 -0
  62. package/src/cli/commands/StartCommand.d.ts.map +1 -1
  63. package/src/cli/commands/StartCommand.js +2 -2
  64. package/src/cli/commands/TemplatesCommand.d.ts +3 -0
  65. package/src/cli/commands/TemplatesCommand.d.ts.map +1 -0
  66. package/src/cli/commands/TemplatesCommand.js +65 -0
  67. package/src/cli/commands/index.d.ts +5 -0
  68. package/src/cli/commands/index.d.ts.map +1 -1
  69. package/src/cli/commands/index.js +5 -0
  70. package/src/cli/config/ConfigManager.js +1 -1
  71. package/src/cli/index.d.ts +2 -1
  72. package/src/cli/index.d.ts.map +1 -1
  73. package/src/cli/index.js +2 -1
  74. package/src/cli/scaffolding/ControllerGenerator.d.ts.map +1 -1
  75. package/src/cli/scaffolding/ControllerGenerator.js +11 -10
  76. package/src/cli/scaffolding/FeatureScaffolder.js +4 -4
  77. package/src/cli/scaffolding/FileGenerator.js +1 -1
  78. package/src/cli/scaffolding/MigrationGenerator.d.ts.map +1 -1
  79. package/src/cli/scaffolding/MigrationGenerator.js +10 -9
  80. package/src/cli/scaffolding/ModelGenerator.d.ts.map +1 -1
  81. package/src/cli/scaffolding/ModelGenerator.js +11 -10
  82. package/src/cli/scaffolding/ProjectScaffolder.d.ts.map +1 -1
  83. package/src/cli/scaffolding/ProjectScaffolder.js +61 -11
  84. package/src/cli/scaffolding/ResponseFactoryGenerator.d.ts.map +1 -1
  85. package/src/cli/scaffolding/ResponseFactoryGenerator.js +2 -1
  86. package/src/cli/scaffolding/RouteGenerator.d.ts.map +1 -1
  87. package/src/cli/scaffolding/RouteGenerator.js +15 -14
  88. package/src/cli/scaffolding/SeederGenerator.js +1 -1
  89. package/src/cli/scaffolding/ServiceIntegrationTestGenerator.d.ts.map +1 -1
  90. package/src/cli/scaffolding/ServiceIntegrationTestGenerator.js +7 -6
  91. package/src/cli/scaffolding/ServiceRequestFactoryGenerator.d.ts +1 -1
  92. package/src/cli/scaffolding/ServiceRequestFactoryGenerator.d.ts.map +1 -1
  93. package/src/cli/scaffolding/ServiceRequestFactoryGenerator.js +2 -2
  94. package/src/cli/scaffolding/ServiceScaffolder.d.ts.map +1 -1
  95. package/src/cli/scaffolding/ServiceScaffolder.js +13 -12
  96. package/src/cli/scaffolding/TemplateEngine.d.ts +10 -3
  97. package/src/cli/scaffolding/TemplateEngine.d.ts.map +1 -1
  98. package/src/cli/scaffolding/TemplateEngine.js +15 -285
  99. package/src/cli/scaffolding/TemplateGenerator.d.ts +40 -0
  100. package/src/cli/scaffolding/TemplateGenerator.d.ts.map +1 -0
  101. package/src/cli/scaffolding/TemplateGenerator.js +172 -0
  102. package/src/cli/scaffolding/index.d.ts +1 -0
  103. package/src/cli/scaffolding/index.d.ts.map +1 -1
  104. package/src/cli/scaffolding/index.js +1 -0
  105. package/src/cli/utils/spawn.js +1 -1
  106. package/src/common/AwsSigV4.d.ts +41 -0
  107. package/src/common/AwsSigV4.d.ts.map +1 -0
  108. package/src/common/AwsSigV4.js +69 -0
  109. package/src/common/index.d.ts +39 -0
  110. package/src/common/index.d.ts.map +1 -1
  111. package/src/common/index.js +101 -8
  112. package/src/common/uuid.d.ts +3 -0
  113. package/src/common/uuid.d.ts.map +1 -0
  114. package/src/common/uuid.js +30 -0
  115. package/src/config/FileLogWriter.d.ts +22 -0
  116. package/src/config/FileLogWriter.d.ts.map +1 -0
  117. package/src/config/FileLogWriter.js +192 -0
  118. package/src/config/SecretsManager.d.ts.map +1 -1
  119. package/src/config/SecretsManager.js +26 -0
  120. package/src/config/StartupConfigValidator.d.ts +15 -0
  121. package/src/config/StartupConfigValidator.d.ts.map +1 -0
  122. package/src/config/StartupConfigValidator.js +86 -0
  123. package/src/config/app.d.ts +2 -1
  124. package/src/config/app.d.ts.map +1 -1
  125. package/src/config/app.js +65 -15
  126. package/src/config/broadcast.d.ts +47 -0
  127. package/src/config/broadcast.d.ts.map +1 -0
  128. package/src/config/broadcast.js +54 -0
  129. package/src/config/cache.d.ts +13 -17
  130. package/src/config/cache.d.ts.map +1 -1
  131. package/src/config/cache.js +9 -11
  132. package/src/config/cloudflare.d.ts +26 -0
  133. package/src/config/cloudflare.d.ts.map +1 -0
  134. package/src/config/cloudflare.js +38 -0
  135. package/src/config/env.d.ts +6 -0
  136. package/src/config/env.d.ts.map +1 -1
  137. package/src/config/env.js +6 -0
  138. package/src/config/index.d.ts +52 -28
  139. package/src/config/index.d.ts.map +1 -1
  140. package/src/config/index.js +3 -0
  141. package/src/config/logger.d.ts +2 -0
  142. package/src/config/logger.d.ts.map +1 -1
  143. package/src/config/logger.js +270 -11
  144. package/src/config/logging/HttpLogger.d.ts +23 -0
  145. package/src/config/logging/HttpLogger.d.ts.map +1 -0
  146. package/src/config/logging/HttpLogger.js +93 -0
  147. package/src/config/logging/KvLogger.d.ts +22 -0
  148. package/src/config/logging/KvLogger.d.ts.map +1 -0
  149. package/src/config/logging/KvLogger.js +143 -0
  150. package/src/config/logging/SlackLogger.d.ts +23 -0
  151. package/src/config/logging/SlackLogger.d.ts.map +1 -0
  152. package/src/config/logging/SlackLogger.js +119 -0
  153. package/src/config/mail.d.ts +81 -0
  154. package/src/config/mail.d.ts.map +1 -0
  155. package/src/config/mail.js +73 -0
  156. package/src/config/middleware.d.ts +8 -0
  157. package/src/config/middleware.d.ts.map +1 -0
  158. package/src/config/middleware.js +18 -0
  159. package/src/config/notification.d.ts +62 -0
  160. package/src/config/notification.d.ts.map +1 -0
  161. package/src/config/notification.js +43 -0
  162. package/src/config/security.d.ts.map +1 -1
  163. package/src/config/security.js +2 -2
  164. package/src/config/startup.d.ts +23 -0
  165. package/src/config/startup.d.ts.map +1 -0
  166. package/src/config/startup.js +15 -0
  167. package/src/config/storage.d.ts +21 -35
  168. package/src/config/storage.d.ts.map +1 -1
  169. package/src/config/storage.js +57 -37
  170. package/src/database/migrations/index.d.ts +1 -1
  171. package/src/database/migrations/index.d.ts.map +1 -1
  172. package/src/database/migrations/index.js +2 -1
  173. package/src/features/Queue.js +1 -25
  174. package/src/functions/lambda.d.ts.map +1 -1
  175. package/src/functions/lambda.js +6 -1
  176. package/src/health/RuntimeHealthProbes.d.ts +13 -0
  177. package/src/health/RuntimeHealthProbes.d.ts.map +1 -0
  178. package/src/health/RuntimeHealthProbes.js +62 -0
  179. package/src/health/StartupHealthChecks.d.ts +26 -0
  180. package/src/health/StartupHealthChecks.d.ts.map +1 -0
  181. package/src/health/StartupHealthChecks.js +124 -0
  182. package/src/http/ErrorResponse.d.ts +28 -0
  183. package/src/http/ErrorResponse.d.ts.map +1 -0
  184. package/src/http/ErrorResponse.js +42 -0
  185. package/src/http/Kernel.d.ts +5 -0
  186. package/src/http/Kernel.d.ts.map +1 -1
  187. package/src/http/Kernel.js +96 -30
  188. package/src/http/Request.d.ts +1 -1
  189. package/src/http/Request.d.ts.map +1 -1
  190. package/src/http/RequestContext.d.ts +20 -0
  191. package/src/http/RequestContext.d.ts.map +1 -0
  192. package/src/http/RequestContext.js +77 -0
  193. package/src/index.d.ts +9 -1
  194. package/src/index.d.ts.map +1 -1
  195. package/src/index.js +8 -2
  196. package/src/microservices/MicroserviceBootstrap.d.ts.map +1 -1
  197. package/src/microservices/MicroserviceBootstrap.js +6 -5
  198. package/src/microservices/MicroserviceManager.d.ts.map +1 -1
  199. package/src/microservices/MicroserviceManager.js +7 -5
  200. package/src/microservices/PostgresAdapter.d.ts.map +1 -1
  201. package/src/microservices/PostgresAdapter.js +7 -4
  202. package/src/microservices/ServiceBundler.d.ts.map +1 -1
  203. package/src/microservices/ServiceBundler.js +3 -1
  204. package/src/microservices/ServiceHealthMonitor.d.ts.map +1 -1
  205. package/src/microservices/ServiceHealthMonitor.js +7 -3
  206. package/src/middleware/CsrfMiddleware.d.ts.map +1 -1
  207. package/src/middleware/CsrfMiddleware.js +2 -19
  208. package/src/middleware/ErrorHandlerMiddleware.d.ts +6 -0
  209. package/src/middleware/ErrorHandlerMiddleware.d.ts.map +1 -0
  210. package/src/middleware/ErrorHandlerMiddleware.js +33 -0
  211. package/src/middleware/LoggingMiddleware.d.ts +9 -0
  212. package/src/middleware/LoggingMiddleware.d.ts.map +1 -0
  213. package/src/middleware/LoggingMiddleware.js +36 -0
  214. package/src/middleware/index.d.ts +2 -0
  215. package/src/middleware/index.d.ts.map +1 -1
  216. package/src/middleware/index.js +2 -0
  217. package/src/node-singletons/async_hooks.d.ts +9 -0
  218. package/src/node-singletons/async_hooks.d.ts.map +1 -0
  219. package/src/node-singletons/async_hooks.js +8 -0
  220. package/src/node-singletons/fs.d.ts +2 -2
  221. package/src/node-singletons/fs.d.ts.map +1 -1
  222. package/src/node-singletons/fs.js +2 -2
  223. package/src/node-singletons/http.d.ts +1 -1
  224. package/src/node-singletons/http.d.ts.map +1 -1
  225. package/src/node-singletons/http.js +1 -1
  226. package/src/node-singletons/index.d.ts +4 -0
  227. package/src/node-singletons/index.d.ts.map +1 -1
  228. package/src/node-singletons/index.js +4 -0
  229. package/src/node-singletons/net.d.ts +9 -0
  230. package/src/node-singletons/net.d.ts.map +1 -0
  231. package/src/node-singletons/net.js +8 -0
  232. package/src/node-singletons/os.d.ts +3 -3
  233. package/src/node-singletons/os.d.ts.map +1 -1
  234. package/src/node-singletons/os.js +3 -4
  235. package/src/node-singletons/path.d.ts +3 -1
  236. package/src/node-singletons/path.d.ts.map +1 -1
  237. package/src/node-singletons/path.js +3 -1
  238. package/src/node-singletons/perf-hooks.d.ts +3 -1
  239. package/src/node-singletons/perf-hooks.d.ts.map +1 -1
  240. package/src/node-singletons/perf-hooks.js +3 -1
  241. package/src/node-singletons/process.d.ts +23 -0
  242. package/src/node-singletons/process.d.ts.map +1 -0
  243. package/src/node-singletons/process.js +8 -0
  244. package/src/node-singletons/readline.d.ts +3 -3
  245. package/src/node-singletons/readline.d.ts.map +1 -1
  246. package/src/node-singletons/readline.js +3 -4
  247. package/src/node-singletons/tls.d.ts +9 -0
  248. package/src/node-singletons/tls.d.ts.map +1 -0
  249. package/src/node-singletons/tls.js +8 -0
  250. package/src/node-singletons/url.d.ts +3 -1
  251. package/src/node-singletons/url.d.ts.map +1 -1
  252. package/src/node-singletons/url.js +3 -1
  253. package/src/orm/ConnectionManager.d.ts +6 -1
  254. package/src/orm/ConnectionManager.d.ts.map +1 -1
  255. package/src/orm/ConnectionManager.js +14 -0
  256. package/src/orm/DatabaseAdapter.d.ts +6 -0
  257. package/src/orm/DatabaseAdapter.d.ts.map +1 -1
  258. package/src/orm/QueryBuilder.d.ts +8 -1
  259. package/src/orm/QueryBuilder.d.ts.map +1 -1
  260. package/src/orm/QueryBuilder.js +188 -28
  261. package/src/orm/adapters/D1Adapter.d.ts.map +1 -1
  262. package/src/orm/adapters/D1Adapter.js +18 -12
  263. package/src/orm/adapters/MySQLAdapter.d.ts.map +1 -1
  264. package/src/orm/adapters/MySQLAdapter.js +4 -0
  265. package/src/orm/adapters/PostgreSQLAdapter.d.ts.map +1 -1
  266. package/src/orm/adapters/PostgreSQLAdapter.js +4 -0
  267. package/src/orm/adapters/SQLServerAdapter.d.ts.map +1 -1
  268. package/src/orm/adapters/SQLServerAdapter.js +4 -0
  269. package/src/orm/adapters/SQLiteAdapter.d.ts.map +1 -1
  270. package/src/orm/adapters/SQLiteAdapter.js +4 -0
  271. package/src/performance/Benchmark.d.ts.map +1 -1
  272. package/src/performance/Benchmark.js +3 -0
  273. package/src/performance/CodeGenerationBenchmark.js +3 -3
  274. package/src/performance/Optimizer.d.ts +1 -1
  275. package/src/performance/Optimizer.d.ts.map +1 -1
  276. package/src/performance/Optimizer.js +157 -80
  277. package/src/performance/establish-baseline.js +3 -3
  278. package/src/runtime/PluginManager.d.ts +3 -1
  279. package/src/runtime/PluginManager.d.ts.map +1 -1
  280. package/src/runtime/PluginManager.js +124 -28
  281. package/src/runtime/RuntimeDetector.d.ts.map +1 -1
  282. package/src/runtime/RuntimeDetector.js +47 -5
  283. package/src/runtime/adapters/CloudflareAdapter.js +2 -2
  284. package/src/runtime/adapters/DenoAdapter.js +9 -7
  285. package/src/runtime/adapters/FargateAdapter.d.ts.map +1 -1
  286. package/src/runtime/adapters/FargateAdapter.js +4 -3
  287. package/src/runtime/adapters/LambdaAdapter.d.ts.map +1 -1
  288. package/src/runtime/adapters/LambdaAdapter.js +4 -2
  289. package/src/runtime/adapters/NodeServerAdapter.d.ts.map +1 -1
  290. package/src/runtime/adapters/NodeServerAdapter.js +7 -6
  291. package/src/scheduler/ScheduleRunner.d.ts +18 -0
  292. package/src/scheduler/ScheduleRunner.d.ts.map +1 -0
  293. package/src/scheduler/ScheduleRunner.js +155 -0
  294. package/src/scheduler/index.d.ts +3 -0
  295. package/src/scheduler/index.d.ts.map +1 -0
  296. package/src/scheduler/index.js +1 -0
  297. package/src/scheduler/types.d.ts +16 -0
  298. package/src/scheduler/types.d.ts.map +1 -0
  299. package/src/scheduler/types.js +4 -0
  300. package/src/schedules/index.d.ts +2 -0
  301. package/src/schedules/index.d.ts.map +1 -0
  302. package/src/schedules/index.js +1 -0
  303. package/src/schedules/log-cleanup.d.ts +4 -0
  304. package/src/schedules/log-cleanup.d.ts.map +1 -0
  305. package/src/schedules/log-cleanup.js +18 -0
  306. package/src/scripts/GenerateEnvArtifacts.d.ts +13 -0
  307. package/src/scripts/GenerateEnvArtifacts.d.ts.map +1 -0
  308. package/src/scripts/GenerateEnvArtifacts.js +171 -0
  309. package/src/scripts/TemplateSync.js +109 -70
  310. package/src/security/CsrfTokenManager.js +1 -1
  311. package/src/security/Encryptor.js +1 -1
  312. package/src/security/Hash.d.ts +14 -0
  313. package/src/security/Hash.d.ts.map +1 -0
  314. package/src/security/Hash.js +81 -0
  315. package/src/security/StartupSecretValidation.d.ts +20 -0
  316. package/src/security/StartupSecretValidation.d.ts.map +1 -0
  317. package/src/security/StartupSecretValidation.js +61 -0
  318. package/src/security/UrlValidator.d.ts +0 -1
  319. package/src/security/UrlValidator.d.ts.map +1 -1
  320. package/src/security/UrlValidator.js +1 -2
  321. package/src/security/Xss.d.ts +14 -0
  322. package/src/security/Xss.d.ts.map +1 -0
  323. package/src/security/Xss.js +57 -0
  324. package/src/security/XssProtection.d.ts.map +1 -1
  325. package/src/security/XssProtection.js +150 -16
  326. package/src/templates/adapters/MySQLAdapter.ts.tpl +5 -0
  327. package/src/templates/adapters/PostgreSQLAdapter.ts.tpl +5 -0
  328. package/src/templates/adapters/SQLServerAdapter.ts.tpl +5 -0
  329. package/src/templates/adapters/SQLiteAdapter.ts.tpl +5 -0
  330. package/src/templates/features/Queue.ts.tpl +1 -29
  331. package/src/templates/project/basic/.env.example.tpl +48 -0
  332. package/src/templates/project/basic/.env.tpl +89 -94
  333. package/src/templates/project/basic/app/Toolkit/Broadcast/sendBroadcast.ts.tpl +7 -0
  334. package/src/templates/project/basic/app/Toolkit/Mail/sendWelcomeEmail.ts.tpl +30 -0
  335. package/src/templates/project/basic/app/Toolkit/Notification/sendSlackNotification.ts.tpl +10 -0
  336. package/src/templates/project/basic/app/Toolkit/Notification/sendSms.ts.tpl +13 -0
  337. package/src/templates/project/basic/config/FileLogWriter.ts.tpl +240 -0
  338. package/src/templates/project/basic/config/SecretsManager.ts.tpl +32 -1
  339. package/src/templates/project/basic/config/StartupConfigValidator.ts.tpl +151 -0
  340. package/src/templates/project/basic/config/app.ts.tpl +84 -15
  341. package/src/templates/project/basic/config/broadcast.ts.tpl +97 -0
  342. package/src/templates/project/basic/config/cache.ts.tpl +19 -23
  343. package/src/templates/project/basic/config/cloudflare.ts.tpl +57 -0
  344. package/src/templates/project/basic/config/env.ts.tpl +7 -1
  345. package/src/templates/project/basic/config/index.ts.tpl +3 -0
  346. package/src/templates/project/basic/config/logger.ts.tpl +301 -11
  347. package/src/templates/project/basic/config/logging/HttpLogger.ts.tpl +121 -0
  348. package/src/templates/project/basic/config/logging/KvLogger.ts.tpl +181 -0
  349. package/src/templates/project/basic/config/logging/SlackLogger.ts.tpl +156 -0
  350. package/src/templates/project/basic/config/mail.ts.tpl +141 -0
  351. package/src/templates/project/basic/config/middleware.ts.tpl +27 -0
  352. package/src/templates/project/basic/config/notification.ts.tpl +86 -0
  353. package/src/templates/project/basic/config/security.ts.tpl +4 -5
  354. package/src/templates/project/basic/config/startup.ts.tpl +27 -0
  355. package/src/templates/project/basic/config/storage.ts.tpl +77 -42
  356. package/src/templates/project/basic/database/migrations/index.ts.tpl +1 -1
  357. package/src/templates/project/basic/package.json.tpl +1 -1
  358. package/src/templates/project/basic/routes/api.ts.tpl +9 -37
  359. package/src/templates/project/basic/routes/broadcast.ts.tpl +32 -0
  360. package/src/templates/project/basic/routes/health.ts.tpl +134 -0
  361. package/src/templates/project/basic/src/index.ts.tpl +38 -11
  362. package/src/templates/project/basic/template.json +3 -0
  363. package/src/toolkit/Secrets/EnvFile.d.ts +15 -0
  364. package/src/toolkit/Secrets/EnvFile.d.ts.map +1 -0
  365. package/src/toolkit/Secrets/EnvFile.js +63 -0
  366. package/src/toolkit/Secrets/Manifest.d.ts +24 -0
  367. package/src/toolkit/Secrets/Manifest.d.ts.map +1 -0
  368. package/src/toolkit/Secrets/Manifest.js +71 -0
  369. package/src/toolkit/Secrets/index.d.ts +42 -0
  370. package/src/toolkit/Secrets/index.d.ts.map +1 -0
  371. package/src/toolkit/Secrets/index.js +119 -0
  372. package/src/toolkit/Secrets/providers/AwsSecretsManager.d.ts +14 -0
  373. package/src/toolkit/Secrets/providers/AwsSecretsManager.d.ts.map +1 -0
  374. package/src/toolkit/Secrets/providers/AwsSecretsManager.js +131 -0
  375. package/src/toolkit/Secrets/providers/CloudflareKv.d.ts +9 -0
  376. package/src/toolkit/Secrets/providers/CloudflareKv.d.ts.map +1 -0
  377. package/src/toolkit/Secrets/providers/CloudflareKv.js +73 -0
  378. package/src/tools/broadcast/Broadcast.d.ts +7 -0
  379. package/src/tools/broadcast/Broadcast.d.ts.map +1 -0
  380. package/src/tools/broadcast/Broadcast.js +37 -0
  381. package/src/tools/broadcast/drivers/BaseDriver.d.ts +5 -0
  382. package/src/tools/broadcast/drivers/BaseDriver.d.ts.map +1 -0
  383. package/src/tools/broadcast/drivers/BaseDriver.js +8 -0
  384. package/src/tools/broadcast/drivers/InMemory.d.ts +18 -0
  385. package/src/tools/broadcast/drivers/InMemory.d.ts.map +1 -0
  386. package/src/tools/broadcast/drivers/InMemory.js +16 -0
  387. package/src/tools/broadcast/drivers/Pusher.d.ts +8 -0
  388. package/src/tools/broadcast/drivers/Pusher.d.ts.map +1 -0
  389. package/src/tools/broadcast/drivers/Pusher.js +75 -0
  390. package/src/tools/broadcast/drivers/Redis.d.ts +19 -0
  391. package/src/tools/broadcast/drivers/Redis.d.ts.map +1 -0
  392. package/src/tools/broadcast/drivers/Redis.js +73 -0
  393. package/src/tools/broadcast/drivers/RedisHttps.d.ts +14 -0
  394. package/src/tools/broadcast/drivers/RedisHttps.d.ts.map +1 -0
  395. package/src/tools/broadcast/drivers/RedisHttps.js +50 -0
  396. package/src/tools/broadcast/index.d.ts +7 -0
  397. package/src/tools/broadcast/index.d.ts.map +1 -0
  398. package/src/tools/broadcast/index.js +6 -0
  399. package/src/tools/http/Http.d.ts +51 -0
  400. package/src/tools/http/Http.d.ts.map +1 -0
  401. package/src/tools/http/Http.js +171 -0
  402. package/src/tools/http/HttpResponse.d.ts +32 -0
  403. package/src/tools/http/HttpResponse.d.ts.map +1 -0
  404. package/src/tools/http/HttpResponse.js +80 -0
  405. package/src/tools/http/index.d.ts +15 -0
  406. package/src/tools/http/index.d.ts.map +1 -0
  407. package/src/tools/http/index.js +9 -0
  408. package/src/tools/mail/Mail.d.ts +22 -0
  409. package/src/tools/mail/Mail.d.ts.map +1 -0
  410. package/src/tools/mail/Mail.js +105 -0
  411. package/src/tools/mail/attachments.d.ts +23 -0
  412. package/src/tools/mail/attachments.d.ts.map +1 -0
  413. package/src/tools/mail/attachments.js +26 -0
  414. package/src/tools/mail/drivers/BaseDriver.d.ts +5 -0
  415. package/src/tools/mail/drivers/BaseDriver.d.ts.map +1 -0
  416. package/src/tools/mail/drivers/BaseDriver.js +8 -0
  417. package/src/tools/mail/drivers/Mailgun.d.ts +31 -0
  418. package/src/tools/mail/drivers/Mailgun.d.ts.map +1 -0
  419. package/src/tools/mail/drivers/Mailgun.js +81 -0
  420. package/src/tools/mail/drivers/SendGrid.d.ts +29 -0
  421. package/src/tools/mail/drivers/SendGrid.d.ts.map +1 -0
  422. package/src/tools/mail/drivers/SendGrid.js +57 -0
  423. package/src/tools/mail/drivers/Ses.d.ts +24 -0
  424. package/src/tools/mail/drivers/Ses.d.ts.map +1 -0
  425. package/src/tools/mail/drivers/Ses.js +116 -0
  426. package/src/tools/mail/drivers/Smtp.d.ts +38 -0
  427. package/src/tools/mail/drivers/Smtp.d.ts.map +1 -0
  428. package/src/tools/mail/drivers/Smtp.js +327 -0
  429. package/src/tools/mail/templates/index.d.ts +27 -0
  430. package/src/tools/mail/templates/index.d.ts.map +1 -0
  431. package/src/tools/mail/templates/index.js +35 -0
  432. package/src/tools/mail/templates/markdown/index.d.ts +17 -0
  433. package/src/tools/mail/templates/markdown/index.d.ts.map +1 -0
  434. package/src/tools/mail/templates/markdown/index.js +49 -0
  435. package/src/tools/mail/templates/markdown/registry.d.ts +15 -0
  436. package/src/tools/mail/templates/markdown/registry.d.ts.map +1 -0
  437. package/src/tools/mail/templates/markdown/registry.js +34 -0
  438. package/src/tools/mail/templates/markdown/validator.d.ts +16 -0
  439. package/src/tools/mail/templates/markdown/validator.d.ts.map +1 -0
  440. package/src/tools/mail/templates/markdown/validator.js +24 -0
  441. package/src/tools/mail/testing.d.ts +41 -0
  442. package/src/tools/mail/testing.d.ts.map +1 -0
  443. package/src/tools/mail/testing.js +34 -0
  444. package/src/tools/notification/Driver.d.ts +11 -0
  445. package/src/tools/notification/Driver.d.ts.map +1 -0
  446. package/src/tools/notification/Driver.js +1 -0
  447. package/src/tools/notification/Notification.d.ts +11 -0
  448. package/src/tools/notification/Notification.d.ts.map +1 -0
  449. package/src/tools/notification/Notification.js +11 -0
  450. package/src/tools/notification/Registry.d.ts +10 -0
  451. package/src/tools/notification/Registry.d.ts.map +1 -0
  452. package/src/tools/notification/Registry.js +22 -0
  453. package/src/tools/notification/Service.d.ts +6 -0
  454. package/src/tools/notification/Service.d.ts.map +1 -0
  455. package/src/tools/notification/Service.js +18 -0
  456. package/src/tools/notification/config.d.ts +5 -0
  457. package/src/tools/notification/config.d.ts.map +1 -0
  458. package/src/tools/notification/config.js +5 -0
  459. package/src/tools/notification/drivers/BaseDriver.d.ts +5 -0
  460. package/src/tools/notification/drivers/BaseDriver.d.ts.map +1 -0
  461. package/src/tools/notification/drivers/BaseDriver.js +8 -0
  462. package/src/tools/notification/drivers/Console.d.ts +7 -0
  463. package/src/tools/notification/drivers/Console.d.ts.map +1 -0
  464. package/src/tools/notification/drivers/Console.js +13 -0
  465. package/src/tools/notification/drivers/Slack.d.ts +16 -0
  466. package/src/tools/notification/drivers/Slack.d.ts.map +1 -0
  467. package/src/tools/notification/drivers/Slack.js +24 -0
  468. package/src/tools/notification/drivers/Termii.d.ts +10 -0
  469. package/src/tools/notification/drivers/Termii.d.ts.map +1 -0
  470. package/src/tools/notification/drivers/Termii.js +47 -0
  471. package/src/tools/notification/drivers/Twilio.d.ts +21 -0
  472. package/src/tools/notification/drivers/Twilio.d.ts.map +1 -0
  473. package/src/tools/notification/drivers/Twilio.js +48 -0
  474. package/src/tools/notification/templates/markdown/index.d.ts +15 -0
  475. package/src/tools/notification/templates/markdown/index.d.ts.map +1 -0
  476. package/src/tools/notification/templates/markdown/index.js +38 -0
  477. package/src/tools/notification/templates/markdown/registry.d.ts +15 -0
  478. package/src/tools/notification/templates/markdown/registry.d.ts.map +1 -0
  479. package/src/tools/notification/templates/markdown/registry.js +36 -0
  480. package/src/tools/notification/testing.d.ts +19 -0
  481. package/src/tools/notification/testing.d.ts.map +1 -0
  482. package/src/tools/notification/testing.js +35 -0
  483. package/src/tools/notification/testingHelpers.d.ts +12 -0
  484. package/src/tools/notification/testingHelpers.d.ts.map +1 -0
  485. package/src/tools/notification/testingHelpers.js +32 -0
  486. package/src/tools/queue/Queue.d.ts +23 -0
  487. package/src/tools/queue/Queue.d.ts.map +1 -0
  488. package/src/tools/queue/Queue.js +38 -0
  489. package/src/tools/queue/drivers/InMemory.d.ts +10 -0
  490. package/src/tools/queue/drivers/InMemory.d.ts.map +1 -0
  491. package/src/tools/queue/drivers/InMemory.js +55 -0
  492. package/src/tools/queue/drivers/Redis.d.ts +10 -0
  493. package/src/tools/queue/drivers/Redis.d.ts.map +1 -0
  494. package/src/tools/queue/drivers/Redis.js +91 -0
  495. package/src/tools/storage/drivers/Gcs.d.ts +20 -0
  496. package/src/tools/storage/drivers/Gcs.d.ts.map +1 -0
  497. package/src/tools/storage/drivers/Gcs.js +152 -0
  498. package/src/tools/storage/drivers/Local.d.ts +17 -0
  499. package/src/tools/storage/drivers/Local.d.ts.map +1 -0
  500. package/src/tools/storage/drivers/Local.js +63 -0
  501. package/src/tools/storage/drivers/R2.d.ts +20 -0
  502. package/src/tools/storage/drivers/R2.d.ts.map +1 -0
  503. package/src/tools/storage/drivers/R2.js +73 -0
  504. package/src/tools/storage/drivers/S3.d.ts +26 -0
  505. package/src/tools/storage/drivers/S3.d.ts.map +1 -0
  506. package/src/tools/storage/drivers/S3.js +258 -0
  507. package/src/tools/storage/index.d.ts +24 -0
  508. package/src/tools/storage/index.d.ts.map +1 -0
  509. package/src/tools/storage/index.js +112 -0
  510. package/src/tools/storage/testing.d.ts +23 -0
  511. package/src/tools/storage/testing.d.ts.map +1 -0
  512. package/src/tools/storage/testing.js +52 -0
  513. package/src/tools/templates/MarkdownRenderer.d.ts +14 -0
  514. package/src/tools/templates/MarkdownRenderer.d.ts.map +1 -0
  515. package/src/tools/templates/MarkdownRenderer.js +300 -0
  516. package/src/tools/templates/index.d.ts +5 -0
  517. package/src/tools/templates/index.d.ts.map +1 -0
  518. package/src/tools/templates/index.js +4 -0
@@ -0,0 +1,327 @@
1
+ import { generateUuid } from '../../../common/uuid';
2
+ import { ErrorFactory } from '../../../exceptions/ZintrustError';
3
+ import * as net from '../../../node-singletons/net';
4
+ import * as tls from '../../../node-singletons/tls';
5
+ const normalizeRecipients = (to) => (Array.isArray(to) ? to : [to]);
6
+ const toBase64 = (value) => Buffer.from(value, 'utf8').toString('base64');
7
+ const isNodeRuntime = () => typeof process !== 'undefined' && typeof process.versions?.node === 'string';
8
+ const validateConfig = (config) => {
9
+ if (!isNodeRuntime()) {
10
+ throw ErrorFactory.createConfigError('SMTP driver requires Node.js runtime');
11
+ }
12
+ if (config.host.trim() === '') {
13
+ throw ErrorFactory.createConfigError('SMTP: missing MAIL_HOST');
14
+ }
15
+ if (!Number.isFinite(config.port) || config.port <= 0) {
16
+ throw ErrorFactory.createConfigError('SMTP: invalid MAIL_PORT');
17
+ }
18
+ };
19
+ const createSocket = async (config, implicitTls) => {
20
+ validateConfig(config);
21
+ return new Promise((resolve, reject) => {
22
+ const onError = (err) => {
23
+ reject(ErrorFactory.createConnectionError('SMTP connection failed', {
24
+ host: config.host,
25
+ port: config.port,
26
+ secure: implicitTls,
27
+ error: err,
28
+ }));
29
+ };
30
+ const socket = implicitTls
31
+ ? tls.connect({
32
+ host: config.host,
33
+ port: config.port,
34
+ servername: config.host,
35
+ })
36
+ : net.connect({ host: config.host, port: config.port });
37
+ if (implicitTls) {
38
+ socket.once('secureConnect', () => resolve(socket));
39
+ }
40
+ else {
41
+ socket.once('connect', () => resolve(socket));
42
+ }
43
+ socket.once('error', onError);
44
+ });
45
+ };
46
+ const upgradeToStartTls = async (socket, host) => {
47
+ return new Promise((resolve, reject) => {
48
+ const tlsSocket = tls.connect({ socket, servername: host });
49
+ tlsSocket.once('secureConnect', () => {
50
+ resolve(tlsSocket);
51
+ });
52
+ tlsSocket.once('error', (err) => {
53
+ reject(ErrorFactory.createConnectionError('SMTP STARTTLS upgrade failed', {
54
+ host,
55
+ error: err,
56
+ }));
57
+ });
58
+ });
59
+ };
60
+ const createLineReader = (socket) => {
61
+ let buffer = '';
62
+ const waiters = [];
63
+ const wake = () => {
64
+ while (waiters.length > 0) {
65
+ const w = waiters.shift();
66
+ if (w)
67
+ w();
68
+ }
69
+ };
70
+ const onData = (data) => {
71
+ buffer += data.toString('utf8');
72
+ wake();
73
+ };
74
+ socket.on('data', onData);
75
+ const tryReadLineFromBuffer = () => {
76
+ const idx = buffer.indexOf('\n');
77
+ if (idx < 0)
78
+ return undefined;
79
+ const line = buffer.slice(0, idx + 1);
80
+ buffer = buffer.slice(idx + 1);
81
+ return line.replaceAll(/\r?\n$/, '');
82
+ };
83
+ const readLine = async () => {
84
+ const immediate = tryReadLineFromBuffer();
85
+ if (typeof immediate === 'string')
86
+ return immediate;
87
+ await new Promise((resolve) => waiters.push(resolve));
88
+ return readLine();
89
+ };
90
+ const readMultiline = async (code, message) => {
91
+ const line = await readLine();
92
+ const nextCodeStr = line.slice(0, 3);
93
+ const nextCode = Number.parseInt(nextCodeStr, 10);
94
+ const nextMsg = line.length > 4 ? line.slice(4) : '';
95
+ const nextMessage = `${message}\n${nextMsg}`.trim();
96
+ if (Number.isFinite(nextCode) && nextCode === code && line[3] === ' ')
97
+ return nextMessage;
98
+ return readMultiline(code, nextMessage);
99
+ };
100
+ const readResponse = async () => {
101
+ const first = await readLine();
102
+ const codeStr = first.slice(0, 3);
103
+ const code = Number.parseInt(codeStr, 10);
104
+ if (!Number.isFinite(code)) {
105
+ throw ErrorFactory.createConnectionError('SMTP: invalid response code', { first });
106
+ }
107
+ let message = first.length > 4 ? first.slice(4) : '';
108
+ // Multiline response: "250-..." then "250 ..."
109
+ if (first[3] === '-') {
110
+ message = await readMultiline(code, message);
111
+ }
112
+ return { code, message };
113
+ };
114
+ const close = () => {
115
+ socket.off('data', onData);
116
+ };
117
+ return { readResponse, close };
118
+ };
119
+ const writeLine = async (socket, line) => {
120
+ return new Promise((resolve, reject) => {
121
+ socket.write(`${line}\r\n`, (err) => {
122
+ if (err)
123
+ reject(err);
124
+ else
125
+ resolve();
126
+ });
127
+ });
128
+ };
129
+ const assertCode = (res, expected, context) => {
130
+ const allowed = Array.isArray(expected) ? expected : [expected];
131
+ if (!allowed.includes(res.code)) {
132
+ throw ErrorFactory.createConnectionError(`SMTP: unexpected response for ${context}`, {
133
+ expected: allowed,
134
+ got: res.code,
135
+ message: res.message,
136
+ });
137
+ }
138
+ };
139
+ const hasCapability = (res, capability) => {
140
+ const cap = capability.trim().toUpperCase();
141
+ if (cap === '')
142
+ return false;
143
+ return res.message
144
+ .split('\n')
145
+ .some((line) => line.trim().toUpperCase().startsWith(cap) || line.trim().toUpperCase().includes(cap));
146
+ };
147
+ const doEhlo = async (socket, reader) => {
148
+ await writeLine(socket, 'EHLO zintrust');
149
+ const res = await reader.readResponse();
150
+ assertCode(res, 250, 'EHLO');
151
+ return res;
152
+ };
153
+ const doAuthLoginIfNeeded = async (socket, reader, config) => {
154
+ const username = config.username ?? '';
155
+ const password = config.password ?? '';
156
+ const wantsAuth = username.trim() !== '' || password.trim() !== '';
157
+ if (!wantsAuth)
158
+ return;
159
+ if (username.trim() === '' || password.trim() === '') {
160
+ throw ErrorFactory.createConfigError('SMTP: both MAIL_USERNAME and MAIL_PASSWORD are required');
161
+ }
162
+ await writeLine(socket, 'AUTH LOGIN');
163
+ const auth1 = await reader.readResponse();
164
+ assertCode(auth1, 334, 'AUTH LOGIN');
165
+ await writeLine(socket, toBase64(username));
166
+ const auth2 = await reader.readResponse();
167
+ assertCode(auth2, 334, 'AUTH username');
168
+ await writeLine(socket, toBase64(password));
169
+ const auth3 = await reader.readResponse();
170
+ assertCode(auth3, 235, 'AUTH password');
171
+ };
172
+ const doMailFrom = async (socket, reader, fromEmail) => {
173
+ await writeLine(socket, `MAIL FROM:<${fromEmail}>`);
174
+ const mailFrom = await reader.readResponse();
175
+ assertCode(mailFrom, [250, 251], 'MAIL FROM');
176
+ };
177
+ const doRcptToAll = async (socket, reader, recipients) => {
178
+ if (recipients.length === 0) {
179
+ throw ErrorFactory.createValidationError('SMTP: missing recipients');
180
+ }
181
+ await recipients.reduce(async (prev, rcpt) => {
182
+ await prev;
183
+ await writeLine(socket, `RCPT TO:<${rcpt}>`);
184
+ const rcptRes = await reader.readResponse();
185
+ assertCode(rcptRes, [250, 251], 'RCPT TO');
186
+ }, Promise.resolve());
187
+ };
188
+ const doData = async (socket, reader, message) => {
189
+ await writeLine(socket, 'DATA');
190
+ const dataRes = await reader.readResponse();
191
+ assertCode(dataRes, 354, 'DATA');
192
+ const raw = buildRfc2822Message(message);
193
+ const stuffed = dotStuff(raw);
194
+ await new Promise((resolve, reject) => {
195
+ socket.write(`${stuffed}\r\n.\r\n`, (err) => {
196
+ if (err)
197
+ reject(err);
198
+ else
199
+ resolve();
200
+ });
201
+ });
202
+ const queued = await reader.readResponse();
203
+ assertCode(queued, 250, 'message body');
204
+ };
205
+ const doQuit = async (socket, reader) => {
206
+ await writeLine(socket, 'QUIT');
207
+ const quit = await reader.readResponse();
208
+ assertCode(quit, [221, 250], 'QUIT');
209
+ };
210
+ const buildRfc2822Message = (msg) => {
211
+ const toList = normalizeRecipients(msg.to);
212
+ const fromNameRaw = msg.from.name;
213
+ const fromName = typeof fromNameRaw === 'string' ? fromNameRaw.trim() : '';
214
+ const fromHeader = fromName === '' ? msg.from.email : `${fromName} <${msg.from.email}>`;
215
+ const toHeader = toList.join(', ');
216
+ const subject = msg.subject;
217
+ const headers = [
218
+ `From: ${fromHeader}`,
219
+ `To: ${toHeader}`,
220
+ `Subject: ${subject}`,
221
+ 'MIME-Version: 1.0',
222
+ ];
223
+ const attachParts = (attachments, innerBody) => {
224
+ const mixedBoundary = `mixed_${generateUuid().replaceAll('-', '')}`;
225
+ const lines = [];
226
+ lines.push(`Content-Type: multipart/mixed; boundary="${mixedBoundary}"`, '', `--${mixedBoundary}`, innerBody);
227
+ // attachments
228
+ for (const a of attachments) {
229
+ const b64 = a.content.toString('base64');
230
+ lines.push(`--${mixedBoundary}`, `Content-Type: application/octet-stream; name="${a.filename}"`, 'Content-Transfer-Encoding: base64', `Content-Disposition: attachment; filename="${a.filename}"`, '');
231
+ // break base64 into 76 char lines per RFC
232
+ for (let i = 0; i < b64.length; i += 76) {
233
+ lines.push(b64.slice(i, i + 76));
234
+ }
235
+ }
236
+ lines.push(`--${mixedBoundary}--`, '');
237
+ return lines.join('\r\n');
238
+ };
239
+ if (typeof msg.html === 'string' && msg.html !== '') {
240
+ const boundary = `zintrust_${generateUuid().replaceAll('-', '')}`;
241
+ headers.push(`Content-Type: multipart/alternative; boundary="${boundary}"`);
242
+ const parts = [
243
+ `--${boundary}`,
244
+ 'Content-Type: text/plain; charset=utf-8',
245
+ 'Content-Transfer-Encoding: 7bit',
246
+ '',
247
+ msg.text,
248
+ `--${boundary}`,
249
+ 'Content-Type: text/html; charset=utf-8',
250
+ 'Content-Transfer-Encoding: 7bit',
251
+ '',
252
+ msg.html,
253
+ `--${boundary}--`,
254
+ '',
255
+ ];
256
+ const inner = `${parts.join('\r\n')}`;
257
+ if (msg.attachments && msg.attachments.length > 0) {
258
+ // wrap in multipart/mixed
259
+ const mixed = attachParts(msg.attachments, inner);
260
+ return `${headers.join('\r\n')}\r\n\r\n${mixed}`;
261
+ }
262
+ return `${headers.join('\r\n')}\r\n\r\n${inner}`;
263
+ }
264
+ // plain text
265
+ if (msg.attachments && msg.attachments.length > 0) {
266
+ const inner = ['Content-Type: text/plain; charset=utf-8', '', msg.text, ''].join('\r\n');
267
+ const mixed = attachParts(msg.attachments, inner);
268
+ return `${headers.join('\r\n')}\r\n\r\n${mixed}`;
269
+ }
270
+ headers.push('Content-Type: text/plain; charset=utf-8');
271
+ return `${headers.join('\r\n')}\r\n\r\n${msg.text}\r\n`;
272
+ };
273
+ const dotStuff = (data) => data
274
+ .replaceAll(/\r?\n/g, '\r\n')
275
+ .split('\r\n')
276
+ .map((line) => (line.startsWith('.') ? `.${line}` : line))
277
+ .join('\r\n');
278
+ export const SmtpDriver = Object.freeze({
279
+ /**
280
+ * NOTE: This is a minimal SMTP implementation intended for Node.js runtimes.
281
+ * - `secure=true` means TLS from the start (SMTPS).
282
+ * - `secure='starttls'` performs STARTTLS after EHLO.
283
+ */
284
+ async send(config, message) {
285
+ let mode = 'none';
286
+ if (config.secure === true)
287
+ mode = 'tls';
288
+ if (config.secure === 'starttls')
289
+ mode = 'starttls';
290
+ let socket = await createSocket(config, mode === 'tls');
291
+ let reader = createLineReader(socket);
292
+ try {
293
+ const greeting = await reader.readResponse();
294
+ assertCode(greeting, 220, 'greeting');
295
+ const ehlo = await doEhlo(socket, reader);
296
+ if (mode === 'starttls') {
297
+ const supportsStartTls = hasCapability(ehlo, 'STARTTLS');
298
+ if (!supportsStartTls) {
299
+ throw ErrorFactory.createConnectionError('SMTP server does not support STARTTLS');
300
+ }
301
+ await writeLine(socket, 'STARTTLS');
302
+ const startTls = await reader.readResponse();
303
+ assertCode(startTls, 220, 'STARTTLS');
304
+ // Swap reader/socket to the upgraded TLS stream
305
+ reader.close();
306
+ socket = await upgradeToStartTls(socket, config.host);
307
+ reader = createLineReader(socket);
308
+ // RFC: EHLO again after STARTTLS
309
+ await doEhlo(socket, reader);
310
+ }
311
+ await doAuthLoginIfNeeded(socket, reader, config);
312
+ await doMailFrom(socket, reader, message.from.email);
313
+ await doRcptToAll(socket, reader, normalizeRecipients(message.to));
314
+ await doData(socket, reader, message);
315
+ await doQuit(socket, reader);
316
+ return { ok: true, provider: 'smtp' };
317
+ }
318
+ catch (err) {
319
+ throw ErrorFactory.createConnectionError('SMTP send failed', { error: err });
320
+ }
321
+ finally {
322
+ reader.close();
323
+ socket.end();
324
+ }
325
+ },
326
+ });
327
+ export default SmtpDriver;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Mail Templates (Core)
3
+ *
4
+ * This folder contains reusable email templates used by core mail tooling.
5
+ * Templates may be organized into subfolders (e.g., `auth/`, `orders/`) with
6
+ * both rich HTML and plain-text variants.
7
+ */
8
+ export type MailTemplate = {
9
+ subject: string;
10
+ text: string;
11
+ html?: string;
12
+ };
13
+ export type MailTemplateRegistry = Record<string, unknown>;
14
+ export declare const MailTemplateRenderer: Readonly<{
15
+ renderString: (template: string, data: Record<string, unknown>) => string;
16
+ render(template: MailTemplate, data: Record<string, unknown>): MailTemplate;
17
+ }>;
18
+ export declare const MailTemplates: Readonly<{
19
+ auth: Readonly<{
20
+ welcome: Readonly<{
21
+ subject: string;
22
+ text: string;
23
+ html: string;
24
+ }>;
25
+ }>;
26
+ }>;
27
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/tools/mail/templates/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAW3D,eAAO,MAAM,oBAAoB;6BATD,MAAM,QAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,MAAM;qBAY3D,YAAY,QAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,YAAY;EAO3E,CAAC;AAEH,eAAO,MAAM,aAAa;;;;;;;;EASO,CAAC"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Mail Templates (Core)
3
+ *
4
+ * This folder contains reusable email templates used by core mail tooling.
5
+ * Templates may be organized into subfolders (e.g., `auth/`, `orders/`) with
6
+ * both rich HTML and plain-text variants.
7
+ */
8
+ const renderString = (template, data) => {
9
+ let out = template;
10
+ for (const [key, value] of Object.entries(data)) {
11
+ const replacement = value === null || value === undefined ? '' : String(value);
12
+ out = out.replaceAll(new RegExp(String.raw `{{\s*${key}\s*}}`, 'g'), replacement);
13
+ }
14
+ return out;
15
+ };
16
+ export const MailTemplateRenderer = Object.freeze({
17
+ renderString,
18
+ render(template, data) {
19
+ return {
20
+ subject: renderString(template.subject, data),
21
+ text: renderString(template.text, data),
22
+ html: typeof template.html === 'string' ? renderString(template.html, data) : undefined,
23
+ };
24
+ },
25
+ });
26
+ export const MailTemplates = Object.freeze({
27
+ auth: Object.freeze({
28
+ // Example template. Apps can add their own workflows under app/Toolkit/Mail.
29
+ welcome: Object.freeze({
30
+ subject: 'Welcome, {{name}}!',
31
+ text: 'Hi {{name}},\n\nWelcome to Zintrust.',
32
+ html: '<p>Hi {{name}},</p><p>Welcome to Zintrust.</p>',
33
+ }),
34
+ }),
35
+ });
@@ -0,0 +1,17 @@
1
+ export declare const loadTemplate: (name: string) => {
2
+ subject?: string;
3
+ preheader?: string;
4
+ variables?: string[];
5
+ content: string;
6
+ };
7
+ export { listTemplates, renderTemplate } from '../../templates/markdown/registry';
8
+ declare const _default: {
9
+ loadTemplate: (name: string) => {
10
+ subject?: string;
11
+ preheader?: string;
12
+ variables?: string[];
13
+ content: string;
14
+ };
15
+ };
16
+ export default _default;
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/tools/mail/templates/markdown/index.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,YAAY,GACvB,MAAM,MAAM,KACX;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAkD/E,CAAC;AAEF,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;;yBArD1E,MAAM,KACX;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;;AAsDlF,wBAAgC"}
@@ -0,0 +1,49 @@
1
+ import { readFileSync } from '../../../../node-singletons/fs';
2
+ import { join } from '../../../../node-singletons/path';
3
+ export const loadTemplate = (name) => {
4
+ // name e.g. 'auth/welcome'
5
+ const parts = name.split('/');
6
+ // Safe parser for top comment metadata <!-- Key: Value --> lines to avoid regex backtracking
7
+ const dir = join(process.cwd(), 'src', 'tools', 'mail', 'templates', 'markdown', ...parts.slice(0, -1));
8
+ const leaf = parts.at(-1) ?? '';
9
+ const filePath = join(dir, `${leaf}.md`);
10
+ const raw = readFileSync(filePath, 'utf-8');
11
+ const meta = {};
12
+ const parseMetaLine = (line) => {
13
+ // Must start with <!-- and end with --> exactly; trim the inner part and split at first colon
14
+ if (!line.startsWith('<!--') || !line.endsWith('-->'))
15
+ return null;
16
+ const inner = line.slice('<!--'.length, -'-->'.length).trim();
17
+ const idx = inner.indexOf(':');
18
+ if (idx === -1)
19
+ return null;
20
+ const key = inner.slice(0, idx).trim().toLowerCase();
21
+ const val = inner.slice(idx + 1).trim();
22
+ if (!key)
23
+ return null;
24
+ return [key, val];
25
+ };
26
+ // Parse top comment metadata <!-- Key: Value --> lines
27
+ const lines = raw.split(/\r?\n/);
28
+ let i = 0;
29
+ for (; i < lines.length; i++) {
30
+ const kv = parseMetaLine(lines[i]);
31
+ if (!kv)
32
+ break;
33
+ const [key, val] = kv;
34
+ if (key === 'subject')
35
+ meta.subject = val;
36
+ if (key === 'preheader')
37
+ meta.preheader = val;
38
+ if (key === 'variables') {
39
+ meta.variables = val
40
+ .split(',')
41
+ .map((s) => s.trim())
42
+ .filter(Boolean);
43
+ }
44
+ }
45
+ const content = lines.slice(i).join('\n').trim();
46
+ return { content, ...meta };
47
+ };
48
+ export { listTemplates, renderTemplate } from '../../templates/markdown/registry';
49
+ export default { loadTemplate };
@@ -0,0 +1,15 @@
1
+ import { loadTemplate } from '../../templates/markdown';
2
+ export declare const listTemplates: () => string[];
3
+ export declare const renderTemplate: (name: string, vars?: Record<string, unknown>) => {
4
+ html: string;
5
+ meta: ReturnType<typeof loadTemplate>;
6
+ };
7
+ declare const _default: {
8
+ listTemplates: () => string[];
9
+ renderTemplate: (name: string, vars?: Record<string, unknown>) => {
10
+ html: string;
11
+ meta: ReturnType<typeof loadTemplate>;
12
+ };
13
+ };
14
+ export default _default;
15
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../../../../src/tools/mail/templates/markdown/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AA2BxD,eAAO,MAAM,aAAa,QAAO,MAAM,EAEtC,CAAC;AAEF,eAAO,MAAM,cAAc,GACzB,MAAM,MAAM,EACZ,OAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,KACjC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAA;CAKvD,CAAC;;yBAZ+B,MAAM,EAAE;2BAKjC,MAAM,SACN,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5B;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAA;KAAE;;AAO1D,wBAAiD"}
@@ -0,0 +1,34 @@
1
+ import { loadTemplate } from '../../templates/markdown';
2
+ import { validateTemplateMeta } from '../../templates/markdown/validator';
3
+ import { readdirSync, statSync } from '../../../../node-singletons/fs';
4
+ import { join, relative } from '../../../../node-singletons/path';
5
+ import { MarkdownRenderer } from '../../../templates';
6
+ const BASE = join(process.cwd(), 'src', 'tools', 'mail', 'templates', 'markdown');
7
+ const walkDir = (dir, base = dir) => {
8
+ const entries = readdirSync(dir);
9
+ let files = [];
10
+ for (const e of entries) {
11
+ const p = join(dir, e);
12
+ const s = statSync(p);
13
+ if (s.isDirectory()) {
14
+ files = files.concat(walkDir(p, base));
15
+ continue;
16
+ }
17
+ if (e.endsWith('.md')) {
18
+ const rel = relative(base, p).replaceAll('\\', '/');
19
+ const withoutExt = rel.toLowerCase().endsWith('.md') ? rel.slice(0, -3) : rel;
20
+ files.push(withoutExt);
21
+ }
22
+ }
23
+ return files;
24
+ };
25
+ export const listTemplates = () => {
26
+ return walkDir(BASE);
27
+ };
28
+ export const renderTemplate = (name, vars = {}) => {
29
+ const tpl = loadTemplate(name);
30
+ validateTemplateMeta(name, tpl);
31
+ const html = MarkdownRenderer.render(tpl.content, vars);
32
+ return { html, meta: tpl };
33
+ };
34
+ export default { listTemplates, renderTemplate };
@@ -0,0 +1,16 @@
1
+ export declare const validateTemplateMeta: (name: string, tpl: {
2
+ subject?: string;
3
+ preheader?: string;
4
+ variables?: string[];
5
+ content: string;
6
+ }) => true;
7
+ declare const _default: {
8
+ validateTemplateMeta: (name: string, tpl: {
9
+ subject?: string;
10
+ preheader?: string;
11
+ variables?: string[];
12
+ content: string;
13
+ }) => true;
14
+ };
15
+ export default _default;
16
+ //# sourceMappingURL=validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../../../../../src/tools/mail/templates/markdown/validator.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,oBAAoB,GAC/B,MAAM,MAAM,EACZ,KAAK;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB,KACA,IA0BF,CAAC;;iCAjCM,MAAM,OACP;QACH,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;QACrB,OAAO,EAAE,MAAM,CAAC;KACjB,KACA,IAAI;;AA4BP,wBAAwC"}
@@ -0,0 +1,24 @@
1
+ import { ErrorFactory } from '../../../../exceptions/ZintrustError';
2
+ export const validateTemplateMeta = (name, tpl) => {
3
+ if (tpl.subject === null || tpl.subject === undefined || tpl.subject.trim() === '') {
4
+ throw ErrorFactory.createValidationError('Template missing subject', { name });
5
+ }
6
+ const placeholders = new Set();
7
+ const rx = /{{\s*([a-zA-Z0-9_.-]+)\s*}}/g;
8
+ let m;
9
+ while ((m = rx.exec(tpl.content)) !== null) {
10
+ placeholders.add(m[1]);
11
+ }
12
+ const metaVars = new Set((tpl.variables ?? []).map((s) => s.trim()).filter(Boolean));
13
+ const missingInContent = Array.from(metaVars).filter((v) => !placeholders.has(v));
14
+ const missingInMeta = Array.from(placeholders).filter((v) => !metaVars.has(v));
15
+ if (missingInContent.length > 0 || missingInMeta.length > 0) {
16
+ throw ErrorFactory.createValidationError('Template variables mismatch', {
17
+ name,
18
+ missingInContent,
19
+ missingInMeta,
20
+ });
21
+ }
22
+ return true;
23
+ };
24
+ export default { validateTemplateMeta };
@@ -0,0 +1,41 @@
1
+ type SentRecord = {
2
+ to: string[];
3
+ subject: string;
4
+ text: string;
5
+ html?: string;
6
+ from?: {
7
+ address?: string;
8
+ name?: string;
9
+ };
10
+ attachments?: Array<{
11
+ filename: string;
12
+ content: Buffer;
13
+ }>;
14
+ };
15
+ type FakeSendInput = {
16
+ to: string | string[];
17
+ subject: string;
18
+ text: string;
19
+ html?: string;
20
+ from?: {
21
+ address?: string;
22
+ name?: string;
23
+ };
24
+ attachments?: Array<{
25
+ filename: string;
26
+ content: Buffer;
27
+ }>;
28
+ };
29
+ export declare const MailFake: Readonly<{
30
+ _sent: Array<SentRecord>;
31
+ send(input: FakeSendInput): Promise<{
32
+ ok: boolean;
33
+ driver: string;
34
+ }>;
35
+ assertSent(predicate: (r: SentRecord) => boolean): void;
36
+ assertNotSent(predicate: (r: SentRecord) => boolean): void;
37
+ getSent(): SentRecord[];
38
+ reset(): void;
39
+ }>;
40
+ export default MailFake;
41
+ //# sourceMappingURL=testing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../../../../src/tools/mail/testing.ts"],"names":[],"mappings":"AAEA,KAAK,UAAU,GAAG;IAChB,EAAE,EAAE,MAAM,EAAE,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3C,WAAW,CAAC,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC5D,CAAC;AAEF,KAAK,aAAa,GAAG;IACnB,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;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3C,WAAW,CAAC,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC5D,CAAC;AAEF,eAAO,MAAM,QAAQ;WACN,KAAK,CAAC,UAAU,CAAC;gBAEZ,aAAa,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;0BAcpD,CAAC,CAAC,EAAE,UAAU,KAAK,OAAO;6BAMvB,CAAC,CAAC,EAAE,UAAU,KAAK,OAAO;;;EAanD,CAAC;AAEH,eAAe,QAAQ,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { ErrorFactory } from '../../exceptions/ZintrustError';
2
+ export const MailFake = Object.freeze({
3
+ _sent: [],
4
+ async send(input) {
5
+ const to = Array.isArray(input.to) ? input.to : [input.to];
6
+ this._sent.push({
7
+ to,
8
+ subject: input.subject,
9
+ text: input.text,
10
+ html: input.html,
11
+ from: input.from,
12
+ attachments: input.attachments,
13
+ });
14
+ await Promise.resolve();
15
+ return { ok: true, driver: 'disabled' };
16
+ },
17
+ assertSent(predicate) {
18
+ if (!this._sent.some(predicate)) {
19
+ throw ErrorFactory.createValidationError('Expected a sent mail matching predicate');
20
+ }
21
+ },
22
+ assertNotSent(predicate) {
23
+ if (this._sent.some(predicate)) {
24
+ throw ErrorFactory.createValidationError('Expected no sent mail matching predicate');
25
+ }
26
+ },
27
+ getSent() {
28
+ return this._sent.slice();
29
+ },
30
+ reset() {
31
+ this._sent.length = 0;
32
+ },
33
+ });
34
+ export default MailFake;
@@ -0,0 +1,11 @@
1
+ export interface INotificationDriver {
2
+ send(recipient: string, message: string, options?: Record<string, unknown>): Promise<unknown>;
3
+ }
4
+ export type NotificationPayload = {
5
+ recipient: string;
6
+ message: string;
7
+ options?: Record<string, unknown>;
8
+ };
9
+ declare const _default: INotificationDriver;
10
+ export default _default;
11
+ //# sourceMappingURL=Driver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Driver.d.ts","sourceRoot":"","sources":["../../../../src/tools/notification/Driver.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC/F;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC,CAAC;wBAE8B,mBAAmB;AAAnD,wBAAoD"}
@@ -0,0 +1 @@
1
+ export default {};