@zintrust/core 0.1.19 → 0.1.21

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 (528) hide show
  1. package/README.md +10 -10
  2. package/bin/zintrust-main.d.ts.map +1 -1
  3. package/bin/zintrust-main.js +9 -0
  4. package/package.json +3 -2
  5. package/public/error-pages/404.html +145 -0
  6. package/public/error-pages/500.html +266 -0
  7. package/public/error-pages/error.css +628 -0
  8. package/public/error-pages/error.js +428 -0
  9. package/public/zintrust.svg +30 -0
  10. package/routes/api.d.ts.map +1 -1
  11. package/routes/api.js +41 -17
  12. package/routes/metrics.d.ts +9 -0
  13. package/routes/metrics.d.ts.map +1 -0
  14. package/routes/metrics.js +20 -0
  15. package/routes/openapi.d.ts +9 -0
  16. package/routes/openapi.d.ts.map +1 -0
  17. package/routes/openapi.js +76 -0
  18. package/src/boot/Application.d.ts +2 -2
  19. package/src/boot/Application.d.ts.map +1 -1
  20. package/src/boot/Application.js +66 -13
  21. package/src/boot/Server.d.ts +3 -2
  22. package/src/boot/Server.d.ts.map +1 -1
  23. package/src/boot/Server.js +39 -165
  24. package/src/boot/bootstrap.js +2 -0
  25. package/src/cache/Cache.d.ts +1 -1
  26. package/src/cache/Cache.d.ts.map +1 -1
  27. package/src/cache/CacheDriver.d.ts +4 -0
  28. package/src/cache/CacheDriver.d.ts.map +1 -1
  29. package/src/cache/drivers/KVDriver.d.ts +1 -1
  30. package/src/cache/drivers/KVDriver.d.ts.map +1 -1
  31. package/src/cache/drivers/MemoryDriver.d.ts +1 -1
  32. package/src/cache/drivers/MemoryDriver.d.ts.map +1 -1
  33. package/src/cache/drivers/MemoryDriver.js +16 -0
  34. package/src/cache/drivers/MongoDriver.d.ts +1 -1
  35. package/src/cache/drivers/MongoDriver.d.ts.map +1 -1
  36. package/src/cache/drivers/RedisDriver.d.ts +1 -1
  37. package/src/cache/drivers/RedisDriver.d.ts.map +1 -1
  38. package/src/cli/CLI.d.ts.map +1 -1
  39. package/src/cli/CLI.js +10 -4
  40. package/src/cli/commands/AddCommand.d.ts +2 -2
  41. package/src/cli/commands/AddCommand.d.ts.map +1 -1
  42. package/src/cli/commands/AddCommand.js +135 -58
  43. package/src/cli/commands/ConfigCommand.d.ts +1 -1
  44. package/src/cli/commands/ConfigCommand.d.ts.map +1 -1
  45. package/src/cli/commands/CreateCommand.d.ts +15 -0
  46. package/src/cli/commands/CreateCommand.d.ts.map +1 -0
  47. package/src/cli/commands/CreateCommand.js +143 -0
  48. package/src/cli/commands/D1MigrateCommand.d.ts +1 -1
  49. package/src/cli/commands/D1MigrateCommand.d.ts.map +1 -1
  50. package/src/cli/commands/D1MigrateCommand.js +16 -20
  51. package/src/cli/commands/DbSeedCommand.d.ts +9 -0
  52. package/src/cli/commands/DbSeedCommand.d.ts.map +1 -0
  53. package/src/cli/commands/DbSeedCommand.js +171 -0
  54. package/src/cli/commands/DebugCommand.d.ts +1 -1
  55. package/src/cli/commands/DebugCommand.d.ts.map +1 -1
  56. package/src/cli/commands/FixCommand.d.ts +1 -1
  57. package/src/cli/commands/FixCommand.d.ts.map +1 -1
  58. package/src/cli/commands/JwtDevCommand.d.ts +8 -0
  59. package/src/cli/commands/JwtDevCommand.d.ts.map +1 -0
  60. package/src/cli/commands/JwtDevCommand.js +114 -0
  61. package/src/cli/commands/KeyGenerateCommand.d.ts +1 -1
  62. package/src/cli/commands/KeyGenerateCommand.d.ts.map +1 -1
  63. package/src/cli/commands/LogsCommand.d.ts +2 -2
  64. package/src/cli/commands/LogsCommand.d.ts.map +1 -1
  65. package/src/cli/commands/LogsCommand.js +36 -2
  66. package/src/cli/commands/MakeMailTemplateCommand.d.ts +1 -1
  67. package/src/cli/commands/MakeMailTemplateCommand.d.ts.map +1 -1
  68. package/src/cli/commands/MakeNotificationTemplateCommand.d.ts +1 -1
  69. package/src/cli/commands/MakeNotificationTemplateCommand.d.ts.map +1 -1
  70. package/src/cli/commands/MigrateCommand.d.ts +1 -1
  71. package/src/cli/commands/MigrateCommand.d.ts.map +1 -1
  72. package/src/cli/commands/MigrateCommand.js +324 -35
  73. package/src/cli/commands/NewCommand.d.ts +1 -1
  74. package/src/cli/commands/NewCommand.d.ts.map +1 -1
  75. package/src/cli/commands/NewCommand.js +12 -4
  76. package/src/cli/commands/PluginCommand.d.ts +1 -1
  77. package/src/cli/commands/PluginCommand.d.ts.map +1 -1
  78. package/src/cli/commands/PrepareCommand.d.ts +1 -1
  79. package/src/cli/commands/PrepareCommand.d.ts.map +1 -1
  80. package/src/cli/commands/QACommand.d.ts +2 -2
  81. package/src/cli/commands/QACommand.d.ts.map +1 -1
  82. package/src/cli/commands/RoutesCommand.d.ts +10 -0
  83. package/src/cli/commands/RoutesCommand.d.ts.map +1 -0
  84. package/src/cli/commands/RoutesCommand.js +242 -0
  85. package/src/cli/commands/SimulateCommand.d.ts +1 -1
  86. package/src/cli/commands/SimulateCommand.d.ts.map +1 -1
  87. package/src/cli/commands/index.d.ts +3 -0
  88. package/src/cli/commands/index.d.ts.map +1 -1
  89. package/src/cli/commands/index.js +3 -0
  90. package/src/cli/config/ConfigManager.d.ts +1 -1
  91. package/src/cli/config/ConfigManager.d.ts.map +1 -1
  92. package/src/cli/config/ConfigValidator.d.ts +1 -1
  93. package/src/cli/config/ConfigValidator.d.ts.map +1 -1
  94. package/src/cli/config/ConfigValidator.js +1 -1
  95. package/src/cli/d1/D1SqlMigrations.d.ts +20 -0
  96. package/src/cli/d1/D1SqlMigrations.d.ts.map +1 -0
  97. package/src/cli/d1/D1SqlMigrations.js +229 -0
  98. package/src/cli/d1/WranglerConfig.d.ts +4 -0
  99. package/src/cli/d1/WranglerConfig.d.ts.map +1 -0
  100. package/src/cli/d1/WranglerConfig.js +122 -0
  101. package/src/cli/d1/WranglerD1.d.ts +11 -0
  102. package/src/cli/d1/WranglerD1.d.ts.map +1 -0
  103. package/src/cli/d1/WranglerD1.js +16 -0
  104. package/src/cli/scaffolding/ControllerGenerator.d.ts.map +1 -1
  105. package/src/cli/scaffolding/ControllerGenerator.js +76 -26
  106. package/src/cli/scaffolding/FactoryGenerator.d.ts.map +1 -1
  107. package/src/cli/scaffolding/FactoryGenerator.js +3 -1
  108. package/src/cli/scaffolding/GovernanceScaffolder.d.ts +23 -0
  109. package/src/cli/scaffolding/GovernanceScaffolder.d.ts.map +1 -0
  110. package/src/cli/scaffolding/GovernanceScaffolder.js +327 -0
  111. package/src/cli/scaffolding/MigrationGenerator.d.ts +10 -0
  112. package/src/cli/scaffolding/MigrationGenerator.d.ts.map +1 -1
  113. package/src/cli/scaffolding/MigrationGenerator.js +137 -51
  114. package/src/cli/scaffolding/ModelGenerator.js +1 -1
  115. package/src/cli/scaffolding/ProjectScaffolder.d.ts.map +1 -1
  116. package/src/cli/scaffolding/ProjectScaffolder.js +36 -4
  117. package/src/cli/scaffolding/RouteGenerator.d.ts.map +1 -1
  118. package/src/cli/scaffolding/RouteGenerator.js +79 -43
  119. package/src/cli/scaffolding/SeederGenerator.d.ts +5 -0
  120. package/src/cli/scaffolding/SeederGenerator.d.ts.map +1 -1
  121. package/src/cli/scaffolding/SeederGenerator.js +63 -15
  122. package/src/cli/scaffolding/ServiceScaffolder.d.ts.map +1 -1
  123. package/src/cli/scaffolding/ServiceScaffolder.js +28 -7
  124. package/src/cli/scaffolding/index.d.ts +2 -0
  125. package/src/cli/scaffolding/index.d.ts.map +1 -1
  126. package/src/cli/scaffolding/index.js +1 -0
  127. package/src/common/index.d.ts +8 -0
  128. package/src/common/index.d.ts.map +1 -1
  129. package/src/common/index.js +28 -0
  130. package/src/common/utility.d.ts +38 -0
  131. package/src/common/utility.d.ts.map +1 -0
  132. package/src/common/utility.js +101 -0
  133. package/src/config/FileLogWriter.d.ts +2 -1
  134. package/src/config/FileLogWriter.d.ts.map +1 -1
  135. package/src/config/FileLogWriter.js +83 -2
  136. package/src/config/app.d.ts.map +1 -1
  137. package/src/config/app.js +3 -1
  138. package/src/config/broadcast.d.ts +14 -28
  139. package/src/config/broadcast.d.ts.map +1 -1
  140. package/src/config/broadcast.js +69 -35
  141. package/src/config/cache.d.ts +13 -45
  142. package/src/config/cache.d.ts.map +1 -1
  143. package/src/config/cache.js +69 -25
  144. package/src/config/cloudflare.d.ts +1 -1
  145. package/src/config/cloudflare.d.ts.map +1 -1
  146. package/src/config/database.d.ts +22 -64
  147. package/src/config/database.d.ts.map +1 -1
  148. package/src/config/database.js +191 -37
  149. package/src/config/env.d.ts +12 -0
  150. package/src/config/env.d.ts.map +1 -1
  151. package/src/config/env.js +14 -0
  152. package/src/config/index.d.ts +33 -137
  153. package/src/config/index.d.ts.map +1 -1
  154. package/src/config/logging/KvLogger.js +1 -1
  155. package/src/config/logging/SlackLogger.js +2 -2
  156. package/src/config/mail.d.ts +19 -55
  157. package/src/config/mail.d.ts.map +1 -1
  158. package/src/config/mail.js +63 -21
  159. package/src/config/middleware.d.ts +44 -1
  160. package/src/config/middleware.d.ts.map +1 -1
  161. package/src/config/middleware.js +157 -5
  162. package/src/config/notification.d.ts +14 -27
  163. package/src/config/notification.d.ts.map +1 -1
  164. package/src/config/notification.js +82 -36
  165. package/src/config/queue.d.ts +21 -51
  166. package/src/config/queue.d.ts.map +1 -1
  167. package/src/config/queue.js +72 -27
  168. package/src/config/security.d.ts +1 -1
  169. package/src/config/security.js +1 -1
  170. package/src/config/storage.d.ts +27 -34
  171. package/src/config/storage.d.ts.map +1 -1
  172. package/src/config/storage.js +97 -56
  173. package/src/config/type.d.ts +13 -2
  174. package/src/config/type.d.ts.map +1 -1
  175. package/src/events/EventDispatcher.d.ts.map +1 -1
  176. package/src/events/EventDispatcher.js +6 -4
  177. package/src/exceptions/ZintrustError.d.ts +7 -0
  178. package/src/exceptions/ZintrustError.d.ts.map +1 -1
  179. package/src/exceptions/ZintrustError.js +56 -0
  180. package/src/features/Auth.d.ts +1 -1
  181. package/src/features/Auth.d.ts.map +1 -1
  182. package/src/features/Auth.js +3 -3
  183. package/src/features/Queue.js +1 -1
  184. package/src/functions/cloudflare.d.ts.map +1 -1
  185. package/src/functions/cloudflare.js +3 -14
  186. package/src/functions/deno.d.ts.map +1 -1
  187. package/src/functions/deno.js +3 -14
  188. package/src/functions/lambda.d.ts.map +1 -1
  189. package/src/functions/lambda.js +3 -14
  190. package/src/health/StartupHealthChecks.js +1 -1
  191. package/src/http/Controller.d.ts +2 -2
  192. package/src/http/Controller.d.ts.map +1 -1
  193. package/src/http/FileUpload.d.ts +68 -0
  194. package/src/http/FileUpload.d.ts.map +1 -0
  195. package/src/http/FileUpload.js +120 -0
  196. package/src/http/Kernel.d.ts +5 -5
  197. package/src/http/Kernel.d.ts.map +1 -1
  198. package/src/http/Kernel.js +139 -23
  199. package/src/http/Request.d.ts +20 -1
  200. package/src/http/Request.d.ts.map +1 -1
  201. package/src/http/Request.js +23 -0
  202. package/src/http/RequestContext.d.ts +6 -0
  203. package/src/http/RequestContext.d.ts.map +1 -1
  204. package/src/http/RequestContext.js +77 -1
  205. package/src/http/Response.d.ts +1 -1
  206. package/src/http/Response.d.ts.map +1 -1
  207. package/src/http/ValidationHelper.d.ts +78 -0
  208. package/src/http/ValidationHelper.d.ts.map +1 -0
  209. package/src/http/ValidationHelper.js +121 -0
  210. package/src/http/error-pages/ErrorPageRenderer.d.ts +17 -0
  211. package/src/http/error-pages/ErrorPageRenderer.d.ts.map +1 -0
  212. package/src/http/error-pages/ErrorPageRenderer.js +88 -0
  213. package/src/http/middleware/BodyParsingMiddleware.d.ts +12 -0
  214. package/src/http/middleware/BodyParsingMiddleware.d.ts.map +1 -0
  215. package/src/http/middleware/BodyParsingMiddleware.js +251 -0
  216. package/src/http/middleware/FileUploadMiddleware.d.ts +12 -0
  217. package/src/http/middleware/FileUploadMiddleware.d.ts.map +1 -0
  218. package/src/http/middleware/FileUploadMiddleware.js +74 -0
  219. package/src/http/parsers/BodyParsers.d.ts +32 -0
  220. package/src/http/parsers/BodyParsers.d.ts.map +1 -0
  221. package/src/http/parsers/BodyParsers.js +159 -0
  222. package/src/http/parsers/MultipartParser.d.ts +33 -0
  223. package/src/http/parsers/MultipartParser.d.ts.map +1 -0
  224. package/src/http/parsers/MultipartParser.js +156 -0
  225. package/src/http/parsers/MultipartParserRegistry.d.ts +34 -0
  226. package/src/http/parsers/MultipartParserRegistry.d.ts.map +1 -0
  227. package/src/http/parsers/MultipartParserRegistry.js +20 -0
  228. package/src/http/validated.d.ts +12 -0
  229. package/src/http/validated.d.ts.map +1 -0
  230. package/src/http/validated.js +41 -0
  231. package/src/index.d.ts +73 -12
  232. package/src/index.d.ts.map +1 -1
  233. package/src/index.js +60 -5
  234. package/src/microservices/PostgresAdapter.d.ts.map +1 -1
  235. package/src/microservices/PostgresAdapter.js +0 -1
  236. package/src/microservices/RequestTracingMiddleware.d.ts +2 -2
  237. package/src/microservices/RequestTracingMiddleware.d.ts.map +1 -1
  238. package/src/microservices/RequestTracingMiddleware.js +3 -0
  239. package/src/microservices/ServiceAuthMiddleware.d.ts +2 -2
  240. package/src/microservices/ServiceAuthMiddleware.d.ts.map +1 -1
  241. package/src/middleware/AuthMiddleware.d.ts +10 -0
  242. package/src/middleware/AuthMiddleware.d.ts.map +1 -0
  243. package/src/middleware/AuthMiddleware.js +16 -0
  244. package/src/middleware/CsrfMiddleware.d.ts +11 -1
  245. package/src/middleware/CsrfMiddleware.d.ts.map +1 -1
  246. package/src/middleware/CsrfMiddleware.js +33 -0
  247. package/src/middleware/JwtAuthMiddleware.d.ts +11 -0
  248. package/src/middleware/JwtAuthMiddleware.d.ts.map +1 -0
  249. package/src/middleware/JwtAuthMiddleware.js +73 -0
  250. package/src/middleware/LoggingMiddleware.d.ts.map +1 -1
  251. package/src/middleware/LoggingMiddleware.js +8 -3
  252. package/src/middleware/MiddlewareStack.d.ts +2 -2
  253. package/src/middleware/MiddlewareStack.d.ts.map +1 -1
  254. package/src/middleware/RateLimiter.d.ts +2 -2
  255. package/src/middleware/RateLimiter.d.ts.map +1 -1
  256. package/src/middleware/SanitizeBodyMiddleware.d.ts +12 -0
  257. package/src/middleware/SanitizeBodyMiddleware.d.ts.map +1 -0
  258. package/src/middleware/SanitizeBodyMiddleware.js +31 -0
  259. package/src/middleware/SecurityMiddleware.d.ts +1 -1
  260. package/src/middleware/SecurityMiddleware.d.ts.map +1 -1
  261. package/src/middleware/SessionMiddleware.d.ts +1 -1
  262. package/src/middleware/SessionMiddleware.d.ts.map +1 -1
  263. package/src/middleware/ValidationMiddleware.d.ts +25 -0
  264. package/src/middleware/ValidationMiddleware.d.ts.map +1 -0
  265. package/src/middleware/ValidationMiddleware.js +251 -0
  266. package/src/migrations/MigrationDiscovery.d.ts +5 -0
  267. package/src/migrations/MigrationDiscovery.d.ts.map +1 -0
  268. package/src/migrations/MigrationDiscovery.js +16 -0
  269. package/src/migrations/MigrationLoader.d.ts +5 -0
  270. package/src/migrations/MigrationLoader.d.ts.map +1 -0
  271. package/src/migrations/MigrationLoader.js +43 -0
  272. package/src/migrations/MigrationLock.d.ts +4 -0
  273. package/src/migrations/MigrationLock.d.ts.map +1 -0
  274. package/src/migrations/MigrationLock.js +33 -0
  275. package/src/migrations/Migrator.d.ts +23 -0
  276. package/src/migrations/Migrator.d.ts.map +1 -0
  277. package/src/migrations/Migrator.js +4 -0
  278. package/src/migrations/MigratorFactory.d.ts +25 -0
  279. package/src/migrations/MigratorFactory.d.ts.map +1 -0
  280. package/src/migrations/MigratorFactory.js +339 -0
  281. package/src/migrations/schema/Blueprint.d.ts +5 -0
  282. package/src/migrations/schema/Blueprint.d.ts.map +1 -0
  283. package/src/migrations/schema/Blueprint.js +189 -0
  284. package/src/migrations/schema/Schema.d.ts +8 -0
  285. package/src/migrations/schema/Schema.d.ts.map +1 -0
  286. package/src/migrations/schema/Schema.js +141 -0
  287. package/src/migrations/schema/SchemaCompiler.d.ts +20 -0
  288. package/src/migrations/schema/SchemaCompiler.d.ts.map +1 -0
  289. package/src/migrations/schema/SchemaCompiler.js +262 -0
  290. package/src/migrations/schema/index.d.ts +5 -0
  291. package/src/migrations/schema/index.d.ts.map +1 -0
  292. package/src/migrations/schema/index.js +3 -0
  293. package/src/migrations/schema/types.d.ts +86 -0
  294. package/src/migrations/schema/types.d.ts.map +1 -0
  295. package/src/migrations/schema/types.js +1 -0
  296. package/src/migrations/types.d.ts +45 -0
  297. package/src/migrations/types.d.ts.map +1 -0
  298. package/src/migrations/types.js +1 -0
  299. package/src/node-singletons/crypto.d.ts +1 -1
  300. package/src/node-singletons/crypto.d.ts.map +1 -1
  301. package/src/node-singletons/crypto.js +1 -1
  302. package/src/node-singletons/fs.d.ts +2 -2
  303. package/src/node-singletons/fs.d.ts.map +1 -1
  304. package/src/node-singletons/fs.js +1 -1
  305. package/src/node-singletons/util.d.ts +6 -0
  306. package/src/node-singletons/util.d.ts.map +1 -0
  307. package/src/node-singletons/util.js +5 -0
  308. package/src/node.d.ts +3 -1
  309. package/src/node.d.ts.map +1 -1
  310. package/src/node.js +6 -2
  311. package/src/observability/OpenTelemetry.d.ts +62 -0
  312. package/src/observability/OpenTelemetry.d.ts.map +1 -0
  313. package/src/observability/OpenTelemetry.js +167 -0
  314. package/src/observability/PrometheusMetrics.d.ts +25 -0
  315. package/src/observability/PrometheusMetrics.d.ts.map +1 -0
  316. package/src/observability/PrometheusMetrics.js +114 -0
  317. package/src/openapi/OpenApiGenerator.d.ts +68 -0
  318. package/src/openapi/OpenApiGenerator.d.ts.map +1 -0
  319. package/src/openapi/OpenApiGenerator.js +287 -0
  320. package/src/orm/Database.d.ts +5 -2
  321. package/src/orm/Database.d.ts.map +1 -1
  322. package/src/orm/Database.js +219 -63
  323. package/src/orm/DatabaseAdapter.d.ts +14 -0
  324. package/src/orm/DatabaseAdapter.d.ts.map +1 -1
  325. package/src/orm/DatabaseAdapterRegistry.d.ts.map +1 -1
  326. package/src/orm/DatabaseAdapterRegistry.js +3 -1
  327. package/src/orm/DatabaseRuntimeRegistration.d.ts.map +1 -1
  328. package/src/orm/DatabaseRuntimeRegistration.js +12 -0
  329. package/src/orm/Model.d.ts +30 -2
  330. package/src/orm/Model.d.ts.map +1 -1
  331. package/src/orm/Model.js +255 -62
  332. package/src/orm/QueryBuilder.d.ts +22 -1
  333. package/src/orm/QueryBuilder.d.ts.map +1 -1
  334. package/src/orm/QueryBuilder.js +406 -99
  335. package/src/orm/Relationships.d.ts +7 -1
  336. package/src/orm/Relationships.d.ts.map +1 -1
  337. package/src/orm/Relationships.js +18 -0
  338. package/src/orm/SchemaCompiler.d.ts +9 -0
  339. package/src/orm/SchemaCompiler.d.ts.map +1 -0
  340. package/src/orm/SchemaCompiler.js +145 -0
  341. package/src/orm/adapters/D1Adapter.d.ts +1 -1
  342. package/src/orm/adapters/D1Adapter.d.ts.map +1 -1
  343. package/src/orm/adapters/MySQLAdapter.d.ts +1 -1
  344. package/src/orm/adapters/MySQLAdapter.d.ts.map +1 -1
  345. package/src/orm/adapters/MySQLAdapter.js +88 -69
  346. package/src/orm/adapters/PostgreSQLAdapter.d.ts +1 -1
  347. package/src/orm/adapters/PostgreSQLAdapter.d.ts.map +1 -1
  348. package/src/orm/adapters/PostgreSQLAdapter.js +88 -69
  349. package/src/orm/adapters/SQLServerAdapter.d.ts +1 -1
  350. package/src/orm/adapters/SQLServerAdapter.d.ts.map +1 -1
  351. package/src/orm/adapters/SQLiteAdapter.d.ts +1 -1
  352. package/src/orm/adapters/SQLiteAdapter.d.ts.map +1 -1
  353. package/src/orm/adapters/SQLiteAdapter.js +59 -3
  354. package/src/orm/maintenance/SqliteMaintenance.d.ts +5 -0
  355. package/src/orm/maintenance/SqliteMaintenance.d.ts.map +1 -0
  356. package/src/orm/maintenance/SqliteMaintenance.js +14 -0
  357. package/src/orm/migrations/MigrationStore.d.ts +38 -0
  358. package/src/orm/migrations/MigrationStore.d.ts.map +1 -0
  359. package/src/orm/migrations/MigrationStore.js +157 -0
  360. package/src/performance/CodeGenerationBenchmark.d.ts.map +1 -1
  361. package/src/performance/Optimizer.d.ts +7 -6
  362. package/src/performance/Optimizer.d.ts.map +1 -1
  363. package/src/performance/Optimizer.js +170 -55
  364. package/src/profiling/MemoryProfiler.d.ts +1 -1
  365. package/src/profiling/MemoryProfiler.d.ts.map +1 -1
  366. package/src/profiling/N1Detector.d.ts +1 -1
  367. package/src/profiling/N1Detector.d.ts.map +1 -1
  368. package/src/profiling/QueryLogger.d.ts +1 -1
  369. package/src/profiling/QueryLogger.d.ts.map +1 -1
  370. package/src/profiling/RequestProfiler.d.ts +3 -3
  371. package/src/profiling/RequestProfiler.d.ts.map +1 -1
  372. package/src/routes/metrics.d.ts +2 -0
  373. package/src/routes/metrics.d.ts.map +1 -0
  374. package/src/routes/metrics.js +1 -0
  375. package/src/routing/CoreRoutes.d.ts +12 -0
  376. package/src/routing/CoreRoutes.d.ts.map +1 -0
  377. package/src/routing/CoreRoutes.js +151 -0
  378. package/src/routing/RouteRegistry.d.ts +39 -0
  379. package/src/routing/RouteRegistry.d.ts.map +1 -0
  380. package/src/routing/RouteRegistry.js +44 -0
  381. package/src/routing/Router.d.ts +26 -9
  382. package/src/routing/Router.d.ts.map +1 -1
  383. package/src/routing/Router.js +79 -35
  384. package/src/routing/common.d.ts +15 -0
  385. package/src/routing/common.d.ts.map +1 -0
  386. package/src/routing/common.js +47 -0
  387. package/src/routing/doc.d.ts +27 -0
  388. package/src/routing/doc.d.ts.map +1 -0
  389. package/src/routing/doc.js +110 -0
  390. package/src/routing/error.d.ts +21 -0
  391. package/src/routing/error.d.ts.map +1 -0
  392. package/src/routing/error.js +126 -0
  393. package/src/routing/errorPages.d.ts +14 -0
  394. package/src/routing/errorPages.d.ts.map +1 -0
  395. package/src/routing/errorPages.js +103 -0
  396. package/src/routing/publicRoot.d.ts +27 -0
  397. package/src/routing/publicRoot.d.ts.map +1 -0
  398. package/src/routing/publicRoot.js +110 -0
  399. package/src/runtime/PluginAutoImports.d.ts +21 -0
  400. package/src/runtime/PluginAutoImports.d.ts.map +1 -0
  401. package/src/runtime/PluginAutoImports.js +59 -0
  402. package/src/runtime/PluginManager.d.ts +1 -5
  403. package/src/runtime/PluginManager.d.ts.map +1 -1
  404. package/src/runtime/PluginManager.js +25 -18
  405. package/src/runtime/RuntimeDetector.d.ts +1 -1
  406. package/src/runtime/RuntimeDetector.d.ts.map +1 -1
  407. package/src/runtime/StartupConfigFileRegistry.d.ts +20 -0
  408. package/src/runtime/StartupConfigFileRegistry.d.ts.map +1 -0
  409. package/src/runtime/StartupConfigFileRegistry.js +44 -0
  410. package/src/runtime/adapters/CloudflareAdapter.d.ts +1 -1
  411. package/src/runtime/adapters/CloudflareAdapter.d.ts.map +1 -1
  412. package/src/runtime/adapters/CloudflareAdapter.js +1 -1
  413. package/src/runtime/adapters/DenoAdapter.d.ts +1 -1
  414. package/src/runtime/adapters/DenoAdapter.d.ts.map +1 -1
  415. package/src/runtime/adapters/DenoAdapter.js +1 -1
  416. package/src/runtime/adapters/LambdaAdapter.d.ts +1 -1
  417. package/src/runtime/adapters/LambdaAdapter.d.ts.map +1 -1
  418. package/src/runtime/adapters/LambdaAdapter.js +1 -1
  419. package/src/runtime/adapters/NodeServerAdapter.d.ts +1 -1
  420. package/src/runtime/adapters/NodeServerAdapter.d.ts.map +1 -1
  421. package/src/runtime/getKernel.d.ts +9 -0
  422. package/src/runtime/getKernel.d.ts.map +1 -0
  423. package/src/runtime/getKernel.js +27 -0
  424. package/src/runtime/useFileLoader.d.ts +26 -0
  425. package/src/runtime/useFileLoader.d.ts.map +1 -0
  426. package/src/runtime/useFileLoader.js +188 -0
  427. package/src/scripts/TemplateImportsCheck.js +40 -0
  428. package/src/scripts/TemplateSync.js +90 -24
  429. package/src/security/Encryptor.d.ts.map +1 -1
  430. package/src/security/Encryptor.js +64 -7
  431. package/src/security/JwtManager.d.ts +1 -0
  432. package/src/security/JwtManager.d.ts.map +1 -1
  433. package/src/security/JwtManager.js +33 -0
  434. package/src/security/Sanitizer.d.ts +76 -0
  435. package/src/security/Sanitizer.d.ts.map +1 -0
  436. package/src/security/Sanitizer.js +412 -0
  437. package/src/security/TokenRevocation.d.ts +7 -0
  438. package/src/security/TokenRevocation.d.ts.map +1 -0
  439. package/src/security/TokenRevocation.js +57 -0
  440. package/src/security/XssProtection.d.ts.map +1 -1
  441. package/src/security/XssProtection.js +62 -14
  442. package/src/seeders/SeederDiscovery.d.ts +5 -0
  443. package/src/seeders/SeederDiscovery.d.ts.map +1 -0
  444. package/src/seeders/SeederDiscovery.js +21 -0
  445. package/src/seeders/SeederLoader.d.ts +5 -0
  446. package/src/seeders/SeederLoader.d.ts.map +1 -0
  447. package/src/seeders/SeederLoader.js +60 -0
  448. package/src/seeders/types.d.ts +18 -0
  449. package/src/seeders/types.d.ts.map +1 -0
  450. package/src/seeders/types.js +1 -0
  451. package/src/session/SessionManager.js +1 -1
  452. package/src/templates/adapters/MySQLAdapter.ts.tpl +109 -85
  453. package/src/templates/adapters/PostgreSQLAdapter.ts.tpl +129 -88
  454. package/src/templates/adapters/SQLServerAdapter.ts.tpl +5 -9
  455. package/src/templates/adapters/SQLiteAdapter.ts.tpl +78 -11
  456. package/src/templates/features/Queue.ts.tpl +3 -2
  457. package/src/templates/project/basic/app/Controllers/AuthController.ts.tpl +217 -0
  458. package/src/templates/project/basic/app/Controllers/UserController.ts.tpl +1 -12
  459. package/src/templates/project/basic/app/Types/controller.ts.tpl +46 -0
  460. package/src/templates/project/basic/config/FileLogWriter.ts.tpl +5 -236
  461. package/src/templates/project/basic/config/SecretsManager.ts.tpl +10 -447
  462. package/src/templates/project/basic/config/StartupConfigValidator.ts.tpl +9 -268
  463. package/src/templates/project/basic/config/app.ts.tpl +13 -153
  464. package/src/templates/project/basic/config/broadcast.ts.tpl +29 -126
  465. package/src/templates/project/basic/config/cache.ts.tpl +12 -70
  466. package/src/templates/project/basic/config/cloudflare.ts.tpl +4 -39
  467. package/src/templates/project/basic/config/constants.ts.tpl +9 -65
  468. package/src/templates/project/basic/config/database.ts.tpl +66 -123
  469. package/src/templates/project/basic/config/env.ts.tpl +5 -169
  470. package/src/templates/project/basic/config/features.ts.tpl +6 -54
  471. package/src/templates/project/basic/config/index.ts.tpl +8 -23
  472. package/src/templates/project/basic/config/logging/HttpLogger.ts.tpl +7 -114
  473. package/src/templates/project/basic/config/mail.ts.tpl +9 -62
  474. package/src/templates/project/basic/config/microservices.ts.tpl +11 -97
  475. package/src/templates/project/basic/config/middleware.ts.tpl +25 -43
  476. package/src/templates/project/basic/config/notification.ts.tpl +13 -114
  477. package/src/templates/project/basic/config/queue.ts.tpl +9 -40
  478. package/src/templates/project/basic/config/security.ts.tpl +11 -163
  479. package/src/templates/project/basic/config/startup.ts.tpl +10 -21
  480. package/src/templates/project/basic/config/storage.ts.tpl +57 -137
  481. package/src/templates/project/basic/config/type.ts.tpl +32 -451
  482. package/src/templates/project/basic/database/factories/UserFactory.ts.tpl +80 -0
  483. package/src/templates/project/basic/database/migrations/create_tasks_table.ts.tpl +28 -0
  484. package/src/templates/project/basic/database/migrations/create_users_table.ts.tpl +29 -0
  485. package/src/templates/project/basic/database/seeders/DatabaseSeeder.ts.tpl +19 -0
  486. package/src/templates/project/basic/database/seeders/UserSeeder.ts.tpl +18 -0
  487. package/src/templates/project/basic/database/seeders/index.ts.tpl +2 -0
  488. package/src/templates/project/basic/routes/api.ts.tpl +71 -33
  489. package/src/templates/project/basic/routes/metrics.ts.tpl +22 -0
  490. package/src/templates/project/basic/src/index.ts.tpl +3 -0
  491. package/src/templates/project/basic/tsconfig.json.tpl +12 -11
  492. package/src/testing/TestEnvironment.d.ts +40 -0
  493. package/src/testing/TestEnvironment.d.ts.map +1 -0
  494. package/src/testing/TestEnvironment.js +141 -0
  495. package/src/testing/TestHttp.d.ts +29 -0
  496. package/src/testing/TestHttp.d.ts.map +1 -0
  497. package/src/testing/TestHttp.js +96 -0
  498. package/src/testing/index.d.ts +5 -0
  499. package/src/testing/index.d.ts.map +1 -0
  500. package/src/testing/index.js +2 -0
  501. package/src/time/DateTime.d.ts +181 -0
  502. package/src/time/DateTime.d.ts.map +1 -0
  503. package/src/time/DateTime.js +300 -0
  504. package/src/time/index.d.ts +7 -0
  505. package/src/time/index.d.ts.map +1 -0
  506. package/src/time/index.js +5 -0
  507. package/src/tools/http/Http.d.ts.map +1 -1
  508. package/src/tools/http/Http.js +4 -0
  509. package/src/tools/mail/drivers/Smtp.js +1 -1
  510. package/src/tools/queue/drivers/InMemory.d.ts +1 -1
  511. package/src/tools/queue/drivers/InMemory.d.ts.map +1 -1
  512. package/src/tools/queue/drivers/InMemory.js +1 -1
  513. package/src/tools/queue/drivers/Redis.d.ts +1 -1
  514. package/src/tools/queue/drivers/Redis.d.ts.map +1 -1
  515. package/src/tools/queue/drivers/Redis.js +1 -1
  516. package/src/validation/ValidationError.d.ts.map +1 -1
  517. package/src/validation/ValidationError.js +4 -2
  518. package/src/validation/Validator.d.ts +49 -16
  519. package/src/validation/Validator.d.ts.map +1 -1
  520. package/src/validation/Validator.js +307 -5
  521. package/src/common/uuid.d.ts +0 -3
  522. package/src/common/uuid.d.ts.map +0 -1
  523. package/src/common/uuid.js +0 -30
  524. package/src/templates/project/basic/.env.example.tpl +0 -74
  525. package/src/templates/project/basic/.env.tpl +0 -166
  526. package/src/templates/project/basic/config/logging/KvLogger.ts.tpl +0 -181
  527. package/src/templates/project/basic/config/logging/SlackLogger.ts.tpl +0 -156
  528. package/src/templates/project/basic/database/migrations/index.ts.tpl +0 -2
@@ -1,6 +1,7 @@
1
1
  // TEMPLATE_START
2
2
 
3
- import { generateSecureJobId, Logger } from '@zintrust/core';
3
+ import { generateSecureJobId } from '@zintrust/core';
4
+ import { Logger } from '@zintrust/core';
4
5
 
5
6
  export interface QueueJob {
6
7
  id: string;
@@ -43,4 +44,4 @@ export const Queue = Object.freeze({
43
44
  },
44
45
  });
45
46
 
46
- // TEMPLATE_END
47
+ // TEMPLATE_END
@@ -0,0 +1,217 @@
1
+ /**
2
+ * Auth Controller
3
+ * Minimal, real auth endpoints backing the example API routes.
4
+ */
5
+
6
+ import {
7
+ getString,
8
+ Auth,
9
+ Logger,
10
+ getValidatedBody,
11
+ useDatabase,
12
+ QueryBuilder,
13
+ JwtManager,
14
+ TokenRevocation
15
+ } from '@zintrust/core';
16
+ import type { AuthControllerApi, JsonRecord, UserRow } from '@app/Types/controller';
17
+ import type { IRequest, IResponse } from '@zintrust/core';
18
+ import User from '@app/Models/User';
19
+
20
+
21
+ const pickPublicUser = (row: UserRow): { id: unknown; name: string; email: string } => {
22
+ return {
23
+ id: row.id,
24
+ name: getString(row.name),
25
+ email: getString(row.email),
26
+ };
27
+ };
28
+
29
+ /**
30
+ * Authenticates a user by email and password.
31
+ * Validates credentials against the database and returns a JWT access token on success.
32
+ * Logs all authentication attempts for security auditing.
33
+ * @param req - HTTP request containing email and password
34
+ * @param res - HTTP response to send authentication result
35
+ * @returns Promise that resolves after sending the response
36
+ */
37
+ async function login(req: IRequest, res: IResponse): Promise<void> {
38
+ const body = getValidatedBody<JsonRecord>(req);
39
+ if (!body) {
40
+ Logger.error('AuthController.login: validation middleware did not populate req.validated.body');
41
+ return res.setStatus(500).json({ error: 'Internal server error' });
42
+ }
43
+ const email = getString(body['email']);
44
+ const password = getString(body['password']);
45
+ const ipAddress = req.getRaw().socket.remoteAddress ?? 'unknown';
46
+
47
+ try {
48
+ const existing = await User.where('email', '=', email).limit(1).first<UserRow>();
49
+
50
+ if (existing === null) {
51
+ Logger.warn('AuthController.login: failed login attempt', {
52
+ email,
53
+ ip: ipAddress,
54
+ reason: 'user_not_found',
55
+ timestamp: new Date().toISOString(),
56
+ });
57
+ res.setStatus(401).json({ error: 'Invalid credentials' });
58
+ return;
59
+ }
60
+
61
+ const passwordHash = getString(existing.password);
62
+ const ok = await Auth.compare(password, passwordHash);
63
+ if (!ok) {
64
+ Logger.warn('AuthController.login: failed login attempt', {
65
+ email,
66
+ ip: ipAddress,
67
+ reason: 'invalid_password',
68
+ timestamp: new Date().toISOString(),
69
+ });
70
+ res.setStatus(401).json({ error: 'Invalid credentials' });
71
+ return;
72
+ }
73
+
74
+ const user = pickPublicUser(existing);
75
+
76
+ const subject = ((): string | undefined => {
77
+ const id = user.id;
78
+ if (typeof id === 'string' && id.length > 0) return id;
79
+ if (typeof id === 'number' && Number.isFinite(id)) return String(id);
80
+ return undefined;
81
+ })();
82
+
83
+ const token = JwtManager.signAccessToken({
84
+ sub: subject,
85
+ email,
86
+ });
87
+
88
+ Logger.info('AuthController.login: successful login', {
89
+ userId: subject,
90
+ email,
91
+ ip: ipAddress,
92
+ timestamp: new Date().toISOString(),
93
+ });
94
+
95
+ res.json({
96
+ token,
97
+ token_type: 'Bearer',
98
+ user,
99
+ });
100
+ } catch (error) {
101
+ Logger.error('AuthController.login: unexpected error', {
102
+ email,
103
+ ip: ipAddress,
104
+ error: error instanceof Error ? error.message : String(error),
105
+ timestamp: new Date().toISOString(),
106
+ });
107
+ res.setStatus(500).json({ error: 'Login failed' });
108
+ }
109
+ }
110
+
111
+ /**
112
+ * Registers a new user with name, email, and password.
113
+ * Validates email uniqueness, hashes password, and stores user in database.
114
+ * Returns 201 on success, 409 if email already exists.
115
+ * @param req - HTTP request containing name, email, and password
116
+ * @param res - HTTP response to send registration result
117
+ * @returns Promise that resolves after sending the response
118
+ */
119
+ async function register(req: IRequest, res: IResponse): Promise<void> {
120
+ const body = getValidatedBody<JsonRecord>(req);
121
+ if (!body) {
122
+ Logger.error(
123
+ 'AuthController.register: validation middleware did not populate req.validated.body'
124
+ );
125
+ res.setStatus(500).json({ error: 'Internal server error' });
126
+ return;
127
+ }
128
+ const name = getString(body['name']);
129
+ const email = getString(body['email']);
130
+ const password = getString(body['password']);
131
+ const ipAddress = req.getRaw().socket.remoteAddress ?? 'unknown';
132
+
133
+ try {
134
+ const db = useDatabase();
135
+
136
+ const existing = await QueryBuilder.create('users', db)
137
+ .where('email', '=', email)
138
+ .limit(1)
139
+ .first<UserRow>();
140
+
141
+ if (existing !== null) {
142
+ Logger.warn('AuthController.register: duplicate email attempt', {
143
+ email,
144
+ ip: ipAddress,
145
+ timestamp: new Date().toISOString(),
146
+ });
147
+ res.setStatus(409).json({ error: 'Email already registered' });
148
+ return;
149
+ }
150
+
151
+ const passwordHash = await Auth.hash(password);
152
+
153
+ await QueryBuilder.create('users', db).insert({
154
+ name,
155
+ email,
156
+ password: passwordHash,
157
+ });
158
+
159
+ Logger.info('AuthController.register: successful registration', {
160
+ email,
161
+ ip: ipAddress,
162
+ timestamp: new Date().toISOString(),
163
+ });
164
+
165
+ res.setStatus(201).json({ message: 'Registered' });
166
+ } catch (error) {
167
+ Logger.error('AuthController.register failed', error);
168
+ res.setStatus(500).json({ error: 'Registration failed' });
169
+ }
170
+ }
171
+
172
+ /**
173
+ * Logs out the current user by revoking their JWT token.
174
+ * Extracts authorization header and marks token as revoked.
175
+ * Requires persistent token revocation store for stateless JWT validation.
176
+ * @param req - HTTP request containing authorization header with JWT token
177
+ * @param res - HTTP response to send logout confirmation
178
+ * @returns Promise that resolves after sending the response
179
+ */
180
+ async function logout(req: IRequest, res: IResponse): Promise<void> {
181
+ const authHeader =
182
+ typeof req.getHeader === 'function' ? req.getHeader('authorization') : undefined;
183
+ TokenRevocation.revoke(authHeader);
184
+ res.json({ message: 'Logged out' });
185
+ }
186
+
187
+ /**
188
+ * Refreshes the user's JWT access token.
189
+ * Generates a new token with the same claims as the current user.
190
+ * Returns 401 if user is not authenticated.
191
+ * @param req - HTTP request with user populated by authentication middleware
192
+ * @param res - HTTP response to send refreshed token
193
+ * @returns Promise that resolves after sending the response
194
+ */
195
+ async function refresh(req: IRequest, res: IResponse): Promise<void> {
196
+ const user = req.user;
197
+ if (user === undefined) {
198
+ res.setStatus(401).json({ error: 'Unauthorized' });
199
+ return;
200
+ }
201
+
202
+ const token = JwtManager.signAccessToken(user);
203
+ res.json({ token, token_type: 'Bearer' });
204
+ }
205
+
206
+ export const AuthController = Object.freeze({
207
+ create(): AuthControllerApi {
208
+ return {
209
+ login,
210
+ register,
211
+ logout,
212
+ refresh,
213
+ };
214
+ },
215
+ });
216
+
217
+ export default AuthController;
@@ -5,19 +5,8 @@
5
5
 
6
6
  import { User } from '@app/Models/User';
7
7
  import { IRequest, Logger, IResponse } from '@zintrust/core';
8
+ import { IUserController } from '@app/Types/controller';
8
9
 
9
- /**
10
- * User Controller Interface
11
- */
12
- export interface IUserController {
13
- index(req: IRequest, res: IResponse): Promise<void>;
14
- show(req: IRequest, res: IResponse): Promise<void>;
15
- create(req: IRequest, res: IResponse): Promise<void>;
16
- store(req: IRequest, res: IResponse): Promise<void>;
17
- edit(req: IRequest, res: IResponse): Promise<void>;
18
- update(req: IRequest, res: IResponse): Promise<void>;
19
- destroy(req: IRequest, res: IResponse): Promise<void>;
20
- }
21
10
 
22
11
  /**
23
12
  * User Controller Methods
@@ -0,0 +1,46 @@
1
+ import type { IRequest, IResponse } from '@zintrust/core';
2
+
3
+ export type JsonRecord = Record<string, unknown>;
4
+
5
+ export type LoginBody = {
6
+ email: string;
7
+ password: string;
8
+ };
9
+
10
+ export type RegisterBody = {
11
+ name: string;
12
+ email: string;
13
+ password: string;
14
+ };
15
+
16
+ export type UserRow = {
17
+ id?: unknown;
18
+ name?: unknown;
19
+ email?: unknown;
20
+ password?: unknown;
21
+ };
22
+ export type AuthControllerApi = {
23
+ login(req: IRequest, res: IResponse): Promise<void>;
24
+ register(req: IRequest, res: IResponse): Promise<void>;
25
+ logout(req: IRequest, res: IResponse): Promise<void>;
26
+ refresh(req: IRequest, res: IResponse): Promise<void>;
27
+ };
28
+
29
+ export type ValidationErrorLike = {
30
+ name?: unknown;
31
+ toObject?: () => Record<string, string[]>;
32
+ };
33
+
34
+ /**
35
+ * User Controller Interface
36
+ */
37
+ export interface IUserController {
38
+ index(req: IRequest, res: IResponse): Promise<void>;
39
+ show(req: IRequest, res: IResponse): Promise<void>;
40
+ create(req: IRequest, res: IResponse): Promise<void>;
41
+ store(req: IRequest, res: IResponse): Promise<void>;
42
+ fill(req: IRequest, res: IResponse): Promise<void>;
43
+ edit(req: IRequest, res: IResponse): Promise<void>;
44
+ update(req: IRequest, res: IResponse): Promise<void>;
45
+ destroy(req: IRequest, res: IResponse): Promise<void>;
46
+ }
@@ -1,240 +1,9 @@
1
1
  /**
2
- * FileLogWriter (Node.js only)
2
+ * FileLogWriter (template)
3
3
  *
4
- * Provides best-effort file logging with daily + size-based rotation.
5
- * This module imports Node built-ins and should be loaded only in Node environments.
4
+ * Keep this file declarative:
5
+ * - Core owns Node-specific file logging implementation.
6
6
  */
7
7
 
8
- import { ensureDirSafe } from '@zintrust/core';
9
- import { Env } from '@zintrust/core';
10
- import * as fs from 'node:fs';
11
- import * as path from 'node:path';
12
-
13
- const getCwdSafe = (): string => {
14
- try {
15
- if (typeof process === 'undefined' || typeof process.cwd !== 'function') return '';
16
- return process.cwd();
17
- } catch {
18
- return '';
19
- }
20
- };
21
-
22
- const getDateStr = (d: Date): string => d.toISOString().slice(0, 10);
23
-
24
- const isAppLogFile = (fileName: string): boolean =>
25
- fileName.startsWith('app-') && fileName.endsWith('.log');
26
-
27
- const parseDateFromLogFilename = (fileName: string): number | null => {
28
- const match = /^app-(\d{4}-\d{2}-\d{2})(?:-\d+)?\.log$/.exec(fileName);
29
- if (match?.[1] === undefined) return null;
30
-
31
- const parsed = Date.parse(`${match[1]}T00:00:00.000Z`);
32
- return Number.isNaN(parsed) ? null : parsed;
33
- };
34
-
35
- const isOlderThanCutoffByMtime = (fullPath: string, cutoff: number): boolean => {
36
- try {
37
- const stat = fs.statSync(fullPath);
38
- return stat.mtime.getTime() < cutoff;
39
- } catch {
40
- return false;
41
- }
42
- };
43
-
44
- const safeUnlink = (fullPath: string): void => {
45
- try {
46
- fs.unlinkSync(fullPath);
47
- } catch {
48
- // best-effort
49
- }
50
- };
51
-
52
- const readDirSafe = (dirPath: string): string[] => {
53
- try {
54
- return fs.readdirSync(dirPath);
55
- } catch {
56
- return [];
57
- }
58
- };
59
-
60
- const shouldDeleteLogFile = (fileName: string, fullPath: string, cutoff: number): boolean => {
61
- const parsed = parseDateFromLogFilename(fileName);
62
- if (parsed !== null) return parsed < cutoff;
63
-
64
- return isOlderThanCutoffByMtime(fullPath, cutoff);
65
- };
66
-
67
- const cleanupOldLogs = (logsDir: string, keepDays: number): void => {
68
- if (keepDays <= 0) return;
69
-
70
- const cutoff = Date.now() - keepDays * 24 * 60 * 60 * 1000;
71
- const files = readDirSafe(logsDir);
72
- if (files.length === 0) return;
73
-
74
- for (const fileName of files) {
75
- if (!isAppLogFile(fileName)) continue;
76
-
77
- const fullPath = path.join(logsDir, fileName);
78
- if (!shouldDeleteLogFile(fileName, fullPath, cutoff)) continue;
79
-
80
- safeUnlink(fullPath);
81
- }
82
- };
83
-
84
- type CleanOnceOptions = {
85
- logsDir?: string;
86
- keepDays?: number;
87
- maxTotalSize?: number;
88
- keepFiles?: number;
89
- };
90
-
91
- const listAppLogFiles = (
92
- logsDir: string,
93
- order: 'newest-first' | 'oldest-first'
94
- ): Array<{ name: string; path: string }> => {
95
- const files = readDirSafe(logsDir)
96
- .filter((f) => isAppLogFile(f))
97
- .map((f) => ({ name: f, path: path.join(logsDir, f) }));
98
-
99
- return files.sort((a, b) => {
100
- if (a.name === b.name) return 0;
101
- const newerFirst = a.name < b.name ? 1 : -1;
102
- return order === 'newest-first' ? newerFirst : -newerFirst;
103
- });
104
- };
105
-
106
- const enforceKeepFilesPolicy = (
107
- filesNewestFirst: Array<{ name: string; path: string }>,
108
- keepFiles: number | undefined,
109
- deleted: string[]
110
- ): void => {
111
- if (typeof keepFiles !== 'number' || keepFiles < 0) return;
112
- if (filesNewestFirst.length <= keepFiles) return;
113
-
114
- const toDelete = filesNewestFirst.slice(keepFiles);
115
- for (const f of toDelete) {
116
- safeUnlink(f.path);
117
- deleted.push(f.path);
118
- }
119
- };
120
-
121
- const getFileSizesTotal = (
122
- filesOldestFirst: Array<{ name: string; path: string }>
123
- ): { total: number; sizes: Array<{ path: string; size: number }> } => {
124
- let total = 0;
125
- const sizes: Array<{ path: string; size: number }> = [];
126
-
127
- for (const file of filesOldestFirst) {
128
- try {
129
- const stat = fs.statSync(file.path);
130
- sizes.push({ path: file.path, size: stat.size });
131
- total += stat.size;
132
- } catch {
133
- // ignore
134
- }
135
- }
136
-
137
- return { total, sizes };
138
- };
139
-
140
- const deleteOldestUntilWithinLimit = (
141
- sizesOldestFirst: Array<{ path: string; size: number }>,
142
- maxTotalSize: number,
143
- deleted: string[],
144
- initialTotal: number
145
- ): void => {
146
- let total = initialTotal;
147
-
148
- let idx = 0;
149
- while (total > maxTotalSize && idx < sizesOldestFirst.length) {
150
- const del = sizesOldestFirst[idx];
151
- safeUnlink(del.path);
152
- deleted.push(del.path);
153
- total -= del.size;
154
- idx++;
155
- }
156
- };
157
-
158
- const enforceMaxTotalSizePolicy = (
159
- logsDir: string,
160
- maxTotalSize: number | undefined,
161
- deleted: string[]
162
- ): void => {
163
- if (typeof maxTotalSize !== 'number' || maxTotalSize <= 0) return;
164
-
165
- const remainingOldestFirst = listAppLogFiles(logsDir, 'oldest-first');
166
- const { total, sizes } = getFileSizesTotal(remainingOldestFirst);
167
- deleteOldestUntilWithinLimit(sizes, maxTotalSize, deleted, total);
168
- };
169
-
170
- /**
171
- * Clean log files with additional retention policies.
172
- * Returns an array of deleted file paths for auditing/tests.
173
- */
174
- export const cleanOnce = (options?: CleanOnceOptions): string[] => {
175
- const cwd = getCwdSafe();
176
- if (cwd === '') return [];
177
-
178
- const logsDir = options?.logsDir ?? path.join(cwd, 'logs');
179
- const keepDays = options?.keepDays ?? Env.LOG_ROTATION_DAYS;
180
- const maxTotalSize = options?.maxTotalSize ?? Env.getInt('LOG_MAX_TOTAL_SIZE', 0);
181
- const keepFiles = options?.keepFiles ?? Env.getInt('LOG_KEEP_FILES', 0);
182
-
183
- // Step 1: delete by age
184
- cleanupOldLogs(logsDir, keepDays);
185
-
186
- const deleted: string[] = [];
187
-
188
- // Step 2: enforce keepFiles (keep newest N files)
189
- const filesNewestFirst = listAppLogFiles(logsDir, 'newest-first');
190
- enforceKeepFilesPolicy(filesNewestFirst, keepFiles, deleted);
191
-
192
- // Step 3: enforce max total size
193
- enforceMaxTotalSizePolicy(logsDir, maxTotalSize, deleted);
194
-
195
- return deleted;
196
- };
197
-
198
- const rotateIfNeeded = (logFile: string, maxSizeBytes: number): void => {
199
- if (maxSizeBytes <= 0) return;
200
-
201
- try {
202
- if (!fs.existsSync(logFile)) return;
203
-
204
- const stat = fs.statSync(logFile);
205
- if (stat.size <= maxSizeBytes) return;
206
-
207
- const ext = '.log';
208
- const base = logFile.endsWith(ext) ? logFile.slice(0, -ext.length) : logFile;
209
- const rotated = `${base}-${Date.now()}${ext}`;
210
- fs.renameSync(logFile, rotated);
211
- } catch {
212
- // best-effort
213
- }
214
- };
215
-
216
- export const FileLogWriter = Object.freeze({
217
- write(line: string): void {
218
- const cwd = getCwdSafe();
219
- if (cwd === '') return;
220
-
221
- const logsDir = path.join(cwd, 'logs');
222
- ensureDirSafe(logsDir);
223
-
224
- const dateStr = getDateStr(new Date());
225
- const logFile = path.join(logsDir, `app-${dateStr}.log`);
226
-
227
- rotateIfNeeded(logFile, Env.LOG_ROTATION_SIZE);
228
-
229
- try {
230
- fs.appendFileSync(logFile, `${line}\n`);
231
- } catch {
232
- // best-effort
233
- return;
234
- }
235
-
236
- cleanupOldLogs(logsDir, Env.LOG_ROTATION_DAYS);
237
- },
238
- });
239
-
240
- export default FileLogWriter;
8
+ export { cleanOnce, FileLogWriter } from '@zintrust/core/node';
9
+ export { FileLogWriter as default } from '@zintrust/core/node';