@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,412 @@
1
+ /**
2
+ * Input Sanitizer (Character Whitelisting)
3
+ *
4
+ * Provides small utilities to remove unwanted characters from user input.
5
+ *
6
+ * Important:
7
+ * - This is NOT a complete SQL injection defense.
8
+ * - Always use parameterized queries / the ORM / QueryBuilder.
9
+ *
10
+ * Use this for:
11
+ * - Normalizing identifiers (username, slug-ish strings)
12
+ * - Cleaning phone numbers / numeric strings
13
+ * - Reducing unexpected characters before storage/logging
14
+ *
15
+ * Bulletproof Mode:
16
+ * - Enabled by default (`bulletproof=true`) for security-critical methods
17
+ * - Throws SanitizerError instead of returning empty/invalid values
18
+ * - Validates numeric ranges, leading zeros, type coercion attacks
19
+ * - ~5-15% performance overhead; disable for performance-critical paths
20
+ */
21
+ import { ErrorFactory } from '../exceptions/ZintrustError.js';
22
+ const MAX_NUMERIC_INPUT_LEN = 64;
23
+ const MAX_EMAIL_LEN = 254;
24
+ const MAX_NAME_LEN = 200;
25
+ const MAX_PASSWORD_LEN = 256;
26
+ const assertMaxLen = (method, label, value, maxLen) => {
27
+ if (value.length <= maxLen)
28
+ return;
29
+ throw ErrorFactory.createSanitizerError(method, `${label} too long`, value);
30
+ };
31
+ const isEmpty = (value) => {
32
+ // Preserve legacy semantics: treat 0 and "0" as empty.
33
+ return (value === null ||
34
+ value === undefined ||
35
+ value === false ||
36
+ value === 0 ||
37
+ value === '' ||
38
+ value === '0');
39
+ };
40
+ const toStr = (value) => {
41
+ return String(value ?? '');
42
+ };
43
+ const stripSpaces = (value) => {
44
+ return toStr(value).replaceAll(' ', '');
45
+ };
46
+ const sanitize = (value, pattern, stripSpace = false) => {
47
+ const input = stripSpace ? stripSpaces(value) : toStr(value);
48
+ return input.replace(pattern, '');
49
+ };
50
+ const isNumericString = (value) => {
51
+ const trimmed = value.trim();
52
+ if (trimmed.length === 0)
53
+ return false;
54
+ const n = Number(trimmed);
55
+ return Number.isFinite(n);
56
+ };
57
+ const parseAmount = (value, bulletproof = true) => {
58
+ if (isEmpty(value))
59
+ return 0;
60
+ const cleaned = sanitize(value, /[^0-9.-]/g, true);
61
+ const num = Number(cleaned);
62
+ if (bulletproof) {
63
+ // Handle string edge cases - check original value
64
+ const str = String(value);
65
+ const trimmed = str.trim();
66
+ assertMaxLen('parseAmount', 'Input', trimmed, MAX_NUMERIC_INPUT_LEN);
67
+ // Reject explicit plus sign prefixes (type confusion)
68
+ if (trimmed.startsWith('+')) {
69
+ throw ErrorFactory.createSanitizerError('parseAmount', 'Plus sign not allowed', value);
70
+ }
71
+ // Reject "Infinity", "-Infinity", "NaN" explicitly
72
+ if (/^[+-]?infinity$/i.test(trimmed) || /^nan$/i.test(trimmed)) {
73
+ throw ErrorFactory.createSanitizerError('parseAmount', 'Non-finite number', value);
74
+ }
75
+ // Reject scientific notation (e.g., "1e308", "2.5e10")
76
+ if (/[eE]/.test(trimmed)) {
77
+ throw ErrorFactory.createSanitizerError('parseAmount', 'Scientific notation not allowed', value);
78
+ }
79
+ assertMaxLen('parseAmount', 'Sanitized numeric', cleaned, MAX_NUMERIC_INPUT_LEN);
80
+ // Require a strict numeric shape after sanitization (prevents "1-2" -> NaN etc.)
81
+ if (!/^-?\d+(?:\.\d+)?$/.test(cleaned)) {
82
+ throw ErrorFactory.createSanitizerError('parseAmount', 'Invalid numeric format', value);
83
+ }
84
+ // Reject Infinity, NaN, and overflow attacks
85
+ if (!Number.isFinite(num)) {
86
+ throw ErrorFactory.createSanitizerError('parseAmount', 'Non-finite number', value);
87
+ }
88
+ if (Math.abs(num) > Number.MAX_SAFE_INTEGER) {
89
+ throw ErrorFactory.createSanitizerError('parseAmount', 'Number exceeds safe integer range', value);
90
+ }
91
+ }
92
+ return Number.isFinite(num) ? num : 0;
93
+ };
94
+ const alphanumeric = (value) => {
95
+ if (isEmpty(value))
96
+ return '';
97
+ return sanitize(value, /[^A-Za-z0-9]/g, true);
98
+ };
99
+ const alphanumericDotDash = (value) => {
100
+ if (isEmpty(value))
101
+ return '';
102
+ return sanitize(value, /[^A-Za-z0-9\-.]/g, true);
103
+ };
104
+ const validateNonNegativeNumericStringPreSanitization = (trimmed, value) => {
105
+ assertMaxLen('nonNegativeNumericStringOrNull', 'Input', trimmed, MAX_NUMERIC_INPUT_LEN);
106
+ // Reject explicit plus sign prefixes (type confusion)
107
+ if (trimmed.startsWith('+')) {
108
+ throw ErrorFactory.createSanitizerError('nonNegativeNumericStringOrNull', 'Plus sign not allowed', value);
109
+ }
110
+ // Reject scientific notation before sanitization can mask it
111
+ if (/[eE]/.test(trimmed)) {
112
+ throw ErrorFactory.createSanitizerError('nonNegativeNumericStringOrNull', 'Scientific notation not allowed', value);
113
+ }
114
+ };
115
+ const validateNonNegativeNumericStringPostSanitization = (da, value) => {
116
+ assertMaxLen('nonNegativeNumericStringOrNull', 'Sanitized numeric', da, MAX_NUMERIC_INPUT_LEN);
117
+ // Strict shape: allow optional leading '-' and optional fractional part.
118
+ if (!/^-?\d+(?:\.\d+)?$/.test(da)) {
119
+ throw ErrorFactory.createSanitizerError('nonNegativeNumericStringOrNull', 'Invalid numeric format', value);
120
+ }
121
+ // For integers (no decimal point), validate leading zeros
122
+ if (da.includes('.')) {
123
+ // For decimals, only check overflow
124
+ const num = Number(da);
125
+ if (Math.abs(num) > Number.MAX_SAFE_INTEGER) {
126
+ throw ErrorFactory.createSanitizerError('nonNegativeNumericStringOrNull', 'Number exceeds safe integer range', value);
127
+ }
128
+ }
129
+ else {
130
+ const numericId = Number.parseInt(da, 10);
131
+ if (!Number.isFinite(numericId) ||
132
+ numericId < 0 ||
133
+ numericId > Number.MAX_SAFE_INTEGER ||
134
+ numericId.toString() !== da) {
135
+ throw ErrorFactory.createSanitizerError('nonNegativeNumericStringOrNull', 'Invalid numeric format (leading zeros, overflow, or type mismatch)', value);
136
+ }
137
+ }
138
+ };
139
+ const nonNegativeNumericStringOrNull = (value, bulletproof = true) => {
140
+ if (isEmpty(value))
141
+ return 0;
142
+ const raw = stripSpaces(value);
143
+ if (bulletproof) {
144
+ const trimmed = raw.trim();
145
+ validateNonNegativeNumericStringPreSanitization(trimmed, value);
146
+ }
147
+ const da = raw.replaceAll(/[^0-9\-.]/g, '');
148
+ const numeric = isNumericString(da);
149
+ if (numeric && Number(da) < 0)
150
+ return 0;
151
+ if (!numeric) {
152
+ return null;
153
+ }
154
+ if (bulletproof) {
155
+ validateNonNegativeNumericStringPostSanitization(da, value);
156
+ }
157
+ return da;
158
+ };
159
+ const digitsOnly = (value, bulletproof = true) => {
160
+ // Special handling for '0' string
161
+ if (value === '0') {
162
+ if (bulletproof) {
163
+ throw ErrorFactory.createSanitizerError('digitsOnly', 'Invalid numeric ID (zero, negative, overflow, or leading zeros)', value);
164
+ }
165
+ return '0';
166
+ }
167
+ if (isEmpty(value))
168
+ return '';
169
+ const da = sanitize(value, /\D/g);
170
+ if (bulletproof) {
171
+ assertMaxLen('digitsOnly', 'Sanitized numeric', da, 16);
172
+ // After removing non-digits, check if result is empty
173
+ if (da.length === 0) {
174
+ throw ErrorFactory.createSanitizerError('digitsOnly', 'Empty result after removing non-digits', value);
175
+ }
176
+ // Check for special characters that get stripped (like +)
177
+ const str = String(value);
178
+ if (/^[+-]/.test(str.trim())) {
179
+ throw ErrorFactory.createSanitizerError('digitsOnly', 'Invalid numeric ID (starts with +/- sign)', value);
180
+ }
181
+ const numericId = Number.parseInt(da, 10);
182
+ if (!Number.isFinite(numericId) ||
183
+ numericId <= 0 ||
184
+ numericId > Number.MAX_SAFE_INTEGER ||
185
+ numericId.toString() !== da) {
186
+ throw ErrorFactory.createSanitizerError('digitsOnly', 'Invalid numeric ID (zero, negative, overflow, or leading zeros)', value);
187
+ }
188
+ }
189
+ return da.replaceAll(' ', '');
190
+ };
191
+ const validateDecimalStringPreSanitization = (trimmed, value) => {
192
+ assertMaxLen('decimalString', 'Input', trimmed, MAX_NUMERIC_INPUT_LEN);
193
+ // Reject explicit plus/minus prefixes and scientific notation (type confusion)
194
+ if (/^[+-]/.test(trimmed)) {
195
+ throw ErrorFactory.createSanitizerError('decimalString', 'Signed values not allowed', value);
196
+ }
197
+ if (/[eE]/.test(trimmed)) {
198
+ throw ErrorFactory.createSanitizerError('decimalString', 'Scientific notation not allowed', value);
199
+ }
200
+ };
201
+ const validateDecimalStringPostSanitization = (result, cleaned, value) => {
202
+ assertMaxLen('decimalString', 'Sanitized numeric', cleaned, MAX_NUMERIC_INPUT_LEN);
203
+ if (result.length === 0) {
204
+ throw ErrorFactory.createSanitizerError('decimalString', 'Empty result after sanitization', value);
205
+ }
206
+ if (!/^\d+(?:\.\d+)?$/.test(result)) {
207
+ throw ErrorFactory.createSanitizerError('decimalString', 'Invalid decimal format', value);
208
+ }
209
+ const num = Number(result);
210
+ if (!Number.isFinite(num)) {
211
+ throw ErrorFactory.createSanitizerError('decimalString', 'Non-numeric decimal value', value);
212
+ }
213
+ if (Math.abs(num) > Number.MAX_SAFE_INTEGER) {
214
+ throw ErrorFactory.createSanitizerError('decimalString', 'Decimal value exceeds safe range', value);
215
+ }
216
+ };
217
+ const decimalString = (value, bulletproof = true) => {
218
+ if (isEmpty(value))
219
+ return '';
220
+ if (bulletproof) {
221
+ const trimmed = String(value).trim();
222
+ validateDecimalStringPreSanitization(trimmed, value);
223
+ }
224
+ // Allow only valid decimal format: digits and at most one decimal point
225
+ const cleaned = sanitize(value, /[^0-9.]/g);
226
+ const parts = cleaned.split('.');
227
+ // Bulletproof mode: reject multiple decimal points rather than merging.
228
+ // Legacy/unsafe mode: normalize by keeping the first decimal point.
229
+ let result;
230
+ if (parts.length > 2) {
231
+ result = bulletproof ? '' : `${parts[0]}.${parts.slice(1).join('')}`;
232
+ }
233
+ else {
234
+ result = cleaned;
235
+ }
236
+ if (bulletproof) {
237
+ validateDecimalStringPostSanitization(result, cleaned, value);
238
+ }
239
+ return result;
240
+ };
241
+ const numericDotOnly = (value) => {
242
+ if (isEmpty(value))
243
+ return '';
244
+ return sanitize(value, /[^0-9.]/g);
245
+ };
246
+ const createBasicSanitizers = () => {
247
+ return {
248
+ parseAmount,
249
+ alphanumeric,
250
+ alphanumericDotDash,
251
+ nonNegativeNumericStringOrNull,
252
+ digitsOnly,
253
+ decimalString,
254
+ numericDotOnly,
255
+ };
256
+ };
257
+ const addressTextSanitizer = (value) => {
258
+ if (isEmpty(value))
259
+ return '';
260
+ return sanitize(value, /[^A-Za-z0-9\-.@+, _]/g);
261
+ };
262
+ const emailLikeSanitizer = (value) => {
263
+ if (isEmpty(value))
264
+ return '';
265
+ return sanitize(value, /[^A-Za-z0-9\-.@+_]/g);
266
+ };
267
+ const emailSanitizer = (value, bulletproof = true) => {
268
+ if (isEmpty(value))
269
+ return '';
270
+ const result = sanitize(value, /[^A-Za-z0-9\-.@_]/g);
271
+ if (bulletproof) {
272
+ const trimmed = result.trim();
273
+ assertMaxLen('email', 'Email', trimmed, MAX_EMAIL_LEN);
274
+ if (trimmed.length === 0) {
275
+ throw ErrorFactory.createSanitizerError('email', 'Empty result after sanitization', value);
276
+ }
277
+ if (!trimmed.includes('@')) {
278
+ throw ErrorFactory.createSanitizerError('email', 'Missing @ symbol in email', value);
279
+ }
280
+ // Basic validation: something@something
281
+ const parts = trimmed.split('@');
282
+ if (parts.length !== 2 || parts[0].length === 0 || parts[1].length === 0) {
283
+ throw ErrorFactory.createSanitizerError('email', 'Invalid email format', value);
284
+ }
285
+ }
286
+ return result;
287
+ };
288
+ const messageTextSanitizer = (value) => {
289
+ if (isEmpty(value))
290
+ return '';
291
+ return sanitize(value, /[^A-Za-z0-9\-.@+_&$%!,()? ]/g);
292
+ };
293
+ const nameTextSanitizer = (value, bulletproof = true) => {
294
+ if (isEmpty(value))
295
+ return '';
296
+ const result = sanitize(value, /[^A-Za-z0-9 .]/g);
297
+ if (bulletproof) {
298
+ const trimmed = result.trim();
299
+ assertMaxLen('nameText', 'Name', trimmed, MAX_NAME_LEN);
300
+ if (trimmed.length === 0) {
301
+ throw ErrorFactory.createSanitizerError('nameText', 'Empty or whitespace-only result', value);
302
+ }
303
+ // Names should have at least one letter
304
+ if (!/[A-Za-z]/.test(trimmed)) {
305
+ throw ErrorFactory.createSanitizerError('nameText', 'Name must contain at least one letter', value);
306
+ }
307
+ }
308
+ return result;
309
+ };
310
+ const wordCharsAndSpacesSanitizer = (value) => {
311
+ if (isEmpty(value))
312
+ return '';
313
+ return sanitize(value, /[^A-Za-z0-9_\s]/g);
314
+ };
315
+ const safePasswordCharsSanitizer = (value, bulletproof = true) => {
316
+ if (isEmpty(value))
317
+ return '';
318
+ const result = sanitize(value, /[^!@#$%&*/\sA-Za-z0-9_]/g);
319
+ if (bulletproof) {
320
+ const trimmed = result.trim();
321
+ assertMaxLen('safePasswordChars', 'Password', trimmed, MAX_PASSWORD_LEN);
322
+ if (trimmed.length === 0) {
323
+ throw ErrorFactory.createSanitizerError('safePasswordChars', 'Empty result after sanitization', value);
324
+ }
325
+ }
326
+ return result;
327
+ };
328
+ const createTextSanitizers = () => {
329
+ return {
330
+ addressText: addressTextSanitizer,
331
+ emailLike: emailLikeSanitizer,
332
+ email: emailSanitizer,
333
+ messageText: messageTextSanitizer,
334
+ nameText: nameTextSanitizer,
335
+ wordCharsAndSpaces: wordCharsAndSpacesSanitizer,
336
+ safePasswordChars: safePasswordCharsSanitizer,
337
+ };
338
+ };
339
+ const createSpecializedSanitizers = () => {
340
+ const ipAddressText = (value) => {
341
+ if (isEmpty(value))
342
+ return '';
343
+ return sanitize(value, /[^A-Za-z0-9:.]/g);
344
+ };
345
+ const alphaNumericColonDash = (value) => {
346
+ if (isEmpty(value))
347
+ return '';
348
+ return sanitize(value, /[^A-Za-z0-9:-]/g);
349
+ };
350
+ const dateSlash = (value) => {
351
+ if (isEmpty(value))
352
+ return '';
353
+ return sanitize(value, /[^0-9/]/g);
354
+ };
355
+ const lowercaseAlphanumeric = (value) => {
356
+ if (isEmpty(value))
357
+ return '';
358
+ return sanitize(value, /[^A-Za-z0-9]/g).toLowerCase();
359
+ };
360
+ const uppercaseAlphanumeric = (value) => {
361
+ if (isEmpty(value))
362
+ return '';
363
+ return sanitize(value, /[^A-Za-z0-9]/g).toUpperCase();
364
+ };
365
+ const alphanumericNoSpaces = (value) => {
366
+ if (isEmpty(value))
367
+ return '';
368
+ return sanitize(value, /[^A-Za-z0-9 ]/g, true);
369
+ };
370
+ const dateSlashNoSpaces = (value) => {
371
+ if (isEmpty(value))
372
+ return '';
373
+ return sanitize(value, /[^0-9/]/g, true);
374
+ };
375
+ // Legacy naming was misleading; this is closer to a "uuid/token safe" whitelist.
376
+ const uuidTokenSafe = (value) => {
377
+ if (isEmpty(value))
378
+ return '';
379
+ return sanitize(value, /[^A-Za-z0-9\-=]/g, true);
380
+ };
381
+ // Base64url-like (plus "=") token whitelisting.
382
+ const tokenSafe = (value) => {
383
+ if (isEmpty(value))
384
+ return '';
385
+ return sanitize(value, /[^A-Za-z0-9\-=_]/g, true);
386
+ };
387
+ const keyLike = (value) => {
388
+ if (isEmpty(value))
389
+ return '';
390
+ return sanitize(value, /[^A-Za-z0-9\-:. ]/g, true);
391
+ };
392
+ return {
393
+ ipAddressText,
394
+ alphaNumericColonDash,
395
+ dateSlash,
396
+ lowercaseAlphanumeric,
397
+ uppercaseAlphanumeric,
398
+ alphanumericNoSpaces,
399
+ dateSlashNoSpaces,
400
+ uuidTokenSafe,
401
+ tokenSafe,
402
+ keyLike,
403
+ };
404
+ };
405
+ export const createSanitizer = () => {
406
+ return Object.freeze({
407
+ ...createBasicSanitizers(),
408
+ ...createTextSanitizers(),
409
+ ...createSpecializedSanitizers(),
410
+ });
411
+ };
412
+ export const Sanitizer = createSanitizer();
@@ -0,0 +1,7 @@
1
+ type AuthorizationHeader = string | string[] | undefined;
2
+ export declare const TokenRevocation: Readonly<{
3
+ revoke(header: AuthorizationHeader): string | null;
4
+ isRevoked(token: string): boolean;
5
+ }>;
6
+ export default TokenRevocation;
7
+ //# sourceMappingURL=TokenRevocation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TokenRevocation.d.ts","sourceRoot":"","sources":["../../../src/security/TokenRevocation.ts"],"names":[],"mappings":"AAGA,KAAK,mBAAmB,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC;AAsCzD,eAAO,MAAM,eAAe;mBACX,mBAAmB,GAAG,MAAM,GAAG,IAAI;qBASjC,MAAM,GAAG,OAAO;EAUjC,CAAC;AAEH,eAAe,eAAe,CAAC"}
@@ -0,0 +1,57 @@
1
+ import { securityConfig } from '../config/security.js';
2
+ import { JwtManager } from './JwtManager.js';
3
+ const revokedTokens = new Map();
4
+ const defaultTtlMs = Math.max(securityConfig.jwt.expiresIn * 1000, 60_000);
5
+ const getBearerToken = (header) => {
6
+ const value = Array.isArray(header) ? header[0] : header;
7
+ if (typeof value !== 'string')
8
+ return null;
9
+ const [scheme, token] = value.trim().split(' ');
10
+ if (scheme.toLowerCase() !== 'bearer')
11
+ return null;
12
+ if (typeof token !== 'string' || token.trim() === '')
13
+ return null;
14
+ return token;
15
+ };
16
+ const cleanupExpired = () => {
17
+ const now = Date.now();
18
+ for (const [token, expiresAt] of revokedTokens.entries()) {
19
+ if (expiresAt <= now) {
20
+ revokedTokens.delete(token);
21
+ }
22
+ }
23
+ };
24
+ const resolveExpiryMs = (token) => {
25
+ try {
26
+ const payload = JwtManager.create().decode(token);
27
+ if (typeof payload.exp === 'number' && Number.isFinite(payload.exp)) {
28
+ return payload.exp * 1000;
29
+ }
30
+ }
31
+ catch {
32
+ // ignore decode errors; fallback to default TTL
33
+ }
34
+ return Date.now() + defaultTtlMs;
35
+ };
36
+ export const TokenRevocation = Object.freeze({
37
+ revoke(header) {
38
+ const token = getBearerToken(header);
39
+ if (token === null)
40
+ return null;
41
+ cleanupExpired();
42
+ revokedTokens.set(token, resolveExpiryMs(token));
43
+ return token;
44
+ },
45
+ isRevoked(token) {
46
+ cleanupExpired();
47
+ const expiresAt = revokedTokens.get(token);
48
+ if (expiresAt === undefined)
49
+ return false;
50
+ if (expiresAt <= Date.now()) {
51
+ revokedTokens.delete(token);
52
+ return false;
53
+ }
54
+ return true;
55
+ },
56
+ });
57
+ export default TokenRevocation;
@@ -0,0 +1,5 @@
1
+ export declare const SeederDiscovery: Readonly<{
2
+ resolveDir(projectRoot: string, dir: string): string;
3
+ listSeederFiles(dir: string): string[];
4
+ }>;
5
+ //# sourceMappingURL=SeederDiscovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SeederDiscovery.d.ts","sourceRoot":"","sources":["../../../src/seeders/SeederDiscovery.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,eAAe;4BACF,MAAM,OAAO,MAAM,GAAG,MAAM;yBAI/B,MAAM,GAAG,MAAM,EAAE;EAQtC,CAAC"}
@@ -0,0 +1,21 @@
1
+ import fs from '../node-singletons/fs.js';
2
+ import * as path from '../node-singletons/path.js';
3
+ const isSeederFile = (file) => {
4
+ if (file.endsWith('.d.ts'))
5
+ return false;
6
+ return file.endsWith('.ts') || file.endsWith('.js');
7
+ };
8
+ export const SeederDiscovery = Object.freeze({
9
+ resolveDir(projectRoot, dir) {
10
+ return path.resolve(projectRoot, dir);
11
+ },
12
+ listSeederFiles(dir) {
13
+ if (!fs.existsSync(dir))
14
+ return [];
15
+ const files = fs.readdirSync(dir);
16
+ return files
17
+ .filter(isSeederFile)
18
+ .sort((a, b) => a.localeCompare(b))
19
+ .map((f) => path.join(dir, f));
20
+ },
21
+ });
@@ -0,0 +1,5 @@
1
+ import type { LoadedSeeder } from '../seeders/types';
2
+ export declare const SeederLoader: Readonly<{
3
+ load(filePath: string): Promise<LoadedSeeder>;
4
+ }>;
5
+ //# sourceMappingURL=SeederLoader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SeederLoader.d.ts","sourceRoot":"","sources":["../../../src/seeders/SeederLoader.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAiB,MAAM,iBAAiB,CAAC;AAwDnE,eAAO,MAAM,YAAY;mBACF,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;EA0BnD,CAAC"}
@@ -0,0 +1,60 @@
1
+ import { ErrorFactory } from '../exceptions/ZintrustError.js';
2
+ import * as path from '../node-singletons/path.js';
3
+ import { pathToFileURL } from 'node:url';
4
+ function isFunction(value) {
5
+ return typeof value === 'function';
6
+ }
7
+ function isRecord(value) {
8
+ return typeof value === 'object' && value !== null;
9
+ }
10
+ function hasRun(value) {
11
+ return typeof value === 'object' && value !== null && 'run' in value;
12
+ }
13
+ function normalizeHandler(fn, label) {
14
+ if (!isFunction(fn)) {
15
+ throw ErrorFactory.createValidationError(`Invalid seeder export: expected function for ${label}`);
16
+ }
17
+ return async (db) => {
18
+ // Support both (db) => Promise<void> and () => Promise<void>.
19
+ if (fn.length <= 0) {
20
+ await Promise.resolve(fn());
21
+ return;
22
+ }
23
+ await Promise.resolve(fn(db));
24
+ };
25
+ }
26
+ function selectSeederExport(mod, baseName) {
27
+ const defaultExport = mod.default;
28
+ const defaultNamed = isRecord(defaultExport) ? defaultExport[baseName] : undefined;
29
+ // Prefer conventional exports first.
30
+ const candidate = mod.seeder ?? mod[baseName] ?? mod.run ?? defaultExport ?? defaultNamed;
31
+ if (candidate !== undefined)
32
+ return candidate;
33
+ // Last resort: pick the first export that looks like a seeder object.
34
+ for (const value of Object.values(mod)) {
35
+ if (hasRun(value))
36
+ return value;
37
+ }
38
+ return undefined;
39
+ }
40
+ export const SeederLoader = Object.freeze({
41
+ async load(filePath) {
42
+ const url = pathToFileURL(filePath).href;
43
+ const raw = (await import(url));
44
+ const mod = isRecord(raw) ? raw : {};
45
+ const baseName = path.basename(filePath, path.extname(filePath));
46
+ const picked = selectSeederExport(mod, baseName);
47
+ const baseExport = mod[baseName];
48
+ const runFn = (hasRun(picked) ? picked.run : undefined) ??
49
+ (hasRun(baseExport) ? baseExport.run : undefined) ??
50
+ mod.run;
51
+ if (runFn === undefined) {
52
+ throw ErrorFactory.createValidationError(`Seeder '${filePath}' is missing a runnable export (expected '${baseName}.run()', 'seeder.run()', 'run()', or default export with 'run()')`);
53
+ }
54
+ return {
55
+ name: baseName,
56
+ filePath,
57
+ run: normalizeHandler(runFn, 'run'),
58
+ };
59
+ },
60
+ });
@@ -0,0 +1,18 @@
1
+ import type { IDatabase } from '../orm/Database';
2
+ export type SeederModule = {
3
+ /** Common pattern: export const UserSeeder = { run() { ... } } */
4
+ [key: string]: unknown;
5
+ /** Alternative: export const seeder = { run() { ... } } */
6
+ seeder?: unknown;
7
+ /** Alternative: export async function run() { ... } */
8
+ run?: unknown;
9
+ /** Interop: export default { run() { ... } } */
10
+ default?: unknown;
11
+ };
12
+ export type SeederHandler = (db: IDatabase) => Promise<void>;
13
+ export type LoadedSeeder = {
14
+ name: string;
15
+ filePath: string;
16
+ run: SeederHandler;
17
+ };
18
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/seeders/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE/C,MAAM,MAAM,YAAY,GAAG;IACzB,kEAAkE;IAClE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,2DAA2D;IAC3D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,uDAAuD;IACvD,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,gDAAgD;IAChD,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,CAAC,EAAE,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAE7D,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,aAAa,CAAC;CACpB,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -1,4 +1,4 @@
1
- import { generateSecureJobId } from '../common/uuid.js';
1
+ import { generateSecureJobId } from '../common/utility.js';
2
2
  const DEFAULT_OPTIONS = {
3
3
  cookieName: 'ZIN_SESSION_ID',
4
4
  headerName: 'x-session-id',