@zintrust/core 0.1.24 → 0.1.26
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 +4 -3
- package/src/auth/Auth.d.ts.map +1 -0
- package/src/boot/Application.d.ts.map +1 -1
- package/src/boot/Application.js +8 -0
- package/src/boot/bootstrap.js +34 -15
- package/src/cache/drivers/RedisDriver.d.ts.map +1 -1
- package/src/cache/drivers/RedisDriver.js +10 -5
- package/src/cli/CLI.d.ts.map +1 -1
- package/src/cli/CLI.js +6 -0
- package/src/cli/commands/QueueCommand.d.ts.map +1 -1
- package/src/cli/commands/QueueCommand.js +89 -39
- package/src/cli/commands/QueueLockCommand.d.ts +7 -0
- package/src/cli/commands/QueueLockCommand.d.ts.map +1 -0
- package/src/cli/commands/QueueLockCommand.js +138 -0
- package/src/cli/commands/StartCommand.d.ts.map +1 -1
- package/src/cli/commands/StartCommand.js +15 -3
- package/src/cli/commands/TemplatesCommand.js +1 -1
- package/src/cli/commands/WorkerCommands.d.ts.map +1 -1
- package/src/cli/commands/WorkerCommands.js +46 -22
- package/src/cli/scaffolding/ProjectScaffolder.js +2 -2
- package/src/cli/scaffolding/RouteGenerator.d.ts.map +1 -1
- package/src/cli/scaffolding/RouteGenerator.js +27 -28
- package/src/cli/services/VersionChecker.d.ts +53 -0
- package/src/cli/services/VersionChecker.d.ts.map +1 -0
- package/src/cli/services/VersionChecker.js +180 -0
- package/src/cli/workers/QueueWorkRunner.d.ts.map +1 -1
- package/src/cli/workers/QueueWorkRunner.js +128 -7
- package/src/common/ExternalServiceUtils.d.ts +2 -2
- package/src/config/app.d.ts +4 -0
- package/src/config/app.d.ts.map +1 -1
- package/src/config/app.js +9 -0
- package/src/config/constants.d.ts +140 -10
- package/src/config/constants.d.ts.map +1 -1
- package/src/config/constants.js +86 -5
- package/src/config/index.d.ts +1 -0
- package/src/config/index.d.ts.map +1 -1
- package/src/config/middleware.d.ts +6 -6
- package/src/config/middleware.d.ts.map +1 -1
- package/src/config/middleware.js +6 -7
- package/src/config/queue.d.ts +4 -0
- package/src/config/queue.d.ts.map +1 -1
- package/src/config/queue.js +1 -1
- package/src/config/redis.d.ts +17 -0
- package/src/config/redis.d.ts.map +1 -0
- package/src/config/redis.js +54 -0
- package/src/config/type.d.ts +3 -0
- package/src/config/type.d.ts.map +1 -1
- package/src/http/Request.d.ts +10 -1
- package/src/http/Request.d.ts.map +1 -1
- package/src/http/Request.js +79 -7
- package/src/http/error-pages/ErrorPageRenderer.d.ts.map +1 -1
- package/src/http/error-pages/ErrorPageRenderer.js +4 -3
- package/src/index.d.ts +14 -11
- package/src/index.d.ts.map +1 -1
- package/src/index.js +18 -11
- package/src/lang/lang.d.ts +23 -0
- package/src/lang/lang.d.ts.map +1 -0
- package/src/lang/lang.js +22 -0
- package/src/middleware/ErrorHandlerMiddleware.d.ts.map +1 -1
- package/src/middleware/ErrorHandlerMiddleware.js +9 -1
- package/src/migrations/schema/SchemaCompiler.js +1 -1
- package/src/migrations/schema/types.d.ts +1 -1
- package/src/migrations/schema/types.d.ts.map +1 -1
- package/src/node.d.ts +1 -1
- package/src/node.d.ts.map +1 -1
- package/src/node.js +1 -1
- package/src/orm/Database.d.ts +1 -1
- package/src/orm/Database.d.ts.map +1 -1
- package/src/orm/Database.js +22 -3
- package/src/performance/Optimizer.js +1 -1
- package/src/routing/Router.d.ts +6 -2
- package/src/routing/Router.d.ts.map +1 -1
- package/src/routing/Router.js +19 -4
- package/src/runtime/PluginManager.js +1 -1
- package/src/runtime/PluginRegistry.js +2 -2
- package/src/start.d.ts.map +1 -1
- package/src/start.js +8 -7
- package/src/templates/TemplateRegistry.js +2 -2
- package/src/templates/TemplateRegistry.ts +2 -2
- package/src/templates/feature/Queue.ts.tpl +114 -0
- package/src/templates/project/basic/app/Controllers/UserController.ts.tpl +22 -0
- package/src/templates/project/basic/config/queue.ts.tpl +19 -0
- package/src/templates/project/basic/package.json.tpl +2 -1
- package/src/templates/project/basic/src/index.ts.tpl +0 -3
- package/src/tools/broadcast/drivers/Redis.d.ts.map +1 -1
- package/src/tools/broadcast/drivers/Redis.js +8 -56
- package/src/tools/mail/Mail.d.ts +1 -29
- package/src/tools/mail/Mail.d.ts.map +1 -1
- package/src/tools/mail/Mail.js +1 -111
- package/src/tools/mail/drivers/SendGrid.d.ts.map +1 -1
- package/src/tools/mail/drivers/SendGrid.js +4 -3
- package/src/tools/mail/drivers/Smtp.d.ts.map +1 -1
- package/src/tools/mail/drivers/Smtp.js +32 -10
- package/src/tools/mail/index.d.ts +40 -0
- package/src/tools/mail/index.d.ts.map +1 -0
- package/src/tools/mail/index.js +129 -0
- package/src/tools/mail/template-loader.d.ts +10 -0
- package/src/tools/mail/template-loader.d.ts.map +1 -0
- package/src/tools/mail/template-loader.js +101 -0
- package/src/tools/mail/template-utils.d.ts +10 -0
- package/src/tools/mail/template-utils.d.ts.map +1 -0
- package/src/tools/mail/template-utils.js +16 -0
- package/src/tools/mail/templates/index.d.ts +30 -0
- package/src/tools/mail/templates/index.d.ts.map +1 -1
- package/src/tools/mail/templates/index.js +69 -0
- package/src/tools/queue/AdvancedQueue.d.ts +19 -0
- package/src/tools/queue/AdvancedQueue.d.ts.map +1 -0
- package/src/tools/queue/AdvancedQueue.js +352 -0
- package/src/tools/queue/DeduplicationBuilder.d.ts +20 -0
- package/src/tools/queue/DeduplicationBuilder.d.ts.map +1 -0
- package/src/tools/queue/DeduplicationBuilder.js +77 -0
- package/src/tools/queue/LockProvider.d.ts +22 -0
- package/src/tools/queue/LockProvider.d.ts.map +1 -0
- package/src/tools/queue/LockProvider.js +282 -0
- package/src/tools/queue/Queue.d.ts.map +1 -1
- package/src/tools/queue/Queue.js +2 -1
- package/src/tools/queue/QueueExtensions.d.ts +46 -0
- package/src/tools/queue/QueueExtensions.d.ts.map +1 -0
- package/src/tools/queue/QueueExtensions.js +129 -0
- package/src/tools/queue/QueueRuntimeRegistration.d.ts.map +1 -1
- package/src/tools/queue/QueueRuntimeRegistration.js +2 -2
- package/src/tools/queue/drivers/Database.d.ts +23 -0
- package/src/tools/queue/drivers/Database.d.ts.map +1 -0
- package/src/tools/queue/drivers/Database.js +123 -0
- package/src/tools/queue/drivers/Redis.d.ts.map +1 -1
- package/src/tools/queue/drivers/Redis.js +11 -82
- package/src/tools/queue/index.d.ts +9 -0
- package/src/tools/queue/index.d.ts.map +1 -0
- package/src/tools/queue/index.js +7 -0
- package/src/tools/redis/RedisKeyManager.d.ts +64 -0
- package/src/tools/redis/RedisKeyManager.d.ts.map +1 -0
- package/src/tools/redis/RedisKeyManager.js +124 -0
- package/src/types/Queue.d.ts +62 -0
- package/src/types/Queue.d.ts.map +1 -0
- package/src/types/Queue.js +5 -0
- package/src/features/Auth.d.ts.map +0 -1
- package/src/features/Queue.d.ts +0 -21
- package/src/features/Queue.d.ts.map +0 -1
- package/src/features/Queue.js +0 -33
- package/src/templates/features/Queue.ts.tpl +0 -47
- package/src/tools/mail/templates/markdown/index.d.ts +0 -17
- package/src/tools/mail/templates/markdown/index.d.ts.map +0 -1
- package/src/tools/mail/templates/markdown/index.js +0 -49
- package/src/tools/mail/templates/markdown/registry.d.ts +0 -15
- package/src/tools/mail/templates/markdown/registry.d.ts.map +0 -1
- package/src/tools/mail/templates/markdown/registry.js +0 -34
- package/src/tools/mail/templates/markdown/validator.d.ts +0 -16
- package/src/tools/mail/templates/markdown/validator.d.ts.map +0 -1
- package/src/tools/mail/templates/markdown/validator.js +0 -24
- /package/src/{features → auth}/Auth.d.ts +0 -0
- /package/src/{features → auth}/Auth.js +0 -0
- /package/src/templates/{features → auth}/Auth.ts.tpl +0 -0
|
@@ -3,28 +3,51 @@
|
|
|
3
3
|
* Worker Management CLI Commands
|
|
4
4
|
* Command-line interface for managing workers
|
|
5
5
|
*/
|
|
6
|
+
import { ErrorFactory } from '../../exceptions/ZintrustError.js';
|
|
6
7
|
import { BaseCommand } from '../BaseCommand.js';
|
|
7
8
|
import { Logger } from '../../config/logger.js';
|
|
8
|
-
import { HealthMonitor as HealthMonitorAny, ResourceMonitor as ResourceMonitorAny, WorkerFactory as WorkerFactoryAny, WorkerRegistry as WorkerRegistryAny, } from '../../../packages/workers/src/index.js';
|
|
9
9
|
// Lazy initialization to prevent temporal dead zone issues
|
|
10
10
|
let WorkerFactory;
|
|
11
11
|
let WorkerRegistry;
|
|
12
12
|
let HealthMonitor;
|
|
13
13
|
let ResourceMonitor;
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
let workersModulePromise;
|
|
15
|
+
const loadWorkersModule = async () => {
|
|
16
|
+
workersModulePromise ??= import('../../../packages/workers/src/index.js');
|
|
17
|
+
try {
|
|
18
|
+
return await workersModulePromise;
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
Logger.error('Failed to load optional package "@zintrust/workers"; worker commands require this package.', error);
|
|
22
|
+
throw ErrorFactory.createCliError('Optional package "@zintrust/workers" is required for worker commands. Install it to use worker:* commands.');
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
const getWorkerFactory = async () => {
|
|
26
|
+
if (!WorkerFactory) {
|
|
27
|
+
const mod = await loadWorkersModule();
|
|
28
|
+
WorkerFactory = mod.WorkerFactory;
|
|
29
|
+
}
|
|
16
30
|
return WorkerFactory;
|
|
17
31
|
};
|
|
18
|
-
const getWorkerRegistry = () => {
|
|
19
|
-
WorkerRegistry
|
|
32
|
+
const getWorkerRegistry = async () => {
|
|
33
|
+
if (!WorkerRegistry) {
|
|
34
|
+
const mod = await loadWorkersModule();
|
|
35
|
+
WorkerRegistry = mod.WorkerRegistry;
|
|
36
|
+
}
|
|
20
37
|
return WorkerRegistry;
|
|
21
38
|
};
|
|
22
|
-
const getHealthMonitor = () => {
|
|
23
|
-
HealthMonitor
|
|
39
|
+
const getHealthMonitor = async () => {
|
|
40
|
+
if (!HealthMonitor) {
|
|
41
|
+
const mod = await loadWorkersModule();
|
|
42
|
+
HealthMonitor = mod.HealthMonitor;
|
|
43
|
+
}
|
|
24
44
|
return HealthMonitor;
|
|
25
45
|
};
|
|
26
|
-
const getResourceMonitor = () => {
|
|
27
|
-
ResourceMonitor
|
|
46
|
+
const getResourceMonitor = async () => {
|
|
47
|
+
if (!ResourceMonitor) {
|
|
48
|
+
const mod = await loadWorkersModule();
|
|
49
|
+
ResourceMonitor = mod.ResourceMonitor;
|
|
50
|
+
}
|
|
28
51
|
return ResourceMonitor;
|
|
29
52
|
};
|
|
30
53
|
/**
|
|
@@ -46,14 +69,15 @@ const formatTable = (headers, rows) => {
|
|
|
46
69
|
const createWorkerListCommand = () => {
|
|
47
70
|
const ext = async () => {
|
|
48
71
|
try {
|
|
49
|
-
const workers = await getWorkerFactory().listPersisted();
|
|
72
|
+
const workers = await (await getWorkerFactory()).listPersisted();
|
|
50
73
|
console.log(`\nTotal Workers: ${workers.length}\n`);
|
|
51
74
|
if (workers.length === 0) {
|
|
52
75
|
console.log('No workers found.');
|
|
53
76
|
return;
|
|
54
77
|
}
|
|
78
|
+
const registry = await getWorkerRegistry();
|
|
55
79
|
const rows = workers.map((name) => {
|
|
56
|
-
const status =
|
|
80
|
+
const status = registry.status(name);
|
|
57
81
|
return [
|
|
58
82
|
name,
|
|
59
83
|
status?.status ?? 'unknown',
|
|
@@ -87,12 +111,12 @@ const createWorkerStatusCommand = () => {
|
|
|
87
111
|
Logger.error('Error: Worker name is required');
|
|
88
112
|
process.exit(1);
|
|
89
113
|
}
|
|
90
|
-
const status = getWorkerRegistry().status(name);
|
|
91
|
-
const health = await getWorkerFactory().getHealth(name);
|
|
114
|
+
const status = (await getWorkerRegistry()).status(name);
|
|
115
|
+
const health = await (await getWorkerFactory()).getHealth(name);
|
|
92
116
|
const healthData = typeof health === 'object' && health !== null
|
|
93
117
|
? health
|
|
94
118
|
: {};
|
|
95
|
-
const metrics = await getWorkerFactory().getMetrics(name);
|
|
119
|
+
const metrics = await (await getWorkerFactory()).getMetrics(name);
|
|
96
120
|
console.log(`\n=== Worker: ${name} ===\n`);
|
|
97
121
|
console.log(`Status: ${status?.status}`);
|
|
98
122
|
console.log(`Version: ${status?.version}`);
|
|
@@ -131,7 +155,7 @@ const createWorkerStartCommand = () => {
|
|
|
131
155
|
Logger.error('Error: Worker name is required');
|
|
132
156
|
process.exit(1);
|
|
133
157
|
}
|
|
134
|
-
await getWorkerFactory().start(name);
|
|
158
|
+
await (await getWorkerFactory()).start(name);
|
|
135
159
|
Logger.info(`✓ Worker "${name}" started successfully`);
|
|
136
160
|
}
|
|
137
161
|
catch (error) {
|
|
@@ -159,7 +183,7 @@ const createWorkerStopCommand = () => {
|
|
|
159
183
|
console.error('Error: Worker name is required');
|
|
160
184
|
process.exit(1);
|
|
161
185
|
}
|
|
162
|
-
await getWorkerFactory().stop(name);
|
|
186
|
+
await (await getWorkerFactory()).stop(name);
|
|
163
187
|
console.log(`✓ Worker "${name}" stopped successfully`);
|
|
164
188
|
}
|
|
165
189
|
catch (error) {
|
|
@@ -188,7 +212,7 @@ const createWorkerRestartCommand = () => {
|
|
|
188
212
|
console.error('Error: Worker name is required');
|
|
189
213
|
process.exit(1);
|
|
190
214
|
}
|
|
191
|
-
await getWorkerFactory().restart(name);
|
|
215
|
+
await (await getWorkerFactory()).restart(name);
|
|
192
216
|
console.log(`✓ Worker "${name}" restarted successfully`);
|
|
193
217
|
}
|
|
194
218
|
catch (error) {
|
|
@@ -211,11 +235,11 @@ const createWorkerRestartCommand = () => {
|
|
|
211
235
|
* Worker Summary Command
|
|
212
236
|
*/
|
|
213
237
|
const createWorkerSummaryCommand = () => {
|
|
214
|
-
const ext = () => {
|
|
238
|
+
const ext = async () => {
|
|
215
239
|
try {
|
|
216
|
-
const workers = getWorkerFactory().list();
|
|
217
|
-
const monitoringSummary = getHealthMonitor().getSummary();
|
|
218
|
-
const resourceUsage = getResourceMonitor().getCurrentUsage('system');
|
|
240
|
+
const workers = (await getWorkerFactory()).list();
|
|
241
|
+
const monitoringSummary = (await getHealthMonitor()).getSummary();
|
|
242
|
+
const resourceUsage = (await getResourceMonitor()).getCurrentUsage('system');
|
|
219
243
|
console.log(`\n=== Worker System Summary ===\n`);
|
|
220
244
|
console.log(`Total Workers: ${workers.length}`);
|
|
221
245
|
console.log(`\nHealth Overview:`);
|
|
@@ -247,7 +271,7 @@ const createWorkerSummaryCommand = () => {
|
|
|
247
271
|
const cmd = BaseCommand.create({
|
|
248
272
|
name: 'worker:summary',
|
|
249
273
|
description: 'Get system-wide worker summary',
|
|
250
|
-
execute: () => ext(),
|
|
274
|
+
execute: async () => ext(),
|
|
251
275
|
});
|
|
252
276
|
return cmd;
|
|
253
277
|
};
|
|
@@ -199,8 +199,8 @@ const createEnvFile = (projectPath, variables) => {
|
|
|
199
199
|
'',
|
|
200
200
|
'# Logging',
|
|
201
201
|
'LOG_LEVEL=debug',
|
|
202
|
-
'LOG_CHANNEL=
|
|
203
|
-
'LOG_FORMAT=
|
|
202
|
+
'LOG_CHANNEL=file',
|
|
203
|
+
'LOG_FORMAT=text',
|
|
204
204
|
'',
|
|
205
205
|
'# Auth / Security',
|
|
206
206
|
'JWT_SECRET=',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RouteGenerator.d.ts","sourceRoot":"","sources":["../../../../src/cli/scaffolding/RouteGenerator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,UAAU,CAAC;AAEnF,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAuBD,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,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,CAqB3F;AAED;;GAEG;AAEH,wBAAgB,cAAc,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,oBAAoB,CAAC,CA4CnF;
|
|
1
|
+
{"version":3,"file":"RouteGenerator.d.ts","sourceRoot":"","sources":["../../../../src/cli/scaffolding/RouteGenerator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,UAAU,CAAC;AAEnF,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAuBD,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,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,CAqB3F;AAED;;GAEG;AAEH,wBAAgB,cAAc,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,oBAAoB,CAAC,CA4CnF;AA4LD;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,eAAe,EAAE,CAsCpD;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,eAAe,EAAE,CA6BjD;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,eAAe,EAAE,CA+BlD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,WAAW,EAAE,CAEhD;AAED;;GAEG;AACH,eAAO,MAAM,cAAc;;;;;;;EAOzB,CAAC"}
|
|
@@ -8,21 +8,21 @@ import * as path from '../../node-singletons/path.js';
|
|
|
8
8
|
// Escape characters that can cause issues when embedding JSON.stringify output
|
|
9
9
|
// into generated JavaScript source (e.g., inside <script> tags).
|
|
10
10
|
const unsafeCharMap = {
|
|
11
|
-
'<':
|
|
12
|
-
'>':
|
|
13
|
-
'/':
|
|
11
|
+
'<': String.raw `\u003C`,
|
|
12
|
+
'>': String.raw `\u003E`,
|
|
13
|
+
'/': String.raw `\u002F`,
|
|
14
14
|
'\\': '\\\\',
|
|
15
|
-
'\b':
|
|
16
|
-
'\f':
|
|
17
|
-
'\n':
|
|
18
|
-
'\r':
|
|
19
|
-
'\t':
|
|
20
|
-
'\0':
|
|
21
|
-
'\u2028':
|
|
22
|
-
'\u2029':
|
|
15
|
+
'\b': String.raw `\b`,
|
|
16
|
+
'\f': String.raw `\f`,
|
|
17
|
+
'\n': String.raw `\n`,
|
|
18
|
+
'\r': String.raw `\r`,
|
|
19
|
+
'\t': String.raw `\t`,
|
|
20
|
+
'\0': String.raw `\0`,
|
|
21
|
+
'\u2028': String.raw `\u2028`,
|
|
22
|
+
'\u2029': String.raw `\u2029`,
|
|
23
23
|
};
|
|
24
24
|
function escapeUnsafeChars(str) {
|
|
25
|
-
return str.
|
|
25
|
+
return str.replaceAll(/[<>/\\\b\f\n\r\t\0\u2028\u2029]/g, (ch) => unsafeCharMap[ch] ?? ch);
|
|
26
26
|
}
|
|
27
27
|
/**
|
|
28
28
|
* Validate route options
|
|
@@ -181,6 +181,19 @@ function buildRouteCode(route, router, groupMiddlewareList) {
|
|
|
181
181
|
return buildMethodRoute(route, router, groupMiddlewareList);
|
|
182
182
|
}
|
|
183
183
|
}
|
|
184
|
+
/**
|
|
185
|
+
* Build middleware property string for routes
|
|
186
|
+
*/
|
|
187
|
+
function buildMiddlewareProp(route, groupMiddlewareList) {
|
|
188
|
+
const localMiddlewareList = (route.middleware ?? []).map((m) => `'${m}'`).join(', ');
|
|
189
|
+
const hasGroup = groupMiddlewareList.trim() !== '';
|
|
190
|
+
const hasLocal = localMiddlewareList.trim() !== '';
|
|
191
|
+
return hasGroup || hasLocal
|
|
192
|
+
? `middleware: [${[hasGroup ? groupMiddlewareList : '', hasLocal ? localMiddlewareList : '']
|
|
193
|
+
.filter((v) => v.trim() !== '')
|
|
194
|
+
.join(', ')}]`
|
|
195
|
+
: '';
|
|
196
|
+
}
|
|
184
197
|
/**
|
|
185
198
|
* Build standard method route (GET, POST, etc.)
|
|
186
199
|
*/
|
|
@@ -192,14 +205,7 @@ function buildMethodRoute(route, router, groupMiddlewareList) {
|
|
|
192
205
|
const tag = toTag(controller);
|
|
193
206
|
const summary = `${method.toUpperCase()} ${routePath}`;
|
|
194
207
|
const controllerVar = toControllerVar(controller);
|
|
195
|
-
const
|
|
196
|
-
const hasGroup = groupMiddlewareList.trim() !== '';
|
|
197
|
-
const hasLocal = localMiddlewareList.trim() !== '';
|
|
198
|
-
const middlewareProp = hasGroup || hasLocal
|
|
199
|
-
? `middleware: [${[hasGroup ? groupMiddlewareList : '', hasLocal ? localMiddlewareList : '']
|
|
200
|
-
.filter((v) => v.trim() !== '')
|
|
201
|
-
.join(', ')}]`
|
|
202
|
-
: '';
|
|
208
|
+
const middlewareProp = buildMiddlewareProp(route, groupMiddlewareList);
|
|
203
209
|
const metaProp = `meta: { summary: ${escapeUnsafeChars(JSON.stringify(summary))}, tags: [${escapeUnsafeChars(JSON.stringify(tag))}] }`;
|
|
204
210
|
const options = `{ ${[middlewareProp, metaProp].filter((v) => v !== '').join(', ')} }`;
|
|
205
211
|
return ` Router.${method}(${router}, '${routePath}', (req, res) => ${controllerVar}.${action}(req, res), ${options});\n`;
|
|
@@ -212,14 +218,7 @@ function buildResourceRoute(route, router, groupMiddlewareList) {
|
|
|
212
218
|
const controller = route.controller;
|
|
213
219
|
const tag = toTag(controller);
|
|
214
220
|
const controllerVar = toControllerVar(controller);
|
|
215
|
-
const
|
|
216
|
-
const hasGroup = groupMiddlewareList.trim() !== '';
|
|
217
|
-
const hasLocal = localMiddlewareList.trim() !== '';
|
|
218
|
-
const middlewareProp = hasGroup || hasLocal
|
|
219
|
-
? `middleware: [${[hasGroup ? groupMiddlewareList : '', hasLocal ? localMiddlewareList : '']
|
|
220
|
-
.filter((v) => v.trim() !== '')
|
|
221
|
-
.join(', ')}]`
|
|
222
|
-
: '';
|
|
221
|
+
const middlewareProp = buildMiddlewareProp(route, groupMiddlewareList);
|
|
223
222
|
const resourceMeta = (action, routePattern) => `meta: { summary: ${escapeUnsafeChars(JSON.stringify(action.toUpperCase() + ' ' + routePattern))}, tags: [${escapeUnsafeChars(JSON.stringify(tag))}] }`;
|
|
224
223
|
const pathId = routePath + '/:id';
|
|
225
224
|
const optsParts = [
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VersionChecker - CLI Version Update Notification Service
|
|
3
|
+
*
|
|
4
|
+
* Checks if the current CLI version is outdated and warns users
|
|
5
|
+
* when a newer version is available from npm registry.
|
|
6
|
+
*/
|
|
7
|
+
interface VersionCheckResult {
|
|
8
|
+
currentVersion: string;
|
|
9
|
+
latestVersion: string;
|
|
10
|
+
isOutdated: boolean;
|
|
11
|
+
updateAvailable: boolean;
|
|
12
|
+
}
|
|
13
|
+
interface VersionCheckConfig {
|
|
14
|
+
enabled: boolean;
|
|
15
|
+
checkInterval: number;
|
|
16
|
+
skipVersionCheck: boolean;
|
|
17
|
+
}
|
|
18
|
+
export declare const VersionChecker: Readonly<{
|
|
19
|
+
/**
|
|
20
|
+
* Get current version from package.json
|
|
21
|
+
*/
|
|
22
|
+
getCurrentVersion(): string;
|
|
23
|
+
/**
|
|
24
|
+
* Get version check configuration
|
|
25
|
+
*/
|
|
26
|
+
getConfig(): VersionCheckConfig;
|
|
27
|
+
/**
|
|
28
|
+
* Check if version check should be performed
|
|
29
|
+
*/
|
|
30
|
+
shouldCheckVersion(): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Fetch latest version from npm registry
|
|
33
|
+
*/
|
|
34
|
+
fetchLatestVersion(): Promise<string>;
|
|
35
|
+
/**
|
|
36
|
+
* Compare versions using semver-like comparison
|
|
37
|
+
*/
|
|
38
|
+
compareVersions(current: string, latest: string): number;
|
|
39
|
+
/**
|
|
40
|
+
* Perform version check and return result
|
|
41
|
+
*/
|
|
42
|
+
checkVersion(): Promise<VersionCheckResult | null>;
|
|
43
|
+
/**
|
|
44
|
+
* Display update notification to user
|
|
45
|
+
*/
|
|
46
|
+
displayUpdateNotification(result: VersionCheckResult): void;
|
|
47
|
+
/**
|
|
48
|
+
* Run version check and display notification if needed
|
|
49
|
+
*/
|
|
50
|
+
runVersionCheck(): Promise<void>;
|
|
51
|
+
}>;
|
|
52
|
+
export {};
|
|
53
|
+
//# sourceMappingURL=VersionChecker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VersionChecker.d.ts","sourceRoot":"","sources":["../../../../src/cli/services/VersionChecker.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,UAAU,kBAAkB;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,OAAO,CAAC;IACpB,eAAe,EAAE,OAAO,CAAC;CAC1B;AAUD,UAAU,kBAAkB;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAED,eAAO,MAAM,cAAc;IACzB;;OAEG;yBACkB,MAAM;IAY3B;;OAEG;iBACU,kBAAkB;IAQ/B;;OAEG;0BACmB,OAAO;IA+B7B;;OAEG;0BACyB,OAAO,CAAC,MAAM,CAAC;IAwB3C;;OAEG;6BACsB,MAAM,UAAU,MAAM,GAAG,MAAM;IAuBxD;;OAEG;oBACmB,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IA8BxD;;OAEG;sCAC+B,kBAAkB,GAAG,IAAI;IA4B3D;;OAEG;uBACsB,OAAO,CAAC,IAAI,CAAC;EAWtC,CAAC"}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VersionChecker - CLI Version Update Notification Service
|
|
3
|
+
*
|
|
4
|
+
* Checks if the current CLI version is outdated and warns users
|
|
5
|
+
* when a newer version is available from npm registry.
|
|
6
|
+
*/
|
|
7
|
+
import { Logger } from '../../config/logger.js';
|
|
8
|
+
import { ErrorFactory } from '../../exceptions/ZintrustError.js';
|
|
9
|
+
import { readFileSync } from '../../node-singletons/fs.js';
|
|
10
|
+
import { join } from '../../node-singletons/path.js';
|
|
11
|
+
export const VersionChecker = Object.freeze({
|
|
12
|
+
/**
|
|
13
|
+
* Get current version from package.json
|
|
14
|
+
*/
|
|
15
|
+
getCurrentVersion() {
|
|
16
|
+
try {
|
|
17
|
+
const packagePath = join(process.cwd(), 'package.json');
|
|
18
|
+
const packageJson = JSON.parse(readFileSync(packagePath, 'utf-8'));
|
|
19
|
+
return typeof packageJson.version === 'string' ? packageJson.version : '0.0.0';
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return '0.0.0';
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
/**
|
|
26
|
+
* Get version check configuration
|
|
27
|
+
*/
|
|
28
|
+
getConfig() {
|
|
29
|
+
return {
|
|
30
|
+
enabled: process.env['ZINTRUST_VERSION_CHECK'] !== 'false',
|
|
31
|
+
checkInterval: Number.parseInt(process.env['ZINTRUST_VERSION_CHECK_INTERVAL'] ?? '24', 10),
|
|
32
|
+
skipVersionCheck: process.env['ZINTRUST_SKIP_VERSION_CHECK'] === 'true',
|
|
33
|
+
};
|
|
34
|
+
},
|
|
35
|
+
/**
|
|
36
|
+
* Check if version check should be performed
|
|
37
|
+
*/
|
|
38
|
+
shouldCheckVersion() {
|
|
39
|
+
const config = this.getConfig();
|
|
40
|
+
// Skip if disabled
|
|
41
|
+
if (!config.enabled || config.skipVersionCheck) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
// Skip for version commands
|
|
45
|
+
const args = new Set(process.argv.slice(2));
|
|
46
|
+
if (args.has('-v') || args.has('--version') || args.has('help')) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
// Check last check time
|
|
50
|
+
const lastCheckKey = 'zintrust_last_version_check';
|
|
51
|
+
const lastCheck = globalThis.localStorage?.getItem?.(lastCheckKey);
|
|
52
|
+
if (lastCheck !== null && lastCheck !== undefined) {
|
|
53
|
+
const lastCheckTime = Number.parseInt(lastCheck, 10);
|
|
54
|
+
const now = Date.now();
|
|
55
|
+
const hoursSinceLastCheck = (now - lastCheckTime) / (1000 * 60 * 60);
|
|
56
|
+
if (hoursSinceLastCheck < config.checkInterval) {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return true;
|
|
61
|
+
},
|
|
62
|
+
/**
|
|
63
|
+
* Fetch latest version from npm registry
|
|
64
|
+
*/
|
|
65
|
+
async fetchLatestVersion() {
|
|
66
|
+
try {
|
|
67
|
+
const response = await fetch('https://registry.npmjs.org/@zintrust/core/latest', {
|
|
68
|
+
method: 'GET',
|
|
69
|
+
headers: {
|
|
70
|
+
Accept: 'application/json',
|
|
71
|
+
'User-Agent': 'ZinTrust-CLI-Version-Check',
|
|
72
|
+
},
|
|
73
|
+
signal: AbortSignal.timeout(5000), // 5 second timeout
|
|
74
|
+
});
|
|
75
|
+
if (!response.ok) {
|
|
76
|
+
throw ErrorFactory.createConfigError(`HTTP ${response.status}: ${response.statusText}`);
|
|
77
|
+
}
|
|
78
|
+
const data = (await response.json());
|
|
79
|
+
return data['dist-tags'].latest || data.version;
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
// Silently fail for network issues - don't block CLI usage
|
|
83
|
+
Logger.debug('Failed to fetch latest version from npm registry', error);
|
|
84
|
+
throw ErrorFactory.createConfigError('Failed to check for updates', error);
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
/**
|
|
88
|
+
* Compare versions using semver-like comparison
|
|
89
|
+
*/
|
|
90
|
+
compareVersions(current, latest) {
|
|
91
|
+
const cleanVersion = (version) => {
|
|
92
|
+
// Remove leading 'v' and trailing pre-release identifiers safely
|
|
93
|
+
// Using specific patterns instead of greedy quantifiers to prevent ReDoS
|
|
94
|
+
return version.replace(/^v/, '').replace(/-[^-]*$/, '');
|
|
95
|
+
};
|
|
96
|
+
const currentParts = cleanVersion(current).split('.').map(Number);
|
|
97
|
+
const latestParts = cleanVersion(latest).split('.').map(Number);
|
|
98
|
+
const maxLength = Math.max(currentParts.length, latestParts.length);
|
|
99
|
+
for (let i = 0; i < maxLength; i++) {
|
|
100
|
+
const currentPart = currentParts[i] || 0;
|
|
101
|
+
const latestPart = latestParts[i] || 0;
|
|
102
|
+
if (currentPart < latestPart)
|
|
103
|
+
return -1;
|
|
104
|
+
if (currentPart > latestPart)
|
|
105
|
+
return 1;
|
|
106
|
+
}
|
|
107
|
+
return 0;
|
|
108
|
+
},
|
|
109
|
+
/**
|
|
110
|
+
* Perform version check and return result
|
|
111
|
+
*/
|
|
112
|
+
async checkVersion() {
|
|
113
|
+
if (!this.shouldCheckVersion()) {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
try {
|
|
117
|
+
const currentVersion = this.getCurrentVersion();
|
|
118
|
+
const latestVersion = await this.fetchLatestVersion();
|
|
119
|
+
const comparison = this.compareVersions(currentVersion, latestVersion);
|
|
120
|
+
const isOutdated = comparison < 0;
|
|
121
|
+
const updateAvailable = isOutdated;
|
|
122
|
+
// Update last check time
|
|
123
|
+
const lastCheckKey = 'zintrust_last_version_check';
|
|
124
|
+
globalThis.localStorage?.setItem?.(lastCheckKey, Date.now().toString());
|
|
125
|
+
return {
|
|
126
|
+
currentVersion,
|
|
127
|
+
latestVersion,
|
|
128
|
+
isOutdated,
|
|
129
|
+
updateAvailable,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
// Silently fail - version check should never block CLI usage
|
|
134
|
+
Logger.debug('Version check failed, continuing with CLI execution', error);
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
/**
|
|
139
|
+
* Display update notification to user
|
|
140
|
+
*/
|
|
141
|
+
displayUpdateNotification(result) {
|
|
142
|
+
if (!result.updateAvailable) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const { currentVersion, latestVersion } = result;
|
|
146
|
+
// Use process.stdout.write for better control and to avoid eslint console errors
|
|
147
|
+
const output = [
|
|
148
|
+
'',
|
|
149
|
+
'⚠️ Update Available',
|
|
150
|
+
'┌' + '─'.repeat(50) + '┐',
|
|
151
|
+
`│ Current: ${currentVersion.padEnd(40)}│`,
|
|
152
|
+
`│ Latest: ${latestVersion.padEnd(40)}│`,
|
|
153
|
+
'└' + '─'.repeat(50) + '┘',
|
|
154
|
+
'',
|
|
155
|
+
'💡 Update to get the latest features and bug fixes:',
|
|
156
|
+
` npm install -g @zintrust/core@${latestVersion}`,
|
|
157
|
+
' or: npx @zintrust/core@latest [command]',
|
|
158
|
+
'',
|
|
159
|
+
'🔧 To disable version checks:',
|
|
160
|
+
' export ZINTRUST_VERSION_CHECK=false',
|
|
161
|
+
'',
|
|
162
|
+
].join('\n');
|
|
163
|
+
process.stdout.write(output);
|
|
164
|
+
},
|
|
165
|
+
/**
|
|
166
|
+
* Run version check and display notification if needed
|
|
167
|
+
*/
|
|
168
|
+
async runVersionCheck() {
|
|
169
|
+
try {
|
|
170
|
+
const result = await this.checkVersion();
|
|
171
|
+
if (result) {
|
|
172
|
+
this.displayUpdateNotification(result);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
catch (error) {
|
|
176
|
+
// Version check should never crash the CLI
|
|
177
|
+
Logger.debug('Version check encountered an error', error);
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QueueWorkRunner.d.ts","sourceRoot":"","sources":["../../../../src/cli/workers/QueueWorkRunner.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"QueueWorkRunner.d.ts","sourceRoot":"","sources":["../../../../src/cli/workers/QueueWorkRunner.ts"],"names":[],"mappings":"AAsBA,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;AAiQF,eAAO,MAAM,eAAe;iBACP,sBAAsB,GAAG,OAAO,CAAC,qBAAqB,CAAC;qBAuCzD,OAAO,GAAG,aAAa;EAUxC,CAAC;AAEH,eAAe,eAAe,CAAC"}
|