@zintrust/core 0.1.0
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.
- package/bin/z.d.ts +7 -0
- package/bin/z.d.ts.map +1 -0
- package/bin/z.js +6 -0
- package/bin/zin.d.ts +7 -0
- package/bin/zin.d.ts.map +1 -0
- package/bin/zin.js +6 -0
- package/bin/zintrust-microservices.d.ts +7 -0
- package/bin/zintrust-microservices.d.ts.map +1 -0
- package/bin/zintrust-microservices.js +165 -0
- package/bin/zintrust.d.ts +9 -0
- package/bin/zintrust.d.ts.map +1 -0
- package/bin/zintrust.js +51 -0
- package/bin/zt.d.ts +7 -0
- package/bin/zt.d.ts.map +1 -0
- package/bin/zt.js +6 -0
- package/package.json +80 -0
- package/src/boot/Application.d.ts +31 -0
- package/src/boot/Application.d.ts.map +1 -0
- package/src/boot/Application.js +159 -0
- package/src/boot/Server.d.ts +23 -0
- package/src/boot/Server.d.ts.map +1 -0
- package/src/boot/Server.js +236 -0
- package/src/boot/bootstrap.d.ts +7 -0
- package/src/boot/bootstrap.d.ts.map +1 -0
- package/src/boot/bootstrap.js +64 -0
- package/src/builder/BundleOptimizer.d.ts +42 -0
- package/src/builder/BundleOptimizer.d.ts.map +1 -0
- package/src/builder/BundleOptimizer.js +356 -0
- package/src/cache/Cache.d.ts +26 -0
- package/src/cache/Cache.d.ts.map +1 -0
- package/src/cache/Cache.js +89 -0
- package/src/cache/CacheDriver.d.ts +28 -0
- package/src/cache/CacheDriver.d.ts.map +1 -0
- package/src/cache/CacheDriver.js +6 -0
- package/src/cache/drivers/KVDriver.d.ts +12 -0
- package/src/cache/drivers/KVDriver.d.ts.map +1 -0
- package/src/cache/drivers/KVDriver.js +54 -0
- package/src/cache/drivers/MemoryDriver.d.ts +12 -0
- package/src/cache/drivers/MemoryDriver.d.ts.map +1 -0
- package/src/cache/drivers/MemoryDriver.js +50 -0
- package/src/cache/drivers/MongoDriver.d.ts +17 -0
- package/src/cache/drivers/MongoDriver.d.ts.map +1 -0
- package/src/cache/drivers/MongoDriver.js +80 -0
- package/src/cache/drivers/RedisDriver.d.ts +12 -0
- package/src/cache/drivers/RedisDriver.d.ts.map +1 -0
- package/src/cache/drivers/RedisDriver.js +79 -0
- package/src/cli/BaseCommand.d.ts +39 -0
- package/src/cli/BaseCommand.d.ts.map +1 -0
- package/src/cli/BaseCommand.js +58 -0
- package/src/cli/CLI.d.ts +21 -0
- package/src/cli/CLI.d.ts.map +1 -0
- package/src/cli/CLI.js +203 -0
- package/src/cli/ErrorHandler.d.ts +23 -0
- package/src/cli/ErrorHandler.d.ts.map +1 -0
- package/src/cli/ErrorHandler.js +95 -0
- package/src/cli/PromptHelper.d.ts +47 -0
- package/src/cli/PromptHelper.d.ts.map +1 -0
- package/src/cli/PromptHelper.js +155 -0
- package/src/cli/commands/AddCommand.d.ts +15 -0
- package/src/cli/commands/AddCommand.d.ts.map +1 -0
- package/src/cli/commands/AddCommand.js +817 -0
- package/src/cli/commands/ConfigCommand.d.ts +15 -0
- package/src/cli/commands/ConfigCommand.d.ts.map +1 -0
- package/src/cli/commands/ConfigCommand.js +273 -0
- package/src/cli/commands/D1MigrateCommand.d.ts +15 -0
- package/src/cli/commands/D1MigrateCommand.d.ts.map +1 -0
- package/src/cli/commands/D1MigrateCommand.js +73 -0
- package/src/cli/commands/DebugCommand.d.ts +15 -0
- package/src/cli/commands/DebugCommand.d.ts.map +1 -0
- package/src/cli/commands/DebugCommand.js +52 -0
- package/src/cli/commands/FixCommand.d.ts +15 -0
- package/src/cli/commands/FixCommand.d.ts.map +1 -0
- package/src/cli/commands/FixCommand.js +80 -0
- package/src/cli/commands/KeyGenerateCommand.d.ts +9 -0
- package/src/cli/commands/KeyGenerateCommand.d.ts.map +1 -0
- package/src/cli/commands/KeyGenerateCommand.js +76 -0
- package/src/cli/commands/LogsCommand.d.ts +19 -0
- package/src/cli/commands/LogsCommand.d.ts.map +1 -0
- package/src/cli/commands/LogsCommand.js +185 -0
- package/src/cli/commands/MigrateCommand.d.ts +15 -0
- package/src/cli/commands/MigrateCommand.d.ts.map +1 -0
- package/src/cli/commands/MigrateCommand.js +56 -0
- package/src/cli/commands/NewCommand.d.ts +32 -0
- package/src/cli/commands/NewCommand.d.ts.map +1 -0
- package/src/cli/commands/NewCommand.js +280 -0
- package/src/cli/commands/PluginCommand.d.ts +9 -0
- package/src/cli/commands/PluginCommand.d.ts.map +1 -0
- package/src/cli/commands/PluginCommand.js +94 -0
- package/src/cli/commands/PrepareCommand.d.ts +8 -0
- package/src/cli/commands/PrepareCommand.d.ts.map +1 -0
- package/src/cli/commands/PrepareCommand.js +51 -0
- package/src/cli/commands/QACommand.d.ts +33 -0
- package/src/cli/commands/QACommand.d.ts.map +1 -0
- package/src/cli/commands/QACommand.js +490 -0
- package/src/cli/commands/SimulateCommand.d.ts +12 -0
- package/src/cli/commands/SimulateCommand.d.ts.map +1 -0
- package/src/cli/commands/SimulateCommand.js +79 -0
- package/src/cli/commands/StartCommand.d.ts +5 -0
- package/src/cli/commands/StartCommand.d.ts.map +1 -0
- package/src/cli/commands/StartCommand.js +227 -0
- package/src/cli/commands/index.d.ts +11 -0
- package/src/cli/commands/index.d.ts.map +1 -0
- package/src/cli/commands/index.js +10 -0
- package/src/cli/config/ConfigManager.d.ts +42 -0
- package/src/cli/config/ConfigManager.d.ts.map +1 -0
- package/src/cli/config/ConfigManager.js +175 -0
- package/src/cli/config/ConfigSchema.d.ts +195 -0
- package/src/cli/config/ConfigSchema.d.ts.map +1 -0
- package/src/cli/config/ConfigSchema.js +171 -0
- package/src/cli/config/ConfigValidator.d.ts +41 -0
- package/src/cli/config/ConfigValidator.d.ts.map +1 -0
- package/src/cli/config/ConfigValidator.js +200 -0
- package/src/cli/config/index.d.ts +8 -0
- package/src/cli/config/index.d.ts.map +1 -0
- package/src/cli/config/index.js +7 -0
- package/src/cli/debug/Dashboard.d.ts +34 -0
- package/src/cli/debug/Dashboard.d.ts.map +1 -0
- package/src/cli/debug/Dashboard.js +152 -0
- package/src/cli/index.d.ts +14 -0
- package/src/cli/index.d.ts.map +1 -0
- package/src/cli/index.js +14 -0
- package/src/cli/logger/Logger.d.ts +43 -0
- package/src/cli/logger/Logger.d.ts.map +1 -0
- package/src/cli/logger/Logger.js +137 -0
- package/src/cli/scaffolding/ControllerGenerator.d.ts +44 -0
- package/src/cli/scaffolding/ControllerGenerator.d.ts.map +1 -0
- package/src/cli/scaffolding/ControllerGenerator.js +540 -0
- package/src/cli/scaffolding/FactoryGenerator.d.ts +47 -0
- package/src/cli/scaffolding/FactoryGenerator.d.ts.map +1 -0
- package/src/cli/scaffolding/FactoryGenerator.js +356 -0
- package/src/cli/scaffolding/FeatureScaffolder.d.ts +40 -0
- package/src/cli/scaffolding/FeatureScaffolder.d.ts.map +1 -0
- package/src/cli/scaffolding/FeatureScaffolder.js +747 -0
- package/src/cli/scaffolding/FileGenerator.d.ts +31 -0
- package/src/cli/scaffolding/FileGenerator.d.ts.map +1 -0
- package/src/cli/scaffolding/FileGenerator.js +222 -0
- package/src/cli/scaffolding/MigrationGenerator.d.ts +35 -0
- package/src/cli/scaffolding/MigrationGenerator.d.ts.map +1 -0
- package/src/cli/scaffolding/MigrationGenerator.js +257 -0
- package/src/cli/scaffolding/ModelGenerator.d.ts +81 -0
- package/src/cli/scaffolding/ModelGenerator.d.ts.map +1 -0
- package/src/cli/scaffolding/ModelGenerator.js +249 -0
- package/src/cli/scaffolding/ProjectScaffolder.d.ts +66 -0
- package/src/cli/scaffolding/ProjectScaffolder.d.ts.map +1 -0
- package/src/cli/scaffolding/ProjectScaffolder.js +439 -0
- package/src/cli/scaffolding/RequestFactoryGenerator.d.ts +50 -0
- package/src/cli/scaffolding/RequestFactoryGenerator.d.ts.map +1 -0
- package/src/cli/scaffolding/RequestFactoryGenerator.js +465 -0
- package/src/cli/scaffolding/ResponseFactoryGenerator.d.ts +43 -0
- package/src/cli/scaffolding/ResponseFactoryGenerator.d.ts.map +1 -0
- package/src/cli/scaffolding/ResponseFactoryGenerator.js +321 -0
- package/src/cli/scaffolding/RouteGenerator.d.ts +66 -0
- package/src/cli/scaffolding/RouteGenerator.d.ts.map +1 -0
- package/src/cli/scaffolding/RouteGenerator.js +306 -0
- package/src/cli/scaffolding/SeederGenerator.d.ts +47 -0
- package/src/cli/scaffolding/SeederGenerator.d.ts.map +1 -0
- package/src/cli/scaffolding/SeederGenerator.js +286 -0
- package/src/cli/scaffolding/ServiceIntegrationTestGenerator.d.ts +40 -0
- package/src/cli/scaffolding/ServiceIntegrationTestGenerator.d.ts.map +1 -0
- package/src/cli/scaffolding/ServiceIntegrationTestGenerator.js +267 -0
- package/src/cli/scaffolding/ServiceRequestFactoryGenerator.d.ts +45 -0
- package/src/cli/scaffolding/ServiceRequestFactoryGenerator.d.ts.map +1 -0
- package/src/cli/scaffolding/ServiceRequestFactoryGenerator.js +397 -0
- package/src/cli/scaffolding/ServiceScaffolder.d.ts +45 -0
- package/src/cli/scaffolding/ServiceScaffolder.d.ts.map +1 -0
- package/src/cli/scaffolding/ServiceScaffolder.js +367 -0
- package/src/cli/scaffolding/TemplateEngine.d.ts +35 -0
- package/src/cli/scaffolding/TemplateEngine.d.ts.map +1 -0
- package/src/cli/scaffolding/TemplateEngine.js +379 -0
- package/src/cli/scaffolding/WorkflowGenerator.d.ts +31 -0
- package/src/cli/scaffolding/WorkflowGenerator.d.ts.map +1 -0
- package/src/cli/scaffolding/WorkflowGenerator.js +193 -0
- package/src/cli/scaffolding/index.d.ts +34 -0
- package/src/cli/scaffolding/index.d.ts.map +1 -0
- package/src/cli/scaffolding/index.js +18 -0
- package/src/cli/utils/DistPackager.d.ts +8 -0
- package/src/cli/utils/DistPackager.d.ts.map +1 -0
- package/src/cli/utils/DistPackager.js +94 -0
- package/src/cli/utils/EnvFileLoader.d.ts +21 -0
- package/src/cli/utils/EnvFileLoader.d.ts.map +1 -0
- package/src/cli/utils/EnvFileLoader.js +166 -0
- package/src/cli/utils/spawn.d.ts +11 -0
- package/src/cli/utils/spawn.d.ts.map +1 -0
- package/src/cli/utils/spawn.js +81 -0
- package/src/common/index.d.ts +87 -0
- package/src/common/index.d.ts.map +1 -0
- package/src/common/index.js +207 -0
- package/src/config/SecretsManager.d.ts +122 -0
- package/src/config/SecretsManager.d.ts.map +1 -0
- package/src/config/SecretsManager.js +328 -0
- package/src/config/app.d.ts +56 -0
- package/src/config/app.d.ts.map +1 -0
- package/src/config/app.js +77 -0
- package/src/config/cache.d.ts +76 -0
- package/src/config/cache.d.ts.map +1 -0
- package/src/config/cache.js +62 -0
- package/src/config/constants.d.ts +108 -0
- package/src/config/constants.d.ts.map +1 -0
- package/src/config/constants.js +64 -0
- package/src/config/database.d.ts +122 -0
- package/src/config/database.d.ts.map +1 -0
- package/src/config/database.js +89 -0
- package/src/config/env.d.ts +56 -0
- package/src/config/env.d.ts.map +1 -0
- package/src/config/env.js +133 -0
- package/src/config/features.d.ts +27 -0
- package/src/config/features.d.ts.map +1 -0
- package/src/config/features.js +49 -0
- package/src/config/index.d.ts +554 -0
- package/src/config/index.d.ts.map +1 -0
- package/src/config/index.js +31 -0
- package/src/config/logger.d.ts +17 -0
- package/src/config/logger.d.ts.map +1 -0
- package/src/config/logger.js +77 -0
- package/src/config/microservices.d.ts +88 -0
- package/src/config/microservices.d.ts.map +1 -0
- package/src/config/microservices.js +90 -0
- package/src/config/queue.d.ts +107 -0
- package/src/config/queue.d.ts.map +1 -0
- package/src/config/queue.js +74 -0
- package/src/config/security.d.ts +108 -0
- package/src/config/security.d.ts.map +1 -0
- package/src/config/security.js +134 -0
- package/src/config/storage.d.ts +105 -0
- package/src/config/storage.d.ts.map +1 -0
- package/src/config/storage.js +79 -0
- package/src/container/ServiceContainer.d.ts +25 -0
- package/src/container/ServiceContainer.d.ts.map +1 -0
- package/src/container/ServiceContainer.js +75 -0
- package/src/database/migrations/index.d.ts +2 -0
- package/src/database/migrations/index.d.ts.map +1 -0
- package/src/database/migrations/index.js +1 -0
- package/src/exceptions/ZintrustError.d.ts +88 -0
- package/src/exceptions/ZintrustError.d.ts.map +1 -0
- package/src/exceptions/ZintrustError.js +110 -0
- package/src/features/Auth.d.ts +20 -0
- package/src/features/Auth.d.ts.map +1 -0
- package/src/features/Auth.js +32 -0
- package/src/features/Queue.d.ts +21 -0
- package/src/features/Queue.d.ts.map +1 -0
- package/src/features/Queue.js +59 -0
- package/src/functions/cloudflare.d.ts +5 -0
- package/src/functions/cloudflare.d.ts.map +1 -0
- package/src/functions/cloudflare.js +34 -0
- package/src/functions/deno.d.ts +3 -0
- package/src/functions/deno.d.ts.map +1 -0
- package/src/functions/deno.js +31 -0
- package/src/functions/lambda.d.ts +2 -0
- package/src/functions/lambda.d.ts.map +1 -0
- package/src/functions/lambda.js +32 -0
- package/src/http/Controller.d.ts +20 -0
- package/src/http/Controller.d.ts.map +1 -0
- package/src/http/Controller.js +46 -0
- package/src/http/Kernel.d.ts +24 -0
- package/src/http/Kernel.d.ts.map +1 -0
- package/src/http/Kernel.js +72 -0
- package/src/http/Request.d.ts +36 -0
- package/src/http/Request.d.ts.map +1 -0
- package/src/http/Request.js +142 -0
- package/src/http/Response.d.ts +32 -0
- package/src/http/Response.d.ts.map +1 -0
- package/src/http/Response.js +70 -0
- package/src/index.d.ts +43 -0
- package/src/index.d.ts.map +1 -0
- package/src/index.js +37 -0
- package/src/microservices/MicroserviceBootstrap.d.ts +75 -0
- package/src/microservices/MicroserviceBootstrap.d.ts.map +1 -0
- package/src/microservices/MicroserviceBootstrap.js +285 -0
- package/src/microservices/MicroserviceGenerator.d.ts +27 -0
- package/src/microservices/MicroserviceGenerator.d.ts.map +1 -0
- package/src/microservices/MicroserviceGenerator.js +436 -0
- package/src/microservices/MicroserviceManager.d.ts +68 -0
- package/src/microservices/MicroserviceManager.d.ts.map +1 -0
- package/src/microservices/MicroserviceManager.js +266 -0
- package/src/microservices/PostgresAdapter.d.ts +90 -0
- package/src/microservices/PostgresAdapter.d.ts.map +1 -0
- package/src/microservices/PostgresAdapter.js +286 -0
- package/src/microservices/RequestTracingMiddleware.d.ts +41 -0
- package/src/microservices/RequestTracingMiddleware.d.ts.map +1 -0
- package/src/microservices/RequestTracingMiddleware.js +122 -0
- package/src/microservices/ServiceAuthMiddleware.d.ts +58 -0
- package/src/microservices/ServiceAuthMiddleware.d.ts.map +1 -0
- package/src/microservices/ServiceAuthMiddleware.js +240 -0
- package/src/microservices/ServiceBundler.d.ts +45 -0
- package/src/microservices/ServiceBundler.d.ts.map +1 -0
- package/src/microservices/ServiceBundler.js +297 -0
- package/src/microservices/ServiceHealthMonitor.d.ts +96 -0
- package/src/microservices/ServiceHealthMonitor.d.ts.map +1 -0
- package/src/microservices/ServiceHealthMonitor.js +379 -0
- package/src/middleware/CsrfMiddleware.d.ts +19 -0
- package/src/middleware/CsrfMiddleware.d.ts.map +1 -0
- package/src/middleware/CsrfMiddleware.js +121 -0
- package/src/middleware/MiddlewareStack.d.ts +27 -0
- package/src/middleware/MiddlewareStack.d.ts.map +1 -0
- package/src/middleware/MiddlewareStack.js +43 -0
- package/src/middleware/RateLimiter.d.ts +22 -0
- package/src/middleware/RateLimiter.d.ts.map +1 -0
- package/src/middleware/RateLimiter.js +72 -0
- package/src/middleware/SecurityMiddleware.d.ts +33 -0
- package/src/middleware/SecurityMiddleware.d.ts.map +1 -0
- package/src/middleware/SecurityMiddleware.js +106 -0
- package/src/middleware/index.d.ts +9 -0
- package/src/middleware/index.d.ts.map +1 -0
- package/src/middleware/index.js +8 -0
- package/src/node-singletons/child-process.d.ts +7 -0
- package/src/node-singletons/child-process.d.ts.map +1 -0
- package/src/node-singletons/child-process.js +6 -0
- package/src/node-singletons/crypto.d.ts +7 -0
- package/src/node-singletons/crypto.d.ts.map +1 -0
- package/src/node-singletons/crypto.js +6 -0
- package/src/node-singletons/events.d.ts +7 -0
- package/src/node-singletons/events.d.ts.map +1 -0
- package/src/node-singletons/events.js +6 -0
- package/src/node-singletons/fs.d.ts +12 -0
- package/src/node-singletons/fs.d.ts.map +1 -0
- package/src/node-singletons/fs.js +14 -0
- package/src/node-singletons/http.d.ts +8 -0
- package/src/node-singletons/http.d.ts.map +1 -0
- package/src/node-singletons/http.js +6 -0
- package/src/node-singletons/index.d.ts +30 -0
- package/src/node-singletons/index.d.ts.map +1 -0
- package/src/node-singletons/index.js +31 -0
- package/src/node-singletons/os.d.ts +9 -0
- package/src/node-singletons/os.d.ts.map +1 -0
- package/src/node-singletons/os.js +9 -0
- package/src/node-singletons/path.d.ts +7 -0
- package/src/node-singletons/path.d.ts.map +1 -0
- package/src/node-singletons/path.js +6 -0
- package/src/node-singletons/perf-hooks.d.ts +7 -0
- package/src/node-singletons/perf-hooks.d.ts.map +1 -0
- package/src/node-singletons/perf-hooks.js +6 -0
- package/src/node-singletons/readline.d.ts +10 -0
- package/src/node-singletons/readline.d.ts.map +1 -0
- package/src/node-singletons/readline.js +9 -0
- package/src/node-singletons/url.d.ts +7 -0
- package/src/node-singletons/url.d.ts.map +1 -0
- package/src/node-singletons/url.js +6 -0
- package/src/orm/ConnectionManager.d.ts +118 -0
- package/src/orm/ConnectionManager.d.ts.map +1 -0
- package/src/orm/ConnectionManager.js +401 -0
- package/src/orm/Database.d.ts +31 -0
- package/src/orm/Database.d.ts.map +1 -0
- package/src/orm/Database.js +163 -0
- package/src/orm/DatabaseAdapter.d.ts +96 -0
- package/src/orm/DatabaseAdapter.d.ts.map +1 -0
- package/src/orm/DatabaseAdapter.js +40 -0
- package/src/orm/Model.d.ts +91 -0
- package/src/orm/Model.d.ts.map +1 -0
- package/src/orm/Model.js +206 -0
- package/src/orm/QueryBuilder.d.ts +52 -0
- package/src/orm/QueryBuilder.d.ts.map +1 -0
- package/src/orm/QueryBuilder.js +134 -0
- package/src/orm/Relationships.d.ts +53 -0
- package/src/orm/Relationships.d.ts.map +1 -0
- package/src/orm/Relationships.js +98 -0
- package/src/orm/Schema.d.ts +123 -0
- package/src/orm/Schema.d.ts.map +1 -0
- package/src/orm/Schema.js +169 -0
- package/src/orm/adapters/D1Adapter.d.ts +15 -0
- package/src/orm/adapters/D1Adapter.d.ts.map +1 -0
- package/src/orm/adapters/D1Adapter.js +125 -0
- package/src/orm/adapters/MySQLAdapter.d.ts +16 -0
- package/src/orm/adapters/MySQLAdapter.d.ts.map +1 -0
- package/src/orm/adapters/MySQLAdapter.js +87 -0
- package/src/orm/adapters/PostgreSQLAdapter.d.ts +16 -0
- package/src/orm/adapters/PostgreSQLAdapter.d.ts.map +1 -0
- package/src/orm/adapters/PostgreSQLAdapter.js +87 -0
- package/src/orm/adapters/SQLServerAdapter.d.ts +16 -0
- package/src/orm/adapters/SQLServerAdapter.d.ts.map +1 -0
- package/src/orm/adapters/SQLServerAdapter.js +81 -0
- package/src/orm/adapters/SQLiteAdapter.d.ts +11 -0
- package/src/orm/adapters/SQLiteAdapter.d.ts.map +1 -0
- package/src/orm/adapters/SQLiteAdapter.js +131 -0
- package/src/performance/Benchmark.d.ts +87 -0
- package/src/performance/Benchmark.d.ts.map +1 -0
- package/src/performance/Benchmark.js +304 -0
- package/src/performance/CodeGenerationBenchmark.d.ts +23 -0
- package/src/performance/CodeGenerationBenchmark.d.ts.map +1 -0
- package/src/performance/CodeGenerationBenchmark.js +249 -0
- package/src/performance/Optimizer.d.ts +99 -0
- package/src/performance/Optimizer.d.ts.map +1 -0
- package/src/performance/Optimizer.js +396 -0
- package/src/performance/establish-baseline.d.ts +9 -0
- package/src/performance/establish-baseline.d.ts.map +1 -0
- package/src/performance/establish-baseline.js +55 -0
- package/src/profiling/MemoryProfiler.d.ts +32 -0
- package/src/profiling/MemoryProfiler.d.ts.map +1 -0
- package/src/profiling/MemoryProfiler.js +84 -0
- package/src/profiling/N1Detector.d.ts +16 -0
- package/src/profiling/N1Detector.d.ts.map +1 -0
- package/src/profiling/N1Detector.js +120 -0
- package/src/profiling/QueryLogger.d.ts +107 -0
- package/src/profiling/QueryLogger.d.ts.map +1 -0
- package/src/profiling/QueryLogger.js +148 -0
- package/src/profiling/RequestProfiler.d.ts +30 -0
- package/src/profiling/RequestProfiler.d.ts.map +1 -0
- package/src/profiling/RequestProfiler.js +94 -0
- package/src/profiling/types.d.ts +77 -0
- package/src/profiling/types.d.ts.map +1 -0
- package/src/profiling/types.js +5 -0
- package/src/routing/Router.d.ts +52 -0
- package/src/routing/Router.d.ts.map +1 -0
- package/src/routing/Router.js +191 -0
- package/src/runtime/PluginManager.d.ts +30 -0
- package/src/runtime/PluginManager.d.ts.map +1 -0
- package/src/runtime/PluginManager.js +197 -0
- package/src/runtime/PluginRegistry.d.ts +22 -0
- package/src/runtime/PluginRegistry.d.ts.map +1 -0
- package/src/runtime/PluginRegistry.js +93 -0
- package/src/runtime/RuntimeAdapter.d.ts +126 -0
- package/src/runtime/RuntimeAdapter.d.ts.map +1 -0
- package/src/runtime/RuntimeAdapter.js +127 -0
- package/src/runtime/RuntimeDetector.d.ts +15 -0
- package/src/runtime/RuntimeDetector.d.ts.map +1 -0
- package/src/runtime/RuntimeDetector.js +219 -0
- package/src/runtime/adapters/CloudflareAdapter.d.ts +43 -0
- package/src/runtime/adapters/CloudflareAdapter.d.ts.map +1 -0
- package/src/runtime/adapters/CloudflareAdapter.js +175 -0
- package/src/runtime/adapters/DenoAdapter.d.ts +30 -0
- package/src/runtime/adapters/DenoAdapter.d.ts.map +1 -0
- package/src/runtime/adapters/DenoAdapter.js +191 -0
- package/src/runtime/adapters/FargateAdapter.d.ts +40 -0
- package/src/runtime/adapters/FargateAdapter.d.ts.map +1 -0
- package/src/runtime/adapters/FargateAdapter.js +156 -0
- package/src/runtime/adapters/LambdaAdapter.d.ts +13 -0
- package/src/runtime/adapters/LambdaAdapter.d.ts.map +1 -0
- package/src/runtime/adapters/LambdaAdapter.js +302 -0
- package/src/runtime/adapters/NodeServerAdapter.d.ts +16 -0
- package/src/runtime/adapters/NodeServerAdapter.d.ts.map +1 -0
- package/src/runtime/adapters/NodeServerAdapter.js +199 -0
- package/src/scripts/TemplateSync.d.ts +7 -0
- package/src/scripts/TemplateSync.d.ts.map +1 -0
- package/src/scripts/TemplateSync.js +234 -0
- package/src/security/CsrfTokenManager.d.ts +28 -0
- package/src/security/CsrfTokenManager.d.ts.map +1 -0
- package/src/security/CsrfTokenManager.js +78 -0
- package/src/security/Encryptor.d.ts +15 -0
- package/src/security/Encryptor.d.ts.map +1 -0
- package/src/security/Encryptor.js +142 -0
- package/src/security/JwtManager.d.ts +41 -0
- package/src/security/JwtManager.d.ts.map +1 -0
- package/src/security/JwtManager.js +229 -0
- package/src/security/UrlValidator.d.ts +21 -0
- package/src/security/UrlValidator.d.ts.map +1 -0
- package/src/security/UrlValidator.js +42 -0
- package/src/security/XssProtection.d.ts +24 -0
- package/src/security/XssProtection.d.ts.map +1 -0
- package/src/security/XssProtection.js +133 -0
- package/src/templates/TemplateRegistry.d.ts +40 -0
- package/src/templates/TemplateRegistry.d.ts.map +1 -0
- package/src/templates/TemplateRegistry.js +78 -0
- package/src/templates/TemplateRegistry.ts +91 -0
- package/src/templates/adapters/MySQLAdapter.ts.tpl +97 -0
- package/src/templates/adapters/PostgreSQLAdapter.ts.tpl +101 -0
- package/src/templates/adapters/SQLServerAdapter.ts.tpl +95 -0
- package/src/templates/adapters/SQLiteAdapter.ts.tpl +189 -0
- package/src/templates/features/Auth.ts.tpl +40 -0
- package/src/templates/features/Queue.ts.tpl +75 -0
- package/src/templates/project/basic/.env.example.tpl +26 -0
- package/src/templates/project/basic/.env.tpl +164 -0
- package/src/templates/project/basic/README.md.tpl +13 -0
- package/src/templates/project/basic/app/Controllers/UserController.ts.tpl +155 -0
- package/src/templates/project/basic/app/Middleware/ProfilerMiddleware.ts.tpl +55 -0
- package/src/templates/project/basic/app/Middleware/index.ts.tpl +304 -0
- package/src/templates/project/basic/app/Models/Post.ts.tpl +30 -0
- package/src/templates/project/basic/app/Models/User.ts.tpl +53 -0
- package/src/templates/project/basic/config/SecretsManager.ts.tpl +453 -0
- package/src/templates/project/basic/config/app.ts.tpl +97 -0
- package/src/templates/project/basic/config/cache.ts.tpl +117 -0
- package/src/templates/project/basic/config/constants.ts.tpl +70 -0
- package/src/templates/project/basic/config/database.ts.tpl +152 -0
- package/src/templates/project/basic/config/env.ts.tpl +148 -0
- package/src/templates/project/basic/config/features.ts.tpl +57 -0
- package/src/templates/project/basic/config/index.ts.tpl +36 -0
- package/src/templates/project/basic/config/logger.ts.tpl +95 -0
- package/src/templates/project/basic/config/microservices.ts.tpl +104 -0
- package/src/templates/project/basic/config/queue.ts.tpl +134 -0
- package/src/templates/project/basic/config/security.ts.tpl +149 -0
- package/src/templates/project/basic/config/storage.ts.tpl +136 -0
- package/src/templates/project/basic/database/factories/.gitkeep.tpl +0 -0
- package/src/templates/project/basic/database/migrations/.gitkeep.tpl +0 -0
- package/src/templates/project/basic/database/migrations/index.ts.tpl +2 -0
- package/src/templates/project/basic/database/seeders/.gitkeep.tpl +0 -0
- package/src/templates/project/basic/package.json.tpl +22 -0
- package/src/templates/project/basic/routes/api.ts.tpl +135 -0
- package/src/templates/project/basic/src/index.ts.tpl +49 -0
- package/src/templates/project/basic/template.json +17 -0
- package/src/templates/project/basic/tsconfig.json.tpl +20 -0
- package/src/validation/ValidationError.d.ts +42 -0
- package/src/validation/ValidationError.d.ts.map +1 -0
- package/src/validation/ValidationError.js +53 -0
- package/src/validation/Validator.d.ts +60 -0
- package/src/validation/Validator.d.ts.map +1 -0
- package/src/validation/Validator.js +190 -0
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Service Health Check and Monitoring System
|
|
3
|
+
* Provides per-service and aggregated health status with detailed diagnostics
|
|
4
|
+
*/
|
|
5
|
+
import { Logger } from '../config/logger';
|
|
6
|
+
import { validateUrl } from '../security/UrlValidator';
|
|
7
|
+
/**
|
|
8
|
+
* Health Check Endpoint Handler
|
|
9
|
+
* Each service should expose this as GET /health
|
|
10
|
+
*/
|
|
11
|
+
export const HealthCheckHandler = Object.freeze({
|
|
12
|
+
/**
|
|
13
|
+
* Create a new health check handler instance
|
|
14
|
+
*/
|
|
15
|
+
create(serviceName, version, port, domain, dependencies = [], checkDatabase) {
|
|
16
|
+
/**
|
|
17
|
+
* Perform full health check
|
|
18
|
+
*/
|
|
19
|
+
const performHealthCheck = async (startTime) => {
|
|
20
|
+
const result = {
|
|
21
|
+
service: serviceName,
|
|
22
|
+
domain,
|
|
23
|
+
port,
|
|
24
|
+
status: 'healthy',
|
|
25
|
+
timestamp: new Date().toISOString(),
|
|
26
|
+
responseTime: 0,
|
|
27
|
+
version,
|
|
28
|
+
checks: {
|
|
29
|
+
http: true,
|
|
30
|
+
database: undefined,
|
|
31
|
+
dependencies: {},
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
await checkDatabaseHealth(result, checkDatabase);
|
|
35
|
+
await checkDependenciesHealth(result, dependencies);
|
|
36
|
+
result.responseTime = Date.now() - startTime;
|
|
37
|
+
return result;
|
|
38
|
+
};
|
|
39
|
+
return {
|
|
40
|
+
/**
|
|
41
|
+
* Handle health check request
|
|
42
|
+
* Returns JSON with service health status
|
|
43
|
+
*/
|
|
44
|
+
async handle(_req, res) {
|
|
45
|
+
const startTime = Date.now();
|
|
46
|
+
try {
|
|
47
|
+
const result = await performHealthCheck(startTime);
|
|
48
|
+
const statusCode = getStatusCode(result.status);
|
|
49
|
+
res.setStatus(statusCode).json(result);
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
Logger.error('Health check handler error:', err);
|
|
53
|
+
const result = {
|
|
54
|
+
service: serviceName,
|
|
55
|
+
domain,
|
|
56
|
+
port,
|
|
57
|
+
status: 'unhealthy',
|
|
58
|
+
timestamp: new Date().toISOString(),
|
|
59
|
+
responseTime: Date.now() - startTime,
|
|
60
|
+
version,
|
|
61
|
+
checks: { http: false },
|
|
62
|
+
message: err.message,
|
|
63
|
+
};
|
|
64
|
+
res.setStatus(503).json(result);
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
/**
|
|
71
|
+
* Get status code based on health status
|
|
72
|
+
*/
|
|
73
|
+
function getStatusCode(status) {
|
|
74
|
+
if (status === 'healthy')
|
|
75
|
+
return 200;
|
|
76
|
+
if (status === 'degraded')
|
|
77
|
+
return 202;
|
|
78
|
+
return 503;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Check single dependency service
|
|
82
|
+
*/
|
|
83
|
+
async function checkDependencyService(depService) {
|
|
84
|
+
try {
|
|
85
|
+
// In a real environment, we would resolve the service URL
|
|
86
|
+
// For now, we assume it's on localhost with a standard port mapping or discovery
|
|
87
|
+
const url = `http://localhost:3000/health?service=${depService}`;
|
|
88
|
+
// SSRF Protection
|
|
89
|
+
validateUrl(url);
|
|
90
|
+
const depResponse = await fetch(url, {
|
|
91
|
+
signal: AbortSignal.timeout(2000),
|
|
92
|
+
});
|
|
93
|
+
return depResponse.ok;
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
Logger.error(`Dependency health check failed for ${depService}`, error);
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Check all dependencies health
|
|
102
|
+
*/
|
|
103
|
+
async function checkDependenciesHealth(result, dependencies) {
|
|
104
|
+
if (dependencies.length === 0)
|
|
105
|
+
return;
|
|
106
|
+
result.checks.dependencies ??= {};
|
|
107
|
+
for (const depService of dependencies) {
|
|
108
|
+
const isHealthy = await checkDependencyService(depService);
|
|
109
|
+
result.checks.dependencies[depService] = isHealthy;
|
|
110
|
+
if (!isHealthy) {
|
|
111
|
+
result.status = 'degraded';
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Check database health
|
|
117
|
+
*/
|
|
118
|
+
async function checkDatabaseHealth(result, checkDatabase) {
|
|
119
|
+
if (checkDatabase === undefined)
|
|
120
|
+
return;
|
|
121
|
+
try {
|
|
122
|
+
result.checks.database = await checkDatabase();
|
|
123
|
+
if (!result.checks.database) {
|
|
124
|
+
result.status = 'degraded';
|
|
125
|
+
result.message = 'Database connection failed';
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
catch (err) {
|
|
129
|
+
Logger.error('Database health check failed:', err);
|
|
130
|
+
result.checks.database = false;
|
|
131
|
+
result.status = 'unhealthy';
|
|
132
|
+
result.message = 'Database check error';
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Service Health Monitor
|
|
137
|
+
* Monitors multiple services and provides aggregated health status
|
|
138
|
+
*/
|
|
139
|
+
export const ServiceHealthMonitor = Object.freeze({
|
|
140
|
+
/**
|
|
141
|
+
* Create a new service health monitor instance
|
|
142
|
+
*/
|
|
143
|
+
create(healthCheckUrls, // serviceName -> healthCheckUrl
|
|
144
|
+
intervalMs = 30000 // Check every 30 seconds
|
|
145
|
+
) {
|
|
146
|
+
let checkIntervalId;
|
|
147
|
+
const lastResults = new Map();
|
|
148
|
+
return createMonitorObject(healthCheckUrls, intervalMs, lastResults, () => checkIntervalId, (id) => {
|
|
149
|
+
checkIntervalId = id;
|
|
150
|
+
});
|
|
151
|
+
},
|
|
152
|
+
});
|
|
153
|
+
/**
|
|
154
|
+
* Create the monitor object with methods
|
|
155
|
+
*/
|
|
156
|
+
function createMonitorObject(healthCheckUrls, intervalMs, lastResults, getIntervalId, setIntervalId) {
|
|
157
|
+
const self = {
|
|
158
|
+
/**
|
|
159
|
+
* Start continuous health monitoring
|
|
160
|
+
*/
|
|
161
|
+
start() {
|
|
162
|
+
startMonitoring(intervalMs, async () => self.checkAll(), getIntervalId, setIntervalId);
|
|
163
|
+
},
|
|
164
|
+
/**
|
|
165
|
+
* Stop health monitoring
|
|
166
|
+
*/
|
|
167
|
+
stop() {
|
|
168
|
+
stopMonitoring(getIntervalId, setIntervalId);
|
|
169
|
+
},
|
|
170
|
+
/**
|
|
171
|
+
* Check all services
|
|
172
|
+
*/
|
|
173
|
+
async checkAll() {
|
|
174
|
+
const status = await runAllChecks(healthCheckUrls, lastResults);
|
|
175
|
+
logHealthSummary(status);
|
|
176
|
+
return status;
|
|
177
|
+
},
|
|
178
|
+
/**
|
|
179
|
+
* Get last known status of all services
|
|
180
|
+
*/
|
|
181
|
+
getLastStatus() {
|
|
182
|
+
const results = Array.from(lastResults.values());
|
|
183
|
+
return calculateAggregatedStatus(results);
|
|
184
|
+
},
|
|
185
|
+
/**
|
|
186
|
+
* Get health status for specific service
|
|
187
|
+
*/
|
|
188
|
+
getServiceStatus(serviceName) {
|
|
189
|
+
return lastResults.get(serviceName);
|
|
190
|
+
},
|
|
191
|
+
/**
|
|
192
|
+
* Check if all services are healthy
|
|
193
|
+
*/
|
|
194
|
+
areAllHealthy() {
|
|
195
|
+
return checkAllHealthy(lastResults, healthCheckUrls);
|
|
196
|
+
},
|
|
197
|
+
/**
|
|
198
|
+
* Check if service is healthy
|
|
199
|
+
*/
|
|
200
|
+
isServiceHealthy(serviceName) {
|
|
201
|
+
const status = self.getServiceStatus(serviceName);
|
|
202
|
+
return status?.status === 'healthy';
|
|
203
|
+
},
|
|
204
|
+
};
|
|
205
|
+
return self;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Start monitoring logic
|
|
209
|
+
*/
|
|
210
|
+
function startMonitoring(intervalMs, checkAll, getIntervalId, setIntervalId) {
|
|
211
|
+
if (getIntervalId() !== undefined) {
|
|
212
|
+
Logger.warn('Health monitoring already started');
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
Logger.info('🏥 Starting service health monitoring');
|
|
216
|
+
let inFlight = false;
|
|
217
|
+
const safeCheckAll = async () => {
|
|
218
|
+
if (inFlight)
|
|
219
|
+
return;
|
|
220
|
+
inFlight = true;
|
|
221
|
+
try {
|
|
222
|
+
await checkAll();
|
|
223
|
+
}
|
|
224
|
+
catch (err) {
|
|
225
|
+
Logger.error('Service health monitoring tick failed:', err);
|
|
226
|
+
}
|
|
227
|
+
finally {
|
|
228
|
+
inFlight = false;
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
void safeCheckAll(); // Initial check
|
|
232
|
+
const id = setInterval(() => {
|
|
233
|
+
void safeCheckAll();
|
|
234
|
+
}, intervalMs);
|
|
235
|
+
// Node: allow process to exit; other runtimes may not support unref()
|
|
236
|
+
if (isUnrefableTimer(id)) {
|
|
237
|
+
id.unref();
|
|
238
|
+
}
|
|
239
|
+
setIntervalId(id);
|
|
240
|
+
}
|
|
241
|
+
function isUnrefableTimer(value) {
|
|
242
|
+
if (typeof value !== 'object' || value === null)
|
|
243
|
+
return false;
|
|
244
|
+
return 'unref' in value && typeof value.unref === 'function';
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Stop monitoring logic
|
|
248
|
+
*/
|
|
249
|
+
function stopMonitoring(getIntervalId, setIntervalId) {
|
|
250
|
+
const id = getIntervalId();
|
|
251
|
+
if (id !== undefined) {
|
|
252
|
+
clearInterval(id);
|
|
253
|
+
setIntervalId(undefined);
|
|
254
|
+
Logger.info('🛑 Health monitoring stopped');
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Check if all services are healthy
|
|
259
|
+
*/
|
|
260
|
+
function checkAllHealthy(lastResults, healthCheckUrls) {
|
|
261
|
+
const results = Array.from(lastResults.values());
|
|
262
|
+
if (results.length === 0 && Object.keys(healthCheckUrls).length > 0) {
|
|
263
|
+
return false;
|
|
264
|
+
}
|
|
265
|
+
return results.length > 0 && results.every((r) => r.status === 'healthy');
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Check single service
|
|
269
|
+
*/
|
|
270
|
+
async function checkService(serviceName, url) {
|
|
271
|
+
const startTime = Date.now();
|
|
272
|
+
try {
|
|
273
|
+
const response = await fetch(url, {
|
|
274
|
+
signal: AbortSignal.timeout(5000),
|
|
275
|
+
});
|
|
276
|
+
await response.json();
|
|
277
|
+
return {
|
|
278
|
+
service: serviceName,
|
|
279
|
+
domain: 'unknown',
|
|
280
|
+
port: 0,
|
|
281
|
+
status: 'healthy',
|
|
282
|
+
timestamp: new Date().toISOString(),
|
|
283
|
+
responseTime: Date.now() - startTime,
|
|
284
|
+
version: 'unknown',
|
|
285
|
+
checks: { http: true },
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
catch (err) {
|
|
289
|
+
Logger.error(`Service health check failed for ${serviceName}:`, err);
|
|
290
|
+
return {
|
|
291
|
+
service: serviceName,
|
|
292
|
+
domain: 'unknown',
|
|
293
|
+
port: 0,
|
|
294
|
+
status: 'stopped',
|
|
295
|
+
timestamp: new Date().toISOString(),
|
|
296
|
+
responseTime: Date.now() - startTime,
|
|
297
|
+
version: 'unknown',
|
|
298
|
+
checks: { http: false },
|
|
299
|
+
message: `Service check failed: ${err.message}`,
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Calculate aggregated health status from results
|
|
305
|
+
*/
|
|
306
|
+
function calculateAggregatedStatus(results) {
|
|
307
|
+
const healthy = results.filter((r) => r.status === 'healthy').length;
|
|
308
|
+
const degraded = results.filter((r) => r.status === 'degraded').length;
|
|
309
|
+
const unhealthy = results.filter((r) => r.status === 'unhealthy').length;
|
|
310
|
+
return {
|
|
311
|
+
timestamp: new Date().toISOString(),
|
|
312
|
+
totalServices: results.length,
|
|
313
|
+
healthy,
|
|
314
|
+
degraded,
|
|
315
|
+
unhealthy,
|
|
316
|
+
services: results,
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Log health summary
|
|
321
|
+
*/
|
|
322
|
+
function logHealthSummary(status) {
|
|
323
|
+
if (status.unhealthy > 0) {
|
|
324
|
+
Logger.warn(`⚠️ Health check: ${status.healthy} healthy, ${status.degraded} degraded, ${status.unhealthy} unhealthy`);
|
|
325
|
+
}
|
|
326
|
+
else if (status.degraded > 0) {
|
|
327
|
+
Logger.warn(`⚠️ Health check: ${status.healthy} healthy, ${status.degraded} degraded`);
|
|
328
|
+
}
|
|
329
|
+
else {
|
|
330
|
+
Logger.info(`✅ All ${status.healthy} services healthy`);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Health Check Aggregator Endpoint
|
|
335
|
+
* Exposes aggregated health status at GET /health/services
|
|
336
|
+
*/
|
|
337
|
+
export const HealthCheckAggregator = Object.freeze({
|
|
338
|
+
/**
|
|
339
|
+
* Create a new health check aggregator instance
|
|
340
|
+
*/
|
|
341
|
+
create(monitor) {
|
|
342
|
+
return {
|
|
343
|
+
/**
|
|
344
|
+
* Handle aggregated health check request
|
|
345
|
+
*/
|
|
346
|
+
async handle(_req, res) {
|
|
347
|
+
const status = monitor.getLastStatus();
|
|
348
|
+
let statusCode;
|
|
349
|
+
if (status.unhealthy > 0) {
|
|
350
|
+
statusCode = 503;
|
|
351
|
+
}
|
|
352
|
+
else if (status.degraded > 0) {
|
|
353
|
+
statusCode = 202;
|
|
354
|
+
}
|
|
355
|
+
else {
|
|
356
|
+
statusCode = 200;
|
|
357
|
+
}
|
|
358
|
+
res.setStatus(statusCode).json(status);
|
|
359
|
+
},
|
|
360
|
+
};
|
|
361
|
+
},
|
|
362
|
+
});
|
|
363
|
+
/**
|
|
364
|
+
* Run all service health checks
|
|
365
|
+
*/
|
|
366
|
+
async function runAllChecks(healthCheckUrls, lastResults) {
|
|
367
|
+
const checks = Object.entries(healthCheckUrls).map(async ([serviceName, url]) => checkService(serviceName, url));
|
|
368
|
+
const results = await Promise.all(checks);
|
|
369
|
+
// Store results
|
|
370
|
+
results.forEach((result) => {
|
|
371
|
+
lastResults.set(result.service, result);
|
|
372
|
+
});
|
|
373
|
+
return calculateAggregatedStatus(results);
|
|
374
|
+
}
|
|
375
|
+
export default {
|
|
376
|
+
HealthCheckHandler,
|
|
377
|
+
ServiceHealthMonitor,
|
|
378
|
+
HealthCheckAggregator,
|
|
379
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CSRF Middleware
|
|
3
|
+
* Protects against Cross-Site Request Forgery attacks
|
|
4
|
+
* Uses CsrfTokenManager for token generation and validation
|
|
5
|
+
*/
|
|
6
|
+
import { Middleware } from './MiddlewareStack';
|
|
7
|
+
export interface CsrfOptions {
|
|
8
|
+
cookieName?: string;
|
|
9
|
+
headerName?: string;
|
|
10
|
+
bodyKey?: string;
|
|
11
|
+
ignoreMethods?: string[];
|
|
12
|
+
}
|
|
13
|
+
export declare const CsrfMiddleware: Readonly<{
|
|
14
|
+
/**
|
|
15
|
+
* Create CSRF protection middleware
|
|
16
|
+
*/
|
|
17
|
+
create(options?: CsrfOptions): Middleware;
|
|
18
|
+
}>;
|
|
19
|
+
//# sourceMappingURL=CsrfMiddleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CsrfMiddleware.d.ts","sourceRoot":"","sources":["../../../src/middleware/CsrfMiddleware.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAGzD,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AASD,eAAO,MAAM,cAAc;IACzB;;OAEG;qBACa,WAAW,GAAQ,UAAU;EA+E7C,CAAC"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CSRF Middleware
|
|
3
|
+
* Protects against Cross-Site Request Forgery attacks
|
|
4
|
+
* Uses CsrfTokenManager for token generation and validation
|
|
5
|
+
*/
|
|
6
|
+
import { Logger } from '../config/logger';
|
|
7
|
+
import { ErrorFactory } from '../exceptions/ZintrustError';
|
|
8
|
+
import { CsrfTokenManager } from '../security/CsrfTokenManager';
|
|
9
|
+
const DEFAULT_OPTIONS = {
|
|
10
|
+
cookieName: 'XSRF-TOKEN',
|
|
11
|
+
headerName: 'X-CSRF-Token',
|
|
12
|
+
bodyKey: '_csrf',
|
|
13
|
+
ignoreMethods: ['GET', 'HEAD', 'OPTIONS'],
|
|
14
|
+
};
|
|
15
|
+
export const CsrfMiddleware = Object.freeze({
|
|
16
|
+
/**
|
|
17
|
+
* Create CSRF protection middleware
|
|
18
|
+
*/
|
|
19
|
+
create(options = {}) {
|
|
20
|
+
const config = { ...DEFAULT_OPTIONS, ...options };
|
|
21
|
+
const manager = CsrfTokenManager.create();
|
|
22
|
+
// Periodic cleanup to prevent memory leaks
|
|
23
|
+
// Run every hour (matching default token TTL)
|
|
24
|
+
const cleanupTimer = setInterval(() => {
|
|
25
|
+
manager.cleanup();
|
|
26
|
+
}, 3600000);
|
|
27
|
+
// Node: allow process to exit; other runtimes may not support unref()
|
|
28
|
+
if (isUnrefableTimer(cleanupTimer)) {
|
|
29
|
+
cleanupTimer.unref();
|
|
30
|
+
}
|
|
31
|
+
return async (req, res, next) => {
|
|
32
|
+
// We need a session ID to bind the token to.
|
|
33
|
+
// Assuming a session middleware has run before this and populated req.context.sessionId
|
|
34
|
+
// or we use a cookie for the session ID.
|
|
35
|
+
// For now, we'll try to get it from a cookie or generate a temporary one if missing (stateless fallback)
|
|
36
|
+
// Note: In a real scenario, this MUST be tied to the user's authenticated session.
|
|
37
|
+
// Here we check for a specific session cookie or header.
|
|
38
|
+
const cookies = parseCookies(req.getHeader('cookie') || '');
|
|
39
|
+
let sessionId = cookies['ZIN_SESSION_ID'] || req.context['sessionId'];
|
|
40
|
+
if (!sessionId) {
|
|
41
|
+
// If no session exists, we can't effectively bind CSRF to a session.
|
|
42
|
+
// However, for the sake of the middleware functioning in a stateless way (Double Submit Cookie pattern),
|
|
43
|
+
// we can generate a pseudo-session-id if one doesn't exist, but it's less secure.
|
|
44
|
+
// Ideally, this middleware should throw if session is missing.
|
|
45
|
+
// For this implementation, we'll skip if no session is found, but log a warning.
|
|
46
|
+
// Logger.warn('CSRF Middleware: No session ID found. Skipping CSRF check.');
|
|
47
|
+
// await next();
|
|
48
|
+
// return;
|
|
49
|
+
// Better approach: Generate a session ID if missing (Double Submit Cookie foundation)
|
|
50
|
+
// IMPORTANT: use a cryptographically secure generator (Sonar S2245).
|
|
51
|
+
sessionId = generateSecureId();
|
|
52
|
+
// We would need to set this session cookie, but we can't easily do that without a SessionManager.
|
|
53
|
+
// We'll assume the SessionMiddleware handles session creation.
|
|
54
|
+
}
|
|
55
|
+
const method = req.getMethod();
|
|
56
|
+
// 1. Token Generation (for safe methods)
|
|
57
|
+
if (config.ignoreMethods?.includes(method) ?? false) {
|
|
58
|
+
const token = manager.generateToken(sessionId);
|
|
59
|
+
// Set cookie for Double Submit Cookie pattern (readable by frontend)
|
|
60
|
+
res.setHeader('Set-Cookie', `${config.cookieName}=${token}; Path=/; SameSite=Strict`);
|
|
61
|
+
// Also expose in locals for server-side rendering
|
|
62
|
+
res.locals['csrfToken'] = token;
|
|
63
|
+
await next();
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
// 2. Token Validation (for unsafe methods)
|
|
67
|
+
const tokenFromHeader = req.getHeader(config.headerName ?? 'X-CSRF-Token');
|
|
68
|
+
const tokenFromBody = req.getBody()?.[config.bodyKey ?? '_csrf'];
|
|
69
|
+
const tokenFromCookie = cookies[config.cookieName ?? 'XSRF-TOKEN'];
|
|
70
|
+
const token = tokenFromHeader || tokenFromBody || tokenFromCookie;
|
|
71
|
+
if (!token || !manager.validateToken(sessionId, token)) {
|
|
72
|
+
Logger.warn(`CSRF validation failed for session ${sessionId}`);
|
|
73
|
+
res.setStatus(403);
|
|
74
|
+
res.json({
|
|
75
|
+
error: 'Forbidden',
|
|
76
|
+
message: 'Invalid CSRF token',
|
|
77
|
+
});
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
await next();
|
|
81
|
+
};
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
/**
|
|
85
|
+
* Helper to parse cookies
|
|
86
|
+
*/
|
|
87
|
+
function parseCookies(cookieHeader) {
|
|
88
|
+
const list = {};
|
|
89
|
+
if (!cookieHeader)
|
|
90
|
+
return list;
|
|
91
|
+
cookieHeader.split(';').forEach((cookie) => {
|
|
92
|
+
const parts = cookie.split('=');
|
|
93
|
+
const name = parts.shift()?.trim();
|
|
94
|
+
const value = parts.join('=');
|
|
95
|
+
if (name !== null && name !== undefined)
|
|
96
|
+
list[name] = decodeURIComponent(value);
|
|
97
|
+
});
|
|
98
|
+
return list;
|
|
99
|
+
}
|
|
100
|
+
function isUnrefableTimer(value) {
|
|
101
|
+
if (typeof value !== 'object' || value === null)
|
|
102
|
+
return false;
|
|
103
|
+
return 'unref' in value && typeof value.unref === 'function';
|
|
104
|
+
}
|
|
105
|
+
function generateSecureId() {
|
|
106
|
+
if (typeof globalThis.crypto?.randomUUID === 'function') {
|
|
107
|
+
return globalThis.crypto.randomUUID();
|
|
108
|
+
}
|
|
109
|
+
if (typeof globalThis.crypto?.getRandomValues === 'function') {
|
|
110
|
+
const bytes = new Uint8Array(32);
|
|
111
|
+
globalThis.crypto.getRandomValues(bytes);
|
|
112
|
+
return bytesToHex(bytes);
|
|
113
|
+
}
|
|
114
|
+
throw ErrorFactory.createSecurityError('CSRF Middleware: secure crypto API not available to generate a session id.');
|
|
115
|
+
}
|
|
116
|
+
function bytesToHex(bytes) {
|
|
117
|
+
let out = '';
|
|
118
|
+
for (const b of bytes)
|
|
119
|
+
out += b.toString(16).padStart(2, '0');
|
|
120
|
+
return out;
|
|
121
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { IRequest } from '../http/Request';
|
|
2
|
+
import { IResponse } from '../http/Response';
|
|
3
|
+
/**
|
|
4
|
+
* Middleware Stack
|
|
5
|
+
* Manages middleware execution pipeline
|
|
6
|
+
*/
|
|
7
|
+
export type Middleware = (req: IRequest, res: IResponse, next: () => Promise<void>) => Promise<void>;
|
|
8
|
+
export interface IMiddlewareStack {
|
|
9
|
+
register(name: string, handler: Middleware): void;
|
|
10
|
+
execute(request: IRequest, response: IResponse, only?: string[] | Middleware[]): Promise<void>;
|
|
11
|
+
getMiddlewares(): Array<{
|
|
12
|
+
name: string;
|
|
13
|
+
handler: Middleware;
|
|
14
|
+
}>;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Middleware Stack
|
|
18
|
+
* Refactored to Functional Object pattern
|
|
19
|
+
*/
|
|
20
|
+
export declare const MiddlewareStack: Readonly<{
|
|
21
|
+
/**
|
|
22
|
+
* Create a new middleware stack instance
|
|
23
|
+
*/
|
|
24
|
+
create(): IMiddlewareStack;
|
|
25
|
+
}>;
|
|
26
|
+
export default MiddlewareStack;
|
|
27
|
+
//# sourceMappingURL=MiddlewareStack.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MiddlewareStack.d.ts","sourceRoot":"","sources":["../../../src/middleware/MiddlewareStack.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C;;;GAGG;AAEH,MAAM,MAAM,UAAU,GAAG,CACvB,GAAG,EAAE,QAAQ,EACb,GAAG,EAAE,SAAS,EACd,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,KACtB,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,IAAI,CAAC;IAClD,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,UAAU,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/F,cAAc,IAAI,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,UAAU,CAAA;KAAE,CAAC,CAAC;CAChE;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe;IAC1B;;OAEG;cACO,gBAAgB;EAsC1B,CAAC;AAEH,eAAe,eAAe,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Middleware Stack
|
|
3
|
+
* Refactored to Functional Object pattern
|
|
4
|
+
*/
|
|
5
|
+
export const MiddlewareStack = Object.freeze({
|
|
6
|
+
/**
|
|
7
|
+
* Create a new middleware stack instance
|
|
8
|
+
*/
|
|
9
|
+
create() {
|
|
10
|
+
const middlewares = [];
|
|
11
|
+
return {
|
|
12
|
+
/**
|
|
13
|
+
* Register middleware
|
|
14
|
+
*/
|
|
15
|
+
register(name, handler) {
|
|
16
|
+
middlewares.push({ name, handler });
|
|
17
|
+
},
|
|
18
|
+
/**
|
|
19
|
+
* Execute middleware stack
|
|
20
|
+
*/
|
|
21
|
+
async execute(request, response, only) {
|
|
22
|
+
const filteredMiddlewares = only
|
|
23
|
+
? middlewares.filter((m) => only.includes(m.name))
|
|
24
|
+
: middlewares;
|
|
25
|
+
let index = 0;
|
|
26
|
+
const next = async () => {
|
|
27
|
+
if (index >= filteredMiddlewares.length)
|
|
28
|
+
return;
|
|
29
|
+
const middleware = filteredMiddlewares[index++];
|
|
30
|
+
await middleware.handler(request, response, next);
|
|
31
|
+
};
|
|
32
|
+
await next();
|
|
33
|
+
},
|
|
34
|
+
/**
|
|
35
|
+
* Get all middleware
|
|
36
|
+
*/
|
|
37
|
+
getMiddlewares() {
|
|
38
|
+
return middlewares;
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
export default MiddlewareStack;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rate Limiter Middleware
|
|
3
|
+
* Token bucket implementation for request rate limiting
|
|
4
|
+
* Zero-dependency implementation
|
|
5
|
+
*/
|
|
6
|
+
import { IRequest } from '../http/Request';
|
|
7
|
+
import { Middleware } from './MiddlewareStack';
|
|
8
|
+
export interface RateLimitOptions {
|
|
9
|
+
windowMs: number;
|
|
10
|
+
max: number;
|
|
11
|
+
message?: string;
|
|
12
|
+
statusCode?: number;
|
|
13
|
+
headers?: boolean;
|
|
14
|
+
keyGenerator?: (req: IRequest) => string;
|
|
15
|
+
}
|
|
16
|
+
export declare const RateLimiter: Readonly<{
|
|
17
|
+
/**
|
|
18
|
+
* Create rate limiter middleware
|
|
19
|
+
*/
|
|
20
|
+
create(options?: RateLimitOptions): Middleware;
|
|
21
|
+
}>;
|
|
22
|
+
//# sourceMappingURL=RateLimiter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RateLimiter.d.ts","sourceRoot":"","sources":["../../../src/middleware/RateLimiter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAEzD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,QAAQ,KAAK,MAAM,CAAC;CAC1C;AAoBD,eAAO,MAAM,WAAW;IACtB;;OAEG;qBACa,gBAAgB,GAAqB,UAAU;EA4D/D,CAAC"}
|