@zintrust/core 0.1.19 → 0.1.20

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 (495) 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 +2 -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 +18 -3
  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/cache/Cache.d.ts +1 -1
  25. package/src/cache/Cache.d.ts.map +1 -1
  26. package/src/cache/CacheDriver.d.ts +4 -0
  27. package/src/cache/CacheDriver.d.ts.map +1 -1
  28. package/src/cache/drivers/KVDriver.d.ts +1 -1
  29. package/src/cache/drivers/KVDriver.d.ts.map +1 -1
  30. package/src/cache/drivers/MemoryDriver.d.ts +1 -1
  31. package/src/cache/drivers/MemoryDriver.d.ts.map +1 -1
  32. package/src/cache/drivers/MemoryDriver.js +16 -0
  33. package/src/cache/drivers/MongoDriver.d.ts +1 -1
  34. package/src/cache/drivers/MongoDriver.d.ts.map +1 -1
  35. package/src/cache/drivers/RedisDriver.d.ts +1 -1
  36. package/src/cache/drivers/RedisDriver.d.ts.map +1 -1
  37. package/src/cli/CLI.d.ts.map +1 -1
  38. package/src/cli/CLI.js +10 -4
  39. package/src/cli/commands/AddCommand.d.ts +2 -2
  40. package/src/cli/commands/AddCommand.d.ts.map +1 -1
  41. package/src/cli/commands/AddCommand.js +135 -58
  42. package/src/cli/commands/ConfigCommand.d.ts +1 -1
  43. package/src/cli/commands/ConfigCommand.d.ts.map +1 -1
  44. package/src/cli/commands/CreateCommand.d.ts +15 -0
  45. package/src/cli/commands/CreateCommand.d.ts.map +1 -0
  46. package/src/cli/commands/CreateCommand.js +143 -0
  47. package/src/cli/commands/D1MigrateCommand.d.ts +1 -1
  48. package/src/cli/commands/D1MigrateCommand.d.ts.map +1 -1
  49. package/src/cli/commands/D1MigrateCommand.js +16 -20
  50. package/src/cli/commands/DbSeedCommand.d.ts +9 -0
  51. package/src/cli/commands/DbSeedCommand.d.ts.map +1 -0
  52. package/src/cli/commands/DbSeedCommand.js +171 -0
  53. package/src/cli/commands/DebugCommand.d.ts +1 -1
  54. package/src/cli/commands/DebugCommand.d.ts.map +1 -1
  55. package/src/cli/commands/FixCommand.d.ts +1 -1
  56. package/src/cli/commands/FixCommand.d.ts.map +1 -1
  57. package/src/cli/commands/JwtDevCommand.d.ts +8 -0
  58. package/src/cli/commands/JwtDevCommand.d.ts.map +1 -0
  59. package/src/cli/commands/JwtDevCommand.js +114 -0
  60. package/src/cli/commands/KeyGenerateCommand.d.ts +1 -1
  61. package/src/cli/commands/KeyGenerateCommand.d.ts.map +1 -1
  62. package/src/cli/commands/LogsCommand.d.ts +2 -2
  63. package/src/cli/commands/LogsCommand.d.ts.map +1 -1
  64. package/src/cli/commands/LogsCommand.js +36 -2
  65. package/src/cli/commands/MakeMailTemplateCommand.d.ts +1 -1
  66. package/src/cli/commands/MakeMailTemplateCommand.d.ts.map +1 -1
  67. package/src/cli/commands/MakeNotificationTemplateCommand.d.ts +1 -1
  68. package/src/cli/commands/MakeNotificationTemplateCommand.d.ts.map +1 -1
  69. package/src/cli/commands/MigrateCommand.d.ts +1 -1
  70. package/src/cli/commands/MigrateCommand.d.ts.map +1 -1
  71. package/src/cli/commands/MigrateCommand.js +291 -35
  72. package/src/cli/commands/NewCommand.d.ts +1 -1
  73. package/src/cli/commands/NewCommand.d.ts.map +1 -1
  74. package/src/cli/commands/NewCommand.js +12 -4
  75. package/src/cli/commands/PluginCommand.d.ts +1 -1
  76. package/src/cli/commands/PluginCommand.d.ts.map +1 -1
  77. package/src/cli/commands/PrepareCommand.d.ts +1 -1
  78. package/src/cli/commands/PrepareCommand.d.ts.map +1 -1
  79. package/src/cli/commands/QACommand.d.ts +2 -2
  80. package/src/cli/commands/QACommand.d.ts.map +1 -1
  81. package/src/cli/commands/RoutesCommand.d.ts +10 -0
  82. package/src/cli/commands/RoutesCommand.d.ts.map +1 -0
  83. package/src/cli/commands/RoutesCommand.js +242 -0
  84. package/src/cli/commands/SimulateCommand.d.ts +1 -1
  85. package/src/cli/commands/SimulateCommand.d.ts.map +1 -1
  86. package/src/cli/commands/index.d.ts +3 -0
  87. package/src/cli/commands/index.d.ts.map +1 -1
  88. package/src/cli/commands/index.js +3 -0
  89. package/src/cli/config/ConfigManager.d.ts +1 -1
  90. package/src/cli/config/ConfigManager.d.ts.map +1 -1
  91. package/src/cli/config/ConfigValidator.d.ts +1 -1
  92. package/src/cli/config/ConfigValidator.d.ts.map +1 -1
  93. package/src/cli/config/ConfigValidator.js +1 -1
  94. package/src/cli/d1/D1SqlMigrations.d.ts +20 -0
  95. package/src/cli/d1/D1SqlMigrations.d.ts.map +1 -0
  96. package/src/cli/d1/D1SqlMigrations.js +224 -0
  97. package/src/cli/d1/WranglerConfig.d.ts +4 -0
  98. package/src/cli/d1/WranglerConfig.d.ts.map +1 -0
  99. package/src/cli/d1/WranglerConfig.js +122 -0
  100. package/src/cli/d1/WranglerD1.d.ts +11 -0
  101. package/src/cli/d1/WranglerD1.d.ts.map +1 -0
  102. package/src/cli/d1/WranglerD1.js +16 -0
  103. package/src/cli/scaffolding/ControllerGenerator.d.ts.map +1 -1
  104. package/src/cli/scaffolding/ControllerGenerator.js +72 -22
  105. package/src/cli/scaffolding/FactoryGenerator.d.ts.map +1 -1
  106. package/src/cli/scaffolding/FactoryGenerator.js +3 -1
  107. package/src/cli/scaffolding/GovernanceScaffolder.d.ts +23 -0
  108. package/src/cli/scaffolding/GovernanceScaffolder.d.ts.map +1 -0
  109. package/src/cli/scaffolding/GovernanceScaffolder.js +327 -0
  110. package/src/cli/scaffolding/MigrationGenerator.d.ts +10 -0
  111. package/src/cli/scaffolding/MigrationGenerator.d.ts.map +1 -1
  112. package/src/cli/scaffolding/MigrationGenerator.js +137 -51
  113. package/src/cli/scaffolding/ProjectScaffolder.d.ts.map +1 -1
  114. package/src/cli/scaffolding/ProjectScaffolder.js +36 -4
  115. package/src/cli/scaffolding/RouteGenerator.d.ts.map +1 -1
  116. package/src/cli/scaffolding/RouteGenerator.js +79 -43
  117. package/src/cli/scaffolding/SeederGenerator.d.ts +5 -0
  118. package/src/cli/scaffolding/SeederGenerator.d.ts.map +1 -1
  119. package/src/cli/scaffolding/SeederGenerator.js +63 -15
  120. package/src/cli/scaffolding/ServiceScaffolder.d.ts.map +1 -1
  121. package/src/cli/scaffolding/ServiceScaffolder.js +24 -3
  122. package/src/cli/scaffolding/index.d.ts +2 -0
  123. package/src/cli/scaffolding/index.d.ts.map +1 -1
  124. package/src/cli/scaffolding/index.js +1 -0
  125. package/src/common/index.d.ts +8 -0
  126. package/src/common/index.d.ts.map +1 -1
  127. package/src/common/index.js +28 -0
  128. package/src/common/utility.d.ts +38 -0
  129. package/src/common/utility.d.ts.map +1 -0
  130. package/src/common/utility.js +101 -0
  131. package/src/config/FileLogWriter.d.ts +2 -1
  132. package/src/config/FileLogWriter.d.ts.map +1 -1
  133. package/src/config/FileLogWriter.js +83 -2
  134. package/src/config/app.d.ts.map +1 -1
  135. package/src/config/app.js +3 -1
  136. package/src/config/broadcast.d.ts +1 -1
  137. package/src/config/broadcast.d.ts.map +1 -1
  138. package/src/config/cache.d.ts +1 -1
  139. package/src/config/cache.d.ts.map +1 -1
  140. package/src/config/cloudflare.d.ts +1 -1
  141. package/src/config/cloudflare.d.ts.map +1 -1
  142. package/src/config/database.d.ts +1 -1
  143. package/src/config/database.d.ts.map +1 -1
  144. package/src/config/database.js +92 -6
  145. package/src/config/env.d.ts +6 -0
  146. package/src/config/env.d.ts.map +1 -1
  147. package/src/config/env.js +7 -0
  148. package/src/config/index.d.ts +1 -1
  149. package/src/config/logging/KvLogger.js +1 -1
  150. package/src/config/logging/SlackLogger.js +2 -2
  151. package/src/config/middleware.d.ts +20 -1
  152. package/src/config/middleware.d.ts.map +1 -1
  153. package/src/config/middleware.js +135 -3
  154. package/src/config/security.d.ts +1 -1
  155. package/src/config/security.js +1 -1
  156. package/src/config/type.d.ts +1 -1
  157. package/src/config/type.d.ts.map +1 -1
  158. package/src/events/EventDispatcher.d.ts.map +1 -1
  159. package/src/events/EventDispatcher.js +6 -4
  160. package/src/exceptions/ZintrustError.d.ts +7 -0
  161. package/src/exceptions/ZintrustError.d.ts.map +1 -1
  162. package/src/exceptions/ZintrustError.js +56 -0
  163. package/src/features/Auth.d.ts +1 -1
  164. package/src/features/Auth.d.ts.map +1 -1
  165. package/src/features/Auth.js +3 -3
  166. package/src/features/Queue.js +1 -1
  167. package/src/functions/cloudflare.d.ts.map +1 -1
  168. package/src/functions/cloudflare.js +3 -14
  169. package/src/functions/deno.d.ts.map +1 -1
  170. package/src/functions/deno.js +3 -14
  171. package/src/functions/lambda.d.ts.map +1 -1
  172. package/src/functions/lambda.js +3 -14
  173. package/src/health/StartupHealthChecks.js +1 -1
  174. package/src/http/Controller.d.ts +2 -2
  175. package/src/http/Controller.d.ts.map +1 -1
  176. package/src/http/FileUpload.d.ts +68 -0
  177. package/src/http/FileUpload.d.ts.map +1 -0
  178. package/src/http/FileUpload.js +120 -0
  179. package/src/http/Kernel.d.ts +5 -5
  180. package/src/http/Kernel.d.ts.map +1 -1
  181. package/src/http/Kernel.js +139 -23
  182. package/src/http/Request.d.ts +20 -1
  183. package/src/http/Request.d.ts.map +1 -1
  184. package/src/http/Request.js +23 -0
  185. package/src/http/RequestContext.d.ts +6 -0
  186. package/src/http/RequestContext.d.ts.map +1 -1
  187. package/src/http/RequestContext.js +77 -1
  188. package/src/http/Response.d.ts +1 -1
  189. package/src/http/Response.d.ts.map +1 -1
  190. package/src/http/ValidationHelper.d.ts +78 -0
  191. package/src/http/ValidationHelper.d.ts.map +1 -0
  192. package/src/http/ValidationHelper.js +121 -0
  193. package/src/http/error-pages/ErrorPageRenderer.d.ts +17 -0
  194. package/src/http/error-pages/ErrorPageRenderer.d.ts.map +1 -0
  195. package/src/http/error-pages/ErrorPageRenderer.js +88 -0
  196. package/src/http/middleware/BodyParsingMiddleware.d.ts +12 -0
  197. package/src/http/middleware/BodyParsingMiddleware.d.ts.map +1 -0
  198. package/src/http/middleware/BodyParsingMiddleware.js +251 -0
  199. package/src/http/middleware/FileUploadMiddleware.d.ts +12 -0
  200. package/src/http/middleware/FileUploadMiddleware.d.ts.map +1 -0
  201. package/src/http/middleware/FileUploadMiddleware.js +74 -0
  202. package/src/http/parsers/BodyParsers.d.ts +32 -0
  203. package/src/http/parsers/BodyParsers.d.ts.map +1 -0
  204. package/src/http/parsers/BodyParsers.js +159 -0
  205. package/src/http/parsers/MultipartParser.d.ts +33 -0
  206. package/src/http/parsers/MultipartParser.d.ts.map +1 -0
  207. package/src/http/parsers/MultipartParser.js +129 -0
  208. package/src/http/parsers/MultipartParserRegistry.d.ts +34 -0
  209. package/src/http/parsers/MultipartParserRegistry.d.ts.map +1 -0
  210. package/src/http/parsers/MultipartParserRegistry.js +20 -0
  211. package/src/http/validated.d.ts +12 -0
  212. package/src/http/validated.d.ts.map +1 -0
  213. package/src/http/validated.js +41 -0
  214. package/src/index.d.ts +64 -7
  215. package/src/index.d.ts.map +1 -1
  216. package/src/index.js +59 -5
  217. package/src/microservices/RequestTracingMiddleware.d.ts +2 -2
  218. package/src/microservices/RequestTracingMiddleware.d.ts.map +1 -1
  219. package/src/microservices/RequestTracingMiddleware.js +3 -0
  220. package/src/microservices/ServiceAuthMiddleware.d.ts +2 -2
  221. package/src/microservices/ServiceAuthMiddleware.d.ts.map +1 -1
  222. package/src/middleware/AuthMiddleware.d.ts +10 -0
  223. package/src/middleware/AuthMiddleware.d.ts.map +1 -0
  224. package/src/middleware/AuthMiddleware.js +16 -0
  225. package/src/middleware/CsrfMiddleware.d.ts +11 -1
  226. package/src/middleware/CsrfMiddleware.d.ts.map +1 -1
  227. package/src/middleware/CsrfMiddleware.js +33 -0
  228. package/src/middleware/JwtAuthMiddleware.d.ts +11 -0
  229. package/src/middleware/JwtAuthMiddleware.d.ts.map +1 -0
  230. package/src/middleware/JwtAuthMiddleware.js +73 -0
  231. package/src/middleware/LoggingMiddleware.d.ts.map +1 -1
  232. package/src/middleware/LoggingMiddleware.js +8 -3
  233. package/src/middleware/MiddlewareStack.d.ts +2 -2
  234. package/src/middleware/MiddlewareStack.d.ts.map +1 -1
  235. package/src/middleware/RateLimiter.d.ts +2 -2
  236. package/src/middleware/RateLimiter.d.ts.map +1 -1
  237. package/src/middleware/SanitizeBodyMiddleware.d.ts +12 -0
  238. package/src/middleware/SanitizeBodyMiddleware.d.ts.map +1 -0
  239. package/src/middleware/SanitizeBodyMiddleware.js +31 -0
  240. package/src/middleware/SecurityMiddleware.d.ts +1 -1
  241. package/src/middleware/SecurityMiddleware.d.ts.map +1 -1
  242. package/src/middleware/SessionMiddleware.d.ts +1 -1
  243. package/src/middleware/SessionMiddleware.d.ts.map +1 -1
  244. package/src/middleware/ValidationMiddleware.d.ts +25 -0
  245. package/src/middleware/ValidationMiddleware.d.ts.map +1 -0
  246. package/src/middleware/ValidationMiddleware.js +251 -0
  247. package/src/migrations/MigrationDiscovery.d.ts +5 -0
  248. package/src/migrations/MigrationDiscovery.d.ts.map +1 -0
  249. package/src/migrations/MigrationDiscovery.js +16 -0
  250. package/src/migrations/MigrationLoader.d.ts +5 -0
  251. package/src/migrations/MigrationLoader.d.ts.map +1 -0
  252. package/src/migrations/MigrationLoader.js +43 -0
  253. package/src/migrations/MigrationLock.d.ts +4 -0
  254. package/src/migrations/MigrationLock.d.ts.map +1 -0
  255. package/src/migrations/MigrationLock.js +33 -0
  256. package/src/migrations/Migrator.d.ts +23 -0
  257. package/src/migrations/Migrator.d.ts.map +1 -0
  258. package/src/migrations/Migrator.js +4 -0
  259. package/src/migrations/MigratorFactory.d.ts +25 -0
  260. package/src/migrations/MigratorFactory.d.ts.map +1 -0
  261. package/src/migrations/MigratorFactory.js +323 -0
  262. package/src/migrations/schema/Blueprint.d.ts +5 -0
  263. package/src/migrations/schema/Blueprint.d.ts.map +1 -0
  264. package/src/migrations/schema/Blueprint.js +189 -0
  265. package/src/migrations/schema/Schema.d.ts +8 -0
  266. package/src/migrations/schema/Schema.d.ts.map +1 -0
  267. package/src/migrations/schema/Schema.js +141 -0
  268. package/src/migrations/schema/SchemaCompiler.d.ts +20 -0
  269. package/src/migrations/schema/SchemaCompiler.d.ts.map +1 -0
  270. package/src/migrations/schema/SchemaCompiler.js +262 -0
  271. package/src/migrations/schema/index.d.ts +5 -0
  272. package/src/migrations/schema/index.d.ts.map +1 -0
  273. package/src/migrations/schema/index.js +3 -0
  274. package/src/migrations/schema/types.d.ts +86 -0
  275. package/src/migrations/schema/types.d.ts.map +1 -0
  276. package/src/migrations/schema/types.js +1 -0
  277. package/src/migrations/types.d.ts +45 -0
  278. package/src/migrations/types.d.ts.map +1 -0
  279. package/src/migrations/types.js +1 -0
  280. package/src/node-singletons/crypto.d.ts +1 -1
  281. package/src/node-singletons/crypto.d.ts.map +1 -1
  282. package/src/node-singletons/crypto.js +1 -1
  283. package/src/node-singletons/fs.d.ts +2 -2
  284. package/src/node-singletons/fs.d.ts.map +1 -1
  285. package/src/node-singletons/fs.js +1 -1
  286. package/src/node-singletons/util.d.ts +6 -0
  287. package/src/node-singletons/util.d.ts.map +1 -0
  288. package/src/node-singletons/util.js +5 -0
  289. package/src/node.d.ts +3 -1
  290. package/src/node.d.ts.map +1 -1
  291. package/src/node.js +6 -2
  292. package/src/observability/OpenTelemetry.d.ts +62 -0
  293. package/src/observability/OpenTelemetry.d.ts.map +1 -0
  294. package/src/observability/OpenTelemetry.js +167 -0
  295. package/src/observability/PrometheusMetrics.d.ts +25 -0
  296. package/src/observability/PrometheusMetrics.d.ts.map +1 -0
  297. package/src/observability/PrometheusMetrics.js +114 -0
  298. package/src/openapi/OpenApiGenerator.d.ts +68 -0
  299. package/src/openapi/OpenApiGenerator.d.ts.map +1 -0
  300. package/src/openapi/OpenApiGenerator.js +287 -0
  301. package/src/orm/Database.d.ts +4 -2
  302. package/src/orm/Database.d.ts.map +1 -1
  303. package/src/orm/Database.js +142 -29
  304. package/src/orm/DatabaseAdapter.d.ts +13 -0
  305. package/src/orm/DatabaseAdapter.d.ts.map +1 -1
  306. package/src/orm/DatabaseAdapterRegistry.d.ts.map +1 -1
  307. package/src/orm/DatabaseAdapterRegistry.js +3 -1
  308. package/src/orm/Model.d.ts +30 -2
  309. package/src/orm/Model.d.ts.map +1 -1
  310. package/src/orm/Model.js +255 -62
  311. package/src/orm/QueryBuilder.d.ts +22 -1
  312. package/src/orm/QueryBuilder.d.ts.map +1 -1
  313. package/src/orm/QueryBuilder.js +405 -99
  314. package/src/orm/Relationships.d.ts +7 -1
  315. package/src/orm/Relationships.d.ts.map +1 -1
  316. package/src/orm/Relationships.js +18 -0
  317. package/src/orm/SchemaCompiler.d.ts +9 -0
  318. package/src/orm/SchemaCompiler.d.ts.map +1 -0
  319. package/src/orm/SchemaCompiler.js +145 -0
  320. package/src/orm/adapters/D1Adapter.d.ts +1 -1
  321. package/src/orm/adapters/D1Adapter.d.ts.map +1 -1
  322. package/src/orm/adapters/MySQLAdapter.d.ts +1 -1
  323. package/src/orm/adapters/MySQLAdapter.d.ts.map +1 -1
  324. package/src/orm/adapters/MySQLAdapter.js +88 -69
  325. package/src/orm/adapters/PostgreSQLAdapter.d.ts +1 -1
  326. package/src/orm/adapters/PostgreSQLAdapter.d.ts.map +1 -1
  327. package/src/orm/adapters/PostgreSQLAdapter.js +88 -69
  328. package/src/orm/adapters/SQLServerAdapter.d.ts +1 -1
  329. package/src/orm/adapters/SQLServerAdapter.d.ts.map +1 -1
  330. package/src/orm/adapters/SQLiteAdapter.d.ts +1 -1
  331. package/src/orm/adapters/SQLiteAdapter.d.ts.map +1 -1
  332. package/src/orm/adapters/SQLiteAdapter.js +58 -2
  333. package/src/orm/maintenance/SqliteMaintenance.d.ts +5 -0
  334. package/src/orm/maintenance/SqliteMaintenance.d.ts.map +1 -0
  335. package/src/orm/maintenance/SqliteMaintenance.js +14 -0
  336. package/src/orm/migrations/MigrationStore.d.ts +38 -0
  337. package/src/orm/migrations/MigrationStore.d.ts.map +1 -0
  338. package/src/orm/migrations/MigrationStore.js +157 -0
  339. package/src/performance/CodeGenerationBenchmark.d.ts.map +1 -1
  340. package/src/performance/Optimizer.d.ts +1 -0
  341. package/src/performance/Optimizer.d.ts.map +1 -1
  342. package/src/performance/Optimizer.js +37 -3
  343. package/src/profiling/MemoryProfiler.d.ts +1 -1
  344. package/src/profiling/MemoryProfiler.d.ts.map +1 -1
  345. package/src/profiling/N1Detector.d.ts +1 -1
  346. package/src/profiling/N1Detector.d.ts.map +1 -1
  347. package/src/profiling/QueryLogger.d.ts +1 -1
  348. package/src/profiling/QueryLogger.d.ts.map +1 -1
  349. package/src/profiling/RequestProfiler.d.ts +3 -3
  350. package/src/profiling/RequestProfiler.d.ts.map +1 -1
  351. package/src/routes/metrics.d.ts +2 -0
  352. package/src/routes/metrics.d.ts.map +1 -0
  353. package/src/routes/metrics.js +1 -0
  354. package/src/routing/CoreRoutes.d.ts +12 -0
  355. package/src/routing/CoreRoutes.d.ts.map +1 -0
  356. package/src/routing/CoreRoutes.js +151 -0
  357. package/src/routing/RouteRegistry.d.ts +39 -0
  358. package/src/routing/RouteRegistry.d.ts.map +1 -0
  359. package/src/routing/RouteRegistry.js +44 -0
  360. package/src/routing/Router.d.ts +26 -9
  361. package/src/routing/Router.d.ts.map +1 -1
  362. package/src/routing/Router.js +79 -35
  363. package/src/routing/common.d.ts +15 -0
  364. package/src/routing/common.d.ts.map +1 -0
  365. package/src/routing/common.js +47 -0
  366. package/src/routing/doc.d.ts +28 -0
  367. package/src/routing/doc.d.ts.map +1 -0
  368. package/src/routing/doc.js +95 -0
  369. package/src/routing/error.d.ts +21 -0
  370. package/src/routing/error.d.ts.map +1 -0
  371. package/src/routing/error.js +126 -0
  372. package/src/routing/errorPages.d.ts +14 -0
  373. package/src/routing/errorPages.d.ts.map +1 -0
  374. package/src/routing/errorPages.js +103 -0
  375. package/src/routing/publicRoot.d.ts +18 -0
  376. package/src/routing/publicRoot.d.ts.map +1 -0
  377. package/src/routing/publicRoot.js +49 -0
  378. package/src/runtime/PluginAutoImports.d.ts +21 -0
  379. package/src/runtime/PluginAutoImports.d.ts.map +1 -0
  380. package/src/runtime/PluginAutoImports.js +59 -0
  381. package/src/runtime/PluginManager.d.ts +1 -5
  382. package/src/runtime/PluginManager.d.ts.map +1 -1
  383. package/src/runtime/PluginManager.js +25 -18
  384. package/src/runtime/RuntimeDetector.d.ts +1 -1
  385. package/src/runtime/RuntimeDetector.d.ts.map +1 -1
  386. package/src/runtime/adapters/CloudflareAdapter.d.ts +1 -1
  387. package/src/runtime/adapters/CloudflareAdapter.d.ts.map +1 -1
  388. package/src/runtime/adapters/CloudflareAdapter.js +1 -1
  389. package/src/runtime/adapters/DenoAdapter.d.ts +1 -1
  390. package/src/runtime/adapters/DenoAdapter.d.ts.map +1 -1
  391. package/src/runtime/adapters/DenoAdapter.js +1 -1
  392. package/src/runtime/adapters/LambdaAdapter.d.ts +1 -1
  393. package/src/runtime/adapters/LambdaAdapter.d.ts.map +1 -1
  394. package/src/runtime/adapters/LambdaAdapter.js +1 -1
  395. package/src/runtime/adapters/NodeServerAdapter.d.ts +1 -1
  396. package/src/runtime/adapters/NodeServerAdapter.d.ts.map +1 -1
  397. package/src/runtime/getKernel.d.ts +9 -0
  398. package/src/runtime/getKernel.d.ts.map +1 -0
  399. package/src/runtime/getKernel.js +27 -0
  400. package/src/scripts/TemplateImportsCheck.js +40 -0
  401. package/src/scripts/TemplateSync.js +86 -20
  402. package/src/security/Encryptor.d.ts.map +1 -1
  403. package/src/security/Encryptor.js +64 -7
  404. package/src/security/JwtManager.d.ts +1 -0
  405. package/src/security/JwtManager.d.ts.map +1 -1
  406. package/src/security/JwtManager.js +33 -0
  407. package/src/security/Sanitizer.d.ts +76 -0
  408. package/src/security/Sanitizer.d.ts.map +1 -0
  409. package/src/security/Sanitizer.js +412 -0
  410. package/src/security/TokenRevocation.d.ts +7 -0
  411. package/src/security/TokenRevocation.d.ts.map +1 -0
  412. package/src/security/TokenRevocation.js +57 -0
  413. package/src/seeders/SeederDiscovery.d.ts +5 -0
  414. package/src/seeders/SeederDiscovery.d.ts.map +1 -0
  415. package/src/seeders/SeederDiscovery.js +21 -0
  416. package/src/seeders/SeederLoader.d.ts +5 -0
  417. package/src/seeders/SeederLoader.d.ts.map +1 -0
  418. package/src/seeders/SeederLoader.js +60 -0
  419. package/src/seeders/types.d.ts +18 -0
  420. package/src/seeders/types.d.ts.map +1 -0
  421. package/src/seeders/types.js +1 -0
  422. package/src/session/SessionManager.js +1 -1
  423. package/src/templates/adapters/MySQLAdapter.ts.tpl +109 -85
  424. package/src/templates/adapters/PostgreSQLAdapter.ts.tpl +129 -88
  425. package/src/templates/adapters/SQLServerAdapter.ts.tpl +5 -9
  426. package/src/templates/adapters/SQLiteAdapter.ts.tpl +78 -11
  427. package/src/templates/features/Queue.ts.tpl +3 -2
  428. package/src/templates/project/basic/app/Controllers/AuthController.ts.tpl +217 -0
  429. package/src/templates/project/basic/app/Controllers/UserController.ts.tpl +1 -12
  430. package/src/templates/project/basic/app/Types/controller.ts.tpl +46 -0
  431. package/src/templates/project/basic/config/FileLogWriter.ts.tpl +5 -236
  432. package/src/templates/project/basic/config/SecretsManager.ts.tpl +10 -447
  433. package/src/templates/project/basic/config/StartupConfigValidator.ts.tpl +9 -268
  434. package/src/templates/project/basic/config/app.ts.tpl +13 -153
  435. package/src/templates/project/basic/config/broadcast.ts.tpl +15 -128
  436. package/src/templates/project/basic/config/cache.ts.tpl +15 -91
  437. package/src/templates/project/basic/config/cloudflare.ts.tpl +4 -39
  438. package/src/templates/project/basic/config/constants.ts.tpl +9 -65
  439. package/src/templates/project/basic/config/database.ts.tpl +29 -122
  440. package/src/templates/project/basic/config/env.ts.tpl +5 -169
  441. package/src/templates/project/basic/config/features.ts.tpl +6 -54
  442. package/src/templates/project/basic/config/index.ts.tpl +8 -23
  443. package/src/templates/project/basic/config/mail.ts.tpl +15 -114
  444. package/src/templates/project/basic/config/microservices.ts.tpl +11 -97
  445. package/src/templates/project/basic/config/middleware.ts.tpl +25 -43
  446. package/src/templates/project/basic/config/notification.ts.tpl +14 -126
  447. package/src/templates/project/basic/config/queue.ts.tpl +16 -79
  448. package/src/templates/project/basic/config/security.ts.tpl +11 -163
  449. package/src/templates/project/basic/config/startup.ts.tpl +10 -21
  450. package/src/templates/project/basic/config/storage.ts.tpl +15 -132
  451. package/src/templates/project/basic/config/type.ts.tpl +33 -451
  452. package/src/templates/project/basic/database/factories/UserFactory.ts.tpl +80 -0
  453. package/src/templates/project/basic/database/migrations/create_tasks_table.ts.tpl +28 -0
  454. package/src/templates/project/basic/database/migrations/create_users_table.ts.tpl +29 -0
  455. package/src/templates/project/basic/database/seeders/DatabaseSeeder.ts.tpl +19 -0
  456. package/src/templates/project/basic/database/seeders/UserSeeder.ts.tpl +18 -0
  457. package/src/templates/project/basic/database/seeders/index.ts.tpl +2 -0
  458. package/src/templates/project/basic/routes/api.ts.tpl +71 -33
  459. package/src/templates/project/basic/routes/metrics.ts.tpl +22 -0
  460. package/src/templates/project/basic/tsconfig.json.tpl +12 -11
  461. package/src/testing/TestEnvironment.d.ts +40 -0
  462. package/src/testing/TestEnvironment.d.ts.map +1 -0
  463. package/src/testing/TestEnvironment.js +141 -0
  464. package/src/testing/TestHttp.d.ts +29 -0
  465. package/src/testing/TestHttp.d.ts.map +1 -0
  466. package/src/testing/TestHttp.js +96 -0
  467. package/src/testing/index.d.ts +5 -0
  468. package/src/testing/index.d.ts.map +1 -0
  469. package/src/testing/index.js +2 -0
  470. package/src/time/DateTime.d.ts +181 -0
  471. package/src/time/DateTime.d.ts.map +1 -0
  472. package/src/time/DateTime.js +300 -0
  473. package/src/time/index.d.ts +7 -0
  474. package/src/time/index.d.ts.map +1 -0
  475. package/src/time/index.js +5 -0
  476. package/src/tools/http/Http.d.ts.map +1 -1
  477. package/src/tools/http/Http.js +4 -0
  478. package/src/tools/mail/drivers/Smtp.js +1 -1
  479. package/src/tools/queue/drivers/InMemory.d.ts +1 -1
  480. package/src/tools/queue/drivers/InMemory.d.ts.map +1 -1
  481. package/src/tools/queue/drivers/InMemory.js +1 -1
  482. package/src/tools/queue/drivers/Redis.d.ts +1 -1
  483. package/src/tools/queue/drivers/Redis.d.ts.map +1 -1
  484. package/src/tools/queue/drivers/Redis.js +1 -1
  485. package/src/validation/ValidationError.d.ts.map +1 -1
  486. package/src/validation/ValidationError.js +4 -2
  487. package/src/validation/Validator.d.ts +49 -16
  488. package/src/validation/Validator.d.ts.map +1 -1
  489. package/src/validation/Validator.js +307 -5
  490. package/src/common/uuid.d.ts +0 -3
  491. package/src/common/uuid.d.ts.map +0 -1
  492. package/src/common/uuid.js +0 -30
  493. package/src/templates/project/basic/.env.example.tpl +0 -74
  494. package/src/templates/project/basic/.env.tpl +0 -166
  495. package/src/templates/project/basic/database/migrations/index.ts.tpl +0 -2
@@ -0,0 +1,68 @@
1
+ /**
2
+ * File Upload Handler
3
+ * Handles multipart/form-data file uploads with validation and storage integration
4
+ */
5
+ import type { IRequest } from './Request';
6
+ import type { Readable } from 'node:stream';
7
+ export interface UploadedFile {
8
+ fieldName: string;
9
+ originalName: string;
10
+ mimeType: string;
11
+ size: number;
12
+ encoding?: string;
13
+ /**
14
+ * Legacy in-memory payload (Phase 3). Optional in Phase 4.
15
+ */
16
+ buffer?: Buffer;
17
+ /**
18
+ * Disk-backed upload path (Phase 4, provided by @zintrust/storage).
19
+ */
20
+ path?: string;
21
+ /**
22
+ * Returns a fresh readable stream for the uploaded content.
23
+ */
24
+ stream?: () => Readable;
25
+ /**
26
+ * Optional cleanup hook (e.g., delete temp file after response).
27
+ */
28
+ cleanup?: () => Promise<void>;
29
+ }
30
+ export interface FileUploadOptions {
31
+ maxSize?: number;
32
+ mimeTypes?: string[];
33
+ required?: boolean;
34
+ }
35
+ export interface IFileUploadHandler {
36
+ file(fieldName: string, options?: FileUploadOptions): UploadedFile | undefined;
37
+ files(fieldName: string, options?: FileUploadOptions): UploadedFile[];
38
+ hasFile(fieldName: string): boolean;
39
+ validate(): {
40
+ valid: boolean;
41
+ errors: Record<string, string[]>;
42
+ };
43
+ }
44
+ /**
45
+ * Create file upload handler for request
46
+ */
47
+ export declare const createFileUploadHandler: (req: IRequest) => IFileUploadHandler;
48
+ export declare const FileUpload: Readonly<{
49
+ /**
50
+ * Create handler for request
51
+ */
52
+ createHandler(req: IRequest): IFileUploadHandler;
53
+ /**
54
+ * Validate uploaded files
55
+ */
56
+ validateFiles(files: UploadedFile[], options: {
57
+ required?: boolean;
58
+ minCount?: number;
59
+ maxCount?: number;
60
+ mimeTypes?: string[];
61
+ maxSize?: number;
62
+ }): {
63
+ valid: boolean;
64
+ error?: string;
65
+ };
66
+ }>;
67
+ export default FileUpload;
68
+ //# sourceMappingURL=FileUpload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileUpload.d.ts","sourceRoot":"","sources":["../../../src/http/FileUpload.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,QAAQ,CAAC;IAExB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,YAAY,GAAG,SAAS,CAAC;IAC/E,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,YAAY,EAAE,CAAC;IACtE,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;IACpC,QAAQ,IAAI;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;KAAE,CAAC;CAClE;AAoBD;;GAEG;AACH,eAAO,MAAM,uBAAuB,GAAI,KAAK,QAAQ,KAAG,kBAsEvD,CAAC;AAEF,eAAO,MAAM,UAAU;IACrB;;OAEG;uBACgB,QAAQ,GAAG,kBAAkB;IAIhD;;OAEG;yBAEM,YAAY,EAAE,WACZ;QACP,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;QACrB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,GACA;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;EA6BrC,CAAC;AAEH,eAAe,UAAU,CAAC"}
@@ -0,0 +1,120 @@
1
+ /**
2
+ * File Upload Handler
3
+ * Handles multipart/form-data file uploads with validation and storage integration
4
+ */
5
+ /**
6
+ * Check if MIME type is allowed
7
+ */
8
+ const isMimeTypeAllowed = (mimeType, allowed) => {
9
+ if (!allowed || allowed.length === 0)
10
+ return true;
11
+ // Support wildcards like "image/*"
12
+ for (const allowedType of allowed) {
13
+ if (allowedType === mimeType)
14
+ return true;
15
+ if (allowedType.endsWith('/*')) {
16
+ const prefix = allowedType.slice(0, -2);
17
+ if (mimeType.startsWith(prefix + '/'))
18
+ return true;
19
+ }
20
+ }
21
+ return false;
22
+ };
23
+ /**
24
+ * Create file upload handler for request
25
+ */
26
+ export const createFileUploadHandler = (req) => {
27
+ // Files would be extracted from multipart/form-data parsing
28
+ // This is a placeholder structure - actual implementation depends on
29
+ // how multipart data is parsed and stored on the request
30
+ const uploadedFiles = new Map();
31
+ // Extract files from request if available
32
+ const requestBody = req.getBody?.();
33
+ if (typeof requestBody === 'object' && requestBody !== null && '__files' in requestBody) {
34
+ const filesData = requestBody.__files;
35
+ if (typeof filesData === 'object' && filesData !== null) {
36
+ for (const [fieldName, files] of Object.entries(filesData)) {
37
+ if (Array.isArray(files)) {
38
+ uploadedFiles.set(fieldName, files);
39
+ }
40
+ }
41
+ }
42
+ }
43
+ return {
44
+ file(fieldName, options) {
45
+ const files = uploadedFiles.get(fieldName);
46
+ if (!files || files.length === 0)
47
+ return undefined;
48
+ const file = files[0];
49
+ // Validate MIME type
50
+ if (!isMimeTypeAllowed(file.mimeType, options?.mimeTypes)) {
51
+ return undefined;
52
+ }
53
+ // Validate size
54
+ const maxSize = options?.maxSize ?? 10 * 1024 * 1024; // 10MB default
55
+ if (file.size > maxSize) {
56
+ return undefined;
57
+ }
58
+ return file;
59
+ },
60
+ files(fieldName, options) {
61
+ const files = uploadedFiles.get(fieldName) ?? [];
62
+ return files.filter((file) => {
63
+ // Validate MIME type
64
+ if (!isMimeTypeAllowed(file.mimeType, options?.mimeTypes)) {
65
+ return false;
66
+ }
67
+ // Validate size
68
+ const maxSize = options?.maxSize ?? 10 * 1024 * 1024; // 10MB default
69
+ if (file.size > maxSize) {
70
+ return false;
71
+ }
72
+ return true;
73
+ });
74
+ },
75
+ hasFile(fieldName) {
76
+ const files = uploadedFiles.get(fieldName);
77
+ return files !== undefined && files.length > 0;
78
+ },
79
+ validate() {
80
+ const errors = {};
81
+ return { valid: Object.keys(errors).length === 0, errors };
82
+ },
83
+ };
84
+ };
85
+ export const FileUpload = Object.freeze({
86
+ /**
87
+ * Create handler for request
88
+ */
89
+ createHandler(req) {
90
+ return createFileUploadHandler(req);
91
+ },
92
+ /**
93
+ * Validate uploaded files
94
+ */
95
+ validateFiles(files, options) {
96
+ if (options.required === true && files.length === 0) {
97
+ return { valid: false, error: 'At least one file is required' };
98
+ }
99
+ if (typeof options.minCount === 'number' && files.length < options.minCount) {
100
+ return { valid: false, error: `At least ${options.minCount} files required` };
101
+ }
102
+ if (typeof options.maxCount === 'number' && files.length > options.maxCount) {
103
+ return { valid: false, error: `Maximum ${options.maxCount} files allowed` };
104
+ }
105
+ for (const file of files) {
106
+ if (!isMimeTypeAllowed(file.mimeType, options.mimeTypes)) {
107
+ return { valid: false, error: `File type not allowed: ${file.mimeType}` };
108
+ }
109
+ const maxSize = options.maxSize ?? 10 * 1024 * 1024;
110
+ if (file.size > maxSize) {
111
+ return {
112
+ valid: false,
113
+ error: `File too large: ${file.originalName} (${file.size} bytes)`,
114
+ };
115
+ }
116
+ }
117
+ return { valid: true };
118
+ },
119
+ });
120
+ export default FileUpload;
@@ -1,12 +1,12 @@
1
1
  /**
2
2
  * HTTP Kernel - Request handling and middleware pipeline
3
3
  */
4
- import { IServiceContainer } from '../container/ServiceContainer';
5
- import { IRequest } from './Request';
6
- import { IResponse } from './Response';
7
- import { IMiddlewareStack, Middleware } from '../middleware/MiddlewareStack';
4
+ import type { IServiceContainer } from '../container/ServiceContainer';
5
+ import type { IRequest } from './Request';
6
+ import type { IResponse } from './Response';
7
+ import type { IMiddlewareStack, Middleware } from '../middleware/MiddlewareStack';
8
8
  import type { IncomingMessage, ServerResponse } from '../node-singletons/http';
9
- import { IRouter } from '../routing/Router';
9
+ import type { IRouter } from '../routing/Router';
10
10
  import type { ISchedule } from '../scheduler/types';
11
11
  export interface IKernel {
12
12
  handle(req: IncomingMessage, res: ServerResponse): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"Kernel.d.ts","sourceRoot":"","sources":["../../../src/http/Kernel.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAEhE,OAAO,EAAE,QAAQ,EAAW,MAAM,eAAe,CAAC;AAElD,OAAO,EAAE,SAAS,EAAY,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAmB,MAAM,6BAA6B,CAAC;AAC5F,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAU,MAAM,iBAAiB,CAAC;AAGlD,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,mBAAmB,CAAC;AAGpE,MAAM,WAAW,OAAO;IACtB,MAAM,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjE,aAAa,CAAC,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,SAAS,CAAC,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,SAAS,GAAG,IAAI,CAAC;IAC/C,wBAAwB,CAAC,GAAG,UAAU,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;IAC5D,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IACpE,SAAS,IAAI,OAAO,CAAC;IACrB,YAAY,IAAI,iBAAiB,CAAC;IAClC,kBAAkB,IAAI,gBAAgB,CAAC;IAGvC,gBAAgB,CAAC,QAAQ,EAAE,SAAS,GAAG,IAAI,CAAC;IAC5C,cAAc,IAAI,IAAI,CAAC;IACvB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9C;AAuJD,eAAO,MAAM,MAAM;qBA1DK,OAAO,aAAa,iBAAiB,KAAG,OAAO;EA4DrE,CAAC;AAEH,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"Kernel.d.ts","sourceRoot":"","sources":["../../../src/http/Kernel.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAG9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAEhF,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC7E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAO/C,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,mBAAmB,CAAC;AAGpE,MAAM,WAAW,OAAO;IACtB,MAAM,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjE,aAAa,CAAC,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,SAAS,CAAC,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,SAAS,GAAG,IAAI,CAAC;IAC/C,wBAAwB,CAAC,GAAG,UAAU,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;IAC5D,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IACpE,SAAS,IAAI,OAAO,CAAC;IACrB,YAAY,IAAI,iBAAiB,CAAC;IAClC,kBAAkB,IAAI,gBAAgB,CAAC;IAGvC,gBAAgB,CAAC,QAAQ,EAAE,SAAS,GAAG,IAAI,CAAC;IAC5C,cAAc,IAAI,IAAI,CAAC;IACvB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9C;AAuTD,eAAO,MAAM,MAAM;qBA1DK,OAAO,aAAa,iBAAiB,KAAG,OAAO;EA4DrE,CAAC;AAEH,eAAe,MAAM,CAAC"}
@@ -3,12 +3,14 @@
3
3
  */
4
4
  import { Logger } from '../config/logger.js';
5
5
  import { middlewareConfig } from '../config/middleware.js';
6
- import { ErrorResponse } from './ErrorResponse.js';
7
6
  import { Request } from './Request.js';
8
7
  import { RequestContext } from './RequestContext.js';
9
8
  import { Response } from './Response.js';
10
9
  import { MiddlewareStack } from '../middleware/MiddlewareStack.js';
11
10
  import { Router } from '../routing/Router.js';
11
+ import { ErrorRouting } from '../routing/error.js';
12
+ import { OpenTelemetry } from '../observability/OpenTelemetry.js';
13
+ import { PrometheusMetrics } from '../observability/PrometheusMetrics.js';
12
14
  import { create as createScheduleRunner } from '../scheduler/ScheduleRunner.js';
13
15
  import { Env } from '../config/env.js';
14
16
  /**
@@ -27,6 +29,27 @@ const isWritableEnded = (res) => {
27
29
  return false;
28
30
  return Boolean(raw.writableEnded);
29
31
  };
32
+ const getStatusSafe = (res) => {
33
+ try {
34
+ if (typeof res.getStatus === 'function')
35
+ return res.getStatus();
36
+ }
37
+ catch {
38
+ // ignore
39
+ }
40
+ try {
41
+ if (typeof res.getRaw === 'function') {
42
+ const raw = res.getRaw();
43
+ const maybeStatusCode = raw.statusCode;
44
+ if (typeof maybeStatusCode === 'number')
45
+ return maybeStatusCode;
46
+ }
47
+ }
48
+ catch {
49
+ // ignore
50
+ }
51
+ return 0;
52
+ };
30
53
  const resolveMiddlewareForRoute = (route, globalMiddleware, routeMiddleware) => {
31
54
  const routeAny = route;
32
55
  const routeMiddlewareNames = Array.isArray(routeAny.middleware)
@@ -37,41 +60,134 @@ const resolveMiddlewareForRoute = (route, globalMiddleware, routeMiddleware) =>
37
60
  .filter((mw) => typeof mw === 'function');
38
61
  return [...globalMiddleware, ...resolvedRouteMiddleware];
39
62
  };
63
+ const maybeStartKernelTraceSpan = (req, context) => {
64
+ if (OpenTelemetry.isEnabled() === false)
65
+ return undefined;
66
+ try {
67
+ return OpenTelemetry.startHttpServerSpan(req, {
68
+ method: context.method,
69
+ path: req.getPath(),
70
+ requestId: context.requestId,
71
+ serviceName: Env.APP_NAME,
72
+ userAgent: context.userAgent,
73
+ userId: context.userId,
74
+ tenantId: context.tenantId,
75
+ });
76
+ }
77
+ catch {
78
+ return undefined;
79
+ }
80
+ };
81
+ const maybeSetKernelTraceRoute = (traceSpan, method, routeLabel) => {
82
+ if (!traceSpan)
83
+ return;
84
+ OpenTelemetry.setHttpRoute(traceSpan.span, method, routeLabel);
85
+ };
86
+ const runKernelPipeline = async (router, globalMiddleware, routeMiddleware, req, res, context, traceSpan) => {
87
+ Logger.info(`[${req.getMethod()}] ${req.getPath()}`);
88
+ const route = Router.match(router, req.getMethod(), req.getPath());
89
+ if (!route) {
90
+ const routeLabel = 'not_found';
91
+ maybeSetKernelTraceRoute(traceSpan, context.method, routeLabel);
92
+ ErrorRouting.handleNotFound(req, res, context.requestId);
93
+ return routeLabel;
94
+ }
95
+ // Safe type guard to ensure route.routePath is a non-empty string before calling .trim()
96
+ const hasNonEmptyRoutePath = (r) => {
97
+ if (typeof r !== 'object' || r === null)
98
+ return false;
99
+ const rp = r.routePath;
100
+ return typeof rp === 'string' && rp.trim() !== '';
101
+ };
102
+ const routeLabel = hasNonEmptyRoutePath(route) ? route.routePath : req.getPath();
103
+ maybeSetKernelTraceRoute(traceSpan, context.method, routeLabel);
104
+ // Use a typed view of the matched route to avoid unsafe member access
105
+ const matchedRoute = route;
106
+ // Coerce route params (which may be undefined or non-string) into the
107
+ // expected Record<string, string> shape required by Request.setParams.
108
+ const safeParams = {};
109
+ if (typeof matchedRoute.params === 'object' && matchedRoute.params !== null) {
110
+ for (const [k, v] of Object.entries(matchedRoute.params)) {
111
+ if (v === undefined || v === null)
112
+ continue;
113
+ safeParams[k] = typeof v === 'string' ? v : String(v);
114
+ }
115
+ }
116
+ req.setParams(safeParams);
117
+ const middlewareToRun = resolveMiddlewareForRoute(matchedRoute, globalMiddleware, routeMiddleware);
118
+ let index = 0;
119
+ const next = async () => {
120
+ if (index < middlewareToRun.length) {
121
+ const mw = middlewareToRun[index++];
122
+ await mw(req, res, next);
123
+ return;
124
+ }
125
+ await matchedRoute.handler(req, res);
126
+ };
127
+ await next();
128
+ return routeLabel;
129
+ };
130
+ const finalizeKernelObservability = (context, res, routeLabel, thrown, traceSpan) => {
131
+ if (Env.getBool('METRICS_ENABLED', false)) {
132
+ const status = getStatusSafe(res);
133
+ const durationMs = Date.now() - context.startTime;
134
+ void PrometheusMetrics.observeHttpRequest({
135
+ method: context.method,
136
+ route: routeLabel,
137
+ status,
138
+ durationMs,
139
+ }).catch(() => {
140
+ // best-effort
141
+ });
142
+ }
143
+ if (traceSpan) {
144
+ const status = getStatusSafe(res);
145
+ // Late-bind context-derived attributes so auth/tenant middleware can populate them.
146
+ try {
147
+ if (typeof context.userId === 'string' && context.userId.trim() !== '') {
148
+ traceSpan.span.setAttribute('enduser.id', context.userId);
149
+ }
150
+ if (typeof context.tenantId === 'string' && context.tenantId.trim() !== '') {
151
+ traceSpan.span.setAttribute('zintrust.tenant_id', context.tenantId);
152
+ }
153
+ if (typeof context.traceId === 'string' && context.traceId.trim() !== '') {
154
+ traceSpan.span.setAttribute('zintrust.trace_id', context.traceId);
155
+ }
156
+ }
157
+ catch {
158
+ // best-effort
159
+ }
160
+ OpenTelemetry.endHttpServerSpan(traceSpan.span, {
161
+ route: routeLabel,
162
+ status,
163
+ error: thrown,
164
+ });
165
+ }
166
+ };
40
167
  const createHandleRequest = (router, globalMiddleware, routeMiddleware) => {
41
168
  return async (req, res) => {
42
169
  const context = RequestContext.create(req);
170
+ let routeLabel = 'unmatched';
171
+ let traceSpan;
172
+ let thrown;
43
173
  try {
44
174
  await RequestContext.run(context, async () => {
45
- Logger.info(`[${req.getMethod()}] ${req.getPath()}`);
46
- // Match route
47
- const route = Router.match(router, req.getMethod(), req.getPath());
48
- if (!route) {
49
- res.setStatus(404).json(ErrorResponse.notFound('Route', context.requestId));
50
- return;
51
- }
52
- req.setParams(route.params);
53
- const middlewareToRun = resolveMiddlewareForRoute(route, globalMiddleware, routeMiddleware);
54
- let index = 0;
55
- const next = async () => {
56
- if (index < middlewareToRun.length) {
57
- const mw = middlewareToRun[index++];
58
- await mw(req, res, next);
59
- return;
60
- }
61
- await route.handler(req, res);
62
- };
63
- await next();
175
+ traceSpan = maybeStartKernelTraceSpan(req, context);
176
+ const run = async () => runKernelPipeline(router, globalMiddleware, routeMiddleware, req, res, context, traceSpan);
177
+ routeLabel = traceSpan
178
+ ? await OpenTelemetry.runWithContext(traceSpan.context, run)
179
+ : await run();
64
180
  });
65
181
  }
66
182
  catch (error) {
183
+ thrown = error;
67
184
  Logger.error('Kernel error:', error);
68
185
  if (!isWritableEnded(res)) {
69
- res
70
- .setStatus(500)
71
- .json(ErrorResponse.internalServerError('Internal server error', context.requestId));
186
+ ErrorRouting.handleInternalServerErrorWithWrappers(req, res, error, context.requestId);
72
187
  }
73
188
  }
74
189
  finally {
190
+ finalizeKernelObservability(context, res, routeLabel, thrown, traceSpan);
75
191
  terminate(req, res);
76
192
  }
77
193
  };
@@ -2,7 +2,8 @@
2
2
  * Request - HTTP Request wrapper
3
3
  * Wraps Node.js IncomingMessage with additional utilities
4
4
  */
5
- import * as http from '../node-singletons/http';
5
+ import type { FileUploadOptions, IFileUploadHandler, UploadedFile } from './FileUpload';
6
+ import type * as http from '../node-singletons/http';
6
7
  type HeadParam = string | string[] | undefined;
7
8
  type JwtPayload = import('../index').JwtPayload;
8
9
  export interface IRequest {
@@ -10,6 +11,12 @@ export interface IRequest {
10
11
  user: JwtPayload | undefined;
11
12
  params: Record<string, string>;
12
13
  body: Record<string, unknown>;
14
+ validated: {
15
+ body?: unknown;
16
+ query?: unknown;
17
+ params?: unknown;
18
+ headers?: unknown;
19
+ };
13
20
  getMethod(): string;
14
21
  getPath(): string;
15
22
  getHeaders(): http.IncomingHttpHeaders;
@@ -25,7 +32,19 @@ export interface IRequest {
25
32
  isJson(): boolean;
26
33
  getRaw(): http.IncomingMessage;
27
34
  context: Record<string, unknown>;
35
+ file(fieldName: string, options?: FileUploadOptions): UploadedFile | undefined;
36
+ files(fieldName: string, options?: FileUploadOptions): UploadedFile[];
37
+ hasFile(fieldName: string): boolean;
38
+ fileUpload(): IFileUploadHandler;
28
39
  }
40
+ export type ValidatedRequest<TBody = unknown, TQuery = unknown, TParams = unknown, THeaders = unknown> = Omit<IRequest, 'validated'> & {
41
+ validated: {
42
+ body: TBody;
43
+ query: TQuery;
44
+ params: TParams;
45
+ headers: THeaders;
46
+ };
47
+ };
29
48
  export declare const Request: Readonly<{
30
49
  /**
31
50
  * Create a new request instance
@@ -1 +1 @@
1
- {"version":3,"file":"Request.d.ts","sourceRoot":"","sources":["../../../src/http/Request.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,IAAI,MAAM,uBAAuB,CAAC;AAE9C,KAAK,SAAS,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC;AAC/C,KAAK,UAAU,GAAG,OAAO,SAAS,EAAE,UAAU,CAAC;AAE/C,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,SAAS,CAAC;IACrB,IAAI,EAAE,UAAU,GAAG,SAAS,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,SAAS,IAAI,MAAM,CAAC;IACpB,OAAO,IAAI,MAAM,CAAC;IAClB,UAAU,IAAI,IAAI,CAAC,mBAAmB,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,mBAAmB,CAAC;IAC3C,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,SAAS,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAC1C,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IAChD,QAAQ,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IAC9C,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7B,OAAO,IAAI,OAAO,CAAC;IACnB,MAAM,IAAI,OAAO,CAAC;IAClB,MAAM,IAAI,IAAI,CAAC,eAAe,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAkKD,eAAO,MAAM,OAAO;IAClB;;OAEG;gBACS,IAAI,CAAC,eAAe,GAAG,QAAQ;EAO3C,CAAC;AAEH,eAAe,OAAO,CAAC"}
1
+ {"version":3,"file":"Request.d.ts","sourceRoot":"","sources":["../../../src/http/Request.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAE5F,OAAO,KAAK,KAAK,IAAI,MAAM,uBAAuB,CAAC;AAEnD,KAAK,SAAS,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC;AAC/C,KAAK,UAAU,GAAG,OAAO,SAAS,EAAE,UAAU,CAAC;AAE/C,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,SAAS,CAAC;IACrB,IAAI,EAAE,UAAU,GAAG,SAAS,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,SAAS,EAAE;QACT,IAAI,CAAC,EAAE,OAAO,CAAC;QACf,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,CAAC;IACF,SAAS,IAAI,MAAM,CAAC;IACpB,OAAO,IAAI,MAAM,CAAC;IAClB,UAAU,IAAI,IAAI,CAAC,mBAAmB,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,mBAAmB,CAAC;IAC3C,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,SAAS,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAC1C,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IAChD,QAAQ,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IAC9C,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7B,OAAO,IAAI,OAAO,CAAC;IACnB,MAAM,IAAI,OAAO,CAAC;IAClB,MAAM,IAAI,IAAI,CAAC,eAAe,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAGjC,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,YAAY,GAAG,SAAS,CAAC;IAC/E,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,YAAY,EAAE,CAAC;IACtE,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;IACpC,UAAU,IAAI,kBAAkB,CAAC;CAClC;AAED,MAAM,MAAM,gBAAgB,CAC1B,KAAK,GAAG,OAAO,EACf,MAAM,GAAG,OAAO,EAChB,OAAO,GAAG,OAAO,EACjB,QAAQ,GAAG,OAAO,IAChB,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG;IAChC,SAAS,EAAE;QACT,IAAI,EAAE,KAAK,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,OAAO,CAAC;QAChB,OAAO,EAAE,QAAQ,CAAC;KACnB,CAAC;CACH,CAAC;AAoMF,eAAO,MAAM,OAAO;IAClB;;OAEG;gBACS,IAAI,CAAC,eAAe,GAAG,QAAQ;EAO3C,CAAC;AAEH,eAAe,OAAO,CAAC"}
@@ -2,6 +2,7 @@
2
2
  * Request - HTTP Request wrapper
3
3
  * Wraps Node.js IncomingMessage with additional utilities
4
4
  */
5
+ import { FileUpload } from './FileUpload.js';
5
6
  /**
6
7
  * Request - HTTP Request wrapper
7
8
  * Refactored to Functional Object pattern
@@ -39,6 +40,7 @@ const createRequestState = (req) => {
39
40
  params: {},
40
41
  body: null,
41
42
  bodyRecord: {},
43
+ validated: {},
42
44
  };
43
45
  };
44
46
  const setBodyState = (state, newBody) => {
@@ -72,6 +74,12 @@ const createRequestProperties = (state, context) => {
72
74
  set body(newBody) {
73
75
  setBodyState(state, newBody);
74
76
  },
77
+ get validated() {
78
+ return state.validated;
79
+ },
80
+ set validated(v) {
81
+ state.validated = v;
82
+ },
75
83
  };
76
84
  };
77
85
  const createRequestMethods = (req, query, state) => {
@@ -117,6 +125,21 @@ const createRequestMethods = (req, query, state) => {
117
125
  const contentType = this.getHeader('content-type');
118
126
  return typeof contentType === 'string' && contentType.includes('application/json');
119
127
  },
128
+ file(fieldName, options) {
129
+ const handler = FileUpload.createHandler(this);
130
+ return handler.file(fieldName, options);
131
+ },
132
+ files(fieldName, options) {
133
+ const handler = FileUpload.createHandler(this);
134
+ return handler.files(fieldName, options);
135
+ },
136
+ hasFile(fieldName) {
137
+ const handler = FileUpload.createHandler(this);
138
+ return handler.hasFile(fieldName);
139
+ },
140
+ fileUpload() {
141
+ return FileUpload.createHandler(this);
142
+ },
120
143
  getRaw() {
121
144
  return req;
122
145
  },
@@ -1,6 +1,9 @@
1
1
  import type { IRequest } from './Request';
2
2
  export interface IRequestContext {
3
3
  requestId: string;
4
+ traceId?: string;
5
+ userId?: string;
6
+ tenantId?: string;
4
7
  startTime: number;
5
8
  method: string;
6
9
  path: string;
@@ -15,6 +18,9 @@ export declare const RequestContext: Readonly<{
15
18
  attach(req: IRequest, context: IRequestContext): void;
16
19
  get(req: IRequest): IRequestContext | undefined;
17
20
  enrich(context: IRequestContext, status: number): IRequestContext;
21
+ setUserId(req: IRequest, userId: string | undefined): void;
22
+ setTenantId(req: IRequest, tenantId: string | undefined): void;
23
+ setTraceId(req: IRequest, traceId: string | undefined): void;
18
24
  }>;
19
25
  export default RequestContext;
20
26
  //# sourceMappingURL=RequestContext.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"RequestContext.d.ts","sourceRoot":"","sources":["../../../src/http/RequestContext.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AA6CD,eAAO,MAAM,cAAc;QACf,CAAC,WAAW,eAAe,YAAY,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;eAKpD,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC;gBAKzC,QAAQ,GAAG,eAAe;gBAoB1B,QAAQ,WAAW,eAAe,GAAG,IAAI;aAM5C,QAAQ,GAAG,eAAe,GAAG,SAAS;oBAM/B,eAAe,UAAU,MAAM,GAAG,eAAe;EAQjE,CAAC;AAEH,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"RequestContext.d.ts","sourceRoot":"","sources":["../../../src/http/RequestContext.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAgGD,eAAO,MAAM,cAAc;QACf,CAAC,WAAW,eAAe,YAAY,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;eAKpD,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC;gBAKzC,QAAQ,GAAG,eAAe;gBAmC1B,QAAQ,WAAW,eAAe,GAAG,IAAI;aAS5C,QAAQ,GAAG,eAAe,GAAG,SAAS;oBAM/B,eAAe,UAAU,MAAM,GAAG,eAAe;mBASlD,QAAQ,UAAU,MAAM,GAAG,SAAS,GAAG,IAAI;qBAIzC,QAAQ,YAAY,MAAM,GAAG,SAAS,GAAG,IAAI;oBAI9C,QAAQ,WAAW,MAAM,GAAG,SAAS,GAAG,IAAI;EAG5D,CAAC;AAEH,eAAe,cAAc,CAAC"}
@@ -1,4 +1,4 @@
1
- import { generateUuid } from '../common/uuid.js';
1
+ import { generateUuid } from '../common/utility.js';
2
2
  const createFallbackStorage = () => {
3
3
  let store;
4
4
  return {
@@ -30,6 +30,52 @@ const getHeaderString = (req, name) => {
30
30
  const value = req.getHeader(name);
31
31
  return typeof value === 'string' ? value : undefined;
32
32
  };
33
+ const extractTraceIdFromTraceparent = (traceparent) => {
34
+ if (typeof traceparent !== 'string')
35
+ return undefined;
36
+ const trimmed = traceparent.trim();
37
+ if (trimmed === '')
38
+ return undefined;
39
+ // W3C traceparent: version-traceid-spanid-flags
40
+ // Example: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
41
+ const parts = trimmed.split('-');
42
+ if (parts.length !== 4)
43
+ return undefined;
44
+ const traceId = parts[1] ?? '';
45
+ if (/^[0-9a-f]{32}$/i.test(traceId) === false)
46
+ return undefined;
47
+ // Disallow all-zero traceId
48
+ if (/^0{32}$/i.test(traceId))
49
+ return undefined;
50
+ return traceId.toLowerCase();
51
+ };
52
+ const getTraceIdFromMicroserviceTraceContext = (req) => {
53
+ const anyReq = req;
54
+ const trace = anyReq.context?.['trace'];
55
+ if (typeof trace !== 'object' || trace === null)
56
+ return undefined;
57
+ const traceId = trace.traceId;
58
+ return typeof traceId === 'string' && traceId.trim() !== '' ? traceId : undefined;
59
+ };
60
+ const getOptionalContextString = (req, key) => {
61
+ const anyReq = req;
62
+ const value = anyReq.context?.[key];
63
+ if (typeof value === 'string')
64
+ return value;
65
+ if (typeof value === 'number')
66
+ return String(value);
67
+ return undefined;
68
+ };
69
+ const setContextField = (req, field, value) => {
70
+ req.context ??= {};
71
+ if (typeof value === 'string' && value.trim() !== '') {
72
+ req.context[field] = value;
73
+ }
74
+ const ctx = RequestContext.get(req);
75
+ if (ctx) {
76
+ ctx[field] = value;
77
+ }
78
+ };
33
79
  const STORAGE_PROMISE = resolveStorage();
34
80
  export const RequestContext = Object.freeze({
35
81
  async run(context, callback) {
@@ -44,14 +90,29 @@ export const RequestContext = Object.freeze({
44
90
  req.context ??= {};
45
91
  const requestIdFromHeader = getHeaderString(req, 'x-request-id');
46
92
  const requestId = requestIdFromHeader ?? generateUuid();
93
+ const traceId = extractTraceIdFromTraceparent(getHeaderString(req, 'traceparent')) ??
94
+ getHeaderString(req, 'x-trace-id') ??
95
+ getTraceIdFromMicroserviceTraceContext(req) ??
96
+ getOptionalContextString(req, 'traceId');
97
+ const userId = getOptionalContextString(req, 'userId');
98
+ const tenantId = getOptionalContextString(req, 'tenantId');
47
99
  const ctx = {
48
100
  requestId,
101
+ traceId,
102
+ userId,
103
+ tenantId,
49
104
  startTime: Date.now(),
50
105
  method: req.getMethod(),
51
106
  path: req.getPath(),
52
107
  userAgent: getHeaderString(req, 'user-agent'),
53
108
  };
54
109
  req.context['requestId'] = requestId;
110
+ if (traceId !== undefined)
111
+ req.context['traceId'] = traceId;
112
+ if (userId !== undefined)
113
+ req.context['userId'] = userId;
114
+ if (tenantId !== undefined)
115
+ req.context['tenantId'] = tenantId;
55
116
  req.context['requestContext'] = ctx;
56
117
  return ctx;
57
118
  },
@@ -59,6 +120,12 @@ export const RequestContext = Object.freeze({
59
120
  req.context ??= {};
60
121
  req.context['requestContext'] = context;
61
122
  req.context['requestId'] = context.requestId;
123
+ if (context.traceId !== undefined)
124
+ req.context['traceId'] = context.traceId;
125
+ if (context.userId !== undefined)
126
+ req.context['userId'] = context.userId;
127
+ if (context.tenantId !== undefined)
128
+ req.context['tenantId'] = context.tenantId;
62
129
  },
63
130
  get(req) {
64
131
  const anyReq = req;
@@ -73,5 +140,14 @@ export const RequestContext = Object.freeze({
73
140
  duration,
74
141
  };
75
142
  },
143
+ setUserId(req, userId) {
144
+ setContextField(req, 'userId', userId);
145
+ },
146
+ setTenantId(req, tenantId) {
147
+ setContextField(req, 'tenantId', tenantId);
148
+ },
149
+ setTraceId(req, traceId) {
150
+ setContextField(req, 'traceId', traceId);
151
+ },
76
152
  });
77
153
  export default RequestContext;
@@ -2,7 +2,7 @@
2
2
  * Response - HTTP Response wrapper
3
3
  * Wraps Node.js ServerResponse with additional utilities
4
4
  */
5
- import * as http from '../node-singletons/http';
5
+ import type * as http from '../node-singletons/http';
6
6
  export interface IResponse {
7
7
  status(code: number): IResponse;
8
8
  setStatus(code: number): IResponse;