@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,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* N+1 Query Pattern Detector
|
|
3
|
+
* Analyzes query logs to identify N+1 patterns
|
|
4
|
+
*/
|
|
5
|
+
/**\n * N1Detector analyzes query logs to identify N+1 patterns
|
|
6
|
+
* Groups identical queries and flags those executed 5+ times as critical
|
|
7
|
+
* Sealed namespace for immutability
|
|
8
|
+
*/
|
|
9
|
+
export const N1Detector = Object.freeze({
|
|
10
|
+
/**
|
|
11
|
+
* Create a new N1Detector instance
|
|
12
|
+
*/
|
|
13
|
+
create() {
|
|
14
|
+
return {
|
|
15
|
+
/**
|
|
16
|
+
* Extract table name from SQL query
|
|
17
|
+
* Handles SELECT, INSERT, UPDATE, DELETE statements
|
|
18
|
+
*/
|
|
19
|
+
extractTableFromSQL(sql) {
|
|
20
|
+
return extractTableFromSQL(sql);
|
|
21
|
+
},
|
|
22
|
+
/**
|
|
23
|
+
* Detect N+1 patterns in query log
|
|
24
|
+
* Groups identical queries and returns those executed 5+ times as patterns
|
|
25
|
+
*/
|
|
26
|
+
detect(queryLog) {
|
|
27
|
+
return detectN1Patterns(queryLog);
|
|
28
|
+
},
|
|
29
|
+
/**
|
|
30
|
+
* Get severity level based on repetition count
|
|
31
|
+
*/
|
|
32
|
+
getSeverity(count) {
|
|
33
|
+
return getSeverity(count);
|
|
34
|
+
},
|
|
35
|
+
/**
|
|
36
|
+
* Generate human-readable summary of N+1 patterns
|
|
37
|
+
*/
|
|
38
|
+
generateSummary(patterns) {
|
|
39
|
+
return generateSummary(patterns);
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
/**
|
|
45
|
+
* Extract table name from SQL query
|
|
46
|
+
*/
|
|
47
|
+
function extractTableFromSQL(sql) {
|
|
48
|
+
// Remove excess whitespace and normalize
|
|
49
|
+
const normalized = sql.trim().replaceAll(/\s+/g, ' ');
|
|
50
|
+
// INSERT INTO table
|
|
51
|
+
let match = new RegExp(/INSERT\s+INTO\s+`?(\w+)`?/i).exec(normalized);
|
|
52
|
+
if (match)
|
|
53
|
+
return match[1];
|
|
54
|
+
// UPDATE table
|
|
55
|
+
match = new RegExp(/UPDATE\s+`?(\w+)`?/i).exec(normalized);
|
|
56
|
+
if (match)
|
|
57
|
+
return match[1];
|
|
58
|
+
// DELETE FROM table
|
|
59
|
+
match = new RegExp(/DELETE\s+FROM\s+`?(\w+)`?/i).exec(normalized);
|
|
60
|
+
if (match)
|
|
61
|
+
return match[1];
|
|
62
|
+
// SELECT ... FROM table
|
|
63
|
+
match = new RegExp(/FROM\s+`?(\w+)`?/i).exec(normalized);
|
|
64
|
+
if (match)
|
|
65
|
+
return match[1];
|
|
66
|
+
return 'unknown';
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Detect N+1 patterns in query log
|
|
70
|
+
*/
|
|
71
|
+
function detectN1Patterns(queryLog) {
|
|
72
|
+
if (queryLog.length === 0) {
|
|
73
|
+
return [];
|
|
74
|
+
}
|
|
75
|
+
// Group queries by SQL
|
|
76
|
+
const queryGroups = new Map();
|
|
77
|
+
for (const entry of queryLog) {
|
|
78
|
+
if (!queryGroups.has(entry.sql)) {
|
|
79
|
+
queryGroups.set(entry.sql, []);
|
|
80
|
+
}
|
|
81
|
+
queryGroups.get(entry.sql)?.push(entry);
|
|
82
|
+
}
|
|
83
|
+
// Find patterns with 5+ executions
|
|
84
|
+
const patterns = [];
|
|
85
|
+
for (const [sql, entries] of queryGroups) {
|
|
86
|
+
const count = entries.length;
|
|
87
|
+
if (count >= 5) {
|
|
88
|
+
const severity = getSeverity(count);
|
|
89
|
+
const table = extractTableFromSQL(sql);
|
|
90
|
+
patterns.push({
|
|
91
|
+
table,
|
|
92
|
+
queryCount: count,
|
|
93
|
+
query: sql,
|
|
94
|
+
severity,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// Sort by query count descending
|
|
99
|
+
patterns.sort((a, b) => b.queryCount - a.queryCount);
|
|
100
|
+
return patterns;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Get severity level based on repetition count
|
|
104
|
+
*/
|
|
105
|
+
function getSeverity(count) {
|
|
106
|
+
return count >= 10 ? 'critical' : 'warning';
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Generate human-readable summary of N+1 patterns
|
|
110
|
+
*/
|
|
111
|
+
function generateSummary(patterns) {
|
|
112
|
+
if (patterns.length === 0) {
|
|
113
|
+
return 'No N+1 patterns detected';
|
|
114
|
+
}
|
|
115
|
+
const lines = ['N+1 Query Patterns Detected:'];
|
|
116
|
+
for (const pattern of patterns) {
|
|
117
|
+
lines.push(` [${pattern.severity.toUpperCase()}] Table "${pattern.table}": ${pattern.queryCount} identical queries`);
|
|
118
|
+
}
|
|
119
|
+
return lines.join('\n');
|
|
120
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Query Logger
|
|
3
|
+
* Tracks database query execution with parameters, duration, and context
|
|
4
|
+
*/
|
|
5
|
+
import { QueryLogEntry } from './types';
|
|
6
|
+
/**
|
|
7
|
+
* QueryLogger tracks all database queries executed during a request context
|
|
8
|
+
* Provides N+1 detection heuristic by flagging identical queries executed 5+ times
|
|
9
|
+
*/
|
|
10
|
+
export type QueryLoggerInstance = IQueryLogger;
|
|
11
|
+
export interface IQueryLogger {
|
|
12
|
+
/**
|
|
13
|
+
* Set current request context ID
|
|
14
|
+
*/
|
|
15
|
+
setContext(context: string): void;
|
|
16
|
+
/**
|
|
17
|
+
* Get current request context ID
|
|
18
|
+
*/
|
|
19
|
+
getContext(): string;
|
|
20
|
+
/**
|
|
21
|
+
* Log a query execution
|
|
22
|
+
*/
|
|
23
|
+
logQuery(sql: string, params: unknown[], duration: number, context?: string): void;
|
|
24
|
+
/**
|
|
25
|
+
* Get query log for a context
|
|
26
|
+
*/
|
|
27
|
+
getQueryLog(context?: string): QueryLogEntry[];
|
|
28
|
+
/**
|
|
29
|
+
* Get query summary (grouped by SQL) for a context
|
|
30
|
+
*/
|
|
31
|
+
getQuerySummary(context?: string): Map<string, QueryLogEntry & {
|
|
32
|
+
executionCount: number;
|
|
33
|
+
}>;
|
|
34
|
+
/**
|
|
35
|
+
* Get N+1 suspects (queries executed 5+ times in same context)
|
|
36
|
+
*/
|
|
37
|
+
getN1Suspects(context?: string, threshold?: number): QueryLogEntry[];
|
|
38
|
+
/**
|
|
39
|
+
* Clear logs for a context
|
|
40
|
+
*/
|
|
41
|
+
clear(context?: string): void;
|
|
42
|
+
/**
|
|
43
|
+
* Get all logs
|
|
44
|
+
*/
|
|
45
|
+
getAllLogs(): Map<string, QueryLogEntry[]>;
|
|
46
|
+
/**
|
|
47
|
+
* Get total query count for a context
|
|
48
|
+
*/
|
|
49
|
+
getQueryCount(context?: string): number;
|
|
50
|
+
/**
|
|
51
|
+
* Get total duration for all queries in a context
|
|
52
|
+
*/
|
|
53
|
+
getTotalDuration(context?: string): number;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* QueryLogger tracks all database queries executed during a request context
|
|
57
|
+
* Provides N+1 detection heuristic by flagging identical queries executed 5+ times
|
|
58
|
+
* Sealed namespace for immutability
|
|
59
|
+
*/
|
|
60
|
+
export declare const QueryLogger: Readonly<{
|
|
61
|
+
logs: Map<string, QueryLogEntry[] | undefined>;
|
|
62
|
+
getInstance(): IQueryLogger;
|
|
63
|
+
/**
|
|
64
|
+
* Set current request context ID
|
|
65
|
+
*/
|
|
66
|
+
setContext(context: string): void;
|
|
67
|
+
/**
|
|
68
|
+
* Get current request context ID
|
|
69
|
+
*/
|
|
70
|
+
getContext(): string;
|
|
71
|
+
/**
|
|
72
|
+
* Log a query execution
|
|
73
|
+
*/
|
|
74
|
+
logQuery(sql: string, params: unknown[], duration: number, context?: string): void;
|
|
75
|
+
/**
|
|
76
|
+
* Get query log for a context
|
|
77
|
+
*/
|
|
78
|
+
getQueryLog(context?: string): QueryLogEntry[];
|
|
79
|
+
/**
|
|
80
|
+
* Get query summary (grouped by SQL) for a context
|
|
81
|
+
*/
|
|
82
|
+
getQuerySummary(context?: string): Map<string, QueryLogEntry & {
|
|
83
|
+
executionCount: number;
|
|
84
|
+
}>;
|
|
85
|
+
/**
|
|
86
|
+
* Get N+1 suspects (queries executed 5+ times in same context)
|
|
87
|
+
* Simple heuristic: identical queries executed many times suggests N+1
|
|
88
|
+
*/
|
|
89
|
+
getN1Suspects(context?: string, threshold?: number): QueryLogEntry[];
|
|
90
|
+
/**
|
|
91
|
+
* Clear logs for a context
|
|
92
|
+
*/
|
|
93
|
+
clear(context?: string): void;
|
|
94
|
+
/**
|
|
95
|
+
* Get all logs
|
|
96
|
+
*/
|
|
97
|
+
getAllLogs(): Map<string, QueryLogEntry[]>;
|
|
98
|
+
/**
|
|
99
|
+
* Get total query count for a context
|
|
100
|
+
*/
|
|
101
|
+
getQueryCount(context?: string): number;
|
|
102
|
+
/**
|
|
103
|
+
* Get total duration for all queries in a context
|
|
104
|
+
*/
|
|
105
|
+
getTotalDuration(context?: string): number;
|
|
106
|
+
}>;
|
|
107
|
+
//# sourceMappingURL=QueryLogger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QueryLogger.d.ts","sourceRoot":"","sources":["../../../src/profiling/QueryLogger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG,YAAY,CAAC;AAE/C,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAElC;;OAEG;IACH,UAAU,IAAI,MAAM,CAAC;IAErB;;OAEG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAEnF;;OAEG;IACH,WAAW,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,aAAa,EAAE,CAAC;IAE/C;;OAEG;IACH,eAAe,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,aAAa,GAAG;QAAE,cAAc,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAE3F;;OAEG;IACH,aAAa,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,aAAa,EAAE,CAAC;IAErE;;OAEG;IACH,KAAK,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE9B;;OAEG;IACH,UAAU,IAAI,GAAG,CAAC,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC;IAE3C;;OAEG;IACH,aAAa,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAExC;;OAEG;IACH,gBAAgB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC5C;AASD;;;;GAIG;AACH,eAAO,MAAM,WAAW;;mBAGP,YAAY;IAG3B;;OAEG;wBACiB,MAAM,GAAG,IAAI;IAcjC;;OAEG;kBACW,MAAM;IAIpB;;OAEG;kBAEI,MAAM,UACH,OAAO,EAAE,YACP,MAAM,YACP,MAAM,GACd,IAAI;IA+BP;;OAEG;0BACkB,MAAM,GAAoB,aAAa,EAAE;IAK9D;;OAEG;8BAEQ,MAAM,GACd,GAAG,CAAC,MAAM,EAAE,aAAa,GAAG;QAAE,cAAc,EAAE,MAAM,CAAA;KAAE,CAAC;IAiB1D;;;OAGG;4BACoB,MAAM,cAA8B,MAAM,GAAO,aAAa,EAAE;IAavF;;OAEG;oBACa,MAAM,GAAG,IAAI;IAS7B;;OAEG;kBACW,GAAG,CAAC,MAAM,EAAE,aAAa,EAAE,CAAC;IAU1C;;OAEG;4BACoB,MAAM,GAAoB,MAAM;IAIvD;;OAEG;+BACuB,MAAM,GAAoB,MAAM;EAI1D,CAAC"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Query Logger
|
|
3
|
+
* Tracks database query execution with parameters, duration, and context
|
|
4
|
+
*/
|
|
5
|
+
// Private state (exposed on QueryLogger for targeted unit-test coverage)
|
|
6
|
+
const logs = new Map();
|
|
7
|
+
let currentContext = 'default';
|
|
8
|
+
const MAX_CONTEXTS = 1000;
|
|
9
|
+
const MAX_QUERIES_PER_CONTEXT = 500;
|
|
10
|
+
/**
|
|
11
|
+
* QueryLogger tracks all database queries executed during a request context
|
|
12
|
+
* Provides N+1 detection heuristic by flagging identical queries executed 5+ times
|
|
13
|
+
* Sealed namespace for immutability
|
|
14
|
+
*/
|
|
15
|
+
export const QueryLogger = Object.freeze({
|
|
16
|
+
// Exposed for rare-branch tests that deliberately corrupt the map.
|
|
17
|
+
logs,
|
|
18
|
+
getInstance() {
|
|
19
|
+
return this;
|
|
20
|
+
},
|
|
21
|
+
/**
|
|
22
|
+
* Set current request context ID
|
|
23
|
+
*/
|
|
24
|
+
setContext(context) {
|
|
25
|
+
currentContext = context;
|
|
26
|
+
if (!logs.has(context)) {
|
|
27
|
+
// Prevent unbounded growth of contexts
|
|
28
|
+
if (logs.size >= MAX_CONTEXTS) {
|
|
29
|
+
const firstKey = logs.keys().next().value;
|
|
30
|
+
if (firstKey !== undefined) {
|
|
31
|
+
logs.delete(firstKey);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
logs.set(context, []);
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
/**
|
|
38
|
+
* Get current request context ID
|
|
39
|
+
*/
|
|
40
|
+
getContext() {
|
|
41
|
+
return currentContext;
|
|
42
|
+
},
|
|
43
|
+
/**
|
|
44
|
+
* Log a query execution
|
|
45
|
+
*/
|
|
46
|
+
logQuery(sql, params, duration, context = currentContext) {
|
|
47
|
+
if (!logs.has(context)) {
|
|
48
|
+
// Prevent unbounded growth of contexts
|
|
49
|
+
if (logs.size >= MAX_CONTEXTS) {
|
|
50
|
+
const firstKey = logs.keys().next().value;
|
|
51
|
+
if (firstKey !== undefined) {
|
|
52
|
+
logs.delete(firstKey);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
logs.set(context, []);
|
|
56
|
+
}
|
|
57
|
+
const entry = {
|
|
58
|
+
sql,
|
|
59
|
+
params,
|
|
60
|
+
duration,
|
|
61
|
+
timestamp: new Date(),
|
|
62
|
+
context,
|
|
63
|
+
};
|
|
64
|
+
const contextLogs = logs.get(context);
|
|
65
|
+
if (Array.isArray(contextLogs)) {
|
|
66
|
+
contextLogs.push(entry);
|
|
67
|
+
// Prevent unbounded growth of queries per context
|
|
68
|
+
if (contextLogs.length > MAX_QUERIES_PER_CONTEXT) {
|
|
69
|
+
contextLogs.shift();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
/**
|
|
74
|
+
* Get query log for a context
|
|
75
|
+
*/
|
|
76
|
+
getQueryLog(context = currentContext) {
|
|
77
|
+
const contextLogs = logs.get(context);
|
|
78
|
+
return Array.isArray(contextLogs) ? contextLogs : [];
|
|
79
|
+
},
|
|
80
|
+
/**
|
|
81
|
+
* Get query summary (grouped by SQL) for a context
|
|
82
|
+
*/
|
|
83
|
+
getQuerySummary(context = currentContext) {
|
|
84
|
+
const queryLogs = this.getQueryLog(context);
|
|
85
|
+
const summary = new Map();
|
|
86
|
+
for (const log of queryLogs) {
|
|
87
|
+
if (!summary.has(log.sql)) {
|
|
88
|
+
summary.set(log.sql, { ...log, executionCount: 0 });
|
|
89
|
+
}
|
|
90
|
+
const entry = summary.get(log.sql);
|
|
91
|
+
if (entry !== undefined) {
|
|
92
|
+
entry.executionCount++;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return summary;
|
|
96
|
+
},
|
|
97
|
+
/**
|
|
98
|
+
* Get N+1 suspects (queries executed 5+ times in same context)
|
|
99
|
+
* Simple heuristic: identical queries executed many times suggests N+1
|
|
100
|
+
*/
|
|
101
|
+
getN1Suspects(context = currentContext, threshold = 5) {
|
|
102
|
+
const summary = this.getQuerySummary(context);
|
|
103
|
+
const suspects = [];
|
|
104
|
+
for (const [, entry] of summary) {
|
|
105
|
+
if (entry.executionCount >= threshold) {
|
|
106
|
+
suspects.push(entry);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return suspects;
|
|
110
|
+
},
|
|
111
|
+
/**
|
|
112
|
+
* Clear logs for a context
|
|
113
|
+
*/
|
|
114
|
+
clear(context) {
|
|
115
|
+
if (context === undefined) {
|
|
116
|
+
logs.clear();
|
|
117
|
+
currentContext = 'default';
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
logs.delete(context);
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
/**
|
|
124
|
+
* Get all logs
|
|
125
|
+
*/
|
|
126
|
+
getAllLogs() {
|
|
127
|
+
const copy = new Map();
|
|
128
|
+
for (const [key, value] of logs.entries()) {
|
|
129
|
+
if (Array.isArray(value)) {
|
|
130
|
+
copy.set(key, value);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return copy;
|
|
134
|
+
},
|
|
135
|
+
/**
|
|
136
|
+
* Get total query count for a context
|
|
137
|
+
*/
|
|
138
|
+
getQueryCount(context = currentContext) {
|
|
139
|
+
return this.getQueryLog(context).length;
|
|
140
|
+
},
|
|
141
|
+
/**
|
|
142
|
+
* Get total duration for all queries in a context
|
|
143
|
+
*/
|
|
144
|
+
getTotalDuration(context = currentContext) {
|
|
145
|
+
const queryLogs = this.getQueryLog(context);
|
|
146
|
+
return queryLogs.reduce((total, log) => total + log.duration, 0);
|
|
147
|
+
},
|
|
148
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Request Profiler
|
|
3
|
+
* Comprehensive profiling of request execution combining query, N+1, and memory metrics
|
|
4
|
+
*/
|
|
5
|
+
import { IMemoryProfiler } from './MemoryProfiler';
|
|
6
|
+
import { IQueryLogger } from './QueryLogger';
|
|
7
|
+
import { IN1Detector, ProfileReport } from './types';
|
|
8
|
+
export interface IRequestProfiler {
|
|
9
|
+
getQueryLogger(): IQueryLogger;
|
|
10
|
+
getN1Detector(): IN1Detector;
|
|
11
|
+
getMemoryProfiler(): IMemoryProfiler;
|
|
12
|
+
captureRequest(fn: () => Promise<unknown>): Promise<ProfileReport>;
|
|
13
|
+
generateReport(profile: ProfileReport): string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* RequestProfiler orchestrates query logging, N+1 detection, and memory profiling
|
|
17
|
+
* Sealed namespace for immutability
|
|
18
|
+
*/
|
|
19
|
+
export declare const RequestProfiler: Readonly<{
|
|
20
|
+
/**
|
|
21
|
+
* Create a new request profiler instance
|
|
22
|
+
*/
|
|
23
|
+
create(): IRequestProfiler;
|
|
24
|
+
}>;
|
|
25
|
+
/**
|
|
26
|
+
* Re-export MemoryProfiler's static formatBytes for convenience
|
|
27
|
+
*/
|
|
28
|
+
export { MemoryProfiler } from './MemoryProfiler';
|
|
29
|
+
export default RequestProfiler;
|
|
30
|
+
//# sourceMappingURL=RequestProfiler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RequestProfiler.d.ts","sourceRoot":"","sources":["../../../src/profiling/RequestProfiler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,eAAe,EAAkB,MAAM,2BAA2B,CAAC;AAE5E,OAAO,EAAE,YAAY,EAAe,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,WAAW,EAAa,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEzE,MAAM,WAAW,gBAAgB;IAC/B,cAAc,IAAI,YAAY,CAAC;IAC/B,aAAa,IAAI,WAAW,CAAC;IAC7B,iBAAiB,IAAI,eAAe,CAAC;IACrC,cAAc,CAAC,EAAE,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IACnE,cAAc,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAAC;CAChD;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe;IAC1B;;OAEG;cACO,gBAAgB;EAkE1B,CAAC;AAmBH;;GAEG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAE3D,eAAe,eAAe,CAAC"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Request Profiler
|
|
3
|
+
* Comprehensive profiling of request execution combining query, N+1, and memory metrics
|
|
4
|
+
*/
|
|
5
|
+
import { MemoryProfiler } from './MemoryProfiler';
|
|
6
|
+
import { N1Detector } from './N1Detector';
|
|
7
|
+
import { QueryLogger } from './QueryLogger';
|
|
8
|
+
/**
|
|
9
|
+
* RequestProfiler orchestrates query logging, N+1 detection, and memory profiling
|
|
10
|
+
* Sealed namespace for immutability
|
|
11
|
+
*/
|
|
12
|
+
export const RequestProfiler = Object.freeze({
|
|
13
|
+
/**
|
|
14
|
+
* Create a new request profiler instance
|
|
15
|
+
*/
|
|
16
|
+
create() {
|
|
17
|
+
const queryLogger = QueryLogger.getInstance();
|
|
18
|
+
const n1Detector = N1Detector.create();
|
|
19
|
+
const memoryProfiler = MemoryProfiler.create();
|
|
20
|
+
let startTime = 0;
|
|
21
|
+
let endTime = 0;
|
|
22
|
+
return {
|
|
23
|
+
getQueryLogger() {
|
|
24
|
+
return queryLogger;
|
|
25
|
+
},
|
|
26
|
+
getN1Detector() {
|
|
27
|
+
return n1Detector;
|
|
28
|
+
},
|
|
29
|
+
getMemoryProfiler() {
|
|
30
|
+
return memoryProfiler;
|
|
31
|
+
},
|
|
32
|
+
async captureRequest(fn) {
|
|
33
|
+
// Start profiling
|
|
34
|
+
startTime = Date.now();
|
|
35
|
+
memoryProfiler.start();
|
|
36
|
+
queryLogger.setContext('profiling');
|
|
37
|
+
try {
|
|
38
|
+
// Execute the request
|
|
39
|
+
await fn();
|
|
40
|
+
}
|
|
41
|
+
finally {
|
|
42
|
+
// End profiling
|
|
43
|
+
endTime = Date.now();
|
|
44
|
+
memoryProfiler.end();
|
|
45
|
+
}
|
|
46
|
+
// Gather profiling data
|
|
47
|
+
const duration = endTime - startTime;
|
|
48
|
+
const queryLog = queryLogger.getQueryLog('profiling');
|
|
49
|
+
const queriesExecuted = queryLog.length;
|
|
50
|
+
const patterns = n1Detector.detect(queryLog);
|
|
51
|
+
const memoryDelta = memoryProfiler.delta();
|
|
52
|
+
return {
|
|
53
|
+
duration,
|
|
54
|
+
queriesExecuted,
|
|
55
|
+
n1Patterns: patterns,
|
|
56
|
+
memoryDelta,
|
|
57
|
+
timestamp: new Date(),
|
|
58
|
+
};
|
|
59
|
+
},
|
|
60
|
+
generateReport(profile) {
|
|
61
|
+
const n1Section = formatN1Section(profile.n1Patterns);
|
|
62
|
+
const lines = [
|
|
63
|
+
'=== Performance Profile Report ===',
|
|
64
|
+
`\nTiming: ${profile.duration}ms`,
|
|
65
|
+
`Queries: ${profile.queriesExecuted}`,
|
|
66
|
+
...n1Section,
|
|
67
|
+
'\nMemory Delta:',
|
|
68
|
+
` Heap Used: ${MemoryProfiler.formatBytes(profile.memoryDelta.heapUsed)}`,
|
|
69
|
+
` Heap Total: ${MemoryProfiler.formatBytes(profile.memoryDelta.heapTotal)}`,
|
|
70
|
+
` External: ${MemoryProfiler.formatBytes(profile.memoryDelta.external)}`,
|
|
71
|
+
` RSS: ${MemoryProfiler.formatBytes(profile.memoryDelta.rss)}`,
|
|
72
|
+
];
|
|
73
|
+
return lines.join('\n');
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
/**
|
|
79
|
+
* Format N+1 section for report
|
|
80
|
+
*/
|
|
81
|
+
function formatN1Section(patterns) {
|
|
82
|
+
if (patterns.length === 0) {
|
|
83
|
+
return ['\nN+1 Patterns: None detected'];
|
|
84
|
+
}
|
|
85
|
+
return [
|
|
86
|
+
'\nN+1 Patterns:',
|
|
87
|
+
...patterns.map((pattern) => ` [${pattern.severity.toUpperCase()}] "${pattern.table}": ${pattern.queryCount}x`),
|
|
88
|
+
];
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Re-export MemoryProfiler's static formatBytes for convenience
|
|
92
|
+
*/
|
|
93
|
+
export { MemoryProfiler } from './MemoryProfiler';
|
|
94
|
+
export default RequestProfiler;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Profiling Type Definitions
|
|
3
|
+
* Shared interfaces for query logging, N+1 detection, and memory profiling
|
|
4
|
+
*/
|
|
5
|
+
export declare const PROFILING_TYPES_MODULE: string;
|
|
6
|
+
/**
|
|
7
|
+
* Log entry for a single database query execution
|
|
8
|
+
*/
|
|
9
|
+
export interface QueryLogEntry {
|
|
10
|
+
sql: string;
|
|
11
|
+
params: unknown[];
|
|
12
|
+
duration: number;
|
|
13
|
+
timestamp: Date;
|
|
14
|
+
context: string;
|
|
15
|
+
executionCount?: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Detected N+1 query pattern
|
|
19
|
+
*/
|
|
20
|
+
export interface N1Pattern {
|
|
21
|
+
table: string;
|
|
22
|
+
queryCount: number;
|
|
23
|
+
query: string;
|
|
24
|
+
severity: 'warning' | 'critical';
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Memory snapshot at a point in time
|
|
28
|
+
*/
|
|
29
|
+
export interface MemorySnapshot {
|
|
30
|
+
heapUsed: number;
|
|
31
|
+
heapTotal: number;
|
|
32
|
+
external: number;
|
|
33
|
+
rss: number;
|
|
34
|
+
timestamp: Date;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Memory delta between two snapshots
|
|
38
|
+
*/
|
|
39
|
+
export interface MemoryDelta {
|
|
40
|
+
heapUsed: number;
|
|
41
|
+
heapTotal: number;
|
|
42
|
+
external: number;
|
|
43
|
+
rss: number;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* N1Detector analyzes query logs to identify N+1 patterns
|
|
47
|
+
* Groups identical queries and flags those executed 5+ times as critical
|
|
48
|
+
*/
|
|
49
|
+
export interface IN1Detector {
|
|
50
|
+
/**
|
|
51
|
+
* Extract table name from SQL query
|
|
52
|
+
*/
|
|
53
|
+
extractTableFromSQL(sql: string): string;
|
|
54
|
+
/**
|
|
55
|
+
* Detect N+1 patterns in query log
|
|
56
|
+
*/
|
|
57
|
+
detect(queryLog: QueryLogEntry[]): N1Pattern[];
|
|
58
|
+
/**
|
|
59
|
+
* Get severity level based on repetition count
|
|
60
|
+
*/
|
|
61
|
+
getSeverity(count: number): 'warning' | 'critical';
|
|
62
|
+
/**
|
|
63
|
+
* Generate human-readable summary of N+1 patterns
|
|
64
|
+
*/
|
|
65
|
+
generateSummary(patterns: N1Pattern[]): string;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Complete profile report for a request
|
|
69
|
+
*/
|
|
70
|
+
export interface ProfileReport {
|
|
71
|
+
duration: number;
|
|
72
|
+
queriesExecuted: number;
|
|
73
|
+
n1Patterns: N1Pattern[];
|
|
74
|
+
memoryDelta: MemoryDelta;
|
|
75
|
+
timestamp: Date;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/profiling/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,sBAAsB,QAAkC,CAAC;AAEtE;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,OAAO,EAAE,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,IAAI,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,SAAS,GAAG,UAAU,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,IAAI,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B;;OAEG;IACH,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;IAEzC;;OAEG;IACH,MAAM,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,SAAS,EAAE,CAAC;IAE/C;;OAEG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,CAAC;IAEnD;;OAEG;IACH,eAAe,CAAC,QAAQ,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC;CAChD;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,WAAW,EAAE,WAAW,CAAC;IACzB,SAAS,EAAE,IAAI,CAAC;CACjB"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { IRequest } from '../http/Request';
|
|
2
|
+
import { IResponse } from '../http/Response';
|
|
3
|
+
/**
|
|
4
|
+
* Router - HTTP Routing Engine
|
|
5
|
+
* Matches incoming requests to route handlers
|
|
6
|
+
*/
|
|
7
|
+
export type RouteHandler = (req: IRequest, res: IResponse) => Promise<void> | void;
|
|
8
|
+
export interface RouteMatch {
|
|
9
|
+
handler: RouteHandler;
|
|
10
|
+
params: Record<string, string>;
|
|
11
|
+
}
|
|
12
|
+
export interface Route {
|
|
13
|
+
method: string;
|
|
14
|
+
path: string;
|
|
15
|
+
pattern: RegExp;
|
|
16
|
+
handler: RouteHandler;
|
|
17
|
+
paramNames: string[];
|
|
18
|
+
}
|
|
19
|
+
export type RouteGroupCallback = (router: IRouter) => void;
|
|
20
|
+
export interface ResourceController {
|
|
21
|
+
index?: RouteHandler;
|
|
22
|
+
show?: RouteHandler;
|
|
23
|
+
store?: RouteHandler;
|
|
24
|
+
update?: RouteHandler;
|
|
25
|
+
destroy?: RouteHandler;
|
|
26
|
+
}
|
|
27
|
+
export type IRouter = {
|
|
28
|
+
routes: Route[];
|
|
29
|
+
prefix: string;
|
|
30
|
+
routeIndex: Map<string, Route[]>;
|
|
31
|
+
};
|
|
32
|
+
export declare const createRouter: () => IRouter;
|
|
33
|
+
/**
|
|
34
|
+
* Router - Sealed namespace for HTTP routing
|
|
35
|
+
* All operations grouped in frozen namespace to prevent mutation
|
|
36
|
+
*/
|
|
37
|
+
export declare const Router: Readonly<{
|
|
38
|
+
createRouter: () => IRouter;
|
|
39
|
+
scopeRouter: (router: IRouter, prefix: string) => IRouter;
|
|
40
|
+
group: (router: IRouter, prefix: string, callback: RouteGroupCallback) => void;
|
|
41
|
+
resource: (router: IRouter, path: string, controller: ResourceController) => void;
|
|
42
|
+
get: (router: IRouter, path: string, handler: RouteHandler) => void;
|
|
43
|
+
post: (router: IRouter, path: string, handler: RouteHandler) => void;
|
|
44
|
+
put: (router: IRouter, path: string, handler: RouteHandler) => void;
|
|
45
|
+
patch: (router: IRouter, path: string, handler: RouteHandler) => void;
|
|
46
|
+
del: (router: IRouter, path: string, handler: RouteHandler) => void;
|
|
47
|
+
any: (router: IRouter, path: string, handler: RouteHandler) => void;
|
|
48
|
+
match: (router: IRouter, method: string, path: string) => RouteMatch | null;
|
|
49
|
+
getRoutes: (router: IRouter) => Route[];
|
|
50
|
+
}>;
|
|
51
|
+
export default Router;
|
|
52
|
+
//# sourceMappingURL=Router.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Router.d.ts","sourceRoot":"","sources":["../../../src/routing/Router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C;;;GAGG;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAEnF,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,YAAY,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,KAAK;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,YAAY,CAAC;IACtB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,MAAM,kBAAkB,GAAG,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;AAE3D,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,OAAO,CAAC,EAAE,YAAY,CAAC;CACxB;AAED,MAAM,MAAM,OAAO,GAAG;IACpB,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;CAClC,CAAC;AAEF,eAAO,MAAM,YAAY,QAAO,OAI9B,CAAC;AAoMH;;;GAGG;AACH,eAAO,MAAM,MAAM;wBA5Ma,OAAO;0BA8IV,OAAO,UAAU,MAAM,KAAG,OAAO;oBAMvC,OAAO,UAAU,MAAM,YAAY,kBAAkB,KAAG,IAAI;uBAIzD,OAAO,QAAQ,MAAM,cAAc,kBAAkB,KAAG,IAAI;kBAgBjE,OAAO,QAAQ,MAAM,WAAW,YAAY,KAAG,IAAI;mBAIlD,OAAO,QAAQ,MAAM,WAAW,YAAY,KAAG,IAAI;kBAIpD,OAAO,QAAQ,MAAM,WAAW,YAAY,KAAG,IAAI;oBAIjD,OAAO,QAAQ,MAAM,WAAW,YAAY,KAAG,IAAI;kBAIrD,OAAO,QAAQ,MAAM,WAAW,YAAY,KAAG,IAAI;kBAInD,OAAO,QAAQ,MAAM,WAAW,YAAY,KAAG,IAAI;oBAOjD,OAAO,UAAU,MAAM,QAAQ,MAAM,KAAG,UAAU,GAAG,IAAI;wBAGrD,OAAO,KAAG,KAAK,EAAE;EAmB1C,CAAC;AAEH,eAAe,MAAM,CAAC"}
|