@zintrust/core 0.1.1 → 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 (483) 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 +1 -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 +150 -16
  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 +9 -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/src/index.ts.tpl +38 -11
  327. package/src/templates/project/basic/template.json +3 -0
  328. package/src/toolkit/Secrets/EnvFile.d.ts +15 -0
  329. package/src/toolkit/Secrets/EnvFile.d.ts.map +1 -0
  330. package/src/toolkit/Secrets/EnvFile.js +63 -0
  331. package/src/toolkit/Secrets/Manifest.d.ts +24 -0
  332. package/src/toolkit/Secrets/Manifest.d.ts.map +1 -0
  333. package/src/toolkit/Secrets/Manifest.js +71 -0
  334. package/src/toolkit/Secrets/index.d.ts +42 -0
  335. package/src/toolkit/Secrets/index.d.ts.map +1 -0
  336. package/src/toolkit/Secrets/index.js +119 -0
  337. package/src/toolkit/Secrets/providers/AwsSecretsManager.d.ts +14 -0
  338. package/src/toolkit/Secrets/providers/AwsSecretsManager.d.ts.map +1 -0
  339. package/src/toolkit/Secrets/providers/AwsSecretsManager.js +131 -0
  340. package/src/toolkit/Secrets/providers/CloudflareKv.d.ts +9 -0
  341. package/src/toolkit/Secrets/providers/CloudflareKv.d.ts.map +1 -0
  342. package/src/toolkit/Secrets/providers/CloudflareKv.js +73 -0
  343. package/src/tools/broadcast/Broadcast.d.ts +7 -0
  344. package/src/tools/broadcast/Broadcast.d.ts.map +1 -0
  345. package/src/tools/broadcast/Broadcast.js +37 -0
  346. package/src/tools/broadcast/drivers/BaseDriver.d.ts +5 -0
  347. package/src/tools/broadcast/drivers/BaseDriver.d.ts.map +1 -0
  348. package/src/tools/broadcast/drivers/BaseDriver.js +8 -0
  349. package/src/tools/broadcast/drivers/InMemory.d.ts +18 -0
  350. package/src/tools/broadcast/drivers/InMemory.d.ts.map +1 -0
  351. package/src/tools/broadcast/drivers/InMemory.js +16 -0
  352. package/src/tools/broadcast/drivers/Pusher.d.ts +8 -0
  353. package/src/tools/broadcast/drivers/Pusher.d.ts.map +1 -0
  354. package/src/tools/broadcast/drivers/Pusher.js +75 -0
  355. package/src/tools/broadcast/drivers/Redis.d.ts +19 -0
  356. package/src/tools/broadcast/drivers/Redis.d.ts.map +1 -0
  357. package/src/tools/broadcast/drivers/Redis.js +73 -0
  358. package/src/tools/broadcast/drivers/RedisHttps.d.ts +14 -0
  359. package/src/tools/broadcast/drivers/RedisHttps.d.ts.map +1 -0
  360. package/src/tools/broadcast/drivers/RedisHttps.js +50 -0
  361. package/src/tools/broadcast/index.d.ts +7 -0
  362. package/src/tools/broadcast/index.d.ts.map +1 -0
  363. package/src/tools/broadcast/index.js +6 -0
  364. package/src/tools/http/Http.d.ts +51 -0
  365. package/src/tools/http/Http.d.ts.map +1 -0
  366. package/src/tools/http/Http.js +171 -0
  367. package/src/tools/http/HttpResponse.d.ts +32 -0
  368. package/src/tools/http/HttpResponse.d.ts.map +1 -0
  369. package/src/tools/http/HttpResponse.js +80 -0
  370. package/src/tools/http/index.d.ts +15 -0
  371. package/src/tools/http/index.d.ts.map +1 -0
  372. package/src/tools/http/index.js +9 -0
  373. package/src/tools/mail/Mail.d.ts +22 -0
  374. package/src/tools/mail/Mail.d.ts.map +1 -0
  375. package/src/tools/mail/Mail.js +105 -0
  376. package/src/tools/mail/attachments.d.ts +23 -0
  377. package/src/tools/mail/attachments.d.ts.map +1 -0
  378. package/src/tools/mail/attachments.js +26 -0
  379. package/src/tools/mail/drivers/BaseDriver.d.ts +5 -0
  380. package/src/tools/mail/drivers/BaseDriver.d.ts.map +1 -0
  381. package/src/tools/mail/drivers/BaseDriver.js +8 -0
  382. package/src/tools/mail/drivers/Mailgun.d.ts +31 -0
  383. package/src/tools/mail/drivers/Mailgun.d.ts.map +1 -0
  384. package/src/tools/mail/drivers/Mailgun.js +81 -0
  385. package/src/tools/mail/drivers/SendGrid.d.ts +29 -0
  386. package/src/tools/mail/drivers/SendGrid.d.ts.map +1 -0
  387. package/src/tools/mail/drivers/SendGrid.js +57 -0
  388. package/src/tools/mail/drivers/Ses.d.ts +24 -0
  389. package/src/tools/mail/drivers/Ses.d.ts.map +1 -0
  390. package/src/tools/mail/drivers/Ses.js +116 -0
  391. package/src/tools/mail/drivers/Smtp.d.ts +38 -0
  392. package/src/tools/mail/drivers/Smtp.d.ts.map +1 -0
  393. package/src/tools/mail/drivers/Smtp.js +327 -0
  394. package/src/tools/mail/templates/index.d.ts +27 -0
  395. package/src/tools/mail/templates/index.d.ts.map +1 -0
  396. package/src/tools/mail/templates/index.js +35 -0
  397. package/src/tools/mail/templates/markdown/index.d.ts +17 -0
  398. package/src/tools/mail/templates/markdown/index.d.ts.map +1 -0
  399. package/src/tools/mail/templates/markdown/index.js +49 -0
  400. package/src/tools/mail/templates/markdown/registry.d.ts +15 -0
  401. package/src/tools/mail/templates/markdown/registry.d.ts.map +1 -0
  402. package/src/tools/mail/templates/markdown/registry.js +34 -0
  403. package/src/tools/mail/templates/markdown/validator.d.ts +16 -0
  404. package/src/tools/mail/templates/markdown/validator.d.ts.map +1 -0
  405. package/src/tools/mail/templates/markdown/validator.js +24 -0
  406. package/src/tools/mail/testing.d.ts +41 -0
  407. package/src/tools/mail/testing.d.ts.map +1 -0
  408. package/src/tools/mail/testing.js +34 -0
  409. package/src/tools/notification/Driver.d.ts +11 -0
  410. package/src/tools/notification/Driver.d.ts.map +1 -0
  411. package/src/tools/notification/Driver.js +1 -0
  412. package/src/tools/notification/Notification.d.ts +11 -0
  413. package/src/tools/notification/Notification.d.ts.map +1 -0
  414. package/src/tools/notification/Notification.js +11 -0
  415. package/src/tools/notification/Registry.d.ts +10 -0
  416. package/src/tools/notification/Registry.d.ts.map +1 -0
  417. package/src/tools/notification/Registry.js +22 -0
  418. package/src/tools/notification/Service.d.ts +6 -0
  419. package/src/tools/notification/Service.d.ts.map +1 -0
  420. package/src/tools/notification/Service.js +18 -0
  421. package/src/tools/notification/config.d.ts +5 -0
  422. package/src/tools/notification/config.d.ts.map +1 -0
  423. package/src/tools/notification/config.js +5 -0
  424. package/src/tools/notification/drivers/BaseDriver.d.ts +5 -0
  425. package/src/tools/notification/drivers/BaseDriver.d.ts.map +1 -0
  426. package/src/tools/notification/drivers/BaseDriver.js +8 -0
  427. package/src/tools/notification/drivers/Console.d.ts +7 -0
  428. package/src/tools/notification/drivers/Console.d.ts.map +1 -0
  429. package/src/tools/notification/drivers/Console.js +13 -0
  430. package/src/tools/notification/drivers/Slack.d.ts +16 -0
  431. package/src/tools/notification/drivers/Slack.d.ts.map +1 -0
  432. package/src/tools/notification/drivers/Slack.js +24 -0
  433. package/src/tools/notification/drivers/Termii.d.ts +10 -0
  434. package/src/tools/notification/drivers/Termii.d.ts.map +1 -0
  435. package/src/tools/notification/drivers/Termii.js +47 -0
  436. package/src/tools/notification/drivers/Twilio.d.ts +21 -0
  437. package/src/tools/notification/drivers/Twilio.d.ts.map +1 -0
  438. package/src/tools/notification/drivers/Twilio.js +48 -0
  439. package/src/tools/notification/templates/markdown/index.d.ts +15 -0
  440. package/src/tools/notification/templates/markdown/index.d.ts.map +1 -0
  441. package/src/tools/notification/templates/markdown/index.js +38 -0
  442. package/src/tools/notification/templates/markdown/registry.d.ts +15 -0
  443. package/src/tools/notification/templates/markdown/registry.d.ts.map +1 -0
  444. package/src/tools/notification/templates/markdown/registry.js +36 -0
  445. package/src/tools/notification/testing.d.ts +19 -0
  446. package/src/tools/notification/testing.d.ts.map +1 -0
  447. package/src/tools/notification/testing.js +35 -0
  448. package/src/tools/notification/testingHelpers.d.ts +12 -0
  449. package/src/tools/notification/testingHelpers.d.ts.map +1 -0
  450. package/src/tools/notification/testingHelpers.js +32 -0
  451. package/src/tools/queue/Queue.d.ts +23 -0
  452. package/src/tools/queue/Queue.d.ts.map +1 -0
  453. package/src/tools/queue/Queue.js +38 -0
  454. package/src/tools/queue/drivers/InMemory.d.ts +10 -0
  455. package/src/tools/queue/drivers/InMemory.d.ts.map +1 -0
  456. package/src/tools/queue/drivers/InMemory.js +55 -0
  457. package/src/tools/queue/drivers/Redis.d.ts +10 -0
  458. package/src/tools/queue/drivers/Redis.d.ts.map +1 -0
  459. package/src/tools/queue/drivers/Redis.js +91 -0
  460. package/src/tools/storage/drivers/Gcs.d.ts +20 -0
  461. package/src/tools/storage/drivers/Gcs.d.ts.map +1 -0
  462. package/src/tools/storage/drivers/Gcs.js +152 -0
  463. package/src/tools/storage/drivers/Local.d.ts +17 -0
  464. package/src/tools/storage/drivers/Local.d.ts.map +1 -0
  465. package/src/tools/storage/drivers/Local.js +63 -0
  466. package/src/tools/storage/drivers/R2.d.ts +20 -0
  467. package/src/tools/storage/drivers/R2.d.ts.map +1 -0
  468. package/src/tools/storage/drivers/R2.js +73 -0
  469. package/src/tools/storage/drivers/S3.d.ts +26 -0
  470. package/src/tools/storage/drivers/S3.d.ts.map +1 -0
  471. package/src/tools/storage/drivers/S3.js +258 -0
  472. package/src/tools/storage/index.d.ts +24 -0
  473. package/src/tools/storage/index.d.ts.map +1 -0
  474. package/src/tools/storage/index.js +112 -0
  475. package/src/tools/storage/testing.d.ts +23 -0
  476. package/src/tools/storage/testing.d.ts.map +1 -0
  477. package/src/tools/storage/testing.js +52 -0
  478. package/src/tools/templates/MarkdownRenderer.d.ts +14 -0
  479. package/src/tools/templates/MarkdownRenderer.d.ts.map +1 -0
  480. package/src/tools/templates/MarkdownRenderer.js +300 -0
  481. package/src/tools/templates/index.d.ts +5 -0
  482. package/src/tools/templates/index.d.ts.map +1 -0
  483. package/src/tools/templates/index.js +4 -0
@@ -5,7 +5,37 @@
5
5
  import { Logger } from '../config/logger';
6
6
  import { ErrorFactory } from '../exceptions/ZintrustError';
7
7
  import { fs } from '../node-singletons/index.js';
8
- import * as path from 'node:path';
8
+ import * as path from '../node-singletons/path';
9
+ const GENERATION_CACHE_STATE_SYMBOL = Symbol.for('zintrust:GenerationCacheState');
10
+ function isUnrefableTimer(value) {
11
+ if (typeof value !== 'object' || value === null)
12
+ return false;
13
+ return 'unref' in value && typeof value.unref === 'function';
14
+ }
15
+ function deleteFileNonBlocking(filePath) {
16
+ try {
17
+ const anyFs = fs;
18
+ if (typeof anyFs.promises?.unlink === 'function') {
19
+ void anyFs.promises.unlink(filePath).catch((err) => {
20
+ const maybeErr = err;
21
+ if (maybeErr.code === 'ENOENT')
22
+ return;
23
+ Logger.error(`Failed to delete cache file: ${filePath} (${err instanceof Error ? err.message : String(err)})`);
24
+ });
25
+ return;
26
+ }
27
+ if (typeof anyFs.unlink === 'function') {
28
+ anyFs.unlink(filePath, (err) => {
29
+ if (err && err.code !== 'ENOENT') {
30
+ Logger.error(`Failed to delete cache file: ${filePath} (${err.message})`);
31
+ }
32
+ });
33
+ }
34
+ }
35
+ catch (err) {
36
+ Logger.error(`Failed to schedule cache file deletion: ${filePath} (${err instanceof Error ? err.message : String(err)})`);
37
+ }
38
+ }
9
39
  /**
10
40
  * Generation Cache - Cache generated code to avoid re-generating identical code
11
41
  * Sealed namespace for immutability
@@ -14,82 +44,127 @@ export const GenerationCache = Object.freeze({
14
44
  /**
15
45
  * Create a new generation cache instance
16
46
  */
17
- create(cacheDir = path.join(process.cwd(), '.gen-cache'), ttlMs = 3600000) {
18
- const state = {
19
- cache: new Map(),
20
- cacheDir,
21
- ttlMs,
22
- };
23
- // Initialize
24
- loadFromDisk(state);
25
- // Active cleanup every 10 minutes
26
- state.cleanupInterval = setInterval(() => {
27
- const now = Date.now();
28
- for (const [key, entry] of state.cache.entries()) {
29
- if (now - entry.timestamp > state.ttlMs) {
30
- state.cache.delete(key);
31
- // Also try to delete from disk
32
- const file = path.join(state.cacheDir, `${key}.json`);
33
- if (fs.existsSync(file)) {
34
- fs.unlinkSync(file);
35
- }
36
- }
37
- }
38
- }, 600000);
39
- return {
40
- /**
41
- * Get from cache
42
- */
43
- get(type, params) {
44
- const key = getCacheKey(type, params);
45
- const entry = state.cache.get(key);
46
- if (entry === undefined)
47
- return null;
48
- // Check TTL
49
- if (Date.now() - entry.timestamp > state.ttlMs) {
50
- state.cache.delete(key);
51
- const file = path.join(state.cacheDir, `${key}.json`);
52
- if (fs.existsSync(file)) {
53
- fs.unlinkSync(file);
54
- }
55
- return null;
56
- }
57
- return entry.code;
58
- },
59
- /**
60
- * Set in cache
61
- */
62
- set(type, params, code) {
63
- const key = getCacheKey(type, params);
64
- state.cache.set(key, {
65
- code,
66
- timestamp: Date.now(),
67
- });
68
- },
69
- /**
70
- * Save cache to disk
71
- */
72
- save() {
73
- saveCacheToDisk(state);
74
- },
75
- /**
76
- * Clear cache
77
- */
78
- clear() {
79
- if (state.cleanupInterval) {
80
- clearInterval(state.cleanupInterval);
81
- }
82
- clearCache(state);
83
- },
84
- /**
85
- * Get cache statistics
86
- */
87
- getStats() {
88
- return getCacheStats(state);
89
- },
90
- };
47
+ create(cacheDir = path.join(process.cwd(), '.gen-cache'), ttlMs = 3600000, maxEntries = 1000) {
48
+ const state = createCacheState(cacheDir, ttlMs, maxEntries);
49
+ initializeCacheState(state);
50
+ startCacheCleanup(state);
51
+ const instance = createCacheInstance(state);
52
+ attachCacheStateForTests(instance, state);
53
+ return instance;
91
54
  },
92
55
  });
56
+ function createCacheState(cacheDir, ttlMs, maxEntries) {
57
+ return {
58
+ cache: new Map(),
59
+ cacheDir,
60
+ ttlMs,
61
+ maxEntries,
62
+ };
63
+ }
64
+ function initializeCacheState(state) {
65
+ loadFromDisk(state);
66
+ }
67
+ function startCacheCleanup(state) {
68
+ // Active cleanup every 10 minutes
69
+ state.cleanupInterval = setInterval(() => {
70
+ const now = Date.now();
71
+ for (const [key, entry] of state.cache.entries()) {
72
+ if (now - entry.timestamp > state.ttlMs) {
73
+ state.cache.delete(key);
74
+ const file = path.join(state.cacheDir, `${key}.json`);
75
+ deleteFileNonBlocking(file);
76
+ }
77
+ }
78
+ // Enforce maxEntries by evicting oldest keys
79
+ if (state.maxEntries !== undefined) {
80
+ while (state.cache.size > state.maxEntries) {
81
+ const oldestKey = state.cache.keys().next().value;
82
+ if (oldestKey === undefined)
83
+ break;
84
+ state.cache.delete(oldestKey);
85
+ const file = path.join(state.cacheDir, `${oldestKey}.json`);
86
+ deleteFileNonBlocking(file);
87
+ }
88
+ }
89
+ }, 600000);
90
+ // Node: allow process to exit; other runtimes may not support unref()
91
+ if (isUnrefableTimer(state.cleanupInterval)) {
92
+ state.cleanupInterval.unref();
93
+ }
94
+ }
95
+ function createCacheInstance(state) {
96
+ return {
97
+ /**
98
+ * Get from cache
99
+ */
100
+ get(type, params) {
101
+ const key = getCacheKey(type, params);
102
+ const entry = state.cache.get(key);
103
+ if (entry === undefined)
104
+ return null;
105
+ // Check TTL
106
+ if (Date.now() - entry.timestamp > state.ttlMs) {
107
+ state.cache.delete(key);
108
+ const file = path.join(state.cacheDir, `${key}.json`);
109
+ deleteFileNonBlocking(file);
110
+ return null;
111
+ }
112
+ return entry.code;
113
+ },
114
+ /**
115
+ * Set in cache
116
+ */
117
+ set(type, params, code) {
118
+ const key = getCacheKey(type, params);
119
+ // If key already exists, delete first so insertion order updates for LRU
120
+ if (state.cache.has(key))
121
+ state.cache.delete(key);
122
+ state.cache.set(key, {
123
+ code,
124
+ timestamp: Date.now(),
125
+ });
126
+ // Enforce maxEntries immediately
127
+ if (state.maxEntries !== undefined) {
128
+ while (state.cache.size > state.maxEntries) {
129
+ const oldest = state.cache.keys().next().value;
130
+ if (oldest === undefined)
131
+ break;
132
+ state.cache.delete(oldest);
133
+ const file = path.join(state.cacheDir, `${oldest}.json`);
134
+ deleteFileNonBlocking(file);
135
+ }
136
+ }
137
+ },
138
+ /**
139
+ * Save cache to disk
140
+ */
141
+ save() {
142
+ saveCacheToDisk(state);
143
+ },
144
+ /**
145
+ * Clear cache
146
+ */
147
+ clear() {
148
+ if (state.cleanupInterval) {
149
+ clearInterval(state.cleanupInterval);
150
+ state.cleanupInterval = undefined;
151
+ }
152
+ clearCache(state);
153
+ },
154
+ /**
155
+ * Get cache statistics
156
+ */
157
+ getStats() {
158
+ return getCacheStats(state);
159
+ },
160
+ };
161
+ }
162
+ function attachCacheStateForTests(instance, state) {
163
+ Object.defineProperty(instance, GENERATION_CACHE_STATE_SYMBOL, {
164
+ value: state,
165
+ enumerable: false,
166
+ });
167
+ }
93
168
  /**
94
169
  * Save cache to disk
95
170
  */
@@ -2,11 +2,11 @@
2
2
  * Establish Performance Baseline
3
3
  * Run all code generator benchmarks and save baseline metrics
4
4
  */
5
+ import { esmFilePath } from '../common/index';
5
6
  import { Logger } from '../config/logger';
6
7
  import { fs } from '../node-singletons/index.js';
7
- import { fileURLToPath } from '../node-singletons/url';
8
+ import * as path from '../node-singletons/path';
8
9
  import { CodeGenerationBenchmark } from './CodeGenerationBenchmark';
9
- import * as path from 'node:path';
10
10
  /**
11
11
  * Run baseline and save results
12
12
  */
@@ -25,7 +25,7 @@ function isMainModuleEsm() {
25
25
  const entry = process.argv[1];
26
26
  if (entry === undefined || entry === '')
27
27
  return false;
28
- const currentFilePath = fileURLToPath(new URL(import.meta.url));
28
+ const currentFilePath = esmFilePath(import.meta.url);
29
29
  // Use realpathSync to handle symlinks (common on macOS /var -> /private/var)
30
30
  if (!('realpathSync' in fs)) {
31
31
  return path.resolve(entry) === path.resolve(currentFilePath);
@@ -19,7 +19,9 @@ export declare const PluginManager: Readonly<{
19
19
  /**
20
20
  * Install a plugin
21
21
  */
22
- install(pluginId: string): Promise<void>;
22
+ install(pluginId: string, options?: {
23
+ packageManager?: string;
24
+ }): Promise<void>;
23
25
  /**
24
26
  * Uninstall a plugin
25
27
  * Note: This does NOT uninstall dependencies to avoid breaking other things,
@@ -1 +1 @@
1
- {"version":3,"file":"PluginManager.d.ts","sourceRoot":"","sources":["../../../src/runtime/PluginManager.ts"],"names":[],"mappings":"AAEA;;;GAGG;AAQH,OAAO,EAAE,gBAAgB,EAAkB,MAAM,yBAAyB,CAAC;AAwG3E,eAAO,MAAM,aAAa;IACxB;;OAEG;YACK,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAIxC;;OAEG;yBACkB,MAAM,GAAG,MAAM,GAAG,IAAI;IAW3C;;OAEG;0BACyB,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAoCrD;;OAEG;sBACqB,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkB9C;;;;OAIG;wBACuB,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;EA2ChD,CAAC"}
1
+ {"version":3,"file":"PluginManager.d.ts","sourceRoot":"","sources":["../../../src/runtime/PluginManager.ts"],"names":[],"mappings":"AAEA;;;GAGG;AASH,OAAO,EAAE,gBAAgB,EAAkB,MAAM,yBAAyB,CAAC;AAoN3E,eAAO,MAAM,aAAa;IACxB;;OAEG;YACK,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAIxC;;OAEG;yBACkB,MAAM,GAAG,MAAM,GAAG,IAAI;IAW3C;;OAEG;0BACyB,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAqCrD;;OAEG;sBACqB,MAAM,YAAY;QAAE,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IA2BrF;;;;OAIG;wBACuB,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;EA2ChD,CAAC"}
@@ -4,15 +4,54 @@
4
4
  * Plugin Manager
5
5
  * Handles installation and removal of framework plugins.
6
6
  */
7
+ import { SpawnUtil } from '../cli/utils/spawn';
8
+ import { esmDirname, resolvePackageManager } from '../common/index';
7
9
  import { Logger } from '../config/logger';
8
10
  import { ErrorFactory } from '../exceptions/ZintrustError';
9
11
  import { execSync } from '../node-singletons/child-process';
10
- import { fsPromises as fs } from '../node-singletons/fs';
12
+ import { existsSync, fsPromises as fs } from '../node-singletons/fs';
11
13
  import * as path from '../node-singletons/path';
12
- import { fileURLToPath } from '../node-singletons/url';
13
14
  import { PluginRegistry } from './PluginRegistry';
14
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
15
- const PROJECT_ROOT = path.resolve(__dirname, '../../');
15
+ const __dirname = esmDirname(import.meta.url);
16
+ const MAX_PACKAGE_ROOT_SEARCH_DEPTH = 20;
17
+ function findPackageRoot(startDir) {
18
+ let current = startDir;
19
+ for (let i = 0; i < MAX_PACKAGE_ROOT_SEARCH_DEPTH; i++) {
20
+ if (existsSync(path.join(current, 'package.json')))
21
+ return current;
22
+ const parent = path.dirname(current);
23
+ if (parent === current)
24
+ break;
25
+ current = parent;
26
+ }
27
+ // Fallback to a reasonable default if package.json isn't found.
28
+ return path.resolve(startDir, '../..');
29
+ }
30
+ function resolveProjectRoot() {
31
+ const fromEnv = process.env['ZINTRUST_PROJECT_ROOT'];
32
+ if (fromEnv !== undefined && fromEnv.trim().length > 0)
33
+ return fromEnv.trim();
34
+ return process.cwd();
35
+ }
36
+ function resolveTemplateRootOrThrow() {
37
+ const packageRoot = findPackageRoot(__dirname);
38
+ const candidates = [
39
+ // Monorepo/dev layout
40
+ path.join(packageRoot, 'src', 'templates'),
41
+ // Packed layout (if templates are shipped without src)
42
+ path.join(packageRoot, 'templates'),
43
+ // Common build output layout
44
+ path.join(packageRoot, 'dist', 'templates'),
45
+ ];
46
+ for (const candidate of candidates) {
47
+ if (existsSync(candidate))
48
+ return candidate;
49
+ }
50
+ throw ErrorFactory.createNotFoundError('Plugin templates directory not found', {
51
+ candidates,
52
+ packageRoot,
53
+ });
54
+ }
16
55
  function isStringRecord(value) {
17
56
  if (typeof value !== 'object' || value === null)
18
57
  return false;
@@ -40,17 +79,45 @@ function getPluginOrThrow(pluginId) {
40
79
  }
41
80
  return { resolvedId, plugin: PluginRegistry[resolvedId] };
42
81
  }
43
- function npmInstall(packages, options) {
82
+ async function npmInstall(packages, options) {
44
83
  if (packages.length === 0)
45
84
  return;
46
85
  Logger.info(`Installing ${options.label}: ${packages.join(', ')}...`);
47
- const devFlag = options.dev ? '-D ' : '';
86
+ const projectRoot = options.projectRoot ?? resolveProjectRoot();
87
+ const pm = options.packageManager ?? resolvePackageManager();
88
+ let cmd;
89
+ let args = [];
90
+ switch (pm) {
91
+ case 'pnpm':
92
+ cmd = 'pnpm';
93
+ args = ['add', ...packages, ...(options.dev ? ['-D'] : [])];
94
+ break;
95
+ case 'yarn':
96
+ cmd = 'yarn';
97
+ args = ['add', ...packages, ...(options.dev ? ['--dev'] : [])];
98
+ break;
99
+ case 'npm':
100
+ default:
101
+ cmd = 'npm';
102
+ args = ['install', ...(options.dev ? ['--save-dev'] : []), ...packages];
103
+ break;
104
+ }
48
105
  try {
49
- const cmd = `npm install ${devFlag}${packages.join(' ')}`; // NOSONAR
50
- execSync(cmd, {
51
- stdio: 'inherit',
52
- cwd: PROJECT_ROOT,
53
- });
106
+ if (pm === 'npm') {
107
+ // Preserve legacy execSync behavior for npm so integration tests and simple CLI usage behave identically
108
+ const cmdStr = options.dev
109
+ ? `npm install -D ${packages.join(' ')}`
110
+ : `npm install ${packages.join(' ')}`; // NOSONAR
111
+ execSync(cmdStr, { stdio: 'inherit', cwd: projectRoot });
112
+ }
113
+ else {
114
+ const exit = await SpawnUtil.spawnAndWait({ command: cmd, args, cwd: projectRoot });
115
+ if (exit !== 0) {
116
+ throw ErrorFactory.createCliError(`Package manager ${pm} failed to install ${options.label}`, {
117
+ exit,
118
+ });
119
+ }
120
+ }
54
121
  }
55
122
  catch (error) {
56
123
  ErrorFactory.createCliError(`Failed to install ${options.label}`, { error });
@@ -58,9 +125,20 @@ function npmInstall(packages, options) {
58
125
  }
59
126
  }
60
127
  async function copyPluginTemplates(plugin) {
128
+ const templateRoot = resolveTemplateRootOrThrow();
129
+ const projectRoot = resolveProjectRoot();
61
130
  for (const template of plugin.templates) {
62
- const sourcePath = path.join(PROJECT_ROOT, 'src/templates', template.source);
63
- const destPath = path.join(PROJECT_ROOT, template.destination);
131
+ const sourcePath = path.join(templateRoot, template.source);
132
+ const destPath = path.join(projectRoot, template.destination);
133
+ // Prevent path traversal: resolved destination must be within project root
134
+ const resolvedDest = path.resolve(destPath);
135
+ const resolvedProjectRoot = path.resolve(projectRoot);
136
+ if (!(resolvedDest === resolvedProjectRoot ||
137
+ resolvedDest.startsWith(resolvedProjectRoot + path.sep))) {
138
+ throw ErrorFactory.createCliError(`Invalid template destination: ${template.destination}`, {
139
+ destination: template.destination,
140
+ });
141
+ }
64
142
  Logger.info(`Copying ${template.source} to ${template.destination}...`);
65
143
  try {
66
144
  // Ensure destination directory exists
@@ -78,16 +156,25 @@ async function copyPluginTemplates(plugin) {
78
156
  function runPostInstall(plugin) {
79
157
  if (!plugin.postInstall)
80
158
  return;
159
+ const projectRoot = resolveProjectRoot();
81
160
  if (plugin.postInstall.command !== undefined) {
82
- Logger.info(`Running post-install command: ${plugin.postInstall.command}...`);
83
- try {
84
- execSync(plugin.postInstall.command, {
85
- stdio: 'inherit',
86
- cwd: PROJECT_ROOT,
87
- });
161
+ // Post-install command execution is opt-in. To avoid arbitrary command execution
162
+ // and reduce supply-chain risk, we only execute when ZINTRUST_ALLOW_POSTINSTALL=1
163
+ const allow = String(process.env['ZINTRUST_ALLOW_POSTINSTALL'] ?? '').trim() === '1';
164
+ if (allow) {
165
+ Logger.info(`Running post-install command: ${plugin.postInstall.command}...`);
166
+ try {
167
+ execSync(plugin.postInstall.command, {
168
+ stdio: 'inherit',
169
+ cwd: projectRoot,
170
+ });
171
+ }
172
+ catch (error) {
173
+ ErrorFactory.createCliError('Post-install command failed', { error });
174
+ }
88
175
  }
89
- catch (error) {
90
- ErrorFactory.createCliError('Post-install command failed', { error });
176
+ else {
177
+ Logger.info(`Post-install command available but not executed (ZINTRUST_ALLOW_POSTINSTALL!=1): ${plugin.postInstall.command}`);
91
178
  }
92
179
  }
93
180
  if (plugin.postInstall.message !== undefined && plugin.postInstall.message.length > 0) {
@@ -125,14 +212,15 @@ export const PluginManager = Object.freeze({
125
212
  throw ErrorFactory.createNotFoundError(`Plugin ${pluginId} not found`, { pluginId });
126
213
  }
127
214
  const plugin = PluginRegistry[resolvedId];
215
+ const projectRoot = resolveProjectRoot();
128
216
  // Check if the main template file exists in the destination
129
217
  // We assume if the first template exists, the plugin is "installed"
130
218
  if (plugin.templates.length > 0) {
131
- const destPath = path.join(PROJECT_ROOT, plugin.templates[0].destination);
219
+ const destPath = path.join(projectRoot, plugin.templates[0].destination);
132
220
  try {
133
221
  await fs.access(destPath);
134
222
  // Also check if dependencies are in package.json
135
- const packageJsonPath = path.join(PROJECT_ROOT, 'package.json');
223
+ const packageJsonPath = path.join(projectRoot, 'package.json');
136
224
  const packageJsonText = await fs.readFile(packageJsonPath, 'utf-8');
137
225
  const packageJson = parsePackageJsonDeps(packageJsonText);
138
226
  const hasDeps = plugin.dependencies.every((dep) => packageJson.dependencies?.[dep] ?? packageJson.devDependencies?.[dep] ?? '');
@@ -148,15 +236,23 @@ export const PluginManager = Object.freeze({
148
236
  /**
149
237
  * Install a plugin
150
238
  */
151
- async install(pluginId) {
239
+ async install(pluginId, options) {
152
240
  const { plugin } = getPluginOrThrow(pluginId);
153
241
  Logger.info(`Installing plugin: ${plugin.name}...`);
154
- // 1. Install dependencies
155
- npmInstall(plugin.dependencies, { dev: false, label: 'dependencies' });
156
- npmInstall(plugin.devDependencies, { dev: true, label: 'dev dependencies' });
242
+ // 1. Install dependencies (use SpawnUtil and support multiple package managers)
243
+ await npmInstall(plugin.dependencies, {
244
+ dev: false,
245
+ label: 'dependencies',
246
+ packageManager: options?.packageManager,
247
+ });
248
+ await npmInstall(plugin.devDependencies, {
249
+ dev: true,
250
+ label: 'dev dependencies',
251
+ packageManager: options?.packageManager,
252
+ });
157
253
  // 2. Copy templates
158
254
  await copyPluginTemplates(plugin);
159
- // 3. Post-Install
255
+ // 3. Post-Install (still executed via execSync - opt-in)
160
256
  runPostInstall(plugin);
161
257
  Logger.info(`✓ Plugin ${plugin.name} installed successfully`);
162
258
  },
@@ -1 +1 @@
1
- {"version":3,"file":"RuntimeDetector.d.ts","sourceRoot":"","sources":["../../../src/runtime/RuntimeDetector.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAyJzF,eAAO,MAAM,eAAe;;;yBA9GF,MAAM;4BAyBD,aAAa,KAAG,cAAc;uCAQnB,MAAM,UAAU,aAAa,KAAG,cAAc;0BAuD7D,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;EA6BhD,CAAC;AAuFH,eAAO,MAAM,oBAAoB;0BA7EE,eAAe,KAAG,OAAO,CAAC,IAAI,CAAC;wBAwDlC,MAAM,KAAe,OAAO,CAAC,IAAI,CAAC;iCAYhC,IAAI;EAapC,CAAC"}
1
+ {"version":3,"file":"RuntimeDetector.d.ts","sourceRoot":"","sources":["../../../src/runtime/RuntimeDetector.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAyJzF,eAAO,MAAM,eAAe;;;yBA9GF,MAAM;4BAyBD,aAAa,KAAG,cAAc;uCAQnB,MAAM,UAAU,aAAa,KAAG,cAAc;0BAuD7D,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;EA6BhD,CAAC;AA8IH,eAAO,MAAM,oBAAoB;0BAtGE,eAAe,KAAG,OAAO,CAAC,IAAI,CAAC;wBA0DlC,MAAM,KAAe,OAAO,CAAC,IAAI,CAAC;iCAmChC,IAAI;EAapC,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { Env } from '../config/env';
2
2
  import Logger from '../config/logger';
3
+ import { ErrorFactory } from '../exceptions/ZintrustError';
3
4
  import { CloudflareAdapter } from './adapters/CloudflareAdapter';
4
5
  import { DenoAdapter } from './adapters/DenoAdapter';
5
6
  import { FargateAdapter } from './adapters/FargateAdapter';
@@ -134,6 +135,26 @@ export const RuntimeDetector = Object.freeze({
134
135
  createAdapterForRuntime,
135
136
  getRuntimeInfo,
136
137
  });
138
+ const runtimeState = {
139
+ isShuttingDown: false,
140
+ };
141
+ const withTimeout = async (promise, timeoutMs, label) => {
142
+ if (timeoutMs <= 0)
143
+ return promise;
144
+ let timeoutId;
145
+ try {
146
+ const timeoutPromise = new Promise((_, reject) => {
147
+ timeoutId = globalThis.setTimeout(() => {
148
+ reject(ErrorFactory.createGeneralError(label, { timeoutMs }));
149
+ }, timeoutMs);
150
+ });
151
+ return await Promise.race([promise, timeoutPromise]);
152
+ }
153
+ finally {
154
+ if (timeoutId !== undefined)
155
+ globalThis.clearTimeout(timeoutId);
156
+ }
157
+ };
137
158
  /**
138
159
  * Application bootstrap factory
139
160
  * Creates and configures runtime-appropriate HTTP handler
@@ -150,6 +171,8 @@ const initialize = async (handler) => {
150
171
  };
151
172
  const runtime = detectRuntime();
152
173
  const adapter = createAdapterForRuntime(runtime, config);
174
+ runtimeState.adapter = adapter;
175
+ runtimeState.runtime = runtime;
153
176
  const logger = adapter.getLogger();
154
177
  const runtimeInfo = getRuntimeInfo();
155
178
  logger.info('Application initializing', runtimeInfo);
@@ -163,7 +186,7 @@ const initialize = async (handler) => {
163
186
  if (serverAdapter.startServer !== undefined) {
164
187
  await serverAdapter.startServer(port, host);
165
188
  }
166
- break;
189
+ return;
167
190
  }
168
191
  case 'deno': {
169
192
  const port = Env.PORT;
@@ -172,13 +195,13 @@ const initialize = async (handler) => {
172
195
  if (serverAdapter.startServer !== undefined) {
173
196
  await serverAdapter.startServer(port, host);
174
197
  }
175
- break;
198
+ return;
176
199
  }
177
200
  case 'lambda':
178
201
  case 'cloudflare':
179
202
  // These platforms handle request routing externally
180
203
  logger.info('Adapter initialized, ready for events');
181
- break;
204
+ return;
182
205
  }
183
206
  };
184
207
  /**
@@ -187,9 +210,27 @@ const initialize = async (handler) => {
187
210
  const shutdown = async (signal = 'SIGTERM') => {
188
211
  const logger = createDefaultLogger();
189
212
  logger.info(`Received ${signal}, gracefully shutting down...`);
190
- // Perform cleanup tasks
191
- process.exit(0);
192
- return Promise.resolve();
213
+ if (runtimeState.isShuttingDown) {
214
+ process.exit(0);
215
+ return;
216
+ }
217
+ runtimeState.isShuttingDown = true;
218
+ const timeoutMs = Number(Env.SHUTDOWN_TIMEOUT);
219
+ try {
220
+ const adapter = runtimeState.adapter;
221
+ if (typeof adapter?.stop === 'function') {
222
+ await withTimeout(adapter.stop(), timeoutMs, 'Runtime adapter shutdown timed out');
223
+ }
224
+ process.exit(0);
225
+ }
226
+ catch (error) {
227
+ logger.error('Graceful shutdown failed', error);
228
+ process.exit(1);
229
+ }
230
+ finally {
231
+ // In real runtimes `process.exit(...)` ends execution, but in tests it's mocked.
232
+ runtimeState.isShuttingDown = false;
233
+ }
193
234
  };
194
235
  /**
195
236
  * Setup graceful shutdown handlers
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Runtime adapter for Cloudflare Workers
3
3
  */
4
- import { Env } from '../../config/env';
4
+ import { appConfig } from '../../config';
5
5
  import { Logger } from '../../config/logger';
6
6
  import { createMockHttpObjects, ErrorResponse, HttpResponse, } from '../RuntimeAdapter';
7
7
  /**
@@ -101,7 +101,7 @@ async function handleCloudflareRequest(adapter, config, logger, event) {
101
101
  }
102
102
  catch (error) {
103
103
  Logger.error('Cloudflare handler error', error);
104
- const errorResponse = ErrorResponse.create(500, 'Internal Server Error', Env.NODE_ENV === 'development' ? { message: error.message } : undefined);
104
+ const errorResponse = ErrorResponse.create(500, 'Internal Server Error', appConfig.isDevelopment() ? { message: error.message } : undefined);
105
105
  return errorResponse.toResponse();
106
106
  }
107
107
  }
@@ -1 +1 @@
1
- {"version":3,"file":"FargateAdapter.d.ts","sourceRoot":"","sources":["../../../../src/runtime/adapters/FargateAdapter.ts"],"names":[],"mappings":"AAUA,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,MAAM,EACX,KAAK,cAAc,EACpB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EACV,aAAa,EAGb,cAAc,EACf,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,kBAAkB;IACjC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,iBAAiB,GAAG,CAC9B,eAAe,EAAE,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,KAAK,IAAI,KACjE,MAAM,CAAC;AAEZ,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,aAAa,GAAG,cAAc,GAAG;IAC5E,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB,CA2DA;AAED;;;;GAIG;AACH,eAAO,MAAM,cAAc;;EAEzB,CAAC;AAEH,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,mBAAmB,EAC1B,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,EAC/B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,aAAa,GAAE,iBAAgC,GAC9C,OAAO,CAAC,IAAI,CAAC,CAgBf;AAED,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,mBAAmB,EAC1B,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,GAC9B,OAAO,CAAC,IAAI,CAAC,CAgBf;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAgB1F;AAED,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,EAC/B,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,GAClB,OAAO,CAAC,IAAI,CAAC,CAuBf;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,CAIpD;AAED,wBAAgB,0BAA0B,IAAI,aAAa,CAAC,QAAQ,CAAC,CAUpE"}
1
+ {"version":3,"file":"FargateAdapter.d.ts","sourceRoot":"","sources":["../../../../src/runtime/adapters/FargateAdapter.ts"],"names":[],"mappings":"AAUA,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,MAAM,EACX,KAAK,cAAc,EACpB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EACV,aAAa,EAGb,cAAc,EACf,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,kBAAkB;IACjC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,iBAAiB,GAAG,CAC9B,eAAe,EAAE,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,KAAK,IAAI,KACjE,MAAM,CAAC;AAEZ,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,aAAa,GAAG,cAAc,GAAG;IAC5E,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB,CA0DA;AAED;;;;GAIG;AACH,eAAO,MAAM,cAAc;;EAEzB,CAAC;AAEH,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,mBAAmB,EAC1B,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,EAC/B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,aAAa,GAAE,iBAAgC,GAC9C,OAAO,CAAC,IAAI,CAAC,CAgBf;AAED,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,mBAAmB,EAC1B,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,GAC9B,OAAO,CAAC,IAAI,CAAC,CAgBf;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAgB1F;AAED,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,EAC/B,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,GAClB,OAAO,CAAC,IAAI,CAAC,CAuBf;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,CAIpD;AAED,wBAAgB,0BAA0B,IAAI,aAAa,CAAC,QAAQ,CAAC,CAUpE"}
@@ -14,10 +14,11 @@ export function createFargateAdapter(config) {
14
14
  const state = {};
15
15
  return {
16
16
  platform: 'fargate',
17
+ // eslint-disable-next-line @typescript-eslint/require-await
17
18
  async handle(_event, _context) {
18
19
  // Fargate adapter doesn't handle individual requests
19
20
  // Instead, use startServer() to run continuous HTTP server
20
- return Promise.reject(ErrorFactory.createConfigError('Fargate adapter requires startServer() method. Use RuntimeDetector for automatic initialization.'));
21
+ throw ErrorFactory.createConfigError('Fargate adapter requires startServer() method. Use RuntimeDetector for automatic initialization.');
21
22
  },
22
23
  parseRequest(_event) {
23
24
  throw ErrorFactory.createConfigError('Fargate adapter uses native Node.js HTTP server');
@@ -1 +1 @@
1
- {"version":3,"file":"LambdaAdapter.d.ts","sourceRoot":"","sources":["../../../../src/runtime/adapters/LambdaAdapter.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,aAAa,EAKb,cAAc,EACf,MAAM,yBAAyB,CAAC;AASjC;;;;GAIG;AACH,eAAO,MAAM,aAAa;IACxB;;OAEG;mBACY,aAAa,GAAG,cAAc;EA8D7C,CAAC"}
1
+ {"version":3,"file":"LambdaAdapter.d.ts","sourceRoot":"","sources":["../../../../src/runtime/adapters/LambdaAdapter.ts"],"names":[],"mappings":"AAYA,OAAO,EACL,aAAa,EAKb,cAAc,EACf,MAAM,yBAAyB,CAAC;AAEjC;;;;GAIG;AACH,eAAO,MAAM,aAAa;IACxB;;OAEG;mBACY,aAAa,GAAG,cAAc;EA8D7C,CAAC"}
@@ -3,8 +3,8 @@
3
3
  */
4
4
  import { Env } from '../../config/env';
5
5
  import { Logger } from '../../config/logger';
6
+ import { IncomingMessage, ServerResponse, } from '../../node-singletons/http';
6
7
  import { ErrorResponse, HttpResponse, } from '../RuntimeAdapter';
7
- import { IncomingMessage, ServerResponse, } from 'node:http';
8
8
  /**
9
9
  * AWS Lambda adapter for API Gateway and ALB events
10
10
  * Converts Lambda events to standard HTTP format for Zintrust framework
@@ -95,7 +95,9 @@ async function handleLambdaRequest(adapter, config, event, _context) {
95
95
  }
96
96
  catch (error) {
97
97
  Logger.error('Lambda handler error', error);
98
- const errorResponse = ErrorResponse.create(500, 'Internal Server Error', Env.NODE_ENV === 'development' ? { message: error.message } : undefined);
98
+ const nodeEnv = typeof Env.NODE_ENV === 'string' && Env.NODE_ENV !== '' ? Env.NODE_ENV : 'development';
99
+ const includeDetails = nodeEnv === 'development' || nodeEnv === 'dev';
100
+ const errorResponse = ErrorResponse.create(500, 'Internal Server Error', includeDetails ? { message: error.message } : undefined);
99
101
  return errorResponse.toResponse();
100
102
  }
101
103
  }