@zintrust/core 0.1.14 → 0.1.16
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/package.json +1 -1
- package/src/boot/Application.d.ts.map +1 -1
- package/src/boot/Application.js +29 -61
- package/src/cli/CLI.d.ts.map +1 -1
- package/src/cli/CLI.js +6 -0
- package/src/cli/commands/BroadcastWorkCommand.d.ts +10 -0
- package/src/cli/commands/BroadcastWorkCommand.d.ts.map +1 -0
- package/src/cli/commands/BroadcastWorkCommand.js +16 -0
- package/src/cli/commands/NotificationWorkCommand.d.ts +10 -0
- package/src/cli/commands/NotificationWorkCommand.d.ts.map +1 -0
- package/src/cli/commands/NotificationWorkCommand.js +16 -0
- package/src/cli/commands/QueueCommand.d.ts +10 -0
- package/src/cli/commands/QueueCommand.d.ts.map +1 -0
- package/src/cli/commands/QueueCommand.js +63 -0
- package/src/cli/commands/QueueWorkCommandUtils.d.ts +10 -0
- package/src/cli/commands/QueueWorkCommandUtils.d.ts.map +1 -0
- package/src/cli/commands/QueueWorkCommandUtils.js +43 -0
- package/src/cli/commands/createKindWorkCommand.d.ts +9 -0
- package/src/cli/commands/createKindWorkCommand.d.ts.map +1 -0
- package/src/cli/commands/createKindWorkCommand.js +33 -0
- package/src/cli/commands/index.d.ts +3 -0
- package/src/cli/commands/index.d.ts.map +1 -1
- package/src/cli/commands/index.js +3 -0
- package/src/cli/scaffolding/ModelGenerator.d.ts.map +1 -1
- package/src/cli/scaffolding/ModelGenerator.js +1 -0
- package/src/cli/workers/QueueWorkRunner.d.ts +23 -0
- package/src/cli/workers/QueueWorkRunner.d.ts.map +1 -0
- package/src/cli/workers/QueueWorkRunner.js +142 -0
- package/src/collections/Collection.d.ts +30 -0
- package/src/collections/Collection.d.ts.map +1 -0
- package/src/collections/Collection.js +146 -0
- package/src/collections/index.d.ts +3 -0
- package/src/collections/index.d.ts.map +1 -0
- package/src/collections/index.js +1 -0
- package/src/config/broadcast.d.ts.map +1 -1
- package/src/config/broadcast.js +5 -3
- package/src/config/cache.d.ts.map +1 -1
- package/src/config/cache.js +12 -6
- package/src/config/database.d.ts.map +1 -1
- package/src/config/database.js +5 -3
- package/src/config/mail.d.ts.map +1 -1
- package/src/config/mail.js +21 -14
- package/src/config/notification.d.ts.map +1 -1
- package/src/config/notification.js +10 -5
- package/src/config/storage.d.ts.map +1 -1
- package/src/config/storage.js +5 -6
- package/src/events/EventDispatcher.d.ts +16 -0
- package/src/events/EventDispatcher.d.ts.map +1 -0
- package/src/events/EventDispatcher.js +90 -0
- package/src/events/index.d.ts +3 -0
- package/src/events/index.d.ts.map +1 -0
- package/src/events/index.js +1 -0
- package/src/features/Queue.js +1 -1
- package/src/http/Response.d.ts +2 -2
- package/src/http/Response.d.ts.map +1 -1
- package/src/index.d.ts +11 -0
- package/src/index.d.ts.map +1 -1
- package/src/index.js +11 -0
- package/src/middleware/CsrfMiddleware.d.ts.map +1 -1
- package/src/middleware/CsrfMiddleware.js +20 -25
- package/src/middleware/SessionMiddleware.d.ts +8 -0
- package/src/middleware/SessionMiddleware.d.ts.map +1 -0
- package/src/middleware/SessionMiddleware.js +15 -0
- package/src/orm/DatabaseRuntimeRegistration.d.ts.map +1 -1
- package/src/orm/DatabaseRuntimeRegistration.js +4 -2
- package/src/orm/Model.d.ts +15 -0
- package/src/orm/Model.d.ts.map +1 -1
- package/src/orm/Model.js +57 -8
- package/src/orm/QueryBuilder.d.ts +9 -1
- package/src/orm/QueryBuilder.d.ts.map +1 -1
- package/src/orm/QueryBuilder.js +54 -2
- package/src/scripts/TemplateSync.js +23 -1
- package/src/security/PasswordResetTokenBroker.d.ts +39 -0
- package/src/security/PasswordResetTokenBroker.d.ts.map +1 -0
- package/src/security/PasswordResetTokenBroker.js +131 -0
- package/src/session/SessionManager.d.ts +39 -0
- package/src/session/SessionManager.d.ts.map +1 -0
- package/src/session/SessionManager.js +149 -0
- package/src/session/index.d.ts +3 -0
- package/src/session/index.d.ts.map +1 -0
- package/src/session/index.js +1 -0
- package/src/templates/features/Queue.ts.tpl +4 -3
- package/src/templates/project/basic/config/FileLogWriter.ts.tpl +4 -3
- package/src/templates/project/basic/config/SecretsManager.ts.tpl +1 -1
- package/src/templates/project/basic/config/broadcast.ts.tpl +6 -4
- package/src/templates/project/basic/config/cache.ts.tpl +17 -5
- package/src/templates/project/basic/config/database.ts.tpl +6 -4
- package/src/templates/project/basic/config/features.ts.tpl +2 -2
- package/src/templates/project/basic/config/logger.ts.tpl +0 -2
- package/src/templates/project/basic/config/logging/HttpLogger.ts.tpl +1 -1
- package/src/templates/project/basic/config/logging/SlackLogger.ts.tpl +1 -1
- package/src/templates/project/basic/config/mail.ts.tpl +26 -16
- package/src/templates/project/basic/config/microservices.ts.tpl +1 -1
- package/src/templates/project/basic/config/middleware.ts.tpl +6 -9
- package/src/templates/project/basic/config/notification.ts.tpl +19 -7
- package/src/templates/project/basic/config/security.ts.tpl +1 -2
- package/src/templates/project/basic/config/storage.ts.tpl +8 -6
- package/src/templates/project/basic/config/type.ts.tpl +2 -2
- package/src/tools/broadcast/Broadcast.d.ts +8 -0
- package/src/tools/broadcast/Broadcast.d.ts.map +1 -1
- package/src/tools/broadcast/Broadcast.js +23 -0
- package/src/tools/broadcast/BroadcastRuntimeRegistration.d.ts.map +1 -1
- package/src/tools/broadcast/BroadcastRuntimeRegistration.js +7 -4
- package/src/tools/notification/Notification.d.ts +10 -0
- package/src/tools/notification/Notification.d.ts.map +1 -1
- package/src/tools/notification/Notification.js +21 -0
- package/src/tools/notification/NotificationRuntimeRegistration.d.ts.map +1 -1
- package/src/tools/notification/NotificationRuntimeRegistration.js +7 -4
- package/src/tools/queue/Queue.d.ts.map +1 -1
- package/src/tools/queue/Queue.js +4 -1
- package/src/tools/queue/QueueRuntimeRegistration.d.ts.map +1 -1
- package/src/tools/queue/QueueRuntimeRegistration.js +5 -8
- package/src/tools/storage/StorageRuntimeRegistration.d.ts.map +1 -1
- package/src/tools/storage/StorageRuntimeRegistration.js +8 -10
- package/src/workers/BroadcastWorker.d.ts +22 -0
- package/src/workers/BroadcastWorker.d.ts.map +1 -0
- package/src/workers/BroadcastWorker.js +24 -0
- package/src/workers/NotificationWorker.d.ts +22 -0
- package/src/workers/NotificationWorker.d.ts.map +1 -0
- package/src/workers/NotificationWorker.js +23 -0
- package/src/workers/createQueueWorker.d.ts +24 -0
- package/src/workers/createQueueWorker.d.ts.map +1 -0
- package/src/workers/createQueueWorker.js +114 -0
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Application.d.ts","sourceRoot":"","sources":["../../../src/boot/Application.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,iBAAiB,EAAoB,MAAM,8BAA8B,CAAC;AAEnF,OAAO,EAAE,gBAAgB,EAAmB,MAAM,8BAA8B,CAAC;AACjF,OAAO,EAAE,KAAK,OAAO,EAAU,MAAM,kBAAkB,CAAC;AASxD,MAAM,WAAW,YAAY;IAC3B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,QAAQ,IAAI,OAAO,CAAC;IACpB,aAAa,IAAI,OAAO,CAAC;IACzB,YAAY,IAAI,OAAO,CAAC;IACxB,SAAS,IAAI,OAAO,CAAC;IACrB,cAAc,IAAI,MAAM,CAAC;IACzB,SAAS,IAAI,OAAO,CAAC;IACrB,YAAY,IAAI,iBAAiB,CAAC;IAClC,kBAAkB,IAAI,gBAAgB,CAAC;IACvC,WAAW,IAAI,MAAM,CAAC;CACvB;
|
|
1
|
+
{"version":3,"file":"Application.d.ts","sourceRoot":"","sources":["../../../src/boot/Application.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,iBAAiB,EAAoB,MAAM,8BAA8B,CAAC;AAEnF,OAAO,EAAE,gBAAgB,EAAmB,MAAM,8BAA8B,CAAC;AACjF,OAAO,EAAE,KAAK,OAAO,EAAU,MAAM,kBAAkB,CAAC;AASxD,MAAM,WAAW,YAAY;IAC3B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,QAAQ,IAAI,OAAO,CAAC;IACpB,aAAa,IAAI,OAAO,CAAC;IACzB,YAAY,IAAI,OAAO,CAAC;IACxB,SAAS,IAAI,OAAO,CAAC;IACrB,cAAc,IAAI,MAAM,CAAC;IACzB,SAAS,IAAI,OAAO,CAAC;IACrB,YAAY,IAAI,iBAAiB,CAAC;IAClC,kBAAkB,IAAI,gBAAgB,CAAC;IACvC,WAAW,IAAI,MAAM,CAAC;CACvB;AAsUD;;GAEG;AACH,eAAO,MAAM,WAAW;IACtB;;OAEG;sBACe,MAAM,GAAG,YAAY;EA0CvC,CAAC;AAEH,eAAe,WAAW,CAAC"}
|
package/src/boot/Application.js
CHANGED
|
@@ -197,6 +197,34 @@ const initializeArtifactDirectories = async (resolvedBasePath) => {
|
|
|
197
197
|
}
|
|
198
198
|
}
|
|
199
199
|
};
|
|
200
|
+
const tryImportOptional = async (modulePath) => {
|
|
201
|
+
try {
|
|
202
|
+
return (await import(modulePath));
|
|
203
|
+
}
|
|
204
|
+
catch {
|
|
205
|
+
return undefined;
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
const registerFromRuntimeConfig = async () => {
|
|
209
|
+
const db = await tryImportOptional('@orm/DatabaseRuntimeRegistration');
|
|
210
|
+
db?.registerDatabasesFromRuntimeConfig?.(databaseConfig);
|
|
211
|
+
const queues = await tryImportOptional('@tools/queue/QueueRuntimeRegistration');
|
|
212
|
+
queues?.registerQueuesFromRuntimeConfig?.(queueConfig);
|
|
213
|
+
const caches = await tryImportOptional('@cache/CacheRuntimeRegistration');
|
|
214
|
+
caches?.registerCachesFromRuntimeConfig?.(cacheConfig);
|
|
215
|
+
const broadcasters = await tryImportOptional('@broadcast/BroadcastRuntimeRegistration');
|
|
216
|
+
broadcasters?.registerBroadcastersFromRuntimeConfig?.({
|
|
217
|
+
default: broadcastConfig.default,
|
|
218
|
+
drivers: broadcastConfig.drivers,
|
|
219
|
+
});
|
|
220
|
+
const disks = await tryImportOptional('@storage/StorageRuntimeRegistration');
|
|
221
|
+
disks?.registerDisksFromRuntimeConfig?.(storageConfig);
|
|
222
|
+
const notifications = await tryImportOptional('@notification/NotificationRuntimeRegistration');
|
|
223
|
+
notifications?.registerNotificationChannelsFromRuntimeConfig?.({
|
|
224
|
+
default: notificationConfig.default,
|
|
225
|
+
drivers: notificationConfig.drivers,
|
|
226
|
+
});
|
|
227
|
+
};
|
|
200
228
|
const createLifecycle = (params) => {
|
|
201
229
|
const boot = async () => {
|
|
202
230
|
if (params.getBooted())
|
|
@@ -205,67 +233,7 @@ const createLifecycle = (params) => {
|
|
|
205
233
|
StartupConfigValidator.assertValid();
|
|
206
234
|
FeatureFlags.initialize();
|
|
207
235
|
await StartupHealthChecks.assertHealthy();
|
|
208
|
-
|
|
209
|
-
// This makes every `databaseConfig.connections[name]` available via `useDatabase(undefined, name)`.
|
|
210
|
-
// The configured default is also registered as 'default'.
|
|
211
|
-
try {
|
|
212
|
-
const { registerDatabasesFromRuntimeConfig } = await import('../orm/DatabaseRuntimeRegistration.js');
|
|
213
|
-
registerDatabasesFromRuntimeConfig(databaseConfig);
|
|
214
|
-
}
|
|
215
|
-
catch {
|
|
216
|
-
// best-effort: ignore in restrictive runtimes
|
|
217
|
-
}
|
|
218
|
-
// Register queue drivers from runtime config.
|
|
219
|
-
// Ensures default drivers like `sync` are available without manual registration.
|
|
220
|
-
try {
|
|
221
|
-
const { registerQueuesFromRuntimeConfig } = await import('../tools/queue/QueueRuntimeRegistration.js');
|
|
222
|
-
registerQueuesFromRuntimeConfig(queueConfig);
|
|
223
|
-
}
|
|
224
|
-
catch {
|
|
225
|
-
// best-effort: ignore in restrictive runtimes
|
|
226
|
-
}
|
|
227
|
-
// Register cache driver factories from runtime config.
|
|
228
|
-
// Ensures built-in drivers are available via the driver registry.
|
|
229
|
-
try {
|
|
230
|
-
const { registerCachesFromRuntimeConfig } = await import('../cache/CacheRuntimeRegistration.js');
|
|
231
|
-
registerCachesFromRuntimeConfig(cacheConfig);
|
|
232
|
-
}
|
|
233
|
-
catch {
|
|
234
|
-
// best-effort: ignore in restrictive runtimes
|
|
235
|
-
}
|
|
236
|
-
// Register broadcasters from runtime config.
|
|
237
|
-
// Ensures named broadcasters are available and unknown names throw when selected.
|
|
238
|
-
try {
|
|
239
|
-
const { registerBroadcastersFromRuntimeConfig } = await import('../tools/broadcast/BroadcastRuntimeRegistration.js');
|
|
240
|
-
registerBroadcastersFromRuntimeConfig({
|
|
241
|
-
default: broadcastConfig.default,
|
|
242
|
-
drivers: broadcastConfig.drivers,
|
|
243
|
-
});
|
|
244
|
-
}
|
|
245
|
-
catch {
|
|
246
|
-
// best-effort: ignore in restrictive runtimes
|
|
247
|
-
}
|
|
248
|
-
// Register storage disks from runtime config.
|
|
249
|
-
// Ensures named disks are available and 'default' is a reserved alias.
|
|
250
|
-
try {
|
|
251
|
-
const { registerDisksFromRuntimeConfig } = await import('../tools/storage/StorageRuntimeRegistration.js');
|
|
252
|
-
registerDisksFromRuntimeConfig(storageConfig);
|
|
253
|
-
}
|
|
254
|
-
catch {
|
|
255
|
-
// best-effort: ignore in restrictive runtimes
|
|
256
|
-
}
|
|
257
|
-
// Register notification channels from runtime config.
|
|
258
|
-
// Enables selecting named channels and reserves the `default` alias.
|
|
259
|
-
try {
|
|
260
|
-
const { registerNotificationChannelsFromRuntimeConfig } = await import('../tools/notification/NotificationRuntimeRegistration.js');
|
|
261
|
-
registerNotificationChannelsFromRuntimeConfig({
|
|
262
|
-
default: notificationConfig.default,
|
|
263
|
-
drivers: notificationConfig.drivers,
|
|
264
|
-
});
|
|
265
|
-
}
|
|
266
|
-
catch {
|
|
267
|
-
// best-effort: ignore in restrictive runtimes
|
|
268
|
-
}
|
|
236
|
+
await registerFromRuntimeConfig();
|
|
269
237
|
await initializeArtifactDirectories(params.resolvedBasePath);
|
|
270
238
|
await registerRoutes(params.resolvedBasePath, params.router);
|
|
271
239
|
// Register service providers
|
package/src/cli/CLI.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CLI.d.ts","sourceRoot":"","sources":["../../../src/cli/CLI.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"CLI.d.ts","sourceRoot":"","sources":["../../../src/cli/CLI.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA4BH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,MAAM,WAAW,IAAI;IACnB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,UAAU,IAAI,OAAO,CAAC;CACvB;AAyLD;;;;;;;GAOG;AACH,eAAO,MAAM,GAAG;cACJ,IAAI;EAed,CAAC"}
|
package/src/cli/CLI.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Orchestrates all CLI commands using Commander
|
|
4
4
|
*/
|
|
5
5
|
import { AddCommand } from './commands/AddCommand.js';
|
|
6
|
+
import { BroadcastWorkCommand } from './commands/BroadcastWorkCommand.js';
|
|
6
7
|
import { ConfigCommand } from './commands/ConfigCommand.js';
|
|
7
8
|
import { D1MigrateCommand } from './commands/D1MigrateCommand.js';
|
|
8
9
|
import { DebugCommand } from './commands/DebugCommand.js';
|
|
@@ -12,9 +13,11 @@ import { MakeMailTemplateCommand } from './commands/MakeMailTemplateCommand.js';
|
|
|
12
13
|
import { MakeNotificationTemplateCommand } from './commands/MakeNotificationTemplateCommand.js';
|
|
13
14
|
import { MigrateCommand } from './commands/MigrateCommand.js';
|
|
14
15
|
import { NewCommand } from './commands/NewCommand.js';
|
|
16
|
+
import { NotificationWorkCommand } from './commands/NotificationWorkCommand.js';
|
|
15
17
|
import { PluginCommand } from './commands/PluginCommand.js';
|
|
16
18
|
import { PrepareCommand } from './commands/PrepareCommand.js';
|
|
17
19
|
import { QACommand } from './commands/QACommand.js';
|
|
20
|
+
import { QueueCommand } from './commands/QueueCommand.js';
|
|
18
21
|
import { SecretsCommand } from './commands/SecretsCommand.js';
|
|
19
22
|
import { SimulateCommand } from './commands/SimulateCommand.js';
|
|
20
23
|
import { StartCommand } from './commands/StartCommand.js';
|
|
@@ -68,6 +71,9 @@ const registerCommands = (program) => {
|
|
|
68
71
|
PrepareCommand,
|
|
69
72
|
AddCommand.create(),
|
|
70
73
|
StartCommand.create(),
|
|
74
|
+
QueueCommand.create(),
|
|
75
|
+
BroadcastWorkCommand.create(),
|
|
76
|
+
NotificationWorkCommand.create(),
|
|
71
77
|
MigrateCommand.create(),
|
|
72
78
|
D1MigrateCommand.create(),
|
|
73
79
|
DebugCommand.create(),
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Broadcast Work Command
|
|
3
|
+
* Alias to work a broadcast queue.
|
|
4
|
+
*/
|
|
5
|
+
import { type IBaseCommand } from '../BaseCommand';
|
|
6
|
+
export declare const BroadcastWorkCommand: Readonly<{
|
|
7
|
+
create(): IBaseCommand;
|
|
8
|
+
}>;
|
|
9
|
+
export default BroadcastWorkCommand;
|
|
10
|
+
//# sourceMappingURL=BroadcastWorkCommand.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BroadcastWorkCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/BroadcastWorkCommand.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGrD,eAAO,MAAM,oBAAoB;cACrB,YAAY;EAQtB,CAAC;AAEH,eAAe,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Broadcast Work Command
|
|
3
|
+
* Alias to work a broadcast queue.
|
|
4
|
+
*/
|
|
5
|
+
import { createKindWorkCommand } from '../commands/createKindWorkCommand.js';
|
|
6
|
+
export const BroadcastWorkCommand = Object.freeze({
|
|
7
|
+
create() {
|
|
8
|
+
return createKindWorkCommand({
|
|
9
|
+
name: 'broadcast:work',
|
|
10
|
+
description: 'Work queued broadcasts',
|
|
11
|
+
kind: 'broadcast',
|
|
12
|
+
helpHint: 'zin broadcast:work --help',
|
|
13
|
+
});
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
export default BroadcastWorkCommand;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Notification Work Command
|
|
3
|
+
* Alias to work a notification queue.
|
|
4
|
+
*/
|
|
5
|
+
import { type IBaseCommand } from '../BaseCommand';
|
|
6
|
+
export declare const NotificationWorkCommand: Readonly<{
|
|
7
|
+
create(): IBaseCommand;
|
|
8
|
+
}>;
|
|
9
|
+
export default NotificationWorkCommand;
|
|
10
|
+
//# sourceMappingURL=NotificationWorkCommand.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NotificationWorkCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/NotificationWorkCommand.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGrD,eAAO,MAAM,uBAAuB;cACxB,YAAY;EAQtB,CAAC;AAEH,eAAe,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Notification Work Command
|
|
3
|
+
* Alias to work a notification queue.
|
|
4
|
+
*/
|
|
5
|
+
import { createKindWorkCommand } from '../commands/createKindWorkCommand.js';
|
|
6
|
+
export const NotificationWorkCommand = Object.freeze({
|
|
7
|
+
create() {
|
|
8
|
+
return createKindWorkCommand({
|
|
9
|
+
name: 'notification:work',
|
|
10
|
+
description: 'Work queued notifications',
|
|
11
|
+
kind: 'notification',
|
|
12
|
+
helpHint: 'zin notification:work --help',
|
|
13
|
+
});
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
export default NotificationWorkCommand;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Queue Command
|
|
3
|
+
* Run queued jobs via the framework CLI.
|
|
4
|
+
*/
|
|
5
|
+
import { type IBaseCommand } from '../BaseCommand';
|
|
6
|
+
export declare const QueueCommand: Readonly<{
|
|
7
|
+
create(): IBaseCommand;
|
|
8
|
+
}>;
|
|
9
|
+
export default QueueCommand;
|
|
10
|
+
//# sourceMappingURL=QueueCommand.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QueueCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/QueueCommand.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAoC,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAYvF,eAAO,MAAM,YAAY;cACb,YAAY;EA0EtB,CAAC;AAEH,eAAe,YAAY,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Queue Command
|
|
3
|
+
* Run queued jobs via the framework CLI.
|
|
4
|
+
*/
|
|
5
|
+
import { BaseCommand } from '../BaseCommand.js';
|
|
6
|
+
import { QueueWorkCommandUtils } from '../commands/QueueWorkCommandUtils.js';
|
|
7
|
+
import { QueueWorkRunner } from '../workers/QueueWorkRunner.js';
|
|
8
|
+
export const QueueCommand = Object.freeze({
|
|
9
|
+
create() {
|
|
10
|
+
return BaseCommand.create({
|
|
11
|
+
name: 'queue',
|
|
12
|
+
description: 'Work queued jobs (broadcast/notification)',
|
|
13
|
+
addOptions: (command) => {
|
|
14
|
+
command
|
|
15
|
+
.argument('<queueName>', 'Queue name to work')
|
|
16
|
+
.option('--timeout <seconds>', 'Stop after this many seconds (default: 10)')
|
|
17
|
+
.option('--retry <count>', 'Retries after first attempt (default: 3)')
|
|
18
|
+
.option('--max-items <count>', 'Max items to process in one run (default: 1000)')
|
|
19
|
+
.option('--driver <name>', 'Queue driver name (default: from QUEUE_DRIVER)');
|
|
20
|
+
command
|
|
21
|
+
.command('work <kind> <queueName>')
|
|
22
|
+
.alias('w')
|
|
23
|
+
.description('Work a queue with explicit kind (broadcast|notification)')
|
|
24
|
+
.option('--timeout <seconds>', 'Stop after this many seconds (default: 10)')
|
|
25
|
+
.option('--retry <count>', 'Retries after first attempt (default: 3)')
|
|
26
|
+
.option('--max-items <count>', 'Max items to process in one run (default: 1000)')
|
|
27
|
+
.option('--driver <name>', 'Queue driver name (default: from QUEUE_DRIVER)')
|
|
28
|
+
.action(async (kindRaw, queueName, subOptions) => {
|
|
29
|
+
const kind = QueueWorkRunner.parseKind(kindRaw);
|
|
30
|
+
const timeoutSeconds = QueueWorkCommandUtils.parsePositiveInt(subOptions['timeout'], '--timeout');
|
|
31
|
+
const retry = QueueWorkCommandUtils.parseNonNegativeInt(subOptions['retry'], '--retry');
|
|
32
|
+
const maxItems = QueueWorkCommandUtils.parsePositiveInt(subOptions['maxItems'], '--max-items');
|
|
33
|
+
const driverName = QueueWorkCommandUtils.normalizeDriverName(subOptions['driver']);
|
|
34
|
+
const result = await QueueWorkRunner.run({
|
|
35
|
+
kind,
|
|
36
|
+
queueName,
|
|
37
|
+
timeoutSeconds,
|
|
38
|
+
retry,
|
|
39
|
+
maxItems,
|
|
40
|
+
driverName,
|
|
41
|
+
});
|
|
42
|
+
QueueWorkCommandUtils.logSummary(queueName, kind, result);
|
|
43
|
+
});
|
|
44
|
+
},
|
|
45
|
+
execute: async (options) => {
|
|
46
|
+
const queueName = QueueWorkCommandUtils.requireQueueNameFromArgs(options.args, 'zin queue --help');
|
|
47
|
+
const timeoutSeconds = QueueWorkCommandUtils.parsePositiveInt(options.timeout, '--timeout');
|
|
48
|
+
const retry = QueueWorkCommandUtils.parseNonNegativeInt(options.retry, '--retry');
|
|
49
|
+
const maxItems = QueueWorkCommandUtils.parsePositiveInt(options.maxItems, '--max-items');
|
|
50
|
+
const driverName = QueueWorkCommandUtils.normalizeDriverName(options.driver);
|
|
51
|
+
const result = await QueueWorkRunner.run({
|
|
52
|
+
queueName,
|
|
53
|
+
timeoutSeconds,
|
|
54
|
+
retry,
|
|
55
|
+
maxItems,
|
|
56
|
+
driverName,
|
|
57
|
+
});
|
|
58
|
+
QueueWorkCommandUtils.logSummary(queueName, 'auto', result);
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
export default QueueCommand;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type QueueWorkRunnerResult } from '../workers/QueueWorkRunner';
|
|
2
|
+
export declare const QueueWorkCommandUtils: Readonly<{
|
|
3
|
+
parsePositiveInt: (value: unknown, flag: string) => number | undefined;
|
|
4
|
+
parseNonNegativeInt: (value: unknown, flag: string) => number | undefined;
|
|
5
|
+
normalizeDriverName: (value: unknown) => string | undefined;
|
|
6
|
+
requireQueueNameFromArgs: (args: unknown[] | undefined, helpHint: string) => string;
|
|
7
|
+
logSummary: (queueName: string, kindLabel: string, result: QueueWorkRunnerResult) => void;
|
|
8
|
+
}>;
|
|
9
|
+
export default QueueWorkCommandUtils;
|
|
10
|
+
//# sourceMappingURL=QueueWorkCommandUtils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QueueWorkCommandUtils.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/QueueWorkCommandUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAI1E,eAAO,MAAM,qBAAqB;8BACN,OAAO,QAAQ,MAAM,KAAG,MAAM,GAAG,SAAS;iCAcvC,OAAO,QAAQ,MAAM,KAAG,MAAM,GAAG,SAAS;iCAc1C,OAAO,KAAG,MAAM,GAAG,SAAS;qCAKxB,OAAO,EAAE,GAAG,SAAS,YAAY,MAAM,KAAG,MAAM;4BAQzD,MAAM,aAAa,MAAM,UAAU,qBAAqB,KAAG,IAAI;EAKvF,CAAC;AAEH,eAAe,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Logger } from '../../config/logger.js';
|
|
2
|
+
import { ErrorFactory } from '../../exceptions/ZintrustError.js';
|
|
3
|
+
export const QueueWorkCommandUtils = Object.freeze({
|
|
4
|
+
parsePositiveInt: (value, flag) => {
|
|
5
|
+
if (value === undefined)
|
|
6
|
+
return undefined;
|
|
7
|
+
const raw = String(value).trim();
|
|
8
|
+
if (raw === '')
|
|
9
|
+
return undefined;
|
|
10
|
+
const n = Number.parseInt(raw, 10);
|
|
11
|
+
if (!Number.isFinite(n) || n <= 0) {
|
|
12
|
+
throw ErrorFactory.createCliError(`Error: Invalid ${flag} '${raw}'. Expected a positive integer.`);
|
|
13
|
+
}
|
|
14
|
+
return n;
|
|
15
|
+
},
|
|
16
|
+
parseNonNegativeInt: (value, flag) => {
|
|
17
|
+
if (value === undefined)
|
|
18
|
+
return undefined;
|
|
19
|
+
const raw = String(value).trim();
|
|
20
|
+
if (raw === '')
|
|
21
|
+
return undefined;
|
|
22
|
+
const n = Number.parseInt(raw, 10);
|
|
23
|
+
if (!Number.isFinite(n) || n < 0) {
|
|
24
|
+
throw ErrorFactory.createCliError(`Error: Invalid ${flag} '${raw}'. Expected a non-negative integer.`);
|
|
25
|
+
}
|
|
26
|
+
return n;
|
|
27
|
+
},
|
|
28
|
+
normalizeDriverName: (value) => {
|
|
29
|
+
const raw = typeof value === 'string' ? value.trim() : '';
|
|
30
|
+
return raw === '' ? undefined : raw;
|
|
31
|
+
},
|
|
32
|
+
requireQueueNameFromArgs: (args, helpHint) => {
|
|
33
|
+
const queueName = typeof args?.[0] === 'string' ? String(args[0]) : '';
|
|
34
|
+
if (queueName.trim() === '') {
|
|
35
|
+
throw ErrorFactory.createCliError(`Error: Missing <queueName>. Try '${helpHint}'.`);
|
|
36
|
+
}
|
|
37
|
+
return queueName;
|
|
38
|
+
},
|
|
39
|
+
logSummary: (queueName, kindLabel, result) => {
|
|
40
|
+
Logger.info(`Queue work complete (${kindLabel}) for '${queueName}': processed=${result.processed} retried=${result.retried} dropped=${result.dropped} notDueRequeued=${result.notDueRequeued} unknown=${result.unknown}`);
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
export default QueueWorkCommandUtils;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type IBaseCommand } from '../BaseCommand';
|
|
2
|
+
import { type QueueWorkKind } from '../workers/QueueWorkRunner';
|
|
3
|
+
export declare function createKindWorkCommand(options: {
|
|
4
|
+
name: string;
|
|
5
|
+
description: string;
|
|
6
|
+
kind: QueueWorkKind;
|
|
7
|
+
helpHint: string;
|
|
8
|
+
}): IBaseCommand;
|
|
9
|
+
//# sourceMappingURL=createKindWorkCommand.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createKindWorkCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/createKindWorkCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEvF,OAAO,EAAmB,KAAK,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAUnF,wBAAgB,qBAAqB,CAAC,OAAO,EAAE;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,aAAa,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,YAAY,CAsCf"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { BaseCommand } from '../BaseCommand.js';
|
|
2
|
+
import { QueueWorkCommandUtils } from '../commands/QueueWorkCommandUtils.js';
|
|
3
|
+
import { QueueWorkRunner } from '../workers/QueueWorkRunner.js';
|
|
4
|
+
export function createKindWorkCommand(options) {
|
|
5
|
+
return BaseCommand.create({
|
|
6
|
+
name: options.name,
|
|
7
|
+
description: options.description,
|
|
8
|
+
addOptions: (command) => {
|
|
9
|
+
command
|
|
10
|
+
.argument('<queueName>', 'Queue name to work')
|
|
11
|
+
.option('--timeout <seconds>', 'Stop after this many seconds (default: 10)')
|
|
12
|
+
.option('--retry <count>', 'Retries after first attempt (default: 3)')
|
|
13
|
+
.option('--max-items <count>', 'Max items to process in one run (default: 1000)')
|
|
14
|
+
.option('--driver <name>', 'Queue driver name (default: from QUEUE_DRIVER)');
|
|
15
|
+
},
|
|
16
|
+
execute: async (cmdOptions) => {
|
|
17
|
+
const queueName = QueueWorkCommandUtils.requireQueueNameFromArgs(cmdOptions.args, options.helpHint);
|
|
18
|
+
const timeoutSeconds = QueueWorkCommandUtils.parsePositiveInt(cmdOptions.timeout, '--timeout');
|
|
19
|
+
const retry = QueueWorkCommandUtils.parseNonNegativeInt(cmdOptions.retry, '--retry');
|
|
20
|
+
const maxItems = QueueWorkCommandUtils.parsePositiveInt(cmdOptions.maxItems, '--max-items');
|
|
21
|
+
const driverName = QueueWorkCommandUtils.normalizeDriverName(cmdOptions.driver);
|
|
22
|
+
const result = await QueueWorkRunner.run({
|
|
23
|
+
kind: options.kind,
|
|
24
|
+
queueName,
|
|
25
|
+
timeoutSeconds,
|
|
26
|
+
retry,
|
|
27
|
+
maxItems,
|
|
28
|
+
driverName,
|
|
29
|
+
});
|
|
30
|
+
QueueWorkCommandUtils.logSummary(queueName, options.kind, result);
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* CLI Commands Module Index
|
|
3
3
|
*/
|
|
4
4
|
export { AddCommand } from '../commands/AddCommand';
|
|
5
|
+
export { BroadcastWorkCommand } from '../commands/BroadcastWorkCommand';
|
|
5
6
|
export { ConfigCommand } from '../commands/ConfigCommand';
|
|
6
7
|
export { DebugCommand } from '../commands/DebugCommand';
|
|
7
8
|
export { LogsCleanupCommand } from '../commands/LogsCleanupCommand';
|
|
@@ -9,7 +10,9 @@ export { MakeMailTemplateCommand } from '../commands/MakeMailTemplateCommand';
|
|
|
9
10
|
export { MakeNotificationTemplateCommand } from '../commands/MakeNotificationTemplateCommand';
|
|
10
11
|
export { MigrateCommand } from '../commands/MigrateCommand';
|
|
11
12
|
export { NewCommand } from '../commands/NewCommand';
|
|
13
|
+
export { NotificationWorkCommand } from '../commands/NotificationWorkCommand';
|
|
12
14
|
export { PrepareCommand } from '../commands/PrepareCommand';
|
|
15
|
+
export { QueueCommand } from '../commands/QueueCommand';
|
|
13
16
|
export { SecretsCommand } from '../commands/SecretsCommand';
|
|
14
17
|
export { StartCommand } from '../commands/StartCommand';
|
|
15
18
|
export { TemplatesCommand } from '../commands/TemplatesCommand';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,EAAE,+BAA+B,EAAE,MAAM,+CAA+C,CAAC;AAChG,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,EAAE,+BAA+B,EAAE,MAAM,+CAA+C,CAAC;AAChG,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* CLI Commands Module Index
|
|
3
3
|
*/
|
|
4
4
|
export { AddCommand } from '../commands/AddCommand.js';
|
|
5
|
+
export { BroadcastWorkCommand } from '../commands/BroadcastWorkCommand.js';
|
|
5
6
|
export { ConfigCommand } from '../commands/ConfigCommand.js';
|
|
6
7
|
export { DebugCommand } from '../commands/DebugCommand.js';
|
|
7
8
|
export { LogsCleanupCommand } from '../commands/LogsCleanupCommand.js';
|
|
@@ -9,7 +10,9 @@ export { MakeMailTemplateCommand } from '../commands/MakeMailTemplateCommand.js'
|
|
|
9
10
|
export { MakeNotificationTemplateCommand } from '../commands/MakeNotificationTemplateCommand.js';
|
|
10
11
|
export { MigrateCommand } from '../commands/MigrateCommand.js';
|
|
11
12
|
export { NewCommand } from '../commands/NewCommand.js';
|
|
13
|
+
export { NotificationWorkCommand } from '../commands/NotificationWorkCommand.js';
|
|
12
14
|
export { PrepareCommand } from '../commands/PrepareCommand.js';
|
|
15
|
+
export { QueueCommand } from '../commands/QueueCommand.js';
|
|
13
16
|
export { SecretsCommand } from '../commands/SecretsCommand.js';
|
|
14
17
|
export { StartCommand } from '../commands/StartCommand.js';
|
|
15
18
|
export { TemplatesCommand } from '../commands/TemplatesCommand.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ModelGenerator.d.ts","sourceRoot":"","sources":["../../../../src/cli/scaffolding/ModelGenerator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,MAAM,MAAM,SAAS,GACjB,QAAQ,GACR,SAAS,GACT,OAAO,GACP,SAAS,GACT,MAAM,GACN,UAAU,GACV,MAAM,GACN,EAAE,CAAC;AAEP,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,WAAW,CAAC;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC;IACtB,aAAa,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACpC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAsB3F;AAED;;GAEG;AAEH,wBAAgB,aAAa,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,oBAAoB,CAAC,CA0ClF;
|
|
1
|
+
{"version":3,"file":"ModelGenerator.d.ts","sourceRoot":"","sources":["../../../../src/cli/scaffolding/ModelGenerator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,MAAM,MAAM,SAAS,GACjB,QAAQ,GACR,SAAS,GACT,OAAO,GACP,SAAS,GACT,MAAM,GACN,UAAU,GACV,MAAM,GACN,EAAE,CAAC;AAEP,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,WAAW,CAAC;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC;IACtB,aAAa,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACpC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAsB3F;AAED;;GAEG;AAEH,wBAAgB,aAAa,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,oBAAoB,CAAC,CA0ClF;AAgID;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,SAAS,EAAE,CAEjD;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,UAAU,EAAE,CAW5C;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,UAAU,EAAE,CAU5C;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,UAAU,EAAE,CAU7C;AAED;;GAEG;AACH,eAAO,MAAM,cAAc;;;;;;;EAOzB,CAAC"}
|
|
@@ -92,6 +92,7 @@ export const ${options.name} = Object.freeze(
|
|
|
92
92
|
fillable: [${fillable.map((f) => `'${f}'`).join(', ')}],
|
|
93
93
|
hidden: [${hidden.map((f) => `'${f}'`).join(', ')}],
|
|
94
94
|
timestamps: ${options.timestamps !== false},
|
|
95
|
+
softDeletes: ${options.softDelete === true},
|
|
95
96
|
casts: {
|
|
96
97
|
`;
|
|
97
98
|
// Add field casts
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type QueueWorkKind = 'broadcast' | 'notification';
|
|
2
|
+
export type QueueWorkRunnerOptions = {
|
|
3
|
+
queueName: string;
|
|
4
|
+
kind?: QueueWorkKind;
|
|
5
|
+
driverName?: string;
|
|
6
|
+
timeoutSeconds?: number;
|
|
7
|
+
maxItems?: number;
|
|
8
|
+
/** Max retries after the first attempt (so total attempts = retry + 1) */
|
|
9
|
+
retry?: number;
|
|
10
|
+
};
|
|
11
|
+
export type QueueWorkRunnerResult = {
|
|
12
|
+
processed: number;
|
|
13
|
+
retried: number;
|
|
14
|
+
dropped: number;
|
|
15
|
+
notDueRequeued: number;
|
|
16
|
+
unknown: number;
|
|
17
|
+
};
|
|
18
|
+
export declare const QueueWorkRunner: Readonly<{
|
|
19
|
+
run(options: QueueWorkRunnerOptions): Promise<QueueWorkRunnerResult>;
|
|
20
|
+
parseKind(value: unknown): QueueWorkKind;
|
|
21
|
+
}>;
|
|
22
|
+
export default QueueWorkRunner;
|
|
23
|
+
//# sourceMappingURL=QueueWorkRunner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QueueWorkRunner.d.ts","sourceRoot":"","sources":["../../../../src/cli/workers/QueueWorkRunner.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG,cAAc,CAAC;AAoBzD,MAAM,MAAM,sBAAsB,GAAG;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAyHF,eAAO,MAAM,eAAe;iBACP,sBAAsB,GAAG,OAAO,CAAC,qBAAqB,CAAC;qBAuCzD,OAAO,GAAG,aAAa;EAUxC,CAAC;AAEH,eAAe,eAAe,CAAC"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { Broadcast } from '../../tools/broadcast/Broadcast.js';
|
|
2
|
+
import { Logger } from '../../config/logger.js';
|
|
3
|
+
import { queueConfig } from '../../config/queue.js';
|
|
4
|
+
import { ErrorFactory } from '../../exceptions/ZintrustError.js';
|
|
5
|
+
import { Notification } from '../../tools/notification/Notification.js';
|
|
6
|
+
import { Queue } from '../../tools/queue/Queue.js';
|
|
7
|
+
import { registerQueuesFromRuntimeConfig } from '../../tools/queue/QueueRuntimeRegistration.js';
|
|
8
|
+
const isKind = (value) => value === 'broadcast' || value === 'notification';
|
|
9
|
+
const detectKindFromPayload = (payload) => {
|
|
10
|
+
if (payload !== null && typeof payload === 'object') {
|
|
11
|
+
const p = payload;
|
|
12
|
+
if (isKind(p['type']))
|
|
13
|
+
return p['type'];
|
|
14
|
+
if (typeof p['channel'] === 'string' && typeof p['event'] === 'string')
|
|
15
|
+
return 'broadcast';
|
|
16
|
+
if (typeof p['recipient'] === 'string' && typeof p['message'] === 'string')
|
|
17
|
+
return 'notification';
|
|
18
|
+
}
|
|
19
|
+
return undefined;
|
|
20
|
+
};
|
|
21
|
+
const normalizeNumber = (value) => {
|
|
22
|
+
if (typeof value === 'number' && Number.isFinite(value))
|
|
23
|
+
return value;
|
|
24
|
+
if (typeof value === 'string' && value.trim() !== '') {
|
|
25
|
+
const n = Number(value);
|
|
26
|
+
if (Number.isFinite(n))
|
|
27
|
+
return n;
|
|
28
|
+
}
|
|
29
|
+
return undefined;
|
|
30
|
+
};
|
|
31
|
+
const getTimestamp = (payload) => {
|
|
32
|
+
return normalizeNumber(payload['timestamp']);
|
|
33
|
+
};
|
|
34
|
+
const getAttempts = (payload) => {
|
|
35
|
+
const n = normalizeNumber(payload['attempts']);
|
|
36
|
+
return typeof n === 'number' && n >= 0 ? Math.floor(n) : 0;
|
|
37
|
+
};
|
|
38
|
+
const withAttempts = (payload, attempts) => {
|
|
39
|
+
return { ...payload, attempts };
|
|
40
|
+
};
|
|
41
|
+
const shouldStop = (startedAtMs, timeoutSeconds) => {
|
|
42
|
+
if (timeoutSeconds === undefined)
|
|
43
|
+
return false;
|
|
44
|
+
const elapsedMs = Date.now() - startedAtMs;
|
|
45
|
+
return elapsedMs >= timeoutSeconds * 1000;
|
|
46
|
+
};
|
|
47
|
+
const processMessage = async (options, msg, maxAttempts, result) => {
|
|
48
|
+
const payload = msg.payload ?? {};
|
|
49
|
+
const kind = options.kind ?? detectKindFromPayload(payload);
|
|
50
|
+
if (kind === undefined) {
|
|
51
|
+
Logger.warn('Queue worker: unknown job payload; dropping', {
|
|
52
|
+
queue: options.queueName,
|
|
53
|
+
messageId: msg.id,
|
|
54
|
+
payloadKeys: Object.keys(payload),
|
|
55
|
+
});
|
|
56
|
+
result.unknown++;
|
|
57
|
+
await Queue.ack(options.queueName, msg.id, options.driverName);
|
|
58
|
+
return 'continue';
|
|
59
|
+
}
|
|
60
|
+
const timestamp = getTimestamp(payload);
|
|
61
|
+
if (typeof timestamp === 'number' && timestamp > Date.now()) {
|
|
62
|
+
// Not due yet: re-enqueue and stop after rotating the head once.
|
|
63
|
+
await Queue.enqueue(options.queueName, payload, options.driverName);
|
|
64
|
+
await Queue.ack(options.queueName, msg.id, options.driverName);
|
|
65
|
+
result.notDueRequeued++;
|
|
66
|
+
return 'break';
|
|
67
|
+
}
|
|
68
|
+
const attempts = getAttempts(payload);
|
|
69
|
+
try {
|
|
70
|
+
if (kind === 'broadcast') {
|
|
71
|
+
const job = payload;
|
|
72
|
+
await Broadcast.send(job.channel, job.event, job.data);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
const job = payload;
|
|
76
|
+
await Notification.send(job.recipient, job.message, job.options ?? {});
|
|
77
|
+
}
|
|
78
|
+
await Queue.ack(options.queueName, msg.id, options.driverName);
|
|
79
|
+
result.processed++;
|
|
80
|
+
return 'continue';
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
const nextAttempts = attempts + 1;
|
|
84
|
+
const canRetry = nextAttempts < maxAttempts;
|
|
85
|
+
Logger.error('Queue worker: job failed', {
|
|
86
|
+
queue: options.queueName,
|
|
87
|
+
kind,
|
|
88
|
+
messageId: msg.id,
|
|
89
|
+
attempts: nextAttempts,
|
|
90
|
+
maxAttempts,
|
|
91
|
+
error,
|
|
92
|
+
});
|
|
93
|
+
if (canRetry) {
|
|
94
|
+
await Queue.enqueue(options.queueName, withAttempts(payload, nextAttempts), options.driverName);
|
|
95
|
+
result.retried++;
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
result.dropped++;
|
|
99
|
+
}
|
|
100
|
+
await Queue.ack(options.queueName, msg.id, options.driverName);
|
|
101
|
+
return 'continue';
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
export const QueueWorkRunner = Object.freeze({
|
|
105
|
+
async run(options) {
|
|
106
|
+
registerQueuesFromRuntimeConfig(queueConfig);
|
|
107
|
+
const startedAtMs = Date.now();
|
|
108
|
+
const maxItems = typeof options.maxItems === 'number' ? options.maxItems : 1000;
|
|
109
|
+
const timeoutSeconds = typeof options.timeoutSeconds === 'number' ? options.timeoutSeconds : 10;
|
|
110
|
+
const maxRetries = typeof options.retry === 'number' ? options.retry : 3;
|
|
111
|
+
const maxAttempts = Math.max(0, Math.floor(maxRetries)) + 1;
|
|
112
|
+
const result = {
|
|
113
|
+
processed: 0,
|
|
114
|
+
retried: 0,
|
|
115
|
+
dropped: 0,
|
|
116
|
+
notDueRequeued: 0,
|
|
117
|
+
unknown: 0,
|
|
118
|
+
};
|
|
119
|
+
/* eslint-disable no-await-in-loop */
|
|
120
|
+
while (result.processed < maxItems && !shouldStop(startedAtMs, timeoutSeconds)) {
|
|
121
|
+
const msg = await Queue.dequeue(options.queueName, options.driverName);
|
|
122
|
+
if (msg === undefined)
|
|
123
|
+
break;
|
|
124
|
+
const outcome = await processMessage(options, { id: msg.id, payload: msg.payload ?? {} }, maxAttempts, result);
|
|
125
|
+
if (outcome === 'break')
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
/* eslint-enable no-await-in-loop */
|
|
129
|
+
return result;
|
|
130
|
+
},
|
|
131
|
+
parseKind(value) {
|
|
132
|
+
const v = String(value ?? '')
|
|
133
|
+
.trim()
|
|
134
|
+
.toLowerCase();
|
|
135
|
+
if (v === 'broadcast' || v === 'broad')
|
|
136
|
+
return 'broadcast';
|
|
137
|
+
if (v === 'notification' || v === 'notify')
|
|
138
|
+
return 'notification';
|
|
139
|
+
throw ErrorFactory.createCliError(`Invalid kind '${String(value)}'. Expected 'broadcast' or 'notification'.`);
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
export default QueueWorkRunner;
|