@zintrust/core 0.1.38 → 0.1.40

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 (72) hide show
  1. package/bin/z.js +0 -0
  2. package/bin/zin.js +0 -0
  3. package/bin/zintrust.js +0 -0
  4. package/bin/zt.js +0 -0
  5. package/package.json +2 -2
  6. package/public/index.html +2 -2
  7. package/src/boot/Application.d.ts.map +1 -1
  8. package/src/boot/Application.js +101 -74
  9. package/src/boot/bootstrap.js +2 -6
  10. package/src/cli/PromptHelper.js +2 -2
  11. package/src/cli/commands/MigrateWorkerCommand.d.ts.map +1 -1
  12. package/src/cli/commands/MigrateWorkerCommand.js +1 -1
  13. package/src/cli/commands/StartCommand.d.ts.map +1 -1
  14. package/src/cli/commands/StartCommand.js +16 -4
  15. package/src/cli/utils/EnvFileLoader.d.ts +2 -1
  16. package/src/cli/utils/EnvFileLoader.d.ts.map +1 -1
  17. package/src/cli/utils/EnvFileLoader.js +8 -8
  18. package/src/cli/utils/spawn.d.ts.map +1 -1
  19. package/src/cli/utils/spawn.js +17 -10
  20. package/src/cli/workers/QueueWorkRunner.d.ts.map +1 -1
  21. package/src/cli/workers/QueueWorkRunner.js +5 -5
  22. package/src/common/ExternalServiceUtils.d.ts.map +1 -1
  23. package/src/common/ExternalServiceUtils.js +7 -2
  24. package/src/config/env.d.ts +5 -0
  25. package/src/config/env.d.ts.map +1 -1
  26. package/src/config/env.js +7 -1
  27. package/src/config/index.d.ts +1 -1
  28. package/src/config/logger.d.ts.map +1 -1
  29. package/src/config/logger.js +60 -16
  30. package/src/config/queue.d.ts +1 -1
  31. package/src/config/queue.d.ts.map +1 -1
  32. package/src/config/queue.js +11 -6
  33. package/src/config/redis.d.ts.map +1 -1
  34. package/src/config/redis.js +3 -2
  35. package/src/config/type.d.ts +9 -5
  36. package/src/config/type.d.ts.map +1 -1
  37. package/src/config/workers.d.ts.map +1 -1
  38. package/src/config/workers.js +4 -0
  39. package/src/index.d.ts +3 -2
  40. package/src/index.d.ts.map +1 -1
  41. package/src/index.js +3 -4
  42. package/src/lang/lang.d.ts +3 -0
  43. package/src/lang/lang.d.ts.map +1 -1
  44. package/src/lang/lang.js +3 -0
  45. package/src/middleware/CsrfMiddleware.d.ts.map +1 -1
  46. package/src/middleware/CsrfMiddleware.js +26 -11
  47. package/src/orm/Model.d.ts.map +1 -1
  48. package/src/orm/Model.js +17 -6
  49. package/src/routes/errorPages.js +1 -1
  50. package/src/runtime/PluginAutoImports.d.ts.map +1 -1
  51. package/src/runtime/PluginAutoImports.js +33 -7
  52. package/src/security/CsrfTokenManager.d.ts +18 -9
  53. package/src/security/CsrfTokenManager.d.ts.map +1 -1
  54. package/src/security/CsrfTokenManager.js +192 -11
  55. package/src/templates/project/basic/app/Middleware/index.ts.tpl +1 -1
  56. package/src/templates/project/basic/config/queue.ts.tpl +2 -2
  57. package/src/toolkit/Secrets/providers/AwsSecretsManager.d.ts.map +1 -1
  58. package/src/toolkit/Secrets/providers/AwsSecretsManager.js +4 -2
  59. package/src/tools/queue/AdvancedQueue.d.ts +2 -1
  60. package/src/tools/queue/AdvancedQueue.d.ts.map +1 -1
  61. package/src/tools/queue/AdvancedQueue.js +2 -1
  62. package/src/tools/queue/LockProvider.d.ts +4 -0
  63. package/src/tools/queue/LockProvider.d.ts.map +1 -1
  64. package/src/tools/queue/LockProvider.js +16 -0
  65. package/src/tools/queue/Queue.d.ts +38 -2
  66. package/src/tools/queue/Queue.d.ts.map +1 -1
  67. package/src/tools/queue/Queue.js +3 -2
  68. package/src/tools/queue/QueueExtensions.d.ts +2 -1
  69. package/src/tools/queue/QueueExtensions.d.ts.map +1 -1
  70. package/src/tools/redis/RedisKeyManager.d.ts +3 -0
  71. package/src/tools/redis/RedisKeyManager.d.ts.map +1 -1
  72. package/src/tools/redis/RedisKeyManager.js +23 -8
package/src/orm/Model.js CHANGED
@@ -69,14 +69,25 @@ const runObservers = async (config, hook, model) => {
69
69
  const observers = config.observers;
70
70
  if (observers === undefined || observers.length === 0)
71
71
  return;
72
- for (const observer of observers) {
73
- const fn = observer[hook];
74
- if (typeof fn === 'function') {
75
- // Observers intentionally run sequentially.
76
- // eslint-disable-next-line no-await-in-loop
77
- await fn(model);
72
+ // Run "before" hooks sequentially to ensure safety and consistent state changes.
73
+ // This allows observers to modify the model or throw errors to cancel the operation.
74
+ const isBeforeHook = ['saving', 'creating', 'updating', 'deleting'].includes(hook);
75
+ if (isBeforeHook) {
76
+ for (const observer of observers) {
77
+ const fn = observer[hook];
78
+ if (typeof fn === 'function') {
79
+ // eslint-disable-next-line no-await-in-loop
80
+ await fn(model);
81
+ }
78
82
  }
83
+ return;
79
84
  }
85
+ // Run "after" hooks in parallel for better performance.
86
+ // These are typically side effects (logging, notifications) that don't depend on each other.
87
+ await Promise.all(observers.map(async (observer) => {
88
+ const fn = observer[hook];
89
+ return typeof fn === 'function' ? Promise.resolve(fn(model)) : Promise.resolve();
90
+ }));
80
91
  };
81
92
  const createModelJSON = (config, attrs) => {
82
93
  const json = {};
@@ -31,7 +31,7 @@ const servePublicRootFile = (relativePath, response, contentType) => {
31
31
  const candidates = candidateRoots.map((root) => path.join(root, relativePath));
32
32
  const filePath = findFirstExistingFile(candidates);
33
33
  try {
34
- if (!filePath) {
34
+ if (filePath === undefined || filePath === null) {
35
35
  response.setStatus(404);
36
36
  response.setHeader(HTTP_HEADERS.CONTENT_TYPE, MIME_TYPES.TEXT);
37
37
  response.send('Not Found');
@@ -1 +1 @@
1
- {"version":3,"file":"PluginAutoImports.d.ts","sourceRoot":"","sources":["../../../src/runtime/PluginAutoImports.ts"],"names":[],"mappings":"AAMA,KAAK,YAAY,GACb;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAChC;IACE,EAAE,EAAE,KAAK,CAAC;IACV,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,WAAW,GAAG,eAAe,CAAC;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAwBN,eAAO,MAAM,iBAAiB;IAC5B;;;;;;OAMG;mCACkC,OAAO,CAAC,YAAY,CAAC;EAqB1D,CAAC"}
1
+ {"version":3,"file":"PluginAutoImports.d.ts","sourceRoot":"","sources":["../../../src/runtime/PluginAutoImports.ts"],"names":[],"mappings":"AAMA,KAAK,YAAY,GACb;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAChC;IACE,EAAE,EAAE,KAAK,CAAC;IACV,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,WAAW,GAAG,eAAe,CAAC;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAwBN,eAAO,MAAM,iBAAiB;IAC5B;;;;;;OAMG;mCACkC,OAAO,CAAC,YAAY,CAAC;EA2D1D,CAAC"}
@@ -33,21 +33,47 @@ export const PluginAutoImports = Object.freeze({
33
33
  async tryImportProjectAutoImports() {
34
34
  const projectRoot = resolveProjectRoot();
35
35
  const candidates = getCandidates(projectRoot);
36
- for (const candidate of candidates) {
37
- if (!existsSync(candidate))
38
- continue;
36
+ // Filter out non-existent candidates first
37
+ const existingCandidates = candidates.filter((candidate) => existsSync(candidate));
38
+ if (existingCandidates.length === 0) {
39
+ Logger.debug('[plugins] No plugin auto-imports file found', { projectRoot, candidates });
40
+ return { ok: false, reason: 'not-found' };
41
+ }
42
+ // Try all existing candidates in parallel
43
+ const importPromises = existingCandidates.map(async (candidate) => {
39
44
  try {
40
45
  const url = pathToFileURL(candidate).href;
41
- // eslint-disable-next-line no-await-in-loop
42
46
  await import(url);
43
47
  return { ok: true, loadedPath: candidate };
44
48
  }
45
49
  catch (error) {
46
50
  const errorMessage = error instanceof Error ? error.message : String(error);
47
- return { ok: false, loadedPath: candidate, reason: 'import-failed', errorMessage };
51
+ return {
52
+ ok: false,
53
+ loadedPath: candidate,
54
+ reason: 'import-failed',
55
+ errorMessage,
56
+ };
57
+ }
58
+ });
59
+ // Return the first successful import, or the first failure if none succeed
60
+ try {
61
+ const results = await Promise.allSettled(importPromises);
62
+ const successfulResult = results.find((result) => result.status === 'fulfilled' && result.value.ok);
63
+ if (successfulResult) {
64
+ return successfulResult.value;
48
65
  }
66
+ // Return the first failed result if no success
67
+ const firstFailedResult = results.find((result) => result.status === 'fulfilled' && !result.value.ok);
68
+ return (firstFailedResult?.value ?? {
69
+ ok: false,
70
+ reason: 'import-failed',
71
+ errorMessage: 'All candidates failed',
72
+ });
73
+ }
74
+ catch (error) {
75
+ const errorMessage = error instanceof Error ? error.message : String(error);
76
+ return { ok: false, reason: 'import-failed', errorMessage };
49
77
  }
50
- Logger.debug('[plugins] No plugin auto-imports file found', { projectRoot, candidates });
51
- return { ok: false, reason: 'not-found' };
52
78
  },
53
79
  });
@@ -2,6 +2,7 @@
2
2
  * CSRF Token Manager
3
3
  * Generate, validate, and bind CSRF tokens to sessions
4
4
  */
5
+ import type { Redis } from 'ioredis';
5
6
  export interface CsrfTokenData {
6
7
  token: string;
7
8
  sessionId: string;
@@ -9,18 +10,26 @@ export interface CsrfTokenData {
9
10
  expiresAt: Date;
10
11
  }
11
12
  export interface ICsrfTokenManager {
12
- generateToken(sessionId: string): string;
13
- validateToken(sessionId: string, token: string): boolean;
14
- invalidateToken(sessionId: string): void;
15
- getTokenData(sessionId: string): CsrfTokenData | null;
16
- refreshToken(sessionId: string): string | null;
17
- cleanup(): number;
18
- clear(): void;
19
- getTokenCount(): number;
13
+ generateToken(sessionId: string): Promise<string>;
14
+ validateToken(sessionId: string, token: string): Promise<boolean>;
15
+ invalidateToken(sessionId: string): Promise<void>;
16
+ getTokenData(sessionId: string): Promise<CsrfTokenData | null>;
17
+ refreshToken(sessionId: string): Promise<string | null>;
18
+ cleanup(): Promise<number>;
19
+ clear(): Promise<void>;
20
+ getTokenCount(): Promise<number>;
20
21
  }
21
22
  export interface CsrfTokenManagerType {
22
- create(): ICsrfTokenManager;
23
+ create(options?: CsrfTokenManagerOptions): ICsrfTokenManager;
23
24
  }
25
+ export type CsrfStoreName = 'memory' | 'redis';
26
+ export type CsrfTokenManagerOptions = {
27
+ store?: CsrfStoreName;
28
+ redis?: Redis;
29
+ keyPrefix?: string;
30
+ tokenLength?: number;
31
+ tokenTtlMs?: number;
32
+ };
24
33
  /**
25
34
  * CsrfTokenManager namespace - sealed for immutability
26
35
  */
@@ -1 +1 @@
1
- {"version":3,"file":"CsrfTokenManager.d.ts","sourceRoot":"","sources":["../../../src/security/CsrfTokenManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;IACzC,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IACzD,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAAC;IACtD,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAC/C,OAAO,IAAI,MAAM,CAAC;IAClB,KAAK,IAAI,IAAI,CAAC;IACd,aAAa,IAAI,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,IAAI,iBAAiB,CAAC;CAC7B;AAoED;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,oBAE7B,CAAC"}
1
+ {"version":3,"file":"CsrfTokenManager.d.ts","sourceRoot":"","sources":["../../../src/security/CsrfTokenManager.ts"],"names":[],"mappings":"AACA;;;GAGG;AAQH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAErC,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAClD,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAClE,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAAC;IAC/D,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACxD,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,OAAO,CAAC,EAAE,uBAAuB,GAAG,iBAAiB,CAAC;CAC9D;AAED,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE/C,MAAM,MAAM,uBAAuB,GAAG;IACpC,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAwRF;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,oBAE7B,CAAC"}
@@ -1,18 +1,40 @@
1
+ /* eslint-disable @typescript-eslint/require-await */
1
2
  /**
2
3
  * CSRF Token Manager
3
4
  * Generate, validate, and bind CSRF tokens to sessions
4
5
  */
5
6
  import { Env } from '../config/env.js';
7
+ import { Logger } from '../config/logger.js';
8
+ import { createRedisConnection } from '../config/workers.js';
9
+ import { ZintrustLang } from '../lang/lang.js';
6
10
  import { randomBytes } from '../node-singletons/crypto.js';
11
+ import { RedisKeys } from '../tools/redis/RedisKeyManager.js';
7
12
  /**
8
13
  * Create a new CSRF token manager instance
9
14
  */
10
- const create = () => {
15
+ const normalizeStoreName = (name) => {
16
+ const raw = String(name ?? '')
17
+ .trim()
18
+ .toLowerCase();
19
+ if (raw === 'redis')
20
+ return 'redis';
21
+ return 'memory';
22
+ };
23
+ const resolveStoreName = (options) => {
24
+ return normalizeStoreName(options?.store ?? Env.CSRF_STORE ?? Env.CSRF_DRIVER ?? Env.get('CSRF_STORE', 'memory'));
25
+ };
26
+ const toTokenData = (stored) => {
27
+ return {
28
+ token: stored.token,
29
+ sessionId: stored.sessionId,
30
+ createdAt: new Date(stored.createdAt),
31
+ expiresAt: new Date(stored.expiresAt),
32
+ };
33
+ };
34
+ const createMemoryManager = (tokenLength, tokenTtl) => {
11
35
  const tokens = new Map();
12
- const tokenLength = Env.TOKEN_LENGTH; // 256 bits
13
- const tokenTtl = Env.TOKEN_TTL; // 1 hour in milliseconds
14
36
  return {
15
- generateToken(sessionId) {
37
+ async generateToken(sessionId) {
16
38
  tokens.delete(sessionId);
17
39
  const token = randomBytes(tokenLength).toString('hex');
18
40
  const now = new Date();
@@ -21,7 +43,7 @@ const create = () => {
21
43
  tokens.set(sessionId, tokenData);
22
44
  return token;
23
45
  },
24
- validateToken(sessionId, token) {
46
+ async validateToken(sessionId, token) {
25
47
  const tokenData = tokens.get(sessionId);
26
48
  if (!tokenData)
27
49
  return false;
@@ -33,13 +55,13 @@ const create = () => {
33
55
  }
34
56
  return isValid;
35
57
  },
36
- invalidateToken(sessionId) {
58
+ async invalidateToken(sessionId) {
37
59
  tokens.delete(sessionId);
38
60
  },
39
- getTokenData(sessionId) {
61
+ async getTokenData(sessionId) {
40
62
  return tokens.get(sessionId) ?? null;
41
63
  },
42
- refreshToken(sessionId) {
64
+ async refreshToken(sessionId) {
43
65
  const tokenData = tokens.get(sessionId);
44
66
  if (!tokenData)
45
67
  return null;
@@ -51,7 +73,7 @@ const create = () => {
51
73
  tokenData.expiresAt = new Date(Date.now() + tokenTtl);
52
74
  return tokenData.token;
53
75
  },
54
- cleanup() {
76
+ async cleanup() {
55
77
  let removed = 0;
56
78
  const now = new Date();
57
79
  for (const [sessionId, tokenData] of tokens.entries()) {
@@ -62,14 +84,173 @@ const create = () => {
62
84
  }
63
85
  return removed;
64
86
  },
65
- clear() {
87
+ async clear() {
66
88
  tokens.clear();
67
89
  },
68
- getTokenCount() {
90
+ async getTokenCount() {
69
91
  return tokens.size;
70
92
  },
71
93
  };
72
94
  };
95
+ // Helper functions for Redis CSRF manager
96
+ const createRedisClientFactory = (options) => {
97
+ let redisClient = options?.redis ?? null;
98
+ return () => {
99
+ if (redisClient)
100
+ return redisClient;
101
+ const dbFromEnv = Env.CSRF_REDIS_DB;
102
+ const database = dbFromEnv >= 0 ? dbFromEnv : Env.getInt('REDIS_QUEUE_DB', ZintrustLang.REDIS_DEFAULT_DB);
103
+ redisClient = createRedisConnection({
104
+ host: Env.get('REDIS_HOST', 'localhost'),
105
+ port: Env.getInt('REDIS_PORT', ZintrustLang.REDIS_DEFAULT_PORT),
106
+ password: Env.get('REDIS_PASSWORD'),
107
+ db: database,
108
+ });
109
+ return redisClient;
110
+ };
111
+ };
112
+ const createRedisTokenOperations = (keyPrefix, tokenTtl, getRedisClient) => {
113
+ const buildKey = (sessionId) => `${keyPrefix}${sessionId}`;
114
+ const fetchTokenData = async (sessionId) => {
115
+ try {
116
+ const client = getRedisClient();
117
+ const payload = await client.get(buildKey(sessionId));
118
+ if (payload === null || payload === '')
119
+ return null;
120
+ const parsed = JSON.parse(payload);
121
+ return toTokenData(parsed);
122
+ }
123
+ catch (error) {
124
+ Logger.error('CSRF Redis fetch failed', error);
125
+ return null;
126
+ }
127
+ };
128
+ const saveTokenData = async (data) => {
129
+ try {
130
+ const client = getRedisClient();
131
+ const stored = {
132
+ token: data.token,
133
+ sessionId: data.sessionId,
134
+ createdAt: data.createdAt.getTime(),
135
+ expiresAt: data.expiresAt.getTime(),
136
+ };
137
+ await client.set(buildKey(data.sessionId), JSON.stringify(stored), 'PX', tokenTtl);
138
+ }
139
+ catch (error) {
140
+ Logger.error('CSRF Redis save failed', error);
141
+ }
142
+ };
143
+ const deleteToken = async (sessionId) => {
144
+ try {
145
+ const client = getRedisClient();
146
+ await client.del(buildKey(sessionId));
147
+ }
148
+ catch (error) {
149
+ Logger.error('CSRF Redis delete failed', error);
150
+ }
151
+ };
152
+ const scanKeys = async () => {
153
+ const client = getRedisClient();
154
+ const keys = [];
155
+ const stream = client.scanStream({ match: `${keyPrefix}*`, count: 200 });
156
+ return new Promise((resolve, reject) => {
157
+ stream.on('data', (resultKeys) => {
158
+ if (Array.isArray(resultKeys) && resultKeys.length) {
159
+ keys.push(...resultKeys);
160
+ }
161
+ });
162
+ stream.on('end', () => resolve(keys));
163
+ stream.on('error', (err) => reject(err));
164
+ });
165
+ };
166
+ return {
167
+ fetchTokenData,
168
+ saveTokenData,
169
+ deleteToken,
170
+ scanKeys,
171
+ };
172
+ };
173
+ const createRedisManager = (tokenLength, tokenTtl, options) => {
174
+ const keyPrefix = options?.keyPrefix ?? RedisKeys.getCsrfPrefix();
175
+ const getRedisClient = createRedisClientFactory(options);
176
+ const { fetchTokenData, saveTokenData, deleteToken, scanKeys } = createRedisTokenOperations(keyPrefix, tokenTtl, getRedisClient);
177
+ return {
178
+ async generateToken(sessionId) {
179
+ const token = randomBytes(tokenLength).toString('hex');
180
+ const now = new Date();
181
+ const expiresAt = new Date(now.getTime() + tokenTtl);
182
+ const tokenData = { token, sessionId, createdAt: now, expiresAt };
183
+ await saveTokenData(tokenData);
184
+ return token;
185
+ },
186
+ async validateToken(sessionId, token) {
187
+ const tokenData = await fetchTokenData(sessionId);
188
+ if (!tokenData)
189
+ return false;
190
+ const isValid = tokenData.token === token;
191
+ const isExpired = new Date() > tokenData.expiresAt;
192
+ if (isExpired) {
193
+ await deleteToken(sessionId);
194
+ return false;
195
+ }
196
+ return isValid;
197
+ },
198
+ async invalidateToken(sessionId) {
199
+ await deleteToken(sessionId);
200
+ },
201
+ async getTokenData(sessionId) {
202
+ return fetchTokenData(sessionId);
203
+ },
204
+ async refreshToken(sessionId) {
205
+ const tokenData = await fetchTokenData(sessionId);
206
+ if (!tokenData)
207
+ return null;
208
+ const isExpired = new Date() > tokenData.expiresAt;
209
+ if (isExpired) {
210
+ await deleteToken(sessionId);
211
+ return null;
212
+ }
213
+ tokenData.expiresAt = new Date(Date.now() + tokenTtl);
214
+ await saveTokenData(tokenData);
215
+ return tokenData.token;
216
+ },
217
+ async cleanup() {
218
+ // Redis handles expiry via TTL, so nothing to do here.
219
+ return Promise.resolve(0); // NOSONAR
220
+ },
221
+ async clear() {
222
+ try {
223
+ const keys = await scanKeys();
224
+ if (keys.length === 0)
225
+ return;
226
+ const client = getRedisClient();
227
+ await client.del(...keys);
228
+ }
229
+ catch (error) {
230
+ Logger.error('CSRF Redis clear failed', error);
231
+ }
232
+ },
233
+ async getTokenCount() {
234
+ try {
235
+ const keys = await scanKeys();
236
+ return keys.length;
237
+ }
238
+ catch (error) {
239
+ Logger.error('CSRF Redis count failed', error);
240
+ return 0;
241
+ }
242
+ },
243
+ };
244
+ };
245
+ const create = (options) => {
246
+ const tokenLength = options?.tokenLength ?? Env.TOKEN_LENGTH; // 256 bits
247
+ const tokenTtl = options?.tokenTtlMs ?? Env.TOKEN_TTL; // 1 hour in milliseconds
248
+ const store = resolveStoreName(options);
249
+ if (store === 'redis') {
250
+ return createRedisManager(tokenLength, tokenTtl, options);
251
+ }
252
+ return createMemoryManager(tokenLength, tokenTtl);
253
+ };
73
254
  /**
74
255
  * CsrfTokenManager namespace - sealed for immutability
75
256
  */
@@ -220,7 +220,7 @@ export const csrfMiddleware = (csrfManager: CsrfManagerInput) => {
220
220
  return;
221
221
  }
222
222
 
223
- const isValid = resolveCsrfManager(csrfManager).validateToken(
223
+ const isValid = await resolveCsrfManager(csrfManager).validateToken(
224
224
  String(sessionId),
225
225
  String(csrfToken)
226
226
  );
@@ -1,4 +1,4 @@
1
- import { Env, type QueueConfigOverrides, type QueueDriverName } from '@zintrust/core';
1
+ import { Env, type QueueConfigOverrides, type QueueDriverName, ZintrustLang } from '@zintrust/core';
2
2
 
3
3
  /**
4
4
  * Queue Configuration (default override)
@@ -41,7 +41,7 @@ export default {
41
41
  host: Env.get('REDIS_HOST', 'localhost'),
42
42
  port: Env.getInt('REDIS_PORT', 6379),
43
43
  password: Env.get('REDIS_PASSWORD'),
44
- database: Env.getInt('REDIS_QUEUE_DB', 1),
44
+ database: Env.getInt('REDIS_QUEUE_DB', ZintrustLang.REDIS_DEFAULT_DB),
45
45
  // Note: Redis driver uses BullMQ for enterprise features
46
46
  // See BullMQ environment variables in file header for customization
47
47
  },
@@ -1 +1 @@
1
- {"version":3,"file":"AwsSecretsManager.d.ts","sourceRoot":"","sources":["../../../../../src/toolkit/Secrets/providers/AwsSecretsManager.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,cAAc,GAAG;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AA0GF,eAAO,MAAM,iBAAiB;qBACX;QACf,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;QACzE,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KAC9D;iBAsDY,MAAM,EAAE;EAcrB,CAAC;AAEH,eAAe,iBAAiB,CAAC"}
1
+ {"version":3,"file":"AwsSecretsManager.d.ts","sourceRoot":"","sources":["../../../../../src/toolkit/Secrets/providers/AwsSecretsManager.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,cAAc,GAAG;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AA0GF,eAAO,MAAM,iBAAiB;qBACX;QACf,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;QACzE,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KAC9D;iBAsDY,MAAM,EAAE;EAkBrB,CAAC;AAEH,eAAe,iBAAiB,CAAC"}
@@ -117,9 +117,11 @@ export const AwsSecretsManager = Object.freeze({
117
117
  },
118
118
  doctorEnv() {
119
119
  const missing = [];
120
- const region = (readEnvString('AWS_REGION') || readEnvString('AWS_DEFAULT_REGION')).trim();
121
- if (region === '')
120
+ const awsRegion = readEnvString('AWS_REGION').trim();
121
+ const awsDefaultRegion = readEnvString('AWS_DEFAULT_REGION').trim();
122
+ if (awsRegion === '' && awsDefaultRegion === '') {
122
123
  missing.push('AWS_REGION');
124
+ }
123
125
  const accessKeyId = readEnvString('AWS_ACCESS_KEY_ID').trim();
124
126
  if (accessKeyId === '')
125
127
  missing.push('AWS_ACCESS_KEY_ID');
@@ -4,8 +4,9 @@
4
4
  */
5
5
  import type { AdvancedJobOptions, JobResult, QueueConfig } from '../../types/Queue';
6
6
  import { type DeduplicationBuilder } from './DeduplicationBuilder';
7
+ import type { BullMQPayload } from './Queue';
7
8
  export interface AdvancedQueue {
8
- enqueue(name: string, payload: unknown, options: AdvancedJobOptions): Promise<string>;
9
+ enqueue(name: string, payload: BullMQPayload, options: AdvancedJobOptions): Promise<string>;
9
10
  deduplicate(id: string, builder: DeduplicationBuilder): Promise<JobResult>;
10
11
  releaseLock(key: string): Promise<void>;
11
12
  extendLock(key: string, ttl: number): Promise<boolean>;
@@ -1 +1 @@
1
- {"version":3,"file":"AdvancedQueue.d.ts","sourceRoot":"","sources":["../../../../src/tools/queue/AdvancedQueue.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAElB,SAAS,EAGT,WAAW,EACZ,MAAM,eAAe,CAAC;AAKvB,OAAO,EAAE,KAAK,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAIxE,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACtF,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAC3E,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACxD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,WAAW,GAAG,aAAa,CAiBtE"}
1
+ {"version":3,"file":"AdvancedQueue.d.ts","sourceRoot":"","sources":["../../../../src/tools/queue/AdvancedQueue.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAElB,SAAS,EAGT,WAAW,EACZ,MAAM,eAAe,CAAC;AAOvB,OAAO,EAAE,KAAK,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAExE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAGlD,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5F,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAC3E,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACxD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,WAAW,GAAG,aAAa,CAiBtE"}
@@ -4,6 +4,7 @@
4
4
  */
5
5
  import { Env } from '../../config/env.js';
6
6
  import { Logger } from '../../config/logger.js';
7
+ import { queueConfig } from '../../config/queue.js';
7
8
  import { createValidationError } from '../../exceptions/ZintrustError.js';
8
9
  import { ZintrustLang } from '../../lang/lang.js';
9
10
  import { createLockProvider, getLockProvider, registerLockProvider } from './LockProvider.js';
@@ -47,7 +48,7 @@ function initializeLockProvider(lockProviderName, config) {
47
48
  return provider;
48
49
  }
49
50
  function resolveLockProviderName(config) {
50
- const envProvider = Env.get('QUEUE_LOCK_PROVIDER', '').trim();
51
+ const envProvider = queueConfig.default;
51
52
  if (config.lockProvider !== undefined &&
52
53
  config.lockProvider !== null &&
53
54
  config.lockProvider.length > 0)
@@ -3,6 +3,10 @@
3
3
  * Provides distributed lock management for job deduplication
4
4
  */
5
5
  import type { LockProvider, LockProviderConfig } from '../../types/Queue';
6
+ /**
7
+ * Close Redis connection and cleanup resources
8
+ */
9
+ export declare function closeLockProvider(): Promise<void>;
6
10
  /**
7
11
  * Redis-based Lock Provider Implementation
8
12
  */
@@ -1 +1 @@
1
- {"version":3,"file":"LockProvider.d.ts","sourceRoot":"","sources":["../../../../src/tools/queue/LockProvider.ts"],"names":[],"mappings":"AACA;;;GAGG;AAGH,OAAO,KAAK,EAGV,YAAY,EACZ,kBAAkB,EAEnB,MAAM,eAAe,CAAC;AAwKvB;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,kBAAkB,GAAG,YAAY,CAWhF;AAYD,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,kBAAkB,GAAG,YAAY,CA4FjF;AAOD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,IAAI,CAG/E;AACD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAEtE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,GAAG,YAAY,CAS3E"}
1
+ {"version":3,"file":"LockProvider.d.ts","sourceRoot":"","sources":["../../../../src/tools/queue/LockProvider.ts"],"names":[],"mappings":"AACA;;;GAGG;AAGH,OAAO,KAAK,EAGV,YAAY,EACZ,kBAAkB,EAEnB,MAAM,eAAe,CAAC;AAwBvB;;GAEG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAUvD;AAkJD;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,kBAAkB,GAAG,YAAY,CAWhF;AAYD,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,kBAAkB,GAAG,YAAY,CA4FjF;AAOD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,IAAI,CAG/E;AACD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAEtE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,GAAG,YAAY,CAS3E"}
@@ -23,6 +23,22 @@ function getRedisClient() {
23
23
  }
24
24
  return redisClient;
25
25
  }
26
+ /**
27
+ * Close Redis connection and cleanup resources
28
+ */
29
+ export async function closeLockProvider() {
30
+ if (redisClient) {
31
+ try {
32
+ await redisClient.quit();
33
+ }
34
+ catch (error) {
35
+ Logger.warn('Error closing Redis lock provider connection', error);
36
+ }
37
+ finally {
38
+ redisClient = null;
39
+ }
40
+ }
41
+ }
26
42
  const METRICS_SUFFIX = {
27
43
  attempts: 'metrics:attempts',
28
44
  acquired: 'metrics:acquired',
@@ -3,13 +3,49 @@ export type QueueMessage<T = unknown> = {
3
3
  payload: T;
4
4
  attempts: number;
5
5
  };
6
- interface IQueueDriver {
6
+ export interface IQueueDriver {
7
7
  enqueue<T = unknown>(queue: string, payload: T): Promise<string>;
8
8
  dequeue<T = unknown>(queue: string): Promise<QueueMessage<T> | undefined>;
9
9
  ack(queue: string, id: string): Promise<void>;
10
10
  length(queue: string): Promise<number>;
11
11
  drain(queue: string): Promise<void>;
12
12
  }
13
+ /**
14
+ * BullMQ payload interface with all supported JobOptions
15
+ */
16
+ export interface BullMQPayload {
17
+ to?: string;
18
+ subject?: string;
19
+ template?: string;
20
+ templateData?: Record<string, unknown>;
21
+ timestamp?: number;
22
+ attempts?: number;
23
+ uniqueId?: string;
24
+ delay?: number;
25
+ priority?: number;
26
+ removeOnComplete?: number | boolean;
27
+ removeOnFail?: number | boolean;
28
+ backoff?: {
29
+ type: 'fixed' | 'exponential';
30
+ delay: number;
31
+ };
32
+ repeat?: {
33
+ every?: number;
34
+ cron?: string;
35
+ limit?: number;
36
+ };
37
+ lifo?: boolean;
38
+ deduplication?: {
39
+ id: string;
40
+ ttl?: number;
41
+ releaseAfter?: string | number | {
42
+ condition: string;
43
+ delay: number;
44
+ };
45
+ };
46
+ uniqueVia?: string;
47
+ [key: string]: unknown;
48
+ }
13
49
  /**
14
50
  * Resolves the lock prefix for queue operations
15
51
  * Uses singleton RedisKeys for consistent key management
@@ -19,7 +55,7 @@ export declare const Queue: Readonly<{
19
55
  register(name: string, driver: IQueueDriver): void;
20
56
  reset(): void;
21
57
  get(name?: string): IQueueDriver;
22
- enqueue<T = unknown>(queue: string, payload: T, driverName?: string): Promise<string>;
58
+ enqueue(queue: string, payload: BullMQPayload, driverName?: string): Promise<string>;
23
59
  dequeue<T = unknown>(queue: string, driverName?: string): Promise<QueueMessage<T> | undefined>;
24
60
  ack(queue: string, id: string, driverName?: string): Promise<void>;
25
61
  length(queue: string, driverName?: string): Promise<number>;
@@ -1 +1 @@
1
- {"version":3,"file":"Queue.d.ts","sourceRoot":"","sources":["../../../../src/tools/queue/Queue.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,YAAY,CAAC,CAAC,GAAG,OAAO,IAAI;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,CAAC,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAErF,UAAU,YAAY;IACpB,OAAO,CAAC,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACjE,OAAO,CAAC,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IAC1E,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACvC,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC;AAID;;;GAGG;AACH,eAAO,MAAM,iBAAiB,QAAO,MAOpC,CAAC;AAIF,eAAO,MAAM,KAAK;mBACD,MAAM,UAAU,YAAY;aAIlC,IAAI;eAIF,MAAM,GAAG,YAAY;YAUlB,CAAC,mBAAmB,MAAM,WAAW,CAAC,eAAe,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAM7E,CAAC,mBACN,MAAM,eACA,MAAM,GAClB,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;eAKtB,MAAM,MAAM,MAAM,eAAe,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;kBAKpD,MAAM,eAAe,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;iBAK9C,MAAM,eAAe,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;EAI9D,CAAC;AAEH,eAAe,KAAK,CAAC"}
1
+ {"version":3,"file":"Queue.d.ts","sourceRoot":"","sources":["../../../../src/tools/queue/Queue.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,YAAY,CAAC,CAAC,GAAG,OAAO,IAAI;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,CAAC,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAErF,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACjE,OAAO,CAAC,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IAC1E,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACvC,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAE5B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAGlB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACpC,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAChC,OAAO,CAAC,EAAE;QACR,IAAI,EAAE,OAAO,GAAG,aAAa,CAAC;QAC9B,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,MAAM,CAAC,EAAE;QACP,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,IAAI,CAAC,EAAE,OAAO,CAAC;IAGf,aAAa,CAAC,EAAE;QACd,EAAE,EAAE,MAAM,CAAC;QACX,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG;YAAE,SAAS,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC;KACvE,CAAC;IAGF,SAAS,CAAC,EAAE,MAAM,CAAC;IAGnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAID;;;GAGG;AACH,eAAO,MAAM,iBAAiB,QAAO,MAOpC,CAAC;AAIF,eAAO,MAAM,KAAK;mBACD,MAAM,UAAU,YAAY;aAIlC,IAAI;eAIF,MAAM,GAAG,YAAY;mBAYX,MAAM,WAAW,aAAa,eAAe,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAM5E,CAAC,mBACN,MAAM,eACA,MAAM,GAClB,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;eAKtB,MAAM,MAAM,MAAM,eAAe,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;kBAKpD,MAAM,eAAe,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;iBAK9C,MAAM,eAAe,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;EAI9D,CAAC;AAEH,eAAe,KAAK,CAAC"}
@@ -1,3 +1,4 @@
1
+ import { ZintrustLang } from '../../lang/lang.js';
1
2
  import { Env } from '../../config/env.js';
2
3
  import { ErrorFactory } from '../../exceptions/ZintrustError.js';
3
4
  import { RedisKeys } from '../redis/RedisKeyManager.js';
@@ -22,8 +23,8 @@ export const Queue = Object.freeze({
22
23
  drivers.clear();
23
24
  },
24
25
  get(name) {
25
- const resolved = (name ?? Env.QUEUE_CONNECTION) || Env.QUEUE_DRIVER || 'inmemory';
26
- const driverName = (resolved !== null && resolved !== undefined ? String(resolved) : 'inmemory')
26
+ const resolved = (name ?? Env.QUEUE_CONNECTION) || Env.QUEUE_DRIVER || ZintrustLang.INMEMORY;
27
+ const driverName = (resolved !== null && resolved !== undefined ? String(resolved) : ZintrustLang.INMEMORY)
27
28
  .trim()
28
29
  .toLowerCase();
29
30
  const driver = drivers.get(driverName);
@@ -4,6 +4,7 @@
4
4
  */
5
5
  import type { AdvancedJobOptions, QueueConfig } from '../../types/Queue';
6
6
  import { createDeduplicationBuilder } from './DeduplicationBuilder';
7
+ import type { BullMQPayload } from './Queue';
7
8
  /**
8
9
  * Extend existing Queue with advanced capabilities
9
10
  * This provides a migration path for existing code
@@ -13,7 +14,7 @@ export declare function extendQueue(config: QueueConfig): void;
13
14
  * Enhanced enqueue method that supports advanced options
14
15
  * This can be used as a drop-in replacement for Queue.enqueue
15
16
  */
16
- export declare function enqueueAdvanced(name: string, payload: unknown, options?: AdvancedJobOptions): Promise<string>;
17
+ export declare function enqueueAdvanced(name: string, payload: BullMQPayload, options?: AdvancedJobOptions): Promise<string>;
17
18
  /**
18
19
  * Initialize default lock providers
19
20
  */
@@ -1 +1 @@
1
- {"version":3,"file":"QueueExtensions.d.ts","sourceRoot":"","sources":["../../../../src/tools/queue/QueueExtensions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAsB,WAAW,EAAE,MAAM,eAAe,CAAC;AAKzF,OAAO,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AAMzE;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAWrD;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,MAAM,CAAC,CAOjB;AAED;;GAEG;AACH,wBAAgB,8BAA8B,IAAI,IAAI,CAuBrD;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,UAAU,CAAC,OAAO,0BAA0B,CAAC,CAEvF;AAED;;GAEG;AACH,eAAO,MAAM,UAAU,EAAE;IACvB,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACvD,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAkC3C,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,gBAAgB;IAC3B;;OAEG;uCAEgB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,aAC7B,MAAM,GAChB,kBAAkB;IAOrB;;OAEG;uCAEgB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,mBACvB,MAAM,QACjB,MAAM,GACX,kBAAkB;CAStB,CAAC"}
1
+ {"version":3,"file":"QueueExtensions.d.ts","sourceRoot":"","sources":["../../../../src/tools/queue/QueueExtensions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAsB,WAAW,EAAE,MAAM,eAAe,CAAC;AAKzF,OAAO,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AAEzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAKlD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAWrD;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,aAAa,EACtB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,MAAM,CAAC,CAOjB;AAED;;GAEG;AACH,wBAAgB,8BAA8B,IAAI,IAAI,CAuBrD;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,UAAU,CAAC,OAAO,0BAA0B,CAAC,CAEvF;AAED;;GAEG;AACH,eAAO,MAAM,UAAU,EAAE;IACvB,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACvD,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAkC3C,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,gBAAgB;IAC3B;;OAEG;uCAEgB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,aAC7B,MAAM,GAChB,kBAAkB;IAOrB;;OAEG;uCAEgB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,mBACvB,MAAM,QACjB,MAAM,GACX,kBAAkB;CAStB,CAAC"}