@zintrust/core 0.1.39 → 0.1.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/zintrust-main.d.ts.map +1 -1
- package/bin/zintrust-main.js +22 -1
- package/package.json +8 -4
- package/public/error-pages/404.html +2 -2
- package/src/auth/Auth.js +1 -1
- package/src/boot/Application.d.ts +1 -16
- package/src/boot/Application.d.ts.map +1 -1
- package/src/boot/Application.js +2 -262
- package/src/boot/Server.d.ts +1 -1
- package/src/boot/Server.d.ts.map +1 -1
- package/src/boot/bootstrap.js +23 -9
- package/src/boot/registry/registerRoute.d.ts +6 -0
- package/src/boot/registry/registerRoute.d.ts.map +1 -0
- package/src/boot/registry/registerRoute.js +96 -0
- package/src/boot/registry/runtime.d.ts +15 -0
- package/src/boot/registry/runtime.d.ts.map +1 -0
- package/src/boot/registry/runtime.js +353 -0
- package/src/boot/registry/type.d.ts +25 -0
- package/src/boot/registry/type.d.ts.map +1 -0
- package/src/boot/registry/type.js +1 -0
- package/src/boot/registry/worker.d.ts +6 -0
- package/src/boot/registry/worker.d.ts.map +1 -0
- package/src/boot/registry/worker.js +35 -0
- package/src/cache/drivers/KVRemoteDriver.d.ts.map +1 -1
- package/src/cache/drivers/KVRemoteDriver.js +14 -1
- package/src/cli/CLI.d.ts.map +1 -1
- package/src/cli/CLI.js +82 -34
- package/src/cli/ErrorHandler.js +1 -1
- package/src/cli/commands/ContainerProxiesCommand.d.ts +5 -0
- package/src/cli/commands/ContainerProxiesCommand.d.ts.map +1 -0
- package/src/cli/commands/ContainerProxiesCommand.js +77 -0
- package/src/cli/commands/ContainerWorkersCommand.d.ts +5 -0
- package/src/cli/commands/ContainerWorkersCommand.d.ts.map +1 -0
- package/src/cli/commands/ContainerWorkersCommand.js +57 -0
- package/src/cli/commands/DeployCommand.d.ts +16 -0
- package/src/cli/commands/DeployCommand.d.ts.map +1 -0
- package/src/cli/commands/DeployCommand.js +110 -0
- package/src/cli/commands/DeployContainerProxiesCommand.d.ts +5 -0
- package/src/cli/commands/DeployContainerProxiesCommand.d.ts.map +1 -0
- package/src/cli/commands/DeployContainerProxiesCommand.js +27 -0
- package/src/cli/commands/DeployContainerWorkersCommand.d.ts +5 -0
- package/src/cli/commands/DeployContainerWorkersCommand.d.ts.map +1 -0
- package/src/cli/commands/DeployContainerWorkersCommand.js +27 -0
- package/src/cli/commands/DockerComposeCommandUtils.d.ts +3 -0
- package/src/cli/commands/DockerComposeCommandUtils.d.ts.map +1 -0
- package/src/cli/commands/DockerComposeCommandUtils.js +34 -0
- package/src/cli/commands/DoctorArchitectureCommand.d.ts +5 -0
- package/src/cli/commands/DoctorArchitectureCommand.d.ts.map +1 -0
- package/src/cli/commands/DoctorArchitectureCommand.js +54 -0
- package/src/cli/commands/InitContainerCommand.d.ts +5 -0
- package/src/cli/commands/InitContainerCommand.d.ts.map +1 -0
- package/src/cli/commands/InitContainerCommand.js +216 -0
- package/src/cli/commands/InitProducerCommand.d.ts +5 -0
- package/src/cli/commands/InitProducerCommand.d.ts.map +1 -0
- package/src/cli/commands/InitProducerCommand.js +47 -0
- package/src/cli/commands/InitProxyCommand.d.ts +5 -0
- package/src/cli/commands/InitProxyCommand.d.ts.map +1 -0
- package/src/cli/commands/InitProxyCommand.js +442 -0
- package/src/cli/commands/MongoDBProxyCommand.d.ts +5 -0
- package/src/cli/commands/MongoDBProxyCommand.d.ts.map +1 -0
- package/src/cli/commands/MongoDBProxyCommand.js +98 -0
- package/src/cli/commands/MySqlProxyCommand.d.ts +6 -0
- package/src/cli/commands/MySqlProxyCommand.d.ts.map +1 -0
- package/src/cli/commands/MySqlProxyCommand.js +32 -0
- package/src/cli/commands/PostgresProxyCommand.d.ts +6 -0
- package/src/cli/commands/PostgresProxyCommand.d.ts.map +1 -0
- package/src/cli/commands/PostgresProxyCommand.js +32 -0
- package/src/cli/commands/ProxyCommand.d.ts +12 -0
- package/src/cli/commands/ProxyCommand.d.ts.map +1 -0
- package/src/cli/commands/ProxyCommand.js +80 -0
- package/src/cli/commands/ProxyCommandUtils.d.ts +6 -0
- package/src/cli/commands/ProxyCommandUtils.d.ts.map +1 -0
- package/src/cli/commands/ProxyCommandUtils.js +38 -0
- package/src/cli/commands/QueueRecoveryCommand.d.ts +6 -0
- package/src/cli/commands/QueueRecoveryCommand.d.ts.map +1 -0
- package/src/cli/commands/QueueRecoveryCommand.js +513 -0
- package/src/cli/commands/RedisProxyCommand.d.ts +6 -0
- package/src/cli/commands/RedisProxyCommand.d.ts.map +1 -0
- package/src/cli/commands/RedisProxyCommand.js +53 -0
- package/src/cli/commands/SmtpProxyCommand.d.ts +6 -0
- package/src/cli/commands/SmtpProxyCommand.d.ts.map +1 -0
- package/src/cli/commands/SmtpProxyCommand.js +56 -0
- package/src/cli/commands/SqlProxyCommandUtils.d.ts +46 -0
- package/src/cli/commands/SqlProxyCommandUtils.d.ts.map +1 -0
- package/src/cli/commands/SqlProxyCommandUtils.js +48 -0
- package/src/cli/commands/SqlServerProxyCommand.d.ts +5 -0
- package/src/cli/commands/SqlServerProxyCommand.d.ts.map +1 -0
- package/src/cli/commands/SqlServerProxyCommand.js +85 -0
- package/src/cli/commands/StartCommand.d.ts.map +1 -1
- package/src/cli/commands/StartCommand.js +145 -18
- package/src/cli/commands/WorkerCommands.d.ts +1 -0
- package/src/cli/commands/WorkerCommands.d.ts.map +1 -1
- package/src/cli/commands/WorkerCommands.js +140 -6
- package/src/cli/commands/index.d.ts +2 -0
- package/src/cli/commands/index.d.ts.map +1 -1
- package/src/cli/commands/index.js +2 -0
- package/src/cli/commands/runner/index.d.ts +2 -2
- package/src/cli/commands/runner/index.d.ts.map +1 -1
- package/src/cli/commands/runner/index.js +15 -4
- package/src/cli/d1/D1SqlMigrations.d.ts.map +1 -1
- package/src/cli/d1/D1SqlMigrations.js +3 -0
- package/src/cli/index.d.ts +4 -0
- package/src/cli/index.d.ts.map +1 -1
- package/src/cli/index.js +4 -0
- package/src/cli/scaffolding/ProjectScaffolder.d.ts.map +1 -1
- package/src/cli/scaffolding/ProjectScaffolder.js +2 -0
- package/src/cli/scaffolding/ServiceScaffolder.d.ts.map +1 -1
- package/src/cli/scaffolding/ServiceScaffolder.js +1 -0
- package/src/cli/utils/EnvFileLoader.d.ts +2 -1
- package/src/cli/utils/EnvFileLoader.d.ts.map +1 -1
- package/src/cli/utils/EnvFileLoader.js +22 -21
- package/src/cli/utils/spawn.d.ts.map +1 -1
- package/src/cli/utils/spawn.js +17 -10
- package/src/cli/workers/QueueWorkRunner.js +1 -1
- package/src/common/ExternalServiceUtils.d.ts.map +1 -1
- package/src/common/ExternalServiceUtils.js +7 -2
- package/src/common/HealthRoutes.d.ts.map +1 -1
- package/src/common/HealthRoutes.js +50 -2
- package/src/common/RemoteSignedJson.d.ts +1 -0
- package/src/common/RemoteSignedJson.d.ts.map +1 -1
- package/src/common/RemoteSignedJson.js +39 -13
- package/src/common/index.d.ts +1 -0
- package/src/common/index.d.ts.map +1 -1
- package/src/common/index.js +12 -1
- package/src/config/FileLogWriter.d.ts.map +1 -1
- package/src/config/FileLogWriter.js +21 -6
- package/src/config/app.d.ts +4 -0
- package/src/config/app.d.ts.map +1 -1
- package/src/config/app.js +4 -0
- package/src/config/cache.d.ts.map +1 -1
- package/src/config/cache.js +22 -2
- package/src/config/cloudflare.d.ts +5 -1
- package/src/config/cloudflare.d.ts.map +1 -1
- package/src/config/cloudflare.js +48 -0
- package/src/config/database.d.ts.map +1 -1
- package/src/config/database.js +48 -13
- package/src/config/env.d.ts +90 -2
- package/src/config/env.d.ts.map +1 -1
- package/src/config/env.js +160 -18
- package/src/config/index.d.ts +1 -0
- package/src/config/index.d.ts.map +1 -1
- package/src/config/logger.d.ts.map +1 -1
- package/src/config/logger.js +60 -16
- package/src/config/mail.d.ts.map +1 -1
- package/src/config/mail.js +16 -10
- package/src/config/middleware.d.ts +5 -0
- package/src/config/middleware.d.ts.map +1 -1
- package/src/config/middleware.js +19 -1
- package/src/config/queue.d.ts.map +1 -1
- package/src/config/queue.js +70 -9
- package/src/config/redis.d.ts.map +1 -1
- package/src/config/redis.js +48 -13
- package/src/config/storage.d.ts.map +1 -1
- package/src/config/storage.js +1 -0
- package/src/config/type.d.ts +19 -0
- package/src/config/type.d.ts.map +1 -1
- package/src/config/workers.d.ts.map +1 -1
- package/src/config/workers.js +122 -16
- package/src/functions/cloudflare.d.ts.map +1 -1
- package/src/functions/cloudflare.js +55 -1
- package/src/health/StartupHealthChecks.js +1 -1
- package/src/http/FileUpload.d.ts +3 -2
- package/src/http/FileUpload.d.ts.map +1 -1
- package/src/http/Kernel.d.ts.map +1 -1
- package/src/http/Kernel.js +2 -1
- package/src/http/error-pages/ErrorPageRenderer.d.ts +4 -0
- package/src/http/error-pages/ErrorPageRenderer.d.ts.map +1 -1
- package/src/http/error-pages/ErrorPageRenderer.js +141 -1
- package/src/http/middleware/BodyParsingMiddleware.d.ts.map +1 -1
- package/src/http/middleware/BodyParsingMiddleware.js +33 -6
- package/src/index.d.ts +25 -53
- package/src/index.d.ts.map +1 -1
- package/src/index.js +30 -14
- package/src/microservices/ServiceAuthMiddleware.d.ts.map +1 -1
- package/src/microservices/ServiceAuthMiddleware.js +12 -4
- package/src/middleware/CsrfMiddleware.d.ts.map +1 -1
- package/src/middleware/CsrfMiddleware.js +39 -10
- package/src/middleware/ErrorHandlerMiddleware.d.ts.map +1 -1
- package/src/middleware/ErrorHandlerMiddleware.js +2 -1
- package/src/migrations/MigrationLoader.js +1 -1
- package/src/migrations/schema/SchemaCompiler.d.ts.map +1 -1
- package/src/migrations/schema/SchemaCompiler.js +6 -3
- package/src/node-singletons/crypto.d.ts +1 -1
- package/src/node-singletons/crypto.d.ts.map +1 -1
- package/src/node-singletons/crypto.js +1 -1
- package/src/node-singletons/fs.d.ts +1 -1
- package/src/node-singletons/fs.d.ts.map +1 -1
- package/src/node-singletons/path.d.ts +1 -1
- package/src/node-singletons/path.d.ts.map +1 -1
- package/src/node-singletons/path.js +1 -1
- package/src/node-singletons/stream.d.ts +11 -0
- package/src/node-singletons/stream.d.ts.map +1 -0
- package/src/node-singletons/stream.js +8 -0
- package/src/observability/OpenTelemetry.d.ts +7 -0
- package/src/observability/OpenTelemetry.d.ts.map +1 -1
- package/src/observability/OpenTelemetry.js +49 -2
- package/src/orm/Database.d.ts +4 -0
- package/src/orm/Database.d.ts.map +1 -1
- package/src/orm/Database.js +80 -9
- package/src/orm/DatabaseRuntimeRegistration.d.ts.map +1 -1
- package/src/orm/DatabaseRuntimeRegistration.js +2 -0
- package/src/orm/QueryBuilder.d.ts +1 -0
- package/src/orm/QueryBuilder.d.ts.map +1 -1
- package/src/orm/QueryBuilder.js +33 -3
- package/src/orm/SchemaCompiler.d.ts.map +1 -1
- package/src/orm/SchemaCompiler.js +6 -3
- package/src/orm/adapters/D1RemoteAdapter.d.ts.map +1 -1
- package/src/orm/adapters/D1RemoteAdapter.js +14 -1
- package/src/orm/adapters/MongoDBProxyAdapter.d.ts +3 -0
- package/src/orm/adapters/MongoDBProxyAdapter.d.ts.map +1 -0
- package/src/orm/adapters/MongoDBProxyAdapter.js +128 -0
- package/src/orm/adapters/MySQLProxyAdapter.d.ts +11 -0
- package/src/orm/adapters/MySQLProxyAdapter.d.ts.map +1 -0
- package/src/orm/adapters/MySQLProxyAdapter.js +143 -0
- package/src/orm/adapters/PostgreSQLProxyAdapter.d.ts +11 -0
- package/src/orm/adapters/PostgreSQLProxyAdapter.d.ts.map +1 -0
- package/src/orm/adapters/PostgreSQLProxyAdapter.js +147 -0
- package/src/orm/adapters/ProxyCache.d.ts +9 -0
- package/src/orm/adapters/ProxyCache.d.ts.map +1 -0
- package/src/orm/adapters/ProxyCache.js +24 -0
- package/src/orm/adapters/ProxySignedRequest.d.ts +11 -0
- package/src/orm/adapters/ProxySignedRequest.d.ts.map +1 -0
- package/src/orm/adapters/ProxySignedRequest.js +30 -0
- package/src/orm/adapters/ProxySigningPath.d.ts +3 -0
- package/src/orm/adapters/ProxySigningPath.d.ts.map +1 -0
- package/src/orm/adapters/ProxySigningPath.js +25 -0
- package/src/orm/adapters/SqlProxyAdapterUtils.d.ts +19 -0
- package/src/orm/adapters/SqlProxyAdapterUtils.d.ts.map +1 -0
- package/src/orm/adapters/SqlProxyAdapterUtils.js +35 -0
- package/src/orm/adapters/SqlServerProxyAdapter.d.ts +3 -0
- package/src/orm/adapters/SqlServerProxyAdapter.d.ts.map +1 -0
- package/src/orm/adapters/SqlServerProxyAdapter.js +146 -0
- package/src/performance/Optimizer.d.ts +1 -0
- package/src/performance/Optimizer.d.ts.map +1 -1
- package/src/performance/Optimizer.js +21 -8
- package/src/proxy/ErrorHandler.d.ts +11 -0
- package/src/proxy/ErrorHandler.d.ts.map +1 -0
- package/src/proxy/ErrorHandler.js +7 -0
- package/src/proxy/PoolManager.d.ts +8 -0
- package/src/proxy/PoolManager.d.ts.map +1 -0
- package/src/proxy/PoolManager.js +18 -0
- package/src/proxy/ProxyBackend.d.ts +18 -0
- package/src/proxy/ProxyBackend.d.ts.map +1 -0
- package/src/proxy/ProxyBackend.js +1 -0
- package/src/proxy/ProxyConfig.d.ts +12 -0
- package/src/proxy/ProxyConfig.d.ts.map +1 -0
- package/src/proxy/ProxyConfig.js +1 -0
- package/src/proxy/ProxyRegistry.d.ts +10 -0
- package/src/proxy/ProxyRegistry.d.ts.map +1 -0
- package/src/proxy/ProxyRegistry.js +11 -0
- package/src/proxy/ProxyServer.d.ts +21 -0
- package/src/proxy/ProxyServer.d.ts.map +1 -0
- package/src/proxy/ProxyServer.js +84 -0
- package/src/proxy/ProxyServerUtils.d.ts +37 -0
- package/src/proxy/ProxyServerUtils.d.ts.map +1 -0
- package/src/proxy/ProxyServerUtils.js +42 -0
- package/src/proxy/ProxySigningConfigResolver.d.ts +22 -0
- package/src/proxy/ProxySigningConfigResolver.d.ts.map +1 -0
- package/src/proxy/ProxySigningConfigResolver.js +24 -0
- package/src/proxy/ProxySigningRequest.d.ts +12 -0
- package/src/proxy/ProxySigningRequest.d.ts.map +1 -0
- package/src/proxy/ProxySigningRequest.js +31 -0
- package/src/proxy/RequestValidator.d.ts +15 -0
- package/src/proxy/RequestValidator.d.ts.map +1 -0
- package/src/proxy/RequestValidator.js +25 -0
- package/src/proxy/SigningService.d.ts +39 -0
- package/src/proxy/SigningService.d.ts.map +1 -0
- package/src/proxy/SigningService.js +107 -0
- package/src/proxy/SqlPayloadValidator.d.ts +13 -0
- package/src/proxy/SqlPayloadValidator.d.ts.map +1 -0
- package/src/proxy/SqlPayloadValidator.js +14 -0
- package/src/proxy/d1/ZintrustD1Proxy.d.ts +2 -0
- package/src/proxy/d1/ZintrustD1Proxy.d.ts.map +1 -0
- package/src/proxy/d1/ZintrustD1Proxy.js +1 -0
- package/src/proxy/d1/register.d.ts +2 -0
- package/src/proxy/d1/register.d.ts.map +1 -0
- package/src/proxy/d1/register.js +5 -0
- package/src/proxy/kv/ZintrustKvProxy.d.ts +2 -0
- package/src/proxy/kv/ZintrustKvProxy.d.ts.map +1 -0
- package/src/proxy/kv/ZintrustKvProxy.js +1 -0
- package/src/proxy/kv/register.d.ts +2 -0
- package/src/proxy/kv/register.d.ts.map +1 -0
- package/src/proxy/kv/register.js +5 -0
- package/src/proxy/mongodb/MongoDBProxyServer.d.ts +33 -0
- package/src/proxy/mongodb/MongoDBProxyServer.d.ts.map +1 -0
- package/src/proxy/mongodb/MongoDBProxyServer.js +202 -0
- package/src/proxy/mongodb/register.d.ts +2 -0
- package/src/proxy/mongodb/register.d.ts.map +1 -0
- package/src/proxy/mongodb/register.js +5 -0
- package/src/proxy/mysql/MySqlProxyServer.d.ts +14 -0
- package/src/proxy/mysql/MySqlProxyServer.d.ts.map +1 -0
- package/src/proxy/mysql/MySqlProxyServer.js +169 -0
- package/src/proxy/mysql/register.d.ts +2 -0
- package/src/proxy/mysql/register.d.ts.map +1 -0
- package/src/proxy/mysql/register.js +5 -0
- package/src/proxy/postgres/PostgresProxyServer.d.ts +14 -0
- package/src/proxy/postgres/PostgresProxyServer.d.ts.map +1 -0
- package/src/proxy/postgres/PostgresProxyServer.js +140 -0
- package/src/proxy/postgres/register.d.ts +2 -0
- package/src/proxy/postgres/register.d.ts.map +1 -0
- package/src/proxy/postgres/register.js +5 -0
- package/src/proxy/redis/RedisProxyServer.d.ts +12 -0
- package/src/proxy/redis/RedisProxyServer.d.ts.map +1 -0
- package/src/proxy/redis/RedisProxyServer.js +192 -0
- package/src/proxy/redis/register.d.ts +2 -0
- package/src/proxy/redis/register.d.ts.map +1 -0
- package/src/proxy/redis/register.js +5 -0
- package/src/proxy/smtp/SmtpProxyServer.d.ts +19 -0
- package/src/proxy/smtp/SmtpProxyServer.d.ts.map +1 -0
- package/src/proxy/smtp/SmtpProxyServer.js +289 -0
- package/src/proxy/smtp/register.d.ts +2 -0
- package/src/proxy/smtp/register.d.ts.map +1 -0
- package/src/proxy/smtp/register.js +5 -0
- package/src/proxy/sqlserver/SqlServerProxyServer.d.ts +14 -0
- package/src/proxy/sqlserver/SqlServerProxyServer.d.ts.map +1 -0
- package/src/proxy/sqlserver/SqlServerProxyServer.js +168 -0
- package/src/proxy/sqlserver/register.d.ts +2 -0
- package/src/proxy/sqlserver/register.d.ts.map +1 -0
- package/src/proxy/sqlserver/register.js +5 -0
- package/src/routes/doc.d.ts.map +1 -1
- package/src/routes/doc.js +16 -2
- package/src/routes/error.d.ts +5 -4
- package/src/routes/error.d.ts.map +1 -1
- package/src/routes/error.js +15 -13
- package/src/routes/errorPages.d.ts +2 -0
- package/src/routes/errorPages.d.ts.map +1 -1
- package/src/routes/errorPages.js +144 -4
- package/src/runtime/PluginAutoImports.d.ts +1 -0
- package/src/runtime/PluginAutoImports.d.ts.map +1 -1
- package/src/runtime/PluginAutoImports.js +94 -9
- package/src/runtime/RuntimeAdapter.d.ts +8 -9
- package/src/runtime/RuntimeAdapter.d.ts.map +1 -1
- package/src/runtime/RuntimeAdapter.js +120 -34
- package/src/runtime/RuntimeServices.d.ts +47 -0
- package/src/runtime/RuntimeServices.d.ts.map +1 -0
- package/src/runtime/RuntimeServices.js +164 -0
- package/src/runtime/StartupConfigFileRegistry.d.ts +4 -4
- package/src/runtime/StartupConfigFileRegistry.d.ts.map +1 -1
- package/src/runtime/StartupConfigFileRegistry.js +12 -0
- package/src/runtime/WorkerAdapterImports.d.ts +5 -0
- package/src/runtime/WorkerAdapterImports.d.ts.map +1 -0
- package/src/runtime/WorkerAdapterImports.js +17 -0
- package/src/runtime/WorkersModule.d.ts +6 -0
- package/src/runtime/WorkersModule.d.ts.map +1 -0
- package/src/runtime/WorkersModule.js +278 -0
- package/src/runtime/adapters/CloudflareAdapter.d.ts.map +1 -1
- package/src/runtime/adapters/CloudflareAdapter.js +19 -2
- package/src/runtime/adapters/DenoAdapter.js +1 -0
- package/src/runtime/adapters/FargateAdapter.js +1 -1
- package/src/runtime/adapters/LambdaAdapter.js +1 -1
- package/src/runtime/adapters/NodeServerAdapter.js +1 -1
- package/src/runtime/detectRuntime.d.ts +10 -0
- package/src/runtime/detectRuntime.d.ts.map +1 -0
- package/src/runtime/detectRuntime.js +57 -0
- package/src/runtime/useFileLoader.d.ts.map +1 -1
- package/src/runtime/useFileLoader.js +16 -0
- package/src/scripts/TemplateImportsCheck.js +2 -2
- package/src/scripts/TemplateSync.js +3 -4
- package/src/security/CsrfTokenManager.d.ts +18 -9
- package/src/security/CsrfTokenManager.d.ts.map +1 -1
- package/src/security/CsrfTokenManager.js +204 -11
- package/src/security/Hash.d.ts +1 -1
- package/src/security/Hash.d.ts.map +1 -1
- package/src/security/Hash.js +31 -36
- package/src/seeders/SeederLoader.js +1 -1
- package/src/session/SessionManager.d.ts +3 -0
- package/src/session/SessionManager.d.ts.map +1 -1
- package/src/session/SessionManager.js +49 -10
- package/src/sockets/CloudflareSocket.d.ts +24 -0
- package/src/sockets/CloudflareSocket.d.ts.map +1 -0
- package/src/sockets/CloudflareSocket.js +259 -0
- package/src/start.d.ts.map +1 -1
- package/src/start.js +1 -8
- package/src/templates/project/basic/app/Middleware/index.ts.tpl +1 -1
- package/src/templates/project/basic/src/zintrust.plugins.wg.ts.tpl +8 -0
- package/src/toolkit/Secrets/providers/AwsSecretsManager.d.ts.map +1 -1
- package/src/toolkit/Secrets/providers/AwsSecretsManager.js +4 -2
- package/src/tools/mail/drivers/Smtp.d.ts.map +1 -1
- package/src/tools/mail/drivers/Smtp.js +223 -18
- package/src/tools/mail/index.d.ts.map +1 -1
- package/src/tools/mail/index.js +5 -4
- package/src/tools/mail/template-loader.d.ts.map +1 -1
- package/src/tools/mail/template-loader.js +197 -29
- package/src/tools/mail/templates/auth-password-reset.d.ts +3 -0
- package/src/tools/mail/templates/auth-password-reset.d.ts.map +1 -0
- package/src/tools/mail/templates/auth-password-reset.js +231 -0
- package/src/tools/mail/templates/auth-welcome.d.ts +3 -0
- package/src/tools/mail/templates/auth-welcome.d.ts.map +1 -0
- package/src/tools/mail/templates/auth-welcome.js +236 -0
- package/src/tools/mail/templates/general.d.ts +3 -0
- package/src/tools/mail/templates/general.d.ts.map +1 -0
- package/src/tools/mail/templates/general.js +109 -0
- package/src/tools/mail/templates/index.js +2 -2
- package/src/tools/mail/templates/job-completed.d.ts +3 -0
- package/src/tools/mail/templates/job-completed.d.ts.map +1 -0
- package/src/tools/mail/templates/job-completed.js +188 -0
- package/src/tools/mail/templates/notifications-new-comment.d.ts +3 -0
- package/src/tools/mail/templates/notifications-new-comment.d.ts.map +1 -0
- package/src/tools/mail/templates/notifications-new-comment.js +228 -0
- package/src/tools/mail/templates/password-reset.d.ts +3 -0
- package/src/tools/mail/templates/password-reset.d.ts.map +1 -0
- package/src/tools/mail/templates/password-reset.js +221 -0
- package/src/tools/mail/templates/performance-report.d.ts +3 -0
- package/src/tools/mail/templates/performance-report.d.ts.map +1 -0
- package/src/tools/mail/templates/performance-report.js +258 -0
- package/src/tools/mail/templates/welcome.d.ts +3 -0
- package/src/tools/mail/templates/welcome.d.ts.map +1 -0
- package/src/tools/mail/templates/welcome.js +187 -0
- package/src/tools/mail/templates/worker-alert.d.ts +3 -0
- package/src/tools/mail/templates/worker-alert.d.ts.map +1 -0
- package/src/tools/mail/templates/worker-alert.js +229 -0
- package/src/tools/notification/Notification.js +1 -1
- package/src/tools/notification/testingHelpers.js +6 -5
- package/src/tools/queue/AdvancedQueue.js +2 -6
- package/src/tools/queue/IdempotencyManager.d.ts +6 -0
- package/src/tools/queue/IdempotencyManager.d.ts.map +1 -0
- package/src/tools/queue/IdempotencyManager.js +36 -0
- package/src/tools/queue/JobHeartbeatStore.d.ts +16 -0
- package/src/tools/queue/JobHeartbeatStore.d.ts.map +1 -0
- package/src/tools/queue/JobHeartbeatStore.js +67 -0
- package/src/tools/queue/JobReconciliationRunner.d.ts +16 -0
- package/src/tools/queue/JobReconciliationRunner.d.ts.map +1 -0
- package/src/tools/queue/JobReconciliationRunner.js +88 -0
- package/src/tools/queue/JobRecoveryDaemon.d.ts +27 -0
- package/src/tools/queue/JobRecoveryDaemon.d.ts.map +1 -0
- package/src/tools/queue/JobRecoveryDaemon.js +205 -0
- package/src/tools/queue/JobStateTracker.d.ts +131 -0
- package/src/tools/queue/JobStateTracker.d.ts.map +1 -0
- package/src/tools/queue/JobStateTracker.js +387 -0
- package/src/tools/queue/JobStateTrackerDbPersistence.d.ts +12 -0
- package/src/tools/queue/JobStateTrackerDbPersistence.d.ts.map +1 -0
- package/src/tools/queue/JobStateTrackerDbPersistence.js +148 -0
- package/src/tools/queue/Queue.d.ts.map +1 -1
- package/src/tools/queue/Queue.js +160 -16
- package/src/tools/queue/QueueDataRedactor.d.ts +6 -0
- package/src/tools/queue/QueueDataRedactor.d.ts.map +1 -0
- package/src/tools/queue/QueueDataRedactor.js +45 -0
- package/src/tools/queue/QueueExtensions.d.ts.map +1 -1
- package/src/tools/queue/QueueExtensions.js +2 -1
- package/src/tools/queue/QueueReliabilityMetrics.d.ts +38 -0
- package/src/tools/queue/QueueReliabilityMetrics.d.ts.map +1 -0
- package/src/tools/queue/QueueReliabilityMetrics.js +131 -0
- package/src/tools/queue/QueueReliabilityOrchestrator.d.ts +7 -0
- package/src/tools/queue/QueueReliabilityOrchestrator.d.ts.map +1 -0
- package/src/tools/queue/QueueReliabilityOrchestrator.js +59 -0
- package/src/tools/queue/QueueRuntimeRegistration.d.ts +1 -9
- package/src/tools/queue/QueueRuntimeRegistration.d.ts.map +1 -1
- package/src/tools/queue/QueueRuntimeRegistration.js +75 -4
- package/src/tools/queue/QueueTracing.d.ts +32 -0
- package/src/tools/queue/QueueTracing.d.ts.map +1 -0
- package/src/tools/queue/QueueTracing.js +151 -0
- package/src/tools/queue/StalledJobMonitor.d.ts +5 -0
- package/src/tools/queue/StalledJobMonitor.d.ts.map +1 -0
- package/src/tools/queue/StalledJobMonitor.js +21 -0
- package/src/tools/queue/TimeoutManager.d.ts +14 -0
- package/src/tools/queue/TimeoutManager.d.ts.map +1 -0
- package/src/tools/queue/TimeoutManager.js +77 -0
- package/src/tools/queue/drivers/Redis.d.ts +1 -0
- package/src/tools/queue/drivers/Redis.d.ts.map +1 -1
- package/src/tools/queue/drivers/Redis.js +1 -0
- package/src/tools/queue/index.d.ts +10 -0
- package/src/tools/queue/index.d.ts.map +1 -1
- package/src/tools/queue/index.js +10 -0
- package/src/tools/redis/RedisKeyManager.d.ts +3 -0
- package/src/tools/redis/RedisKeyManager.d.ts.map +1 -1
- package/src/tools/redis/RedisKeyManager.js +15 -0
- package/src/tools/storage/drivers/R2.d.ts +13 -0
- package/src/tools/storage/drivers/R2.d.ts.map +1 -1
- package/src/tools/storage/drivers/R2.js +29 -0
- package/src/zintrust.plugins.d.ts +9 -0
- package/src/zintrust.plugins.d.ts.map +1 -0
- package/src/zintrust.plugins.js +7 -0
- package/src/zintrust.plugins.wg.d.ts +9 -0
- package/src/zintrust.plugins.wg.d.ts.map +1 -0
- package/src/zintrust.plugins.wg.js +7 -0
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import { ErrorFactory } from '../exceptions/ZintrustError.js';
|
|
2
|
+
import { EventEmitter } from '../node-singletons/index.js';
|
|
3
|
+
// Lazy import cloudflare:sockets to prevent Node.js evaluation errors
|
|
4
|
+
let connect;
|
|
5
|
+
const getCloudflareConnect = async () => {
|
|
6
|
+
if (connect === undefined) {
|
|
7
|
+
const module = await import('cloudflare:sockets');
|
|
8
|
+
connect = module.connect;
|
|
9
|
+
}
|
|
10
|
+
return connect;
|
|
11
|
+
};
|
|
12
|
+
const DEFAULT_TIMEOUT_MS = 30000;
|
|
13
|
+
const toBuffer = (data) => {
|
|
14
|
+
if (typeof Buffer !== 'undefined')
|
|
15
|
+
return Buffer.from(data);
|
|
16
|
+
return data;
|
|
17
|
+
};
|
|
18
|
+
const createTimeoutSignal = (timeoutMs) => {
|
|
19
|
+
if (timeoutMs <= 0)
|
|
20
|
+
return undefined;
|
|
21
|
+
if (typeof AbortSignal === 'undefined' || typeof AbortSignal.timeout !== 'function')
|
|
22
|
+
return undefined;
|
|
23
|
+
return AbortSignal.timeout(timeoutMs);
|
|
24
|
+
};
|
|
25
|
+
const withTimeout = async (promise, timeoutMs, message) => {
|
|
26
|
+
const signal = createTimeoutSignal(timeoutMs);
|
|
27
|
+
if (!signal)
|
|
28
|
+
return promise;
|
|
29
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
30
|
+
signal.addEventListener('abort', () => reject(ErrorFactory.createConnectionError(message)), {
|
|
31
|
+
once: true,
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
return Promise.race([promise, timeoutPromise]);
|
|
35
|
+
};
|
|
36
|
+
const releaseStreamLocks = (state) => {
|
|
37
|
+
if (typeof process !== 'undefined' && process.env?.['VITEST'] !== undefined) {
|
|
38
|
+
state.reader = undefined;
|
|
39
|
+
state.writer = undefined;
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const reader = state.reader;
|
|
43
|
+
if (reader && typeof reader.releaseLock === 'function') {
|
|
44
|
+
try {
|
|
45
|
+
reader.releaseLock();
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// ignore lock release errors
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
const writer = state.writer;
|
|
52
|
+
if (writer && typeof writer.releaseLock === 'function') {
|
|
53
|
+
try {
|
|
54
|
+
writer.releaseLock();
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// ignore lock release errors
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
state.reader = undefined;
|
|
61
|
+
state.writer = undefined;
|
|
62
|
+
};
|
|
63
|
+
const flushBuffered = (state, emitter) => {
|
|
64
|
+
if (state.paused)
|
|
65
|
+
return;
|
|
66
|
+
while (state.bufferedChunks.length > 0) {
|
|
67
|
+
const chunk = state.bufferedChunks.shift();
|
|
68
|
+
if (chunk !== undefined)
|
|
69
|
+
emitter.emit('data', toBuffer(chunk));
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
const startReading = (state, emitter) => {
|
|
73
|
+
const token = state.socketToken;
|
|
74
|
+
const readNext = async () => {
|
|
75
|
+
if (state.socketToken !== token)
|
|
76
|
+
return;
|
|
77
|
+
if (!state.reader)
|
|
78
|
+
return; //NOSONAR
|
|
79
|
+
return state.reader
|
|
80
|
+
.read()
|
|
81
|
+
.then(async ({ done, value }) => {
|
|
82
|
+
if (state.socketToken !== token)
|
|
83
|
+
return;
|
|
84
|
+
if (done) {
|
|
85
|
+
emitter.emit('end');
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
88
|
+
if (state.paused) {
|
|
89
|
+
state.bufferedChunks.push(value);
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
emitter.emit('data', toBuffer(value));
|
|
93
|
+
}
|
|
94
|
+
return readNext();
|
|
95
|
+
})
|
|
96
|
+
.catch((error) => {
|
|
97
|
+
emitter.emit('error', error);
|
|
98
|
+
});
|
|
99
|
+
};
|
|
100
|
+
readNext().catch((error) => emitter.emit('error', error));
|
|
101
|
+
};
|
|
102
|
+
const bindSocketLifecycle = async (emitter, state, socket, emitConnect) => {
|
|
103
|
+
state.socketToken += 1;
|
|
104
|
+
const token = state.socketToken;
|
|
105
|
+
state.socket = socket;
|
|
106
|
+
state.closed = false;
|
|
107
|
+
const waitForOpen = withTimeout(socket.opened, state.timeoutMs, 'Cloudflare socket connection timed out');
|
|
108
|
+
return waitForOpen
|
|
109
|
+
.then(() => {
|
|
110
|
+
state.reader = socket.readable.getReader();
|
|
111
|
+
state.writer = socket.writable.getWriter();
|
|
112
|
+
if (emitConnect)
|
|
113
|
+
emitter.emit('connect');
|
|
114
|
+
startReading(state, emitter);
|
|
115
|
+
socket.closed
|
|
116
|
+
.then(() => {
|
|
117
|
+
if (state.socketToken !== token)
|
|
118
|
+
return;
|
|
119
|
+
if (state.closed)
|
|
120
|
+
return;
|
|
121
|
+
state.closed = true;
|
|
122
|
+
emitter.emit('close');
|
|
123
|
+
try {
|
|
124
|
+
releaseStreamLocks(state);
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
// ignore release errors
|
|
128
|
+
}
|
|
129
|
+
emitter.removeAllListeners();
|
|
130
|
+
})
|
|
131
|
+
.catch((error) => {
|
|
132
|
+
if (state.socketToken !== token)
|
|
133
|
+
return;
|
|
134
|
+
if (state.closed)
|
|
135
|
+
return;
|
|
136
|
+
state.closed = true;
|
|
137
|
+
emitter.emit('error', error);
|
|
138
|
+
try {
|
|
139
|
+
releaseStreamLocks(state);
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
// ignore release errors
|
|
143
|
+
}
|
|
144
|
+
emitter.removeAllListeners();
|
|
145
|
+
});
|
|
146
|
+
})
|
|
147
|
+
.catch((error) => {
|
|
148
|
+
emitter.emit('error', error);
|
|
149
|
+
try {
|
|
150
|
+
releaseStreamLocks(state);
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
// ignore release errors
|
|
154
|
+
}
|
|
155
|
+
emitter.removeAllListeners();
|
|
156
|
+
});
|
|
157
|
+
};
|
|
158
|
+
const createEmitterHandlers = (emitter, state) => {
|
|
159
|
+
emitter.write = (data) => {
|
|
160
|
+
if (!state.writer)
|
|
161
|
+
return false;
|
|
162
|
+
try {
|
|
163
|
+
const payload = data instanceof Uint8Array ? data : new Uint8Array(data);
|
|
164
|
+
const writePromise = state.writer.write(payload);
|
|
165
|
+
writePromise.catch((error) => emitter.emit('error', error));
|
|
166
|
+
if (state.writer.desiredSize !== null && state.writer.desiredSize <= 0) {
|
|
167
|
+
state.writer.ready
|
|
168
|
+
.then(() => emitter.emit('drain'))
|
|
169
|
+
.catch((error) => emitter.emit('error', error));
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
emitter.emit('error', error);
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
emitter.end = () => {
|
|
180
|
+
const socket = state.socket;
|
|
181
|
+
if (!socket)
|
|
182
|
+
return;
|
|
183
|
+
socket
|
|
184
|
+
.close()
|
|
185
|
+
.then(() => {
|
|
186
|
+
emitter.emit('close');
|
|
187
|
+
releaseStreamLocks(state);
|
|
188
|
+
emitter.removeAllListeners();
|
|
189
|
+
})
|
|
190
|
+
.catch((error) => {
|
|
191
|
+
emitter.emit('error', error);
|
|
192
|
+
releaseStreamLocks(state);
|
|
193
|
+
emitter.removeAllListeners();
|
|
194
|
+
});
|
|
195
|
+
};
|
|
196
|
+
emitter.destroy = emitter.end;
|
|
197
|
+
emitter.connect = (...args) => {
|
|
198
|
+
const last = args.at(-1);
|
|
199
|
+
if (typeof last === 'function') {
|
|
200
|
+
emitter.once('connect', last);
|
|
201
|
+
}
|
|
202
|
+
return emitter;
|
|
203
|
+
};
|
|
204
|
+
emitter.startTls = async () => {
|
|
205
|
+
const socket = state.socket;
|
|
206
|
+
if (!socket || typeof socket.startTls !== 'function') {
|
|
207
|
+
throw ErrorFactory.createConnectionError('Cloudflare socket does not support STARTTLS');
|
|
208
|
+
}
|
|
209
|
+
releaseStreamLocks(state);
|
|
210
|
+
state.bufferedChunks = [];
|
|
211
|
+
const tlsSocket = socket.startTls();
|
|
212
|
+
await bindSocketLifecycle(emitter, state, tlsSocket, false);
|
|
213
|
+
};
|
|
214
|
+
emitter.pause = () => {
|
|
215
|
+
state.paused = true;
|
|
216
|
+
};
|
|
217
|
+
emitter.resume = () => {
|
|
218
|
+
state.paused = false;
|
|
219
|
+
flushBuffered(state, emitter);
|
|
220
|
+
};
|
|
221
|
+
emitter.setTimeout = (timeoutMs, callback) => {
|
|
222
|
+
state.timeoutToken += 1;
|
|
223
|
+
const token = state.timeoutToken;
|
|
224
|
+
const signal = createTimeoutSignal(timeoutMs);
|
|
225
|
+
if (!signal)
|
|
226
|
+
return;
|
|
227
|
+
signal.addEventListener('abort', () => {
|
|
228
|
+
if (state.timeoutToken !== token)
|
|
229
|
+
return;
|
|
230
|
+
emitter.emit('timeout');
|
|
231
|
+
callback?.();
|
|
232
|
+
}, { once: true });
|
|
233
|
+
};
|
|
234
|
+
emitter.setNoDelay = () => undefined;
|
|
235
|
+
emitter.setKeepAlive = () => undefined;
|
|
236
|
+
emitter.ref = () => undefined;
|
|
237
|
+
emitter.unref = () => undefined;
|
|
238
|
+
};
|
|
239
|
+
function createCloudflareSocket(hostname, port, options = {}) {
|
|
240
|
+
const emitter = new EventEmitter();
|
|
241
|
+
const secureTransport = options.tls === true ? 'starttls' : 'off';
|
|
242
|
+
const state = {
|
|
243
|
+
paused: false,
|
|
244
|
+
bufferedChunks: [],
|
|
245
|
+
closed: false,
|
|
246
|
+
timeoutToken: 0,
|
|
247
|
+
socketToken: 0,
|
|
248
|
+
timeoutMs: options.timeoutMs ?? DEFAULT_TIMEOUT_MS,
|
|
249
|
+
};
|
|
250
|
+
createEmitterHandlers(emitter, state);
|
|
251
|
+
getCloudflareConnect()
|
|
252
|
+
.then((connectFn) => connectFn({ hostname, port }, { secureTransport, allowHalfOpen: false }))
|
|
253
|
+
.then(async (socket) => bindSocketLifecycle(emitter, state, socket, true))
|
|
254
|
+
.catch((error) => emitter.emit('error', error));
|
|
255
|
+
return emitter;
|
|
256
|
+
}
|
|
257
|
+
export const CloudflareSocket = Object.freeze({
|
|
258
|
+
create: createCloudflareSocket,
|
|
259
|
+
});
|
package/src/start.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/start.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/start.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,UAAU,GAAI,eAAe,MAAM,KAAG,OAYlD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,KAAK,QAAa,OAAO,CAAC,IAAI,CAO1C,CAAC;AAEF;;GAEG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAEhD,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEpE;;GAEG;AACH,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAElD;;GAEG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC"}
|
package/src/start.js
CHANGED
|
@@ -1,12 +1,5 @@
|
|
|
1
1
|
import { ZintrustLang } from './lang/lang.js';
|
|
2
|
-
|
|
3
|
-
// Avoid importing any `node:*` modules so this file remains Worker-safe.
|
|
4
|
-
// In Workers/Deno, `process` is typically undefined.
|
|
5
|
-
return (typeof process !== ZintrustLang.UNDEFINED &&
|
|
6
|
-
typeof process === ZintrustLang.OBJECT &&
|
|
7
|
-
process !== null &&
|
|
8
|
-
typeof process.versions === ZintrustLang.OBJECT);
|
|
9
|
-
};
|
|
2
|
+
import { isNodeRuntime } from './runtime/detectRuntime.js';
|
|
10
3
|
const fileUrlToPathLike = (value) => {
|
|
11
4
|
if (!value.startsWith(ZintrustLang.FILE_PROTOCOL))
|
|
12
5
|
return value;
|
|
@@ -220,7 +220,7 @@ export const csrfMiddleware = (csrfManager: CsrfManagerInput) => {
|
|
|
220
220
|
return;
|
|
221
221
|
}
|
|
222
222
|
|
|
223
|
-
const isValid = resolveCsrfManager(csrfManager).validateToken(
|
|
223
|
+
const isValid = await resolveCsrfManager(csrfManager).validateToken(
|
|
224
224
|
String(sessionId),
|
|
225
225
|
String(csrfToken)
|
|
226
226
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AwsSecretsManager.d.ts","sourceRoot":"","sources":["../../../../../src/toolkit/Secrets/providers/AwsSecretsManager.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,cAAc,GAAG;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AA0GF,eAAO,MAAM,iBAAiB;qBACX;QACf,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;QACzE,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KAC9D;iBAsDY,MAAM,EAAE;
|
|
1
|
+
{"version":3,"file":"AwsSecretsManager.d.ts","sourceRoot":"","sources":["../../../../../src/toolkit/Secrets/providers/AwsSecretsManager.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,cAAc,GAAG;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AA0GF,eAAO,MAAM,iBAAiB;qBACX;QACf,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;QACzE,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KAC9D;iBAsDY,MAAM,EAAE;EAkBrB,CAAC;AAEH,eAAe,iBAAiB,CAAC"}
|
|
@@ -117,9 +117,11 @@ export const AwsSecretsManager = Object.freeze({
|
|
|
117
117
|
},
|
|
118
118
|
doctorEnv() {
|
|
119
119
|
const missing = [];
|
|
120
|
-
const
|
|
121
|
-
|
|
120
|
+
const awsRegion = readEnvString('AWS_REGION').trim();
|
|
121
|
+
const awsDefaultRegion = readEnvString('AWS_DEFAULT_REGION').trim();
|
|
122
|
+
if (awsRegion === '' && awsDefaultRegion === '') {
|
|
122
123
|
missing.push('AWS_REGION');
|
|
124
|
+
}
|
|
123
125
|
const accessKeyId = readEnvString('AWS_ACCESS_KEY_ID').trim();
|
|
124
126
|
if (accessKeyId === '')
|
|
125
127
|
missing.push('AWS_ACCESS_KEY_ID');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Smtp.d.ts","sourceRoot":"","sources":["../../../../../src/tools/mail/drivers/Smtp.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Smtp.d.ts","sourceRoot":"","sources":["../../../../../src/tools/mail/drivers/Smtp.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnE,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACtB,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,cAAc,EAAE,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AA+pBF,eAAO,MAAM,UAAU;IACrB;;;;OAIG;iBACgB,UAAU,WAAW,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;EAuDzE,CAAC;AAEH,eAAe,UAAU,CAAC"}
|
|
@@ -1,13 +1,31 @@
|
|
|
1
1
|
import { generateUuid } from '../../../common/utility.js';
|
|
2
|
+
import { RemoteSignedJson } from '../../../common/RemoteSignedJson.js';
|
|
3
|
+
import { Cloudflare } from '../../../config/cloudflare.js';
|
|
4
|
+
import { Env } from '../../../config/env.js';
|
|
5
|
+
import { Logger } from '../../../config/logger.js';
|
|
2
6
|
import { ErrorFactory } from '../../../exceptions/ZintrustError.js';
|
|
3
7
|
import * as net from '../../../node-singletons/net.js';
|
|
4
8
|
import * as tls from '../../../node-singletons/tls.js';
|
|
9
|
+
import { normalizeSigningCredentials } from '../../../proxy/SigningService.js';
|
|
10
|
+
const resolveSigningPrefix = (baseUrl) => {
|
|
11
|
+
try {
|
|
12
|
+
const parsed = new URL(baseUrl);
|
|
13
|
+
const path = parsed.pathname.endsWith('/') ? parsed.pathname.slice(0, -1) : parsed.pathname;
|
|
14
|
+
if (path === '' || path === '/')
|
|
15
|
+
return undefined;
|
|
16
|
+
return path;
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
5
22
|
const normalizeRecipients = (to) => (Array.isArray(to) ? to : [to]);
|
|
6
23
|
const toBase64 = (value) => Buffer.from(value, 'utf8').toString('base64');
|
|
7
24
|
const isNodeRuntime = () => typeof process !== 'undefined' && typeof process.versions?.node === 'string';
|
|
25
|
+
const isWorkersRuntime = () => Cloudflare.getWorkersEnv() !== null;
|
|
8
26
|
const validateConfig = (config) => {
|
|
9
|
-
if (!isNodeRuntime()) {
|
|
10
|
-
throw ErrorFactory.createConfigError('SMTP driver requires Node.js runtime');
|
|
27
|
+
if (!isNodeRuntime() && !isWorkersRuntime()) {
|
|
28
|
+
throw ErrorFactory.createConfigError('SMTP driver requires Node.js or Workers runtime');
|
|
11
29
|
}
|
|
12
30
|
if (config.host.trim() === '') {
|
|
13
31
|
throw ErrorFactory.createConfigError('SMTP: missing MAIL_HOST');
|
|
@@ -16,7 +34,95 @@ const validateConfig = (config) => {
|
|
|
16
34
|
throw ErrorFactory.createConfigError('SMTP: invalid MAIL_PORT');
|
|
17
35
|
}
|
|
18
36
|
};
|
|
19
|
-
const
|
|
37
|
+
const resolveProxyBaseUrl = () => {
|
|
38
|
+
const explicit = Env.SMTP_PROXY_URL.trim();
|
|
39
|
+
if (explicit !== '')
|
|
40
|
+
return explicit;
|
|
41
|
+
const host = Env.SMTP_PROXY_HOST || '127.0.0.1';
|
|
42
|
+
const port = Env.SMTP_PROXY_PORT;
|
|
43
|
+
return `http://${host}:${port}`;
|
|
44
|
+
};
|
|
45
|
+
const buildProxySettings = () => {
|
|
46
|
+
const baseUrl = resolveProxyBaseUrl();
|
|
47
|
+
const keyId = Env.SMTP_PROXY_KEY_ID ?? '';
|
|
48
|
+
const secret = Env.SMTP_PROXY_SECRET ?? '';
|
|
49
|
+
const timeoutMs = Env.SMTP_PROXY_TIMEOUT_MS;
|
|
50
|
+
return { baseUrl, keyId, secret, timeoutMs };
|
|
51
|
+
};
|
|
52
|
+
const buildSignedSettings = (settings) => {
|
|
53
|
+
const creds = normalizeSigningCredentials({
|
|
54
|
+
keyId: settings.keyId ?? '',
|
|
55
|
+
secret: settings.secret ?? '',
|
|
56
|
+
});
|
|
57
|
+
return {
|
|
58
|
+
baseUrl: settings.baseUrl,
|
|
59
|
+
keyId: creds.keyId,
|
|
60
|
+
secret: creds.secret,
|
|
61
|
+
timeoutMs: settings.timeoutMs,
|
|
62
|
+
signaturePathPrefixToStrip: resolveSigningPrefix(settings.baseUrl),
|
|
63
|
+
missingUrlMessage: 'SMTP proxy URL is missing (SMTP_PROXY_URL)',
|
|
64
|
+
missingCredentialsMessage: 'SMTP proxy signing credentials are missing (SMTP_PROXY_KEY_ID / SMTP_PROXY_SECRET)',
|
|
65
|
+
messages: {
|
|
66
|
+
unauthorized: 'SMTP proxy unauthorized',
|
|
67
|
+
forbidden: 'SMTP proxy forbidden',
|
|
68
|
+
rateLimited: 'SMTP proxy rate limited',
|
|
69
|
+
rejected: 'SMTP proxy rejected request',
|
|
70
|
+
error: 'SMTP proxy error',
|
|
71
|
+
timedOut: 'SMTP proxy request timed out',
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
const ensureSignedSettings = (settings) => {
|
|
76
|
+
const signedSettings = buildSignedSettings(settings);
|
|
77
|
+
if (signedSettings.baseUrl.trim() === '') {
|
|
78
|
+
throw ErrorFactory.createConfigError('SMTP proxy URL is missing (SMTP_PROXY_URL)');
|
|
79
|
+
}
|
|
80
|
+
if (signedSettings.keyId.trim() === '' || signedSettings.secret.trim() === '') {
|
|
81
|
+
throw ErrorFactory.createConfigError('SMTP proxy signing credentials are missing (SMTP_PROXY_KEY_ID / SMTP_PROXY_SECRET)');
|
|
82
|
+
}
|
|
83
|
+
return signedSettings;
|
|
84
|
+
};
|
|
85
|
+
const shouldUseProxy = () => {
|
|
86
|
+
if (Env.USE_SMTP_PROXY === true)
|
|
87
|
+
return true;
|
|
88
|
+
return Env.SMTP_PROXY_URL.trim() !== '';
|
|
89
|
+
};
|
|
90
|
+
const serializeMessage = (message) => {
|
|
91
|
+
const attachments = message.attachments?.map((attachment) => {
|
|
92
|
+
const raw = Buffer.isBuffer(attachment.content)
|
|
93
|
+
? attachment.content
|
|
94
|
+
: Buffer.from(attachment.content);
|
|
95
|
+
return {
|
|
96
|
+
filename: attachment.filename,
|
|
97
|
+
contentBase64: raw.toString('base64'),
|
|
98
|
+
};
|
|
99
|
+
});
|
|
100
|
+
return {
|
|
101
|
+
to: message.to,
|
|
102
|
+
from: message.from,
|
|
103
|
+
subject: message.subject,
|
|
104
|
+
text: message.text,
|
|
105
|
+
html: message.html,
|
|
106
|
+
attachments: attachments && attachments.length > 0 ? attachments : undefined,
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
const sendViaProxy = async (message) => {
|
|
110
|
+
const settings = buildProxySettings();
|
|
111
|
+
const signedSettings = ensureSignedSettings(settings);
|
|
112
|
+
return RemoteSignedJson.request(signedSettings, '/zin/smtp/send', {
|
|
113
|
+
message: serializeMessage(message),
|
|
114
|
+
});
|
|
115
|
+
};
|
|
116
|
+
const loadCloudflareSocketFactory = async () => {
|
|
117
|
+
const mod = (await import('../../../sockets/CloudflareSocket.js'));
|
|
118
|
+
const record = mod;
|
|
119
|
+
const socketFactory = record.CloudflareSocket;
|
|
120
|
+
if (!socketFactory || typeof socketFactory.create !== 'function') {
|
|
121
|
+
throw ErrorFactory.createConnectionError('Cloudflare socket factory unavailable');
|
|
122
|
+
}
|
|
123
|
+
return socketFactory;
|
|
124
|
+
};
|
|
125
|
+
const createNodeSocket = async (config, implicitTls) => {
|
|
20
126
|
validateConfig(config);
|
|
21
127
|
return new Promise((resolve, reject) => {
|
|
22
128
|
const onError = (err) => {
|
|
@@ -34,6 +140,16 @@ const createSocket = async (config, implicitTls) => {
|
|
|
34
140
|
servername: config.host,
|
|
35
141
|
})
|
|
36
142
|
: net.connect({ host: config.host, port: config.port });
|
|
143
|
+
if (typeof socket.setTimeout === 'function') {
|
|
144
|
+
socket.setTimeout(10000);
|
|
145
|
+
}
|
|
146
|
+
socket.once('timeout', () => {
|
|
147
|
+
socket.destroy();
|
|
148
|
+
reject(ErrorFactory.createConnectionError('SMTP connection timed out', {
|
|
149
|
+
host: config.host,
|
|
150
|
+
port: config.port,
|
|
151
|
+
}));
|
|
152
|
+
});
|
|
37
153
|
if (implicitTls) {
|
|
38
154
|
socket.once('secureConnect', () => resolve(socket));
|
|
39
155
|
}
|
|
@@ -43,9 +159,67 @@ const createSocket = async (config, implicitTls) => {
|
|
|
43
159
|
socket.once('error', onError);
|
|
44
160
|
});
|
|
45
161
|
};
|
|
162
|
+
const createWorkersSocket = async (config, implicitTls) => {
|
|
163
|
+
validateConfig(config);
|
|
164
|
+
return new Promise((resolve, reject) => {
|
|
165
|
+
let cleanup = () => undefined;
|
|
166
|
+
const onError = (err) => {
|
|
167
|
+
cleanup();
|
|
168
|
+
reject(ErrorFactory.createConnectionError('SMTP connection failed', {
|
|
169
|
+
host: config.host,
|
|
170
|
+
port: config.port,
|
|
171
|
+
secure: implicitTls,
|
|
172
|
+
error: err,
|
|
173
|
+
}));
|
|
174
|
+
};
|
|
175
|
+
const socketFactoryPromise = loadCloudflareSocketFactory();
|
|
176
|
+
socketFactoryPromise
|
|
177
|
+
.then((socketFactory) => {
|
|
178
|
+
const socket = socketFactory.create(config.host, config.port, {
|
|
179
|
+
tls: implicitTls,
|
|
180
|
+
});
|
|
181
|
+
if (!socket) {
|
|
182
|
+
reject(ErrorFactory.createConnectionError('SMTP socket initialization failed'));
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
const onConnect = () => {
|
|
186
|
+
cleanup(socket);
|
|
187
|
+
resolve(socket);
|
|
188
|
+
};
|
|
189
|
+
cleanup = (target) => {
|
|
190
|
+
if (!target)
|
|
191
|
+
return;
|
|
192
|
+
if (typeof target.off === 'function') {
|
|
193
|
+
target.off('connect', onConnect);
|
|
194
|
+
target.off('error', onError);
|
|
195
|
+
}
|
|
196
|
+
else if (typeof target.removeListener === 'function') {
|
|
197
|
+
target.removeListener('connect', onConnect);
|
|
198
|
+
target.removeListener('error', onError);
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
socket.once('connect', onConnect);
|
|
202
|
+
socket.once('error', onError);
|
|
203
|
+
})
|
|
204
|
+
.catch((err) => {
|
|
205
|
+
reject(ErrorFactory.createConnectionError('SMTP socket initialization failed', {
|
|
206
|
+
error: err,
|
|
207
|
+
}));
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
};
|
|
211
|
+
const createSocket = async (config, implicitTls) => {
|
|
212
|
+
if (isWorkersRuntime())
|
|
213
|
+
return createWorkersSocket(config, implicitTls);
|
|
214
|
+
return createNodeSocket(config, implicitTls);
|
|
215
|
+
};
|
|
46
216
|
const upgradeToStartTls = async (socket, host) => {
|
|
217
|
+
if (typeof socket.startTls === 'function') {
|
|
218
|
+
await socket.startTls();
|
|
219
|
+
return socket;
|
|
220
|
+
}
|
|
47
221
|
return new Promise((resolve, reject) => {
|
|
48
|
-
const tlsSocket = tls.connect({ socket, servername: host });
|
|
222
|
+
const tlsSocket = tls.connect({ socket: socket, servername: host });
|
|
49
223
|
tlsSocket.once('secureConnect', () => {
|
|
50
224
|
resolve(tlsSocket);
|
|
51
225
|
});
|
|
@@ -68,7 +242,8 @@ const createLineReader = (socket) => {
|
|
|
68
242
|
}
|
|
69
243
|
};
|
|
70
244
|
const onData = (data) => {
|
|
71
|
-
|
|
245
|
+
const chunk = data instanceof Uint8Array ? data : Buffer.from(String(data));
|
|
246
|
+
buffer += Buffer.from(chunk).toString('utf8');
|
|
72
247
|
wake();
|
|
73
248
|
};
|
|
74
249
|
socket.on('data', onData);
|
|
@@ -84,7 +259,19 @@ const createLineReader = (socket) => {
|
|
|
84
259
|
const immediate = tryReadLineFromBuffer();
|
|
85
260
|
if (typeof immediate === 'string')
|
|
86
261
|
return immediate;
|
|
87
|
-
await new Promise((resolve) =>
|
|
262
|
+
await new Promise((resolve, reject) => {
|
|
263
|
+
let fired = false;
|
|
264
|
+
const timer = globalThis.setTimeout(() => {
|
|
265
|
+
fired = true;
|
|
266
|
+
reject(ErrorFactory.createConnectionError('SMTP read timeout'));
|
|
267
|
+
}, 30000);
|
|
268
|
+
waiters.push(() => {
|
|
269
|
+
if (fired)
|
|
270
|
+
return;
|
|
271
|
+
clearTimeout(timer);
|
|
272
|
+
resolve();
|
|
273
|
+
});
|
|
274
|
+
});
|
|
88
275
|
return readLine();
|
|
89
276
|
};
|
|
90
277
|
const readMultiline = async (code, message) => {
|
|
@@ -112,20 +299,39 @@ const createLineReader = (socket) => {
|
|
|
112
299
|
return { code, message };
|
|
113
300
|
};
|
|
114
301
|
const close = () => {
|
|
115
|
-
socket.off
|
|
302
|
+
if (typeof socket.off === 'function') {
|
|
303
|
+
socket.off('data', onData);
|
|
304
|
+
}
|
|
116
305
|
};
|
|
117
306
|
return { readResponse, close };
|
|
118
307
|
};
|
|
119
|
-
const
|
|
308
|
+
const writeRaw = async (socket, data) => {
|
|
120
309
|
return new Promise((resolve, reject) => {
|
|
121
|
-
|
|
310
|
+
let settled = false;
|
|
311
|
+
const finish = (err) => {
|
|
312
|
+
if (settled)
|
|
313
|
+
return;
|
|
314
|
+
settled = true;
|
|
122
315
|
if (err)
|
|
123
316
|
reject(err);
|
|
124
317
|
else
|
|
125
318
|
resolve();
|
|
126
|
-
}
|
|
319
|
+
};
|
|
320
|
+
try {
|
|
321
|
+
const writer = socket;
|
|
322
|
+
writer.write(data, (err) => finish(err));
|
|
323
|
+
if (writer.write.length < 2) {
|
|
324
|
+
finish();
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
catch (err) {
|
|
328
|
+
finish(err);
|
|
329
|
+
}
|
|
127
330
|
});
|
|
128
331
|
};
|
|
332
|
+
const writeLine = async (socket, line) => {
|
|
333
|
+
return writeRaw(socket, `${line}\r\n`);
|
|
334
|
+
};
|
|
129
335
|
const assertCode = (res, expected, context) => {
|
|
130
336
|
const allowed = Array.isArray(expected) ? expected : [expected];
|
|
131
337
|
if (!allowed.includes(res.code)) {
|
|
@@ -213,14 +419,7 @@ const doData = async (socket, reader, message) => {
|
|
|
213
419
|
assertCode(dataRes, 354, 'DATA');
|
|
214
420
|
const raw = buildRfc2822Message(message);
|
|
215
421
|
const stuffed = dotStuff(raw);
|
|
216
|
-
await
|
|
217
|
-
socket.write(`${stuffed}\r\n.\r\n`, (err) => {
|
|
218
|
-
if (err)
|
|
219
|
-
reject(err);
|
|
220
|
-
else
|
|
221
|
-
resolve();
|
|
222
|
-
});
|
|
223
|
-
});
|
|
422
|
+
await writeRaw(socket, `${stuffed}\r\n.\r\n`);
|
|
224
423
|
const queued = await reader.readResponse();
|
|
225
424
|
assertCode(queued, 250, 'message body');
|
|
226
425
|
};
|
|
@@ -304,6 +503,12 @@ export const SmtpDriver = Object.freeze({
|
|
|
304
503
|
* - `secure='starttls'` performs STARTTLS after EHLO.
|
|
305
504
|
*/
|
|
306
505
|
async send(config, message) {
|
|
506
|
+
if (shouldUseProxy()) {
|
|
507
|
+
const proxyUrl = Env.SMTP_PROXY_URL;
|
|
508
|
+
Logger.debug('[SmtpDriver] Using SmtpProxy', { proxyUrl });
|
|
509
|
+
const result = await sendViaProxy(message);
|
|
510
|
+
return { ok: Boolean(result.ok), provider: 'smtp', messageId: result.messageId };
|
|
511
|
+
}
|
|
307
512
|
let mode = 'none';
|
|
308
513
|
if (config.secure === true)
|
|
309
514
|
mode = 'tls';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/tools/mail/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAsB,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAI7E,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE;QACL,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,WAAW,CAAC,EAAE,eAAe,EAAE,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,UAAU,GAAG,UAAU,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,GAAG,YAAY,CAAC;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/tools/mail/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAsB,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAI7E,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE;QACL,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,WAAW,CAAC,EAAE,eAAe,EAAE,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,UAAU,GAAG,UAAU,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,GAAG,YAAY,CAAC;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAgJF,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAsBD,eAAO,MAAM,IAAI;IACf;;OAEG;kBACiB,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC;IAIrD,sBAAsB;gBACJ,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC;IAGnD;;;;OAIG;iBACU,MAAM;cAnEb,CAAC,KAAK,EAAE,aAAa,KAAK,OAAO,CAAC,cAAc,CAAC;;gBAuErC,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;EAGzD,CAAC;AAEH,eAAe,IAAI,CAAC"}
|
package/src/tools/mail/index.js
CHANGED
|
@@ -70,10 +70,7 @@ const sendWithDriver = async (driver, message) => {
|
|
|
70
70
|
throw ErrorFactory.createConfigError(`Mail driver not registered: ${driver.driver} (run \`zin add mail:${driver.driver}\` / \`npm i @zintrust/mail-${driver.driver}\`)`);
|
|
71
71
|
}
|
|
72
72
|
// Config exists for future drivers, but implementations are intentionally CLI/runtime-safe and added incrementally.
|
|
73
|
-
{
|
|
74
|
-
const err = ErrorFactory.createConfigError(`Mail driver not implemented: ${mailConfig.default}`);
|
|
75
|
-
throw err;
|
|
76
|
-
}
|
|
73
|
+
throw ErrorFactory.createConfigError(`Mail driver not registered: ${mailConfig.default}. Available drivers: ses, sendgrid, mailgun, smtp. Run \`zin add mail:${mailConfig.default}\` to install.`);
|
|
77
74
|
};
|
|
78
75
|
const createMailer = (name) => Object.freeze({
|
|
79
76
|
async send(input) {
|
|
@@ -95,10 +92,14 @@ const createMailer = (name) => Object.freeze({
|
|
|
95
92
|
});
|
|
96
93
|
},
|
|
97
94
|
});
|
|
95
|
+
const looksLikeHtml = (value) => /<\s*html\b|<!doctype\b|<\s*body\b/i.test(value);
|
|
98
96
|
async function renderTemplateToHtml(input) {
|
|
99
97
|
const { template, variables } = input;
|
|
100
98
|
// Import lazily to avoid circular deps
|
|
101
99
|
const { loadTemplate } = await import('./template-loader.js');
|
|
100
|
+
if (looksLikeHtml(template)) {
|
|
101
|
+
return loadTemplate(template, (variables ?? {}));
|
|
102
|
+
}
|
|
102
103
|
// template-loader expects full filename
|
|
103
104
|
const fileName = template.endsWith('.html') ? template : `${template}.html`;
|
|
104
105
|
return loadTemplate(fileName, (variables ?? {}));
|