@zintrust/core 0.1.0 → 0.1.2
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 +214 -0
- package/bin/zintrust.d.ts.map +1 -1
- package/bin/zintrust.js +18 -1
- package/package.json +4 -34
- package/public/index.html +535 -0
- package/src/boot/Application.d.ts.map +1 -1
- package/src/boot/Application.js +46 -3
- package/src/boot/Server.d.ts.map +1 -1
- package/src/boot/Server.js +3 -4
- package/src/boot/bootstrap.js +77 -6
- package/src/builder/BundleOptimizer.d.ts.map +1 -1
- package/src/builder/BundleOptimizer.js +25 -29
- package/src/cache/Cache.d.ts.map +1 -1
- package/src/cache/Cache.js +4 -2
- package/src/cache/drivers/KVDriver.d.ts.map +1 -1
- package/src/cache/drivers/KVDriver.js +8 -7
- package/src/cache/drivers/MemoryDriver.d.ts.map +1 -1
- package/src/cache/drivers/MemoryDriver.js +5 -0
- package/src/cache/drivers/RedisDriver.js +1 -1
- package/src/cli/BaseCommand.d.ts +2 -2
- package/src/cli/BaseCommand.d.ts.map +1 -1
- package/src/cli/BaseCommand.js +2 -1
- package/src/cli/CLI.d.ts.map +1 -1
- package/src/cli/CLI.js +22 -18
- package/src/cli/ErrorHandler.d.ts.map +1 -1
- package/src/cli/ErrorHandler.js +2 -4
- package/src/cli/commands/AddCommand.d.ts +81 -0
- package/src/cli/commands/AddCommand.d.ts.map +1 -1
- package/src/cli/commands/AddCommand.js +24 -5
- package/src/cli/commands/ConfigCommand.d.ts.map +1 -1
- package/src/cli/commands/ConfigCommand.js +59 -25
- package/src/cli/commands/D1MigrateCommand.d.ts +4 -0
- package/src/cli/commands/D1MigrateCommand.d.ts.map +1 -1
- package/src/cli/commands/D1MigrateCommand.js +6 -4
- package/src/cli/commands/FixCommand.d.ts.map +1 -1
- package/src/cli/commands/FixCommand.js +3 -15
- package/src/cli/commands/LogsCleanupCommand.d.ts +6 -0
- package/src/cli/commands/LogsCleanupCommand.d.ts.map +1 -0
- package/src/cli/commands/LogsCleanupCommand.js +20 -0
- package/src/cli/commands/LogsCommand.d.ts.map +1 -1
- package/src/cli/commands/LogsCommand.js +4 -6
- package/src/cli/commands/MakeMailTemplateCommand.d.ts +10 -0
- package/src/cli/commands/MakeMailTemplateCommand.d.ts.map +1 -0
- package/src/cli/commands/MakeMailTemplateCommand.js +74 -0
- package/src/cli/commands/MakeNotificationTemplateCommand.d.ts +10 -0
- package/src/cli/commands/MakeNotificationTemplateCommand.d.ts.map +1 -0
- package/src/cli/commands/MakeNotificationTemplateCommand.js +113 -0
- package/src/cli/commands/MigrateCommand.d.ts.map +1 -1
- package/src/cli/commands/MigrateCommand.js +3 -3
- package/src/cli/commands/NewCommand.d.ts +4 -0
- package/src/cli/commands/NewCommand.d.ts.map +1 -1
- package/src/cli/commands/NewCommand.js +34 -19
- package/src/cli/commands/PluginCommand.d.ts.map +1 -1
- package/src/cli/commands/PluginCommand.js +8 -4
- package/src/cli/commands/PrepareCommand.d.ts.map +1 -1
- package/src/cli/commands/PrepareCommand.js +1 -1
- package/src/cli/commands/QACommand.d.ts.map +1 -1
- package/src/cli/commands/QACommand.js +16 -26
- package/src/cli/commands/SecretsCommand.d.ts +16 -0
- package/src/cli/commands/SecretsCommand.d.ts.map +1 -0
- package/src/cli/commands/SecretsCommand.js +91 -0
- package/src/cli/commands/StartCommand.d.ts.map +1 -1
- package/src/cli/commands/StartCommand.js +2 -2
- package/src/cli/commands/TemplatesCommand.d.ts +3 -0
- package/src/cli/commands/TemplatesCommand.d.ts.map +1 -0
- package/src/cli/commands/TemplatesCommand.js +65 -0
- package/src/cli/commands/index.d.ts +5 -0
- package/src/cli/commands/index.d.ts.map +1 -1
- package/src/cli/commands/index.js +5 -0
- package/src/cli/config/ConfigManager.js +1 -1
- package/src/cli/index.d.ts +2 -1
- package/src/cli/index.d.ts.map +1 -1
- package/src/cli/index.js +2 -1
- package/src/cli/scaffolding/ControllerGenerator.d.ts.map +1 -1
- package/src/cli/scaffolding/ControllerGenerator.js +11 -10
- package/src/cli/scaffolding/FeatureScaffolder.js +4 -4
- package/src/cli/scaffolding/FileGenerator.js +1 -1
- package/src/cli/scaffolding/MigrationGenerator.d.ts.map +1 -1
- package/src/cli/scaffolding/MigrationGenerator.js +10 -9
- package/src/cli/scaffolding/ModelGenerator.d.ts.map +1 -1
- package/src/cli/scaffolding/ModelGenerator.js +11 -10
- package/src/cli/scaffolding/ProjectScaffolder.d.ts.map +1 -1
- package/src/cli/scaffolding/ProjectScaffolder.js +61 -11
- package/src/cli/scaffolding/ResponseFactoryGenerator.d.ts.map +1 -1
- package/src/cli/scaffolding/ResponseFactoryGenerator.js +2 -1
- package/src/cli/scaffolding/RouteGenerator.d.ts.map +1 -1
- package/src/cli/scaffolding/RouteGenerator.js +15 -14
- package/src/cli/scaffolding/SeederGenerator.js +1 -1
- package/src/cli/scaffolding/ServiceIntegrationTestGenerator.d.ts.map +1 -1
- package/src/cli/scaffolding/ServiceIntegrationTestGenerator.js +7 -6
- package/src/cli/scaffolding/ServiceRequestFactoryGenerator.d.ts +1 -1
- package/src/cli/scaffolding/ServiceRequestFactoryGenerator.d.ts.map +1 -1
- package/src/cli/scaffolding/ServiceRequestFactoryGenerator.js +2 -2
- package/src/cli/scaffolding/ServiceScaffolder.d.ts.map +1 -1
- package/src/cli/scaffolding/ServiceScaffolder.js +13 -12
- package/src/cli/scaffolding/TemplateEngine.d.ts +10 -3
- package/src/cli/scaffolding/TemplateEngine.d.ts.map +1 -1
- package/src/cli/scaffolding/TemplateEngine.js +15 -285
- package/src/cli/scaffolding/TemplateGenerator.d.ts +40 -0
- package/src/cli/scaffolding/TemplateGenerator.d.ts.map +1 -0
- package/src/cli/scaffolding/TemplateGenerator.js +172 -0
- package/src/cli/scaffolding/index.d.ts +1 -0
- package/src/cli/scaffolding/index.d.ts.map +1 -1
- package/src/cli/scaffolding/index.js +1 -0
- package/src/cli/utils/spawn.js +1 -1
- package/src/common/AwsSigV4.d.ts +41 -0
- package/src/common/AwsSigV4.d.ts.map +1 -0
- package/src/common/AwsSigV4.js +69 -0
- package/src/common/index.d.ts +39 -0
- package/src/common/index.d.ts.map +1 -1
- package/src/common/index.js +101 -8
- package/src/common/uuid.d.ts +3 -0
- package/src/common/uuid.d.ts.map +1 -0
- package/src/common/uuid.js +30 -0
- package/src/config/FileLogWriter.d.ts +22 -0
- package/src/config/FileLogWriter.d.ts.map +1 -0
- package/src/config/FileLogWriter.js +192 -0
- package/src/config/SecretsManager.d.ts.map +1 -1
- package/src/config/SecretsManager.js +26 -0
- package/src/config/StartupConfigValidator.d.ts +15 -0
- package/src/config/StartupConfigValidator.d.ts.map +1 -0
- package/src/config/StartupConfigValidator.js +86 -0
- package/src/config/app.d.ts +2 -1
- package/src/config/app.d.ts.map +1 -1
- package/src/config/app.js +65 -15
- package/src/config/broadcast.d.ts +47 -0
- package/src/config/broadcast.d.ts.map +1 -0
- package/src/config/broadcast.js +54 -0
- package/src/config/cache.d.ts +13 -17
- package/src/config/cache.d.ts.map +1 -1
- package/src/config/cache.js +9 -11
- package/src/config/cloudflare.d.ts +26 -0
- package/src/config/cloudflare.d.ts.map +1 -0
- package/src/config/cloudflare.js +38 -0
- package/src/config/env.d.ts +6 -0
- package/src/config/env.d.ts.map +1 -1
- package/src/config/env.js +6 -0
- package/src/config/index.d.ts +52 -28
- package/src/config/index.d.ts.map +1 -1
- package/src/config/index.js +3 -0
- package/src/config/logger.d.ts +2 -0
- package/src/config/logger.d.ts.map +1 -1
- package/src/config/logger.js +270 -11
- package/src/config/logging/HttpLogger.d.ts +23 -0
- package/src/config/logging/HttpLogger.d.ts.map +1 -0
- package/src/config/logging/HttpLogger.js +93 -0
- package/src/config/logging/KvLogger.d.ts +22 -0
- package/src/config/logging/KvLogger.d.ts.map +1 -0
- package/src/config/logging/KvLogger.js +143 -0
- package/src/config/logging/SlackLogger.d.ts +23 -0
- package/src/config/logging/SlackLogger.d.ts.map +1 -0
- package/src/config/logging/SlackLogger.js +119 -0
- package/src/config/mail.d.ts +81 -0
- package/src/config/mail.d.ts.map +1 -0
- package/src/config/mail.js +73 -0
- package/src/config/middleware.d.ts +8 -0
- package/src/config/middleware.d.ts.map +1 -0
- package/src/config/middleware.js +18 -0
- package/src/config/notification.d.ts +62 -0
- package/src/config/notification.d.ts.map +1 -0
- package/src/config/notification.js +43 -0
- package/src/config/security.d.ts.map +1 -1
- package/src/config/security.js +2 -2
- package/src/config/startup.d.ts +23 -0
- package/src/config/startup.d.ts.map +1 -0
- package/src/config/startup.js +15 -0
- package/src/config/storage.d.ts +21 -35
- package/src/config/storage.d.ts.map +1 -1
- package/src/config/storage.js +57 -37
- package/src/database/migrations/index.d.ts +1 -1
- package/src/database/migrations/index.d.ts.map +1 -1
- package/src/database/migrations/index.js +2 -1
- package/src/features/Queue.js +1 -25
- package/src/functions/lambda.d.ts.map +1 -1
- package/src/functions/lambda.js +6 -1
- package/src/health/RuntimeHealthProbes.d.ts +13 -0
- package/src/health/RuntimeHealthProbes.d.ts.map +1 -0
- package/src/health/RuntimeHealthProbes.js +62 -0
- package/src/health/StartupHealthChecks.d.ts +26 -0
- package/src/health/StartupHealthChecks.d.ts.map +1 -0
- package/src/health/StartupHealthChecks.js +124 -0
- package/src/http/ErrorResponse.d.ts +28 -0
- package/src/http/ErrorResponse.d.ts.map +1 -0
- package/src/http/ErrorResponse.js +42 -0
- package/src/http/Kernel.d.ts +5 -0
- package/src/http/Kernel.d.ts.map +1 -1
- package/src/http/Kernel.js +96 -30
- package/src/http/Request.d.ts +1 -1
- package/src/http/Request.d.ts.map +1 -1
- package/src/http/RequestContext.d.ts +20 -0
- package/src/http/RequestContext.d.ts.map +1 -0
- package/src/http/RequestContext.js +77 -0
- package/src/index.d.ts +9 -1
- package/src/index.d.ts.map +1 -1
- package/src/index.js +8 -2
- package/src/microservices/MicroserviceBootstrap.d.ts.map +1 -1
- package/src/microservices/MicroserviceBootstrap.js +6 -5
- package/src/microservices/MicroserviceManager.d.ts.map +1 -1
- package/src/microservices/MicroserviceManager.js +7 -5
- package/src/microservices/PostgresAdapter.d.ts.map +1 -1
- package/src/microservices/PostgresAdapter.js +7 -4
- package/src/microservices/ServiceBundler.d.ts.map +1 -1
- package/src/microservices/ServiceBundler.js +3 -1
- package/src/microservices/ServiceHealthMonitor.d.ts.map +1 -1
- package/src/microservices/ServiceHealthMonitor.js +7 -3
- package/src/middleware/CsrfMiddleware.d.ts.map +1 -1
- package/src/middleware/CsrfMiddleware.js +2 -19
- package/src/middleware/ErrorHandlerMiddleware.d.ts +6 -0
- package/src/middleware/ErrorHandlerMiddleware.d.ts.map +1 -0
- package/src/middleware/ErrorHandlerMiddleware.js +33 -0
- package/src/middleware/LoggingMiddleware.d.ts +9 -0
- package/src/middleware/LoggingMiddleware.d.ts.map +1 -0
- package/src/middleware/LoggingMiddleware.js +36 -0
- package/src/middleware/index.d.ts +2 -0
- package/src/middleware/index.d.ts.map +1 -1
- package/src/middleware/index.js +2 -0
- package/src/node-singletons/async_hooks.d.ts +9 -0
- package/src/node-singletons/async_hooks.d.ts.map +1 -0
- package/src/node-singletons/async_hooks.js +8 -0
- 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 +2 -2
- package/src/node-singletons/http.d.ts +1 -1
- package/src/node-singletons/http.d.ts.map +1 -1
- package/src/node-singletons/http.js +1 -1
- package/src/node-singletons/index.d.ts +4 -0
- package/src/node-singletons/index.d.ts.map +1 -1
- package/src/node-singletons/index.js +4 -0
- package/src/node-singletons/net.d.ts +9 -0
- package/src/node-singletons/net.d.ts.map +1 -0
- package/src/node-singletons/net.js +8 -0
- package/src/node-singletons/os.d.ts +3 -3
- package/src/node-singletons/os.d.ts.map +1 -1
- package/src/node-singletons/os.js +3 -4
- package/src/node-singletons/path.d.ts +3 -1
- package/src/node-singletons/path.d.ts.map +1 -1
- package/src/node-singletons/path.js +3 -1
- package/src/node-singletons/perf-hooks.d.ts +3 -1
- package/src/node-singletons/perf-hooks.d.ts.map +1 -1
- package/src/node-singletons/perf-hooks.js +3 -1
- package/src/node-singletons/process.d.ts +23 -0
- package/src/node-singletons/process.d.ts.map +1 -0
- package/src/node-singletons/process.js +8 -0
- package/src/node-singletons/readline.d.ts +3 -3
- package/src/node-singletons/readline.d.ts.map +1 -1
- package/src/node-singletons/readline.js +3 -4
- package/src/node-singletons/tls.d.ts +9 -0
- package/src/node-singletons/tls.d.ts.map +1 -0
- package/src/node-singletons/tls.js +8 -0
- package/src/node-singletons/url.d.ts +3 -1
- package/src/node-singletons/url.d.ts.map +1 -1
- package/src/node-singletons/url.js +3 -1
- package/src/orm/ConnectionManager.d.ts +6 -1
- package/src/orm/ConnectionManager.d.ts.map +1 -1
- package/src/orm/ConnectionManager.js +14 -0
- package/src/orm/DatabaseAdapter.d.ts +6 -0
- package/src/orm/DatabaseAdapter.d.ts.map +1 -1
- package/src/orm/QueryBuilder.d.ts +8 -1
- package/src/orm/QueryBuilder.d.ts.map +1 -1
- package/src/orm/QueryBuilder.js +188 -28
- package/src/orm/adapters/D1Adapter.d.ts.map +1 -1
- package/src/orm/adapters/D1Adapter.js +18 -12
- package/src/orm/adapters/MySQLAdapter.d.ts.map +1 -1
- package/src/orm/adapters/MySQLAdapter.js +4 -0
- package/src/orm/adapters/PostgreSQLAdapter.d.ts.map +1 -1
- package/src/orm/adapters/PostgreSQLAdapter.js +4 -0
- package/src/orm/adapters/SQLServerAdapter.d.ts.map +1 -1
- package/src/orm/adapters/SQLServerAdapter.js +4 -0
- package/src/orm/adapters/SQLiteAdapter.d.ts.map +1 -1
- package/src/orm/adapters/SQLiteAdapter.js +4 -0
- package/src/performance/Benchmark.d.ts.map +1 -1
- package/src/performance/Benchmark.js +3 -0
- package/src/performance/CodeGenerationBenchmark.js +3 -3
- package/src/performance/Optimizer.d.ts +1 -1
- package/src/performance/Optimizer.d.ts.map +1 -1
- package/src/performance/Optimizer.js +157 -80
- package/src/performance/establish-baseline.js +3 -3
- package/src/runtime/PluginManager.d.ts +3 -1
- package/src/runtime/PluginManager.d.ts.map +1 -1
- package/src/runtime/PluginManager.js +124 -28
- package/src/runtime/RuntimeDetector.d.ts.map +1 -1
- package/src/runtime/RuntimeDetector.js +47 -5
- package/src/runtime/adapters/CloudflareAdapter.js +2 -2
- package/src/runtime/adapters/DenoAdapter.js +9 -7
- package/src/runtime/adapters/FargateAdapter.d.ts.map +1 -1
- package/src/runtime/adapters/FargateAdapter.js +4 -3
- package/src/runtime/adapters/LambdaAdapter.d.ts.map +1 -1
- package/src/runtime/adapters/LambdaAdapter.js +4 -2
- package/src/runtime/adapters/NodeServerAdapter.d.ts.map +1 -1
- package/src/runtime/adapters/NodeServerAdapter.js +7 -6
- package/src/scheduler/ScheduleRunner.d.ts +18 -0
- package/src/scheduler/ScheduleRunner.d.ts.map +1 -0
- package/src/scheduler/ScheduleRunner.js +155 -0
- package/src/scheduler/index.d.ts +3 -0
- package/src/scheduler/index.d.ts.map +1 -0
- package/src/scheduler/index.js +1 -0
- package/src/scheduler/types.d.ts +16 -0
- package/src/scheduler/types.d.ts.map +1 -0
- package/src/scheduler/types.js +4 -0
- package/src/schedules/index.d.ts +2 -0
- package/src/schedules/index.d.ts.map +1 -0
- package/src/schedules/index.js +1 -0
- package/src/schedules/log-cleanup.d.ts +4 -0
- package/src/schedules/log-cleanup.d.ts.map +1 -0
- package/src/schedules/log-cleanup.js +18 -0
- package/src/scripts/GenerateEnvArtifacts.d.ts +13 -0
- package/src/scripts/GenerateEnvArtifacts.d.ts.map +1 -0
- package/src/scripts/GenerateEnvArtifacts.js +171 -0
- package/src/scripts/TemplateSync.js +109 -70
- package/src/security/CsrfTokenManager.js +1 -1
- package/src/security/Encryptor.js +1 -1
- package/src/security/Hash.d.ts +14 -0
- package/src/security/Hash.d.ts.map +1 -0
- package/src/security/Hash.js +81 -0
- package/src/security/StartupSecretValidation.d.ts +20 -0
- package/src/security/StartupSecretValidation.d.ts.map +1 -0
- package/src/security/StartupSecretValidation.js +61 -0
- package/src/security/UrlValidator.d.ts +0 -1
- package/src/security/UrlValidator.d.ts.map +1 -1
- package/src/security/UrlValidator.js +1 -2
- package/src/security/Xss.d.ts +14 -0
- package/src/security/Xss.d.ts.map +1 -0
- package/src/security/Xss.js +57 -0
- package/src/security/XssProtection.d.ts.map +1 -1
- package/src/security/XssProtection.js +150 -16
- package/src/templates/adapters/MySQLAdapter.ts.tpl +5 -0
- package/src/templates/adapters/PostgreSQLAdapter.ts.tpl +5 -0
- package/src/templates/adapters/SQLServerAdapter.ts.tpl +5 -0
- package/src/templates/adapters/SQLiteAdapter.ts.tpl +5 -0
- package/src/templates/features/Queue.ts.tpl +1 -29
- package/src/templates/project/basic/.env.example.tpl +48 -0
- package/src/templates/project/basic/.env.tpl +89 -94
- package/src/templates/project/basic/app/Toolkit/Broadcast/sendBroadcast.ts.tpl +7 -0
- package/src/templates/project/basic/app/Toolkit/Mail/sendWelcomeEmail.ts.tpl +30 -0
- package/src/templates/project/basic/app/Toolkit/Notification/sendSlackNotification.ts.tpl +10 -0
- package/src/templates/project/basic/app/Toolkit/Notification/sendSms.ts.tpl +13 -0
- package/src/templates/project/basic/config/FileLogWriter.ts.tpl +240 -0
- package/src/templates/project/basic/config/SecretsManager.ts.tpl +32 -1
- package/src/templates/project/basic/config/StartupConfigValidator.ts.tpl +151 -0
- package/src/templates/project/basic/config/app.ts.tpl +84 -15
- package/src/templates/project/basic/config/broadcast.ts.tpl +97 -0
- package/src/templates/project/basic/config/cache.ts.tpl +19 -23
- package/src/templates/project/basic/config/cloudflare.ts.tpl +57 -0
- package/src/templates/project/basic/config/env.ts.tpl +7 -1
- package/src/templates/project/basic/config/index.ts.tpl +3 -0
- package/src/templates/project/basic/config/logger.ts.tpl +301 -11
- package/src/templates/project/basic/config/logging/HttpLogger.ts.tpl +121 -0
- package/src/templates/project/basic/config/logging/KvLogger.ts.tpl +181 -0
- package/src/templates/project/basic/config/logging/SlackLogger.ts.tpl +156 -0
- package/src/templates/project/basic/config/mail.ts.tpl +141 -0
- package/src/templates/project/basic/config/middleware.ts.tpl +27 -0
- package/src/templates/project/basic/config/notification.ts.tpl +86 -0
- package/src/templates/project/basic/config/security.ts.tpl +4 -5
- package/src/templates/project/basic/config/startup.ts.tpl +27 -0
- package/src/templates/project/basic/config/storage.ts.tpl +77 -42
- package/src/templates/project/basic/database/migrations/index.ts.tpl +1 -1
- package/src/templates/project/basic/package.json.tpl +1 -1
- package/src/templates/project/basic/routes/api.ts.tpl +9 -37
- package/src/templates/project/basic/routes/broadcast.ts.tpl +32 -0
- package/src/templates/project/basic/routes/health.ts.tpl +134 -0
- package/src/templates/project/basic/src/index.ts.tpl +38 -11
- package/src/templates/project/basic/template.json +3 -0
- package/src/toolkit/Secrets/EnvFile.d.ts +15 -0
- package/src/toolkit/Secrets/EnvFile.d.ts.map +1 -0
- package/src/toolkit/Secrets/EnvFile.js +63 -0
- package/src/toolkit/Secrets/Manifest.d.ts +24 -0
- package/src/toolkit/Secrets/Manifest.d.ts.map +1 -0
- package/src/toolkit/Secrets/Manifest.js +71 -0
- package/src/toolkit/Secrets/index.d.ts +42 -0
- package/src/toolkit/Secrets/index.d.ts.map +1 -0
- package/src/toolkit/Secrets/index.js +119 -0
- package/src/toolkit/Secrets/providers/AwsSecretsManager.d.ts +14 -0
- package/src/toolkit/Secrets/providers/AwsSecretsManager.d.ts.map +1 -0
- package/src/toolkit/Secrets/providers/AwsSecretsManager.js +131 -0
- package/src/toolkit/Secrets/providers/CloudflareKv.d.ts +9 -0
- package/src/toolkit/Secrets/providers/CloudflareKv.d.ts.map +1 -0
- package/src/toolkit/Secrets/providers/CloudflareKv.js +73 -0
- package/src/tools/broadcast/Broadcast.d.ts +7 -0
- package/src/tools/broadcast/Broadcast.d.ts.map +1 -0
- package/src/tools/broadcast/Broadcast.js +37 -0
- package/src/tools/broadcast/drivers/BaseDriver.d.ts +5 -0
- package/src/tools/broadcast/drivers/BaseDriver.d.ts.map +1 -0
- package/src/tools/broadcast/drivers/BaseDriver.js +8 -0
- package/src/tools/broadcast/drivers/InMemory.d.ts +18 -0
- package/src/tools/broadcast/drivers/InMemory.d.ts.map +1 -0
- package/src/tools/broadcast/drivers/InMemory.js +16 -0
- package/src/tools/broadcast/drivers/Pusher.d.ts +8 -0
- package/src/tools/broadcast/drivers/Pusher.d.ts.map +1 -0
- package/src/tools/broadcast/drivers/Pusher.js +75 -0
- package/src/tools/broadcast/drivers/Redis.d.ts +19 -0
- package/src/tools/broadcast/drivers/Redis.d.ts.map +1 -0
- package/src/tools/broadcast/drivers/Redis.js +73 -0
- package/src/tools/broadcast/drivers/RedisHttps.d.ts +14 -0
- package/src/tools/broadcast/drivers/RedisHttps.d.ts.map +1 -0
- package/src/tools/broadcast/drivers/RedisHttps.js +50 -0
- package/src/tools/broadcast/index.d.ts +7 -0
- package/src/tools/broadcast/index.d.ts.map +1 -0
- package/src/tools/broadcast/index.js +6 -0
- package/src/tools/http/Http.d.ts +51 -0
- package/src/tools/http/Http.d.ts.map +1 -0
- package/src/tools/http/Http.js +171 -0
- package/src/tools/http/HttpResponse.d.ts +32 -0
- package/src/tools/http/HttpResponse.d.ts.map +1 -0
- package/src/tools/http/HttpResponse.js +80 -0
- package/src/tools/http/index.d.ts +15 -0
- package/src/tools/http/index.d.ts.map +1 -0
- package/src/tools/http/index.js +9 -0
- package/src/tools/mail/Mail.d.ts +22 -0
- package/src/tools/mail/Mail.d.ts.map +1 -0
- package/src/tools/mail/Mail.js +105 -0
- package/src/tools/mail/attachments.d.ts +23 -0
- package/src/tools/mail/attachments.d.ts.map +1 -0
- package/src/tools/mail/attachments.js +26 -0
- package/src/tools/mail/drivers/BaseDriver.d.ts +5 -0
- package/src/tools/mail/drivers/BaseDriver.d.ts.map +1 -0
- package/src/tools/mail/drivers/BaseDriver.js +8 -0
- package/src/tools/mail/drivers/Mailgun.d.ts +31 -0
- package/src/tools/mail/drivers/Mailgun.d.ts.map +1 -0
- package/src/tools/mail/drivers/Mailgun.js +81 -0
- package/src/tools/mail/drivers/SendGrid.d.ts +29 -0
- package/src/tools/mail/drivers/SendGrid.d.ts.map +1 -0
- package/src/tools/mail/drivers/SendGrid.js +57 -0
- package/src/tools/mail/drivers/Ses.d.ts +24 -0
- package/src/tools/mail/drivers/Ses.d.ts.map +1 -0
- package/src/tools/mail/drivers/Ses.js +116 -0
- package/src/tools/mail/drivers/Smtp.d.ts +38 -0
- package/src/tools/mail/drivers/Smtp.d.ts.map +1 -0
- package/src/tools/mail/drivers/Smtp.js +327 -0
- package/src/tools/mail/templates/index.d.ts +27 -0
- package/src/tools/mail/templates/index.d.ts.map +1 -0
- package/src/tools/mail/templates/index.js +35 -0
- package/src/tools/mail/templates/markdown/index.d.ts +17 -0
- package/src/tools/mail/templates/markdown/index.d.ts.map +1 -0
- package/src/tools/mail/templates/markdown/index.js +49 -0
- package/src/tools/mail/templates/markdown/registry.d.ts +15 -0
- package/src/tools/mail/templates/markdown/registry.d.ts.map +1 -0
- package/src/tools/mail/templates/markdown/registry.js +34 -0
- package/src/tools/mail/templates/markdown/validator.d.ts +16 -0
- package/src/tools/mail/templates/markdown/validator.d.ts.map +1 -0
- package/src/tools/mail/templates/markdown/validator.js +24 -0
- package/src/tools/mail/testing.d.ts +41 -0
- package/src/tools/mail/testing.d.ts.map +1 -0
- package/src/tools/mail/testing.js +34 -0
- package/src/tools/notification/Driver.d.ts +11 -0
- package/src/tools/notification/Driver.d.ts.map +1 -0
- package/src/tools/notification/Driver.js +1 -0
- package/src/tools/notification/Notification.d.ts +11 -0
- package/src/tools/notification/Notification.d.ts.map +1 -0
- package/src/tools/notification/Notification.js +11 -0
- package/src/tools/notification/Registry.d.ts +10 -0
- package/src/tools/notification/Registry.d.ts.map +1 -0
- package/src/tools/notification/Registry.js +22 -0
- package/src/tools/notification/Service.d.ts +6 -0
- package/src/tools/notification/Service.d.ts.map +1 -0
- package/src/tools/notification/Service.js +18 -0
- package/src/tools/notification/config.d.ts +5 -0
- package/src/tools/notification/config.d.ts.map +1 -0
- package/src/tools/notification/config.js +5 -0
- package/src/tools/notification/drivers/BaseDriver.d.ts +5 -0
- package/src/tools/notification/drivers/BaseDriver.d.ts.map +1 -0
- package/src/tools/notification/drivers/BaseDriver.js +8 -0
- package/src/tools/notification/drivers/Console.d.ts +7 -0
- package/src/tools/notification/drivers/Console.d.ts.map +1 -0
- package/src/tools/notification/drivers/Console.js +13 -0
- package/src/tools/notification/drivers/Slack.d.ts +16 -0
- package/src/tools/notification/drivers/Slack.d.ts.map +1 -0
- package/src/tools/notification/drivers/Slack.js +24 -0
- package/src/tools/notification/drivers/Termii.d.ts +10 -0
- package/src/tools/notification/drivers/Termii.d.ts.map +1 -0
- package/src/tools/notification/drivers/Termii.js +47 -0
- package/src/tools/notification/drivers/Twilio.d.ts +21 -0
- package/src/tools/notification/drivers/Twilio.d.ts.map +1 -0
- package/src/tools/notification/drivers/Twilio.js +48 -0
- package/src/tools/notification/templates/markdown/index.d.ts +15 -0
- package/src/tools/notification/templates/markdown/index.d.ts.map +1 -0
- package/src/tools/notification/templates/markdown/index.js +38 -0
- package/src/tools/notification/templates/markdown/registry.d.ts +15 -0
- package/src/tools/notification/templates/markdown/registry.d.ts.map +1 -0
- package/src/tools/notification/templates/markdown/registry.js +36 -0
- package/src/tools/notification/testing.d.ts +19 -0
- package/src/tools/notification/testing.d.ts.map +1 -0
- package/src/tools/notification/testing.js +35 -0
- package/src/tools/notification/testingHelpers.d.ts +12 -0
- package/src/tools/notification/testingHelpers.d.ts.map +1 -0
- package/src/tools/notification/testingHelpers.js +32 -0
- package/src/tools/queue/Queue.d.ts +23 -0
- package/src/tools/queue/Queue.d.ts.map +1 -0
- package/src/tools/queue/Queue.js +38 -0
- package/src/tools/queue/drivers/InMemory.d.ts +10 -0
- package/src/tools/queue/drivers/InMemory.d.ts.map +1 -0
- package/src/tools/queue/drivers/InMemory.js +55 -0
- package/src/tools/queue/drivers/Redis.d.ts +10 -0
- package/src/tools/queue/drivers/Redis.d.ts.map +1 -0
- package/src/tools/queue/drivers/Redis.js +91 -0
- package/src/tools/storage/drivers/Gcs.d.ts +20 -0
- package/src/tools/storage/drivers/Gcs.d.ts.map +1 -0
- package/src/tools/storage/drivers/Gcs.js +152 -0
- package/src/tools/storage/drivers/Local.d.ts +17 -0
- package/src/tools/storage/drivers/Local.d.ts.map +1 -0
- package/src/tools/storage/drivers/Local.js +63 -0
- package/src/tools/storage/drivers/R2.d.ts +20 -0
- package/src/tools/storage/drivers/R2.d.ts.map +1 -0
- package/src/tools/storage/drivers/R2.js +73 -0
- package/src/tools/storage/drivers/S3.d.ts +26 -0
- package/src/tools/storage/drivers/S3.d.ts.map +1 -0
- package/src/tools/storage/drivers/S3.js +258 -0
- package/src/tools/storage/index.d.ts +24 -0
- package/src/tools/storage/index.d.ts.map +1 -0
- package/src/tools/storage/index.js +112 -0
- package/src/tools/storage/testing.d.ts +23 -0
- package/src/tools/storage/testing.d.ts.map +1 -0
- package/src/tools/storage/testing.js +52 -0
- package/src/tools/templates/MarkdownRenderer.d.ts +14 -0
- package/src/tools/templates/MarkdownRenderer.d.ts.map +1 -0
- package/src/tools/templates/MarkdownRenderer.js +300 -0
- package/src/tools/templates/index.d.ts +5 -0
- package/src/tools/templates/index.d.ts.map +1 -0
- package/src/tools/templates/index.js +4 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { ErrorFactory } from '../../exceptions/ZintrustError';
|
|
2
|
+
const drivers = new Map();
|
|
3
|
+
export const Queue = Object.freeze({
|
|
4
|
+
register(name, driver) {
|
|
5
|
+
drivers.set(name.toLowerCase(), driver);
|
|
6
|
+
},
|
|
7
|
+
get(name) {
|
|
8
|
+
const driverName = (name ?? process.env['QUEUE_DRIVER'] ?? 'inmemory')
|
|
9
|
+
.toString()
|
|
10
|
+
.trim()
|
|
11
|
+
.toLowerCase();
|
|
12
|
+
const driver = drivers.get(driverName);
|
|
13
|
+
if (!driver)
|
|
14
|
+
throw ErrorFactory.createConfigError(`Queue driver not registered: ${driverName}`);
|
|
15
|
+
return driver;
|
|
16
|
+
},
|
|
17
|
+
async enqueue(queue, payload, driverName) {
|
|
18
|
+
const driver = Queue.get(driverName);
|
|
19
|
+
return driver.enqueue(queue, payload);
|
|
20
|
+
},
|
|
21
|
+
async dequeue(queue, driverName) {
|
|
22
|
+
const driver = Queue.get(driverName);
|
|
23
|
+
return driver.dequeue(queue);
|
|
24
|
+
},
|
|
25
|
+
async ack(queue, id, driverName) {
|
|
26
|
+
const driver = Queue.get(driverName);
|
|
27
|
+
return driver.ack(queue, id);
|
|
28
|
+
},
|
|
29
|
+
async length(queue, driverName) {
|
|
30
|
+
const driver = Queue.get(driverName);
|
|
31
|
+
return driver.length(queue);
|
|
32
|
+
},
|
|
33
|
+
async drain(queue, driverName) {
|
|
34
|
+
const driver = Queue.get(driverName);
|
|
35
|
+
return driver.drain(queue);
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
export default Queue;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { QueueMessage } from '../../queue/Queue';
|
|
2
|
+
export declare const InMemoryQueue: {
|
|
3
|
+
readonly enqueue: <T = unknown>(queue: string, payload: T) => Promise<string>;
|
|
4
|
+
readonly dequeue: <T = unknown>(queue: string) => Promise<QueueMessage<T> | undefined>;
|
|
5
|
+
readonly ack: (_queue: string, _id: string) => Promise<void>;
|
|
6
|
+
readonly length: (queue: string) => Promise<number>;
|
|
7
|
+
readonly drain: (queue: string) => Promise<void>;
|
|
8
|
+
};
|
|
9
|
+
export default InMemoryQueue;
|
|
10
|
+
//# sourceMappingURL=InMemory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InMemory.d.ts","sourceRoot":"","sources":["../../../../../src/tools/queue/drivers/InMemory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAIlD,eAAO,MAAM,aAAa;uBAQR,CAAC,mBAAmB,MAAM,WAAW,CAAC,KAAG,OAAO,CAAC,MAAM,CAAC;uBAmBxD,CAAC,mBAAmB,MAAM,KAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;2BAW7D,MAAM,OAAO,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;6BAKjC,MAAM,KAAG,OAAO,CAAC,MAAM,CAAC;4BAOzB,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;CAMzC,CAAC;AAEL,eAAe,aAAa,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { generateUuid } from '../../../common/uuid';
|
|
2
|
+
export const InMemoryQueue = (() => {
|
|
3
|
+
const store = new Map();
|
|
4
|
+
const ensure = (queue) => {
|
|
5
|
+
if (!store.has(queue))
|
|
6
|
+
store.set(queue, []);
|
|
7
|
+
};
|
|
8
|
+
return {
|
|
9
|
+
async enqueue(queue, payload) {
|
|
10
|
+
await Promise.resolve();
|
|
11
|
+
ensure(queue);
|
|
12
|
+
const id = generateUuid();
|
|
13
|
+
const msg = {
|
|
14
|
+
id,
|
|
15
|
+
payload: payload,
|
|
16
|
+
attempts: 0,
|
|
17
|
+
enqueuedAt: Date.now(),
|
|
18
|
+
};
|
|
19
|
+
const arr = store.get(queue);
|
|
20
|
+
if (arr && arr.length > 0) {
|
|
21
|
+
arr.push(msg);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
store.set(queue, [msg]);
|
|
25
|
+
}
|
|
26
|
+
return id;
|
|
27
|
+
},
|
|
28
|
+
async dequeue(queue) {
|
|
29
|
+
await Promise.resolve();
|
|
30
|
+
ensure(queue);
|
|
31
|
+
const arr = store.get(queue);
|
|
32
|
+
if (arr && arr.length > 0) {
|
|
33
|
+
const msg = arr.shift();
|
|
34
|
+
return msg;
|
|
35
|
+
}
|
|
36
|
+
return undefined;
|
|
37
|
+
},
|
|
38
|
+
async ack(_queue, _id) {
|
|
39
|
+
// in-memory dequeue already removed the message; ack is a no-op
|
|
40
|
+
await Promise.resolve();
|
|
41
|
+
},
|
|
42
|
+
async length(queue) {
|
|
43
|
+
await Promise.resolve();
|
|
44
|
+
ensure(queue);
|
|
45
|
+
const arr = store.get(queue);
|
|
46
|
+
return Array.isArray(arr) ? arr.length : 0;
|
|
47
|
+
},
|
|
48
|
+
async drain(queue) {
|
|
49
|
+
await Promise.resolve();
|
|
50
|
+
ensure(queue);
|
|
51
|
+
store.set(queue, []);
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
})();
|
|
55
|
+
export default InMemoryQueue;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { QueueMessage } from '../../queue/Queue';
|
|
2
|
+
export declare const RedisQueue: {
|
|
3
|
+
readonly enqueue: <T = unknown>(queue: string, payload: T) => Promise<string>;
|
|
4
|
+
readonly dequeue: <T = unknown>(queue: string) => Promise<QueueMessage<T> | undefined>;
|
|
5
|
+
readonly ack: (_queue: string, _id: string) => Promise<void>;
|
|
6
|
+
readonly length: (queue: string) => Promise<number>;
|
|
7
|
+
readonly drain: (queue: string) => Promise<void>;
|
|
8
|
+
};
|
|
9
|
+
export default RedisQueue;
|
|
10
|
+
//# sourceMappingURL=Redis.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Redis.d.ts","sourceRoot":"","sources":["../../../../../src/tools/queue/drivers/Redis.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAelD,eAAO,MAAM,UAAU;uBAuDL,CAAC,mBAAmB,MAAM,WAAW,CAAC,KAAG,OAAO,CAAC,MAAM,CAAC;uBAQxD,CAAC,mBAAmB,MAAM,KAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;2BAY7D,MAAM,OAAO,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;6BAMjC,MAAM,KAAG,OAAO,CAAC,MAAM,CAAC;4BAKzB,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;CAKzC,CAAC;AAEL,eAAe,UAAU,CAAC"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { generateUuid } from '../../../common/uuid';
|
|
2
|
+
import { ErrorFactory } from '../../../exceptions/ZintrustError';
|
|
3
|
+
const getRedisUrl = () => {
|
|
4
|
+
const url = (process.env['REDIS_URL'] ?? '').trim();
|
|
5
|
+
return url.length > 0 ? url : null;
|
|
6
|
+
};
|
|
7
|
+
export const RedisQueue = (() => {
|
|
8
|
+
let client = null;
|
|
9
|
+
let connected = false;
|
|
10
|
+
const ensureClient = async () => {
|
|
11
|
+
if (connected && client !== null)
|
|
12
|
+
return client;
|
|
13
|
+
const url = getRedisUrl();
|
|
14
|
+
if (url === null)
|
|
15
|
+
throw ErrorFactory.createConfigError('Redis queue driver requires REDIS_URL');
|
|
16
|
+
// Import lazily so package is optional for environments that don't use Redis
|
|
17
|
+
// Prefer real 'redis' package when available, otherwise allow tests to inject a fake client
|
|
18
|
+
try {
|
|
19
|
+
// Dynamically import the redis package if available (optional dependency)
|
|
20
|
+
// Tests can inject a fake client on `globalThis.__fakeRedisClient` if the package is absent.
|
|
21
|
+
// Dynamically import the redis package if available (optional dependency)
|
|
22
|
+
const mod = (await import('redis'));
|
|
23
|
+
const createClient = mod.createClient;
|
|
24
|
+
client = createClient({ url });
|
|
25
|
+
if (typeof client.connect === 'function') {
|
|
26
|
+
try {
|
|
27
|
+
// Await connect to ensure readiness; network errors will be surfaced
|
|
28
|
+
await client.connect();
|
|
29
|
+
connected = true;
|
|
30
|
+
}
|
|
31
|
+
catch (connectionError) {
|
|
32
|
+
connected = false;
|
|
33
|
+
// log non-fatally — operations will surface errors as needed
|
|
34
|
+
// eslint-disable-next-line no-console
|
|
35
|
+
console.warn('Redis client connect failed:', String(connectionError));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
connected = true;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
const globalFake = globalThis
|
|
44
|
+
.__fakeRedisClient;
|
|
45
|
+
if (globalFake === undefined) {
|
|
46
|
+
throw ErrorFactory.createConfigError("Redis queue driver requires the 'redis' package or a test fake client set in globalThis.__fakeRedisClient");
|
|
47
|
+
}
|
|
48
|
+
client = globalFake;
|
|
49
|
+
connected = true;
|
|
50
|
+
}
|
|
51
|
+
if (client === null)
|
|
52
|
+
throw ErrorFactory.createConfigError('Redis client could not be initialized');
|
|
53
|
+
return client;
|
|
54
|
+
};
|
|
55
|
+
return {
|
|
56
|
+
async enqueue(queue, payload) {
|
|
57
|
+
const cli = await ensureClient();
|
|
58
|
+
const id = generateUuid();
|
|
59
|
+
const msg = JSON.stringify({ id, payload, attempts: 0 });
|
|
60
|
+
await cli.rPush(queue, msg);
|
|
61
|
+
return id;
|
|
62
|
+
},
|
|
63
|
+
async dequeue(queue) {
|
|
64
|
+
const cli = await ensureClient();
|
|
65
|
+
const raw = await cli.lPop(queue);
|
|
66
|
+
if (raw === null)
|
|
67
|
+
return undefined;
|
|
68
|
+
try {
|
|
69
|
+
const parsed = JSON.parse(raw);
|
|
70
|
+
return parsed;
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
throw ErrorFactory.createTryCatchError('Failed to parse queue message', err);
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
async ack(_queue, _id) {
|
|
77
|
+
// Simple list-based queue removes on dequeue, so ack is a no-op here.
|
|
78
|
+
// For visibility timeout or retry semantics, implement BRPOPLPUSH and a processing list.
|
|
79
|
+
return Promise.resolve(); // NOSONAR
|
|
80
|
+
},
|
|
81
|
+
async length(queue) {
|
|
82
|
+
const cli = await ensureClient();
|
|
83
|
+
return cli.lLen(queue);
|
|
84
|
+
},
|
|
85
|
+
async drain(queue) {
|
|
86
|
+
const cli = await ensureClient();
|
|
87
|
+
await cli.del(queue);
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
})();
|
|
91
|
+
export default RedisQueue;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type GcsConfig = {
|
|
2
|
+
bucket: string;
|
|
3
|
+
projectId?: string;
|
|
4
|
+
keyFile?: string;
|
|
5
|
+
url?: string;
|
|
6
|
+
};
|
|
7
|
+
type TempUrlOptions = {
|
|
8
|
+
expiresIn?: number;
|
|
9
|
+
method?: 'GET' | 'PUT';
|
|
10
|
+
};
|
|
11
|
+
export declare const GcsDriver: Readonly<{
|
|
12
|
+
url(config: GcsConfig, key: string): string | undefined;
|
|
13
|
+
put(config: GcsConfig, key: string, content: string | Buffer): Promise<string>;
|
|
14
|
+
get(config: GcsConfig, key: string): Promise<Buffer>;
|
|
15
|
+
exists(config: GcsConfig, key: string): Promise<boolean>;
|
|
16
|
+
delete(config: GcsConfig, key: string): Promise<void>;
|
|
17
|
+
tempUrl(config: GcsConfig, key: string, options?: TempUrlOptions): Promise<string>;
|
|
18
|
+
}>;
|
|
19
|
+
export default GcsDriver;
|
|
20
|
+
//# sourceMappingURL=Gcs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Gcs.d.ts","sourceRoot":"","sources":["../../../../../src/tools/storage/drivers/Gcs.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,SAAS,GAAG;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,KAAK,cAAc,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,KAAK,GAAG,KAAK,CAAA;CAAE,CAAC;AA+ErE,eAAO,MAAM,SAAS;gBACR,SAAS,OAAO,MAAM,GAAG,MAAM,GAAG,SAAS;gBAWrC,SAAS,OAAO,MAAM,WAAW,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;gBAkBlE,SAAS,OAAO,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;mBAiBrC,SAAS,OAAO,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;mBAgBzC,SAAS,OAAO,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;oBAiBrC,SAAS,OAAO,MAAM,YAAY,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC;EA8BxF,CAAC;AAEH,eAAe,SAAS,CAAC"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { ErrorFactory } from '../../../exceptions/ZintrustError';
|
|
2
|
+
let cachedRealClient;
|
|
3
|
+
const getInjectedStorageModule = () => {
|
|
4
|
+
return globalThis
|
|
5
|
+
.__fakeGoogleCloudStorageModule;
|
|
6
|
+
};
|
|
7
|
+
const getInjectedFakeClient = () => {
|
|
8
|
+
const v = globalThis.__fakeGcsClient;
|
|
9
|
+
return v;
|
|
10
|
+
};
|
|
11
|
+
const loadRealClient = async (config) => {
|
|
12
|
+
if (cachedRealClient !== undefined)
|
|
13
|
+
return cachedRealClient;
|
|
14
|
+
// Avoid a string-literal import so TypeScript doesn't require the module at build time.
|
|
15
|
+
const specifier = '@google-cloud/storage';
|
|
16
|
+
const injected = getInjectedStorageModule();
|
|
17
|
+
let mod;
|
|
18
|
+
try {
|
|
19
|
+
mod = (injected ?? (await import(specifier)));
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
throw ErrorFactory.createConfigError('GCS: missing optional dependency @google-cloud/storage (install it or inject globalThis.__fakeGcsClient for tests)', { error: err });
|
|
23
|
+
}
|
|
24
|
+
if (typeof mod.Storage !== 'function') {
|
|
25
|
+
throw ErrorFactory.createConfigError('GCS: @google-cloud/storage did not export Storage');
|
|
26
|
+
}
|
|
27
|
+
const opts = {};
|
|
28
|
+
if (typeof config.projectId === 'string' && config.projectId.trim() !== '') {
|
|
29
|
+
opts['projectId'] = config.projectId;
|
|
30
|
+
}
|
|
31
|
+
if (typeof config.keyFile === 'string' && config.keyFile.trim() !== '') {
|
|
32
|
+
opts['keyFilename'] = config.keyFile;
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
cachedRealClient = new mod.Storage(opts);
|
|
36
|
+
return cachedRealClient;
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
throw ErrorFactory.createConfigError('GCS: failed to initialize Storage client', {
|
|
40
|
+
error: err,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
const getClient = async (config) => {
|
|
45
|
+
const injected = getInjectedFakeClient();
|
|
46
|
+
if (injected !== undefined)
|
|
47
|
+
return injected;
|
|
48
|
+
return loadRealClient(config);
|
|
49
|
+
};
|
|
50
|
+
const encodePathSegments = (key) => key
|
|
51
|
+
.split('/')
|
|
52
|
+
.map((seg) => encodeURIComponent(seg))
|
|
53
|
+
.join('/');
|
|
54
|
+
export const GcsDriver = Object.freeze({
|
|
55
|
+
url(config, key) {
|
|
56
|
+
const bucket = String(config.bucket ?? '').trim();
|
|
57
|
+
if (bucket === '')
|
|
58
|
+
return undefined;
|
|
59
|
+
const base = typeof config.url === 'string' ? config.url.trim() : '';
|
|
60
|
+
if (base !== '')
|
|
61
|
+
return `${base.replace(/\/$/, '')}/${key}`;
|
|
62
|
+
const encodedKey = encodePathSegments(key);
|
|
63
|
+
return `https://storage.googleapis.com/${encodeURIComponent(bucket)}/${encodedKey}`;
|
|
64
|
+
},
|
|
65
|
+
async put(config, key, content) {
|
|
66
|
+
const bucket = String(config.bucket ?? '').trim();
|
|
67
|
+
if (bucket === '')
|
|
68
|
+
throw ErrorFactory.createConfigError('GCS: bucket is not configured');
|
|
69
|
+
const client = await getClient(config);
|
|
70
|
+
const file = client.bucket(bucket).file(key);
|
|
71
|
+
if (typeof file.save !== 'function') {
|
|
72
|
+
throw ErrorFactory.createConfigError('GCS: client is missing file.save()');
|
|
73
|
+
}
|
|
74
|
+
await file.save(content);
|
|
75
|
+
const url = GcsDriver.url(config, key);
|
|
76
|
+
if (url === undefined)
|
|
77
|
+
return '';
|
|
78
|
+
return url;
|
|
79
|
+
},
|
|
80
|
+
async get(config, key) {
|
|
81
|
+
const bucket = String(config.bucket ?? '').trim();
|
|
82
|
+
if (bucket === '')
|
|
83
|
+
throw ErrorFactory.createConfigError('GCS: bucket is not configured');
|
|
84
|
+
const client = await getClient(config);
|
|
85
|
+
const file = client.bucket(bucket).file(key);
|
|
86
|
+
if (typeof file.download !== 'function') {
|
|
87
|
+
throw ErrorFactory.createConfigError('GCS: client is missing file.download()');
|
|
88
|
+
}
|
|
89
|
+
const [data] = await file.download();
|
|
90
|
+
if (Buffer.isBuffer(data))
|
|
91
|
+
return data;
|
|
92
|
+
if (typeof data === 'string')
|
|
93
|
+
return Buffer.from(data);
|
|
94
|
+
return Buffer.from(data);
|
|
95
|
+
},
|
|
96
|
+
async exists(config, key) {
|
|
97
|
+
const bucket = String(config.bucket ?? '').trim();
|
|
98
|
+
if (bucket === '')
|
|
99
|
+
throw ErrorFactory.createConfigError('GCS: bucket is not configured');
|
|
100
|
+
const client = await getClient(config);
|
|
101
|
+
const file = client.bucket(bucket).file(key);
|
|
102
|
+
if (typeof file.exists !== 'function') {
|
|
103
|
+
// if client doesn't support exists, assume true (matches Storage.exists default behavior)
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
const [exists] = await file.exists();
|
|
107
|
+
return Boolean(exists);
|
|
108
|
+
},
|
|
109
|
+
async delete(config, key) {
|
|
110
|
+
const bucket = String(config.bucket ?? '').trim();
|
|
111
|
+
if (bucket === '')
|
|
112
|
+
throw ErrorFactory.createConfigError('GCS: bucket is not configured');
|
|
113
|
+
const client = await getClient(config);
|
|
114
|
+
const file = client.bucket(bucket).file(key);
|
|
115
|
+
if (typeof file.delete !== 'function')
|
|
116
|
+
return;
|
|
117
|
+
try {
|
|
118
|
+
// google-cloud-storage supports ignoreNotFound, but keep it flexible for fakes
|
|
119
|
+
await file.delete({ ignoreNotFound: true });
|
|
120
|
+
}
|
|
121
|
+
catch (err) {
|
|
122
|
+
void err; // NOSONAR
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
async tempUrl(config, key, options) {
|
|
126
|
+
const bucket = String(config.bucket ?? '').trim();
|
|
127
|
+
if (bucket === '')
|
|
128
|
+
throw ErrorFactory.createConfigError('GCS: bucket is not configured');
|
|
129
|
+
const expiresIn = options?.expiresIn ?? 900;
|
|
130
|
+
if (!Number.isFinite(expiresIn) || expiresIn <= 0) {
|
|
131
|
+
throw ErrorFactory.createValidationError('GCS: expiresIn must be a positive number', {
|
|
132
|
+
expiresIn,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
if (expiresIn > 604800) {
|
|
136
|
+
throw ErrorFactory.createValidationError('GCS: expiresIn exceeds 7 days', {
|
|
137
|
+
expiresIn,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
const method = options?.method ?? 'GET';
|
|
141
|
+
const action = method === 'PUT' ? 'write' : 'read';
|
|
142
|
+
const client = await getClient(config);
|
|
143
|
+
const file = client.bucket(bucket).file(key);
|
|
144
|
+
if (typeof file.getSignedUrl !== 'function') {
|
|
145
|
+
throw ErrorFactory.createConfigError('GCS: client is missing file.getSignedUrl()');
|
|
146
|
+
}
|
|
147
|
+
const expires = Date.now() + expiresIn * 1000;
|
|
148
|
+
const [url] = await file.getSignedUrl({ version: 'v4', action, expires });
|
|
149
|
+
return url;
|
|
150
|
+
},
|
|
151
|
+
});
|
|
152
|
+
export default GcsDriver;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type LocalConfig = {
|
|
2
|
+
root: string;
|
|
3
|
+
url?: string;
|
|
4
|
+
};
|
|
5
|
+
export declare const LocalDriver: Readonly<{
|
|
6
|
+
put(config: LocalConfig, key: string, content: string | Buffer): Promise<string>;
|
|
7
|
+
get(config: LocalConfig, key: string): Promise<Buffer>;
|
|
8
|
+
exists(config: LocalConfig, key: string): Promise<boolean>;
|
|
9
|
+
delete(config: LocalConfig, key: string): Promise<void>;
|
|
10
|
+
url(config: LocalConfig, key: string): string | undefined;
|
|
11
|
+
tempUrl(config: LocalConfig, key: string, _options?: {
|
|
12
|
+
expiresIn?: number;
|
|
13
|
+
method?: "GET" | "PUT";
|
|
14
|
+
}): string;
|
|
15
|
+
}>;
|
|
16
|
+
export default LocalDriver;
|
|
17
|
+
//# sourceMappingURL=Local.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Local.d.ts","sourceRoot":"","sources":["../../../../../src/tools/storage/drivers/Local.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,eAAO,MAAM,WAAW;gBACJ,WAAW,OAAO,MAAM,WAAW,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;gBAkBpE,WAAW,OAAO,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;mBASvC,WAAW,OAAO,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;mBAU3C,WAAW,OAAO,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;gBAUjD,WAAW,OAAO,MAAM,GAAG,MAAM,GAAG,SAAS;oBAM/C,WAAW,OACd,MAAM,aACA;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,KAAK,GAAG,KAAK,CAAA;KAAE,GACxD,MAAM;EAST,CAAC;AAEH,eAAe,WAAW,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { ErrorFactory } from '../../../exceptions/ZintrustError';
|
|
2
|
+
import { fsPromises as fs } from '../../../node-singletons/fs';
|
|
3
|
+
import * as path from '../../../node-singletons/path';
|
|
4
|
+
export const LocalDriver = Object.freeze({
|
|
5
|
+
async put(config, key, content) {
|
|
6
|
+
const root = config.root;
|
|
7
|
+
if (!root || root.trim() === '') {
|
|
8
|
+
throw ErrorFactory.createConfigError('Local storage root is not configured');
|
|
9
|
+
}
|
|
10
|
+
const fullPath = path.join(root, key);
|
|
11
|
+
const dir = path.dirname(fullPath);
|
|
12
|
+
await fs.mkdir(dir, { recursive: true });
|
|
13
|
+
if (typeof content === 'string') {
|
|
14
|
+
await fs.writeFile(fullPath, content, 'utf8');
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
await fs.writeFile(fullPath, content);
|
|
18
|
+
}
|
|
19
|
+
return fullPath;
|
|
20
|
+
},
|
|
21
|
+
async get(config, key) {
|
|
22
|
+
const fullPath = path.join(config.root, key);
|
|
23
|
+
try {
|
|
24
|
+
return await fs.readFile(fullPath);
|
|
25
|
+
}
|
|
26
|
+
catch (err) {
|
|
27
|
+
throw ErrorFactory.createNotFoundError('Local storage: file not found', { key, error: err });
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
async exists(config, key) {
|
|
31
|
+
const fullPath = path.join(config.root, key);
|
|
32
|
+
try {
|
|
33
|
+
await fs.access(fullPath);
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
async delete(config, key) {
|
|
41
|
+
const fullPath = path.join(config.root, key);
|
|
42
|
+
try {
|
|
43
|
+
await fs.unlink(fullPath);
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
// ignore not found
|
|
47
|
+
void err; // NOSONAR
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
url(config, key) {
|
|
51
|
+
if (config?.url === undefined || config.url.trim() === '')
|
|
52
|
+
return undefined;
|
|
53
|
+
return `${config.url.replace(/\/$/, '')}/${key}`;
|
|
54
|
+
},
|
|
55
|
+
tempUrl(config, key, _options) {
|
|
56
|
+
const url = LocalDriver.url(config, key);
|
|
57
|
+
if (url === undefined) {
|
|
58
|
+
throw ErrorFactory.createConfigError('Local storage: url is not configured (set STORAGE_URL)');
|
|
59
|
+
}
|
|
60
|
+
return url;
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
export default LocalDriver;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type R2Config = {
|
|
2
|
+
bucket: string;
|
|
3
|
+
region?: string;
|
|
4
|
+
accessKeyId: string;
|
|
5
|
+
secretAccessKey: string;
|
|
6
|
+
endpoint?: string;
|
|
7
|
+
};
|
|
8
|
+
export declare const R2Driver: Readonly<{
|
|
9
|
+
put(config: R2Config, key: string, content: string | Buffer): Promise<string>;
|
|
10
|
+
get(config: R2Config, key: string): Promise<Buffer>;
|
|
11
|
+
exists(config: R2Config, key: string): Promise<boolean>;
|
|
12
|
+
delete(config: R2Config, key: string): Promise<void>;
|
|
13
|
+
url(config: R2Config, key: string): string;
|
|
14
|
+
tempUrl(config: R2Config, key: string, options?: {
|
|
15
|
+
expiresIn?: number;
|
|
16
|
+
method?: "GET" | "PUT";
|
|
17
|
+
}): string;
|
|
18
|
+
}>;
|
|
19
|
+
export default R2Driver;
|
|
20
|
+
//# sourceMappingURL=R2.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"R2.d.ts","sourceRoot":"","sources":["../../../../../src/tools/storage/drivers/R2.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,QAAQ,GAAG;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,eAAO,MAAM,QAAQ;gBACD,QAAQ,OAAO,MAAM,WAAW,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;gBAkBjE,QAAQ,OAAO,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;mBAapC,QAAQ,OAAO,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;mBAaxC,QAAQ,OAAO,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;gBAa9C,QAAQ,OAAO,MAAM,GAAG,MAAM;oBAQhC,QAAQ,OACX,MAAM,YACD;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,KAAK,GAAG,KAAK,CAAA;KAAE,GACvD,MAAM;EAgBT,CAAC;AAEH,eAAe,QAAQ,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { ErrorFactory } from '../../../exceptions/ZintrustError';
|
|
2
|
+
import { S3Driver } from '../drivers/S3';
|
|
3
|
+
export const R2Driver = Object.freeze({
|
|
4
|
+
async put(config, key, content) {
|
|
5
|
+
if (typeof config.endpoint !== 'string' || config.endpoint.trim() === '') {
|
|
6
|
+
throw ErrorFactory.createConfigError('R2: missing endpoint');
|
|
7
|
+
}
|
|
8
|
+
// Delegate to S3Driver using path-style endpoint
|
|
9
|
+
const s3Config = {
|
|
10
|
+
bucket: config.bucket,
|
|
11
|
+
region: config.region ?? 'auto',
|
|
12
|
+
accessKeyId: config.accessKeyId,
|
|
13
|
+
secretAccessKey: config.secretAccessKey,
|
|
14
|
+
endpoint: config.endpoint,
|
|
15
|
+
usePathStyle: true,
|
|
16
|
+
};
|
|
17
|
+
return S3Driver.put(s3Config, key, content);
|
|
18
|
+
},
|
|
19
|
+
async get(config, key) {
|
|
20
|
+
const s3Config = {
|
|
21
|
+
bucket: config.bucket,
|
|
22
|
+
region: config.region ?? 'auto',
|
|
23
|
+
accessKeyId: config.accessKeyId,
|
|
24
|
+
secretAccessKey: config.secretAccessKey,
|
|
25
|
+
endpoint: config.endpoint,
|
|
26
|
+
usePathStyle: true,
|
|
27
|
+
};
|
|
28
|
+
return S3Driver.get(s3Config, key);
|
|
29
|
+
},
|
|
30
|
+
async exists(config, key) {
|
|
31
|
+
const s3Config = {
|
|
32
|
+
bucket: config.bucket,
|
|
33
|
+
region: config.region ?? 'auto',
|
|
34
|
+
accessKeyId: config.accessKeyId,
|
|
35
|
+
secretAccessKey: config.secretAccessKey,
|
|
36
|
+
endpoint: config.endpoint,
|
|
37
|
+
usePathStyle: true,
|
|
38
|
+
};
|
|
39
|
+
return S3Driver.exists(s3Config, key);
|
|
40
|
+
},
|
|
41
|
+
async delete(config, key) {
|
|
42
|
+
const s3Config = {
|
|
43
|
+
bucket: config.bucket,
|
|
44
|
+
region: config.region ?? 'auto',
|
|
45
|
+
accessKeyId: config.accessKeyId,
|
|
46
|
+
secretAccessKey: config.secretAccessKey,
|
|
47
|
+
endpoint: config.endpoint,
|
|
48
|
+
usePathStyle: true,
|
|
49
|
+
};
|
|
50
|
+
return S3Driver.delete(s3Config, key);
|
|
51
|
+
},
|
|
52
|
+
url(config, key) {
|
|
53
|
+
if (config.endpoint !== undefined && config.endpoint.trim() !== '') {
|
|
54
|
+
return `${config.endpoint.replace(/\/$/, '')}/${config.bucket}/${key}`;
|
|
55
|
+
}
|
|
56
|
+
return `https://${config.bucket}.r2.cloudflarestorage.com/${key}`;
|
|
57
|
+
},
|
|
58
|
+
tempUrl(config, key, options) {
|
|
59
|
+
if (typeof config.endpoint !== 'string' || config.endpoint.trim() === '') {
|
|
60
|
+
throw ErrorFactory.createConfigError('R2: missing endpoint');
|
|
61
|
+
}
|
|
62
|
+
const s3Config = {
|
|
63
|
+
bucket: config.bucket,
|
|
64
|
+
region: config.region ?? 'auto',
|
|
65
|
+
accessKeyId: config.accessKeyId,
|
|
66
|
+
secretAccessKey: config.secretAccessKey,
|
|
67
|
+
endpoint: config.endpoint,
|
|
68
|
+
usePathStyle: true,
|
|
69
|
+
};
|
|
70
|
+
return S3Driver.tempUrl(s3Config, key, options);
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
export default R2Driver;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type S3Config = {
|
|
2
|
+
bucket: string;
|
|
3
|
+
region: string;
|
|
4
|
+
accessKeyId: string;
|
|
5
|
+
secretAccessKey: string;
|
|
6
|
+
endpoint?: string;
|
|
7
|
+
usePathStyle?: boolean;
|
|
8
|
+
};
|
|
9
|
+
export type GS3Cred = {
|
|
10
|
+
accessKeyId: string;
|
|
11
|
+
secretAccessKey: string;
|
|
12
|
+
sessionToken: string | undefined;
|
|
13
|
+
};
|
|
14
|
+
export declare const S3Driver: Readonly<{
|
|
15
|
+
put(config: S3Config, key: string, content: string | Buffer): Promise<string>;
|
|
16
|
+
get(config: S3Config, key: string): Promise<Buffer>;
|
|
17
|
+
exists(config: S3Config, key: string): Promise<boolean>;
|
|
18
|
+
delete(config: S3Config, key: string): Promise<void>;
|
|
19
|
+
url(config: S3Config, key: string): string;
|
|
20
|
+
tempUrl(config: S3Config, key: string, options?: {
|
|
21
|
+
expiresIn?: number;
|
|
22
|
+
method?: "GET" | "PUT";
|
|
23
|
+
}): string;
|
|
24
|
+
}>;
|
|
25
|
+
export default S3Driver;
|
|
26
|
+
//# sourceMappingURL=S3.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"S3.d.ts","sourceRoot":"","sources":["../../../../../src/tools/storage/drivers/S3.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,QAAQ,GAAG;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC,CAAC;AAwGF,eAAO,MAAM,QAAQ;gBACD,QAAQ,OAAO,MAAM,WAAW,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;gBA8CjE,QAAQ,OAAO,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;mBA0CpC,QAAQ,OAAO,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;mBAkCxC,QAAQ,OAAO,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;gBAoC9C,QAAQ,OAAO,MAAM,GAAG,MAAM;oBAOhC,QAAQ,OACX,MAAM,YACD;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,KAAK,GAAG,KAAK,CAAA;KAAE,GACvD,MAAM;EAqDT,CAAC;AAEH,eAAe,QAAQ,CAAC"}
|