@zintrust/core 0.1.1 → 0.1.3
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 +3 -3
- package/bin/zintrust.d.ts.map +1 -1
- package/bin/zintrust.js +18 -1
- package/package.json +15 -1
- 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 +6 -4
- package/src/cache/drivers/KVDriver.d.ts.map +1 -1
- package/src/cache/drivers/KVDriver.js +6 -6
- 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 +11 -4
- package/src/cli/commands/AddCommand.js +1 -1
- package/src/cli/commands/ConfigCommand.d.ts.map +1 -1
- package/src/cli/commands/ConfigCommand.js +34 -4
- 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 +4 -3
- package/src/cli/commands/FixCommand.d.ts.map +1 -1
- package/src/cli/commands/FixCommand.js +3 -16
- 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 +1 -1
- 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/NewCommand.d.ts +4 -0
- package/src/cli/commands/NewCommand.d.ts.map +1 -1
- package/src/cli/commands/NewCommand.js +33 -20
- 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 +11 -20
- 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.js +1 -1
- package/src/cli/scaffolding/FeatureScaffolder.js +4 -4
- package/src/cli/scaffolding/FileGenerator.js +1 -1
- package/src/cli/scaffolding/ModelGenerator.js +1 -1
- 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 +3 -2
- package/src/cli/scaffolding/RouteGenerator.js +1 -1
- package/src/cli/scaffolding/ServiceIntegrationTestGenerator.js +1 -1
- package/src/cli/scaffolding/ServiceScaffolder.js +2 -2
- 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 +37 -11
- 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/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/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/MicroserviceManager.d.ts.map +1 -1
- package/src/microservices/MicroserviceManager.js +9 -6
- package/src/microservices/PostgresAdapter.d.ts.map +1 -1
- package/src/microservices/PostgresAdapter.js +3 -1
- package/src/microservices/ServiceBundler.d.ts.map +1 -1
- package/src/microservices/ServiceBundler.js +6 -4
- package/src/microservices/ServiceHealthMonitor.js +2 -2
- 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/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 +150 -75
- 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 -6
- package/src/runtime/adapters/CloudflareAdapter.js +2 -2
- package/src/runtime/adapters/FargateAdapter.d.ts.map +1 -1
- package/src/runtime/adapters/FargateAdapter.js +2 -1
- 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 +2 -1
- 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 +155 -17
- 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 +44 -21
- 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 +11 -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/routes/storage.ts.tpl +42 -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 +49 -0
- package/src/tools/http/Http.d.ts.map +1 -0
- package/src/tools/http/Http.js +169 -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/LocalSignedUrl.d.ts +12 -0
- package/src/tools/storage/LocalSignedUrl.d.ts.map +1 -0
- package/src/tools/storage/LocalSignedUrl.js +108 -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 +18 -0
- package/src/tools/storage/drivers/Local.d.ts.map +1 -0
- package/src/tools/storage/drivers/Local.js +89 -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 +111 -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,13 @@
|
|
|
1
|
+
import { sendSms } from '@notification/drivers/Twilio';
|
|
2
|
+
|
|
3
|
+
export async function sendSmsNotification(
|
|
4
|
+
accountSid: string,
|
|
5
|
+
authToken: string,
|
|
6
|
+
from: string,
|
|
7
|
+
to: string,
|
|
8
|
+
body: string
|
|
9
|
+
): Promise<void> {
|
|
10
|
+
await sendSms({ accountSid, authToken, from }, { to, body });
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export default Object.freeze({ sendSmsNotification });
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FileLogWriter (Node.js only)
|
|
3
|
+
*
|
|
4
|
+
* Provides best-effort file logging with daily + size-based rotation.
|
|
5
|
+
* This module imports Node built-ins and should be loaded only in Node environments.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { ensureDirSafe } from '@common/index';
|
|
9
|
+
import { Env } from '@config/env';
|
|
10
|
+
import * as fs from '@node-singletons/fs';
|
|
11
|
+
import * as path from '@node-singletons/path';
|
|
12
|
+
|
|
13
|
+
const getCwdSafe = (): string => {
|
|
14
|
+
try {
|
|
15
|
+
if (typeof process === 'undefined' || typeof process.cwd !== 'function') return '';
|
|
16
|
+
return process.cwd();
|
|
17
|
+
} catch {
|
|
18
|
+
return '';
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const getDateStr = (d: Date): string => d.toISOString().slice(0, 10);
|
|
23
|
+
|
|
24
|
+
const isAppLogFile = (fileName: string): boolean =>
|
|
25
|
+
fileName.startsWith('app-') && fileName.endsWith('.log');
|
|
26
|
+
|
|
27
|
+
const parseDateFromLogFilename = (fileName: string): number | null => {
|
|
28
|
+
const match = /^app-(\d{4}-\d{2}-\d{2})(?:-\d+)?\.log$/.exec(fileName);
|
|
29
|
+
if (match?.[1] === undefined) return null;
|
|
30
|
+
|
|
31
|
+
const parsed = Date.parse(`${match[1]}T00:00:00.000Z`);
|
|
32
|
+
return Number.isNaN(parsed) ? null : parsed;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const isOlderThanCutoffByMtime = (fullPath: string, cutoff: number): boolean => {
|
|
36
|
+
try {
|
|
37
|
+
const stat = fs.statSync(fullPath);
|
|
38
|
+
return stat.mtime.getTime() < cutoff;
|
|
39
|
+
} catch {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const safeUnlink = (fullPath: string): void => {
|
|
45
|
+
try {
|
|
46
|
+
fs.unlinkSync(fullPath);
|
|
47
|
+
} catch {
|
|
48
|
+
// best-effort
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const readDirSafe = (dirPath: string): string[] => {
|
|
53
|
+
try {
|
|
54
|
+
return fs.readdirSync(dirPath);
|
|
55
|
+
} catch {
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const shouldDeleteLogFile = (fileName: string, fullPath: string, cutoff: number): boolean => {
|
|
61
|
+
const parsed = parseDateFromLogFilename(fileName);
|
|
62
|
+
if (parsed !== null) return parsed < cutoff;
|
|
63
|
+
|
|
64
|
+
return isOlderThanCutoffByMtime(fullPath, cutoff);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const cleanupOldLogs = (logsDir: string, keepDays: number): void => {
|
|
68
|
+
if (keepDays <= 0) return;
|
|
69
|
+
|
|
70
|
+
const cutoff = Date.now() - keepDays * 24 * 60 * 60 * 1000;
|
|
71
|
+
const files = readDirSafe(logsDir);
|
|
72
|
+
if (files.length === 0) return;
|
|
73
|
+
|
|
74
|
+
for (const fileName of files) {
|
|
75
|
+
if (!isAppLogFile(fileName)) continue;
|
|
76
|
+
|
|
77
|
+
const fullPath = path.join(logsDir, fileName);
|
|
78
|
+
if (!shouldDeleteLogFile(fileName, fullPath, cutoff)) continue;
|
|
79
|
+
|
|
80
|
+
safeUnlink(fullPath);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
type CleanOnceOptions = {
|
|
85
|
+
logsDir?: string;
|
|
86
|
+
keepDays?: number;
|
|
87
|
+
maxTotalSize?: number;
|
|
88
|
+
keepFiles?: number;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const listAppLogFiles = (
|
|
92
|
+
logsDir: string,
|
|
93
|
+
order: 'newest-first' | 'oldest-first'
|
|
94
|
+
): Array<{ name: string; path: string }> => {
|
|
95
|
+
const files = readDirSafe(logsDir)
|
|
96
|
+
.filter((f) => isAppLogFile(f))
|
|
97
|
+
.map((f) => ({ name: f, path: path.join(logsDir, f) }));
|
|
98
|
+
|
|
99
|
+
return files.sort((a, b) => {
|
|
100
|
+
if (a.name === b.name) return 0;
|
|
101
|
+
const newerFirst = a.name < b.name ? 1 : -1;
|
|
102
|
+
return order === 'newest-first' ? newerFirst : -newerFirst;
|
|
103
|
+
});
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const enforceKeepFilesPolicy = (
|
|
107
|
+
filesNewestFirst: Array<{ name: string; path: string }>,
|
|
108
|
+
keepFiles: number | undefined,
|
|
109
|
+
deleted: string[]
|
|
110
|
+
): void => {
|
|
111
|
+
if (typeof keepFiles !== 'number' || keepFiles < 0) return;
|
|
112
|
+
if (filesNewestFirst.length <= keepFiles) return;
|
|
113
|
+
|
|
114
|
+
const toDelete = filesNewestFirst.slice(keepFiles);
|
|
115
|
+
for (const f of toDelete) {
|
|
116
|
+
safeUnlink(f.path);
|
|
117
|
+
deleted.push(f.path);
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
const getFileSizesTotal = (
|
|
122
|
+
filesOldestFirst: Array<{ name: string; path: string }>
|
|
123
|
+
): { total: number; sizes: Array<{ path: string; size: number }> } => {
|
|
124
|
+
let total = 0;
|
|
125
|
+
const sizes: Array<{ path: string; size: number }> = [];
|
|
126
|
+
|
|
127
|
+
for (const file of filesOldestFirst) {
|
|
128
|
+
try {
|
|
129
|
+
const stat = fs.statSync(file.path);
|
|
130
|
+
sizes.push({ path: file.path, size: stat.size });
|
|
131
|
+
total += stat.size;
|
|
132
|
+
} catch {
|
|
133
|
+
// ignore
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return { total, sizes };
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
const deleteOldestUntilWithinLimit = (
|
|
141
|
+
sizesOldestFirst: Array<{ path: string; size: number }>,
|
|
142
|
+
maxTotalSize: number,
|
|
143
|
+
deleted: string[],
|
|
144
|
+
initialTotal: number
|
|
145
|
+
): void => {
|
|
146
|
+
let total = initialTotal;
|
|
147
|
+
|
|
148
|
+
let idx = 0;
|
|
149
|
+
while (total > maxTotalSize && idx < sizesOldestFirst.length) {
|
|
150
|
+
const del = sizesOldestFirst[idx];
|
|
151
|
+
safeUnlink(del.path);
|
|
152
|
+
deleted.push(del.path);
|
|
153
|
+
total -= del.size;
|
|
154
|
+
idx++;
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
const enforceMaxTotalSizePolicy = (
|
|
159
|
+
logsDir: string,
|
|
160
|
+
maxTotalSize: number | undefined,
|
|
161
|
+
deleted: string[]
|
|
162
|
+
): void => {
|
|
163
|
+
if (typeof maxTotalSize !== 'number' || maxTotalSize <= 0) return;
|
|
164
|
+
|
|
165
|
+
const remainingOldestFirst = listAppLogFiles(logsDir, 'oldest-first');
|
|
166
|
+
const { total, sizes } = getFileSizesTotal(remainingOldestFirst);
|
|
167
|
+
deleteOldestUntilWithinLimit(sizes, maxTotalSize, deleted, total);
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Clean log files with additional retention policies.
|
|
172
|
+
* Returns an array of deleted file paths for auditing/tests.
|
|
173
|
+
*/
|
|
174
|
+
export const cleanOnce = (options?: CleanOnceOptions): string[] => {
|
|
175
|
+
const cwd = getCwdSafe();
|
|
176
|
+
if (cwd === '') return [];
|
|
177
|
+
|
|
178
|
+
const logsDir = options?.logsDir ?? path.join(cwd, 'logs');
|
|
179
|
+
const keepDays = options?.keepDays ?? Env.LOG_ROTATION_DAYS;
|
|
180
|
+
const maxTotalSize = options?.maxTotalSize ?? Env.getInt('LOG_MAX_TOTAL_SIZE', 0);
|
|
181
|
+
const keepFiles = options?.keepFiles ?? Env.getInt('LOG_KEEP_FILES', 0);
|
|
182
|
+
|
|
183
|
+
// Step 1: delete by age
|
|
184
|
+
cleanupOldLogs(logsDir, keepDays);
|
|
185
|
+
|
|
186
|
+
const deleted: string[] = [];
|
|
187
|
+
|
|
188
|
+
// Step 2: enforce keepFiles (keep newest N files)
|
|
189
|
+
const filesNewestFirst = listAppLogFiles(logsDir, 'newest-first');
|
|
190
|
+
enforceKeepFilesPolicy(filesNewestFirst, keepFiles, deleted);
|
|
191
|
+
|
|
192
|
+
// Step 3: enforce max total size
|
|
193
|
+
enforceMaxTotalSizePolicy(logsDir, maxTotalSize, deleted);
|
|
194
|
+
|
|
195
|
+
return deleted;
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
const rotateIfNeeded = (logFile: string, maxSizeBytes: number): void => {
|
|
199
|
+
if (maxSizeBytes <= 0) return;
|
|
200
|
+
|
|
201
|
+
try {
|
|
202
|
+
if (!fs.existsSync(logFile)) return;
|
|
203
|
+
|
|
204
|
+
const stat = fs.statSync(logFile);
|
|
205
|
+
if (stat.size <= maxSizeBytes) return;
|
|
206
|
+
|
|
207
|
+
const ext = '.log';
|
|
208
|
+
const base = logFile.endsWith(ext) ? logFile.slice(0, -ext.length) : logFile;
|
|
209
|
+
const rotated = `${base}-${Date.now()}${ext}`;
|
|
210
|
+
fs.renameSync(logFile, rotated);
|
|
211
|
+
} catch {
|
|
212
|
+
// best-effort
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
export const FileLogWriter = Object.freeze({
|
|
217
|
+
write(line: string): void {
|
|
218
|
+
const cwd = getCwdSafe();
|
|
219
|
+
if (cwd === '') return;
|
|
220
|
+
|
|
221
|
+
const logsDir = path.join(cwd, 'logs');
|
|
222
|
+
ensureDirSafe(logsDir);
|
|
223
|
+
|
|
224
|
+
const dateStr = getDateStr(new Date());
|
|
225
|
+
const logFile = path.join(logsDir, `app-${dateStr}.log`);
|
|
226
|
+
|
|
227
|
+
rotateIfNeeded(logFile, Env.LOG_ROTATION_SIZE);
|
|
228
|
+
|
|
229
|
+
try {
|
|
230
|
+
fs.appendFileSync(logFile, `${line}\n`);
|
|
231
|
+
} catch {
|
|
232
|
+
// best-effort
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
cleanupOldLogs(logsDir, Env.LOG_ROTATION_DAYS);
|
|
237
|
+
},
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
export default FileLogWriter;
|
|
@@ -38,6 +38,25 @@ interface SecretsManagerInstance {
|
|
|
38
38
|
clearCache(key?: string): void;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
function pruneCache(
|
|
42
|
+
cache: Map<string, { value: string; expiresAt: number }>,
|
|
43
|
+
maxEntries: number
|
|
44
|
+
): void {
|
|
45
|
+
if (cache.size <= maxEntries) return;
|
|
46
|
+
|
|
47
|
+
const now = Date.now();
|
|
48
|
+
for (const [key, entry] of cache.entries()) {
|
|
49
|
+
if (entry.expiresAt <= now) cache.delete(key);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// If still large, drop oldest entries (Map preserves insertion order)
|
|
53
|
+
while (cache.size > maxEntries) {
|
|
54
|
+
const next = cache.keys().next();
|
|
55
|
+
if (next.done === true) break;
|
|
56
|
+
cache.delete(next.value);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
41
60
|
/**
|
|
42
61
|
* Get secret value from appropriate backend
|
|
43
62
|
*/
|
|
@@ -53,6 +72,9 @@ async function runGetSecret(
|
|
|
53
72
|
return cached.value;
|
|
54
73
|
}
|
|
55
74
|
|
|
75
|
+
// Opportunistic cleanup if cache has grown
|
|
76
|
+
pruneCache(cache, 500);
|
|
77
|
+
|
|
56
78
|
let value: string;
|
|
57
79
|
|
|
58
80
|
switch (config.platform) {
|
|
@@ -77,6 +99,8 @@ async function runGetSecret(
|
|
|
77
99
|
expiresAt: Date.now() + ttl,
|
|
78
100
|
});
|
|
79
101
|
|
|
102
|
+
pruneCache(cache, 500);
|
|
103
|
+
|
|
80
104
|
return value;
|
|
81
105
|
}
|
|
82
106
|
|
|
@@ -169,14 +193,13 @@ const SecretsManagerImpl = {
|
|
|
169
193
|
/**
|
|
170
194
|
* Rotate secret (trigger new secret generation)
|
|
171
195
|
*/
|
|
196
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
172
197
|
async rotateSecret(_key: string): Promise<void> {
|
|
173
198
|
if (config.platform === 'aws') {
|
|
174
199
|
// AWS Secrets Manager supports automatic rotation
|
|
175
|
-
|
|
200
|
+
throw ErrorFactory.createConfigError('Secret rotation not implemented');
|
|
176
201
|
}
|
|
177
|
-
|
|
178
|
-
ErrorFactory.createConfigError('Secret rotation not supported on this platform')
|
|
179
|
-
);
|
|
202
|
+
throw ErrorFactory.createConfigError('Secret rotation not supported on this platform');
|
|
180
203
|
},
|
|
181
204
|
|
|
182
205
|
/**
|
|
@@ -191,7 +214,7 @@ const SecretsManagerImpl = {
|
|
|
191
214
|
case 'deno':
|
|
192
215
|
case 'local':
|
|
193
216
|
default:
|
|
194
|
-
return
|
|
217
|
+
return [];
|
|
195
218
|
}
|
|
196
219
|
},
|
|
197
220
|
|
|
@@ -212,41 +235,39 @@ const SecretsManagerImpl = {
|
|
|
212
235
|
/**
|
|
213
236
|
* AWS Secrets Manager integration
|
|
214
237
|
*/
|
|
238
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
215
239
|
async function getFromAWSSecretsManager(key: string): Promise<string> {
|
|
216
240
|
try {
|
|
217
241
|
Logger.debug(`[AWS] Getting secret: ${key}`);
|
|
218
242
|
throw ErrorFactory.createConfigError('AWS SDK not available in core - use wrapper module');
|
|
219
243
|
} catch (error) {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
error
|
|
224
|
-
)
|
|
244
|
+
throw ErrorFactory.createTryCatchError(
|
|
245
|
+
`Failed to retrieve secret from AWS: ${(error as Error).message}`,
|
|
246
|
+
error
|
|
225
247
|
);
|
|
226
248
|
}
|
|
227
249
|
}
|
|
228
250
|
|
|
251
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
229
252
|
async function setInAWSSecretsManager(
|
|
230
253
|
key: string,
|
|
231
254
|
_value: string,
|
|
232
255
|
_options?: SetSecretOptions
|
|
233
256
|
): Promise<void> {
|
|
234
257
|
Logger.info(`[AWS] Setting secret: ${key}`);
|
|
235
|
-
|
|
236
|
-
ErrorFactory.createConfigError('AWS SDK not available in core - use wrapper module')
|
|
237
|
-
);
|
|
258
|
+
throw ErrorFactory.createConfigError('AWS SDK not available in core - use wrapper module');
|
|
238
259
|
}
|
|
239
260
|
|
|
261
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
240
262
|
async function deleteFromAWSSecretsManager(key: string): Promise<void> {
|
|
241
263
|
Logger.info(`[AWS] Deleting secret: ${key}`);
|
|
242
|
-
|
|
243
|
-
ErrorFactory.createConfigError('AWS SDK not available in core - use wrapper module')
|
|
244
|
-
);
|
|
264
|
+
throw ErrorFactory.createConfigError('AWS SDK not available in core - use wrapper module');
|
|
245
265
|
}
|
|
246
266
|
|
|
267
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
247
268
|
async function listFromAWSSecretsManager(pattern?: string): Promise<string[]> {
|
|
248
269
|
Logger.info(`[AWS] Listing secrets with pattern: ${pattern ?? '*'}`);
|
|
249
|
-
return
|
|
270
|
+
return [];
|
|
250
271
|
}
|
|
251
272
|
|
|
252
273
|
/**
|
|
@@ -294,25 +315,27 @@ async function listFromCloudflareKV(config: SecretConfig, pattern?: string): Pro
|
|
|
294
315
|
/**
|
|
295
316
|
* Deno environment integration
|
|
296
317
|
*/
|
|
318
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
297
319
|
async function getFromDenoEnv(key: string): Promise<string> {
|
|
298
320
|
const value = (
|
|
299
321
|
globalThis as unknown as Record<string, { env?: { get?: (key: string) => string } }>
|
|
300
322
|
)['Deno']?.env?.get?.(key);
|
|
301
323
|
if (value === undefined || value === null || value === '') {
|
|
302
|
-
|
|
324
|
+
throw ErrorFactory.createNotFoundError(`Secret not found: ${key}`, { key });
|
|
303
325
|
}
|
|
304
|
-
return
|
|
326
|
+
return value;
|
|
305
327
|
}
|
|
306
328
|
|
|
307
329
|
/**
|
|
308
330
|
* Local environment variables (Node.js)
|
|
309
331
|
*/
|
|
332
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
310
333
|
async function getFromEnv(key: string): Promise<string> {
|
|
311
334
|
const value = process.env[key];
|
|
312
335
|
if (value === undefined || value === null || value === '') {
|
|
313
|
-
|
|
336
|
+
throw ErrorFactory.createNotFoundError(`Secret not found: ${key}`, { key });
|
|
314
337
|
}
|
|
315
|
-
return
|
|
338
|
+
return value;
|
|
316
339
|
}
|
|
317
340
|
|
|
318
341
|
/**
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { appConfig } from '@config/app';
|
|
2
|
+
import { ErrorFactory } from '@exceptions/ZintrustError';
|
|
3
|
+
|
|
4
|
+
export type StartupConfigValidationError = {
|
|
5
|
+
key: string;
|
|
6
|
+
value: unknown;
|
|
7
|
+
message: string;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export type StartupConfigValidationResult = {
|
|
11
|
+
valid: boolean;
|
|
12
|
+
errors: StartupConfigValidationError[];
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const isSensitiveKey = (key: string): boolean => {
|
|
16
|
+
const normalized = key.toLowerCase();
|
|
17
|
+
return (
|
|
18
|
+
normalized.includes('password') ||
|
|
19
|
+
normalized.includes('secret') ||
|
|
20
|
+
normalized.includes('token') ||
|
|
21
|
+
normalized.includes('key') ||
|
|
22
|
+
normalized.includes('authorization')
|
|
23
|
+
);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const redactValue = (key: string, value: unknown): unknown => {
|
|
27
|
+
return isSensitiveKey(key) ? '<redacted>' : value;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const pushError = (
|
|
31
|
+
errors: StartupConfigValidationError[],
|
|
32
|
+
key: string,
|
|
33
|
+
value: unknown,
|
|
34
|
+
message: string
|
|
35
|
+
): void => {
|
|
36
|
+
errors.push({ key, value: redactValue(key, value), message });
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const validateEnum = (
|
|
40
|
+
errors: StartupConfigValidationError[],
|
|
41
|
+
key: string,
|
|
42
|
+
value: string,
|
|
43
|
+
allowed: readonly string[]
|
|
44
|
+
): void => {
|
|
45
|
+
if (!allowed.includes(value)) {
|
|
46
|
+
pushError(errors, key, value, `${key} must be one of: ${allowed.join(', ')}`);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const validateIntRange = (
|
|
51
|
+
errors: StartupConfigValidationError[],
|
|
52
|
+
key: string,
|
|
53
|
+
value: number,
|
|
54
|
+
min: number,
|
|
55
|
+
max: number
|
|
56
|
+
): void => {
|
|
57
|
+
if (Number.isNaN(value)) {
|
|
58
|
+
pushError(errors, key, value, `${key} must be a valid integer`);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (value < min || value > max) {
|
|
63
|
+
pushError(errors, key, value, `${key} must be between ${min} and ${max}`);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const validatePositiveInt = (
|
|
68
|
+
errors: StartupConfigValidationError[],
|
|
69
|
+
key: string,
|
|
70
|
+
value: number
|
|
71
|
+
): void => {
|
|
72
|
+
if (Number.isNaN(value)) {
|
|
73
|
+
pushError(errors, key, value, `${key} must be a valid integer`);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (value <= 0) {
|
|
78
|
+
pushError(errors, key, value, `${key} must be greater than 0`);
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
type ProcessLike = {
|
|
83
|
+
env?: Record<string, string | undefined>;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const getProcessLike = (): ProcessLike | undefined => {
|
|
87
|
+
return typeof process === 'undefined' ? undefined : (process as unknown as ProcessLike);
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const getEnvString = (key: string, defaultValue: string): string => {
|
|
91
|
+
const proc = getProcessLike();
|
|
92
|
+
const env = proc?.env ?? {};
|
|
93
|
+
return env[key] ?? defaultValue;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const getEnvInt = (key: string, defaultValue: number): number => {
|
|
97
|
+
const raw = getEnvString(key, String(defaultValue));
|
|
98
|
+
return Number.parseInt(raw, 10);
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
export const StartupConfigValidator = Object.freeze({
|
|
102
|
+
validate(): StartupConfigValidationResult {
|
|
103
|
+
const errors: StartupConfigValidationError[] = [];
|
|
104
|
+
|
|
105
|
+
const nodeEnv = getEnvString('NODE_ENV', 'development');
|
|
106
|
+
validateEnum(errors, 'NODE_ENV', nodeEnv, ['development', 'production', 'testing', 'test']);
|
|
107
|
+
|
|
108
|
+
const appPort = getEnvInt('APP_PORT', 3000);
|
|
109
|
+
validateIntRange(errors, 'APP_PORT', appPort, 1, 65535);
|
|
110
|
+
|
|
111
|
+
const logFormat = getEnvString('LOG_FORMAT', 'text');
|
|
112
|
+
validateEnum(errors, 'LOG_FORMAT', logFormat, ['text', 'json']);
|
|
113
|
+
|
|
114
|
+
const logLevel = getEnvString('LOG_LEVEL', 'debug');
|
|
115
|
+
validateEnum(errors, 'LOG_LEVEL', logLevel, ['debug', 'info', 'warn', 'error']);
|
|
116
|
+
|
|
117
|
+
const logRotationSize = getEnvInt('LOG_ROTATION_SIZE', 10485760);
|
|
118
|
+
validatePositiveInt(errors, 'LOG_ROTATION_SIZE', logRotationSize);
|
|
119
|
+
|
|
120
|
+
const logRotationDays = getEnvInt('LOG_ROTATION_DAYS', 7);
|
|
121
|
+
validatePositiveInt(errors, 'LOG_ROTATION_DAYS', logRotationDays);
|
|
122
|
+
|
|
123
|
+
const startupHealthTimeoutMs = getEnvInt('STARTUP_HEALTH_TIMEOUT_MS', 2500);
|
|
124
|
+
validatePositiveInt(errors, 'STARTUP_HEALTH_TIMEOUT_MS', startupHealthTimeoutMs);
|
|
125
|
+
|
|
126
|
+
if (appConfig.isProduction()) {
|
|
127
|
+
const appKey = getEnvString('APP_KEY', '');
|
|
128
|
+
if (appKey.trim().length < 16) {
|
|
129
|
+
pushError(
|
|
130
|
+
errors,
|
|
131
|
+
'APP_KEY',
|
|
132
|
+
appKey,
|
|
133
|
+
'APP_KEY must be set and at least 16 characters in production'
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return { valid: errors.length === 0, errors };
|
|
139
|
+
},
|
|
140
|
+
|
|
141
|
+
assertValid(): void {
|
|
142
|
+
const result = StartupConfigValidator.validate();
|
|
143
|
+
if (result.valid) return;
|
|
144
|
+
|
|
145
|
+
throw ErrorFactory.createConfigError('Invalid startup configuration', {
|
|
146
|
+
errors: result.errors,
|
|
147
|
+
});
|
|
148
|
+
},
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
export default StartupConfigValidator;
|