@zintrust/core 0.1.1 → 0.1.3

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 (487) hide show
  1. package/README.md +3 -3
  2. package/bin/zintrust.d.ts.map +1 -1
  3. package/bin/zintrust.js +18 -1
  4. package/package.json +15 -1
  5. package/src/boot/Application.d.ts.map +1 -1
  6. package/src/boot/Application.js +46 -3
  7. package/src/boot/Server.d.ts.map +1 -1
  8. package/src/boot/Server.js +3 -4
  9. package/src/boot/bootstrap.js +77 -6
  10. package/src/builder/BundleOptimizer.d.ts.map +1 -1
  11. package/src/builder/BundleOptimizer.js +6 -4
  12. package/src/cache/drivers/KVDriver.d.ts.map +1 -1
  13. package/src/cache/drivers/KVDriver.js +6 -6
  14. package/src/cache/drivers/RedisDriver.js +1 -1
  15. package/src/cli/BaseCommand.d.ts +2 -2
  16. package/src/cli/BaseCommand.d.ts.map +1 -1
  17. package/src/cli/BaseCommand.js +2 -1
  18. package/src/cli/CLI.d.ts.map +1 -1
  19. package/src/cli/CLI.js +11 -4
  20. package/src/cli/commands/AddCommand.js +1 -1
  21. package/src/cli/commands/ConfigCommand.d.ts.map +1 -1
  22. package/src/cli/commands/ConfigCommand.js +34 -4
  23. package/src/cli/commands/D1MigrateCommand.d.ts +4 -0
  24. package/src/cli/commands/D1MigrateCommand.d.ts.map +1 -1
  25. package/src/cli/commands/D1MigrateCommand.js +4 -3
  26. package/src/cli/commands/FixCommand.d.ts.map +1 -1
  27. package/src/cli/commands/FixCommand.js +3 -16
  28. package/src/cli/commands/LogsCleanupCommand.d.ts +6 -0
  29. package/src/cli/commands/LogsCleanupCommand.d.ts.map +1 -0
  30. package/src/cli/commands/LogsCleanupCommand.js +20 -0
  31. package/src/cli/commands/LogsCommand.d.ts.map +1 -1
  32. package/src/cli/commands/LogsCommand.js +1 -1
  33. package/src/cli/commands/MakeMailTemplateCommand.d.ts +10 -0
  34. package/src/cli/commands/MakeMailTemplateCommand.d.ts.map +1 -0
  35. package/src/cli/commands/MakeMailTemplateCommand.js +74 -0
  36. package/src/cli/commands/MakeNotificationTemplateCommand.d.ts +10 -0
  37. package/src/cli/commands/MakeNotificationTemplateCommand.d.ts.map +1 -0
  38. package/src/cli/commands/MakeNotificationTemplateCommand.js +113 -0
  39. package/src/cli/commands/NewCommand.d.ts +4 -0
  40. package/src/cli/commands/NewCommand.d.ts.map +1 -1
  41. package/src/cli/commands/NewCommand.js +33 -20
  42. package/src/cli/commands/PluginCommand.d.ts.map +1 -1
  43. package/src/cli/commands/PluginCommand.js +8 -4
  44. package/src/cli/commands/PrepareCommand.d.ts.map +1 -1
  45. package/src/cli/commands/PrepareCommand.js +1 -1
  46. package/src/cli/commands/QACommand.d.ts.map +1 -1
  47. package/src/cli/commands/QACommand.js +11 -20
  48. package/src/cli/commands/SecretsCommand.d.ts +16 -0
  49. package/src/cli/commands/SecretsCommand.d.ts.map +1 -0
  50. package/src/cli/commands/SecretsCommand.js +91 -0
  51. package/src/cli/commands/StartCommand.d.ts.map +1 -1
  52. package/src/cli/commands/StartCommand.js +2 -2
  53. package/src/cli/commands/TemplatesCommand.d.ts +3 -0
  54. package/src/cli/commands/TemplatesCommand.d.ts.map +1 -0
  55. package/src/cli/commands/TemplatesCommand.js +65 -0
  56. package/src/cli/commands/index.d.ts +5 -0
  57. package/src/cli/commands/index.d.ts.map +1 -1
  58. package/src/cli/commands/index.js +5 -0
  59. package/src/cli/config/ConfigManager.js +1 -1
  60. package/src/cli/index.d.ts +2 -1
  61. package/src/cli/index.d.ts.map +1 -1
  62. package/src/cli/index.js +2 -1
  63. package/src/cli/scaffolding/ControllerGenerator.js +1 -1
  64. package/src/cli/scaffolding/FeatureScaffolder.js +4 -4
  65. package/src/cli/scaffolding/FileGenerator.js +1 -1
  66. package/src/cli/scaffolding/ModelGenerator.js +1 -1
  67. package/src/cli/scaffolding/ProjectScaffolder.d.ts.map +1 -1
  68. package/src/cli/scaffolding/ProjectScaffolder.js +61 -11
  69. package/src/cli/scaffolding/ResponseFactoryGenerator.d.ts.map +1 -1
  70. package/src/cli/scaffolding/ResponseFactoryGenerator.js +3 -2
  71. package/src/cli/scaffolding/RouteGenerator.js +1 -1
  72. package/src/cli/scaffolding/ServiceIntegrationTestGenerator.js +1 -1
  73. package/src/cli/scaffolding/ServiceScaffolder.js +2 -2
  74. package/src/cli/scaffolding/TemplateGenerator.d.ts +40 -0
  75. package/src/cli/scaffolding/TemplateGenerator.d.ts.map +1 -0
  76. package/src/cli/scaffolding/TemplateGenerator.js +172 -0
  77. package/src/cli/scaffolding/index.d.ts +1 -0
  78. package/src/cli/scaffolding/index.d.ts.map +1 -1
  79. package/src/cli/scaffolding/index.js +1 -0
  80. package/src/cli/utils/spawn.js +1 -1
  81. package/src/common/AwsSigV4.d.ts +41 -0
  82. package/src/common/AwsSigV4.d.ts.map +1 -0
  83. package/src/common/AwsSigV4.js +69 -0
  84. package/src/common/index.d.ts +39 -0
  85. package/src/common/index.d.ts.map +1 -1
  86. package/src/common/index.js +101 -8
  87. package/src/common/uuid.d.ts +3 -0
  88. package/src/common/uuid.d.ts.map +1 -0
  89. package/src/common/uuid.js +30 -0
  90. package/src/config/FileLogWriter.d.ts +22 -0
  91. package/src/config/FileLogWriter.d.ts.map +1 -0
  92. package/src/config/FileLogWriter.js +192 -0
  93. package/src/config/SecretsManager.d.ts.map +1 -1
  94. package/src/config/SecretsManager.js +37 -11
  95. package/src/config/StartupConfigValidator.d.ts +15 -0
  96. package/src/config/StartupConfigValidator.d.ts.map +1 -0
  97. package/src/config/StartupConfigValidator.js +86 -0
  98. package/src/config/app.d.ts +2 -1
  99. package/src/config/app.d.ts.map +1 -1
  100. package/src/config/app.js +65 -15
  101. package/src/config/broadcast.d.ts +47 -0
  102. package/src/config/broadcast.d.ts.map +1 -0
  103. package/src/config/broadcast.js +54 -0
  104. package/src/config/cache.d.ts +13 -17
  105. package/src/config/cache.d.ts.map +1 -1
  106. package/src/config/cache.js +9 -11
  107. package/src/config/cloudflare.d.ts +26 -0
  108. package/src/config/cloudflare.d.ts.map +1 -0
  109. package/src/config/cloudflare.js +38 -0
  110. package/src/config/env.d.ts +6 -0
  111. package/src/config/env.d.ts.map +1 -1
  112. package/src/config/env.js +6 -0
  113. package/src/config/index.d.ts +52 -28
  114. package/src/config/index.d.ts.map +1 -1
  115. package/src/config/index.js +3 -0
  116. package/src/config/logger.d.ts +2 -0
  117. package/src/config/logger.d.ts.map +1 -1
  118. package/src/config/logger.js +270 -11
  119. package/src/config/logging/HttpLogger.d.ts +23 -0
  120. package/src/config/logging/HttpLogger.d.ts.map +1 -0
  121. package/src/config/logging/HttpLogger.js +93 -0
  122. package/src/config/logging/KvLogger.d.ts +22 -0
  123. package/src/config/logging/KvLogger.d.ts.map +1 -0
  124. package/src/config/logging/KvLogger.js +143 -0
  125. package/src/config/logging/SlackLogger.d.ts +23 -0
  126. package/src/config/logging/SlackLogger.d.ts.map +1 -0
  127. package/src/config/logging/SlackLogger.js +119 -0
  128. package/src/config/mail.d.ts +81 -0
  129. package/src/config/mail.d.ts.map +1 -0
  130. package/src/config/mail.js +73 -0
  131. package/src/config/middleware.d.ts +8 -0
  132. package/src/config/middleware.d.ts.map +1 -0
  133. package/src/config/middleware.js +18 -0
  134. package/src/config/notification.d.ts +62 -0
  135. package/src/config/notification.d.ts.map +1 -0
  136. package/src/config/notification.js +43 -0
  137. package/src/config/security.d.ts.map +1 -1
  138. package/src/config/security.js +2 -2
  139. package/src/config/startup.d.ts +23 -0
  140. package/src/config/startup.d.ts.map +1 -0
  141. package/src/config/startup.js +15 -0
  142. package/src/config/storage.d.ts +21 -35
  143. package/src/config/storage.d.ts.map +1 -1
  144. package/src/config/storage.js +57 -37
  145. package/src/database/migrations/index.d.ts +1 -1
  146. package/src/database/migrations/index.d.ts.map +1 -1
  147. package/src/database/migrations/index.js +2 -1
  148. package/src/features/Queue.js +1 -25
  149. package/src/health/RuntimeHealthProbes.d.ts +13 -0
  150. package/src/health/RuntimeHealthProbes.d.ts.map +1 -0
  151. package/src/health/RuntimeHealthProbes.js +62 -0
  152. package/src/health/StartupHealthChecks.d.ts +26 -0
  153. package/src/health/StartupHealthChecks.d.ts.map +1 -0
  154. package/src/health/StartupHealthChecks.js +124 -0
  155. package/src/http/ErrorResponse.d.ts +28 -0
  156. package/src/http/ErrorResponse.d.ts.map +1 -0
  157. package/src/http/ErrorResponse.js +42 -0
  158. package/src/http/Kernel.d.ts +5 -0
  159. package/src/http/Kernel.d.ts.map +1 -1
  160. package/src/http/Kernel.js +96 -30
  161. package/src/http/RequestContext.d.ts +20 -0
  162. package/src/http/RequestContext.d.ts.map +1 -0
  163. package/src/http/RequestContext.js +77 -0
  164. package/src/index.d.ts +9 -1
  165. package/src/index.d.ts.map +1 -1
  166. package/src/index.js +8 -2
  167. package/src/microservices/MicroserviceManager.d.ts.map +1 -1
  168. package/src/microservices/MicroserviceManager.js +9 -6
  169. package/src/microservices/PostgresAdapter.d.ts.map +1 -1
  170. package/src/microservices/PostgresAdapter.js +3 -1
  171. package/src/microservices/ServiceBundler.d.ts.map +1 -1
  172. package/src/microservices/ServiceBundler.js +6 -4
  173. package/src/microservices/ServiceHealthMonitor.js +2 -2
  174. package/src/middleware/CsrfMiddleware.d.ts.map +1 -1
  175. package/src/middleware/CsrfMiddleware.js +2 -19
  176. package/src/middleware/ErrorHandlerMiddleware.d.ts +6 -0
  177. package/src/middleware/ErrorHandlerMiddleware.d.ts.map +1 -0
  178. package/src/middleware/ErrorHandlerMiddleware.js +33 -0
  179. package/src/middleware/LoggingMiddleware.d.ts +9 -0
  180. package/src/middleware/LoggingMiddleware.d.ts.map +1 -0
  181. package/src/middleware/LoggingMiddleware.js +36 -0
  182. package/src/middleware/index.d.ts +2 -0
  183. package/src/middleware/index.d.ts.map +1 -1
  184. package/src/middleware/index.js +2 -0
  185. package/src/node-singletons/async_hooks.d.ts +9 -0
  186. package/src/node-singletons/async_hooks.d.ts.map +1 -0
  187. package/src/node-singletons/async_hooks.js +8 -0
  188. package/src/node-singletons/fs.d.ts +2 -2
  189. package/src/node-singletons/fs.d.ts.map +1 -1
  190. package/src/node-singletons/fs.js +2 -2
  191. package/src/node-singletons/http.d.ts +1 -1
  192. package/src/node-singletons/http.d.ts.map +1 -1
  193. package/src/node-singletons/http.js +1 -1
  194. package/src/node-singletons/index.d.ts +4 -0
  195. package/src/node-singletons/index.d.ts.map +1 -1
  196. package/src/node-singletons/index.js +4 -0
  197. package/src/node-singletons/net.d.ts +9 -0
  198. package/src/node-singletons/net.d.ts.map +1 -0
  199. package/src/node-singletons/net.js +8 -0
  200. package/src/node-singletons/os.d.ts +3 -3
  201. package/src/node-singletons/os.d.ts.map +1 -1
  202. package/src/node-singletons/os.js +3 -4
  203. package/src/node-singletons/path.d.ts +3 -1
  204. package/src/node-singletons/path.d.ts.map +1 -1
  205. package/src/node-singletons/path.js +3 -1
  206. package/src/node-singletons/perf-hooks.d.ts +3 -1
  207. package/src/node-singletons/perf-hooks.d.ts.map +1 -1
  208. package/src/node-singletons/perf-hooks.js +3 -1
  209. package/src/node-singletons/process.d.ts +23 -0
  210. package/src/node-singletons/process.d.ts.map +1 -0
  211. package/src/node-singletons/process.js +8 -0
  212. package/src/node-singletons/readline.d.ts +3 -3
  213. package/src/node-singletons/readline.d.ts.map +1 -1
  214. package/src/node-singletons/readline.js +3 -4
  215. package/src/node-singletons/tls.d.ts +9 -0
  216. package/src/node-singletons/tls.d.ts.map +1 -0
  217. package/src/node-singletons/tls.js +8 -0
  218. package/src/node-singletons/url.d.ts +3 -1
  219. package/src/node-singletons/url.d.ts.map +1 -1
  220. package/src/node-singletons/url.js +3 -1
  221. package/src/orm/ConnectionManager.d.ts +6 -1
  222. package/src/orm/ConnectionManager.d.ts.map +1 -1
  223. package/src/orm/ConnectionManager.js +14 -0
  224. package/src/orm/DatabaseAdapter.d.ts +6 -0
  225. package/src/orm/DatabaseAdapter.d.ts.map +1 -1
  226. package/src/orm/QueryBuilder.d.ts +8 -1
  227. package/src/orm/QueryBuilder.d.ts.map +1 -1
  228. package/src/orm/QueryBuilder.js +188 -28
  229. package/src/orm/adapters/D1Adapter.d.ts.map +1 -1
  230. package/src/orm/adapters/D1Adapter.js +18 -12
  231. package/src/orm/adapters/MySQLAdapter.d.ts.map +1 -1
  232. package/src/orm/adapters/MySQLAdapter.js +4 -0
  233. package/src/orm/adapters/PostgreSQLAdapter.d.ts.map +1 -1
  234. package/src/orm/adapters/PostgreSQLAdapter.js +4 -0
  235. package/src/orm/adapters/SQLServerAdapter.d.ts.map +1 -1
  236. package/src/orm/adapters/SQLServerAdapter.js +4 -0
  237. package/src/orm/adapters/SQLiteAdapter.d.ts.map +1 -1
  238. package/src/orm/adapters/SQLiteAdapter.js +4 -0
  239. package/src/performance/CodeGenerationBenchmark.js +3 -3
  240. package/src/performance/Optimizer.d.ts +1 -1
  241. package/src/performance/Optimizer.d.ts.map +1 -1
  242. package/src/performance/Optimizer.js +150 -75
  243. package/src/performance/establish-baseline.js +3 -3
  244. package/src/runtime/PluginManager.d.ts +3 -1
  245. package/src/runtime/PluginManager.d.ts.map +1 -1
  246. package/src/runtime/PluginManager.js +124 -28
  247. package/src/runtime/RuntimeDetector.d.ts.map +1 -1
  248. package/src/runtime/RuntimeDetector.js +47 -6
  249. package/src/runtime/adapters/CloudflareAdapter.js +2 -2
  250. package/src/runtime/adapters/FargateAdapter.d.ts.map +1 -1
  251. package/src/runtime/adapters/FargateAdapter.js +2 -1
  252. package/src/runtime/adapters/LambdaAdapter.d.ts.map +1 -1
  253. package/src/runtime/adapters/LambdaAdapter.js +4 -2
  254. package/src/runtime/adapters/NodeServerAdapter.d.ts.map +1 -1
  255. package/src/runtime/adapters/NodeServerAdapter.js +2 -1
  256. package/src/scheduler/ScheduleRunner.d.ts +18 -0
  257. package/src/scheduler/ScheduleRunner.d.ts.map +1 -0
  258. package/src/scheduler/ScheduleRunner.js +155 -0
  259. package/src/scheduler/index.d.ts +3 -0
  260. package/src/scheduler/index.d.ts.map +1 -0
  261. package/src/scheduler/index.js +1 -0
  262. package/src/scheduler/types.d.ts +16 -0
  263. package/src/scheduler/types.d.ts.map +1 -0
  264. package/src/scheduler/types.js +4 -0
  265. package/src/schedules/index.d.ts +2 -0
  266. package/src/schedules/index.d.ts.map +1 -0
  267. package/src/schedules/index.js +1 -0
  268. package/src/schedules/log-cleanup.d.ts +4 -0
  269. package/src/schedules/log-cleanup.d.ts.map +1 -0
  270. package/src/schedules/log-cleanup.js +18 -0
  271. package/src/scripts/GenerateEnvArtifacts.d.ts +13 -0
  272. package/src/scripts/GenerateEnvArtifacts.d.ts.map +1 -0
  273. package/src/scripts/GenerateEnvArtifacts.js +171 -0
  274. package/src/scripts/TemplateSync.js +109 -70
  275. package/src/security/CsrfTokenManager.js +1 -1
  276. package/src/security/Encryptor.js +1 -1
  277. package/src/security/Hash.d.ts +14 -0
  278. package/src/security/Hash.d.ts.map +1 -0
  279. package/src/security/Hash.js +81 -0
  280. package/src/security/StartupSecretValidation.d.ts +20 -0
  281. package/src/security/StartupSecretValidation.d.ts.map +1 -0
  282. package/src/security/StartupSecretValidation.js +61 -0
  283. package/src/security/UrlValidator.d.ts +0 -1
  284. package/src/security/UrlValidator.d.ts.map +1 -1
  285. package/src/security/UrlValidator.js +1 -2
  286. package/src/security/Xss.d.ts +14 -0
  287. package/src/security/Xss.d.ts.map +1 -0
  288. package/src/security/Xss.js +57 -0
  289. package/src/security/XssProtection.d.ts.map +1 -1
  290. package/src/security/XssProtection.js +155 -17
  291. package/src/templates/adapters/MySQLAdapter.ts.tpl +5 -0
  292. package/src/templates/adapters/PostgreSQLAdapter.ts.tpl +5 -0
  293. package/src/templates/adapters/SQLServerAdapter.ts.tpl +5 -0
  294. package/src/templates/adapters/SQLiteAdapter.ts.tpl +5 -0
  295. package/src/templates/features/Queue.ts.tpl +1 -29
  296. package/src/templates/project/basic/.env.example.tpl +48 -0
  297. package/src/templates/project/basic/.env.tpl +89 -94
  298. package/src/templates/project/basic/app/Toolkit/Broadcast/sendBroadcast.ts.tpl +7 -0
  299. package/src/templates/project/basic/app/Toolkit/Mail/sendWelcomeEmail.ts.tpl +30 -0
  300. package/src/templates/project/basic/app/Toolkit/Notification/sendSlackNotification.ts.tpl +10 -0
  301. package/src/templates/project/basic/app/Toolkit/Notification/sendSms.ts.tpl +13 -0
  302. package/src/templates/project/basic/config/FileLogWriter.ts.tpl +240 -0
  303. package/src/templates/project/basic/config/SecretsManager.ts.tpl +44 -21
  304. package/src/templates/project/basic/config/StartupConfigValidator.ts.tpl +151 -0
  305. package/src/templates/project/basic/config/app.ts.tpl +84 -15
  306. package/src/templates/project/basic/config/broadcast.ts.tpl +97 -0
  307. package/src/templates/project/basic/config/cache.ts.tpl +19 -23
  308. package/src/templates/project/basic/config/cloudflare.ts.tpl +57 -0
  309. package/src/templates/project/basic/config/env.ts.tpl +7 -1
  310. package/src/templates/project/basic/config/index.ts.tpl +3 -0
  311. package/src/templates/project/basic/config/logger.ts.tpl +301 -11
  312. package/src/templates/project/basic/config/logging/HttpLogger.ts.tpl +121 -0
  313. package/src/templates/project/basic/config/logging/KvLogger.ts.tpl +181 -0
  314. package/src/templates/project/basic/config/logging/SlackLogger.ts.tpl +156 -0
  315. package/src/templates/project/basic/config/mail.ts.tpl +141 -0
  316. package/src/templates/project/basic/config/middleware.ts.tpl +27 -0
  317. package/src/templates/project/basic/config/notification.ts.tpl +86 -0
  318. package/src/templates/project/basic/config/security.ts.tpl +4 -5
  319. package/src/templates/project/basic/config/startup.ts.tpl +27 -0
  320. package/src/templates/project/basic/config/storage.ts.tpl +77 -42
  321. package/src/templates/project/basic/database/migrations/index.ts.tpl +1 -1
  322. package/src/templates/project/basic/package.json.tpl +1 -1
  323. package/src/templates/project/basic/routes/api.ts.tpl +11 -37
  324. package/src/templates/project/basic/routes/broadcast.ts.tpl +32 -0
  325. package/src/templates/project/basic/routes/health.ts.tpl +134 -0
  326. package/src/templates/project/basic/routes/storage.ts.tpl +42 -0
  327. package/src/templates/project/basic/src/index.ts.tpl +38 -11
  328. package/src/templates/project/basic/template.json +3 -0
  329. package/src/toolkit/Secrets/EnvFile.d.ts +15 -0
  330. package/src/toolkit/Secrets/EnvFile.d.ts.map +1 -0
  331. package/src/toolkit/Secrets/EnvFile.js +63 -0
  332. package/src/toolkit/Secrets/Manifest.d.ts +24 -0
  333. package/src/toolkit/Secrets/Manifest.d.ts.map +1 -0
  334. package/src/toolkit/Secrets/Manifest.js +71 -0
  335. package/src/toolkit/Secrets/index.d.ts +42 -0
  336. package/src/toolkit/Secrets/index.d.ts.map +1 -0
  337. package/src/toolkit/Secrets/index.js +119 -0
  338. package/src/toolkit/Secrets/providers/AwsSecretsManager.d.ts +14 -0
  339. package/src/toolkit/Secrets/providers/AwsSecretsManager.d.ts.map +1 -0
  340. package/src/toolkit/Secrets/providers/AwsSecretsManager.js +131 -0
  341. package/src/toolkit/Secrets/providers/CloudflareKv.d.ts +9 -0
  342. package/src/toolkit/Secrets/providers/CloudflareKv.d.ts.map +1 -0
  343. package/src/toolkit/Secrets/providers/CloudflareKv.js +73 -0
  344. package/src/tools/broadcast/Broadcast.d.ts +7 -0
  345. package/src/tools/broadcast/Broadcast.d.ts.map +1 -0
  346. package/src/tools/broadcast/Broadcast.js +37 -0
  347. package/src/tools/broadcast/drivers/BaseDriver.d.ts +5 -0
  348. package/src/tools/broadcast/drivers/BaseDriver.d.ts.map +1 -0
  349. package/src/tools/broadcast/drivers/BaseDriver.js +8 -0
  350. package/src/tools/broadcast/drivers/InMemory.d.ts +18 -0
  351. package/src/tools/broadcast/drivers/InMemory.d.ts.map +1 -0
  352. package/src/tools/broadcast/drivers/InMemory.js +16 -0
  353. package/src/tools/broadcast/drivers/Pusher.d.ts +8 -0
  354. package/src/tools/broadcast/drivers/Pusher.d.ts.map +1 -0
  355. package/src/tools/broadcast/drivers/Pusher.js +75 -0
  356. package/src/tools/broadcast/drivers/Redis.d.ts +19 -0
  357. package/src/tools/broadcast/drivers/Redis.d.ts.map +1 -0
  358. package/src/tools/broadcast/drivers/Redis.js +73 -0
  359. package/src/tools/broadcast/drivers/RedisHttps.d.ts +14 -0
  360. package/src/tools/broadcast/drivers/RedisHttps.d.ts.map +1 -0
  361. package/src/tools/broadcast/drivers/RedisHttps.js +50 -0
  362. package/src/tools/broadcast/index.d.ts +7 -0
  363. package/src/tools/broadcast/index.d.ts.map +1 -0
  364. package/src/tools/broadcast/index.js +6 -0
  365. package/src/tools/http/Http.d.ts +49 -0
  366. package/src/tools/http/Http.d.ts.map +1 -0
  367. package/src/tools/http/Http.js +169 -0
  368. package/src/tools/http/HttpResponse.d.ts +32 -0
  369. package/src/tools/http/HttpResponse.d.ts.map +1 -0
  370. package/src/tools/http/HttpResponse.js +80 -0
  371. package/src/tools/http/index.d.ts +15 -0
  372. package/src/tools/http/index.d.ts.map +1 -0
  373. package/src/tools/http/index.js +9 -0
  374. package/src/tools/mail/Mail.d.ts +22 -0
  375. package/src/tools/mail/Mail.d.ts.map +1 -0
  376. package/src/tools/mail/Mail.js +105 -0
  377. package/src/tools/mail/attachments.d.ts +23 -0
  378. package/src/tools/mail/attachments.d.ts.map +1 -0
  379. package/src/tools/mail/attachments.js +26 -0
  380. package/src/tools/mail/drivers/BaseDriver.d.ts +5 -0
  381. package/src/tools/mail/drivers/BaseDriver.d.ts.map +1 -0
  382. package/src/tools/mail/drivers/BaseDriver.js +8 -0
  383. package/src/tools/mail/drivers/Mailgun.d.ts +31 -0
  384. package/src/tools/mail/drivers/Mailgun.d.ts.map +1 -0
  385. package/src/tools/mail/drivers/Mailgun.js +81 -0
  386. package/src/tools/mail/drivers/SendGrid.d.ts +29 -0
  387. package/src/tools/mail/drivers/SendGrid.d.ts.map +1 -0
  388. package/src/tools/mail/drivers/SendGrid.js +57 -0
  389. package/src/tools/mail/drivers/Ses.d.ts +24 -0
  390. package/src/tools/mail/drivers/Ses.d.ts.map +1 -0
  391. package/src/tools/mail/drivers/Ses.js +116 -0
  392. package/src/tools/mail/drivers/Smtp.d.ts +38 -0
  393. package/src/tools/mail/drivers/Smtp.d.ts.map +1 -0
  394. package/src/tools/mail/drivers/Smtp.js +327 -0
  395. package/src/tools/mail/templates/index.d.ts +27 -0
  396. package/src/tools/mail/templates/index.d.ts.map +1 -0
  397. package/src/tools/mail/templates/index.js +35 -0
  398. package/src/tools/mail/templates/markdown/index.d.ts +17 -0
  399. package/src/tools/mail/templates/markdown/index.d.ts.map +1 -0
  400. package/src/tools/mail/templates/markdown/index.js +49 -0
  401. package/src/tools/mail/templates/markdown/registry.d.ts +15 -0
  402. package/src/tools/mail/templates/markdown/registry.d.ts.map +1 -0
  403. package/src/tools/mail/templates/markdown/registry.js +34 -0
  404. package/src/tools/mail/templates/markdown/validator.d.ts +16 -0
  405. package/src/tools/mail/templates/markdown/validator.d.ts.map +1 -0
  406. package/src/tools/mail/templates/markdown/validator.js +24 -0
  407. package/src/tools/mail/testing.d.ts +41 -0
  408. package/src/tools/mail/testing.d.ts.map +1 -0
  409. package/src/tools/mail/testing.js +34 -0
  410. package/src/tools/notification/Driver.d.ts +11 -0
  411. package/src/tools/notification/Driver.d.ts.map +1 -0
  412. package/src/tools/notification/Driver.js +1 -0
  413. package/src/tools/notification/Notification.d.ts +11 -0
  414. package/src/tools/notification/Notification.d.ts.map +1 -0
  415. package/src/tools/notification/Notification.js +11 -0
  416. package/src/tools/notification/Registry.d.ts +10 -0
  417. package/src/tools/notification/Registry.d.ts.map +1 -0
  418. package/src/tools/notification/Registry.js +22 -0
  419. package/src/tools/notification/Service.d.ts +6 -0
  420. package/src/tools/notification/Service.d.ts.map +1 -0
  421. package/src/tools/notification/Service.js +18 -0
  422. package/src/tools/notification/config.d.ts +5 -0
  423. package/src/tools/notification/config.d.ts.map +1 -0
  424. package/src/tools/notification/config.js +5 -0
  425. package/src/tools/notification/drivers/BaseDriver.d.ts +5 -0
  426. package/src/tools/notification/drivers/BaseDriver.d.ts.map +1 -0
  427. package/src/tools/notification/drivers/BaseDriver.js +8 -0
  428. package/src/tools/notification/drivers/Console.d.ts +7 -0
  429. package/src/tools/notification/drivers/Console.d.ts.map +1 -0
  430. package/src/tools/notification/drivers/Console.js +13 -0
  431. package/src/tools/notification/drivers/Slack.d.ts +16 -0
  432. package/src/tools/notification/drivers/Slack.d.ts.map +1 -0
  433. package/src/tools/notification/drivers/Slack.js +24 -0
  434. package/src/tools/notification/drivers/Termii.d.ts +10 -0
  435. package/src/tools/notification/drivers/Termii.d.ts.map +1 -0
  436. package/src/tools/notification/drivers/Termii.js +47 -0
  437. package/src/tools/notification/drivers/Twilio.d.ts +21 -0
  438. package/src/tools/notification/drivers/Twilio.d.ts.map +1 -0
  439. package/src/tools/notification/drivers/Twilio.js +48 -0
  440. package/src/tools/notification/templates/markdown/index.d.ts +15 -0
  441. package/src/tools/notification/templates/markdown/index.d.ts.map +1 -0
  442. package/src/tools/notification/templates/markdown/index.js +38 -0
  443. package/src/tools/notification/templates/markdown/registry.d.ts +15 -0
  444. package/src/tools/notification/templates/markdown/registry.d.ts.map +1 -0
  445. package/src/tools/notification/templates/markdown/registry.js +36 -0
  446. package/src/tools/notification/testing.d.ts +19 -0
  447. package/src/tools/notification/testing.d.ts.map +1 -0
  448. package/src/tools/notification/testing.js +35 -0
  449. package/src/tools/notification/testingHelpers.d.ts +12 -0
  450. package/src/tools/notification/testingHelpers.d.ts.map +1 -0
  451. package/src/tools/notification/testingHelpers.js +32 -0
  452. package/src/tools/queue/Queue.d.ts +23 -0
  453. package/src/tools/queue/Queue.d.ts.map +1 -0
  454. package/src/tools/queue/Queue.js +38 -0
  455. package/src/tools/queue/drivers/InMemory.d.ts +10 -0
  456. package/src/tools/queue/drivers/InMemory.d.ts.map +1 -0
  457. package/src/tools/queue/drivers/InMemory.js +55 -0
  458. package/src/tools/queue/drivers/Redis.d.ts +10 -0
  459. package/src/tools/queue/drivers/Redis.d.ts.map +1 -0
  460. package/src/tools/queue/drivers/Redis.js +91 -0
  461. package/src/tools/storage/LocalSignedUrl.d.ts +12 -0
  462. package/src/tools/storage/LocalSignedUrl.d.ts.map +1 -0
  463. package/src/tools/storage/LocalSignedUrl.js +108 -0
  464. package/src/tools/storage/drivers/Gcs.d.ts +20 -0
  465. package/src/tools/storage/drivers/Gcs.d.ts.map +1 -0
  466. package/src/tools/storage/drivers/Gcs.js +152 -0
  467. package/src/tools/storage/drivers/Local.d.ts +18 -0
  468. package/src/tools/storage/drivers/Local.d.ts.map +1 -0
  469. package/src/tools/storage/drivers/Local.js +89 -0
  470. package/src/tools/storage/drivers/R2.d.ts +20 -0
  471. package/src/tools/storage/drivers/R2.d.ts.map +1 -0
  472. package/src/tools/storage/drivers/R2.js +73 -0
  473. package/src/tools/storage/drivers/S3.d.ts +26 -0
  474. package/src/tools/storage/drivers/S3.d.ts.map +1 -0
  475. package/src/tools/storage/drivers/S3.js +258 -0
  476. package/src/tools/storage/index.d.ts +24 -0
  477. package/src/tools/storage/index.d.ts.map +1 -0
  478. package/src/tools/storage/index.js +111 -0
  479. package/src/tools/storage/testing.d.ts +23 -0
  480. package/src/tools/storage/testing.d.ts.map +1 -0
  481. package/src/tools/storage/testing.js +52 -0
  482. package/src/tools/templates/MarkdownRenderer.d.ts +14 -0
  483. package/src/tools/templates/MarkdownRenderer.d.ts.map +1 -0
  484. package/src/tools/templates/MarkdownRenderer.js +300 -0
  485. package/src/tools/templates/index.d.ts +5 -0
  486. package/src/tools/templates/index.d.ts.map +1 -0
  487. package/src/tools/templates/index.js +4 -0
@@ -3,9 +3,124 @@
3
3
  * Sealed namespace pattern - all exports through Logger namespace
4
4
  * Replaces console.* calls throughout the codebase
5
5
  */
6
+ import { appConfig } from './app';
6
7
  import { Env } from './env';
7
- const isDevelopment = Env.NODE_ENV === 'development' || Env.NODE_ENV === undefined;
8
- const isProduction = Env.NODE_ENV === 'production';
8
+ const isDevelopment = () => appConfig.isDevelopment();
9
+ const isProduction = () => appConfig.isProduction();
10
+ const getLogFormat = () => Env.get('LOG_FORMAT', 'text');
11
+ const isJsonFormat = (value) => value === 'json';
12
+ const SENSITIVE_FIELDS = new Set([
13
+ 'password',
14
+ 'token',
15
+ 'authorization',
16
+ 'secret',
17
+ 'apikey',
18
+ 'api_key',
19
+ 'jwt',
20
+ 'bearer',
21
+ ]);
22
+ const redactSensitiveData = (data) => {
23
+ const seen = new WeakSet();
24
+ const walk = (value) => {
25
+ if (Array.isArray(value)) {
26
+ if (seen.has(value))
27
+ return '[Circular]';
28
+ seen.add(value);
29
+ return value.map((v) => walk(v));
30
+ }
31
+ if (typeof value === 'object' && value !== null) {
32
+ const asObj = value;
33
+ if (seen.has(asObj))
34
+ return '[Circular]';
35
+ seen.add(asObj);
36
+ const out = {};
37
+ for (const [key, inner] of Object.entries(asObj)) {
38
+ if (SENSITIVE_FIELDS.has(key.toLowerCase())) {
39
+ out[key] = '[REDACTED]';
40
+ }
41
+ else {
42
+ out[key] = walk(inner);
43
+ }
44
+ }
45
+ return out;
46
+ }
47
+ return value;
48
+ };
49
+ return walk(data);
50
+ };
51
+ const safeStringify = (obj, indent = false) => {
52
+ const seen = new WeakSet();
53
+ return JSON.stringify(obj, (_key, value) => {
54
+ if (typeof value === 'object' && value !== null) {
55
+ const asObj = value;
56
+ if (seen.has(asObj))
57
+ return '[Circular]';
58
+ seen.add(asObj);
59
+ }
60
+ return value;
61
+ }, indent ? 2 : 0);
62
+ };
63
+ let fileWriterPromise;
64
+ let fileWriter;
65
+ const getFileWriter = () => {
66
+ if (fileWriter !== undefined)
67
+ return;
68
+ if (fileWriterPromise !== undefined)
69
+ return;
70
+ fileWriterPromise = import('./FileLogWriter')
71
+ .then((mod) => {
72
+ fileWriter = mod.FileLogWriter;
73
+ return mod;
74
+ })
75
+ .catch(() => {
76
+ fileWriterPromise = undefined;
77
+ return { FileLogWriter: { write: (_line) => undefined } };
78
+ });
79
+ };
80
+ const shouldLogToFile = () => {
81
+ // Prefer dynamic lookup so late-bound env (tests, some runtimes) is respected.
82
+ if (!Env.getBool('LOG_TO_FILE', false))
83
+ return false;
84
+ if (typeof process === 'undefined')
85
+ return false;
86
+ return true;
87
+ };
88
+ const buildFileLine = (params) => {
89
+ if (isJsonFormat(getLogFormat()))
90
+ return params.formatted;
91
+ let line = params.formatted;
92
+ if (typeof params.errorMessage === 'string' && params.errorMessage.length > 0) {
93
+ line = `${line} ${params.errorMessage}`;
94
+ }
95
+ else if (params.data !== undefined && params.data !== '') {
96
+ line = `${line} ${safeStringify(redactSensitiveData(params.data))}`;
97
+ }
98
+ return line;
99
+ };
100
+ const writeToFile = (line) => {
101
+ if (!shouldLogToFile())
102
+ return;
103
+ if (fileWriter !== undefined) {
104
+ fileWriter.write(line);
105
+ return;
106
+ }
107
+ getFileWriter();
108
+ fileWriterPromise?.then((mod) => mod.FileLogWriter.write(line));
109
+ };
110
+ const formatLogMessage = (params) => {
111
+ if (isJsonFormat(getLogFormat())) {
112
+ return safeStringify({
113
+ timestamp: new Date().toISOString(),
114
+ level: params.level,
115
+ message: params.message,
116
+ category: params.category,
117
+ data: redactSensitiveData(params.data),
118
+ error: params.errorMessage,
119
+ });
120
+ }
121
+ // text format
122
+ return `[${params.level.toUpperCase()}] ${params.message}`;
123
+ };
9
124
  /**
10
125
  * Helper to extract error message from unknown error type
11
126
  */
@@ -16,33 +131,162 @@ const getErrorMessage = (error) => {
16
131
  if (error instanceof Error) {
17
132
  return error.message;
18
133
  }
19
- return String(error);
134
+ if (typeof error === 'string')
135
+ return error;
136
+ if (typeof error === 'number' || typeof error === 'bigint')
137
+ return error.toString();
138
+ if (typeof error === 'boolean')
139
+ return error ? 'true' : 'false';
140
+ if (typeof error === 'symbol')
141
+ return error.toString();
142
+ if (typeof error === 'function')
143
+ return '[Function]';
144
+ try {
145
+ return safeStringify(error);
146
+ }
147
+ catch {
148
+ return '[Unserializable error]';
149
+ }
150
+ };
151
+ const emitCloudLogs = (event) => {
152
+ // Lazy-load to avoid cycles and avoid cost when disabled.
153
+ void (async () => {
154
+ try {
155
+ if (event.level === 'error' || event.level === 'fatal') {
156
+ const mod = await import('./logging/KvLogger');
157
+ void mod.KvLogger.enqueue(event);
158
+ }
159
+ }
160
+ catch {
161
+ // best-effort
162
+ }
163
+ try {
164
+ if (event.level === 'warn' || event.level === 'error' || event.level === 'fatal') {
165
+ const mod = await import('./logging/SlackLogger');
166
+ void mod.SlackLogger.enqueue(event);
167
+ }
168
+ }
169
+ catch {
170
+ // best-effort
171
+ }
172
+ try {
173
+ const mod = await import('./logging/HttpLogger');
174
+ void mod.HttpLogger.enqueue(event);
175
+ }
176
+ catch {
177
+ // best-effort
178
+ }
179
+ })();
20
180
  };
21
181
  // Private helper functions
22
182
  const logDebug = (message, data, category) => {
23
183
  String(category);
24
- if (isDevelopment) {
25
- console.debug(`[DEBUG] ${message}`, data ?? ''); // eslint-disable-line no-console
184
+ if (isDevelopment()) {
185
+ const timestamp = new Date().toISOString();
186
+ const out = formatLogMessage({ level: 'debug', message, data, category });
187
+ writeToFile(buildFileLine({ formatted: out, data }));
188
+ if (isJsonFormat(getLogFormat())) {
189
+ console.debug(out); // eslint-disable-line no-console
190
+ return;
191
+ }
192
+ console.debug(out, data ?? ''); // eslint-disable-line no-console
193
+ emitCloudLogs({
194
+ timestamp,
195
+ level: 'debug',
196
+ message,
197
+ category,
198
+ data: redactSensitiveData(data),
199
+ });
26
200
  }
27
201
  };
28
202
  const logInfo = (message, data, category) => {
29
203
  String(category);
30
- console.log(`[INFO] ${message}`, data ?? ''); // eslint-disable-line no-console
204
+ const timestamp = new Date().toISOString();
205
+ const out = formatLogMessage({ level: 'info', message, data, category });
206
+ writeToFile(buildFileLine({ formatted: out, data }));
207
+ if (isJsonFormat(getLogFormat())) {
208
+ console.log(out); // eslint-disable-line no-console
209
+ }
210
+ else {
211
+ console.log(out, data ?? ''); // eslint-disable-line no-console
212
+ }
213
+ emitCloudLogs({
214
+ timestamp,
215
+ level: 'info',
216
+ message,
217
+ category,
218
+ data: redactSensitiveData(data),
219
+ });
31
220
  };
32
221
  const logWarn = (message, data, category) => {
33
222
  String(category);
34
- console.warn(`[WARN] ${message}`, data ?? ''); // eslint-disable-line no-console
223
+ const timestamp = new Date().toISOString();
224
+ const out = formatLogMessage({ level: 'warn', message, data, category });
225
+ writeToFile(buildFileLine({ formatted: out, data }));
226
+ if (isJsonFormat(getLogFormat())) {
227
+ console.warn(out); // eslint-disable-line no-console
228
+ }
229
+ else {
230
+ console.warn(out, data ?? ''); // eslint-disable-line no-console
231
+ }
232
+ emitCloudLogs({
233
+ timestamp,
234
+ level: 'warn',
235
+ message,
236
+ category,
237
+ data: redactSensitiveData(data),
238
+ });
35
239
  };
36
240
  const logError = (message, error, category) => {
37
241
  const errorMessage = getErrorMessage(error);
38
242
  String(category);
39
- console.error(`[ERROR] ${message}`, errorMessage); // eslint-disable-line no-console
243
+ const timestamp = new Date().toISOString();
244
+ const out = formatLogMessage({
245
+ level: 'error',
246
+ message,
247
+ category,
248
+ errorMessage,
249
+ });
250
+ writeToFile(buildFileLine({ formatted: out, errorMessage }));
251
+ if (isJsonFormat(getLogFormat())) {
252
+ console.error(out); // eslint-disable-line no-console
253
+ }
254
+ else {
255
+ console.error(out, errorMessage); // eslint-disable-line no-console
256
+ }
257
+ emitCloudLogs({
258
+ timestamp,
259
+ level: 'error',
260
+ message,
261
+ category,
262
+ error: errorMessage,
263
+ });
40
264
  };
41
265
  const logFatal = (message, error, category) => {
42
266
  const errorMessage = getErrorMessage(error);
43
267
  String(category);
44
- console.error(`[FATAL] ${message}`, errorMessage); // eslint-disable-line no-console
45
- if (isProduction && typeof process !== 'undefined') {
268
+ const timestamp = new Date().toISOString();
269
+ const out = formatLogMessage({
270
+ level: 'fatal',
271
+ message,
272
+ category,
273
+ errorMessage,
274
+ });
275
+ writeToFile(buildFileLine({ formatted: out, errorMessage }));
276
+ if (isJsonFormat(getLogFormat())) {
277
+ console.error(out); // eslint-disable-line no-console
278
+ }
279
+ else {
280
+ console.error(out, errorMessage); // eslint-disable-line no-console
281
+ }
282
+ emitCloudLogs({
283
+ timestamp,
284
+ level: 'fatal',
285
+ message,
286
+ category,
287
+ error: errorMessage,
288
+ });
289
+ if (isProduction() && typeof process !== 'undefined') {
46
290
  process.exit(1);
47
291
  }
48
292
  };
@@ -65,13 +309,28 @@ const createLoggerScope = (scope) => {
65
309
  },
66
310
  };
67
311
  };
68
- // Sealed namespace with all logger functionality
312
+ // Expose log cleanup API and sealed namespace with all logger functionality
313
+ export const cleanLogsOnce = async () => {
314
+ if (!shouldLogToFile())
315
+ return [];
316
+ try {
317
+ const mod = await import('./FileLogWriter');
318
+ const deleted = mod.cleanOnce();
319
+ logInfo('Log cleanup executed', { deletedCount: deleted.length });
320
+ return deleted;
321
+ }
322
+ catch (err) {
323
+ logError('Log cleanup failed', err);
324
+ return [];
325
+ }
326
+ };
69
327
  export const Logger = Object.freeze({
70
328
  debug: logDebug,
71
329
  info: logInfo,
72
330
  warn: logWarn,
73
331
  error: logError,
74
332
  fatal: logFatal,
333
+ cleanLogsOnce,
75
334
  scope: createLoggerScope,
76
335
  });
77
336
  export default Logger;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * HTTP Endpoint Logger
3
+ * Sends logs to an external HTTP logging service.
4
+ *
5
+ * Enabled via env:
6
+ * - HTTP_LOG_ENABLED (default: false)
7
+ * - HTTP_LOG_ENDPOINT_URL
8
+ * - HTTP_LOG_BATCH_SIZE (default: 50)
9
+ * - HTTP_LOG_AUTH_TOKEN (optional)
10
+ */
11
+ export type HttpLogEvent = {
12
+ timestamp: string;
13
+ level: 'debug' | 'info' | 'warn' | 'error' | 'fatal';
14
+ message: string;
15
+ category?: string;
16
+ data?: unknown;
17
+ error?: string;
18
+ };
19
+ export declare const HttpLogger: Readonly<{
20
+ enqueue(event: HttpLogEvent): Promise<void>;
21
+ }>;
22
+ export default HttpLogger;
23
+ //# sourceMappingURL=HttpLogger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HttpLogger.d.ts","sourceRoot":"","sources":["../../../../src/config/logging/HttpLogger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH,MAAM,MAAM,YAAY,GAAG;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAkFF,eAAO,MAAM,UAAU;mBACA,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;EAYjD,CAAC;AAEH,eAAe,UAAU,CAAC"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * HTTP Endpoint Logger
3
+ * Sends logs to an external HTTP logging service.
4
+ *
5
+ * Enabled via env:
6
+ * - HTTP_LOG_ENABLED (default: false)
7
+ * - HTTP_LOG_ENDPOINT_URL
8
+ * - HTTP_LOG_BATCH_SIZE (default: 50)
9
+ * - HTTP_LOG_AUTH_TOKEN (optional)
10
+ */
11
+ import { delay } from '../../common/index';
12
+ import { Env } from '../env';
13
+ import { ErrorFactory } from '../../exceptions/ZintrustError';
14
+ import { HttpClient } from '../../tools/http/Http';
15
+ const isEnabled = () => Env.getBool('HTTP_LOG_ENABLED', false);
16
+ let buffer = [];
17
+ let flushPromise;
18
+ const postBatch = async (events) => {
19
+ const endpoint = Env.get('HTTP_LOG_ENDPOINT_URL').trim();
20
+ if (endpoint.length === 0) {
21
+ throw ErrorFactory.createConfigError('HTTP_LOG_ENDPOINT_URL is required when HTTP logging is enabled');
22
+ }
23
+ const token = Env.get('HTTP_LOG_AUTH_TOKEN').trim();
24
+ const builder = HttpClient.post(endpoint, {
25
+ sentAt: new Date().toISOString(),
26
+ count: events.length,
27
+ events,
28
+ });
29
+ if (token.length > 0) {
30
+ builder.withAuth(token, 'Bearer');
31
+ }
32
+ await builder.send();
33
+ };
34
+ const flushNow = async () => {
35
+ const toSend = buffer;
36
+ buffer = [];
37
+ if (!isEnabled())
38
+ return;
39
+ if (toSend.length === 0)
40
+ return;
41
+ const maxRetries = 3;
42
+ const attemptPost = async (attempt) => {
43
+ try {
44
+ await postBatch(toSend);
45
+ }
46
+ catch {
47
+ if (attempt >= maxRetries)
48
+ return;
49
+ const backoffMs = 100 * 2 ** attempt;
50
+ await delay(backoffMs);
51
+ await attemptPost(attempt + 1);
52
+ }
53
+ };
54
+ await attemptPost(0);
55
+ };
56
+ const scheduleFlush = async () => {
57
+ if (flushPromise !== undefined)
58
+ return flushPromise;
59
+ const promise = new Promise((resolve) => {
60
+ const run = async () => {
61
+ try {
62
+ await flushNow();
63
+ }
64
+ finally {
65
+ resolve(undefined);
66
+ }
67
+ };
68
+ if (typeof globalThis.setTimeout !== 'function') {
69
+ void run();
70
+ return;
71
+ }
72
+ globalThis.setTimeout(() => {
73
+ void run();
74
+ }, 0);
75
+ });
76
+ flushPromise = promise.finally(() => {
77
+ flushPromise = undefined;
78
+ });
79
+ return flushPromise;
80
+ };
81
+ export const HttpLogger = Object.freeze({
82
+ async enqueue(event) {
83
+ if (!isEnabled())
84
+ return Promise.resolve(); // NOSONAR
85
+ buffer.push(event);
86
+ const batchSize = Math.max(1, Env.getInt('HTTP_LOG_BATCH_SIZE', 50));
87
+ if (buffer.length >= batchSize) {
88
+ return scheduleFlush();
89
+ }
90
+ return scheduleFlush();
91
+ },
92
+ });
93
+ export default HttpLogger;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * KV Logger
3
+ * Writes batches of log events to a KV namespace (Cloudflare Workers compatible)
4
+ *
5
+ * Enabled via env:
6
+ * - KV_LOG_ENABLED (default: false)
7
+ * - KV_NAMESPACE (binding name; default: 'CACHE')
8
+ * - KV_LOG_RETENTION_DAYS (default: 30)
9
+ */
10
+ export type KvLogEvent = {
11
+ timestamp: string;
12
+ level: 'debug' | 'info' | 'warn' | 'error' | 'fatal';
13
+ message: string;
14
+ category?: string;
15
+ data?: unknown;
16
+ error?: string;
17
+ };
18
+ export declare const KvLogger: Readonly<{
19
+ enqueue(event: KvLogEvent): Promise<void>;
20
+ }>;
21
+ export default KvLogger;
22
+ //# sourceMappingURL=KvLogger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"KvLogger.d.ts","sourceRoot":"","sources":["../../../../src/config/logging/KvLogger.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,MAAM,MAAM,UAAU,GAAG;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AA2IF,eAAO,MAAM,QAAQ;mBACE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;EAkB/C,CAAC;AAEH,eAAe,QAAQ,CAAC"}
@@ -0,0 +1,143 @@
1
+ /**
2
+ * KV Logger
3
+ * Writes batches of log events to a KV namespace (Cloudflare Workers compatible)
4
+ *
5
+ * Enabled via env:
6
+ * - KV_LOG_ENABLED (default: false)
7
+ * - KV_NAMESPACE (binding name; default: 'CACHE')
8
+ * - KV_LOG_RETENTION_DAYS (default: 30)
9
+ */
10
+ import { Cloudflare } from '../cloudflare';
11
+ import { Env } from '../env';
12
+ const getRetentionTtlSeconds = () => {
13
+ const days = Env.getInt('KV_LOG_RETENTION_DAYS', 30);
14
+ const safeDays = Number.isFinite(days) && days > 0 ? days : 30;
15
+ return safeDays * 24 * 60 * 60;
16
+ };
17
+ const getKvBindingName = () => {
18
+ const name = Env.get('KV_NAMESPACE', 'CACHE').trim();
19
+ return name.length > 0 ? name : 'CACHE';
20
+ };
21
+ const isEnabled = () => Env.getBool('KV_LOG_ENABLED', false);
22
+ const safeRandom = () => {
23
+ try {
24
+ // Prefer crypto if available
25
+ const cryptoObj = globalThis.crypto;
26
+ if (cryptoObj?.getRandomValues) {
27
+ const bytes = new Uint8Array(8);
28
+ cryptoObj.getRandomValues(bytes);
29
+ return Array.from(bytes)
30
+ .map((b) => b.toString(16).padStart(2, '0'))
31
+ .join('');
32
+ }
33
+ }
34
+ catch {
35
+ // fall through
36
+ }
37
+ const generate = Math.random().toString(16).slice(2); // NOSONAR
38
+ const fallback = generate + Math.random().toString(16).slice(2); // NOSONAR this is not used for security
39
+ return fallback;
40
+ };
41
+ const buildKey = (timestampIso) => {
42
+ const date = timestampIso.slice(0, 10);
43
+ const hour = timestampIso.slice(11, 13);
44
+ return `logs:${date}:${hour}:${safeRandom()}`;
45
+ };
46
+ let buffer = [];
47
+ let flushTimer;
48
+ let flushPromise;
49
+ const scheduleFlush = async () => {
50
+ if (flushPromise !== undefined)
51
+ return flushPromise;
52
+ // Fixed small batching window to reduce KV write volume.
53
+ const windowMs = 1000;
54
+ const promise = new Promise((resolve) => {
55
+ const run = async () => {
56
+ try {
57
+ await flushNow();
58
+ }
59
+ finally {
60
+ resolve(undefined);
61
+ }
62
+ };
63
+ if (typeof globalThis.setTimeout !== 'function') {
64
+ // microtask-ish
65
+ void run();
66
+ return;
67
+ }
68
+ flushTimer = globalThis.setTimeout(() => {
69
+ flushTimer = undefined;
70
+ void run();
71
+ }, windowMs);
72
+ });
73
+ flushPromise = promise.finally(() => {
74
+ flushPromise = undefined;
75
+ });
76
+ return flushPromise;
77
+ };
78
+ const getKv = () => {
79
+ const bindingName = getKvBindingName();
80
+ return Cloudflare.getKVBinding(bindingName);
81
+ };
82
+ const putBatch = async (kv, events) => {
83
+ if (events.length === 0)
84
+ return;
85
+ const timestamp = events.at(-1)?.timestamp ?? new Date().toISOString();
86
+ const key = buildKey(timestamp);
87
+ const payload = JSON.stringify({
88
+ version: 1,
89
+ createdAt: new Date().toISOString(),
90
+ count: events.length,
91
+ events,
92
+ });
93
+ const opts = { expirationTtl: getRetentionTtlSeconds() };
94
+ await kv.put(key, payload, opts);
95
+ };
96
+ const flushNow = async () => {
97
+ if (!isEnabled()) {
98
+ buffer = [];
99
+ return;
100
+ }
101
+ const kv = getKv();
102
+ if (kv === null) {
103
+ buffer = [];
104
+ return;
105
+ }
106
+ const toSend = buffer;
107
+ buffer = [];
108
+ try {
109
+ await putBatch(kv, toSend);
110
+ }
111
+ catch {
112
+ // Best-effort: never throw from logging.
113
+ }
114
+ };
115
+ const flushSoon = async () => {
116
+ if (flushPromise !== undefined)
117
+ return flushPromise;
118
+ flushPromise = Promise.resolve()
119
+ .then(async () => flushNow())
120
+ .finally(() => {
121
+ flushPromise = undefined;
122
+ });
123
+ return flushPromise;
124
+ };
125
+ export const KvLogger = Object.freeze({
126
+ async enqueue(event) {
127
+ if (!isEnabled())
128
+ return Promise.resolve();
129
+ buffer.push(event);
130
+ // Basic size guard: flush if it gets too large
131
+ const maxBatch = 100;
132
+ if (buffer.length >= maxBatch) {
133
+ // Cancel scheduled flush and flush immediately
134
+ if (flushTimer !== undefined) {
135
+ globalThis.clearTimeout(flushTimer);
136
+ flushTimer = undefined;
137
+ }
138
+ return flushSoon();
139
+ }
140
+ return scheduleFlush();
141
+ },
142
+ });
143
+ export default KvLogger;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Slack Notification Logger
3
+ * Sends warn/error/fatal log events to a Slack incoming webhook.
4
+ *
5
+ * Enabled via env:
6
+ * - SLACK_LOG_ENABLED (default: false)
7
+ * - SLACK_LOG_WEBHOOK_URL
8
+ * - SLACK_LOG_LEVELS (comma-separated; default: "warn,error,fatal")
9
+ * - SLACK_LOG_BATCH_WINDOW_MS (default: 5000)
10
+ */
11
+ export type SlackLogEvent = {
12
+ timestamp: string;
13
+ level: 'debug' | 'info' | 'warn' | 'error' | 'fatal';
14
+ message: string;
15
+ category?: string;
16
+ data?: unknown;
17
+ error?: string;
18
+ };
19
+ export declare const SlackLogger: Readonly<{
20
+ enqueue(event: SlackLogEvent): Promise<void>;
21
+ }>;
22
+ export default SlackLogger;
23
+ //# sourceMappingURL=SlackLogger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SlackLogger.d.ts","sourceRoot":"","sources":["../../../../src/config/logging/SlackLogger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,MAAM,MAAM,aAAa,GAAG;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAoHF,eAAO,MAAM,WAAW;mBACD,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;EAclD,CAAC;AAEH,eAAe,WAAW,CAAC"}