@zintrust/core 2.4.0 → 2.4.2

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 (49) hide show
  1. package/bin/zintrust-main.d.ts.map +1 -1
  2. package/bin/zintrust-main.js +11 -1
  3. package/package.json +2 -2
  4. package/src/cache/Cache.d.ts +6 -0
  5. package/src/cache/Cache.d.ts.map +1 -1
  6. package/src/cache/Cache.js +50 -0
  7. package/src/cache/CacheDriver.d.ts +8 -0
  8. package/src/cache/CacheDriver.d.ts.map +1 -1
  9. package/src/cache/drivers/RedisDriver.d.ts.map +1 -1
  10. package/src/cache/drivers/RedisDriver.js +64 -2
  11. package/src/cli/CLI.d.ts.map +1 -1
  12. package/src/cli/CLI.js +2 -0
  13. package/src/cli/commands/DoctorArchitectureCommand.d.ts.map +1 -1
  14. package/src/cli/commands/DoctorArchitectureCommand.js +4 -2
  15. package/src/cli/commands/RedisRpcCommand.d.ts +6 -0
  16. package/src/cli/commands/RedisRpcCommand.d.ts.map +1 -0
  17. package/src/cli/commands/RedisRpcCommand.js +96 -0
  18. package/src/cli/commands/index.d.ts +1 -0
  19. package/src/cli/commands/index.d.ts.map +1 -1
  20. package/src/cli/commands/index.js +1 -0
  21. package/src/cli/scaffolding/env.d.ts.map +1 -1
  22. package/src/cli/scaffolding/env.js +9 -0
  23. package/src/cli/services/WorkerStartupDiagnostics.d.ts.map +1 -1
  24. package/src/cli/services/WorkerStartupDiagnostics.js +4 -2
  25. package/src/config/app.d.ts.map +1 -1
  26. package/src/config/app.js +3 -0
  27. package/src/config/env.d.ts +7 -0
  28. package/src/config/env.d.ts.map +1 -1
  29. package/src/config/env.js +7 -0
  30. package/src/config/queue.d.ts.map +1 -1
  31. package/src/config/queue.js +4 -42
  32. package/src/config/workers.d.ts.map +1 -1
  33. package/src/config/workers.js +12 -6
  34. package/src/index.js +3 -3
  35. package/src/orm/adapters/D1RemoteAdapter.d.ts.map +1 -1
  36. package/src/orm/adapters/D1RemoteAdapter.js +2 -1
  37. package/src/proxy/redis/RedisProxyServer.d.ts.map +1 -1
  38. package/src/proxy/redis/RedisProxyServer.js +77 -241
  39. package/src/tools/mail/drivers/Cloudflare.d.ts.map +1 -1
  40. package/src/tools/mail/drivers/Cloudflare.js +2 -0
  41. package/src/tools/redis/RedisTransport.d.ts +2 -27
  42. package/src/tools/redis/RedisTransport.d.ts.map +1 -1
  43. package/src/tools/redis/RedisTransport.js +123 -155
  44. package/src/zintrust.plugins.d.ts +6 -3
  45. package/src/zintrust.plugins.d.ts.map +1 -1
  46. package/src/zintrust.plugins.js +6 -3
  47. package/src/proxy/redis/RedisProxyActions.d.ts +0 -15
  48. package/src/proxy/redis/RedisProxyActions.d.ts.map +0 -1
  49. package/src/proxy/redis/RedisProxyActions.js +0 -124
@@ -2,7 +2,6 @@ import { Env } from '../../config/env.js';
2
2
  import { Logger } from '../../config/logger.js';
3
3
  import { ErrorFactory } from '../../exceptions/ZintrustError.js';
4
4
  import { parseCustomHeadersFromEnv } from '../../orm/adapters/SqlProxyAdapterUtils.js';
5
- import { resolveProxyRpcService, } from '../../proxy/CloudflareProxyShared.js';
6
5
  import { SignedRequest } from '../../security/SignedRequest.js';
7
6
  const loggedSelections = new Set();
8
7
  const readEnvString = (key, fallback = '') => {
@@ -19,6 +18,20 @@ const readEnvBool = (key, fallback = false) => {
19
18
  const value = Env[key];
20
19
  return typeof value === 'boolean' ? value : fallback;
21
20
  };
21
+ const readEnvInt = (key, fallback) => {
22
+ if (typeof Env.getInt === 'function') {
23
+ return Env.getInt(key, fallback);
24
+ }
25
+ const value = Env[key];
26
+ if (typeof value === 'number' && Number.isFinite(value)) {
27
+ return value;
28
+ }
29
+ if (typeof value === 'string' && value.trim() !== '') {
30
+ const parsed = Number.parseInt(value, 10);
31
+ return Number.isNaN(parsed) ? fallback : parsed;
32
+ }
33
+ return fallback;
34
+ };
22
35
  const resolveSigningPrefix = (baseUrl) => {
23
36
  try {
24
37
  const parsed = new URL(baseUrl);
@@ -56,20 +69,19 @@ const resolveProxyBaseUrl = () => {
56
69
  return explicit;
57
70
  return `http://${Env.REDIS_PROXY_HOST}:${Env.REDIS_PROXY_PORT}`;
58
71
  };
59
- const createRequestId = () => {
60
- const crypto = globalThis.crypto;
61
- if (typeof crypto?.randomUUID === 'function')
62
- return crypto.randomUUID();
63
- return `req_${Date.now()}_${Math.random().toString(16).slice(2)}`;
64
- };
65
- const resolveProxySettings = (_options) => ({
72
+ const resolveProxySettings = () => ({
66
73
  baseUrl: resolveProxyBaseUrl(),
67
- keyId: Env.get('REDIS_PROXY_KEY_ID').trim() === '' ? undefined : Env.get('REDIS_PROXY_KEY_ID'),
68
- secret: Env.REDIS_PROXY_SECRET.trim() === '' ? undefined : Env.get('REDIS_PROXY_SECRET'),
74
+ keyId: Env.REDIS_PROXY_KEY_ID.trim() === '' ? undefined : Env.REDIS_PROXY_KEY_ID,
75
+ secret: Env.REDIS_PROXY_SECRET.trim() === '' ? undefined : Env.REDIS_PROXY_SECRET,
69
76
  timeoutMs: Env.REDIS_PROXY_TIMEOUT_MS,
70
- service: resolveProxyRpcService('redis'),
71
77
  customHeaders: parseCustomHeadersFromEnv('REDIS'),
72
78
  });
79
+ const isRedisRpcEnabled = () => readEnvBool('USE_REDIS_PROXY', false) && readEnvString('REDIS_RPC_URL', '').trim() !== '';
80
+ const resolveRpcSettings = () => ({
81
+ baseUrl: readEnvString('REDIS_RPC_URL', '').trim(),
82
+ secret: readEnvString('REDIS_RPC_SECRET', readEnvString('REDIS_PROXY_SECRET', readEnvString('APP_KEY', ''))),
83
+ timeoutMs: readEnvInt('REDIS_RPC_TIMEOUT_MS', 30000),
84
+ });
73
85
  const buildHeaders = async (settings, requestUrl, body) => {
74
86
  const headers = {
75
87
  'Content-Type': 'application/json',
@@ -90,17 +102,11 @@ const buildHeaders = async (settings, requestUrl, body) => {
90
102
  }
91
103
  return headers;
92
104
  };
93
- const requestProxyCommand = async (settings, action, payload) => {
105
+ const requestProxyCommand = async (settings, command, args) => {
94
106
  if (settings.baseUrl.trim() === '') {
95
107
  throw ErrorFactory.createConfigError('Redis proxy URL is missing (REDIS_PROXY_URL)');
96
108
  }
97
- const envelope = {
98
- service: settings.service,
99
- action,
100
- requestId: createRequestId(),
101
- payload,
102
- };
103
- const body = JSON.stringify(envelope);
109
+ const body = JSON.stringify({ command, args });
104
110
  const requestUrl = buildRequestUrl(settings.baseUrl, '/zin/redis/command');
105
111
  const headers = await buildHeaders(settings, requestUrl, body);
106
112
  const signal = typeof AbortSignal !== 'undefined' && 'timeout' in AbortSignal
@@ -114,33 +120,56 @@ const requestProxyCommand = async (settings, action, payload) => {
114
120
  });
115
121
  if (!response.ok) {
116
122
  const text = await response.text();
117
- // Don't log HTML responses (e.g., 502 Bad Gateway pages)
118
- const isHtml = text.trim().toLowerCase().startsWith('<!doctype html') ||
119
- text.trim().toLowerCase().startsWith('<html');
120
- const errorMessage = isHtml ? 'Non-JSON response from proxy (proxy may be unavailable)' : text;
121
- throw ErrorFactory.createTryCatchError(`Redis proxy request failed (${response.status})`, errorMessage);
123
+ throw ErrorFactory.createTryCatchError(`Redis proxy request failed (${response.status})`, text);
122
124
  }
123
125
  const parsed = (await response.json());
124
126
  return parsed.result;
125
127
  };
126
- const loadScriptDefinition = async (settings, definition) => {
127
- const loaded = await requestProxyCommand(settings, 'SCRIPT', {
128
- args: ['LOAD', definition.lua],
129
- });
130
- return loaded;
131
- };
132
- const getDefinedScriptSha = async (settings, registry, command) => {
133
- const cached = registry.shaByCommand.get(command);
134
- if (cached !== undefined) {
135
- return cached;
128
+ const requestRpcMethod = async (settings, method, payload) => {
129
+ if (settings.baseUrl.trim() === '') {
130
+ throw ErrorFactory.createConfigError('Redis RPC URL is missing. Set USE_REDIS_PROXY=true and REDIS_RPC_URL.');
136
131
  }
137
- const definition = registry.definitions.get(command);
138
- if (definition === undefined) {
139
- return undefined;
132
+ const url = new URL('/rpc', settings.baseUrl);
133
+ const body = JSON.stringify({
134
+ service: 'redis',
135
+ method,
136
+ payload,
137
+ });
138
+ const signal = typeof AbortSignal !== 'undefined' && 'timeout' in AbortSignal
139
+ ? AbortSignal.timeout(settings.timeoutMs)
140
+ : undefined;
141
+ const response = await fetch(url.toString(), {
142
+ method: 'POST',
143
+ headers: {
144
+ 'Content-Type': 'application/json',
145
+ ...(settings.secret !== undefined && settings.secret.trim() !== ''
146
+ ? { 'x-redis-rpc-secret': settings.secret }
147
+ : {}),
148
+ },
149
+ body,
150
+ signal,
151
+ });
152
+ const parsed = (await response.json());
153
+ if (!response.ok || parsed.ok !== true) {
154
+ const errorMessage = parsed.error?.message;
155
+ throw ErrorFactory.createTryCatchError(typeof errorMessage === 'string' && errorMessage.trim() !== ''
156
+ ? errorMessage
157
+ : `Redis RPC request failed (${response.status})`, parsed.error?.details);
140
158
  }
141
- const sha = await loadScriptDefinition(settings, definition);
142
- registry.shaByCommand.set(command, sha);
143
- return sha;
159
+ return parsed.result;
160
+ };
161
+ const requestRpcCommand = async (settings, command, args) => requestRpcMethod(settings, 'call', { args: [command, ...args] });
162
+ const requestRpcPipeline = async (settings, commands, transaction) => {
163
+ const results = await requestRpcMethod(settings, transaction ? 'multi' : 'pipeline', { commands, transaction });
164
+ return results.map(([error, result]) => [
165
+ error === null ? null : ErrorFactory.createTryCatchError(error),
166
+ result,
167
+ ]);
168
+ };
169
+ const requestRedisCommand = async (mode, settings, command, args) => {
170
+ return mode === 'rpc'
171
+ ? requestRpcCommand(settings, command, args)
172
+ : requestProxyCommand(settings, command, args);
144
173
  };
145
174
  const logTransportSelection = (mode, config, options) => {
146
175
  const rawSubsystem = options?.subsystem?.trim();
@@ -157,6 +186,7 @@ const logTransportSelection = (mode, config, options) => {
157
186
  host: mode === 'direct' ? config.host : undefined,
158
187
  port: mode === 'direct' ? config.port : undefined,
159
188
  proxyUrl: mode === 'proxy' ? resolveProxyBaseUrl() : undefined,
189
+ rpcUrl: mode === 'rpc' ? readEnvString('REDIS_RPC_URL', '') : undefined,
160
190
  });
161
191
  };
162
192
  const normalizeScanResponse = (value) => {
@@ -169,7 +199,7 @@ const normalizeScanResponse = (value) => {
169
199
  : [];
170
200
  return [cursor, batch];
171
201
  };
172
- const createScanStream = (settings, options) => {
202
+ const createScanStream = (settings, mode, options) => {
173
203
  const handlers = new Map();
174
204
  const stream = {
175
205
  on(event, handler) {
@@ -201,9 +231,13 @@ const createScanStream = (settings, options) => {
201
231
  let cursor = '0';
202
232
  do {
203
233
  // eslint-disable-next-line no-await-in-loop
204
- const result = await requestProxyCommand(settings, 'SCAN', {
205
- args: [cursor, 'MATCH', options?.match ?? '*', 'COUNT', String(options?.count ?? 200)],
206
- });
234
+ const result = await requestRedisCommand(mode, settings, 'SCAN', [
235
+ cursor,
236
+ 'MATCH',
237
+ options?.match ?? '*',
238
+ 'COUNT',
239
+ String(options?.count ?? 200),
240
+ ]);
207
241
  const [nextCursor, batch] = normalizeScanResponse(result);
208
242
  cursor = nextCursor;
209
243
  if (batch.length > 0) {
@@ -219,19 +253,18 @@ const createScanStream = (settings, options) => {
219
253
  });
220
254
  return stream;
221
255
  };
222
- const createPipeline = (settings) => {
256
+ const createPipeline = (settings, mode, transaction = false) => {
223
257
  const commands = [];
224
258
  const target = {
225
259
  async exec() {
226
- Logger.debug('[redis][proxy][pipeline] Executing pipeline', {
227
- commandCount: commands.length,
228
- commands: commands.map((c) => ({ command: c.command, argsCount: c.args.length })),
229
- });
260
+ if (mode === 'rpc') {
261
+ return requestRpcPipeline(settings, commands, transaction);
262
+ }
230
263
  const results = [];
231
264
  for (const entry of commands) {
232
265
  try {
233
266
  // eslint-disable-next-line no-await-in-loop
234
- const result = await requestProxyCommand(settings, entry.command, { args: entry.args });
267
+ const result = await requestRedisCommand(mode, settings, entry.command, entry.args);
235
268
  results.push([null, result]);
236
269
  }
237
270
  catch (error) {
@@ -245,14 +278,6 @@ const createPipeline = (settings) => {
245
278
  }
246
279
  return results;
247
280
  },
248
- runCommand(name, args) {
249
- Logger.debug('[redis][proxy][pipeline] runCommand called in pipeline', {
250
- commandName: name,
251
- argsCount: args.length,
252
- });
253
- commands.push({ command: name, args });
254
- return pipeline;
255
- },
256
281
  };
257
282
  const pipeline = new Proxy(target, {
258
283
  get(obj, prop) {
@@ -261,7 +286,7 @@ const createPipeline = (settings) => {
261
286
  if (prop in obj)
262
287
  return Reflect.get(obj, prop);
263
288
  return (...args) => {
264
- commands.push({ command: prop, args });
289
+ commands.push({ command: prop.toUpperCase(), args });
265
290
  return pipeline;
266
291
  };
267
292
  },
@@ -269,120 +294,63 @@ const createPipeline = (settings) => {
269
294
  return pipeline;
270
295
  };
271
296
  export const resolveRedisTransportMode = () => {
272
- return readEnvBool('USE_REDIS_PROXY', false) || readEnvString('REDIS_PROXY_URL', '').trim() !== ''
273
- ? 'proxy'
274
- : 'direct';
297
+ if (isRedisRpcEnabled())
298
+ return 'rpc';
299
+ return readEnvBool('USE_REDIS_PROXY', false) ? 'proxy' : 'direct';
275
300
  };
276
- const createCommandFunction = (settings, command) => {
277
- return async (...args) => requestProxyCommand(settings, command, { args });
278
- };
279
- const createDefinedScriptFunction = (settings, command, registry) => {
280
- return async (...args) => {
281
- const sha = await getDefinedScriptSha(settings, registry, command);
282
- if (sha === undefined) {
283
- return requestProxyCommand(settings, command, { args });
284
- }
285
- const definition = registry.definitions.get(command);
286
- const numberOfKeys = definition?.numberOfKeys ?? 0;
287
- return requestProxyCommand(settings, 'EVALSHA', {
288
- args: [sha, numberOfKeys, ...args],
289
- });
290
- };
291
- };
292
- const createScriptsHandler = (settings) => {
293
- return new Proxy({}, {
294
- get(_target, prop) {
295
- if (typeof prop !== 'string')
296
- return undefined;
297
- return async (...args) => requestProxyCommand(settings, prop, { args });
298
- },
299
- });
300
- };
301
- const handlePropertyAccess = (obj, prop, client, settings, registry) => {
302
- if (typeof prop !== 'string')
303
- return Reflect.get(obj, prop);
304
- if (prop === 'then')
305
- return undefined;
306
- if (prop === 'setMaxListeners') {
307
- return function (_count) {
308
- return client;
309
- };
310
- }
311
- if (prop === 'getMaxListeners') {
312
- return function () {
313
- return Infinity;
314
- };
315
- }
316
- if (registry.definitions.has(prop)) {
317
- return createDefinedScriptFunction(settings, prop, registry);
318
- }
319
- if (prop in obj) {
320
- return Reflect.get(obj, prop);
301
+ export const createRedisProxyConnection = (config, options) => {
302
+ const mode = resolveRedisTransportMode();
303
+ const settings = mode === 'rpc' ? resolveRpcSettings() : resolveProxySettings();
304
+ if (mode === 'direct') {
305
+ throw ErrorFactory.createConfigError('Redis proxy connection requested while direct mode is active.');
321
306
  }
322
- return createCommandFunction(settings, prop);
323
- };
324
- const createProxyTarget = (config, options, settings, client, registry) => {
307
+ logTransportSelection(mode, config, options);
325
308
  const target = {
326
- __bullmq_iredis: true,
327
- isCluster: false,
328
- options: Object.freeze({}),
329
309
  status: 'ready',
330
310
  connect: async () => { },
331
311
  // eslint-disable-next-line @typescript-eslint/require-await
332
312
  quit: async () => 'OK',
333
313
  disconnect: () => undefined,
334
- duplicate: () => createRedisProxyConnection(config, options, registry),
335
- defineCommand: (name, definition) => {
336
- registry.definitions.set(name, definition);
337
- registry.shaByCommand.delete(name);
338
- Logger.debug('[redis][proxy][bullmq] registered defined command', {
339
- commandName: name,
340
- numberOfKeys: definition.numberOfKeys,
341
- luaLength: definition.lua.length,
342
- });
343
- },
344
- runCommand: async (name, args) => requestProxyCommand(settings, name, { args }),
345
- on: (_event, _handler) => client ?? target,
346
- once: (_event, _handler) => client ?? target,
347
- off: (_event, _handler) => client ?? target,
348
- removeListener: (_event, _handler) => client ?? target,
349
- setMaxListeners: (_count) => client ?? target,
314
+ on: (_event, _handler) => client,
315
+ once: (_event, _handler) => client,
316
+ off: (_event, _handler) => client,
317
+ removeListener: (_event, _handler) => client,
318
+ setMaxListeners: (_count) => client,
350
319
  getMaxListeners: () => Infinity,
351
- call: async (command, ...args) => requestProxyCommand(settings, command, { args }),
352
- scripts: createScriptsHandler(settings),
353
- pipeline: () => createPipeline(settings),
354
- multi: () => createPipeline(settings),
355
- scanStream: (scanOptions) => createScanStream(settings, scanOptions),
356
- };
357
- return target;
358
- };
359
- export const createRedisProxyConnection = (config, options, registry) => {
360
- const settings = resolveProxySettings(options);
361
- const scriptRegistry = registry ?? {
362
- definitions: new Map(),
363
- shaByCommand: new Map(),
320
+ call: async (command, ...args) => {
321
+ return requestRedisCommand(mode, settings, command, args);
322
+ },
323
+ pipeline: () => createPipeline(settings, mode),
324
+ multi: () => createPipeline(settings, mode, true),
325
+ scanStream: (scanOptions) => createScanStream(settings, mode, scanOptions),
364
326
  };
365
- logTransportSelection('proxy', config, options);
366
- Logger.info('[redis][proxy] Creating opaque proxy connection', {
367
- transport: 'BullMQ',
368
- });
369
- const proxyTarget = createProxyTarget(config, options, settings, null, scriptRegistry);
370
- const client = new Proxy(proxyTarget, {
327
+ const client = new Proxy(target, {
371
328
  get(obj, prop) {
372
- return handlePropertyAccess(obj, prop, client, settings, scriptRegistry);
329
+ if (typeof prop !== 'string')
330
+ return Reflect.get(obj, prop);
331
+ if (prop === 'then')
332
+ return undefined;
333
+ if (prop === 'setMaxListeners') {
334
+ return function (_count) {
335
+ return client;
336
+ };
337
+ }
338
+ if (prop === 'getMaxListeners') {
339
+ return function () {
340
+ return Infinity;
341
+ };
342
+ }
343
+ if (prop in obj)
344
+ return Reflect.get(obj, prop);
345
+ return async (...args) => requestRedisCommand(mode, settings, prop.toUpperCase(), args);
373
346
  },
374
347
  });
375
348
  return client;
376
349
  };
377
350
  export const ensureRedisTransportMode = (config, options) => {
378
351
  const mode = resolveRedisTransportMode();
379
- const subsystem = options?.subsystem ?? 'redis';
380
- const requireDirectForScripts = options?.requireDirectForScripts ?? Env.REDIS_REQUIRE_DIRECT_FOR_SCRIPTS;
381
352
  if (mode === 'proxy' && options?.requireDirect === true) {
382
- throw ErrorFactory.createConfigError(`Redis subsystem '${subsystem}' requires a direct Redis connection, but proxy mode is enabled.`);
383
- }
384
- if (mode === 'proxy' && requireDirectForScripts) {
385
- throw ErrorFactory.createConfigError(`Redis subsystem '${subsystem}' requires a direct Redis connection for scripts, but proxy mode is enabled.`);
353
+ throw ErrorFactory.createConfigError(`Redis subsystem '${options.subsystem ?? 'redis'}' requires a direct Redis connection, but proxy mode is enabled.`);
386
354
  }
387
355
  if (mode === 'direct') {
388
356
  logTransportSelection(mode, config, options);
@@ -1,7 +1,10 @@
1
1
  /**
2
- * Auto-generated fallback module.
3
- * This file is created by scripts/ensure-worker-plugins.mjs when missing.
4
- * It allows optional runtime plugin imports to resolve in CI/scaffolded setups.
2
+ * ZinTrust plugin auto-imports
3
+ *
4
+ * In real projects, this file is managed by `zin plugin install` and contains
5
+ * side-effect imports (e.g. `@zintrust/db-sqlite/register`) that register
6
+ * optional adapters/drivers into core registries.
7
+ *
5
8
  */
6
9
  export type {};
7
10
  export declare const __zintrustGeneratedPluginStub = "zintrust.plugins.ts";
@@ -1 +1 @@
1
- {"version":3,"file":"zintrust.plugins.d.ts","sourceRoot":"","sources":["../../src/zintrust.plugins.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,YAAY,EAAE,CAAC;AAgBf,eAAO,MAAM,6BAA6B,wBAAwB,CAAC;;AACnE,wBAAkB"}
1
+ {"version":3,"file":"zintrust.plugins.d.ts","sourceRoot":"","sources":["../../src/zintrust.plugins.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,YAAY,EAAE,CAAC;AAgBf,eAAO,MAAM,6BAA6B,wBAAwB,CAAC;;AACnE,wBAAkB"}
@@ -1,7 +1,10 @@
1
1
  /**
2
- * Auto-generated fallback module.
3
- * This file is created by scripts/ensure-worker-plugins.mjs when missing.
4
- * It allows optional runtime plugin imports to resolve in CI/scaffolded setups.
2
+ * ZinTrust plugin auto-imports
3
+ *
4
+ * In real projects, this file is managed by `zin plugin install` and contains
5
+ * side-effect imports (e.g. `@zintrust/db-sqlite/register`) that register
6
+ * optional adapters/drivers into core registries.
7
+ *
5
8
  */
6
9
  import * as TraceRuntime from './runtime/plugins/trace-runtime.js';
7
10
  globalThis.__zintrust_system_trace_plugin_requested__ = true;
@@ -1,15 +0,0 @@
1
- import type { QueueDriver } from '@zintrust/queue-monitor/driver';
2
- import type { Metrics } from '@zintrust/queue-monitor/metrics';
3
- export type QueueMonitorContext = Readonly<{
4
- driver: QueueDriver;
5
- metrics: Metrics;
6
- }>;
7
- export type RedisProxyRedisConfig = Readonly<{
8
- host: string;
9
- port: number;
10
- password: string;
11
- db: number;
12
- }>;
13
- export declare const createQueueMonitorContext: (redis: RedisProxyRedisConfig) => Promise<QueueMonitorContext>;
14
- export declare const dispatchServiceCommand: (service: string, action: string, payload: Record<string, unknown>, queueMonitor: QueueMonitorContext) => Promise<unknown>;
15
- //# sourceMappingURL=RedisProxyActions.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"RedisProxyActions.d.ts","sourceRoot":"","sources":["../../../../src/proxy/redis/RedisProxyActions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iCAAiC,CAAC;AAG/D,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACzC,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC,CAAC;AAEH,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC,CAAC;AA4BH,eAAO,MAAM,yBAAyB,GACpC,OAAO,qBAAqB,KAC3B,OAAO,CAAC,mBAAmB,CAU7B,CAAC;AAuIF,eAAO,MAAM,sBAAsB,GACjC,SAAS,MAAM,EACf,QAAQ,MAAM,EACd,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,cAAc,mBAAmB,KAChC,OAAO,CAAC,OAAO,CAUjB,CAAC"}
@@ -1,124 +0,0 @@
1
- import { ErrorFactory } from '../../exceptions/ZintrustError.js';
2
- const loadQueueMonitorDriverModule = async () => {
3
- return import('@zintrust/queue-monitor/driver');
4
- };
5
- const loadQueueMonitorMetricsModule = async () => {
6
- return import('@zintrust/queue-monitor/metrics');
7
- };
8
- const loadQueueMonitoringServiceModule = async () => {
9
- return import('../../../packages/queue-monitor/src/QueueMonitoringService.js');
10
- };
11
- const loadWorkersApiModule = async () => {
12
- return import('../../../packages/workers/src/dashboard/workers-api.js');
13
- };
14
- const loadWorkerFactoryModule = async () => {
15
- return import('../../../packages/workers/src/WorkerFactory.js');
16
- };
17
- export const createQueueMonitorContext = async (redis) => {
18
- const [driverModule, metricsModule] = await Promise.all([
19
- loadQueueMonitorDriverModule(),
20
- loadQueueMonitorMetricsModule(),
21
- ]);
22
- return {
23
- driver: driverModule.createBullMQDriver(redis),
24
- metrics: metricsModule.createMetrics(redis),
25
- };
26
- };
27
- const readString = (value) => {
28
- return typeof value === 'string' && value.trim() !== '' ? value.trim() : undefined;
29
- };
30
- const readBoolean = (value) => value === true;
31
- const readNumber = (value) => {
32
- return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
33
- };
34
- const readQueueNames = (value) => {
35
- if (!Array.isArray(value))
36
- return undefined;
37
- const names = value
38
- .filter((entry) => typeof entry === 'string')
39
- .map((entry) => entry.trim())
40
- .filter((entry) => entry.length > 0);
41
- return names.length > 0 ? names : undefined;
42
- };
43
- const resolveWorkerPersistenceOverride = (payload) => {
44
- const driver = readString(payload['driver']);
45
- if (driver === 'redis')
46
- return { driver: 'redis' };
47
- if (driver === 'database')
48
- return { driver: 'database' };
49
- if (driver === 'memory')
50
- return { driver: 'memory' };
51
- return undefined;
52
- };
53
- const workerActionHandlers = {
54
- getWorkers: async (payload) => {
55
- const module = await loadWorkersApiModule();
56
- return module.getWorkers(payload);
57
- },
58
- getWorkerDetails: async (payload) => {
59
- const module = await loadWorkersApiModule();
60
- return module.getWorkerDetails(readString(payload['name'] ?? payload['workerName']) ?? '', readString(payload['driver']));
61
- },
62
- toggleAutoStart: async (payload) => {
63
- const module = await loadWorkersApiModule();
64
- return module.toggleAutoStart(readString(payload['name'] ?? payload['workerName']) ?? '', readBoolean(payload['enabled']));
65
- },
66
- listPersistedRecords: async (payload) => {
67
- const module = await loadWorkerFactoryModule();
68
- return module.WorkerFactory.listPersistedRecords(resolveWorkerPersistenceOverride(payload), {
69
- offset: readNumber(payload['offset']),
70
- limit: readNumber(payload['limit']),
71
- search: readString(payload['search']),
72
- includeInactive: readBoolean(payload['includeInactive']),
73
- });
74
- },
75
- listFileBackedRecords: async () => {
76
- const module = await loadWorkerFactoryModule();
77
- return module.WorkerFactory.listFileBackedRecords();
78
- },
79
- getPersisted: async (payload) => {
80
- const module = await loadWorkerFactoryModule();
81
- return module.WorkerFactory.getPersisted(readString(payload['name'] ?? payload['workerName']) ?? '', resolveWorkerPersistenceOverride(payload));
82
- },
83
- getHealth: async (payload) => {
84
- const module = await loadWorkerFactoryModule();
85
- return module.WorkerFactory.getHealth(readString(payload['name'] ?? payload['workerName']) ?? '');
86
- },
87
- getMetrics: async (payload) => {
88
- const module = await loadWorkerFactoryModule();
89
- return module.WorkerFactory.getMetrics(readString(payload['name'] ?? payload['workerName']) ?? '');
90
- },
91
- };
92
- const queueMonitorActionHandlers = {
93
- getRecentJobsForQueue: async (payload, queueMonitor) => {
94
- const module = await loadQueueMonitoringServiceModule();
95
- return module.getRecentJobsForQueue(readString(payload['queue'] ?? payload['queueName']) ?? '', queueMonitor.metrics, queueMonitor.driver);
96
- },
97
- getRecentJobsForSelection: async (payload, queueMonitor) => {
98
- const module = await loadQueueMonitoringServiceModule();
99
- return module.getRecentJobsForSelection(readString(payload['queue'] ?? payload['queueName']) ?? '', queueMonitor.metrics, queueMonitor.driver, readQueueNames(payload['queueNames']));
100
- },
101
- };
102
- const dispatchWorkerAction = async (action, payload) => {
103
- const handler = workerActionHandlers[action];
104
- if (handler === undefined) {
105
- throw ErrorFactory.createValidationError(`Unsupported worker action: ${action}`);
106
- }
107
- return handler(payload);
108
- };
109
- const dispatchQueueMonitorAction = async (action, payload, queueMonitor) => {
110
- const handler = queueMonitorActionHandlers[action];
111
- if (handler === undefined) {
112
- throw ErrorFactory.createValidationError(`Unsupported queue-monitor action: ${action}`);
113
- }
114
- return handler(payload, queueMonitor);
115
- };
116
- export const dispatchServiceCommand = async (service, action, payload, queueMonitor) => {
117
- if (service === 'worker') {
118
- return dispatchWorkerAction(action, payload);
119
- }
120
- if (service === 'queue-monitor') {
121
- return dispatchQueueMonitorAction(action, payload, queueMonitor);
122
- }
123
- throw ErrorFactory.createValidationError(`Unsupported RPC service: ${service}`);
124
- };