@zintrust/core 0.1.15 → 0.1.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/package.json +1 -1
- package/public/index.html +1 -1
- 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/scaffolding/ProjectScaffolder.d.ts.map +1 -1
- package/src/cli/scaffolding/ProjectScaffolder.js +2 -1
- 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/env.d.ts +2 -0
- package/src/config/env.d.ts.map +1 -1
- package/src/config/env.js +4 -0
- package/src/config/index.d.ts +3 -0
- package/src/config/index.d.ts.map +1 -1
- package/src/config/security.d.ts +4 -1
- package/src/config/security.d.ts.map +1 -1
- package/src/config/security.js +9 -1
- 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.d.ts +1 -1
- package/src/features/Queue.d.ts.map +1 -1
- package/src/features/Queue.js +2 -2
- package/src/http/Response.d.ts +2 -2
- package/src/http/Response.d.ts.map +1 -1
- package/src/index.d.ts +12 -0
- package/src/index.d.ts.map +1 -1
- package/src/index.js +12 -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/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/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/EncryptedEnvelope.d.ts +77 -0
- package/src/security/EncryptedEnvelope.d.ts.map +1 -0
- package/src/security/EncryptedEnvelope.js +256 -0
- 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/security/StartupSecretValidation.d.ts.map +1 -1
- package/src/security/StartupSecretValidation.js +72 -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 +5 -4
- 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 +2 -2
- package/src/templates/project/basic/config/cache.ts.tpl +2 -2
- package/src/templates/project/basic/config/database.ts.tpl +2 -2
- package/src/templates/project/basic/config/env.ts.tpl +5 -0
- 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 +2 -2
- 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 +2 -2
- package/src/templates/project/basic/config/security.ts.tpl +12 -3
- package/src/templates/project/basic/config/storage.ts.tpl +2 -2
- 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/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/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
|
@@ -0,0 +1,24 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,114 @@
|
|
|
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
|
+
}
|