@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.
Files changed (152) hide show
  1. package/package.json +4 -3
  2. package/src/auth/Auth.d.ts.map +1 -0
  3. package/src/boot/Application.d.ts.map +1 -1
  4. package/src/boot/Application.js +8 -0
  5. package/src/boot/bootstrap.js +34 -15
  6. package/src/cache/drivers/RedisDriver.d.ts.map +1 -1
  7. package/src/cache/drivers/RedisDriver.js +10 -5
  8. package/src/cli/CLI.d.ts.map +1 -1
  9. package/src/cli/CLI.js +6 -0
  10. package/src/cli/commands/QueueCommand.d.ts.map +1 -1
  11. package/src/cli/commands/QueueCommand.js +89 -39
  12. package/src/cli/commands/QueueLockCommand.d.ts +7 -0
  13. package/src/cli/commands/QueueLockCommand.d.ts.map +1 -0
  14. package/src/cli/commands/QueueLockCommand.js +138 -0
  15. package/src/cli/commands/StartCommand.d.ts.map +1 -1
  16. package/src/cli/commands/StartCommand.js +15 -3
  17. package/src/cli/commands/TemplatesCommand.js +1 -1
  18. package/src/cli/commands/WorkerCommands.d.ts.map +1 -1
  19. package/src/cli/commands/WorkerCommands.js +46 -22
  20. package/src/cli/scaffolding/ProjectScaffolder.js +2 -2
  21. package/src/cli/scaffolding/RouteGenerator.d.ts.map +1 -1
  22. package/src/cli/scaffolding/RouteGenerator.js +27 -28
  23. package/src/cli/services/VersionChecker.d.ts +53 -0
  24. package/src/cli/services/VersionChecker.d.ts.map +1 -0
  25. package/src/cli/services/VersionChecker.js +180 -0
  26. package/src/cli/workers/QueueWorkRunner.d.ts.map +1 -1
  27. package/src/cli/workers/QueueWorkRunner.js +128 -7
  28. package/src/common/ExternalServiceUtils.d.ts +2 -2
  29. package/src/config/app.d.ts +4 -0
  30. package/src/config/app.d.ts.map +1 -1
  31. package/src/config/app.js +9 -0
  32. package/src/config/constants.d.ts +140 -10
  33. package/src/config/constants.d.ts.map +1 -1
  34. package/src/config/constants.js +86 -5
  35. package/src/config/index.d.ts +1 -0
  36. package/src/config/index.d.ts.map +1 -1
  37. package/src/config/middleware.d.ts +6 -6
  38. package/src/config/middleware.d.ts.map +1 -1
  39. package/src/config/middleware.js +6 -7
  40. package/src/config/queue.d.ts +4 -0
  41. package/src/config/queue.d.ts.map +1 -1
  42. package/src/config/queue.js +1 -1
  43. package/src/config/redis.d.ts +17 -0
  44. package/src/config/redis.d.ts.map +1 -0
  45. package/src/config/redis.js +54 -0
  46. package/src/config/type.d.ts +3 -0
  47. package/src/config/type.d.ts.map +1 -1
  48. package/src/http/Request.d.ts +10 -1
  49. package/src/http/Request.d.ts.map +1 -1
  50. package/src/http/Request.js +79 -7
  51. package/src/http/error-pages/ErrorPageRenderer.d.ts.map +1 -1
  52. package/src/http/error-pages/ErrorPageRenderer.js +4 -3
  53. package/src/index.d.ts +14 -11
  54. package/src/index.d.ts.map +1 -1
  55. package/src/index.js +18 -11
  56. package/src/lang/lang.d.ts +23 -0
  57. package/src/lang/lang.d.ts.map +1 -0
  58. package/src/lang/lang.js +22 -0
  59. package/src/middleware/ErrorHandlerMiddleware.d.ts.map +1 -1
  60. package/src/middleware/ErrorHandlerMiddleware.js +9 -1
  61. package/src/migrations/schema/SchemaCompiler.js +1 -1
  62. package/src/migrations/schema/types.d.ts +1 -1
  63. package/src/migrations/schema/types.d.ts.map +1 -1
  64. package/src/node.d.ts +1 -1
  65. package/src/node.d.ts.map +1 -1
  66. package/src/node.js +1 -1
  67. package/src/orm/Database.d.ts +1 -1
  68. package/src/orm/Database.d.ts.map +1 -1
  69. package/src/orm/Database.js +22 -3
  70. package/src/performance/Optimizer.js +1 -1
  71. package/src/routing/Router.d.ts +6 -2
  72. package/src/routing/Router.d.ts.map +1 -1
  73. package/src/routing/Router.js +19 -4
  74. package/src/runtime/PluginManager.js +1 -1
  75. package/src/runtime/PluginRegistry.js +2 -2
  76. package/src/start.d.ts.map +1 -1
  77. package/src/start.js +8 -7
  78. package/src/templates/TemplateRegistry.js +2 -2
  79. package/src/templates/TemplateRegistry.ts +2 -2
  80. package/src/templates/feature/Queue.ts.tpl +114 -0
  81. package/src/templates/project/basic/app/Controllers/UserController.ts.tpl +22 -0
  82. package/src/templates/project/basic/config/queue.ts.tpl +19 -0
  83. package/src/templates/project/basic/package.json.tpl +2 -1
  84. package/src/templates/project/basic/src/index.ts.tpl +0 -3
  85. package/src/tools/broadcast/drivers/Redis.d.ts.map +1 -1
  86. package/src/tools/broadcast/drivers/Redis.js +8 -56
  87. package/src/tools/mail/Mail.d.ts +1 -29
  88. package/src/tools/mail/Mail.d.ts.map +1 -1
  89. package/src/tools/mail/Mail.js +1 -111
  90. package/src/tools/mail/drivers/SendGrid.d.ts.map +1 -1
  91. package/src/tools/mail/drivers/SendGrid.js +4 -3
  92. package/src/tools/mail/drivers/Smtp.d.ts.map +1 -1
  93. package/src/tools/mail/drivers/Smtp.js +32 -10
  94. package/src/tools/mail/index.d.ts +40 -0
  95. package/src/tools/mail/index.d.ts.map +1 -0
  96. package/src/tools/mail/index.js +129 -0
  97. package/src/tools/mail/template-loader.d.ts +10 -0
  98. package/src/tools/mail/template-loader.d.ts.map +1 -0
  99. package/src/tools/mail/template-loader.js +101 -0
  100. package/src/tools/mail/template-utils.d.ts +10 -0
  101. package/src/tools/mail/template-utils.d.ts.map +1 -0
  102. package/src/tools/mail/template-utils.js +16 -0
  103. package/src/tools/mail/templates/index.d.ts +30 -0
  104. package/src/tools/mail/templates/index.d.ts.map +1 -1
  105. package/src/tools/mail/templates/index.js +69 -0
  106. package/src/tools/queue/AdvancedQueue.d.ts +19 -0
  107. package/src/tools/queue/AdvancedQueue.d.ts.map +1 -0
  108. package/src/tools/queue/AdvancedQueue.js +352 -0
  109. package/src/tools/queue/DeduplicationBuilder.d.ts +20 -0
  110. package/src/tools/queue/DeduplicationBuilder.d.ts.map +1 -0
  111. package/src/tools/queue/DeduplicationBuilder.js +77 -0
  112. package/src/tools/queue/LockProvider.d.ts +22 -0
  113. package/src/tools/queue/LockProvider.d.ts.map +1 -0
  114. package/src/tools/queue/LockProvider.js +282 -0
  115. package/src/tools/queue/Queue.d.ts.map +1 -1
  116. package/src/tools/queue/Queue.js +2 -1
  117. package/src/tools/queue/QueueExtensions.d.ts +46 -0
  118. package/src/tools/queue/QueueExtensions.d.ts.map +1 -0
  119. package/src/tools/queue/QueueExtensions.js +129 -0
  120. package/src/tools/queue/QueueRuntimeRegistration.d.ts.map +1 -1
  121. package/src/tools/queue/QueueRuntimeRegistration.js +2 -2
  122. package/src/tools/queue/drivers/Database.d.ts +23 -0
  123. package/src/tools/queue/drivers/Database.d.ts.map +1 -0
  124. package/src/tools/queue/drivers/Database.js +123 -0
  125. package/src/tools/queue/drivers/Redis.d.ts.map +1 -1
  126. package/src/tools/queue/drivers/Redis.js +11 -82
  127. package/src/tools/queue/index.d.ts +9 -0
  128. package/src/tools/queue/index.d.ts.map +1 -0
  129. package/src/tools/queue/index.js +7 -0
  130. package/src/tools/redis/RedisKeyManager.d.ts +64 -0
  131. package/src/tools/redis/RedisKeyManager.d.ts.map +1 -0
  132. package/src/tools/redis/RedisKeyManager.js +124 -0
  133. package/src/types/Queue.d.ts +62 -0
  134. package/src/types/Queue.d.ts.map +1 -0
  135. package/src/types/Queue.js +5 -0
  136. package/src/features/Auth.d.ts.map +0 -1
  137. package/src/features/Queue.d.ts +0 -21
  138. package/src/features/Queue.d.ts.map +0 -1
  139. package/src/features/Queue.js +0 -33
  140. package/src/templates/features/Queue.ts.tpl +0 -47
  141. package/src/tools/mail/templates/markdown/index.d.ts +0 -17
  142. package/src/tools/mail/templates/markdown/index.d.ts.map +0 -1
  143. package/src/tools/mail/templates/markdown/index.js +0 -49
  144. package/src/tools/mail/templates/markdown/registry.d.ts +0 -15
  145. package/src/tools/mail/templates/markdown/registry.d.ts.map +0 -1
  146. package/src/tools/mail/templates/markdown/registry.js +0 -34
  147. package/src/tools/mail/templates/markdown/validator.d.ts +0 -16
  148. package/src/tools/mail/templates/markdown/validator.d.ts.map +0 -1
  149. package/src/tools/mail/templates/markdown/validator.js +0 -24
  150. /package/src/{features → auth}/Auth.d.ts +0 -0
  151. /package/src/{features → auth}/Auth.js +0 -0
  152. /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
- const getWorkerFactory = () => {
15
- WorkerFactory ??= WorkerFactoryAny;
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 ??= WorkerRegistryAny;
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 ??= HealthMonitorAny;
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 ??= ResourceMonitorAny;
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 = getWorkerRegistry().status(name);
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=console',
203
- 'LOG_FORMAT=json',
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;AA+LD;;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"}
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
- '<': '\\u003C',
12
- '>': '\\u003E',
13
- '/': '\\u002F',
11
+ '<': String.raw `\u003C`,
12
+ '>': String.raw `\u003E`,
13
+ '/': String.raw `\u002F`,
14
14
  '\\': '\\\\',
15
- '\b': '\\b',
16
- '\f': '\\f',
17
- '\n': '\\n',
18
- '\r': '\\r',
19
- '\t': '\\t',
20
- '\0': '\\0',
21
- '\u2028': '\\u2028',
22
- '\u2029': '\\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.replace(/[<>/\\\b\f\n\r\t\0\u2028\u2029]/g, (ch) => unsafeCharMap[ch] ?? ch);
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 localMiddlewareList = (route.middleware ?? []).map((m) => `'${m}'`).join(', ');
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 localMiddlewareList = (route.middleware ?? []).map((m) => `'${m}'`).join(', ');
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":"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"}
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"}