@zintrust/core 0.1.24 → 0.1.25
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 +176 -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 +25 -0
- package/src/tools/queue/LockProvider.d.ts.map +1 -0
- package/src/tools/queue/LockProvider.js +276 -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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zintrust/core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.25",
|
|
4
4
|
"description": "Production-grade TypeScript backend framework for JavaScript",
|
|
5
5
|
"homepage": "https://zintrust.com",
|
|
6
6
|
"repository": {
|
|
@@ -36,13 +36,14 @@
|
|
|
36
36
|
"bcrypt": "^6.0.0",
|
|
37
37
|
"chalk": "^5.6.2",
|
|
38
38
|
"commander": "^14.0.2",
|
|
39
|
-
"inquirer": "^13.2.
|
|
39
|
+
"inquirer": "^13.2.1",
|
|
40
40
|
"jsonwebtoken": "^9.0.3"
|
|
41
41
|
},
|
|
42
42
|
"overrides": {
|
|
43
43
|
"node-forge": "1.3.3",
|
|
44
44
|
"cross-spawn": "^7.0.5",
|
|
45
|
-
"glob": "^11.1.0"
|
|
45
|
+
"glob": "^11.1.0",
|
|
46
|
+
"undici": "^6.23.0"
|
|
46
47
|
},
|
|
47
48
|
"bin": {
|
|
48
49
|
"zintrust": "bin/zintrust.js",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Auth.d.ts","sourceRoot":"","sources":["../../../src/auth/Auth.ts"],"names":[],"mappings":"AAEA,OAAY,EAAE,KAAK,MAAM,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAIlE,eAAO,MAAM,IAAI;IACf;;OAEG;mBACkB,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAK7C;;OAEG;sBACqB,MAAM,QAAQ,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAI/D;;OAEG;2BAEQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,UACxB,MAAM,cACH,WAAW,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,GAC/C,MAAM;IAKT;;OAEG;gBACS,CAAC,SAAS,MAAM,UAAU,MAAM,GAAG,CAAC;EAGhD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Application.d.ts","sourceRoot":"","sources":["../../../src/boot/Application.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAGtE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAErE,OAAO,EAAE,KAAK,OAAO,EAAU,MAAM,kBAAkB,CAAC;AAUxD,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,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAGtE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAErE,OAAO,EAAE,KAAK,OAAO,EAAU,MAAM,kBAAkB,CAAC;AAUxD,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;AAqZD;;GAEG;AACH,eAAO,MAAM,WAAW;IACtB;;OAEG;sBACe,MAAM,GAAG,YAAY;EA0CvC,CAAC;AAEH,eAAe,WAAW,CAAC"}
|
package/src/boot/Application.js
CHANGED
|
@@ -291,6 +291,14 @@ const createLifecycle = (params) => {
|
|
|
291
291
|
catch (error) {
|
|
292
292
|
Logger.error('Shutdown hook failed:', error);
|
|
293
293
|
}
|
|
294
|
+
// Ensure FileLogWriter.flush is attempted even if dynamic registration failed.
|
|
295
|
+
try {
|
|
296
|
+
const fileLogWriter = await tryImportOptional('@config/FileLogWriter');
|
|
297
|
+
fileLogWriter?.FileLogWriter?.flush?.();
|
|
298
|
+
}
|
|
299
|
+
catch {
|
|
300
|
+
/* best-effort */
|
|
301
|
+
}
|
|
294
302
|
params.setBooted(false);
|
|
295
303
|
Logger.info('✅ Application shut down successfully');
|
|
296
304
|
};
|
package/src/boot/bootstrap.js
CHANGED
|
@@ -87,8 +87,11 @@ const gracefulShutdown = async (signal) => {
|
|
|
87
87
|
if (isShuttingDown)
|
|
88
88
|
return;
|
|
89
89
|
isShuttingDown = true;
|
|
90
|
-
const
|
|
91
|
-
const
|
|
90
|
+
const shutdownBudgetMs = Env.getInt('SHUTDOWN_TIMEOUT', 1500);
|
|
91
|
+
const minForceExitMs = shutdownBudgetMs + 250;
|
|
92
|
+
const forceExitMs = Math.max(Env.getInt('SHUTDOWN_FORCE_EXIT_MS', 10000), minForceExitMs);
|
|
93
|
+
const deadlineMs = Date.now() + shutdownBudgetMs;
|
|
94
|
+
const remainingMs = () => Math.max(0, deadlineMs - Date.now());
|
|
92
95
|
Logger.info(`${signal} received, shutting down gracefully...`);
|
|
93
96
|
try {
|
|
94
97
|
const forceExitTimer = globalThis.setTimeout(() => {
|
|
@@ -97,24 +100,30 @@ const gracefulShutdown = async (signal) => {
|
|
|
97
100
|
// Best-effort: don't keep the process alive just for this timer
|
|
98
101
|
forceExitTimer.unref?.();
|
|
99
102
|
await withTimeout((async () => {
|
|
103
|
+
// Shutdown worker management system FIRST (before database closes)
|
|
104
|
+
if (appConfig.detectRuntime() === 'nodejs' || appConfig.detectRuntime() === 'lambda') {
|
|
105
|
+
try {
|
|
106
|
+
const { WorkerShutdown } = await import('../../packages/workers/src/index.js');
|
|
107
|
+
const workerBudgetMs = Math.min(15000, remainingMs());
|
|
108
|
+
await withTimeout(WorkerShutdown.shutdown({ signal, timeout: workerBudgetMs, forceExit: false }), workerBudgetMs, 'Worker shutdown timed out');
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
Logger.warn('Worker shutdown failed (continuing with app shutdown)', error);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
100
114
|
if (serverInstance !== undefined) {
|
|
101
115
|
await serverInstance.close();
|
|
102
116
|
}
|
|
103
117
|
if (appInstance !== undefined) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
await withTimeout(WorkerShutdown.shutdown({ signal, timeout: 30000, forceExit: false }), timeoutMs, 'Worker shutdown timed out');
|
|
112
|
-
Logger.info('Worker management system shutdown complete');
|
|
113
|
-
}
|
|
114
|
-
catch (error) {
|
|
115
|
-
Logger.warn('Worker shutdown failed (continuing with app shutdown)', error);
|
|
118
|
+
try {
|
|
119
|
+
const appBudgetMs = Math.min(5000, remainingMs());
|
|
120
|
+
await withTimeout(appInstance.shutdown(), appBudgetMs, 'App shutdown timed out');
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
Logger.warn('App shutdown failed or timed out, forcing exit', error);
|
|
124
|
+
}
|
|
116
125
|
}
|
|
117
|
-
}
|
|
126
|
+
})(), shutdownBudgetMs, 'Graceful shutdown timed out');
|
|
118
127
|
globalThis.clearTimeout(forceExitTimer);
|
|
119
128
|
process.exit(0);
|
|
120
129
|
}
|
|
@@ -155,6 +164,16 @@ const BootstrapFunctions = Object.freeze({
|
|
|
155
164
|
*/
|
|
156
165
|
async start() {
|
|
157
166
|
try {
|
|
167
|
+
// Ensure project-installed adapters/drivers are registered for web server.
|
|
168
|
+
// (This is driven by src/zintrust.plugins.ts generated by `zin plugin install`.)
|
|
169
|
+
try {
|
|
170
|
+
const { PluginAutoImports } = await import('../runtime/PluginAutoImports.js');
|
|
171
|
+
await PluginAutoImports.tryImportProjectAutoImports();
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
// best-effort; run without plugins if loader fails (e.g. non-Node runtime)
|
|
175
|
+
Logger.debug('Plugin auto-imports loader skipped:', error);
|
|
176
|
+
}
|
|
158
177
|
// Create application instance
|
|
159
178
|
// if (Env.ZINTRUST_PROJECT_ROOT) {
|
|
160
179
|
// }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RedisDriver.d.ts","sourceRoot":"","sources":["../../../../src/cache/drivers/RedisDriver.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"RedisDriver.d.ts","sourceRoot":"","sources":["../../../../src/cache/drivers/RedisDriver.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAoFtD;;GAEG;AACH,eAAO,MAAM,WAAW;kBA9EL,WAAW;EAgF5B,CAAC"}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { Env } from '../../config/env.js';
|
|
6
6
|
import { Logger } from '../../config/logger.js';
|
|
7
7
|
import * as net from '../../node-singletons/net.js';
|
|
8
|
+
import { createCacheKey } from '../../tools/redis/RedisKeyManager.js';
|
|
8
9
|
/**
|
|
9
10
|
* Create a new Redis driver instance
|
|
10
11
|
*/
|
|
@@ -38,7 +39,8 @@ const create = () => {
|
|
|
38
39
|
return {
|
|
39
40
|
async get(key) {
|
|
40
41
|
try {
|
|
41
|
-
const
|
|
42
|
+
const prefixedKey = createCacheKey(key);
|
|
43
|
+
const response = await sendCommand(`GET ${prefixedKey}\r\n`);
|
|
42
44
|
if (response.startsWith('$-1'))
|
|
43
45
|
return null;
|
|
44
46
|
// Basic RESP parsing
|
|
@@ -52,21 +54,24 @@ const create = () => {
|
|
|
52
54
|
}
|
|
53
55
|
},
|
|
54
56
|
async set(key, value, ttl) {
|
|
57
|
+
const prefixedKey = createCacheKey(key);
|
|
55
58
|
const jsonValue = JSON.stringify(value);
|
|
56
|
-
let command = `SET ${
|
|
59
|
+
let command = `SET ${prefixedKey} ${jsonValue}\r\n`;
|
|
57
60
|
if (ttl !== undefined) {
|
|
58
|
-
command = `SETEX ${
|
|
61
|
+
command = `SETEX ${prefixedKey} ${ttl} ${jsonValue}\r\n`;
|
|
59
62
|
}
|
|
60
63
|
await sendCommand(command);
|
|
61
64
|
},
|
|
62
65
|
async delete(key) {
|
|
63
|
-
|
|
66
|
+
const prefixedKey = createCacheKey(key);
|
|
67
|
+
await sendCommand(`DEL ${prefixedKey}\r\n`);
|
|
64
68
|
},
|
|
65
69
|
async clear() {
|
|
66
70
|
await sendCommand(`FLUSHDB\r\n`);
|
|
67
71
|
},
|
|
68
72
|
async has(key) {
|
|
69
|
-
const
|
|
73
|
+
const prefixedKey = createCacheKey(key);
|
|
74
|
+
const response = await sendCommand(`EXISTS ${prefixedKey}\r\n`);
|
|
70
75
|
return response.includes(':1');
|
|
71
76
|
},
|
|
72
77
|
};
|
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;AA0CH,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;AA2MD;;;;;;;GAOG;AACH,eAAO,MAAM,GAAG;cACJ,IAAI;EAed,CAAC"}
|
package/src/cli/CLI.js
CHANGED
|
@@ -32,6 +32,7 @@ import { TemplatesCommand } from './commands/TemplatesCommand.js';
|
|
|
32
32
|
import { UpgradeCommand } from './commands/UpgradeCommand.js';
|
|
33
33
|
import { WorkerCommands } from './commands/WorkerCommands.js';
|
|
34
34
|
import { ErrorHandler } from './ErrorHandler.js';
|
|
35
|
+
import { VersionChecker } from './services/VersionChecker.js';
|
|
35
36
|
import { esmDirname } from '../common/index.js';
|
|
36
37
|
import { Logger } from '../config/logger.js';
|
|
37
38
|
import { ErrorFactory } from '../exceptions/ZintrustError.js';
|
|
@@ -194,6 +195,11 @@ const runCLI = async (program, version, args) => {
|
|
|
194
195
|
}
|
|
195
196
|
// Always show banner for normal commands
|
|
196
197
|
ErrorHandler.banner(version);
|
|
198
|
+
// Run version check in background (non-blocking)
|
|
199
|
+
VersionChecker.runVersionCheck().catch((error) => {
|
|
200
|
+
// Version check should never crash the CLI
|
|
201
|
+
Logger.debug('Version check encountered an error', error);
|
|
202
|
+
});
|
|
197
203
|
// Show help if no arguments provided
|
|
198
204
|
if (args.length === 0) {
|
|
199
205
|
program.help();
|
|
@@ -1 +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;
|
|
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;AAqHvF,eAAO,MAAM,YAAY;cACb,YAAY;EAmBtB,CAAC;AAEH,eAAe,YAAY,CAAC"}
|
|
@@ -3,8 +3,93 @@
|
|
|
3
3
|
* Run queued jobs via the framework CLI.
|
|
4
4
|
*/
|
|
5
5
|
import { BaseCommand } from '../BaseCommand.js';
|
|
6
|
+
import { setupQueueLockCommands } from '../commands/QueueLockCommand.js';
|
|
6
7
|
import { QueueWorkCommandUtils } from '../commands/QueueWorkCommandUtils.js';
|
|
7
8
|
import { QueueWorkRunner } from '../workers/QueueWorkRunner.js';
|
|
9
|
+
/**
|
|
10
|
+
* Setup work subcommand with explicit kind
|
|
11
|
+
*/
|
|
12
|
+
const setupWorkCommand = (command) => {
|
|
13
|
+
command
|
|
14
|
+
.command('work <kind> <queueName>')
|
|
15
|
+
.alias('w')
|
|
16
|
+
.description('Work a queue with explicit kind (broadcast|notification)')
|
|
17
|
+
.option('--timeout <seconds>', 'Stop after this many seconds (default: 10)')
|
|
18
|
+
.option('--retry <count>', 'Retries after first attempt (default: 3)')
|
|
19
|
+
.option('--max-items <count>', 'Max items to process in one run (default: 1000)')
|
|
20
|
+
.option('--driver <name>', 'Queue driver name (default: from QUEUE_DRIVER)')
|
|
21
|
+
.action(async (kindRaw, queueName, subOptions) => {
|
|
22
|
+
const kind = QueueWorkRunner.parseKind(kindRaw);
|
|
23
|
+
const timeoutSeconds = QueueWorkCommandUtils.parsePositiveInt(subOptions['timeout'], '--timeout');
|
|
24
|
+
const retry = QueueWorkCommandUtils.parseNonNegativeInt(subOptions['retry'], '--retry');
|
|
25
|
+
const maxItems = QueueWorkCommandUtils.parsePositiveInt(subOptions['maxItems'], '--max-items');
|
|
26
|
+
const driverName = QueueWorkCommandUtils.normalizeDriverName(subOptions['driver']);
|
|
27
|
+
const result = await QueueWorkRunner.run({
|
|
28
|
+
kind,
|
|
29
|
+
queueName,
|
|
30
|
+
timeoutSeconds,
|
|
31
|
+
retry,
|
|
32
|
+
maxItems,
|
|
33
|
+
driverName,
|
|
34
|
+
});
|
|
35
|
+
QueueWorkCommandUtils.logSummary(queueName, kind, result);
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Setup prune subcommand
|
|
40
|
+
*/
|
|
41
|
+
const setupPruneCommand = (command) => {
|
|
42
|
+
command
|
|
43
|
+
.command('prune')
|
|
44
|
+
.description('Prune failed jobs from the database queue')
|
|
45
|
+
.option('--hours <count>', 'Prune jobs older than this many hours (default: 168)', '168')
|
|
46
|
+
.action(async (options) => {
|
|
47
|
+
const { Logger } = await import('../../config/logger.js');
|
|
48
|
+
const { QueryBuilder } = await import('../../orm/QueryBuilder.js');
|
|
49
|
+
const { useEnsureDbConnected } = await import('../../orm/Database.js');
|
|
50
|
+
const { databaseConfig } = await import('../../config/database.js');
|
|
51
|
+
const hours = Number.parseInt(options.hours ?? '168', 10);
|
|
52
|
+
const cutoff = new Date(Date.now() - hours * 60 * 60 * 1000);
|
|
53
|
+
Logger.info(`[Queue] Pruning failed jobs older than ${cutoff.toISOString()}...`);
|
|
54
|
+
try {
|
|
55
|
+
// Resolved connection config (Queue prune usually runs on default DB)
|
|
56
|
+
const config = databaseConfig.getConnection();
|
|
57
|
+
const db = await useEnsureDbConnected(config);
|
|
58
|
+
const deleted = await QueryBuilder.create('queue_jobs_failed', db)
|
|
59
|
+
.where('failed_at', '<', cutoff)
|
|
60
|
+
.delete();
|
|
61
|
+
Logger.info(`[Queue] Pruned ${deleted} failed jobs.`);
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
65
|
+
if (msg.includes('no such table')) {
|
|
66
|
+
Logger.warn('[Queue] Table queue_jobs_failed not found. Skipping prune.');
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
Logger.error('[Queue] Prune failed', err);
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Parse command options and run queue work
|
|
77
|
+
*/
|
|
78
|
+
const executeQueueWork = async (options) => {
|
|
79
|
+
const queueName = QueueWorkCommandUtils.requireQueueNameFromArgs(options.args, 'zin queue --help');
|
|
80
|
+
const timeoutSeconds = QueueWorkCommandUtils.parsePositiveInt(options.timeout, '--timeout');
|
|
81
|
+
const retry = QueueWorkCommandUtils.parseNonNegativeInt(options.retry, '--retry');
|
|
82
|
+
const maxItems = QueueWorkCommandUtils.parsePositiveInt(options.maxItems, '--max-items');
|
|
83
|
+
const driverName = QueueWorkCommandUtils.normalizeDriverName(options.driver);
|
|
84
|
+
const result = await QueueWorkRunner.run({
|
|
85
|
+
queueName,
|
|
86
|
+
timeoutSeconds,
|
|
87
|
+
retry,
|
|
88
|
+
maxItems,
|
|
89
|
+
driverName,
|
|
90
|
+
});
|
|
91
|
+
QueueWorkCommandUtils.logSummary(queueName, 'auto', result);
|
|
92
|
+
};
|
|
8
93
|
export const QueueCommand = Object.freeze({
|
|
9
94
|
create() {
|
|
10
95
|
return BaseCommand.create({
|
|
@@ -17,46 +102,11 @@ export const QueueCommand = Object.freeze({
|
|
|
17
102
|
.option('--retry <count>', 'Retries after first attempt (default: 3)')
|
|
18
103
|
.option('--max-items <count>', 'Max items to process in one run (default: 1000)')
|
|
19
104
|
.option('--driver <name>', 'Queue driver name (default: from QUEUE_DRIVER)');
|
|
20
|
-
command
|
|
21
|
-
|
|
22
|
-
|
|
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);
|
|
105
|
+
setupWorkCommand(command);
|
|
106
|
+
setupPruneCommand(command);
|
|
107
|
+
setupQueueLockCommands(command);
|
|
59
108
|
},
|
|
109
|
+
execute: executeQueueWork,
|
|
60
110
|
});
|
|
61
111
|
},
|
|
62
112
|
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Queue Lock Command Extensions
|
|
3
|
+
* Implements CLI commands for managing queue locks and deduplication
|
|
4
|
+
*/
|
|
5
|
+
import type { Command } from 'commander';
|
|
6
|
+
export declare function setupQueueLockCommands(command: Command): void;
|
|
7
|
+
//# sourceMappingURL=QueueLockCommand.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QueueLockCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/QueueLockCommand.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA2IzC,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAK7D"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Queue Lock Command Extensions
|
|
3
|
+
* Implements CLI commands for managing queue locks and deduplication
|
|
4
|
+
*/
|
|
5
|
+
import { ErrorFactory } from '../../exceptions/ZintrustError.js';
|
|
6
|
+
import { ZintrustLang } from '../../lang/lang.js';
|
|
7
|
+
import { Logger } from '../../config/logger.js';
|
|
8
|
+
import { createAdvancedQueue } from '../../tools/queue/AdvancedQueue.js';
|
|
9
|
+
import { getLockProvider } from '../../tools/queue/LockProvider.js';
|
|
10
|
+
// Reusing initialization logic from AdvancedQueue
|
|
11
|
+
// But we need direct access to lock provider for maintenance
|
|
12
|
+
// AdvancedQueue only exposes limited interface
|
|
13
|
+
function getProvider(providerName = 'redis') {
|
|
14
|
+
// Create proper QueueConfig object that matches the expected interface
|
|
15
|
+
const advancedQueueConfig = {
|
|
16
|
+
name: ZintrustLang.CLI_LOCKS,
|
|
17
|
+
connection: undefined, // No specific connection needed for CLI operations
|
|
18
|
+
defaultDedupTtl: ZintrustLang.ZINTRUST_LOCKS_TTL,
|
|
19
|
+
lockProvider: providerName,
|
|
20
|
+
};
|
|
21
|
+
// Need to ensure provider is registered. creating AdvancedQueue triggers registration.
|
|
22
|
+
createAdvancedQueue(advancedQueueConfig);
|
|
23
|
+
const provider = getLockProvider(providerName);
|
|
24
|
+
if (!provider) {
|
|
25
|
+
throw ErrorFactory.createCliError(`Lock provider '${providerName}' not found.`);
|
|
26
|
+
}
|
|
27
|
+
return provider;
|
|
28
|
+
}
|
|
29
|
+
const setupLockListCommand = (command) => {
|
|
30
|
+
command
|
|
31
|
+
.command('lock:list')
|
|
32
|
+
.description('List active deduplication locks')
|
|
33
|
+
.option('--pattern <pattern>', 'Key pattern to match (default: *)', '*')
|
|
34
|
+
.option('--provider <name>', 'Lock provider name (default: redis)', 'redis')
|
|
35
|
+
.action(async (options) => {
|
|
36
|
+
try {
|
|
37
|
+
const provider = getProvider(options.provider);
|
|
38
|
+
const locks = await provider.list(options?.pattern ?? '*');
|
|
39
|
+
if (locks.length === 0) {
|
|
40
|
+
Logger.info('No locks found.');
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
Logger.info(`Found ${locks.length} locks:`);
|
|
44
|
+
// Batch all status checks for better performance
|
|
45
|
+
const statusPromises = locks.map(async (key) => {
|
|
46
|
+
const status = await provider.status(key);
|
|
47
|
+
const expires = status.expires ? status.expires.toISOString() : 'never';
|
|
48
|
+
const ttl = typeof status.ttl === 'number' ? `${Math.round(status.ttl / 1000)}s` : 'unknown';
|
|
49
|
+
return { key, ttl, expires };
|
|
50
|
+
});
|
|
51
|
+
const lockStatuses = await Promise.all(statusPromises);
|
|
52
|
+
for (const { key, ttl, expires } of lockStatuses) {
|
|
53
|
+
Logger.info(`- [${key}] (TTL: ${ttl}, Expires: ${expires})`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
Logger.error('Failed to list locks', error);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
};
|
|
61
|
+
const setupLockReleaseCommand = (command) => {
|
|
62
|
+
command
|
|
63
|
+
.command('lock:release <key>')
|
|
64
|
+
.description('Manually release a deduplication lock')
|
|
65
|
+
.option('--provider <name>', 'Lock provider name (default: redis)', 'redis')
|
|
66
|
+
.action(async (key, options) => {
|
|
67
|
+
try {
|
|
68
|
+
const provider = getProvider(options.provider);
|
|
69
|
+
const status = await provider.status(key);
|
|
70
|
+
if (!status.exists) {
|
|
71
|
+
Logger.info(`Lock '${key}' does not exist.`);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
await provider.release({ key, ttl: 0, acquired: true, expires: new Date() });
|
|
75
|
+
Logger.info(`Lock '${key}' released successfully.`);
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
Logger.error(`Failed to release lock ${key}`, error);
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
};
|
|
82
|
+
const setupLockExtendCommand = (command) => {
|
|
83
|
+
command
|
|
84
|
+
.command('lock:extend <key> <seconds>')
|
|
85
|
+
.description('Extend TTL of an existing lock')
|
|
86
|
+
.option('--provider <name>', 'Lock provider name (default: redis)', 'redis')
|
|
87
|
+
.action(async (key, seconds, options) => {
|
|
88
|
+
try {
|
|
89
|
+
const ttl = Number.parseInt(seconds, 10) * 1000;
|
|
90
|
+
const provider = getProvider(options.provider);
|
|
91
|
+
// Mock lock object for extension
|
|
92
|
+
const lock = { key, ttl: 0, acquired: true, expires: new Date() };
|
|
93
|
+
const extended = await provider.extend(lock, ttl);
|
|
94
|
+
if (extended) {
|
|
95
|
+
Logger.info(`Lock '${key}' extended by ${seconds} seconds.`);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
Logger.info(`Failed to extend lock '${key}' (may not exist).`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
Logger.error(`Failed to extend lock ${key}`, error);
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
};
|
|
106
|
+
const setupDedupeStatusCommand = (command) => {
|
|
107
|
+
command
|
|
108
|
+
.command('dedupe:status <id>')
|
|
109
|
+
.description('Check deduplication status of a job ID')
|
|
110
|
+
.option('--provider <name>', 'Lock provider name (default: redis)', 'redis')
|
|
111
|
+
.action(async (id, options) => {
|
|
112
|
+
try {
|
|
113
|
+
const provider = getProvider(options.provider);
|
|
114
|
+
const status = await provider.status(id);
|
|
115
|
+
if (status.exists) {
|
|
116
|
+
Logger.info(`Job ID '${id}' is currently LOCKED (Deduplicated).`);
|
|
117
|
+
const ttlMs = status.ttl;
|
|
118
|
+
const ttlSeconds = ttlMs !== null && ttlMs !== undefined && !Number.isNaN(ttlMs) && ttlMs > 0
|
|
119
|
+
? Math.round(ttlMs / 1000) + 's'
|
|
120
|
+
: 'unknown';
|
|
121
|
+
Logger.info(`TTL Remaining: ${ttlSeconds}`);
|
|
122
|
+
Logger.info(`Expires At: ${status.expires ? status.expires.toISOString() : 'unknown'}`);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
Logger.info(`Job ID '${id}' is NOT locked (Ready for processing or expired).`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
Logger.error(`Failed to check status for ${id}`, error);
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
};
|
|
133
|
+
export function setupQueueLockCommands(command) {
|
|
134
|
+
setupLockListCommand(command);
|
|
135
|
+
setupLockReleaseCommand(command);
|
|
136
|
+
setupLockExtendCommand(command);
|
|
137
|
+
setupDedupeStatusCommand(command);
|
|
138
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StartCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/StartCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"StartCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/StartCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAqavF,eAAO,MAAM,YAAY;cACb,YAAY;EAyBtB,CAAC"}
|
|
@@ -246,18 +246,30 @@ const executeNodeStart = async (cmd, cwd, mode, watchEnabled) => {
|
|
|
246
246
|
cmd.warn('Watch mode disabled; starting once.');
|
|
247
247
|
const bootstrap = resolveBootstrapEntryTs(cwd);
|
|
248
248
|
const args = bootstrap === undefined ? ['src/index.ts'] : [bootstrap];
|
|
249
|
-
const exitCode = await SpawnUtil.spawnAndWait({
|
|
249
|
+
const exitCode = await SpawnUtil.spawnAndWait({
|
|
250
|
+
command: 'tsx',
|
|
251
|
+
args,
|
|
252
|
+
forwardSignals: false,
|
|
253
|
+
});
|
|
250
254
|
process.exit(exitCode);
|
|
251
255
|
}
|
|
252
256
|
const packageJson = readPackageJson(cwd);
|
|
253
257
|
const dev = resolveNodeDevCommand(cwd, packageJson);
|
|
254
258
|
cmd.info('Starting in development mode (watch enabled)...');
|
|
255
|
-
const exitCode = await SpawnUtil.spawnAndWait({
|
|
259
|
+
const exitCode = await SpawnUtil.spawnAndWait({
|
|
260
|
+
command: dev.command,
|
|
261
|
+
args: dev.args,
|
|
262
|
+
forwardSignals: false,
|
|
263
|
+
});
|
|
256
264
|
process.exit(exitCode);
|
|
257
265
|
}
|
|
258
266
|
const prod = resolveNodeProdCommand(cwd);
|
|
259
267
|
cmd.info('Starting in production mode...');
|
|
260
|
-
const exitCode = await SpawnUtil.spawnAndWait({
|
|
268
|
+
const exitCode = await SpawnUtil.spawnAndWait({
|
|
269
|
+
command: prod.command,
|
|
270
|
+
args: prod.args,
|
|
271
|
+
forwardSignals: false,
|
|
272
|
+
});
|
|
261
273
|
process.exit(exitCode);
|
|
262
274
|
};
|
|
263
275
|
const executeStart = async (options, cmd) => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { BaseCommand } from '../BaseCommand.js';
|
|
2
2
|
import { ErrorHandler } from '../ErrorHandler.js';
|
|
3
3
|
import { ErrorFactory } from '../../exceptions/ZintrustError.js';
|
|
4
|
-
import { listTemplates as listMail, renderTemplate as renderMail } from '../../tools/mail/templates/
|
|
4
|
+
import { listTemplates as listMail, renderTemplate as renderMail } from '../../tools/mail/templates/index.js';
|
|
5
5
|
import { listTemplates as listNotification, renderTemplate as renderNotification, } from '../../tools/notification/templates/markdown/index.js';
|
|
6
6
|
const listForScope = (scope) => {
|
|
7
7
|
let items = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkerCommands.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/WorkerCommands.ts"],"names":[],"mappings":"AACA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"WorkerCommands.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/WorkerCommands.ts"],"names":[],"mappings":"AACA;;;GAGG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAmWrD;;GAEG;AACH,eAAO,MAAM,cAAc;mCAjPS,YAAY;qCA4CV,YAAY;oCAiDb,YAAY;mCA+Bb,YAAY;sCAgCT,YAAY;sCAgCZ,YAAY;CA4DlD,CAAC"}
|