@zintrust/core 0.1.21 → 0.1.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/z.d.ts +1 -1
- package/bin/z.js +1 -1
- package/bin/zin.d.ts +1 -1
- package/bin/zin.js +1 -1
- package/bin/zintrust-main.d.ts +1 -1
- package/bin/zintrust-main.js +2 -2
- package/bin/zintrust-microservices.d.ts +1 -1
- package/bin/zintrust-microservices.js +1 -1
- package/bin/zintrust.d.ts +1 -1
- package/bin/zintrust.js +1 -1
- package/bin/zt.d.ts +1 -1
- package/bin/zt.js +1 -1
- package/package.json +2 -3
- package/public/index.html +3 -3
- package/routes/api.js +1 -1
- package/routes/health.d.ts +3 -4
- package/routes/health.d.ts.map +1 -1
- package/routes/health.js +3 -125
- package/src/boot/Application.d.ts.map +1 -1
- package/src/boot/Application.js +11 -22
- package/src/boot/bootstrap.d.ts +1 -1
- package/src/boot/bootstrap.js +48 -7
- package/src/builder/BundleOptimizer.d.ts +1 -1
- package/src/builder/BundleOptimizer.js +1 -1
- package/src/cache/drivers/KVRemoteDriver.d.ts +1 -1
- package/src/cache/drivers/KVRemoteDriver.js +1 -1
- package/src/cli/CLI.d.ts.map +1 -1
- package/src/cli/CLI.js +15 -1
- package/src/cli/ErrorHandler.js +3 -3
- package/src/cli/commands/AddCommand.d.ts +1 -1
- package/src/cli/commands/AddCommand.d.ts.map +1 -1
- package/src/cli/commands/AddCommand.js +1 -1
- package/src/cli/commands/DbSeedCommand.js +1 -1
- package/src/cli/commands/MakeMailTemplateCommand.js +2 -1
- package/src/cli/commands/MakeNotificationTemplateCommand.js +2 -1
- package/src/cli/commands/MigrateCommand.d.ts.map +1 -1
- package/src/cli/commands/MigrateCommand.js +1 -1
- package/src/cli/commands/MigrateWorkerCommand.d.ts +9 -0
- package/src/cli/commands/MigrateWorkerCommand.d.ts.map +1 -0
- package/src/cli/commands/MigrateWorkerCommand.js +182 -0
- package/src/cli/commands/NewCommand.d.ts +1 -1
- package/src/cli/commands/NewCommand.d.ts.map +1 -1
- package/src/cli/commands/NewCommand.js +21 -7
- package/src/cli/commands/PublishCommand.d.ts +5 -0
- package/src/cli/commands/PublishCommand.d.ts.map +1 -0
- package/src/cli/commands/PublishCommand.js +54 -0
- package/src/cli/commands/QACommand.js +4 -4
- package/src/cli/commands/ResourceControlCommand.d.ts +6 -0
- package/src/cli/commands/ResourceControlCommand.d.ts.map +1 -0
- package/src/cli/commands/ResourceControlCommand.js +43 -0
- package/src/cli/commands/SimulateCommand.d.ts +1 -1
- package/src/cli/commands/SimulateCommand.js +4 -4
- package/src/cli/commands/StartCommand.d.ts.map +1 -1
- package/src/cli/commands/StartCommand.js +19 -7
- package/src/cli/commands/UpgradeCommand.d.ts +1 -1
- package/src/cli/commands/UpgradeCommand.js +2 -2
- package/src/cli/commands/WorkerCommands.d.ts +17 -0
- package/src/cli/commands/WorkerCommands.d.ts.map +1 -0
- package/src/cli/commands/WorkerCommands.js +264 -0
- 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/config/ConfigSchema.d.ts +1 -1
- package/src/cli/config/ConfigSchema.d.ts.map +1 -1
- package/src/cli/config/ConfigSchema.js +4 -3
- package/src/cli/d1/D1SqlMigrations.d.ts.map +1 -1
- package/src/cli/d1/D1SqlMigrations.js +4 -3
- package/src/cli/scaffolding/ModelGenerator.d.ts +1 -1
- package/src/cli/scaffolding/ModelGenerator.d.ts.map +1 -1
- package/src/cli/scaffolding/ModelGenerator.js +10 -2
- package/src/cli/scaffolding/ProjectScaffolder.js +5 -5
- package/src/cli/scaffolding/RouteGenerator.d.ts.map +1 -1
- package/src/cli/scaffolding/RouteGenerator.js +21 -2
- package/src/cli/scaffolding/TemplateEngine.js +1 -1
- package/src/cli/utils/EnvFileLoader.d.ts.map +1 -1
- package/src/common/ExternalServiceUtils.d.ts +63 -0
- package/src/common/ExternalServiceUtils.d.ts.map +1 -0
- package/src/common/ExternalServiceUtils.js +116 -0
- package/src/common/HealthRoutes.d.ts +10 -0
- package/src/common/HealthRoutes.d.ts.map +1 -0
- package/src/common/HealthRoutes.js +114 -0
- package/src/config/SecretsManager.d.ts.map +1 -1
- package/src/config/SecretsManager.js +2 -1
- package/src/config/app.d.ts +2 -1
- package/src/config/app.d.ts.map +1 -1
- package/src/config/app.js +98 -52
- package/src/config/broadcast.d.ts.map +1 -1
- package/src/config/broadcast.js +2 -2
- package/src/config/cache.d.ts.map +1 -1
- package/src/config/cache.js +2 -2
- package/src/config/database.d.ts.map +1 -1
- package/src/config/database.js +24 -5
- package/src/config/env.d.ts +43 -1
- package/src/config/env.d.ts.map +1 -1
- package/src/config/env.js +68 -21
- package/src/config/index.d.ts +10 -1
- package/src/config/index.d.ts.map +1 -1
- package/src/config/index.js +1 -0
- package/src/config/mail.d.ts.map +1 -1
- package/src/config/mail.js +3 -3
- package/src/config/middleware.d.ts.map +1 -1
- package/src/config/middleware.js +1 -1
- package/src/config/notification.d.ts.map +1 -1
- package/src/config/notification.js +2 -2
- package/src/config/queue.d.ts +14 -0
- package/src/config/queue.d.ts.map +1 -1
- package/src/config/queue.js +61 -36
- package/src/config/security.js +2 -2
- package/src/config/storage.d.ts.map +1 -1
- package/src/config/storage.js +5 -5
- package/src/config/type.d.ts +122 -0
- package/src/config/type.d.ts.map +1 -1
- package/src/config/type.js +10 -1
- package/src/config/workers.d.ts +13 -0
- package/src/config/workers.d.ts.map +1 -0
- package/src/config/workers.js +173 -0
- package/src/database/Paginator.d.ts +37 -0
- package/src/database/Paginator.d.ts.map +1 -0
- package/src/database/Paginator.js +81 -0
- package/src/exceptions/ZintrustError.d.ts +5 -2
- package/src/exceptions/ZintrustError.d.ts.map +1 -1
- package/src/exceptions/ZintrustError.js +6 -2
- package/src/features/Auth.d.ts +1 -1
- package/src/features/Auth.d.ts.map +1 -1
- package/src/features/Auth.js +3 -2
- package/src/features/Queue.d.ts.map +1 -1
- package/src/features/Queue.js +0 -2
- package/src/index.d.ts +15 -5
- package/src/index.d.ts.map +1 -1
- package/src/index.js +24 -3
- package/src/microservices/MicroserviceBootstrap.d.ts.map +1 -1
- package/src/microservices/MicroserviceBootstrap.js +3 -1
- package/src/microservices/MicroserviceGenerator.js +4 -4
- package/src/microservices/MicroserviceManager.d.ts +1 -1
- package/src/microservices/MicroserviceManager.js +1 -1
- package/src/middleware/RateLimiter.d.ts.map +1 -1
- package/src/middleware/RateLimiter.js +4 -3
- package/src/migrations/MigrationLoader.d.ts +1 -1
- package/src/migrations/MigrationLoader.d.ts.map +1 -1
- package/src/migrations/Migrator.d.ts +3 -3
- package/src/migrations/Migrator.d.ts.map +1 -1
- package/src/migrations/Migrator.js +1 -1
- package/src/migrations/MigratorFactory.d.ts +1 -1
- package/src/migrations/MigratorFactory.d.ts.map +1 -1
- package/src/migrations/MigratorFactory.js +3 -3
- package/src/migrations/enum/index.d.ts +93 -0
- package/src/migrations/enum/index.d.ts.map +1 -0
- package/src/migrations/enum/index.js +92 -0
- package/src/migrations/schema/Blueprint.d.ts +1 -1
- package/src/migrations/schema/Blueprint.d.ts.map +1 -1
- package/src/migrations/schema/Blueprint.js +27 -25
- package/src/migrations/schema/Schema.d.ts +1 -1
- package/src/migrations/schema/Schema.d.ts.map +1 -1
- package/src/migrations/schema/Schema.js +4 -3
- package/src/migrations/schema/SchemaCompiler.d.ts +1 -1
- package/src/migrations/schema/SchemaCompiler.d.ts.map +1 -1
- package/src/migrations/schema/SchemaCompiler.js +99 -91
- package/src/migrations/schema/index.d.ts +4 -4
- package/src/migrations/schema/index.d.ts.map +1 -1
- package/src/migrations/schema/index.js +3 -3
- package/src/migrations/schema/types.d.ts +2 -1
- package/src/migrations/schema/types.d.ts.map +1 -1
- 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/os.d.ts +10 -1
- package/src/node-singletons/os.d.ts.map +1 -1
- package/src/node-singletons/os.js +10 -1
- package/src/openapi/OpenApiGenerator.js +2 -2
- package/src/orm/ConnectionManager.d.ts +7 -5
- package/src/orm/ConnectionManager.d.ts.map +1 -1
- package/src/orm/ConnectionManager.js +249 -93
- package/src/orm/Database.d.ts +2 -1
- package/src/orm/Database.d.ts.map +1 -1
- package/src/orm/DatabaseAdapter.d.ts +3 -2
- package/src/orm/DatabaseAdapter.d.ts.map +1 -1
- package/src/orm/DatabaseAdapter.js +17 -0
- package/src/orm/Model.d.ts +8 -1
- package/src/orm/Model.d.ts.map +1 -1
- package/src/orm/Model.js +109 -26
- package/src/orm/QueryBuilder.d.ts +12 -2
- package/src/orm/QueryBuilder.d.ts.map +1 -1
- package/src/orm/QueryBuilder.js +438 -38
- package/src/orm/Relationships.d.ts +61 -1
- package/src/orm/Relationships.d.ts.map +1 -1
- package/src/orm/Relationships.js +190 -0
- package/src/orm/adapters/D1Adapter.d.ts.map +1 -1
- package/src/orm/adapters/D1Adapter.js +2 -1
- package/src/orm/adapters/D1RemoteAdapter.d.ts +1 -1
- package/src/orm/adapters/D1RemoteAdapter.d.ts.map +1 -1
- package/src/orm/adapters/D1RemoteAdapter.js +3 -2
- package/src/orm/adapters/MySQLAdapter.d.ts.map +1 -1
- package/src/orm/adapters/MySQLAdapter.js +2 -1
- package/src/orm/adapters/SQLServerAdapter.d.ts.map +1 -1
- package/src/orm/adapters/SQLServerAdapter.js +2 -1
- package/src/orm/adapters/SQLiteAdapter.d.ts.map +1 -1
- package/src/orm/adapters/SQLiteAdapter.js +2 -1
- package/src/orm/migrations/MigrationStore.d.ts.map +1 -1
- package/src/performance/Optimizer.d.ts.map +1 -1
- package/src/performance/Optimizer.js +57 -18
- package/src/profiling/RequestProfiler.d.ts.map +1 -1
- package/src/profiling/RequestProfiler.js +3 -1
- package/src/routing/CoreRoutes.d.ts +1 -1
- package/src/routing/CoreRoutes.d.ts.map +1 -1
- package/src/routing/CoreRoutes.js +2 -116
- package/src/routing/error.d.ts.map +1 -1
- package/src/routing/error.js +3 -2
- package/src/routing/publicRoot.d.ts.map +1 -1
- package/src/routing/publicRoot.js +4 -2
- package/src/runtime/PluginAutoImports.d.ts.map +1 -1
- package/src/runtime/PluginAutoImports.js +20 -4
- package/src/runtime/PluginManager.d.ts.map +1 -1
- package/src/runtime/PluginManager.js +23 -6
- package/src/runtime/RuntimeAdapter.d.ts +3 -3
- package/src/runtime/RuntimeAdapter.d.ts.map +1 -1
- package/src/runtime/StartupConfigFileRegistry.d.ts +15 -13
- package/src/runtime/StartupConfigFileRegistry.d.ts.map +1 -1
- package/src/runtime/StartupConfigFileRegistry.js +12 -12
- package/src/runtime/adapters/CloudflareAdapter.d.ts.map +1 -1
- package/src/runtime/adapters/CloudflareAdapter.js +1 -1
- package/src/runtime/adapters/DenoAdapter.d.ts.map +1 -1
- package/src/runtime/adapters/DenoAdapter.js +1 -1
- package/src/runtime/adapters/FargateAdapter.d.ts +2 -2
- package/src/runtime/adapters/FargateAdapter.d.ts.map +1 -1
- package/src/runtime/adapters/FargateAdapter.js +1 -1
- package/src/runtime/adapters/LambdaAdapter.d.ts +1 -1
- package/src/runtime/adapters/LambdaAdapter.d.ts.map +1 -1
- package/src/runtime/adapters/LambdaAdapter.js +6 -4
- package/src/runtime/adapters/NodeServerAdapter.js +1 -1
- package/src/scripts/GenerateEnvArtifacts.js +1 -1
- package/src/security/SignedRequest.js +1 -1
- package/src/security/StartupSecretValidation.d.ts.map +1 -1
- package/src/security/StartupSecretValidation.js +7 -1
- package/src/start.d.ts.map +1 -1
- package/src/start.js +0 -2
- package/src/templates/features/Auth.ts.tpl +4 -4
- package/src/templates/project/basic/README.md.tpl +1 -1
- package/src/templates/project/basic/app/Middleware/index.ts.tpl +1 -1
- package/src/templates/project/basic/config/notification.ts.tpl +1 -1
- package/src/templates/project/basic/routes/api.ts.tpl +1 -3
- package/src/templates/project/basic/src/index.ts.tpl +1 -1
- package/src/templates/project/basic/src/zintrust.plugins.ts.tpl +1 -1
- package/src/templates/project/basic/template.json +1 -1
- package/src/toolkit/Secrets/index.d.ts.map +1 -1
- package/src/toolkit/Secrets/index.js +13 -9
- package/src/toolkit/Secrets/providers/AwsSecretsManager.d.ts.map +1 -1
- package/src/toolkit/Secrets/providers/AwsSecretsManager.js +20 -7
- package/src/toolkit/Secrets/providers/CloudflareKv.d.ts.map +1 -1
- package/src/toolkit/Secrets/providers/CloudflareKv.js +19 -6
- package/src/tools/http/Http.js +1 -1
- package/src/tools/mail/drivers/Ses.d.ts.map +1 -1
- package/src/tools/mail/drivers/Ses.js +5 -4
- package/src/tools/mail/templates/index.js +2 -2
- package/src/tools/notification/drivers/Termii.d.ts.map +1 -1
- package/src/tools/notification/drivers/Termii.js +6 -17
- package/src/tools/notification/testingHelpers.d.ts.map +1 -1
- package/src/tools/queue/Queue.d.ts.map +1 -1
- package/src/tools/queue/Queue.js +3 -5
- package/src/tools/queue/drivers/Redis.d.ts.map +1 -1
- package/src/tools/queue/drivers/Redis.js +7 -1
- package/src/tools/storage/drivers/S3.d.ts.map +1 -1
- package/src/tools/storage/drivers/S3.js +16 -3
- package/src/routes/health.d.ts +0 -2
- package/src/routes/health.d.ts.map +0 -1
- package/src/routes/health.js +0 -1
- package/src/runtime/RuntimeDetector.d.ts +0 -15
- package/src/runtime/RuntimeDetector.d.ts.map +0 -1
- package/src/runtime/RuntimeDetector.js +0 -271
- package/src/templates/project/basic/routes/health.ts.tpl +0 -143
- package/src/templates/project/basic/routes/metrics.ts.tpl +0 -22
- package/src/workers/BroadcastWorker.d.ts +0 -22
- package/src/workers/BroadcastWorker.d.ts.map +0 -1
- package/src/workers/BroadcastWorker.js +0 -24
- package/src/workers/NotificationWorker.d.ts +0 -22
- package/src/workers/NotificationWorker.d.ts.map +0 -1
- package/src/workers/NotificationWorker.js +0 -23
- package/src/workers/createQueueWorker.d.ts +0 -24
- package/src/workers/createQueueWorker.d.ts.map +0 -1
- package/src/workers/createQueueWorker.js +0 -114
|
@@ -1,271 +0,0 @@
|
|
|
1
|
-
import { Env } from '../config/env.js';
|
|
2
|
-
import Logger from '../config/logger.js';
|
|
3
|
-
import { ErrorFactory } from '../exceptions/ZintrustError.js';
|
|
4
|
-
import { CloudflareAdapter } from './adapters/CloudflareAdapter.js';
|
|
5
|
-
import { DenoAdapter } from './adapters/DenoAdapter.js';
|
|
6
|
-
import { FargateAdapter } from './adapters/FargateAdapter.js';
|
|
7
|
-
import { LambdaAdapter } from './adapters/LambdaAdapter.js';
|
|
8
|
-
import { NodeServerAdapter } from './adapters/NodeServerAdapter.js';
|
|
9
|
-
/**
|
|
10
|
-
* Runtime detector - automatically selects appropriate adapter based on environment
|
|
11
|
-
* Supports: Lambda, Fargate, Cloudflare Workers, Deno, and standard Node.js
|
|
12
|
-
*/
|
|
13
|
-
const RUNTIME_VAR = 'RUNTIME';
|
|
14
|
-
const AUTO = 'auto';
|
|
15
|
-
function ensureInstanceOfCompat(adapterExport) {
|
|
16
|
-
if (typeof adapterExport === 'function' || adapterExport === null)
|
|
17
|
-
return;
|
|
18
|
-
if (typeof adapterExport !== 'object')
|
|
19
|
-
return;
|
|
20
|
-
const obj = adapterExport;
|
|
21
|
-
if (obj[Symbol.hasInstance] !== undefined)
|
|
22
|
-
return;
|
|
23
|
-
// Adapters are typically exported as sealed/frozen namespaces.
|
|
24
|
-
// Some tests mock adapters as plain extensible objects and still assert via `instanceof`.
|
|
25
|
-
// Only patch mocks; never attempt to mutate a sealed export.
|
|
26
|
-
if (Object.isExtensible(obj) === false)
|
|
27
|
-
return;
|
|
28
|
-
try {
|
|
29
|
-
Object.defineProperty(obj, Symbol.hasInstance, {
|
|
30
|
-
value: (instance) => typeof instance === 'object' && instance !== null,
|
|
31
|
-
configurable: true,
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
catch {
|
|
35
|
-
// Best-effort only; never crash runtime detection because of test-compat shims.
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
// Some tests mock adapters as plain factory objects (not constructors) but still
|
|
39
|
-
// assert via `instanceof`. Adding Symbol.hasInstance avoids a TypeError.
|
|
40
|
-
ensureInstanceOfCompat(LambdaAdapter);
|
|
41
|
-
ensureInstanceOfCompat(FargateAdapter);
|
|
42
|
-
ensureInstanceOfCompat(CloudflareAdapter);
|
|
43
|
-
ensureInstanceOfCompat(DenoAdapter);
|
|
44
|
-
ensureInstanceOfCompat(NodeServerAdapter);
|
|
45
|
-
function hasEnvValue(key) {
|
|
46
|
-
return Env.get(key).trim() !== '';
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Detect current runtime environment
|
|
50
|
-
*/
|
|
51
|
-
const detectRuntime = () => {
|
|
52
|
-
const explicit = Env.get('RUNTIME').trim();
|
|
53
|
-
if (explicit !== '' && explicit !== 'auto')
|
|
54
|
-
return explicit;
|
|
55
|
-
// Auto-detection logic
|
|
56
|
-
if (isLambda() === true) {
|
|
57
|
-
return 'lambda';
|
|
58
|
-
}
|
|
59
|
-
if (isCloudflare() === true) {
|
|
60
|
-
return 'cloudflare';
|
|
61
|
-
}
|
|
62
|
-
if (isDeno() === true) {
|
|
63
|
-
return 'deno';
|
|
64
|
-
}
|
|
65
|
-
// Default to nodejs for containers (Fargate, Docker, Cloud Run)
|
|
66
|
-
return 'nodejs';
|
|
67
|
-
};
|
|
68
|
-
/**
|
|
69
|
-
* Create appropriate adapter for detected runtime
|
|
70
|
-
*/
|
|
71
|
-
const createAdapter = (config) => {
|
|
72
|
-
const runtime = detectRuntime();
|
|
73
|
-
return createAdapterForRuntime(runtime, config);
|
|
74
|
-
};
|
|
75
|
-
/**
|
|
76
|
-
* Create adapter for specific runtime
|
|
77
|
-
*/
|
|
78
|
-
const createAdapterForRuntime = (runtime, config) => {
|
|
79
|
-
const logger = config.logger ?? createDefaultLogger();
|
|
80
|
-
switch (runtime.toLowerCase()) {
|
|
81
|
-
case 'lambda':
|
|
82
|
-
logger.info('Using Lambda adapter');
|
|
83
|
-
return LambdaAdapter.create(config);
|
|
84
|
-
case 'fargate':
|
|
85
|
-
logger.info('Using Fargate adapter');
|
|
86
|
-
return FargateAdapter.create(config);
|
|
87
|
-
case 'cloudflare':
|
|
88
|
-
logger.info('Using Cloudflare Workers adapter');
|
|
89
|
-
return CloudflareAdapter.create(config);
|
|
90
|
-
case 'deno':
|
|
91
|
-
logger.info('Using Deno adapter');
|
|
92
|
-
return DenoAdapter.create(config);
|
|
93
|
-
case 'nodejs':
|
|
94
|
-
default:
|
|
95
|
-
logger.info('Using Node.js HTTP server adapter');
|
|
96
|
-
return NodeServerAdapter.create(config);
|
|
97
|
-
}
|
|
98
|
-
};
|
|
99
|
-
/**
|
|
100
|
-
* Check if running on AWS Lambda
|
|
101
|
-
*/
|
|
102
|
-
function isLambda() {
|
|
103
|
-
return (hasEnvValue('LAMBDA_TASK_ROOT') === true ||
|
|
104
|
-
hasEnvValue('AWS_LAMBDA_FUNCTION_NAME') === true ||
|
|
105
|
-
hasEnvValue('AWS_EXECUTION_ENV') === true);
|
|
106
|
-
}
|
|
107
|
-
/**
|
|
108
|
-
* Check if running on Cloudflare Workers
|
|
109
|
-
*/
|
|
110
|
-
function isCloudflare() {
|
|
111
|
-
return globalThis.CF !== undefined;
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Check if running on Deno
|
|
115
|
-
*/
|
|
116
|
-
function isDeno() {
|
|
117
|
-
return globalThis.Deno !== undefined;
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* Get runtime information for logging/debugging
|
|
121
|
-
*/
|
|
122
|
-
const getRuntimeInfo = () => {
|
|
123
|
-
const runtime = detectRuntime();
|
|
124
|
-
const info = {
|
|
125
|
-
detected_runtime: runtime,
|
|
126
|
-
node_env: Env.NODE_ENV,
|
|
127
|
-
node_version: process.version,
|
|
128
|
-
};
|
|
129
|
-
if (runtime === 'lambda') {
|
|
130
|
-
info['lambda_function_name'] = Env.get('AWS_LAMBDA_FUNCTION_NAME', '');
|
|
131
|
-
info['lambda_function_version'] = Env.get('AWS_LAMBDA_FUNCTION_VERSION', '');
|
|
132
|
-
info['aws_region'] = Env.get('AWS_REGION', '');
|
|
133
|
-
}
|
|
134
|
-
else if (runtime === 'deno') {
|
|
135
|
-
// @ts-expect-error - Deno global
|
|
136
|
-
info.deno_version = globalThis['Deno']?.version?.deno;
|
|
137
|
-
}
|
|
138
|
-
return info;
|
|
139
|
-
};
|
|
140
|
-
export const RuntimeDetector = Object.freeze({
|
|
141
|
-
RUNTIME_VAR,
|
|
142
|
-
AUTO,
|
|
143
|
-
detectRuntime,
|
|
144
|
-
createAdapter,
|
|
145
|
-
createAdapterForRuntime,
|
|
146
|
-
getRuntimeInfo,
|
|
147
|
-
});
|
|
148
|
-
const runtimeState = {
|
|
149
|
-
isShuttingDown: false,
|
|
150
|
-
};
|
|
151
|
-
const withTimeout = async (promise, timeoutMs, label) => {
|
|
152
|
-
if (timeoutMs <= 0)
|
|
153
|
-
return promise;
|
|
154
|
-
let timeoutId;
|
|
155
|
-
try {
|
|
156
|
-
const timeoutPromise = new Promise((_, reject) => {
|
|
157
|
-
timeoutId = globalThis.setTimeout(() => {
|
|
158
|
-
reject(ErrorFactory.createGeneralError(label, { timeoutMs }));
|
|
159
|
-
}, timeoutMs);
|
|
160
|
-
});
|
|
161
|
-
return await Promise.race([promise, timeoutPromise]);
|
|
162
|
-
}
|
|
163
|
-
finally {
|
|
164
|
-
if (timeoutId !== undefined)
|
|
165
|
-
globalThis.clearTimeout(timeoutId);
|
|
166
|
-
}
|
|
167
|
-
};
|
|
168
|
-
/**
|
|
169
|
-
* Application bootstrap factory
|
|
170
|
-
* Creates and configures runtime-appropriate HTTP handler
|
|
171
|
-
*/
|
|
172
|
-
/**
|
|
173
|
-
* Initialize application for current runtime
|
|
174
|
-
*/
|
|
175
|
-
const initialize = async (handler) => {
|
|
176
|
-
const config = {
|
|
177
|
-
handler,
|
|
178
|
-
logger: createDefaultLogger(),
|
|
179
|
-
timeout: Env.REQUEST_TIMEOUT,
|
|
180
|
-
maxBodySize: Env.MAX_BODY_SIZE,
|
|
181
|
-
};
|
|
182
|
-
const runtime = detectRuntime();
|
|
183
|
-
const adapter = createAdapterForRuntime(runtime, config);
|
|
184
|
-
runtimeState.adapter = adapter;
|
|
185
|
-
runtimeState.runtime = runtime;
|
|
186
|
-
const logger = adapter.getLogger();
|
|
187
|
-
const runtimeInfo = getRuntimeInfo();
|
|
188
|
-
logger.info('Application initializing', runtimeInfo);
|
|
189
|
-
// Start appropriate server based on runtime
|
|
190
|
-
switch (runtime) {
|
|
191
|
-
case 'fargate':
|
|
192
|
-
case 'nodejs': {
|
|
193
|
-
const port = Env.PORT;
|
|
194
|
-
const host = Env.HOST;
|
|
195
|
-
const serverAdapter = adapter;
|
|
196
|
-
if (serverAdapter.startServer !== undefined) {
|
|
197
|
-
await serverAdapter.startServer(port, host);
|
|
198
|
-
}
|
|
199
|
-
return;
|
|
200
|
-
}
|
|
201
|
-
case 'deno': {
|
|
202
|
-
const port = Env.PORT;
|
|
203
|
-
const host = '0.0.0.0';
|
|
204
|
-
const serverAdapter = adapter;
|
|
205
|
-
if (serverAdapter.startServer !== undefined) {
|
|
206
|
-
await serverAdapter.startServer(port, host);
|
|
207
|
-
}
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
210
|
-
case 'lambda':
|
|
211
|
-
case 'cloudflare':
|
|
212
|
-
// These platforms handle request routing externally
|
|
213
|
-
logger.info('Adapter initialized, ready for events');
|
|
214
|
-
return;
|
|
215
|
-
}
|
|
216
|
-
};
|
|
217
|
-
/**
|
|
218
|
-
* Handle graceful shutdown
|
|
219
|
-
*/
|
|
220
|
-
const shutdown = async (signal = 'SIGTERM') => {
|
|
221
|
-
const logger = createDefaultLogger();
|
|
222
|
-
logger.info(`Received ${signal}, gracefully shutting down...`);
|
|
223
|
-
if (runtimeState.isShuttingDown) {
|
|
224
|
-
process.exit(0);
|
|
225
|
-
return;
|
|
226
|
-
}
|
|
227
|
-
runtimeState.isShuttingDown = true;
|
|
228
|
-
const timeoutMs = Number(Env.SHUTDOWN_TIMEOUT);
|
|
229
|
-
try {
|
|
230
|
-
const adapter = runtimeState.adapter;
|
|
231
|
-
if (typeof adapter?.stop === 'function') {
|
|
232
|
-
await withTimeout(adapter.stop(), timeoutMs, 'Runtime adapter shutdown timed out');
|
|
233
|
-
}
|
|
234
|
-
process.exit(0);
|
|
235
|
-
}
|
|
236
|
-
catch (error) {
|
|
237
|
-
logger.error('Graceful shutdown failed', error);
|
|
238
|
-
process.exit(1);
|
|
239
|
-
}
|
|
240
|
-
finally {
|
|
241
|
-
// In real runtimes `process.exit(...)` ends execution, but in tests it's mocked.
|
|
242
|
-
runtimeState.isShuttingDown = false;
|
|
243
|
-
}
|
|
244
|
-
};
|
|
245
|
-
/**
|
|
246
|
-
* Setup graceful shutdown handlers
|
|
247
|
-
*/
|
|
248
|
-
const setupGracefulShutdown = () => {
|
|
249
|
-
const signals = ['SIGTERM', 'SIGINT'];
|
|
250
|
-
signals.forEach((signal) => {
|
|
251
|
-
process.on(signal, async () => {
|
|
252
|
-
await shutdown(signal);
|
|
253
|
-
});
|
|
254
|
-
});
|
|
255
|
-
};
|
|
256
|
-
export const ApplicationBootstrap = Object.freeze({
|
|
257
|
-
initialize,
|
|
258
|
-
shutdown,
|
|
259
|
-
setupGracefulShutdown,
|
|
260
|
-
});
|
|
261
|
-
function createDefaultLogger() {
|
|
262
|
-
return {
|
|
263
|
-
debug: (msg, data) => Logger.debug(`[Runtime] ${msg}`, data === undefined ? undefined : data),
|
|
264
|
-
info: (msg, data) => Logger.info(`[Runtime] ${msg}`, data === undefined ? undefined : data),
|
|
265
|
-
warn: (msg, data) => Logger.warn(`[Runtime] ${msg}`, data === undefined ? undefined : data),
|
|
266
|
-
error: (msg, err) => {
|
|
267
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
268
|
-
Logger.error(`[Runtime] ${msg}`, { error: message });
|
|
269
|
-
},
|
|
270
|
-
};
|
|
271
|
-
}
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Health Routes
|
|
3
|
-
* Provides health, liveness, and readiness endpoints.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { useDatabase, appConfig, Env , Logger, RuntimeHealthProbes, QueryBuilder} from '@zintrust/core';
|
|
7
|
-
import { type IRouter, Router } from '@zintrust/core';
|
|
8
|
-
|
|
9
|
-
export function registerHealthRoutes(router: IRouter): void {
|
|
10
|
-
registerHealthRoute(router);
|
|
11
|
-
registerHealthLiveRoute(router);
|
|
12
|
-
registerHealthReadyRoute(router);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
function registerHealthRoute(router: IRouter): void {
|
|
16
|
-
Router.get(router, '/health', async (_req, res) => {
|
|
17
|
-
const environment = Env.NODE_ENV ?? 'development';
|
|
18
|
-
|
|
19
|
-
try {
|
|
20
|
-
const db = useDatabase();
|
|
21
|
-
const maybeIsConnected = (db as unknown as { isConnected?: unknown }).isConnected;
|
|
22
|
-
const maybeConnect = (db as unknown as { connect?: unknown }).connect;
|
|
23
|
-
if (typeof maybeIsConnected === 'function' && maybeIsConnected.call(db) === false) {
|
|
24
|
-
if (typeof maybeConnect === 'function') {
|
|
25
|
-
await maybeConnect.call(db);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
await QueryBuilder.ping(db);
|
|
29
|
-
|
|
30
|
-
const uptime =
|
|
31
|
-
typeof process !== 'undefined' && typeof process.uptime === 'function'
|
|
32
|
-
? process.uptime()
|
|
33
|
-
: 0;
|
|
34
|
-
|
|
35
|
-
res.json({
|
|
36
|
-
status: 'healthy',
|
|
37
|
-
timestamp: new Date().toISOString(),
|
|
38
|
-
uptime,
|
|
39
|
-
database: 'connected',
|
|
40
|
-
environment,
|
|
41
|
-
});
|
|
42
|
-
} catch (error) {
|
|
43
|
-
Logger.error('Health check failed:', error);
|
|
44
|
-
|
|
45
|
-
const isProd = environment === 'production' || environment === 'prod';
|
|
46
|
-
|
|
47
|
-
res.setStatus(503).json({
|
|
48
|
-
status: 'unhealthy',
|
|
49
|
-
timestamp: new Date().toISOString(),
|
|
50
|
-
database: 'disconnected',
|
|
51
|
-
error: isProd ? 'Service unavailable' : (error as Error).message,
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function registerHealthLiveRoute(router: IRouter): void {
|
|
58
|
-
Router.get(router, '/health/live', async (_req, res) => {
|
|
59
|
-
const uptime =
|
|
60
|
-
typeof process !== 'undefined' && typeof process.uptime === 'function' ? process.uptime() : 0;
|
|
61
|
-
|
|
62
|
-
res.json({
|
|
63
|
-
status: 'alive',
|
|
64
|
-
timestamp: new Date().toISOString(),
|
|
65
|
-
uptime,
|
|
66
|
-
});
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function registerHealthReadyRoute(router: IRouter): void {
|
|
71
|
-
Router.get(router, '/health/ready', async (_req, res) => {
|
|
72
|
-
const startTime = Date.now();
|
|
73
|
-
const environment = appConfig.environment;
|
|
74
|
-
|
|
75
|
-
let databaseResponseTime: number | null = null;
|
|
76
|
-
let cacheResponseTime: number | null = null;
|
|
77
|
-
|
|
78
|
-
try {
|
|
79
|
-
const db = useDatabase();
|
|
80
|
-
const maybeIsConnected = (db as unknown as { isConnected?: unknown }).isConnected;
|
|
81
|
-
const maybeConnect = (db as unknown as { connect?: unknown }).connect;
|
|
82
|
-
if (typeof maybeIsConnected === 'function' && maybeIsConnected.call(db) === false) {
|
|
83
|
-
if (typeof maybeConnect === 'function') {
|
|
84
|
-
await maybeConnect.call(db);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
await QueryBuilder.ping(db);
|
|
88
|
-
|
|
89
|
-
databaseResponseTime = Date.now() - startTime;
|
|
90
|
-
|
|
91
|
-
// Only probe KV at runtime when explicitly configured.
|
|
92
|
-
cacheResponseTime = await RuntimeHealthProbes.pingKvCache(2000);
|
|
93
|
-
|
|
94
|
-
res.json({
|
|
95
|
-
status: 'ready',
|
|
96
|
-
timestamp: new Date().toISOString(),
|
|
97
|
-
environment,
|
|
98
|
-
dependencies: {
|
|
99
|
-
database: {
|
|
100
|
-
status: 'ready',
|
|
101
|
-
responseTime: databaseResponseTime,
|
|
102
|
-
},
|
|
103
|
-
...(cacheResponseTime === null
|
|
104
|
-
? {}
|
|
105
|
-
: {
|
|
106
|
-
cache: {
|
|
107
|
-
status: 'ready',
|
|
108
|
-
responseTime: cacheResponseTime,
|
|
109
|
-
},
|
|
110
|
-
}),
|
|
111
|
-
},
|
|
112
|
-
});
|
|
113
|
-
} catch (error) {
|
|
114
|
-
Logger.error('Readiness check failed:', error);
|
|
115
|
-
|
|
116
|
-
const isProd = environment === 'production';
|
|
117
|
-
|
|
118
|
-
const responseTime = Date.now() - startTime;
|
|
119
|
-
|
|
120
|
-
const dependencies: Record<string, unknown> = {
|
|
121
|
-
database: {
|
|
122
|
-
status: databaseResponseTime === null ? 'unavailable' : 'ready',
|
|
123
|
-
responseTime: databaseResponseTime ?? responseTime,
|
|
124
|
-
},
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
if (RuntimeHealthProbes.getCacheDriverName() === 'kv') {
|
|
128
|
-
dependencies['cache'] = {
|
|
129
|
-
status: 'unavailable',
|
|
130
|
-
responseTime: cacheResponseTime ?? responseTime,
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
res.setStatus(503).json({
|
|
135
|
-
status: 'not_ready',
|
|
136
|
-
timestamp: new Date().toISOString(),
|
|
137
|
-
environment,
|
|
138
|
-
dependencies,
|
|
139
|
-
error: isProd ? 'Service unavailable' : (error as Error).message,
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
});
|
|
143
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Metrics Routes
|
|
3
|
-
*
|
|
4
|
-
* Exposes Prometheus metrics when enabled.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { Env, PrometheusMetrics, type IRouter, Router } from '@zintrust/core';
|
|
8
|
-
|
|
9
|
-
export function registerMetricsRoutes(router: IRouter): void {
|
|
10
|
-
if (Env.getBool('METRICS_ENABLED', false) === false) return;
|
|
11
|
-
|
|
12
|
-
const pathFromEnv = Env.get('METRICS_PATH', '/metrics').trim();
|
|
13
|
-
const path = pathFromEnv === '' ? '/metrics' : pathFromEnv;
|
|
14
|
-
|
|
15
|
-
Router.get(router, path, async (_req, res) => {
|
|
16
|
-
const { contentType, body } = await PrometheusMetrics.getMetricsText();
|
|
17
|
-
res.setHeader('Content-Type', contentType);
|
|
18
|
-
res.send(body);
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export default registerMetricsRoutes;
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* BroadcastWorker - Processes queued broadcasts
|
|
3
|
-
*
|
|
4
|
-
* This worker dequeues broadcast messages and sends them using the Broadcast service.
|
|
5
|
-
* Use with Queue.dequeue() in a background process or cron job.
|
|
6
|
-
*/
|
|
7
|
-
export declare const BroadcastWorker: Readonly<{
|
|
8
|
-
processOne: (queueName?: string, driverName?: string) => Promise<boolean>;
|
|
9
|
-
processAll: (queueName?: string, driverName?: string) => Promise<number>;
|
|
10
|
-
runOnce: (opts?: {
|
|
11
|
-
queueName?: string;
|
|
12
|
-
driverName?: string;
|
|
13
|
-
maxItems?: number;
|
|
14
|
-
}) => Promise<number>;
|
|
15
|
-
startWorker: (opts?: {
|
|
16
|
-
queueName?: string;
|
|
17
|
-
driverName?: string;
|
|
18
|
-
signal?: AbortSignal;
|
|
19
|
-
}) => Promise<number>;
|
|
20
|
-
}>;
|
|
21
|
-
export default BroadcastWorker;
|
|
22
|
-
//# sourceMappingURL=BroadcastWorker.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"BroadcastWorker.d.ts","sourceRoot":"","sources":["../../../src/workers/BroadcastWorker.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH,eAAO,MAAM,eAAe;0BAbrB,CAAC,oBAAoB,CAAC;0BAGf,CAAC,oBAAoB,CAAC;kBACnB,CAAC;iBAAiB,CAAC;kBAE3B,CAAC;gBACC,CAAA;;sBAGE,CAAC;iBAGP,CAAA;kBAAwB,CAAC;cAC3B,CAAC;;EAaJ,CAAC;AAEH,eAAe,eAAe,CAAC"}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* BroadcastWorker - Processes queued broadcasts
|
|
3
|
-
*
|
|
4
|
-
* This worker dequeues broadcast messages and sends them using the Broadcast service.
|
|
5
|
-
* Use with Queue.dequeue() in a background process or cron job.
|
|
6
|
-
*/
|
|
7
|
-
import { createQueueWorker } from '../workers/createQueueWorker.js';
|
|
8
|
-
import { Broadcast } from '../tools/broadcast/Broadcast.js';
|
|
9
|
-
export const BroadcastWorker = Object.freeze({
|
|
10
|
-
...createQueueWorker({
|
|
11
|
-
kindLabel: 'broadcast',
|
|
12
|
-
defaultQueueName: 'broadcasts',
|
|
13
|
-
maxAttempts: 3,
|
|
14
|
-
getLogFields: (payload) => ({
|
|
15
|
-
channel: payload.channel,
|
|
16
|
-
event: payload.event,
|
|
17
|
-
queuedAt: payload.timestamp,
|
|
18
|
-
}),
|
|
19
|
-
handle: async (payload) => {
|
|
20
|
-
await Broadcast.send(payload.channel, payload.event, payload.data);
|
|
21
|
-
},
|
|
22
|
-
}),
|
|
23
|
-
});
|
|
24
|
-
export default BroadcastWorker;
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* NotificationWorker - Processes queued notifications
|
|
3
|
-
*
|
|
4
|
-
* This worker dequeues notification messages and sends them using the Notification service.
|
|
5
|
-
* Use with Queue.dequeue() in a background process or cron job.
|
|
6
|
-
*/
|
|
7
|
-
export declare const NotificationWorker: Readonly<{
|
|
8
|
-
processOne: (queueName?: string, driverName?: string) => Promise<boolean>;
|
|
9
|
-
processAll: (queueName?: string, driverName?: string) => Promise<number>;
|
|
10
|
-
runOnce: (opts?: {
|
|
11
|
-
queueName?: string;
|
|
12
|
-
driverName?: string;
|
|
13
|
-
maxItems?: number;
|
|
14
|
-
}) => Promise<number>;
|
|
15
|
-
startWorker: (opts?: {
|
|
16
|
-
queueName?: string;
|
|
17
|
-
driverName?: string;
|
|
18
|
-
signal?: AbortSignal;
|
|
19
|
-
}) => Promise<number>;
|
|
20
|
-
}>;
|
|
21
|
-
export default NotificationWorker;
|
|
22
|
-
//# sourceMappingURL=NotificationWorker.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"NotificationWorker.d.ts","sourceRoot":"","sources":["../../../src/workers/NotificationWorker.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH,eAAO,MAAM,kBAAkB;0BAdyD,CAAC,oBACzE,CAAC;0BAGf,CAAC,oBAAoB,CAAC;kBACnB,CAAC;iBAAkB,CAAA;kBAAwB,CAAC;gBAEtC,CAAC;;sBAGV,CAAC;iBAAiB,CAAC;kBACZ,CAAC;cAGL,CAAC;;EAaJ,CAAC;AAEH,eAAe,kBAAkB,CAAC"}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* NotificationWorker - Processes queued notifications
|
|
3
|
-
*
|
|
4
|
-
* This worker dequeues notification messages and sends them using the Notification service.
|
|
5
|
-
* Use with Queue.dequeue() in a background process or cron job.
|
|
6
|
-
*/
|
|
7
|
-
import { createQueueWorker } from '../workers/createQueueWorker.js';
|
|
8
|
-
import { Notification } from '../tools/notification/Notification.js';
|
|
9
|
-
export const NotificationWorker = Object.freeze({
|
|
10
|
-
...createQueueWorker({
|
|
11
|
-
kindLabel: 'notification',
|
|
12
|
-
defaultQueueName: 'notifications',
|
|
13
|
-
maxAttempts: 3,
|
|
14
|
-
getLogFields: (payload) => ({
|
|
15
|
-
recipient: payload.recipient,
|
|
16
|
-
queuedAt: payload.timestamp,
|
|
17
|
-
}),
|
|
18
|
-
handle: async (payload) => {
|
|
19
|
-
await Notification.send(payload.recipient, payload.message, payload.options);
|
|
20
|
-
},
|
|
21
|
-
}),
|
|
22
|
-
});
|
|
23
|
-
export default NotificationWorker;
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
type QueueWorker = {
|
|
2
|
-
processOne: (queueName?: string, driverName?: string) => Promise<boolean>;
|
|
3
|
-
processAll: (queueName?: string, driverName?: string) => Promise<number>;
|
|
4
|
-
runOnce: (opts?: {
|
|
5
|
-
queueName?: string;
|
|
6
|
-
driverName?: string;
|
|
7
|
-
maxItems?: number;
|
|
8
|
-
}) => Promise<number>;
|
|
9
|
-
startWorker: (opts?: {
|
|
10
|
-
queueName?: string;
|
|
11
|
-
driverName?: string;
|
|
12
|
-
signal?: AbortSignal;
|
|
13
|
-
}) => Promise<number>;
|
|
14
|
-
};
|
|
15
|
-
export type CreateQueueWorkerOptions<TPayload> = {
|
|
16
|
-
kindLabel: string;
|
|
17
|
-
defaultQueueName: string;
|
|
18
|
-
maxAttempts: number;
|
|
19
|
-
getLogFields: (payload: TPayload) => Record<string, unknown>;
|
|
20
|
-
handle: (payload: TPayload) => Promise<void>;
|
|
21
|
-
};
|
|
22
|
-
export declare function createQueueWorker<TPayload>(options: CreateQueueWorkerOptions<TPayload>): QueueWorker;
|
|
23
|
-
export {};
|
|
24
|
-
//# sourceMappingURL=createQueueWorker.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createQueueWorker.d.ts","sourceRoot":"","sources":["../../../src/workers/createQueueWorker.ts"],"names":[],"mappings":"AAGA,KAAK,WAAW,GAAG;IACjB,UAAU,EAAE,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1E,UAAU,EAAE,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACzE,OAAO,EAAE,CAAC,IAAI,CAAC,EAAE;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACtB,WAAW,EAAE,CAAC,IAAI,CAAC,EAAE;QACnB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,MAAM,CAAC,EAAE,WAAW,CAAC;KACtB,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,wBAAwB,CAAC,QAAQ,IAAI;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,CAAC,OAAO,EAAE,QAAQ,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7D,MAAM,EAAE,CAAC,OAAO,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9C,CAAC;AA4IF,wBAAgB,iBAAiB,CAAC,QAAQ,EACxC,OAAO,EAAE,wBAAwB,CAAC,QAAQ,CAAC,GAC1C,WAAW,CAOb"}
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import { Logger } from '../config/logger.js';
|
|
2
|
-
import { Queue } from '../tools/queue/Queue.js';
|
|
3
|
-
const buildBaseLogFields = (message, getLogFields) => {
|
|
4
|
-
return {
|
|
5
|
-
messageId: message.id,
|
|
6
|
-
...getLogFields(message.payload),
|
|
7
|
-
};
|
|
8
|
-
};
|
|
9
|
-
const createProcessOne = (options) => {
|
|
10
|
-
return async (queueName = options.defaultQueueName, driverName) => {
|
|
11
|
-
const message = await Queue.dequeue(queueName, driverName);
|
|
12
|
-
if (!message)
|
|
13
|
-
return false;
|
|
14
|
-
const baseLogFields = buildBaseLogFields(message, options.getLogFields);
|
|
15
|
-
// Check for delayed execution
|
|
16
|
-
const payload = message.payload;
|
|
17
|
-
const rawTimestamp = 'timestamp' in payload ? payload['timestamp'] : 0;
|
|
18
|
-
const timestamp = typeof rawTimestamp === 'number' ? rawTimestamp : 0;
|
|
19
|
-
if (timestamp > Date.now()) {
|
|
20
|
-
Logger.info(`${options.kindLabel} not due yet, re-queueing`, {
|
|
21
|
-
...baseLogFields,
|
|
22
|
-
dueAt: new Date(timestamp).toISOString(),
|
|
23
|
-
});
|
|
24
|
-
// Re-queue original payload
|
|
25
|
-
await Queue.enqueue(queueName, message.payload, driverName);
|
|
26
|
-
await Queue.ack(queueName, message.id, driverName);
|
|
27
|
-
return false;
|
|
28
|
-
}
|
|
29
|
-
try {
|
|
30
|
-
Logger.info(`Processing queued ${options.kindLabel}`, baseLogFields);
|
|
31
|
-
await options.handle(message.payload);
|
|
32
|
-
await Queue.ack(queueName, message.id, driverName);
|
|
33
|
-
Logger.info(`${options.kindLabel} processed successfully`, baseLogFields);
|
|
34
|
-
return true;
|
|
35
|
-
}
|
|
36
|
-
catch (error) {
|
|
37
|
-
const attempts = message.attempts ?? 0;
|
|
38
|
-
Logger.error(`Failed to process ${options.kindLabel}`, {
|
|
39
|
-
...baseLogFields,
|
|
40
|
-
error,
|
|
41
|
-
attempts,
|
|
42
|
-
});
|
|
43
|
-
if (attempts < options.maxAttempts) {
|
|
44
|
-
await Queue.enqueue(queueName, message.payload, driverName);
|
|
45
|
-
Logger.info(`${options.kindLabel} re-queued for retry`, {
|
|
46
|
-
...baseLogFields,
|
|
47
|
-
attempts: attempts + 1,
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
await Queue.ack(queueName, message.id, driverName);
|
|
51
|
-
return false;
|
|
52
|
-
}
|
|
53
|
-
};
|
|
54
|
-
};
|
|
55
|
-
const createProcessAll = (defaultQueueName, processOne) => {
|
|
56
|
-
return async (queueName = defaultQueueName, driverName) => {
|
|
57
|
-
let processed = 0;
|
|
58
|
-
let hasMore = true;
|
|
59
|
-
while (hasMore) {
|
|
60
|
-
// eslint-disable-next-line no-await-in-loop
|
|
61
|
-
hasMore = await processOne(queueName, driverName);
|
|
62
|
-
if (hasMore)
|
|
63
|
-
processed++;
|
|
64
|
-
}
|
|
65
|
-
return processed;
|
|
66
|
-
};
|
|
67
|
-
};
|
|
68
|
-
const createRunOnce = (defaultQueueName, processOne) => {
|
|
69
|
-
return async (opts = {}) => {
|
|
70
|
-
const { queueName = defaultQueueName, driverName, maxItems } = opts;
|
|
71
|
-
let processed = 0;
|
|
72
|
-
if (maxItems === undefined) {
|
|
73
|
-
while (true) {
|
|
74
|
-
// eslint-disable-next-line no-await-in-loop
|
|
75
|
-
const didProcess = await processOne(queueName, driverName);
|
|
76
|
-
if (!didProcess)
|
|
77
|
-
break;
|
|
78
|
-
processed++;
|
|
79
|
-
}
|
|
80
|
-
return processed;
|
|
81
|
-
}
|
|
82
|
-
for (let i = 0; i < maxItems; i++) {
|
|
83
|
-
// eslint-disable-next-line no-await-in-loop
|
|
84
|
-
const didProcess = await processOne(queueName, driverName);
|
|
85
|
-
if (!didProcess)
|
|
86
|
-
break;
|
|
87
|
-
processed++;
|
|
88
|
-
}
|
|
89
|
-
return processed;
|
|
90
|
-
};
|
|
91
|
-
};
|
|
92
|
-
const createStartWorker = (kindLabel, defaultQueueName, processOne) => {
|
|
93
|
-
return async (opts = {}) => {
|
|
94
|
-
const { queueName = defaultQueueName, driverName, signal } = opts;
|
|
95
|
-
Logger.info(`Starting ${kindLabel} worker (drain-until-empty)`, { queueName });
|
|
96
|
-
let processedCount = 0;
|
|
97
|
-
while (signal?.aborted !== true) {
|
|
98
|
-
// eslint-disable-next-line no-await-in-loop
|
|
99
|
-
const didProcess = await processOne(queueName, driverName);
|
|
100
|
-
if (!didProcess)
|
|
101
|
-
break;
|
|
102
|
-
processedCount++;
|
|
103
|
-
}
|
|
104
|
-
Logger.info(`${kindLabel} worker finished (queue drained)`, { queueName, processedCount });
|
|
105
|
-
return processedCount;
|
|
106
|
-
};
|
|
107
|
-
};
|
|
108
|
-
export function createQueueWorker(options) {
|
|
109
|
-
const processOne = createProcessOne(options);
|
|
110
|
-
const processAll = createProcessAll(options.defaultQueueName, processOne);
|
|
111
|
-
const runOnce = createRunOnce(options.defaultQueueName, processOne);
|
|
112
|
-
const startWorker = createStartWorker(options.kindLabel, options.defaultQueueName, processOne);
|
|
113
|
-
return Object.freeze({ processOne, processAll, runOnce, startWorker });
|
|
114
|
-
}
|