@zintrust/core 0.1.19 → 0.1.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -10
- package/bin/zintrust-main.d.ts.map +1 -1
- package/bin/zintrust-main.js +9 -0
- package/package.json +3 -2
- package/public/error-pages/404.html +145 -0
- package/public/error-pages/500.html +266 -0
- package/public/error-pages/error.css +628 -0
- package/public/error-pages/error.js +428 -0
- package/public/zintrust.svg +30 -0
- package/routes/api.d.ts.map +1 -1
- package/routes/api.js +41 -17
- package/routes/metrics.d.ts +9 -0
- package/routes/metrics.d.ts.map +1 -0
- package/routes/metrics.js +20 -0
- package/routes/openapi.d.ts +9 -0
- package/routes/openapi.d.ts.map +1 -0
- package/routes/openapi.js +76 -0
- package/src/boot/Application.d.ts +2 -2
- package/src/boot/Application.d.ts.map +1 -1
- package/src/boot/Application.js +66 -13
- package/src/boot/Server.d.ts +3 -2
- package/src/boot/Server.d.ts.map +1 -1
- package/src/boot/Server.js +39 -165
- package/src/boot/bootstrap.js +2 -0
- package/src/cache/Cache.d.ts +1 -1
- package/src/cache/Cache.d.ts.map +1 -1
- package/src/cache/CacheDriver.d.ts +4 -0
- package/src/cache/CacheDriver.d.ts.map +1 -1
- package/src/cache/drivers/KVDriver.d.ts +1 -1
- package/src/cache/drivers/KVDriver.d.ts.map +1 -1
- package/src/cache/drivers/MemoryDriver.d.ts +1 -1
- package/src/cache/drivers/MemoryDriver.d.ts.map +1 -1
- package/src/cache/drivers/MemoryDriver.js +16 -0
- package/src/cache/drivers/MongoDriver.d.ts +1 -1
- package/src/cache/drivers/MongoDriver.d.ts.map +1 -1
- package/src/cache/drivers/RedisDriver.d.ts +1 -1
- package/src/cache/drivers/RedisDriver.d.ts.map +1 -1
- package/src/cli/CLI.d.ts.map +1 -1
- package/src/cli/CLI.js +10 -4
- package/src/cli/commands/AddCommand.d.ts +2 -2
- package/src/cli/commands/AddCommand.d.ts.map +1 -1
- package/src/cli/commands/AddCommand.js +135 -58
- package/src/cli/commands/ConfigCommand.d.ts +1 -1
- package/src/cli/commands/ConfigCommand.d.ts.map +1 -1
- package/src/cli/commands/CreateCommand.d.ts +15 -0
- package/src/cli/commands/CreateCommand.d.ts.map +1 -0
- package/src/cli/commands/CreateCommand.js +143 -0
- package/src/cli/commands/D1MigrateCommand.d.ts +1 -1
- package/src/cli/commands/D1MigrateCommand.d.ts.map +1 -1
- package/src/cli/commands/D1MigrateCommand.js +16 -20
- package/src/cli/commands/DbSeedCommand.d.ts +9 -0
- package/src/cli/commands/DbSeedCommand.d.ts.map +1 -0
- package/src/cli/commands/DbSeedCommand.js +171 -0
- package/src/cli/commands/DebugCommand.d.ts +1 -1
- package/src/cli/commands/DebugCommand.d.ts.map +1 -1
- package/src/cli/commands/FixCommand.d.ts +1 -1
- package/src/cli/commands/FixCommand.d.ts.map +1 -1
- package/src/cli/commands/JwtDevCommand.d.ts +8 -0
- package/src/cli/commands/JwtDevCommand.d.ts.map +1 -0
- package/src/cli/commands/JwtDevCommand.js +114 -0
- package/src/cli/commands/KeyGenerateCommand.d.ts +1 -1
- package/src/cli/commands/KeyGenerateCommand.d.ts.map +1 -1
- package/src/cli/commands/LogsCommand.d.ts +2 -2
- package/src/cli/commands/LogsCommand.d.ts.map +1 -1
- package/src/cli/commands/LogsCommand.js +36 -2
- package/src/cli/commands/MakeMailTemplateCommand.d.ts +1 -1
- package/src/cli/commands/MakeMailTemplateCommand.d.ts.map +1 -1
- package/src/cli/commands/MakeNotificationTemplateCommand.d.ts +1 -1
- package/src/cli/commands/MakeNotificationTemplateCommand.d.ts.map +1 -1
- package/src/cli/commands/MigrateCommand.d.ts +1 -1
- package/src/cli/commands/MigrateCommand.d.ts.map +1 -1
- package/src/cli/commands/MigrateCommand.js +324 -35
- package/src/cli/commands/NewCommand.d.ts +1 -1
- package/src/cli/commands/NewCommand.d.ts.map +1 -1
- package/src/cli/commands/NewCommand.js +12 -4
- package/src/cli/commands/PluginCommand.d.ts +1 -1
- package/src/cli/commands/PluginCommand.d.ts.map +1 -1
- package/src/cli/commands/PrepareCommand.d.ts +1 -1
- package/src/cli/commands/PrepareCommand.d.ts.map +1 -1
- package/src/cli/commands/QACommand.d.ts +2 -2
- package/src/cli/commands/QACommand.d.ts.map +1 -1
- package/src/cli/commands/RoutesCommand.d.ts +10 -0
- package/src/cli/commands/RoutesCommand.d.ts.map +1 -0
- package/src/cli/commands/RoutesCommand.js +242 -0
- package/src/cli/commands/SimulateCommand.d.ts +1 -1
- package/src/cli/commands/SimulateCommand.d.ts.map +1 -1
- package/src/cli/commands/index.d.ts +3 -0
- package/src/cli/commands/index.d.ts.map +1 -1
- package/src/cli/commands/index.js +3 -0
- package/src/cli/config/ConfigManager.d.ts +1 -1
- package/src/cli/config/ConfigManager.d.ts.map +1 -1
- package/src/cli/config/ConfigValidator.d.ts +1 -1
- package/src/cli/config/ConfigValidator.d.ts.map +1 -1
- package/src/cli/config/ConfigValidator.js +1 -1
- package/src/cli/d1/D1SqlMigrations.d.ts +20 -0
- package/src/cli/d1/D1SqlMigrations.d.ts.map +1 -0
- package/src/cli/d1/D1SqlMigrations.js +229 -0
- package/src/cli/d1/WranglerConfig.d.ts +4 -0
- package/src/cli/d1/WranglerConfig.d.ts.map +1 -0
- package/src/cli/d1/WranglerConfig.js +122 -0
- package/src/cli/d1/WranglerD1.d.ts +11 -0
- package/src/cli/d1/WranglerD1.d.ts.map +1 -0
- package/src/cli/d1/WranglerD1.js +16 -0
- package/src/cli/scaffolding/ControllerGenerator.d.ts.map +1 -1
- package/src/cli/scaffolding/ControllerGenerator.js +76 -26
- package/src/cli/scaffolding/FactoryGenerator.d.ts.map +1 -1
- package/src/cli/scaffolding/FactoryGenerator.js +3 -1
- package/src/cli/scaffolding/GovernanceScaffolder.d.ts +23 -0
- package/src/cli/scaffolding/GovernanceScaffolder.d.ts.map +1 -0
- package/src/cli/scaffolding/GovernanceScaffolder.js +327 -0
- package/src/cli/scaffolding/MigrationGenerator.d.ts +10 -0
- package/src/cli/scaffolding/MigrationGenerator.d.ts.map +1 -1
- package/src/cli/scaffolding/MigrationGenerator.js +137 -51
- package/src/cli/scaffolding/ModelGenerator.js +1 -1
- package/src/cli/scaffolding/ProjectScaffolder.d.ts.map +1 -1
- package/src/cli/scaffolding/ProjectScaffolder.js +36 -4
- package/src/cli/scaffolding/RouteGenerator.d.ts.map +1 -1
- package/src/cli/scaffolding/RouteGenerator.js +79 -43
- package/src/cli/scaffolding/SeederGenerator.d.ts +5 -0
- package/src/cli/scaffolding/SeederGenerator.d.ts.map +1 -1
- package/src/cli/scaffolding/SeederGenerator.js +63 -15
- package/src/cli/scaffolding/ServiceScaffolder.d.ts.map +1 -1
- package/src/cli/scaffolding/ServiceScaffolder.js +28 -7
- package/src/cli/scaffolding/index.d.ts +2 -0
- package/src/cli/scaffolding/index.d.ts.map +1 -1
- package/src/cli/scaffolding/index.js +1 -0
- package/src/common/index.d.ts +8 -0
- package/src/common/index.d.ts.map +1 -1
- package/src/common/index.js +28 -0
- package/src/common/utility.d.ts +38 -0
- package/src/common/utility.d.ts.map +1 -0
- package/src/common/utility.js +101 -0
- package/src/config/FileLogWriter.d.ts +2 -1
- package/src/config/FileLogWriter.d.ts.map +1 -1
- package/src/config/FileLogWriter.js +83 -2
- package/src/config/app.d.ts.map +1 -1
- package/src/config/app.js +3 -1
- package/src/config/broadcast.d.ts +14 -28
- package/src/config/broadcast.d.ts.map +1 -1
- package/src/config/broadcast.js +69 -35
- package/src/config/cache.d.ts +13 -45
- package/src/config/cache.d.ts.map +1 -1
- package/src/config/cache.js +69 -25
- package/src/config/cloudflare.d.ts +1 -1
- package/src/config/cloudflare.d.ts.map +1 -1
- package/src/config/database.d.ts +22 -64
- package/src/config/database.d.ts.map +1 -1
- package/src/config/database.js +191 -37
- package/src/config/env.d.ts +12 -0
- package/src/config/env.d.ts.map +1 -1
- package/src/config/env.js +14 -0
- package/src/config/index.d.ts +33 -137
- package/src/config/index.d.ts.map +1 -1
- package/src/config/logging/KvLogger.js +1 -1
- package/src/config/logging/SlackLogger.js +2 -2
- package/src/config/mail.d.ts +19 -55
- package/src/config/mail.d.ts.map +1 -1
- package/src/config/mail.js +63 -21
- package/src/config/middleware.d.ts +44 -1
- package/src/config/middleware.d.ts.map +1 -1
- package/src/config/middleware.js +157 -5
- package/src/config/notification.d.ts +14 -27
- package/src/config/notification.d.ts.map +1 -1
- package/src/config/notification.js +82 -36
- package/src/config/queue.d.ts +21 -51
- package/src/config/queue.d.ts.map +1 -1
- package/src/config/queue.js +72 -27
- package/src/config/security.d.ts +1 -1
- package/src/config/security.js +1 -1
- package/src/config/storage.d.ts +27 -34
- package/src/config/storage.d.ts.map +1 -1
- package/src/config/storage.js +97 -56
- package/src/config/type.d.ts +13 -2
- package/src/config/type.d.ts.map +1 -1
- package/src/events/EventDispatcher.d.ts.map +1 -1
- package/src/events/EventDispatcher.js +6 -4
- package/src/exceptions/ZintrustError.d.ts +7 -0
- package/src/exceptions/ZintrustError.d.ts.map +1 -1
- package/src/exceptions/ZintrustError.js +56 -0
- package/src/features/Auth.d.ts +1 -1
- package/src/features/Auth.d.ts.map +1 -1
- package/src/features/Auth.js +3 -3
- package/src/features/Queue.js +1 -1
- package/src/functions/cloudflare.d.ts.map +1 -1
- package/src/functions/cloudflare.js +3 -14
- package/src/functions/deno.d.ts.map +1 -1
- package/src/functions/deno.js +3 -14
- package/src/functions/lambda.d.ts.map +1 -1
- package/src/functions/lambda.js +3 -14
- package/src/health/StartupHealthChecks.js +1 -1
- package/src/http/Controller.d.ts +2 -2
- package/src/http/Controller.d.ts.map +1 -1
- package/src/http/FileUpload.d.ts +68 -0
- package/src/http/FileUpload.d.ts.map +1 -0
- package/src/http/FileUpload.js +120 -0
- package/src/http/Kernel.d.ts +5 -5
- package/src/http/Kernel.d.ts.map +1 -1
- package/src/http/Kernel.js +139 -23
- package/src/http/Request.d.ts +20 -1
- package/src/http/Request.d.ts.map +1 -1
- package/src/http/Request.js +23 -0
- package/src/http/RequestContext.d.ts +6 -0
- package/src/http/RequestContext.d.ts.map +1 -1
- package/src/http/RequestContext.js +77 -1
- package/src/http/Response.d.ts +1 -1
- package/src/http/Response.d.ts.map +1 -1
- package/src/http/ValidationHelper.d.ts +78 -0
- package/src/http/ValidationHelper.d.ts.map +1 -0
- package/src/http/ValidationHelper.js +121 -0
- package/src/http/error-pages/ErrorPageRenderer.d.ts +17 -0
- package/src/http/error-pages/ErrorPageRenderer.d.ts.map +1 -0
- package/src/http/error-pages/ErrorPageRenderer.js +88 -0
- package/src/http/middleware/BodyParsingMiddleware.d.ts +12 -0
- package/src/http/middleware/BodyParsingMiddleware.d.ts.map +1 -0
- package/src/http/middleware/BodyParsingMiddleware.js +251 -0
- package/src/http/middleware/FileUploadMiddleware.d.ts +12 -0
- package/src/http/middleware/FileUploadMiddleware.d.ts.map +1 -0
- package/src/http/middleware/FileUploadMiddleware.js +74 -0
- package/src/http/parsers/BodyParsers.d.ts +32 -0
- package/src/http/parsers/BodyParsers.d.ts.map +1 -0
- package/src/http/parsers/BodyParsers.js +159 -0
- package/src/http/parsers/MultipartParser.d.ts +33 -0
- package/src/http/parsers/MultipartParser.d.ts.map +1 -0
- package/src/http/parsers/MultipartParser.js +156 -0
- package/src/http/parsers/MultipartParserRegistry.d.ts +34 -0
- package/src/http/parsers/MultipartParserRegistry.d.ts.map +1 -0
- package/src/http/parsers/MultipartParserRegistry.js +20 -0
- package/src/http/validated.d.ts +12 -0
- package/src/http/validated.d.ts.map +1 -0
- package/src/http/validated.js +41 -0
- package/src/index.d.ts +73 -12
- package/src/index.d.ts.map +1 -1
- package/src/index.js +60 -5
- package/src/microservices/PostgresAdapter.d.ts.map +1 -1
- package/src/microservices/PostgresAdapter.js +0 -1
- package/src/microservices/RequestTracingMiddleware.d.ts +2 -2
- package/src/microservices/RequestTracingMiddleware.d.ts.map +1 -1
- package/src/microservices/RequestTracingMiddleware.js +3 -0
- package/src/microservices/ServiceAuthMiddleware.d.ts +2 -2
- package/src/microservices/ServiceAuthMiddleware.d.ts.map +1 -1
- package/src/middleware/AuthMiddleware.d.ts +10 -0
- package/src/middleware/AuthMiddleware.d.ts.map +1 -0
- package/src/middleware/AuthMiddleware.js +16 -0
- package/src/middleware/CsrfMiddleware.d.ts +11 -1
- package/src/middleware/CsrfMiddleware.d.ts.map +1 -1
- package/src/middleware/CsrfMiddleware.js +33 -0
- package/src/middleware/JwtAuthMiddleware.d.ts +11 -0
- package/src/middleware/JwtAuthMiddleware.d.ts.map +1 -0
- package/src/middleware/JwtAuthMiddleware.js +73 -0
- package/src/middleware/LoggingMiddleware.d.ts.map +1 -1
- package/src/middleware/LoggingMiddleware.js +8 -3
- package/src/middleware/MiddlewareStack.d.ts +2 -2
- package/src/middleware/MiddlewareStack.d.ts.map +1 -1
- package/src/middleware/RateLimiter.d.ts +2 -2
- package/src/middleware/RateLimiter.d.ts.map +1 -1
- package/src/middleware/SanitizeBodyMiddleware.d.ts +12 -0
- package/src/middleware/SanitizeBodyMiddleware.d.ts.map +1 -0
- package/src/middleware/SanitizeBodyMiddleware.js +31 -0
- package/src/middleware/SecurityMiddleware.d.ts +1 -1
- package/src/middleware/SecurityMiddleware.d.ts.map +1 -1
- package/src/middleware/SessionMiddleware.d.ts +1 -1
- package/src/middleware/SessionMiddleware.d.ts.map +1 -1
- package/src/middleware/ValidationMiddleware.d.ts +25 -0
- package/src/middleware/ValidationMiddleware.d.ts.map +1 -0
- package/src/middleware/ValidationMiddleware.js +251 -0
- package/src/migrations/MigrationDiscovery.d.ts +5 -0
- package/src/migrations/MigrationDiscovery.d.ts.map +1 -0
- package/src/migrations/MigrationDiscovery.js +16 -0
- package/src/migrations/MigrationLoader.d.ts +5 -0
- package/src/migrations/MigrationLoader.d.ts.map +1 -0
- package/src/migrations/MigrationLoader.js +43 -0
- package/src/migrations/MigrationLock.d.ts +4 -0
- package/src/migrations/MigrationLock.d.ts.map +1 -0
- package/src/migrations/MigrationLock.js +33 -0
- package/src/migrations/Migrator.d.ts +23 -0
- package/src/migrations/Migrator.d.ts.map +1 -0
- package/src/migrations/Migrator.js +4 -0
- package/src/migrations/MigratorFactory.d.ts +25 -0
- package/src/migrations/MigratorFactory.d.ts.map +1 -0
- package/src/migrations/MigratorFactory.js +339 -0
- package/src/migrations/schema/Blueprint.d.ts +5 -0
- package/src/migrations/schema/Blueprint.d.ts.map +1 -0
- package/src/migrations/schema/Blueprint.js +189 -0
- package/src/migrations/schema/Schema.d.ts +8 -0
- package/src/migrations/schema/Schema.d.ts.map +1 -0
- package/src/migrations/schema/Schema.js +141 -0
- package/src/migrations/schema/SchemaCompiler.d.ts +20 -0
- package/src/migrations/schema/SchemaCompiler.d.ts.map +1 -0
- package/src/migrations/schema/SchemaCompiler.js +262 -0
- package/src/migrations/schema/index.d.ts +5 -0
- package/src/migrations/schema/index.d.ts.map +1 -0
- package/src/migrations/schema/index.js +3 -0
- package/src/migrations/schema/types.d.ts +86 -0
- package/src/migrations/schema/types.d.ts.map +1 -0
- package/src/migrations/schema/types.js +1 -0
- package/src/migrations/types.d.ts +45 -0
- package/src/migrations/types.d.ts.map +1 -0
- package/src/migrations/types.js +1 -0
- package/src/node-singletons/crypto.d.ts +1 -1
- package/src/node-singletons/crypto.d.ts.map +1 -1
- package/src/node-singletons/crypto.js +1 -1
- package/src/node-singletons/fs.d.ts +2 -2
- package/src/node-singletons/fs.d.ts.map +1 -1
- package/src/node-singletons/fs.js +1 -1
- package/src/node-singletons/util.d.ts +6 -0
- package/src/node-singletons/util.d.ts.map +1 -0
- package/src/node-singletons/util.js +5 -0
- package/src/node.d.ts +3 -1
- package/src/node.d.ts.map +1 -1
- package/src/node.js +6 -2
- package/src/observability/OpenTelemetry.d.ts +62 -0
- package/src/observability/OpenTelemetry.d.ts.map +1 -0
- package/src/observability/OpenTelemetry.js +167 -0
- package/src/observability/PrometheusMetrics.d.ts +25 -0
- package/src/observability/PrometheusMetrics.d.ts.map +1 -0
- package/src/observability/PrometheusMetrics.js +114 -0
- package/src/openapi/OpenApiGenerator.d.ts +68 -0
- package/src/openapi/OpenApiGenerator.d.ts.map +1 -0
- package/src/openapi/OpenApiGenerator.js +287 -0
- package/src/orm/Database.d.ts +5 -2
- package/src/orm/Database.d.ts.map +1 -1
- package/src/orm/Database.js +219 -63
- package/src/orm/DatabaseAdapter.d.ts +14 -0
- package/src/orm/DatabaseAdapter.d.ts.map +1 -1
- package/src/orm/DatabaseAdapterRegistry.d.ts.map +1 -1
- package/src/orm/DatabaseAdapterRegistry.js +3 -1
- package/src/orm/DatabaseRuntimeRegistration.d.ts.map +1 -1
- package/src/orm/DatabaseRuntimeRegistration.js +12 -0
- package/src/orm/Model.d.ts +30 -2
- package/src/orm/Model.d.ts.map +1 -1
- package/src/orm/Model.js +255 -62
- package/src/orm/QueryBuilder.d.ts +22 -1
- package/src/orm/QueryBuilder.d.ts.map +1 -1
- package/src/orm/QueryBuilder.js +406 -99
- package/src/orm/Relationships.d.ts +7 -1
- package/src/orm/Relationships.d.ts.map +1 -1
- package/src/orm/Relationships.js +18 -0
- package/src/orm/SchemaCompiler.d.ts +9 -0
- package/src/orm/SchemaCompiler.d.ts.map +1 -0
- package/src/orm/SchemaCompiler.js +145 -0
- package/src/orm/adapters/D1Adapter.d.ts +1 -1
- package/src/orm/adapters/D1Adapter.d.ts.map +1 -1
- package/src/orm/adapters/MySQLAdapter.d.ts +1 -1
- package/src/orm/adapters/MySQLAdapter.d.ts.map +1 -1
- package/src/orm/adapters/MySQLAdapter.js +88 -69
- package/src/orm/adapters/PostgreSQLAdapter.d.ts +1 -1
- package/src/orm/adapters/PostgreSQLAdapter.d.ts.map +1 -1
- package/src/orm/adapters/PostgreSQLAdapter.js +88 -69
- package/src/orm/adapters/SQLServerAdapter.d.ts +1 -1
- package/src/orm/adapters/SQLServerAdapter.d.ts.map +1 -1
- package/src/orm/adapters/SQLiteAdapter.d.ts +1 -1
- package/src/orm/adapters/SQLiteAdapter.d.ts.map +1 -1
- package/src/orm/adapters/SQLiteAdapter.js +59 -3
- package/src/orm/maintenance/SqliteMaintenance.d.ts +5 -0
- package/src/orm/maintenance/SqliteMaintenance.d.ts.map +1 -0
- package/src/orm/maintenance/SqliteMaintenance.js +14 -0
- package/src/orm/migrations/MigrationStore.d.ts +38 -0
- package/src/orm/migrations/MigrationStore.d.ts.map +1 -0
- package/src/orm/migrations/MigrationStore.js +157 -0
- package/src/performance/CodeGenerationBenchmark.d.ts.map +1 -1
- package/src/performance/Optimizer.d.ts +7 -6
- package/src/performance/Optimizer.d.ts.map +1 -1
- package/src/performance/Optimizer.js +170 -55
- package/src/profiling/MemoryProfiler.d.ts +1 -1
- package/src/profiling/MemoryProfiler.d.ts.map +1 -1
- package/src/profiling/N1Detector.d.ts +1 -1
- package/src/profiling/N1Detector.d.ts.map +1 -1
- package/src/profiling/QueryLogger.d.ts +1 -1
- package/src/profiling/QueryLogger.d.ts.map +1 -1
- package/src/profiling/RequestProfiler.d.ts +3 -3
- package/src/profiling/RequestProfiler.d.ts.map +1 -1
- package/src/routes/metrics.d.ts +2 -0
- package/src/routes/metrics.d.ts.map +1 -0
- package/src/routes/metrics.js +1 -0
- package/src/routing/CoreRoutes.d.ts +12 -0
- package/src/routing/CoreRoutes.d.ts.map +1 -0
- package/src/routing/CoreRoutes.js +151 -0
- package/src/routing/RouteRegistry.d.ts +39 -0
- package/src/routing/RouteRegistry.d.ts.map +1 -0
- package/src/routing/RouteRegistry.js +44 -0
- package/src/routing/Router.d.ts +26 -9
- package/src/routing/Router.d.ts.map +1 -1
- package/src/routing/Router.js +79 -35
- package/src/routing/common.d.ts +15 -0
- package/src/routing/common.d.ts.map +1 -0
- package/src/routing/common.js +47 -0
- package/src/routing/doc.d.ts +27 -0
- package/src/routing/doc.d.ts.map +1 -0
- package/src/routing/doc.js +110 -0
- package/src/routing/error.d.ts +21 -0
- package/src/routing/error.d.ts.map +1 -0
- package/src/routing/error.js +126 -0
- package/src/routing/errorPages.d.ts +14 -0
- package/src/routing/errorPages.d.ts.map +1 -0
- package/src/routing/errorPages.js +103 -0
- package/src/routing/publicRoot.d.ts +27 -0
- package/src/routing/publicRoot.d.ts.map +1 -0
- package/src/routing/publicRoot.js +110 -0
- package/src/runtime/PluginAutoImports.d.ts +21 -0
- package/src/runtime/PluginAutoImports.d.ts.map +1 -0
- package/src/runtime/PluginAutoImports.js +59 -0
- package/src/runtime/PluginManager.d.ts +1 -5
- package/src/runtime/PluginManager.d.ts.map +1 -1
- package/src/runtime/PluginManager.js +25 -18
- package/src/runtime/RuntimeDetector.d.ts +1 -1
- package/src/runtime/RuntimeDetector.d.ts.map +1 -1
- package/src/runtime/StartupConfigFileRegistry.d.ts +20 -0
- package/src/runtime/StartupConfigFileRegistry.d.ts.map +1 -0
- package/src/runtime/StartupConfigFileRegistry.js +44 -0
- package/src/runtime/adapters/CloudflareAdapter.d.ts +1 -1
- package/src/runtime/adapters/CloudflareAdapter.d.ts.map +1 -1
- package/src/runtime/adapters/CloudflareAdapter.js +1 -1
- package/src/runtime/adapters/DenoAdapter.d.ts +1 -1
- package/src/runtime/adapters/DenoAdapter.d.ts.map +1 -1
- package/src/runtime/adapters/DenoAdapter.js +1 -1
- package/src/runtime/adapters/LambdaAdapter.d.ts +1 -1
- package/src/runtime/adapters/LambdaAdapter.d.ts.map +1 -1
- package/src/runtime/adapters/LambdaAdapter.js +1 -1
- package/src/runtime/adapters/NodeServerAdapter.d.ts +1 -1
- package/src/runtime/adapters/NodeServerAdapter.d.ts.map +1 -1
- package/src/runtime/getKernel.d.ts +9 -0
- package/src/runtime/getKernel.d.ts.map +1 -0
- package/src/runtime/getKernel.js +27 -0
- package/src/runtime/useFileLoader.d.ts +26 -0
- package/src/runtime/useFileLoader.d.ts.map +1 -0
- package/src/runtime/useFileLoader.js +188 -0
- package/src/scripts/TemplateImportsCheck.js +40 -0
- package/src/scripts/TemplateSync.js +90 -24
- package/src/security/Encryptor.d.ts.map +1 -1
- package/src/security/Encryptor.js +64 -7
- package/src/security/JwtManager.d.ts +1 -0
- package/src/security/JwtManager.d.ts.map +1 -1
- package/src/security/JwtManager.js +33 -0
- package/src/security/Sanitizer.d.ts +76 -0
- package/src/security/Sanitizer.d.ts.map +1 -0
- package/src/security/Sanitizer.js +412 -0
- package/src/security/TokenRevocation.d.ts +7 -0
- package/src/security/TokenRevocation.d.ts.map +1 -0
- package/src/security/TokenRevocation.js +57 -0
- package/src/security/XssProtection.d.ts.map +1 -1
- package/src/security/XssProtection.js +62 -14
- package/src/seeders/SeederDiscovery.d.ts +5 -0
- package/src/seeders/SeederDiscovery.d.ts.map +1 -0
- package/src/seeders/SeederDiscovery.js +21 -0
- package/src/seeders/SeederLoader.d.ts +5 -0
- package/src/seeders/SeederLoader.d.ts.map +1 -0
- package/src/seeders/SeederLoader.js +60 -0
- package/src/seeders/types.d.ts +18 -0
- package/src/seeders/types.d.ts.map +1 -0
- package/src/seeders/types.js +1 -0
- package/src/session/SessionManager.js +1 -1
- package/src/templates/adapters/MySQLAdapter.ts.tpl +109 -85
- package/src/templates/adapters/PostgreSQLAdapter.ts.tpl +129 -88
- package/src/templates/adapters/SQLServerAdapter.ts.tpl +5 -9
- package/src/templates/adapters/SQLiteAdapter.ts.tpl +78 -11
- package/src/templates/features/Queue.ts.tpl +3 -2
- package/src/templates/project/basic/app/Controllers/AuthController.ts.tpl +217 -0
- package/src/templates/project/basic/app/Controllers/UserController.ts.tpl +1 -12
- package/src/templates/project/basic/app/Types/controller.ts.tpl +46 -0
- package/src/templates/project/basic/config/FileLogWriter.ts.tpl +5 -236
- package/src/templates/project/basic/config/SecretsManager.ts.tpl +10 -447
- package/src/templates/project/basic/config/StartupConfigValidator.ts.tpl +9 -268
- package/src/templates/project/basic/config/app.ts.tpl +13 -153
- package/src/templates/project/basic/config/broadcast.ts.tpl +29 -126
- package/src/templates/project/basic/config/cache.ts.tpl +12 -70
- package/src/templates/project/basic/config/cloudflare.ts.tpl +4 -39
- package/src/templates/project/basic/config/constants.ts.tpl +9 -65
- package/src/templates/project/basic/config/database.ts.tpl +66 -123
- package/src/templates/project/basic/config/env.ts.tpl +5 -169
- package/src/templates/project/basic/config/features.ts.tpl +6 -54
- package/src/templates/project/basic/config/index.ts.tpl +8 -23
- package/src/templates/project/basic/config/logging/HttpLogger.ts.tpl +7 -114
- package/src/templates/project/basic/config/mail.ts.tpl +9 -62
- package/src/templates/project/basic/config/microservices.ts.tpl +11 -97
- package/src/templates/project/basic/config/middleware.ts.tpl +25 -43
- package/src/templates/project/basic/config/notification.ts.tpl +13 -114
- package/src/templates/project/basic/config/queue.ts.tpl +9 -40
- package/src/templates/project/basic/config/security.ts.tpl +11 -163
- package/src/templates/project/basic/config/startup.ts.tpl +10 -21
- package/src/templates/project/basic/config/storage.ts.tpl +57 -137
- package/src/templates/project/basic/config/type.ts.tpl +32 -451
- package/src/templates/project/basic/database/factories/UserFactory.ts.tpl +80 -0
- package/src/templates/project/basic/database/migrations/create_tasks_table.ts.tpl +28 -0
- package/src/templates/project/basic/database/migrations/create_users_table.ts.tpl +29 -0
- package/src/templates/project/basic/database/seeders/DatabaseSeeder.ts.tpl +19 -0
- package/src/templates/project/basic/database/seeders/UserSeeder.ts.tpl +18 -0
- package/src/templates/project/basic/database/seeders/index.ts.tpl +2 -0
- package/src/templates/project/basic/routes/api.ts.tpl +71 -33
- package/src/templates/project/basic/routes/metrics.ts.tpl +22 -0
- package/src/templates/project/basic/src/index.ts.tpl +3 -0
- package/src/templates/project/basic/tsconfig.json.tpl +12 -11
- package/src/testing/TestEnvironment.d.ts +40 -0
- package/src/testing/TestEnvironment.d.ts.map +1 -0
- package/src/testing/TestEnvironment.js +141 -0
- package/src/testing/TestHttp.d.ts +29 -0
- package/src/testing/TestHttp.d.ts.map +1 -0
- package/src/testing/TestHttp.js +96 -0
- package/src/testing/index.d.ts +5 -0
- package/src/testing/index.d.ts.map +1 -0
- package/src/testing/index.js +2 -0
- package/src/time/DateTime.d.ts +181 -0
- package/src/time/DateTime.d.ts.map +1 -0
- package/src/time/DateTime.js +300 -0
- package/src/time/index.d.ts +7 -0
- package/src/time/index.d.ts.map +1 -0
- package/src/time/index.js +5 -0
- package/src/tools/http/Http.d.ts.map +1 -1
- package/src/tools/http/Http.js +4 -0
- package/src/tools/mail/drivers/Smtp.js +1 -1
- package/src/tools/queue/drivers/InMemory.d.ts +1 -1
- package/src/tools/queue/drivers/InMemory.d.ts.map +1 -1
- package/src/tools/queue/drivers/InMemory.js +1 -1
- package/src/tools/queue/drivers/Redis.d.ts +1 -1
- package/src/tools/queue/drivers/Redis.d.ts.map +1 -1
- package/src/tools/queue/drivers/Redis.js +1 -1
- package/src/validation/ValidationError.d.ts.map +1 -1
- package/src/validation/ValidationError.js +4 -2
- package/src/validation/Validator.d.ts +49 -16
- package/src/validation/Validator.d.ts.map +1 -1
- package/src/validation/Validator.js +307 -5
- package/src/common/uuid.d.ts +0 -3
- package/src/common/uuid.d.ts.map +0 -1
- package/src/common/uuid.js +0 -30
- package/src/templates/project/basic/.env.example.tpl +0 -74
- package/src/templates/project/basic/.env.tpl +0 -166
- package/src/templates/project/basic/config/logging/KvLogger.ts.tpl +0 -181
- package/src/templates/project/basic/config/logging/SlackLogger.ts.tpl +0 -156
- package/src/templates/project/basic/database/migrations/index.ts.tpl +0 -2
|
@@ -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 {};
|
|
@@ -3,101 +3,125 @@
|
|
|
3
3
|
* MySQL Database Adapter
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
type DatabaseConfig,
|
|
12
|
-
type IDatabaseAdapter,
|
|
13
|
-
type QueryResult,
|
|
14
|
-
} from '@zintrust/core';
|
|
6
|
+
import { FeatureFlags } from '@zintrust/core';
|
|
7
|
+
import { Logger } from '@zintrust/core';
|
|
8
|
+
import { ErrorFactory } from '@zintrust/core';
|
|
9
|
+
import { DatabaseConfig, IDatabaseAdapter, QueryResult } from '@zintrust/core';
|
|
10
|
+
import { QueryBuilder } from '@zintrust/core';
|
|
15
11
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
12
|
+
type AdapterState = {
|
|
13
|
+
connected: boolean;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
function createRawQuery(state: AdapterState) {
|
|
17
|
+
return async function rawQuery<T = unknown>(sql: string, parameters?: unknown[]): Promise<T[]> {
|
|
18
|
+
if (!FeatureFlags.isRawQueryEnabled()) {
|
|
19
|
+
throw ErrorFactory.createConfigError('Raw SQL queries are disabled');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (!state.connected) {
|
|
23
|
+
throw ErrorFactory.createConnectionError('Database not connected');
|
|
24
|
+
}
|
|
26
25
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
26
|
+
try {
|
|
27
|
+
Logger.warn(`Raw SQL Query executed: ${sql}`, { parameters });
|
|
28
|
+
// Mock implementation for tests
|
|
29
|
+
if (sql.includes('INVALID')) {
|
|
30
|
+
throw ErrorFactory.createDatabaseError('Invalid SQL syntax');
|
|
31
|
+
}
|
|
32
|
+
return [] as T[];
|
|
33
|
+
} catch (error) {
|
|
34
|
+
throw ErrorFactory.createTryCatchError(`Raw SQL query failed: ${sql}`, error);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
}
|
|
37
38
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
function createMySQLAdapterInstance(config: DatabaseConfig, state: AdapterState): IDatabaseAdapter {
|
|
40
|
+
return {
|
|
41
|
+
async connect(): Promise<void> {
|
|
42
|
+
if (config.host === 'error') {
|
|
43
|
+
throw ErrorFactory.createConnectionError(
|
|
44
|
+
'Failed to connect to MySQL: Error: Connection failed'
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
state.connected = true;
|
|
48
|
+
Logger.info(`✓ MySQL connected (${config.host}:${config.port})`);
|
|
49
|
+
},
|
|
42
50
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
},
|
|
51
|
+
async disconnect(): Promise<void> {
|
|
52
|
+
state.connected = false;
|
|
53
|
+
Logger.info('✓ MySQL disconnected');
|
|
54
|
+
},
|
|
48
55
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
56
|
+
async query(_sql: string, _parameters: unknown[]): Promise<QueryResult> {
|
|
57
|
+
if (!state.connected) throw ErrorFactory.createConnectionError('Database not connected');
|
|
58
|
+
// Mock implementation
|
|
59
|
+
return { rows: [], rowCount: 0 };
|
|
60
|
+
},
|
|
53
61
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
62
|
+
async queryOne(sql: string, parameters: unknown[]): Promise<Record<string, unknown> | null> {
|
|
63
|
+
const result = await this.query(sql, parameters);
|
|
64
|
+
return result.rows[0] ?? null;
|
|
65
|
+
},
|
|
57
66
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
await this.query('START TRANSACTION', []);
|
|
62
|
-
const result = await callback(this);
|
|
63
|
-
await this.query('COMMIT', []);
|
|
64
|
-
return result;
|
|
65
|
-
} catch (error) {
|
|
66
|
-
await this.query('ROLLBACK', []);
|
|
67
|
-
throw ErrorFactory.createTryCatchError('MySQL transaction failed', error);
|
|
68
|
-
}
|
|
69
|
-
},
|
|
67
|
+
async ping(): Promise<void> {
|
|
68
|
+
await this.query(QueryBuilder.create('').select('1').toSQL(), []);
|
|
69
|
+
},
|
|
70
70
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
71
|
+
async transaction<T>(callback: (adapter: IDatabaseAdapter) => Promise<T>): Promise<T> {
|
|
72
|
+
if (!state.connected) throw ErrorFactory.createConnectionError('Database not connected');
|
|
73
|
+
try {
|
|
74
|
+
await this.query('START TRANSACTION', []);
|
|
75
|
+
const result = await callback(this);
|
|
76
|
+
await this.query('COMMIT', []);
|
|
77
|
+
return result;
|
|
78
|
+
} catch (error) {
|
|
79
|
+
await this.query('ROLLBACK', []);
|
|
80
|
+
throw ErrorFactory.createTryCatchError('MySQL transaction failed', error);
|
|
81
|
+
}
|
|
82
|
+
},
|
|
81
83
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
84
|
+
getType(): string {
|
|
85
|
+
return 'mysql';
|
|
86
|
+
},
|
|
87
|
+
isConnected(): boolean {
|
|
88
|
+
return state.connected;
|
|
89
|
+
},
|
|
90
|
+
rawQuery: createRawQuery(state),
|
|
91
|
+
getPlaceholder(_index: number): string {
|
|
92
|
+
return '?';
|
|
93
|
+
},
|
|
85
94
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
95
|
+
async ensureMigrationsTable(): Promise<void> {
|
|
96
|
+
await this.query(
|
|
97
|
+
`CREATE TABLE IF NOT EXISTS migrations (
|
|
98
|
+
id INTEGER PRIMARY KEY AUTO_INCREMENT,
|
|
99
|
+
name VARCHAR(255) NOT NULL,
|
|
100
|
+
scope VARCHAR(255) NOT NULL DEFAULT 'global',
|
|
101
|
+
service VARCHAR(255) NOT NULL DEFAULT '',
|
|
102
|
+
batch INTEGER NOT NULL,
|
|
103
|
+
status VARCHAR(255) NOT NULL,
|
|
104
|
+
applied_at DATETIME NULL,
|
|
105
|
+
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
106
|
+
UNIQUE(name, scope, service)
|
|
107
|
+
)`,
|
|
108
|
+
[]
|
|
109
|
+
);
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* MySQL adapter implementation
|
|
116
|
+
* Sealed namespace for immutability
|
|
117
|
+
*/
|
|
118
|
+
export const MySQLAdapter = Object.freeze({
|
|
119
|
+
/**
|
|
120
|
+
* Create a new MySQL adapter instance
|
|
121
|
+
*/
|
|
122
|
+
create(config: DatabaseConfig): IDatabaseAdapter {
|
|
123
|
+
const state: AdapterState = { connected: false };
|
|
124
|
+
return createMySQLAdapterInstance(config, state);
|
|
101
125
|
},
|
|
102
126
|
});
|
|
103
127
|
|
|
@@ -3,15 +3,133 @@
|
|
|
3
3
|
* PostgreSQL Database Adapter
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
6
|
+
import { FeatureFlags } from '@zintrust/core';
|
|
7
|
+
import { Logger } from '@zintrust/core';
|
|
8
|
+
import { ErrorFactory } from '@zintrust/core';
|
|
9
|
+
import { DatabaseConfig, IDatabaseAdapter, QueryResult } from '@zintrust/core';
|
|
10
|
+
import { QueryBuilder } from '@zintrust/core';
|
|
11
|
+
|
|
12
|
+
type AdapterState = {
|
|
13
|
+
connected: boolean;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
function assertConnected(state: AdapterState): void {
|
|
17
|
+
if (!state.connected) throw ErrorFactory.createConnectionError('Database not connected');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async function pgConnect(config: DatabaseConfig, state: AdapterState): Promise<void> {
|
|
21
|
+
if (config.host === 'error') {
|
|
22
|
+
throw ErrorFactory.createConnectionError('Failed to connect to PostgreSQL: Connection failed');
|
|
23
|
+
}
|
|
24
|
+
state.connected = true;
|
|
25
|
+
Logger.info(`✓ PostgreSQL connected (${config.host}:${config.port})`);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async function pgDisconnect(state: AdapterState): Promise<void> {
|
|
29
|
+
state.connected = false;
|
|
30
|
+
Logger.info('✓ PostgreSQL disconnected');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async function pgQuery(
|
|
34
|
+
state: AdapterState,
|
|
35
|
+
_sql: string,
|
|
36
|
+
_parameters: unknown[]
|
|
37
|
+
): Promise<QueryResult> {
|
|
38
|
+
assertConnected(state);
|
|
39
|
+
// Mock implementation
|
|
40
|
+
return { rows: [], rowCount: 0 };
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async function pgQueryOne(
|
|
44
|
+
adapter: IDatabaseAdapter,
|
|
45
|
+
sql: string,
|
|
46
|
+
parameters: unknown[]
|
|
47
|
+
): Promise<Record<string, unknown> | null> {
|
|
48
|
+
const result = await adapter.query(sql, parameters);
|
|
49
|
+
return result.rows[0] ?? null;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async function pgPing(adapter: IDatabaseAdapter): Promise<void> {
|
|
53
|
+
await adapter.query(QueryBuilder.create('').select('1').toSQL(), []);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async function pgTransaction<T>(
|
|
57
|
+
state: AdapterState,
|
|
58
|
+
adapter: IDatabaseAdapter,
|
|
59
|
+
callback: (adapter: IDatabaseAdapter) => Promise<T>
|
|
60
|
+
): Promise<T> {
|
|
61
|
+
assertConnected(state);
|
|
62
|
+
try {
|
|
63
|
+
await adapter.query('BEGIN', []);
|
|
64
|
+
const result = await callback(adapter);
|
|
65
|
+
await adapter.query('COMMIT', []);
|
|
66
|
+
return result;
|
|
67
|
+
} catch (error) {
|
|
68
|
+
await adapter.query('ROLLBACK', []);
|
|
69
|
+
throw ErrorFactory.createTryCatchError('PostgreSQL transaction failed', error);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async function pgRawQuery<T = unknown>(
|
|
74
|
+
state: AdapterState,
|
|
75
|
+
sql: string,
|
|
76
|
+
parameters?: unknown[]
|
|
77
|
+
): Promise<T[]> {
|
|
78
|
+
if (!FeatureFlags.isRawQueryEnabled()) {
|
|
79
|
+
throw ErrorFactory.createConfigError(
|
|
80
|
+
'Raw SQL queries are disabled. Set USE_RAW_QRY=true environment variable to enable.'
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
assertConnected(state);
|
|
85
|
+
|
|
86
|
+
Logger.warn(`Raw SQL Query executed: ${sql}`, { parameters });
|
|
87
|
+
|
|
88
|
+
try {
|
|
89
|
+
if (sql.toUpperCase().includes('INVALID')) {
|
|
90
|
+
throw ErrorFactory.createDatabaseError('Invalid SQL syntax');
|
|
91
|
+
}
|
|
92
|
+
// Mock implementation
|
|
93
|
+
return [] as T[];
|
|
94
|
+
} catch (error) {
|
|
95
|
+
throw ErrorFactory.createTryCatchError('Raw SQL Query failed', error);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
async function pgEnsureMigrationsTable(adapter: IDatabaseAdapter): Promise<void> {
|
|
100
|
+
await adapter.query(
|
|
101
|
+
`CREATE TABLE IF NOT EXISTS migrations (
|
|
102
|
+
id SERIAL PRIMARY KEY,
|
|
103
|
+
name VARCHAR(255) NOT NULL,
|
|
104
|
+
scope VARCHAR(255) NOT NULL DEFAULT 'global',
|
|
105
|
+
service VARCHAR(255) NOT NULL DEFAULT '',
|
|
106
|
+
batch INTEGER NOT NULL,
|
|
107
|
+
status VARCHAR(255) NOT NULL,
|
|
108
|
+
applied_at TIMESTAMP NULL,
|
|
109
|
+
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
110
|
+
UNIQUE(name, scope, service)
|
|
111
|
+
)`,
|
|
112
|
+
[]
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function createAdapter(config: DatabaseConfig, state: AdapterState): IDatabaseAdapter {
|
|
117
|
+
const adapter: IDatabaseAdapter = {
|
|
118
|
+
connect: async () => pgConnect(config, state),
|
|
119
|
+
disconnect: async () => pgDisconnect(state),
|
|
120
|
+
query: async (sql, parameters) => pgQuery(state, sql, parameters),
|
|
121
|
+
queryOne: async (sql, parameters) => pgQueryOne(adapter, sql, parameters),
|
|
122
|
+
ping: async () => pgPing(adapter),
|
|
123
|
+
transaction: async (callback) => pgTransaction(state, adapter, callback),
|
|
124
|
+
getType: () => 'postgresql',
|
|
125
|
+
isConnected: () => state.connected,
|
|
126
|
+
rawQuery: async (sql, parameters) => pgRawQuery(state, sql, parameters),
|
|
127
|
+
getPlaceholder: (index) => `$${index}`,
|
|
128
|
+
ensureMigrationsTable: async () => pgEnsureMigrationsTable(adapter),
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
return adapter;
|
|
132
|
+
}
|
|
15
133
|
|
|
16
134
|
/**
|
|
17
135
|
* PostgreSQL adapter implementation
|
|
@@ -22,85 +140,8 @@ export const PostgreSQLAdapter = Object.freeze({
|
|
|
22
140
|
* Create a new PostgreSQL adapter instance
|
|
23
141
|
*/
|
|
24
142
|
create(config: DatabaseConfig): IDatabaseAdapter {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
return {
|
|
28
|
-
async connect(): Promise<void> {
|
|
29
|
-
if (config.host === 'error') {
|
|
30
|
-
throw ErrorFactory.createConnectionError(
|
|
31
|
-
'Failed to connect to PostgreSQL: Connection failed'
|
|
32
|
-
);
|
|
33
|
-
}
|
|
34
|
-
connected = true;
|
|
35
|
-
Logger.info(`✓ PostgreSQL connected (${config.host}:${config.port})`);
|
|
36
|
-
},
|
|
37
|
-
|
|
38
|
-
async disconnect(): Promise<void> {
|
|
39
|
-
connected = false;
|
|
40
|
-
Logger.info('✓ PostgreSQL disconnected');
|
|
41
|
-
},
|
|
42
|
-
|
|
43
|
-
async query(_sql: string, _parameters: unknown[]): Promise<QueryResult> {
|
|
44
|
-
if (!connected) throw ErrorFactory.createConnectionError('Database not connected');
|
|
45
|
-
// Mock implementation
|
|
46
|
-
return { rows: [], rowCount: 0 };
|
|
47
|
-
},
|
|
48
|
-
|
|
49
|
-
async queryOne(sql: string, parameters: unknown[]): Promise<Record<string, unknown> | null> {
|
|
50
|
-
const result = await this.query(sql, parameters);
|
|
51
|
-
return result.rows[0] ?? null;
|
|
52
|
-
},
|
|
53
|
-
|
|
54
|
-
async ping(): Promise<void> {
|
|
55
|
-
await this.query(QueryBuilder.create('').select('1').toSQL(), []);
|
|
56
|
-
},
|
|
57
|
-
|
|
58
|
-
async transaction<T>(callback: (adapter: IDatabaseAdapter) => Promise<T>): Promise<T> {
|
|
59
|
-
if (!connected) throw ErrorFactory.createConnectionError('Database not connected');
|
|
60
|
-
try {
|
|
61
|
-
await this.query('BEGIN', []);
|
|
62
|
-
const result = await callback(this);
|
|
63
|
-
await this.query('COMMIT', []);
|
|
64
|
-
return result;
|
|
65
|
-
} catch (error) {
|
|
66
|
-
await this.query('ROLLBACK', []);
|
|
67
|
-
throw ErrorFactory.createTryCatchError('PostgreSQL transaction failed', error);
|
|
68
|
-
}
|
|
69
|
-
},
|
|
70
|
-
|
|
71
|
-
getType(): string {
|
|
72
|
-
return 'postgresql';
|
|
73
|
-
},
|
|
74
|
-
isConnected(): boolean {
|
|
75
|
-
return connected;
|
|
76
|
-
},
|
|
77
|
-
async rawQuery<T = unknown>(sql: string, parameters?: unknown[]): Promise<T[]> {
|
|
78
|
-
if (!FeatureFlags.isRawQueryEnabled()) {
|
|
79
|
-
throw ErrorFactory.createConfigError(
|
|
80
|
-
'Raw SQL queries are disabled. Set USE_RAW_QRY=true environment variable to enable.'
|
|
81
|
-
);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
if (!connected) {
|
|
85
|
-
throw ErrorFactory.createConnectionError('Database not connected');
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
Logger.warn(`Raw SQL Query executed: ${sql}`, { parameters });
|
|
89
|
-
|
|
90
|
-
try {
|
|
91
|
-
if (sql.toUpperCase().includes('INVALID')) {
|
|
92
|
-
throw ErrorFactory.createDatabaseError('Invalid SQL syntax');
|
|
93
|
-
}
|
|
94
|
-
// Mock implementation
|
|
95
|
-
return [] as T[];
|
|
96
|
-
} catch (error) {
|
|
97
|
-
throw ErrorFactory.createTryCatchError('Raw SQL Query failed', error);
|
|
98
|
-
}
|
|
99
|
-
},
|
|
100
|
-
getPlaceholder(index: number): string {
|
|
101
|
-
return `$${index}`;
|
|
102
|
-
},
|
|
103
|
-
};
|
|
143
|
+
const state: AdapterState = { connected: false };
|
|
144
|
+
return createAdapter(config, state);
|
|
104
145
|
},
|
|
105
146
|
});
|
|
106
147
|
|
|
@@ -3,15 +3,11 @@
|
|
|
3
3
|
* SQL Server Database Adapter
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
type DatabaseConfig,
|
|
12
|
-
type IDatabaseAdapter,
|
|
13
|
-
type QueryResult,
|
|
14
|
-
} from '@zintrust/core';
|
|
6
|
+
import { FeatureFlags } from '@zintrust/core';
|
|
7
|
+
import { Logger } from '@zintrust/core';
|
|
8
|
+
import { ErrorFactory } from '@zintrust/core';
|
|
9
|
+
import { DatabaseConfig, IDatabaseAdapter, QueryResult } from '@zintrust/core';
|
|
10
|
+
import { QueryBuilder } from '@zintrust/core';
|
|
15
11
|
|
|
16
12
|
/**
|
|
17
13
|
* SQL Server adapter implementation
|
|
@@ -4,17 +4,14 @@
|
|
|
4
4
|
* Production Implementation
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import { FeatureFlags } from '@zintrust/core';
|
|
8
|
+
import { Logger } from '@zintrust/core';
|
|
9
|
+
import { ErrorFactory } from '@zintrust/core';
|
|
10
|
+
import fs from 'node:fs';
|
|
11
|
+
import * as path from 'node:path';
|
|
7
12
|
import { performance } from 'node:perf_hooks';
|
|
8
|
-
|
|
9
|
-
import {
|
|
10
|
-
ErrorFactory,
|
|
11
|
-
FeatureFlags,
|
|
12
|
-
Logger,
|
|
13
|
-
QueryBuilder,
|
|
14
|
-
type DatabaseConfig,
|
|
15
|
-
type IDatabaseAdapter,
|
|
16
|
-
type QueryResult,
|
|
17
|
-
} from '@zintrust/core';
|
|
13
|
+
import { DatabaseConfig, IDatabaseAdapter, QueryResult } from '@zintrust/core';
|
|
14
|
+
import { QueryBuilder } from '@zintrust/core';
|
|
18
15
|
|
|
19
16
|
type SqliteRunInfo = { changes: number };
|
|
20
17
|
type SqliteStatement = {
|
|
@@ -27,6 +24,22 @@ type SqliteDatabase = {
|
|
|
27
24
|
close: () => void;
|
|
28
25
|
};
|
|
29
26
|
|
|
27
|
+
type SqliteIdentifier = string & { readonly __sqliteIdentifier: unique symbol };
|
|
28
|
+
|
|
29
|
+
const SAFE_SQLITE_IDENTIFIER = /^[A-Za-z_]\w*$/;
|
|
30
|
+
|
|
31
|
+
const toSqliteIdentifier = (value: string): SqliteIdentifier => {
|
|
32
|
+
if (!SAFE_SQLITE_IDENTIFIER.test(value)) {
|
|
33
|
+
throw ErrorFactory.createDatabaseError('Unsafe sqlite identifier');
|
|
34
|
+
}
|
|
35
|
+
return value as SqliteIdentifier;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const quoteSqliteIdentifier = (id: SqliteIdentifier): string => {
|
|
39
|
+
// Safe due to SAFE_SQLITE_IDENTIFIER allowlist.
|
|
40
|
+
return `"${id}"`;
|
|
41
|
+
};
|
|
42
|
+
|
|
30
43
|
function isMissingEsmPackage(error: unknown, packageName: string): boolean {
|
|
31
44
|
if (typeof error !== 'object' || error === null) return false;
|
|
32
45
|
const maybe = error as { code?: unknown; message?: unknown };
|
|
@@ -43,7 +56,11 @@ async function importSqliteDatabaseConstructor(): Promise<
|
|
|
43
56
|
new (filename: string) => SqliteDatabase
|
|
44
57
|
> {
|
|
45
58
|
try {
|
|
46
|
-
|
|
59
|
+
// Avoid a literal dynamic import so bundlers (e.g. Wrangler/esbuild) don't
|
|
60
|
+
// try to bundle the native sqlite driver into non-Node targets.
|
|
61
|
+
const pkg = (globalThis as unknown as { __zintrustSqliteDriver?: string })
|
|
62
|
+
.__zintrustSqliteDriver;
|
|
63
|
+
const mod = (await import(pkg ?? 'better-sqlite3')) as unknown as {
|
|
47
64
|
default?: new (filename: string) => SqliteDatabase;
|
|
48
65
|
};
|
|
49
66
|
|
|
@@ -113,6 +130,18 @@ async function connectSQLite(state: SQLiteAdapterState): Promise<void> {
|
|
|
113
130
|
|
|
114
131
|
const filename = normalizeFilename(state.config.database);
|
|
115
132
|
|
|
133
|
+
// Ensure file-backed sqlite DB directories exist (e.g. .zintrust/dbs/*.sqlite).
|
|
134
|
+
if (filename !== ':memory:') {
|
|
135
|
+
try {
|
|
136
|
+
fs.mkdirSync(path.dirname(filename), { recursive: true });
|
|
137
|
+
} catch (error) {
|
|
138
|
+
throw ErrorFactory.createTryCatchError('Failed to create SQLite database directory', {
|
|
139
|
+
filename,
|
|
140
|
+
cause: error,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
116
145
|
const SqliteDatabaseCtor = await importSqliteDatabaseConstructor();
|
|
117
146
|
state.db = new SqliteDatabaseCtor(filename);
|
|
118
147
|
|
|
@@ -220,6 +249,44 @@ function createSQLiteAdapter(config: DatabaseConfig): IDatabaseAdapter {
|
|
|
220
249
|
return rawQuerySQLite<T>(state, sql, parameters);
|
|
221
250
|
},
|
|
222
251
|
|
|
252
|
+
async ensureMigrationsTable(): Promise<void> {
|
|
253
|
+
await adapter.query(
|
|
254
|
+
`CREATE TABLE IF NOT EXISTS migrations (
|
|
255
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
256
|
+
name TEXT NOT NULL,
|
|
257
|
+
scope TEXT NOT NULL DEFAULT 'global',
|
|
258
|
+
service TEXT NOT NULL DEFAULT '',
|
|
259
|
+
batch INTEGER NOT NULL,
|
|
260
|
+
status TEXT NOT NULL,
|
|
261
|
+
applied_at TEXT NULL,
|
|
262
|
+
created_at TEXT NOT NULL,
|
|
263
|
+
UNIQUE(name, scope, service)
|
|
264
|
+
)`,
|
|
265
|
+
[]
|
|
266
|
+
);
|
|
267
|
+
},
|
|
268
|
+
|
|
269
|
+
async resetSchema(): Promise<void> {
|
|
270
|
+
// Best-effort for SQLite.
|
|
271
|
+
await adapter.query('PRAGMA foreign_keys = OFF', []);
|
|
272
|
+
|
|
273
|
+
const tables = (await adapter.query(
|
|
274
|
+
"SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'",
|
|
275
|
+
[]
|
|
276
|
+
)) as unknown as { rows: Array<{ name?: unknown }> };
|
|
277
|
+
|
|
278
|
+
await Promise.all(
|
|
279
|
+
tables.rows.map(async (t) => {
|
|
280
|
+
const name = typeof t.name === 'string' ? t.name : '';
|
|
281
|
+
if (name.length === 0) return;
|
|
282
|
+
const tableName = toSqliteIdentifier(name);
|
|
283
|
+
await adapter.query(`DROP TABLE IF EXISTS ${quoteSqliteIdentifier(tableName)}`, []);
|
|
284
|
+
})
|
|
285
|
+
);
|
|
286
|
+
|
|
287
|
+
await adapter.query('PRAGMA foreign_keys = ON', []);
|
|
288
|
+
},
|
|
289
|
+
|
|
223
290
|
getType(): string {
|
|
224
291
|
return 'sqlite';
|
|
225
292
|
},
|