@nestjs-redisx/core 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +51 -0
- package/dist/index.d.ts +4917 -0
- package/dist/index.js +4925 -0
- package/dist/index.js.map +1 -0
- package/package.json +68 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,4917 @@
|
|
|
1
|
+
import { Provider, Type, ModuleMetadata, DynamicModule, OnModuleDestroy, Logger, OnModuleInit } from '@nestjs/common';
|
|
2
|
+
import { ModuleRef } from '@nestjs/core';
|
|
3
|
+
import EventEmitter from 'events';
|
|
4
|
+
import Redis, { Cluster } from 'ioredis';
|
|
5
|
+
import { RedisClientType, RedisClusterType, RedisSentinelType } from 'redis';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Context provided to plugins during lifecycle methods.
|
|
9
|
+
* Gives access to core services and configuration.
|
|
10
|
+
*/
|
|
11
|
+
interface IPluginContext {
|
|
12
|
+
/**
|
|
13
|
+
* Client manager for accessing and querying Redis clients.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* if (context.clientManager.hasClient('cache')) {
|
|
18
|
+
* const client = await context.clientManager.getClient('cache');
|
|
19
|
+
* }
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
readonly clientManager: IClientManager$1;
|
|
23
|
+
/**
|
|
24
|
+
* Full module configuration.
|
|
25
|
+
* Includes global config and plugin-specific config.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
29
|
+
* const cacheConfig = context.config.cache;
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
readonly config: IRedisXConfig;
|
|
33
|
+
/**
|
|
34
|
+
* Logger instance scoped to the plugin.
|
|
35
|
+
* Automatically includes plugin name in logs.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```typescript
|
|
39
|
+
* context.logger.info('Cache initialized', { size: 1000 });
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
readonly logger: IRedisXLogger;
|
|
43
|
+
/**
|
|
44
|
+
* NestJS ModuleRef for advanced DI operations.
|
|
45
|
+
* Use sparingly, prefer explicit injection.
|
|
46
|
+
*/
|
|
47
|
+
readonly moduleRef: ModuleRef;
|
|
48
|
+
/**
|
|
49
|
+
* Gets another plugin by name.
|
|
50
|
+
* Returns undefined if plugin not loaded.
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```typescript
|
|
54
|
+
* const cachePlugin = context.getPlugin<CachePlugin>('cache');
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
getPlugin<T extends IRedisXPlugin>(name: string): T | undefined;
|
|
58
|
+
/**
|
|
59
|
+
* Checks if a plugin is loaded.
|
|
60
|
+
*/
|
|
61
|
+
hasPlugin(name: string): boolean;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Client manager interface for plugin context.
|
|
65
|
+
* Delegates to the real RedisClientManager.
|
|
66
|
+
*/
|
|
67
|
+
interface IClientManager$1 {
|
|
68
|
+
/**
|
|
69
|
+
* Gets Redis client by name.
|
|
70
|
+
* @param name Client name (defaults to 'default')
|
|
71
|
+
*/
|
|
72
|
+
getClient(name?: string): Promise<IRedisDriver$1>;
|
|
73
|
+
/**
|
|
74
|
+
* Checks if client exists.
|
|
75
|
+
*/
|
|
76
|
+
hasClient(name: string): boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Gets all registered client names.
|
|
79
|
+
*/
|
|
80
|
+
getClientNames(): string[];
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* RedisX configuration interface.
|
|
84
|
+
*/
|
|
85
|
+
interface IRedisXConfig {
|
|
86
|
+
/**
|
|
87
|
+
* Redis client configurations.
|
|
88
|
+
*/
|
|
89
|
+
clients: Record<string, IClientConfig>;
|
|
90
|
+
/**
|
|
91
|
+
* Registered plugins.
|
|
92
|
+
*/
|
|
93
|
+
plugins?: IRedisXPlugin[];
|
|
94
|
+
/**
|
|
95
|
+
* Global configuration.
|
|
96
|
+
*/
|
|
97
|
+
global?: {
|
|
98
|
+
/** Enable debug logging */
|
|
99
|
+
debug?: boolean;
|
|
100
|
+
/** Default TTL for operations */
|
|
101
|
+
defaultTtl?: number;
|
|
102
|
+
/** Key prefix for all keys */
|
|
103
|
+
keyPrefix?: string;
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Client configuration.
|
|
108
|
+
*/
|
|
109
|
+
interface IClientConfig {
|
|
110
|
+
host?: string;
|
|
111
|
+
port?: number;
|
|
112
|
+
password?: string;
|
|
113
|
+
db?: number;
|
|
114
|
+
keyPrefix?: string;
|
|
115
|
+
connectTimeout?: number;
|
|
116
|
+
commandTimeout?: number;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Logger interface.
|
|
120
|
+
*/
|
|
121
|
+
interface IRedisXLogger {
|
|
122
|
+
debug(message: string, context?: Record<string, unknown>): void;
|
|
123
|
+
info(message: string, context?: Record<string, unknown>): void;
|
|
124
|
+
warn(message: string, context?: Record<string, unknown>): void;
|
|
125
|
+
error(message: string, error?: Error, context?: Record<string, unknown>): void;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Redis driver interface (re-export for context).
|
|
129
|
+
*/
|
|
130
|
+
interface IRedisDriver$1 {
|
|
131
|
+
connect(): Promise<void>;
|
|
132
|
+
disconnect(): Promise<void>;
|
|
133
|
+
isConnected(): boolean;
|
|
134
|
+
get(key: string): Promise<string | null>;
|
|
135
|
+
set(key: string, value: string, options?: unknown): Promise<'OK' | null>;
|
|
136
|
+
del(keys: string | string[]): Promise<number>;
|
|
137
|
+
eval(script: string, keys: string[], args: (string | number)[]): Promise<unknown>;
|
|
138
|
+
evalsha(sha: string, keys: string[], args: (string | number)[]): Promise<unknown>;
|
|
139
|
+
pipeline(): unknown;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Base interface for all RedisX plugins.
|
|
144
|
+
*
|
|
145
|
+
* Plugins extend core functionality without modifying core code.
|
|
146
|
+
* They follow the Open/Closed Principle.
|
|
147
|
+
*
|
|
148
|
+
* ## Lifecycle hooks
|
|
149
|
+
*
|
|
150
|
+
* `onRegister()`, `onModuleInit()`, `onModuleDestroy()` and `dependencies`
|
|
151
|
+
* are managed by `PluginRegistryService`. Plugins are initialized in
|
|
152
|
+
* topological order based on `dependencies`. During shutdown, hooks are
|
|
153
|
+
* called in reverse dependency order.
|
|
154
|
+
*
|
|
155
|
+
* @example
|
|
156
|
+
* ```typescript
|
|
157
|
+
* export class CachePlugin implements IRedisXPlugin {
|
|
158
|
+
* readonly name = 'cache';
|
|
159
|
+
* readonly version = '1.0.0';
|
|
160
|
+
*
|
|
161
|
+
* getProviders() {
|
|
162
|
+
* return [CacheService, TagIndexService];
|
|
163
|
+
* }
|
|
164
|
+
* }
|
|
165
|
+
* ```
|
|
166
|
+
*/
|
|
167
|
+
interface IRedisXPlugin {
|
|
168
|
+
/**
|
|
169
|
+
* Unique plugin identifier.
|
|
170
|
+
* Used for dependency resolution and configuration mapping.
|
|
171
|
+
* Must be lowercase, alphanumeric with hyphens.
|
|
172
|
+
*
|
|
173
|
+
* @example 'cache', 'locks', 'rate-limit'
|
|
174
|
+
*/
|
|
175
|
+
readonly name: string;
|
|
176
|
+
/**
|
|
177
|
+
* Plugin version following semver.
|
|
178
|
+
* Used for compatibility checks.
|
|
179
|
+
*
|
|
180
|
+
* @example '1.0.0', '2.1.3'
|
|
181
|
+
*/
|
|
182
|
+
readonly version: string;
|
|
183
|
+
/**
|
|
184
|
+
* Optional human-readable description.
|
|
185
|
+
*/
|
|
186
|
+
readonly description?: string;
|
|
187
|
+
/**
|
|
188
|
+
* Names of plugins this plugin depends on.
|
|
189
|
+
* Core ensures dependencies are initialized first.
|
|
190
|
+
*
|
|
191
|
+
* @example ['cache'] - depends on cache plugin
|
|
192
|
+
*/
|
|
193
|
+
readonly dependencies?: string[];
|
|
194
|
+
/**
|
|
195
|
+
* Called immediately when plugin is registered.
|
|
196
|
+
* Use for synchronous setup that doesn't require other plugins.
|
|
197
|
+
*
|
|
198
|
+
* @param context - Plugin context with core services
|
|
199
|
+
*/
|
|
200
|
+
onRegister?(context: IPluginContext): void | Promise<void>;
|
|
201
|
+
/**
|
|
202
|
+
* Called after all plugins registered and Redis connected.
|
|
203
|
+
* Dependencies are guaranteed to be initialized.
|
|
204
|
+
* Use for async setup like loading Lua scripts.
|
|
205
|
+
*
|
|
206
|
+
* @param context - Plugin context with core services
|
|
207
|
+
*/
|
|
208
|
+
onModuleInit?(context: IPluginContext): void | Promise<void>;
|
|
209
|
+
/**
|
|
210
|
+
* Called when application is shutting down.
|
|
211
|
+
* Use for cleanup (close connections, flush buffers).
|
|
212
|
+
* Called in reverse dependency order.
|
|
213
|
+
*
|
|
214
|
+
* @param context - Plugin context with core services
|
|
215
|
+
*/
|
|
216
|
+
onModuleDestroy?(context: IPluginContext): void | Promise<void>;
|
|
217
|
+
/**
|
|
218
|
+
* Returns NestJS providers this plugin contributes.
|
|
219
|
+
* These are registered in the DI container.
|
|
220
|
+
*/
|
|
221
|
+
getProviders?(): Provider[];
|
|
222
|
+
/**
|
|
223
|
+
* Returns exports that other modules can inject.
|
|
224
|
+
* Typically the main service of the plugin.
|
|
225
|
+
*/
|
|
226
|
+
getExports?(): Array<Provider | string | symbol | Type>;
|
|
227
|
+
/**
|
|
228
|
+
* Returns NestJS controllers this plugin contributes.
|
|
229
|
+
* Controllers handle HTTP endpoints.
|
|
230
|
+
*/
|
|
231
|
+
getControllers?(): Type[];
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Configuration types for NestJS RedisX.
|
|
236
|
+
* Based on ARCHITECTURE.md - Configuration Schema.
|
|
237
|
+
*/
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Base connection options common to all connection types.
|
|
241
|
+
*/
|
|
242
|
+
interface IBaseConnectionConfig {
|
|
243
|
+
/**
|
|
244
|
+
* Password for authentication.
|
|
245
|
+
*/
|
|
246
|
+
password?: string;
|
|
247
|
+
/**
|
|
248
|
+
* Database number (0-15).
|
|
249
|
+
* @default 0
|
|
250
|
+
*/
|
|
251
|
+
db?: number;
|
|
252
|
+
/**
|
|
253
|
+
* Key prefix for all operations.
|
|
254
|
+
* @example 'myapp:'
|
|
255
|
+
*/
|
|
256
|
+
keyPrefix?: string;
|
|
257
|
+
/**
|
|
258
|
+
* Connection timeout in milliseconds.
|
|
259
|
+
* @default 10000
|
|
260
|
+
*/
|
|
261
|
+
connectTimeout?: number;
|
|
262
|
+
/**
|
|
263
|
+
* Command timeout in milliseconds.
|
|
264
|
+
* @default 5000
|
|
265
|
+
*/
|
|
266
|
+
commandTimeout?: number;
|
|
267
|
+
/**
|
|
268
|
+
* Keep-alive interval in milliseconds.
|
|
269
|
+
* @default 0 (disabled)
|
|
270
|
+
*/
|
|
271
|
+
keepAlive?: number;
|
|
272
|
+
/**
|
|
273
|
+
* Enable offline queue.
|
|
274
|
+
* @default true
|
|
275
|
+
*/
|
|
276
|
+
enableOfflineQueue?: boolean;
|
|
277
|
+
/**
|
|
278
|
+
* Enable auto-reconnect.
|
|
279
|
+
* @default true
|
|
280
|
+
*/
|
|
281
|
+
enableAutoReconnect?: boolean;
|
|
282
|
+
/**
|
|
283
|
+
* Maximum retry attempts for commands.
|
|
284
|
+
* @default 3
|
|
285
|
+
*/
|
|
286
|
+
maxRetriesPerRequest?: number;
|
|
287
|
+
/**
|
|
288
|
+
* Retry strategy function.
|
|
289
|
+
*/
|
|
290
|
+
retryStrategy?: (times: number) => number | null;
|
|
291
|
+
/**
|
|
292
|
+
* Reconnect on error function.
|
|
293
|
+
*/
|
|
294
|
+
reconnectOnError?: (error: Error) => boolean | 1 | 2;
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Single instance Redis connection configuration.
|
|
298
|
+
*/
|
|
299
|
+
interface ISingleConnectionConfig extends IBaseConnectionConfig {
|
|
300
|
+
/**
|
|
301
|
+
* Connection type discriminator.
|
|
302
|
+
*/
|
|
303
|
+
type?: 'single';
|
|
304
|
+
/**
|
|
305
|
+
* Redis host.
|
|
306
|
+
* @default 'localhost'
|
|
307
|
+
*/
|
|
308
|
+
host?: string;
|
|
309
|
+
/**
|
|
310
|
+
* Redis port.
|
|
311
|
+
* @default 6379
|
|
312
|
+
*/
|
|
313
|
+
port?: number;
|
|
314
|
+
/**
|
|
315
|
+
* Optional TLS configuration.
|
|
316
|
+
*/
|
|
317
|
+
tls?: ITlsConfig;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Redis Cluster connection configuration.
|
|
321
|
+
*/
|
|
322
|
+
interface IClusterConnectionConfig extends IBaseConnectionConfig {
|
|
323
|
+
/**
|
|
324
|
+
* Connection type discriminator.
|
|
325
|
+
*/
|
|
326
|
+
type: 'cluster';
|
|
327
|
+
/**
|
|
328
|
+
* Cluster nodes.
|
|
329
|
+
* @example [{ host: 'localhost', port: 6379 }, { host: 'localhost', port: 6380 }]
|
|
330
|
+
*/
|
|
331
|
+
nodes: Array<{
|
|
332
|
+
host: string;
|
|
333
|
+
port: number;
|
|
334
|
+
}>;
|
|
335
|
+
/**
|
|
336
|
+
* Cluster-specific options.
|
|
337
|
+
*/
|
|
338
|
+
clusterOptions?: {
|
|
339
|
+
/**
|
|
340
|
+
* Maximum number of redirections.
|
|
341
|
+
* @default 16
|
|
342
|
+
*/
|
|
343
|
+
maxRedirections?: number;
|
|
344
|
+
/**
|
|
345
|
+
* Retry delay for cluster commands.
|
|
346
|
+
* @default 100
|
|
347
|
+
*/
|
|
348
|
+
retryDelayOnClusterDown?: number;
|
|
349
|
+
/**
|
|
350
|
+
* Retry delay when all slots covered.
|
|
351
|
+
* @default 100
|
|
352
|
+
*/
|
|
353
|
+
retryDelayOnFailover?: number;
|
|
354
|
+
/**
|
|
355
|
+
* Scale reads to slaves.
|
|
356
|
+
* @default 'master'
|
|
357
|
+
*/
|
|
358
|
+
scaleReads?: 'master' | 'slave' | 'all';
|
|
359
|
+
/**
|
|
360
|
+
* Enable readonly mode for slave nodes.
|
|
361
|
+
* @default false
|
|
362
|
+
*/
|
|
363
|
+
enableReadyCheck?: boolean;
|
|
364
|
+
/**
|
|
365
|
+
* NAT mapping for Docker/firewall scenarios.
|
|
366
|
+
* Maps internal IPs to external accessible addresses.
|
|
367
|
+
* @example { '172.17.0.2:6379': { host: 'localhost', port: 6379 } }
|
|
368
|
+
*/
|
|
369
|
+
natMap?: Record<string, {
|
|
370
|
+
host: string;
|
|
371
|
+
port: number;
|
|
372
|
+
}>;
|
|
373
|
+
/**
|
|
374
|
+
* Additional ioredis cluster options.
|
|
375
|
+
* Allows passing any other ioredis ClusterOptions.
|
|
376
|
+
*/
|
|
377
|
+
[key: string]: unknown;
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Redis Sentinel connection configuration.
|
|
382
|
+
*/
|
|
383
|
+
interface ISentinelConnectionConfig extends IBaseConnectionConfig {
|
|
384
|
+
/**
|
|
385
|
+
* Connection type discriminator.
|
|
386
|
+
*/
|
|
387
|
+
type: 'sentinel';
|
|
388
|
+
/**
|
|
389
|
+
* Sentinel nodes.
|
|
390
|
+
*/
|
|
391
|
+
sentinels: Array<{
|
|
392
|
+
host: string;
|
|
393
|
+
port: number;
|
|
394
|
+
}>;
|
|
395
|
+
/**
|
|
396
|
+
* Master name.
|
|
397
|
+
*/
|
|
398
|
+
name: string;
|
|
399
|
+
/**
|
|
400
|
+
* Optional TLS configuration.
|
|
401
|
+
*/
|
|
402
|
+
tls?: ITlsConfig;
|
|
403
|
+
/**
|
|
404
|
+
* Sentinel-specific options.
|
|
405
|
+
*/
|
|
406
|
+
sentinelOptions?: {
|
|
407
|
+
/**
|
|
408
|
+
* Enable TLS for sentinel connections.
|
|
409
|
+
*/
|
|
410
|
+
enableTLSForSentinelMode?: boolean;
|
|
411
|
+
/**
|
|
412
|
+
* Sentinel password (if different from node password).
|
|
413
|
+
*/
|
|
414
|
+
sentinelPassword?: string;
|
|
415
|
+
/**
|
|
416
|
+
* Retry strategy for sentinel.
|
|
417
|
+
*/
|
|
418
|
+
sentinelRetryStrategy?: (times: number) => number | null;
|
|
419
|
+
/**
|
|
420
|
+
* Prefer slave nodes for reads.
|
|
421
|
+
* @default false
|
|
422
|
+
*/
|
|
423
|
+
preferredSlaves?: boolean;
|
|
424
|
+
/**
|
|
425
|
+
* NAT mapping for sentinel-managed instances.
|
|
426
|
+
* Maps internal master/slave addresses to external accessible addresses.
|
|
427
|
+
* @example { 'redis-master:6379': { host: 'localhost', port: 6379 } }
|
|
428
|
+
*/
|
|
429
|
+
natMap?: Record<string, {
|
|
430
|
+
host: string;
|
|
431
|
+
port: number;
|
|
432
|
+
}>;
|
|
433
|
+
/**
|
|
434
|
+
* Master connection pool size.
|
|
435
|
+
* Number of connections to maintain to the master node.
|
|
436
|
+
* @default 1
|
|
437
|
+
*/
|
|
438
|
+
masterPoolSize?: number;
|
|
439
|
+
/**
|
|
440
|
+
* Replica connection pool size per node.
|
|
441
|
+
* Set to 0 to disable replica connections.
|
|
442
|
+
* @default 0
|
|
443
|
+
*/
|
|
444
|
+
replicaPoolSize?: number;
|
|
445
|
+
/**
|
|
446
|
+
* Interval in milliseconds to scan for topology changes.
|
|
447
|
+
* @default 10000
|
|
448
|
+
*/
|
|
449
|
+
scanInterval?: number;
|
|
450
|
+
/**
|
|
451
|
+
* Maximum number of command rediscovers on topology change.
|
|
452
|
+
* @default 16
|
|
453
|
+
*/
|
|
454
|
+
maxCommandRediscovers?: number;
|
|
455
|
+
/**
|
|
456
|
+
* Additional ioredis/node-redis sentinel options.
|
|
457
|
+
*/
|
|
458
|
+
[key: string]: unknown;
|
|
459
|
+
};
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* TLS configuration.
|
|
463
|
+
*/
|
|
464
|
+
interface ITlsConfig {
|
|
465
|
+
/**
|
|
466
|
+
* Enable TLS.
|
|
467
|
+
* @default false
|
|
468
|
+
*/
|
|
469
|
+
enabled?: boolean;
|
|
470
|
+
/**
|
|
471
|
+
* CA certificate.
|
|
472
|
+
*/
|
|
473
|
+
ca?: string | Buffer;
|
|
474
|
+
/**
|
|
475
|
+
* Client certificate.
|
|
476
|
+
*/
|
|
477
|
+
cert?: string | Buffer;
|
|
478
|
+
/**
|
|
479
|
+
* Client key.
|
|
480
|
+
*/
|
|
481
|
+
key?: string | Buffer;
|
|
482
|
+
/**
|
|
483
|
+
* Reject unauthorized certificates.
|
|
484
|
+
* @default true
|
|
485
|
+
*/
|
|
486
|
+
rejectUnauthorized?: boolean;
|
|
487
|
+
}
|
|
488
|
+
/**
|
|
489
|
+
* Union type for all connection configurations.
|
|
490
|
+
*/
|
|
491
|
+
type ConnectionConfig = ISingleConnectionConfig | IClusterConnectionConfig | ISentinelConnectionConfig;
|
|
492
|
+
/**
|
|
493
|
+
* Configuration for a single Redis client.
|
|
494
|
+
*/
|
|
495
|
+
interface IRedisClientOptions {
|
|
496
|
+
/**
|
|
497
|
+
* Client name (for named clients).
|
|
498
|
+
* @default 'default'
|
|
499
|
+
*/
|
|
500
|
+
name?: string;
|
|
501
|
+
/**
|
|
502
|
+
* Connection configuration.
|
|
503
|
+
*/
|
|
504
|
+
connection: ConnectionConfig;
|
|
505
|
+
/**
|
|
506
|
+
* Namespace/prefix for this client.
|
|
507
|
+
* Overrides connection.keyPrefix.
|
|
508
|
+
*/
|
|
509
|
+
namespace?: string;
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* Driver type for Redis connections.
|
|
513
|
+
*/
|
|
514
|
+
type DriverType = 'ioredis' | 'node-redis';
|
|
515
|
+
/**
|
|
516
|
+
* Global module configuration options.
|
|
517
|
+
*/
|
|
518
|
+
interface IGlobalConfig {
|
|
519
|
+
/**
|
|
520
|
+
* Redis driver to use.
|
|
521
|
+
* @default 'ioredis'
|
|
522
|
+
*/
|
|
523
|
+
driver?: DriverType;
|
|
524
|
+
/**
|
|
525
|
+
* Enable debug logging.
|
|
526
|
+
* @default false
|
|
527
|
+
*/
|
|
528
|
+
debug?: boolean;
|
|
529
|
+
/**
|
|
530
|
+
* Default TTL for cache operations (seconds).
|
|
531
|
+
* @default 3600
|
|
532
|
+
*/
|
|
533
|
+
defaultTtl?: number;
|
|
534
|
+
/**
|
|
535
|
+
* Global key prefix for all clients.
|
|
536
|
+
*/
|
|
537
|
+
keyPrefix?: string;
|
|
538
|
+
/**
|
|
539
|
+
* Enable graceful shutdown.
|
|
540
|
+
* @default true
|
|
541
|
+
*/
|
|
542
|
+
gracefulShutdown?: boolean;
|
|
543
|
+
/**
|
|
544
|
+
* Graceful shutdown timeout (milliseconds).
|
|
545
|
+
* @default 5000
|
|
546
|
+
*/
|
|
547
|
+
gracefulShutdownTimeout?: number;
|
|
548
|
+
/**
|
|
549
|
+
* Enable health checks.
|
|
550
|
+
* @default true
|
|
551
|
+
*/
|
|
552
|
+
enableHealthChecks?: boolean;
|
|
553
|
+
/**
|
|
554
|
+
* Health check interval (milliseconds).
|
|
555
|
+
* @default 30000
|
|
556
|
+
*/
|
|
557
|
+
healthCheckInterval?: number;
|
|
558
|
+
}
|
|
559
|
+
/**
|
|
560
|
+
* Synchronous module configuration.
|
|
561
|
+
*/
|
|
562
|
+
interface IRedisModuleOptions {
|
|
563
|
+
/**
|
|
564
|
+
* Redis client configurations.
|
|
565
|
+
* Can be a single config or a map of named clients.
|
|
566
|
+
*/
|
|
567
|
+
clients: ConnectionConfig | Record<string, ConnectionConfig>;
|
|
568
|
+
/**
|
|
569
|
+
* Registered plugins.
|
|
570
|
+
*/
|
|
571
|
+
plugins?: IRedisXPlugin[];
|
|
572
|
+
/**
|
|
573
|
+
* Global configuration.
|
|
574
|
+
*/
|
|
575
|
+
global?: IGlobalConfig;
|
|
576
|
+
}
|
|
577
|
+
/**
|
|
578
|
+
* Factory function for async configuration.
|
|
579
|
+
*/
|
|
580
|
+
interface IRedisModuleOptionsFactory {
|
|
581
|
+
/**
|
|
582
|
+
* Creates module options asynchronously.
|
|
583
|
+
*/
|
|
584
|
+
createRedisModuleOptions(): Promise<IRedisModuleOptions> | IRedisModuleOptions;
|
|
585
|
+
}
|
|
586
|
+
/**
|
|
587
|
+
* Asynchronous module configuration.
|
|
588
|
+
*/
|
|
589
|
+
interface IRedisModuleAsyncOptions extends Pick<ModuleMetadata, 'imports'> {
|
|
590
|
+
/**
|
|
591
|
+
* Registered plugins.
|
|
592
|
+
* Plugins must be provided outside useFactory to ensure providers are available at module construction time.
|
|
593
|
+
* This is a standard NestJS pattern (similar to @nestjs/typeorm entities, @nestjs/graphql resolvers).
|
|
594
|
+
*/
|
|
595
|
+
plugins?: IRedisXPlugin[];
|
|
596
|
+
/**
|
|
597
|
+
* Factory function returning options.
|
|
598
|
+
*/
|
|
599
|
+
useFactory?: (...args: unknown[]) => Promise<IRedisModuleOptions> | IRedisModuleOptions;
|
|
600
|
+
/**
|
|
601
|
+
* Dependencies to inject into factory.
|
|
602
|
+
*/
|
|
603
|
+
inject?: unknown[];
|
|
604
|
+
/**
|
|
605
|
+
* Use existing provider.
|
|
606
|
+
*/
|
|
607
|
+
useExisting?: Type<IRedisModuleOptionsFactory>;
|
|
608
|
+
/**
|
|
609
|
+
* Use class provider.
|
|
610
|
+
*/
|
|
611
|
+
useClass?: Type<IRedisModuleOptionsFactory>;
|
|
612
|
+
}
|
|
613
|
+
/**
|
|
614
|
+
* Client metadata stored in the registry.
|
|
615
|
+
*/
|
|
616
|
+
interface IClientMetadata {
|
|
617
|
+
/**
|
|
618
|
+
* Client name.
|
|
619
|
+
*/
|
|
620
|
+
name: string;
|
|
621
|
+
/**
|
|
622
|
+
* Connection configuration.
|
|
623
|
+
*/
|
|
624
|
+
config: ConnectionConfig;
|
|
625
|
+
/**
|
|
626
|
+
* Connection status.
|
|
627
|
+
*/
|
|
628
|
+
status: ConnectionStatus;
|
|
629
|
+
/**
|
|
630
|
+
* Last connection time.
|
|
631
|
+
*/
|
|
632
|
+
connectedAt?: Date;
|
|
633
|
+
/**
|
|
634
|
+
* Last error.
|
|
635
|
+
*/
|
|
636
|
+
lastError?: Error;
|
|
637
|
+
/**
|
|
638
|
+
* Number of reconnection attempts.
|
|
639
|
+
*/
|
|
640
|
+
reconnectAttempts: number;
|
|
641
|
+
}
|
|
642
|
+
/**
|
|
643
|
+
* Connection status.
|
|
644
|
+
*/
|
|
645
|
+
declare enum ConnectionStatus {
|
|
646
|
+
DISCONNECTED = "disconnected",
|
|
647
|
+
CONNECTING = "connecting",
|
|
648
|
+
CONNECTED = "connected",
|
|
649
|
+
RECONNECTING = "reconnecting",
|
|
650
|
+
ERROR = "error"
|
|
651
|
+
}
|
|
652
|
+
/**
|
|
653
|
+
* Health check result.
|
|
654
|
+
*/
|
|
655
|
+
interface IHealthCheckResult {
|
|
656
|
+
/**
|
|
657
|
+
* Overall health status.
|
|
658
|
+
*/
|
|
659
|
+
status: 'healthy' | 'unhealthy' | 'degraded';
|
|
660
|
+
/**
|
|
661
|
+
* Individual client statuses.
|
|
662
|
+
*/
|
|
663
|
+
clients: Record<string, IClientHealthStatus>;
|
|
664
|
+
/**
|
|
665
|
+
* Timestamp of check.
|
|
666
|
+
*/
|
|
667
|
+
timestamp: Date;
|
|
668
|
+
}
|
|
669
|
+
/**
|
|
670
|
+
* Client health status.
|
|
671
|
+
*/
|
|
672
|
+
interface IClientHealthStatus {
|
|
673
|
+
/**
|
|
674
|
+
* Client name.
|
|
675
|
+
*/
|
|
676
|
+
name: string;
|
|
677
|
+
/**
|
|
678
|
+
* Connection status.
|
|
679
|
+
*/
|
|
680
|
+
status: ConnectionStatus;
|
|
681
|
+
/**
|
|
682
|
+
* Latency in milliseconds (ping).
|
|
683
|
+
*/
|
|
684
|
+
latency?: number;
|
|
685
|
+
/**
|
|
686
|
+
* Last error message.
|
|
687
|
+
*/
|
|
688
|
+
error?: string;
|
|
689
|
+
/**
|
|
690
|
+
* Uptime in milliseconds.
|
|
691
|
+
*/
|
|
692
|
+
uptime?: number;
|
|
693
|
+
}
|
|
694
|
+
/**
|
|
695
|
+
* Type guard for single connection config.
|
|
696
|
+
*/
|
|
697
|
+
declare function isSingleConnection(config: ConnectionConfig): config is ISingleConnectionConfig;
|
|
698
|
+
/**
|
|
699
|
+
* Type guard for cluster connection config.
|
|
700
|
+
*/
|
|
701
|
+
declare function isClusterConnection(config: ConnectionConfig): config is IClusterConnectionConfig;
|
|
702
|
+
/**
|
|
703
|
+
* Type guard for sentinel connection config.
|
|
704
|
+
*/
|
|
705
|
+
declare function isSentinelConnection(config: ConnectionConfig): config is ISentinelConnectionConfig;
|
|
706
|
+
/**
|
|
707
|
+
* Type guard for async options with factory.
|
|
708
|
+
*/
|
|
709
|
+
declare function hasFactory(options: IRedisModuleAsyncOptions): options is Required<Pick<IRedisModuleAsyncOptions, 'useFactory'>> & IRedisModuleAsyncOptions;
|
|
710
|
+
/**
|
|
711
|
+
* Type guard for async options with existing provider.
|
|
712
|
+
*/
|
|
713
|
+
declare function hasExisting(options: IRedisModuleAsyncOptions): options is Required<Pick<IRedisModuleAsyncOptions, 'useExisting'>> & IRedisModuleAsyncOptions;
|
|
714
|
+
/**
|
|
715
|
+
* Type guard for async options with class provider.
|
|
716
|
+
*/
|
|
717
|
+
declare function hasClass(options: IRedisModuleAsyncOptions): options is Required<Pick<IRedisModuleAsyncOptions, 'useClass'>> & IRedisModuleAsyncOptions;
|
|
718
|
+
|
|
719
|
+
/**
|
|
720
|
+
* Redis module for NestJS.
|
|
721
|
+
*
|
|
722
|
+
* Global module that provides Redis client(s) with driver abstraction,
|
|
723
|
+
* health monitoring, automatic reconnection, and plugin system.
|
|
724
|
+
*
|
|
725
|
+
* Module is always global - no need to import in feature modules.
|
|
726
|
+
*
|
|
727
|
+
* @example
|
|
728
|
+
* **Synchronous configuration:**
|
|
729
|
+
* ```typescript
|
|
730
|
+
* @Module({
|
|
731
|
+
* imports: [
|
|
732
|
+
* RedisModule.forRoot({
|
|
733
|
+
* clients: {
|
|
734
|
+
* type: 'single',
|
|
735
|
+
* host: 'localhost',
|
|
736
|
+
* port: 6379,
|
|
737
|
+
* },
|
|
738
|
+
* }),
|
|
739
|
+
* ],
|
|
740
|
+
* })
|
|
741
|
+
* export class AppModule {}
|
|
742
|
+
* ```
|
|
743
|
+
*
|
|
744
|
+
* @example
|
|
745
|
+
* **Asynchronous configuration with factory:**
|
|
746
|
+
* ```typescript
|
|
747
|
+
* @Module({
|
|
748
|
+
* imports: [
|
|
749
|
+
* RedisModule.forRootAsync({
|
|
750
|
+
* useFactory: (config: ConfigService) => ({
|
|
751
|
+
* clients: {
|
|
752
|
+
* type: 'single',
|
|
753
|
+
* host: config.get('REDIS_HOST'),
|
|
754
|
+
* port: config.get('REDIS_PORT'),
|
|
755
|
+
* },
|
|
756
|
+
* }),
|
|
757
|
+
* inject: [ConfigService],
|
|
758
|
+
* }),
|
|
759
|
+
* ],
|
|
760
|
+
* })
|
|
761
|
+
* export class AppModule {}
|
|
762
|
+
* ```
|
|
763
|
+
*
|
|
764
|
+
* @example
|
|
765
|
+
* **With plugins:**
|
|
766
|
+
* ```typescript
|
|
767
|
+
* @Module({
|
|
768
|
+
* imports: [
|
|
769
|
+
* RedisModule.forRoot({
|
|
770
|
+
* clients: { type: 'single', host: 'localhost', port: 6379 },
|
|
771
|
+
* plugins: [new CachePlugin(), new LocksPlugin()],
|
|
772
|
+
* }),
|
|
773
|
+
* ],
|
|
774
|
+
* })
|
|
775
|
+
* export class AppModule {}
|
|
776
|
+
* ```
|
|
777
|
+
*/
|
|
778
|
+
declare class RedisModule {
|
|
779
|
+
/**
|
|
780
|
+
* Configures Redis module synchronously.
|
|
781
|
+
*
|
|
782
|
+
* Creates a global module with Redis clients and plugins.
|
|
783
|
+
* All providers are available for injection everywhere.
|
|
784
|
+
*
|
|
785
|
+
* @param options - Redis module options
|
|
786
|
+
* @returns Dynamic module
|
|
787
|
+
*
|
|
788
|
+
* @example
|
|
789
|
+
* ```typescript
|
|
790
|
+
* RedisModule.forRoot({
|
|
791
|
+
* clients: {
|
|
792
|
+
* type: 'single',
|
|
793
|
+
* host: 'localhost',
|
|
794
|
+
* port: 6379,
|
|
795
|
+
* },
|
|
796
|
+
* plugins: [new CachePlugin(), new LocksPlugin()],
|
|
797
|
+
* })
|
|
798
|
+
* ```
|
|
799
|
+
*/
|
|
800
|
+
static forRoot(options: IRedisModuleOptions): DynamicModule;
|
|
801
|
+
/**
|
|
802
|
+
* Configures Redis module asynchronously.
|
|
803
|
+
*
|
|
804
|
+
* Allows configuration to be loaded asynchronously using factory function,
|
|
805
|
+
* existing provider, or class-based factory. Supports plugins.
|
|
806
|
+
*
|
|
807
|
+
* Note: Plugins must be provided in the async options (outside useFactory),
|
|
808
|
+
* not in the factory result. This is a standard NestJS pattern — plugins
|
|
809
|
+
* must be available at module construction time for NestJS DI.
|
|
810
|
+
*
|
|
811
|
+
* @param options - Async Redis module options
|
|
812
|
+
* @returns Dynamic module
|
|
813
|
+
*
|
|
814
|
+
* @example
|
|
815
|
+
* **Using factory with plugins:**
|
|
816
|
+
* ```typescript
|
|
817
|
+
* RedisModule.forRootAsync({
|
|
818
|
+
* plugins: [new CachePlugin(), new LocksPlugin()],
|
|
819
|
+
* useFactory: (config: ConfigService) => ({
|
|
820
|
+
* clients: {
|
|
821
|
+
* type: 'single',
|
|
822
|
+
* host: config.get('REDIS_HOST'),
|
|
823
|
+
* port: config.get('REDIS_PORT'),
|
|
824
|
+
* },
|
|
825
|
+
* }),
|
|
826
|
+
* inject: [ConfigService],
|
|
827
|
+
* })
|
|
828
|
+
* ```
|
|
829
|
+
*
|
|
830
|
+
* @example
|
|
831
|
+
* **Using class:**
|
|
832
|
+
* ```typescript
|
|
833
|
+
* @Injectable()
|
|
834
|
+
* class RedisConfigService implements IRedisModuleOptionsFactory {
|
|
835
|
+
* createRedisModuleOptions(): IRedisModuleOptions {
|
|
836
|
+
* return {
|
|
837
|
+
* clients: { type: 'single', host: 'localhost', port: 6379 },
|
|
838
|
+
* };
|
|
839
|
+
* }
|
|
840
|
+
* }
|
|
841
|
+
*
|
|
842
|
+
* RedisModule.forRootAsync({
|
|
843
|
+
* plugins: [new CachePlugin()],
|
|
844
|
+
* useClass: RedisConfigService,
|
|
845
|
+
* })
|
|
846
|
+
* ```
|
|
847
|
+
*/
|
|
848
|
+
static forRootAsync(options: IRedisModuleAsyncOptions): DynamicModule;
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
/**
|
|
852
|
+
* Redis driver abstraction interface.
|
|
853
|
+
*
|
|
854
|
+
* Complete interface for all Redis operations.
|
|
855
|
+
* All Redis operations MUST go through this interface.
|
|
856
|
+
* NEVER import ioredis or redis directly.
|
|
857
|
+
*
|
|
858
|
+
* @example
|
|
859
|
+
* ```typescript
|
|
860
|
+
* @Injectable()
|
|
861
|
+
* export class CacheService {
|
|
862
|
+
* constructor(
|
|
863
|
+
* @Inject(REDIS_DRIVER) private readonly driver: IRedisDriver
|
|
864
|
+
* ) {}
|
|
865
|
+
* }
|
|
866
|
+
* ```
|
|
867
|
+
*/
|
|
868
|
+
interface IRedisDriver {
|
|
869
|
+
/**
|
|
870
|
+
* Connects to Redis.
|
|
871
|
+
* Called automatically by ClientManager.
|
|
872
|
+
*/
|
|
873
|
+
connect(): Promise<void>;
|
|
874
|
+
/**
|
|
875
|
+
* Disconnects from Redis gracefully.
|
|
876
|
+
* Called automatically on module destroy.
|
|
877
|
+
*/
|
|
878
|
+
disconnect(): Promise<void>;
|
|
879
|
+
/**
|
|
880
|
+
* Checks if connected to Redis.
|
|
881
|
+
*/
|
|
882
|
+
isConnected(): boolean;
|
|
883
|
+
/**
|
|
884
|
+
* Pings Redis server.
|
|
885
|
+
* @returns 'PONG' or custom message
|
|
886
|
+
*/
|
|
887
|
+
ping(message?: string): Promise<string>;
|
|
888
|
+
/**
|
|
889
|
+
* Selects database.
|
|
890
|
+
* @param db - Database number (0-15)
|
|
891
|
+
*/
|
|
892
|
+
select(db: number): Promise<void>;
|
|
893
|
+
/**
|
|
894
|
+
* Gets value of a key.
|
|
895
|
+
* @returns Value or null if key doesn't exist
|
|
896
|
+
*/
|
|
897
|
+
get(key: string): Promise<string | null>;
|
|
898
|
+
/**
|
|
899
|
+
* Sets value of a key with optional TTL.
|
|
900
|
+
* @returns 'OK' if successful, null otherwise
|
|
901
|
+
*/
|
|
902
|
+
set(key: string, value: string, options?: ISetOptions): Promise<'OK' | null>;
|
|
903
|
+
/**
|
|
904
|
+
* Gets multiple values.
|
|
905
|
+
* @returns Array of values (null for non-existent keys)
|
|
906
|
+
*/
|
|
907
|
+
mget(...keys: string[]): Promise<Array<string | null>>;
|
|
908
|
+
/**
|
|
909
|
+
* Sets multiple key-value pairs.
|
|
910
|
+
* @returns 'OK' if successful
|
|
911
|
+
*/
|
|
912
|
+
mset(data: Record<string, string>): Promise<'OK'>;
|
|
913
|
+
/**
|
|
914
|
+
* Sets value only if key doesn't exist.
|
|
915
|
+
* @returns 1 if set, 0 if not set
|
|
916
|
+
*/
|
|
917
|
+
setnx(key: string, value: string): Promise<number>;
|
|
918
|
+
/**
|
|
919
|
+
* Sets value with expiration in seconds.
|
|
920
|
+
* @returns 'OK' if successful
|
|
921
|
+
*/
|
|
922
|
+
setex(key: string, seconds: number, value: string): Promise<'OK'>;
|
|
923
|
+
/**
|
|
924
|
+
* Gets value and deletes key atomically.
|
|
925
|
+
* @returns Value or null if key doesn't exist
|
|
926
|
+
*/
|
|
927
|
+
getdel(key: string): Promise<string | null>;
|
|
928
|
+
/**
|
|
929
|
+
* Gets value and sets expiration atomically.
|
|
930
|
+
* @returns Value or null if key doesn't exist
|
|
931
|
+
*/
|
|
932
|
+
getex(key: string, options: {
|
|
933
|
+
ex?: number;
|
|
934
|
+
px?: number;
|
|
935
|
+
}): Promise<string | null>;
|
|
936
|
+
/**
|
|
937
|
+
* Increments integer value by 1.
|
|
938
|
+
* @returns New value after increment
|
|
939
|
+
*/
|
|
940
|
+
incr(key: string): Promise<number>;
|
|
941
|
+
/**
|
|
942
|
+
* Increments integer value by amount.
|
|
943
|
+
* @returns New value after increment
|
|
944
|
+
*/
|
|
945
|
+
incrby(key: string, increment: number): Promise<number>;
|
|
946
|
+
/**
|
|
947
|
+
* Decrements integer value by 1.
|
|
948
|
+
* @returns New value after decrement
|
|
949
|
+
*/
|
|
950
|
+
decr(key: string): Promise<number>;
|
|
951
|
+
/**
|
|
952
|
+
* Decrements integer value by amount.
|
|
953
|
+
* @returns New value after decrement
|
|
954
|
+
*/
|
|
955
|
+
decrby(key: string, decrement: number): Promise<number>;
|
|
956
|
+
/**
|
|
957
|
+
* Appends value to key.
|
|
958
|
+
* @returns Length of string after append
|
|
959
|
+
*/
|
|
960
|
+
append(key: string, value: string): Promise<number>;
|
|
961
|
+
/**
|
|
962
|
+
* Gets length of string value.
|
|
963
|
+
* @returns Length of string, 0 if key doesn't exist
|
|
964
|
+
*/
|
|
965
|
+
strlen(key: string): Promise<number>;
|
|
966
|
+
/**
|
|
967
|
+
* Increments value by float amount.
|
|
968
|
+
* @returns New value after increment
|
|
969
|
+
*/
|
|
970
|
+
incrbyfloat(key: string, increment: number): Promise<string>;
|
|
971
|
+
/**
|
|
972
|
+
* Gets substring of string value.
|
|
973
|
+
* @param start - Start offset (can be negative)
|
|
974
|
+
* @param end - End offset (can be negative)
|
|
975
|
+
* @returns Substring
|
|
976
|
+
*/
|
|
977
|
+
getrange(key: string, start: number, end: number): Promise<string>;
|
|
978
|
+
/**
|
|
979
|
+
* Overwrites part of string at offset.
|
|
980
|
+
* @returns Length of string after modification
|
|
981
|
+
*/
|
|
982
|
+
setrange(key: string, offset: number, value: string): Promise<number>;
|
|
983
|
+
/**
|
|
984
|
+
* Sets multiple keys only if none exist.
|
|
985
|
+
* @returns 1 if all keys set, 0 if no keys set
|
|
986
|
+
*/
|
|
987
|
+
msetnx(data: Record<string, string>): Promise<number>;
|
|
988
|
+
/**
|
|
989
|
+
* Deletes one or more keys.
|
|
990
|
+
* @returns Number of keys deleted
|
|
991
|
+
*/
|
|
992
|
+
del(...keys: string[]): Promise<number>;
|
|
993
|
+
/**
|
|
994
|
+
* Checks if key exists.
|
|
995
|
+
* @returns Number of existing keys
|
|
996
|
+
*/
|
|
997
|
+
exists(...keys: string[]): Promise<number>;
|
|
998
|
+
/**
|
|
999
|
+
* Sets TTL on a key (seconds).
|
|
1000
|
+
* @returns 1 if timeout was set, 0 if key doesn't exist
|
|
1001
|
+
*/
|
|
1002
|
+
expire(key: string, seconds: number): Promise<number>;
|
|
1003
|
+
/**
|
|
1004
|
+
* Sets TTL on a key (milliseconds).
|
|
1005
|
+
* @returns 1 if timeout was set, 0 if key doesn't exist
|
|
1006
|
+
*/
|
|
1007
|
+
pexpire(key: string, milliseconds: number): Promise<number>;
|
|
1008
|
+
/**
|
|
1009
|
+
* Sets absolute expiration time (Unix timestamp in seconds).
|
|
1010
|
+
* @returns 1 if timeout was set, 0 if key doesn't exist
|
|
1011
|
+
*/
|
|
1012
|
+
expireat(key: string, timestamp: number): Promise<number>;
|
|
1013
|
+
/**
|
|
1014
|
+
* Gets TTL of a key (seconds).
|
|
1015
|
+
* @returns TTL in seconds, -1 if no TTL, -2 if key doesn't exist
|
|
1016
|
+
*/
|
|
1017
|
+
ttl(key: string): Promise<number>;
|
|
1018
|
+
/**
|
|
1019
|
+
* Gets TTL of a key (milliseconds).
|
|
1020
|
+
* @returns TTL in milliseconds, -1 if no TTL, -2 if key doesn't exist
|
|
1021
|
+
*/
|
|
1022
|
+
pttl(key: string): Promise<number>;
|
|
1023
|
+
/**
|
|
1024
|
+
* Removes expiration from key.
|
|
1025
|
+
* @returns 1 if expiration removed, 0 if key has no expiration
|
|
1026
|
+
*/
|
|
1027
|
+
persist(key: string): Promise<number>;
|
|
1028
|
+
/**
|
|
1029
|
+
* Renames key.
|
|
1030
|
+
* @returns 'OK' if successful
|
|
1031
|
+
* @throws Error if source key doesn't exist
|
|
1032
|
+
*/
|
|
1033
|
+
rename(key: string, newKey: string): Promise<'OK'>;
|
|
1034
|
+
/**
|
|
1035
|
+
* Renames key only if new key doesn't exist.
|
|
1036
|
+
* @returns 1 if renamed, 0 if new key exists
|
|
1037
|
+
*/
|
|
1038
|
+
renamenx(key: string, newKey: string): Promise<number>;
|
|
1039
|
+
/**
|
|
1040
|
+
* Gets type of value stored at key.
|
|
1041
|
+
* @returns Type name: 'string', 'list', 'set', 'zset', 'hash', 'stream', 'none'
|
|
1042
|
+
*/
|
|
1043
|
+
type(key: string): Promise<string>;
|
|
1044
|
+
/**
|
|
1045
|
+
* Scans keys matching pattern.
|
|
1046
|
+
* @returns Cursor and array of keys
|
|
1047
|
+
*/
|
|
1048
|
+
scan(cursor: number, options?: IScanOptions): Promise<[string, string[]]>;
|
|
1049
|
+
/**
|
|
1050
|
+
* Deletes keys asynchronously (non-blocking).
|
|
1051
|
+
* Better for large keys than del.
|
|
1052
|
+
* @returns Number of keys unlinked
|
|
1053
|
+
*/
|
|
1054
|
+
unlink(...keys: string[]): Promise<number>;
|
|
1055
|
+
/**
|
|
1056
|
+
* Copies key to another key.
|
|
1057
|
+
* @param destination - Destination key
|
|
1058
|
+
* @param options - Copy options (replace, db)
|
|
1059
|
+
* @returns 1 if copied, 0 if not
|
|
1060
|
+
*/
|
|
1061
|
+
copy(source: string, destination: string, options?: ICopyOptions): Promise<number>;
|
|
1062
|
+
/**
|
|
1063
|
+
* Finds all keys matching pattern.
|
|
1064
|
+
* WARNING: Use SCAN in production for large keyspaces.
|
|
1065
|
+
* @returns Array of matching keys
|
|
1066
|
+
*/
|
|
1067
|
+
keys(pattern: string): Promise<string[]>;
|
|
1068
|
+
/**
|
|
1069
|
+
* Alters the last access time of keys.
|
|
1070
|
+
* @returns Number of keys touched
|
|
1071
|
+
*/
|
|
1072
|
+
touch(...keys: string[]): Promise<number>;
|
|
1073
|
+
/**
|
|
1074
|
+
* Returns the internal encoding of a Redis object.
|
|
1075
|
+
* @param subcommand - ENCODING, FREQ, IDLETIME, REFCOUNT
|
|
1076
|
+
* @returns Object info
|
|
1077
|
+
*/
|
|
1078
|
+
object(subcommand: 'ENCODING' | 'FREQ' | 'IDLETIME' | 'REFCOUNT', key: string): Promise<string | number | null>;
|
|
1079
|
+
/**
|
|
1080
|
+
* Serializes the value at key.
|
|
1081
|
+
* @returns Serialized value or null
|
|
1082
|
+
*/
|
|
1083
|
+
dump(key: string): Promise<string | null>;
|
|
1084
|
+
/**
|
|
1085
|
+
* Deserializes and stores value at key.
|
|
1086
|
+
* @param ttl - TTL in milliseconds (0 = no expiry)
|
|
1087
|
+
* @param serializedValue - Serialized value from dump
|
|
1088
|
+
* @param options - Restore options
|
|
1089
|
+
* @returns 'OK' if successful
|
|
1090
|
+
*/
|
|
1091
|
+
restore(key: string, ttl: number, serializedValue: string, options?: IRestoreOptions): Promise<'OK'>;
|
|
1092
|
+
/**
|
|
1093
|
+
* Returns server time.
|
|
1094
|
+
* @returns [unix timestamp in seconds, microseconds]
|
|
1095
|
+
*/
|
|
1096
|
+
time(): Promise<[string, string]>;
|
|
1097
|
+
/**
|
|
1098
|
+
* Gets value of hash field.
|
|
1099
|
+
* @returns Value or null if field doesn't exist
|
|
1100
|
+
*/
|
|
1101
|
+
hget(key: string, field: string): Promise<string | null>;
|
|
1102
|
+
/**
|
|
1103
|
+
* Sets value of hash field.
|
|
1104
|
+
* @returns 1 if new field, 0 if field updated
|
|
1105
|
+
*/
|
|
1106
|
+
hset(key: string, field: string, value: string): Promise<number>;
|
|
1107
|
+
/**
|
|
1108
|
+
* Sets multiple hash fields.
|
|
1109
|
+
* @returns 'OK' if successful
|
|
1110
|
+
*/
|
|
1111
|
+
hmset(key: string, data: Record<string, string>): Promise<'OK'>;
|
|
1112
|
+
/**
|
|
1113
|
+
* Gets multiple hash field values.
|
|
1114
|
+
* @returns Array of values (null for non-existent fields)
|
|
1115
|
+
*/
|
|
1116
|
+
hmget(key: string, ...fields: string[]): Promise<Array<string | null>>;
|
|
1117
|
+
/**
|
|
1118
|
+
* Gets all fields and values of hash.
|
|
1119
|
+
* @returns Object with field-value pairs
|
|
1120
|
+
*/
|
|
1121
|
+
hgetall(key: string): Promise<Record<string, string>>;
|
|
1122
|
+
/**
|
|
1123
|
+
* Deletes hash fields.
|
|
1124
|
+
* @returns Number of fields deleted
|
|
1125
|
+
*/
|
|
1126
|
+
hdel(key: string, ...fields: string[]): Promise<number>;
|
|
1127
|
+
/**
|
|
1128
|
+
* Checks if hash field exists.
|
|
1129
|
+
* @returns 1 if field exists, 0 otherwise
|
|
1130
|
+
*/
|
|
1131
|
+
hexists(key: string, field: string): Promise<number>;
|
|
1132
|
+
/**
|
|
1133
|
+
* Gets all field names in hash.
|
|
1134
|
+
*/
|
|
1135
|
+
hkeys(key: string): Promise<string[]>;
|
|
1136
|
+
/**
|
|
1137
|
+
* Gets all values in hash.
|
|
1138
|
+
*/
|
|
1139
|
+
hvals(key: string): Promise<string[]>;
|
|
1140
|
+
/**
|
|
1141
|
+
* Gets number of fields in hash.
|
|
1142
|
+
*/
|
|
1143
|
+
hlen(key: string): Promise<number>;
|
|
1144
|
+
/**
|
|
1145
|
+
* Increments hash field by integer.
|
|
1146
|
+
* @returns New value after increment
|
|
1147
|
+
*/
|
|
1148
|
+
hincrby(key: string, field: string, increment: number): Promise<number>;
|
|
1149
|
+
/**
|
|
1150
|
+
* Scans hash fields.
|
|
1151
|
+
* @returns Cursor and array of field-value pairs
|
|
1152
|
+
*/
|
|
1153
|
+
hscan(key: string, cursor: number, options?: IScanOptions): Promise<[string, string[]]>;
|
|
1154
|
+
/**
|
|
1155
|
+
* Sets hash field only if it doesn't exist.
|
|
1156
|
+
* @returns 1 if field set, 0 if field exists
|
|
1157
|
+
*/
|
|
1158
|
+
hsetnx(key: string, field: string, value: string): Promise<number>;
|
|
1159
|
+
/**
|
|
1160
|
+
* Increments hash field by float.
|
|
1161
|
+
* @returns New value as string
|
|
1162
|
+
*/
|
|
1163
|
+
hincrbyfloat(key: string, field: string, increment: number): Promise<string>;
|
|
1164
|
+
/**
|
|
1165
|
+
* Gets string length of hash field value.
|
|
1166
|
+
* @returns Length of field value, 0 if field/key doesn't exist
|
|
1167
|
+
*/
|
|
1168
|
+
hstrlen(key: string, field: string): Promise<number>;
|
|
1169
|
+
/**
|
|
1170
|
+
* Gets random fields from hash.
|
|
1171
|
+
* @param count - Number of fields (negative for duplicates allowed)
|
|
1172
|
+
* @param withValues - Include values
|
|
1173
|
+
* @returns Random field(s) or field-value pairs
|
|
1174
|
+
*/
|
|
1175
|
+
hrandfield(key: string, count?: number, withValues?: boolean): Promise<string | string[] | null>;
|
|
1176
|
+
/**
|
|
1177
|
+
* Pushes values to left of list.
|
|
1178
|
+
* @returns Length of list after push
|
|
1179
|
+
*/
|
|
1180
|
+
lpush(key: string, ...values: string[]): Promise<number>;
|
|
1181
|
+
/**
|
|
1182
|
+
* Pushes values to right of list.
|
|
1183
|
+
* @returns Length of list after push
|
|
1184
|
+
*/
|
|
1185
|
+
rpush(key: string, ...values: string[]): Promise<number>;
|
|
1186
|
+
/**
|
|
1187
|
+
* Pops value from left of list.
|
|
1188
|
+
* @returns Value or null if list is empty
|
|
1189
|
+
*/
|
|
1190
|
+
lpop(key: string): Promise<string | null>;
|
|
1191
|
+
/**
|
|
1192
|
+
* Pops value from right of list.
|
|
1193
|
+
* @returns Value or null if list is empty
|
|
1194
|
+
*/
|
|
1195
|
+
rpop(key: string): Promise<string | null>;
|
|
1196
|
+
/**
|
|
1197
|
+
* Gets list length.
|
|
1198
|
+
* @returns Number of elements
|
|
1199
|
+
*/
|
|
1200
|
+
llen(key: string): Promise<number>;
|
|
1201
|
+
/**
|
|
1202
|
+
* Gets list range.
|
|
1203
|
+
* @returns Array of values
|
|
1204
|
+
*/
|
|
1205
|
+
lrange(key: string, start: number, stop: number): Promise<string[]>;
|
|
1206
|
+
/**
|
|
1207
|
+
* Trims list to specified range.
|
|
1208
|
+
* @returns 'OK' if successful
|
|
1209
|
+
*/
|
|
1210
|
+
ltrim(key: string, start: number, stop: number): Promise<'OK'>;
|
|
1211
|
+
/**
|
|
1212
|
+
* Gets element at index.
|
|
1213
|
+
* @returns Value or null if index out of range
|
|
1214
|
+
*/
|
|
1215
|
+
lindex(key: string, index: number): Promise<string | null>;
|
|
1216
|
+
/**
|
|
1217
|
+
* Sets element at index.
|
|
1218
|
+
* @returns 'OK' if successful
|
|
1219
|
+
*/
|
|
1220
|
+
lset(key: string, index: number, value: string): Promise<'OK'>;
|
|
1221
|
+
/**
|
|
1222
|
+
* Inserts element before or after pivot.
|
|
1223
|
+
* @param position - BEFORE or AFTER
|
|
1224
|
+
* @param pivot - Reference element
|
|
1225
|
+
* @param element - Element to insert
|
|
1226
|
+
* @returns List length, -1 if pivot not found
|
|
1227
|
+
*/
|
|
1228
|
+
linsert(key: string, position: 'BEFORE' | 'AFTER', pivot: string, element: string): Promise<number>;
|
|
1229
|
+
/**
|
|
1230
|
+
* Removes elements from list.
|
|
1231
|
+
* @param count - Number to remove (0=all, positive=head, negative=tail)
|
|
1232
|
+
* @param element - Element to remove
|
|
1233
|
+
* @returns Number of removed elements
|
|
1234
|
+
*/
|
|
1235
|
+
lrem(key: string, count: number, element: string): Promise<number>;
|
|
1236
|
+
/**
|
|
1237
|
+
* Gets index of element in list.
|
|
1238
|
+
* @param options - RANK, COUNT, MAXLEN options
|
|
1239
|
+
* @returns Index or null if not found
|
|
1240
|
+
*/
|
|
1241
|
+
lpos(key: string, element: string, options?: ILposOptions): Promise<number | number[] | null>;
|
|
1242
|
+
/**
|
|
1243
|
+
* Blocking left pop from list.
|
|
1244
|
+
* @param timeout - Timeout in seconds (0 = block forever)
|
|
1245
|
+
* @returns [key, element] or null on timeout
|
|
1246
|
+
*/
|
|
1247
|
+
blpop(keys: string[], timeout: number): Promise<[string, string] | null>;
|
|
1248
|
+
/**
|
|
1249
|
+
* Blocking right pop from list.
|
|
1250
|
+
* @param timeout - Timeout in seconds (0 = block forever)
|
|
1251
|
+
* @returns [key, element] or null on timeout
|
|
1252
|
+
*/
|
|
1253
|
+
brpop(keys: string[], timeout: number): Promise<[string, string] | null>;
|
|
1254
|
+
/**
|
|
1255
|
+
* Atomically moves element between lists.
|
|
1256
|
+
* @param source - Source list key
|
|
1257
|
+
* @param destination - Destination list key
|
|
1258
|
+
* @param from - LEFT or RIGHT
|
|
1259
|
+
* @param to - LEFT or RIGHT
|
|
1260
|
+
* @returns Moved element or null
|
|
1261
|
+
*/
|
|
1262
|
+
lmove(source: string, destination: string, from: 'LEFT' | 'RIGHT', to: 'LEFT' | 'RIGHT'): Promise<string | null>;
|
|
1263
|
+
/**
|
|
1264
|
+
* Blocking version of lmove.
|
|
1265
|
+
* @param timeout - Timeout in seconds
|
|
1266
|
+
* @returns Moved element or null on timeout
|
|
1267
|
+
*/
|
|
1268
|
+
blmove(source: string, destination: string, from: 'LEFT' | 'RIGHT', to: 'LEFT' | 'RIGHT', timeout: number): Promise<string | null>;
|
|
1269
|
+
/**
|
|
1270
|
+
* Adds members to set.
|
|
1271
|
+
* @returns Number of members added
|
|
1272
|
+
*/
|
|
1273
|
+
sadd(key: string, ...members: string[]): Promise<number>;
|
|
1274
|
+
/**
|
|
1275
|
+
* Removes members from set.
|
|
1276
|
+
* @returns Number of members removed
|
|
1277
|
+
*/
|
|
1278
|
+
srem(key: string, ...members: string[]): Promise<number>;
|
|
1279
|
+
/**
|
|
1280
|
+
* Gets all members of set.
|
|
1281
|
+
*/
|
|
1282
|
+
smembers(key: string): Promise<string[]>;
|
|
1283
|
+
/**
|
|
1284
|
+
* Checks if member is in set.
|
|
1285
|
+
* @returns 1 if member exists, 0 otherwise
|
|
1286
|
+
*/
|
|
1287
|
+
sismember(key: string, member: string): Promise<number>;
|
|
1288
|
+
/**
|
|
1289
|
+
* Gets number of members in set.
|
|
1290
|
+
*/
|
|
1291
|
+
scard(key: string): Promise<number>;
|
|
1292
|
+
/**
|
|
1293
|
+
* Gets random member from set.
|
|
1294
|
+
* @returns Random member or null if set is empty
|
|
1295
|
+
*/
|
|
1296
|
+
srandmember(key: string, count?: number): Promise<string | string[] | null>;
|
|
1297
|
+
/**
|
|
1298
|
+
* Pops random member from set.
|
|
1299
|
+
* @returns Random member or null if set is empty
|
|
1300
|
+
*/
|
|
1301
|
+
spop(key: string, count?: number): Promise<string | string[] | null>;
|
|
1302
|
+
/**
|
|
1303
|
+
* Scans set members.
|
|
1304
|
+
* @returns Cursor and array of members
|
|
1305
|
+
*/
|
|
1306
|
+
sscan(key: string, cursor: number, options?: IScanOptions): Promise<[string, string[]]>;
|
|
1307
|
+
/**
|
|
1308
|
+
* Moves member from one set to another.
|
|
1309
|
+
* @returns 1 if moved, 0 if member not in source
|
|
1310
|
+
*/
|
|
1311
|
+
smove(source: string, destination: string, member: string): Promise<number>;
|
|
1312
|
+
/**
|
|
1313
|
+
* Returns intersection of sets.
|
|
1314
|
+
* @returns Array of common members
|
|
1315
|
+
*/
|
|
1316
|
+
sinter(...keys: string[]): Promise<string[]>;
|
|
1317
|
+
/**
|
|
1318
|
+
* Stores intersection of sets.
|
|
1319
|
+
* @returns Number of members in result
|
|
1320
|
+
*/
|
|
1321
|
+
sinterstore(destination: string, ...keys: string[]): Promise<number>;
|
|
1322
|
+
/**
|
|
1323
|
+
* Returns union of sets.
|
|
1324
|
+
* @returns Array of all unique members
|
|
1325
|
+
*/
|
|
1326
|
+
sunion(...keys: string[]): Promise<string[]>;
|
|
1327
|
+
/**
|
|
1328
|
+
* Stores union of sets.
|
|
1329
|
+
* @returns Number of members in result
|
|
1330
|
+
*/
|
|
1331
|
+
sunionstore(destination: string, ...keys: string[]): Promise<number>;
|
|
1332
|
+
/**
|
|
1333
|
+
* Returns difference of sets (first - others).
|
|
1334
|
+
* @returns Array of members in first set but not in others
|
|
1335
|
+
*/
|
|
1336
|
+
sdiff(...keys: string[]): Promise<string[]>;
|
|
1337
|
+
/**
|
|
1338
|
+
* Stores difference of sets.
|
|
1339
|
+
* @returns Number of members in result
|
|
1340
|
+
*/
|
|
1341
|
+
sdiffstore(destination: string, ...keys: string[]): Promise<number>;
|
|
1342
|
+
/**
|
|
1343
|
+
* Checks if multiple members are in set.
|
|
1344
|
+
* @returns Array of 1/0 for each member
|
|
1345
|
+
*/
|
|
1346
|
+
smismember(key: string, ...members: string[]): Promise<number[]>;
|
|
1347
|
+
/**
|
|
1348
|
+
* Adds members to sorted set with scores.
|
|
1349
|
+
* @returns Number of members added
|
|
1350
|
+
*/
|
|
1351
|
+
zadd(key: string, ...args: Array<number | string>): Promise<number>;
|
|
1352
|
+
/**
|
|
1353
|
+
* Removes members from sorted set.
|
|
1354
|
+
* @returns Number of members removed
|
|
1355
|
+
*/
|
|
1356
|
+
zrem(key: string, ...members: string[]): Promise<number>;
|
|
1357
|
+
/**
|
|
1358
|
+
* Gets members in range by index.
|
|
1359
|
+
*/
|
|
1360
|
+
zrange(key: string, start: number, stop: number, withScores?: boolean): Promise<string[]>;
|
|
1361
|
+
/**
|
|
1362
|
+
* Gets members in range by score.
|
|
1363
|
+
*/
|
|
1364
|
+
zrangebyscore(key: string, min: number | string, max: number | string, withScores?: boolean): Promise<string[]>;
|
|
1365
|
+
/**
|
|
1366
|
+
* Gets score of member.
|
|
1367
|
+
* @returns Score or null if member doesn't exist
|
|
1368
|
+
*/
|
|
1369
|
+
zscore(key: string, member: string): Promise<string | null>;
|
|
1370
|
+
/**
|
|
1371
|
+
* Gets number of members in sorted set.
|
|
1372
|
+
*/
|
|
1373
|
+
zcard(key: string): Promise<number>;
|
|
1374
|
+
/**
|
|
1375
|
+
* Gets rank of member (0-based, lowest score first).
|
|
1376
|
+
* @returns Rank or null if member doesn't exist
|
|
1377
|
+
*/
|
|
1378
|
+
zrank(key: string, member: string): Promise<number | null>;
|
|
1379
|
+
/**
|
|
1380
|
+
* Increments score of member.
|
|
1381
|
+
* @returns New score
|
|
1382
|
+
*/
|
|
1383
|
+
zincrby(key: string, increment: number, member: string): Promise<string>;
|
|
1384
|
+
/**
|
|
1385
|
+
* Scans sorted set members.
|
|
1386
|
+
* @returns Cursor and array of member-score pairs
|
|
1387
|
+
*/
|
|
1388
|
+
zscan(key: string, cursor: number, options?: IScanOptions): Promise<[string, string[]]>;
|
|
1389
|
+
/**
|
|
1390
|
+
* Gets reverse rank of member (highest score first).
|
|
1391
|
+
* @returns Rank or null if member doesn't exist
|
|
1392
|
+
*/
|
|
1393
|
+
zrevrank(key: string, member: string): Promise<number | null>;
|
|
1394
|
+
/**
|
|
1395
|
+
* Counts members with scores in range.
|
|
1396
|
+
* @returns Number of members
|
|
1397
|
+
*/
|
|
1398
|
+
zcount(key: string, min: number | string, max: number | string): Promise<number>;
|
|
1399
|
+
/**
|
|
1400
|
+
* Counts members in lexicographical range.
|
|
1401
|
+
* @returns Number of members
|
|
1402
|
+
*/
|
|
1403
|
+
zlexcount(key: string, min: string, max: string): Promise<number>;
|
|
1404
|
+
/**
|
|
1405
|
+
* Removes and returns members with lowest scores.
|
|
1406
|
+
* @returns Array of [member, score] pairs
|
|
1407
|
+
*/
|
|
1408
|
+
zpopmin(key: string, count?: number): Promise<string[]>;
|
|
1409
|
+
/**
|
|
1410
|
+
* Removes and returns members with highest scores.
|
|
1411
|
+
* @returns Array of [member, score] pairs
|
|
1412
|
+
*/
|
|
1413
|
+
zpopmax(key: string, count?: number): Promise<string[]>;
|
|
1414
|
+
/**
|
|
1415
|
+
* Blocking pop from sorted set (lowest score).
|
|
1416
|
+
* @param timeout - Timeout in seconds
|
|
1417
|
+
* @returns [key, member, score] or null on timeout
|
|
1418
|
+
*/
|
|
1419
|
+
bzpopmin(keys: string[], timeout: number): Promise<[string, string, string] | null>;
|
|
1420
|
+
/**
|
|
1421
|
+
* Blocking pop from sorted set (highest score).
|
|
1422
|
+
* @param timeout - Timeout in seconds
|
|
1423
|
+
* @returns [key, member, score] or null on timeout
|
|
1424
|
+
*/
|
|
1425
|
+
bzpopmax(keys: string[], timeout: number): Promise<[string, string, string] | null>;
|
|
1426
|
+
/**
|
|
1427
|
+
* Computes union of sorted sets and stores result.
|
|
1428
|
+
* @param destination - Destination key
|
|
1429
|
+
* @param keys - Source keys
|
|
1430
|
+
* @param options - WEIGHTS and AGGREGATE options
|
|
1431
|
+
* @returns Number of elements in result
|
|
1432
|
+
*/
|
|
1433
|
+
zunionstore(destination: string, keys: string[], options?: IZStoreOptions): Promise<number>;
|
|
1434
|
+
/**
|
|
1435
|
+
* Computes intersection of sorted sets and stores result.
|
|
1436
|
+
* @param destination - Destination key
|
|
1437
|
+
* @param keys - Source keys
|
|
1438
|
+
* @param options - WEIGHTS and AGGREGATE options
|
|
1439
|
+
* @returns Number of elements in result
|
|
1440
|
+
*/
|
|
1441
|
+
zinterstore(destination: string, keys: string[], options?: IZStoreOptions): Promise<number>;
|
|
1442
|
+
/**
|
|
1443
|
+
* Gets scores of multiple members.
|
|
1444
|
+
* @returns Array of scores (null for non-existent members)
|
|
1445
|
+
*/
|
|
1446
|
+
zmscore(key: string, ...members: string[]): Promise<Array<string | null>>;
|
|
1447
|
+
/**
|
|
1448
|
+
* Gets random members from sorted set.
|
|
1449
|
+
* @param count - Number of members (negative for duplicates allowed)
|
|
1450
|
+
* @param withScores - Include scores
|
|
1451
|
+
* @returns Random member(s) or member-score pairs
|
|
1452
|
+
*/
|
|
1453
|
+
zrandmember(key: string, count?: number, withScores?: boolean): Promise<string | string[] | null>;
|
|
1454
|
+
/**
|
|
1455
|
+
* Gets members in score range in reverse order.
|
|
1456
|
+
* @returns Array of members (with scores if withScores)
|
|
1457
|
+
*/
|
|
1458
|
+
zrevrangebyscore(key: string, max: number | string, min: number | string, options?: IZRangeByScoreOptions): Promise<string[]>;
|
|
1459
|
+
/**
|
|
1460
|
+
* Publishes message to channel.
|
|
1461
|
+
* @returns Number of subscribers that received the message
|
|
1462
|
+
*/
|
|
1463
|
+
publish(channel: string, message: string): Promise<number>;
|
|
1464
|
+
/**
|
|
1465
|
+
* Subscribes to channels.
|
|
1466
|
+
*/
|
|
1467
|
+
subscribe(...channels: string[]): Promise<void>;
|
|
1468
|
+
/**
|
|
1469
|
+
* Unsubscribes from channels.
|
|
1470
|
+
*/
|
|
1471
|
+
unsubscribe(...channels: string[]): Promise<void>;
|
|
1472
|
+
/**
|
|
1473
|
+
* Subscribes to channels by pattern.
|
|
1474
|
+
*/
|
|
1475
|
+
psubscribe(...patterns: string[]): Promise<void>;
|
|
1476
|
+
/**
|
|
1477
|
+
* Unsubscribes from channel patterns.
|
|
1478
|
+
*/
|
|
1479
|
+
punsubscribe(...patterns: string[]): Promise<void>;
|
|
1480
|
+
/**
|
|
1481
|
+
* Adds entry to stream.
|
|
1482
|
+
* @param key - Stream key
|
|
1483
|
+
* @param id - Entry ID ('*' for auto-generated)
|
|
1484
|
+
* @param fields - Field-value pairs
|
|
1485
|
+
* @param options - Optional MAXLEN/MINID trimming
|
|
1486
|
+
* @returns Entry ID
|
|
1487
|
+
*/
|
|
1488
|
+
xadd(key: string, id: string, fields: Record<string, string>, options?: IStreamAddOptions): Promise<string>;
|
|
1489
|
+
/**
|
|
1490
|
+
* Reads entries from streams.
|
|
1491
|
+
* @param streams - Stream keys and IDs to read from
|
|
1492
|
+
* @param options - Read options (COUNT, BLOCK)
|
|
1493
|
+
* @returns Array of stream entries or null
|
|
1494
|
+
*/
|
|
1495
|
+
xread(streams: Array<{
|
|
1496
|
+
key: string;
|
|
1497
|
+
id: string;
|
|
1498
|
+
}>, options?: IStreamReadOptions): Promise<StreamReadResult | null>;
|
|
1499
|
+
/**
|
|
1500
|
+
* Reads entries from streams using consumer group.
|
|
1501
|
+
* @param group - Consumer group name
|
|
1502
|
+
* @param consumer - Consumer name
|
|
1503
|
+
* @param streams - Stream keys and IDs to read from
|
|
1504
|
+
* @param options - Read options (COUNT, BLOCK, NOACK)
|
|
1505
|
+
* @returns Array of stream entries or null
|
|
1506
|
+
*/
|
|
1507
|
+
xreadgroup(group: string, consumer: string, streams: Array<{
|
|
1508
|
+
key: string;
|
|
1509
|
+
id: string;
|
|
1510
|
+
}>, options?: IStreamReadGroupOptions): Promise<StreamReadResult | null>;
|
|
1511
|
+
/**
|
|
1512
|
+
* Gets range of entries from stream.
|
|
1513
|
+
* @param key - Stream key
|
|
1514
|
+
* @param start - Start ID ('-' for oldest)
|
|
1515
|
+
* @param end - End ID ('+' for newest)
|
|
1516
|
+
* @param options - Optional COUNT
|
|
1517
|
+
* @returns Array of entries
|
|
1518
|
+
*/
|
|
1519
|
+
xrange(key: string, start: string, end: string, options?: {
|
|
1520
|
+
count?: number;
|
|
1521
|
+
}): Promise<IStreamEntry[]>;
|
|
1522
|
+
/**
|
|
1523
|
+
* Gets range of entries in reverse order.
|
|
1524
|
+
* @param key - Stream key
|
|
1525
|
+
* @param end - End ID ('+' for newest)
|
|
1526
|
+
* @param start - Start ID ('-' for oldest)
|
|
1527
|
+
* @param options - Optional COUNT
|
|
1528
|
+
* @returns Array of entries
|
|
1529
|
+
*/
|
|
1530
|
+
xrevrange(key: string, end: string, start: string, options?: {
|
|
1531
|
+
count?: number;
|
|
1532
|
+
}): Promise<IStreamEntry[]>;
|
|
1533
|
+
/**
|
|
1534
|
+
* Gets stream length.
|
|
1535
|
+
* @param key - Stream key
|
|
1536
|
+
* @returns Number of entries
|
|
1537
|
+
*/
|
|
1538
|
+
xlen(key: string): Promise<number>;
|
|
1539
|
+
/**
|
|
1540
|
+
* Gets stream information.
|
|
1541
|
+
* @param key - Stream key
|
|
1542
|
+
* @returns Stream info object
|
|
1543
|
+
*/
|
|
1544
|
+
xinfo(key: string): Promise<IStreamInfo>;
|
|
1545
|
+
/**
|
|
1546
|
+
* Trims stream to specified length.
|
|
1547
|
+
* @param key - Stream key
|
|
1548
|
+
* @param maxLen - Maximum length
|
|
1549
|
+
* @param approximate - Use '~' for approximate trimming (better performance)
|
|
1550
|
+
* @returns Number of entries removed
|
|
1551
|
+
*/
|
|
1552
|
+
xtrim(key: string, maxLen: number, approximate?: boolean): Promise<number>;
|
|
1553
|
+
/**
|
|
1554
|
+
* Creates consumer group.
|
|
1555
|
+
* @param key - Stream key
|
|
1556
|
+
* @param group - Group name
|
|
1557
|
+
* @param id - Start ID ('$' for new entries only, '0' for all)
|
|
1558
|
+
* @param mkstream - Create stream if doesn't exist
|
|
1559
|
+
* @returns 'OK' if successful
|
|
1560
|
+
*/
|
|
1561
|
+
xgroupCreate(key: string, group: string, id: string, mkstream?: boolean): Promise<'OK'>;
|
|
1562
|
+
/**
|
|
1563
|
+
* Destroys consumer group.
|
|
1564
|
+
* @param key - Stream key
|
|
1565
|
+
* @param group - Group name
|
|
1566
|
+
* @returns 1 if destroyed, 0 if didn't exist
|
|
1567
|
+
*/
|
|
1568
|
+
xgroupDestroy(key: string, group: string): Promise<number>;
|
|
1569
|
+
/**
|
|
1570
|
+
* Deletes consumer from group.
|
|
1571
|
+
* @param key - Stream key
|
|
1572
|
+
* @param group - Group name
|
|
1573
|
+
* @param consumer - Consumer name
|
|
1574
|
+
* @returns Number of pending messages removed
|
|
1575
|
+
*/
|
|
1576
|
+
xgroupDelConsumer(key: string, group: string, consumer: string): Promise<number>;
|
|
1577
|
+
/**
|
|
1578
|
+
* Sets consumer group last delivered ID.
|
|
1579
|
+
* @param key - Stream key
|
|
1580
|
+
* @param group - Group name
|
|
1581
|
+
* @param id - New last ID
|
|
1582
|
+
* @returns 'OK' if successful
|
|
1583
|
+
*/
|
|
1584
|
+
xgroupSetId(key: string, group: string, id: string): Promise<'OK'>;
|
|
1585
|
+
/**
|
|
1586
|
+
* Acknowledges message processing.
|
|
1587
|
+
* @param key - Stream key
|
|
1588
|
+
* @param group - Group name
|
|
1589
|
+
* @param ids - Message IDs to acknowledge
|
|
1590
|
+
* @returns Number of messages acknowledged
|
|
1591
|
+
*/
|
|
1592
|
+
xack(key: string, group: string, ...ids: string[]): Promise<number>;
|
|
1593
|
+
/**
|
|
1594
|
+
* Gets pending messages info.
|
|
1595
|
+
* @param key - Stream key
|
|
1596
|
+
* @param group - Group name
|
|
1597
|
+
* @returns Pending info summary
|
|
1598
|
+
*/
|
|
1599
|
+
xpending(key: string, group: string): Promise<IStreamPendingInfo>;
|
|
1600
|
+
/**
|
|
1601
|
+
* Gets detailed pending messages.
|
|
1602
|
+
* @param key - Stream key
|
|
1603
|
+
* @param group - Group name
|
|
1604
|
+
* @param start - Start ID
|
|
1605
|
+
* @param end - End ID
|
|
1606
|
+
* @param count - Max entries to return
|
|
1607
|
+
* @param consumer - Optional consumer filter
|
|
1608
|
+
* @returns Array of pending entries
|
|
1609
|
+
*/
|
|
1610
|
+
xpendingRange(key: string, group: string, start: string, end: string, count: number, consumer?: string): Promise<IStreamPendingEntry[]>;
|
|
1611
|
+
/**
|
|
1612
|
+
* Claims messages from another consumer.
|
|
1613
|
+
* @param key - Stream key
|
|
1614
|
+
* @param group - Group name
|
|
1615
|
+
* @param consumer - New consumer
|
|
1616
|
+
* @param minIdleTime - Minimum idle time in ms
|
|
1617
|
+
* @param ids - Message IDs to claim
|
|
1618
|
+
* @returns Claimed entries
|
|
1619
|
+
*/
|
|
1620
|
+
xclaim(key: string, group: string, consumer: string, minIdleTime: number, ...ids: string[]): Promise<IStreamEntry[]>;
|
|
1621
|
+
/**
|
|
1622
|
+
* Deletes entries from stream.
|
|
1623
|
+
* @param key - Stream key
|
|
1624
|
+
* @param ids - Entry IDs to delete
|
|
1625
|
+
* @returns Number of entries deleted
|
|
1626
|
+
*/
|
|
1627
|
+
xdel(key: string, ...ids: string[]): Promise<number>;
|
|
1628
|
+
/**
|
|
1629
|
+
* Creates a pipeline for batching commands.
|
|
1630
|
+
* Commands are executed atomically but not transactionally.
|
|
1631
|
+
*/
|
|
1632
|
+
pipeline(): IPipeline;
|
|
1633
|
+
/**
|
|
1634
|
+
* Creates a multi/exec transaction.
|
|
1635
|
+
* Commands are executed atomically and transactionally.
|
|
1636
|
+
*/
|
|
1637
|
+
multi(): IMulti;
|
|
1638
|
+
/**
|
|
1639
|
+
* Evaluates Lua script.
|
|
1640
|
+
* @param script - Lua script source
|
|
1641
|
+
* @param keys - KEYS array
|
|
1642
|
+
* @param args - ARGV array
|
|
1643
|
+
* @returns Script result
|
|
1644
|
+
*/
|
|
1645
|
+
eval(script: string, keys: string[], args: Array<string | number>): Promise<unknown>;
|
|
1646
|
+
/**
|
|
1647
|
+
* Evaluates Lua script by SHA.
|
|
1648
|
+
* @param sha - Script SHA hash
|
|
1649
|
+
* @param keys - KEYS array
|
|
1650
|
+
* @param args - ARGV array
|
|
1651
|
+
* @returns Script result
|
|
1652
|
+
*/
|
|
1653
|
+
evalsha(sha: string, keys: string[], args: Array<string | number>): Promise<unknown>;
|
|
1654
|
+
/**
|
|
1655
|
+
* Loads Lua script and returns SHA.
|
|
1656
|
+
* @param script - Lua script source
|
|
1657
|
+
* @returns SHA hash
|
|
1658
|
+
*/
|
|
1659
|
+
scriptLoad(script: string): Promise<string>;
|
|
1660
|
+
/**
|
|
1661
|
+
* Checks if scripts exist.
|
|
1662
|
+
* @param shas - Script SHA hashes
|
|
1663
|
+
* @returns Array of 1/0 for each script
|
|
1664
|
+
*/
|
|
1665
|
+
scriptExists(...shas: string[]): Promise<number[]>;
|
|
1666
|
+
/**
|
|
1667
|
+
* Flushes all scripts from cache.
|
|
1668
|
+
* @returns 'OK' if successful
|
|
1669
|
+
*/
|
|
1670
|
+
scriptFlush(): Promise<'OK'>;
|
|
1671
|
+
/**
|
|
1672
|
+
* Flushes all keys from current database.
|
|
1673
|
+
* @returns 'OK' if successful
|
|
1674
|
+
*/
|
|
1675
|
+
flushdb(): Promise<'OK'>;
|
|
1676
|
+
/**
|
|
1677
|
+
* Flushes all keys from all databases.
|
|
1678
|
+
* @returns 'OK' if successful
|
|
1679
|
+
*/
|
|
1680
|
+
flushall(): Promise<'OK'>;
|
|
1681
|
+
/**
|
|
1682
|
+
* Gets server info.
|
|
1683
|
+
* @param section - Optional info section
|
|
1684
|
+
* @returns Info string
|
|
1685
|
+
*/
|
|
1686
|
+
info(section?: string): Promise<string>;
|
|
1687
|
+
/**
|
|
1688
|
+
* Gets database size (number of keys).
|
|
1689
|
+
* @returns Number of keys
|
|
1690
|
+
*/
|
|
1691
|
+
dbsize(): Promise<number>;
|
|
1692
|
+
/**
|
|
1693
|
+
* Adds elements to HyperLogLog.
|
|
1694
|
+
* @returns 1 if cardinality changed, 0 otherwise
|
|
1695
|
+
*/
|
|
1696
|
+
pfadd(key: string, ...elements: string[]): Promise<number>;
|
|
1697
|
+
/**
|
|
1698
|
+
* Returns estimated cardinality.
|
|
1699
|
+
* @returns Estimated number of unique elements
|
|
1700
|
+
*/
|
|
1701
|
+
pfcount(...keys: string[]): Promise<number>;
|
|
1702
|
+
/**
|
|
1703
|
+
* Merges HyperLogLogs into destination.
|
|
1704
|
+
* @returns 'OK' if successful
|
|
1705
|
+
*/
|
|
1706
|
+
pfmerge(destination: string, ...sources: string[]): Promise<'OK'>;
|
|
1707
|
+
/**
|
|
1708
|
+
* Adds geospatial members.
|
|
1709
|
+
* @param members - Array of [longitude, latitude, member]
|
|
1710
|
+
* @returns Number of members added
|
|
1711
|
+
*/
|
|
1712
|
+
geoadd(key: string, ...members: Array<number | string>): Promise<number>;
|
|
1713
|
+
/**
|
|
1714
|
+
* Returns distance between two members.
|
|
1715
|
+
* @param unit - m, km, mi, ft
|
|
1716
|
+
* @returns Distance or null if member doesn't exist
|
|
1717
|
+
*/
|
|
1718
|
+
geodist(key: string, member1: string, member2: string, unit?: GeoUnit): Promise<string | null>;
|
|
1719
|
+
/**
|
|
1720
|
+
* Returns geohash strings for members.
|
|
1721
|
+
* @returns Array of geohash strings (null for non-existent)
|
|
1722
|
+
*/
|
|
1723
|
+
geohash(key: string, ...members: string[]): Promise<Array<string | null>>;
|
|
1724
|
+
/**
|
|
1725
|
+
* Returns positions of members.
|
|
1726
|
+
* @returns Array of [longitude, latitude] or null
|
|
1727
|
+
*/
|
|
1728
|
+
geopos(key: string, ...members: string[]): Promise<Array<[string, string] | null>>;
|
|
1729
|
+
/**
|
|
1730
|
+
* Searches for members in radius.
|
|
1731
|
+
* @returns Array of members with optional distance/coordinates
|
|
1732
|
+
*/
|
|
1733
|
+
geosearch(key: string, options: IGeoSearchOptions): Promise<Array<string | IGeoSearchResult>>;
|
|
1734
|
+
/**
|
|
1735
|
+
* Searches and stores result.
|
|
1736
|
+
* @returns Number of members in result
|
|
1737
|
+
*/
|
|
1738
|
+
geosearchstore(destination: string, source: string, options: IGeoSearchOptions & {
|
|
1739
|
+
storedist?: boolean;
|
|
1740
|
+
}): Promise<number>;
|
|
1741
|
+
/**
|
|
1742
|
+
* Sets bit at offset.
|
|
1743
|
+
* @returns Previous bit value
|
|
1744
|
+
*/
|
|
1745
|
+
setbit(key: string, offset: number, value: 0 | 1): Promise<number>;
|
|
1746
|
+
/**
|
|
1747
|
+
* Gets bit at offset.
|
|
1748
|
+
* @returns Bit value (0 or 1)
|
|
1749
|
+
*/
|
|
1750
|
+
getbit(key: string, offset: number): Promise<number>;
|
|
1751
|
+
/**
|
|
1752
|
+
* Counts set bits in range.
|
|
1753
|
+
* @param start - Start byte offset
|
|
1754
|
+
* @param end - End byte offset
|
|
1755
|
+
* @param mode - BYTE or BIT
|
|
1756
|
+
* @returns Number of set bits
|
|
1757
|
+
*/
|
|
1758
|
+
bitcount(key: string, start?: number, end?: number, mode?: 'BYTE' | 'BIT'): Promise<number>;
|
|
1759
|
+
/**
|
|
1760
|
+
* Performs bitwise operations.
|
|
1761
|
+
* @param operation - AND, OR, XOR, NOT
|
|
1762
|
+
* @param destKey - Destination key
|
|
1763
|
+
* @param keys - Source keys (one for NOT)
|
|
1764
|
+
* @returns Size of result in bytes
|
|
1765
|
+
*/
|
|
1766
|
+
bitop(operation: 'AND' | 'OR' | 'XOR' | 'NOT', destKey: string, ...keys: string[]): Promise<number>;
|
|
1767
|
+
/**
|
|
1768
|
+
* Finds first bit set to value.
|
|
1769
|
+
* @param bit - 0 or 1
|
|
1770
|
+
* @param start - Start byte offset
|
|
1771
|
+
* @param end - End byte offset
|
|
1772
|
+
* @param mode - BYTE or BIT
|
|
1773
|
+
* @returns Position of first bit, -1 if not found
|
|
1774
|
+
*/
|
|
1775
|
+
bitpos(key: string, bit: 0 | 1, start?: number, end?: number, mode?: 'BYTE' | 'BIT'): Promise<number>;
|
|
1776
|
+
/**
|
|
1777
|
+
* Executes Redis Cluster commands.
|
|
1778
|
+
* @param subcommand - Cluster subcommand (INFO, NODES, etc.)
|
|
1779
|
+
* @param args - Additional arguments
|
|
1780
|
+
* @returns Command result
|
|
1781
|
+
*/
|
|
1782
|
+
cluster(subcommand: string, ...args: Array<string | number>): Promise<unknown>;
|
|
1783
|
+
/**
|
|
1784
|
+
* Executes Redis Sentinel commands.
|
|
1785
|
+
* @param subcommand - Sentinel subcommand (masters, master, replicas, etc.)
|
|
1786
|
+
* @param args - Additional arguments
|
|
1787
|
+
* @returns Command result
|
|
1788
|
+
*/
|
|
1789
|
+
sentinel(subcommand: string, ...args: Array<string | number>): Promise<unknown>;
|
|
1790
|
+
/**
|
|
1791
|
+
* Registers event handler.
|
|
1792
|
+
*/
|
|
1793
|
+
on(event: DriverEvent, handler: DriverEventHandler): void;
|
|
1794
|
+
/**
|
|
1795
|
+
* Registers one-time event handler.
|
|
1796
|
+
*/
|
|
1797
|
+
once(event: DriverEvent, handler: DriverEventHandler): void;
|
|
1798
|
+
/**
|
|
1799
|
+
* Unregisters event handler.
|
|
1800
|
+
*/
|
|
1801
|
+
off(event: DriverEvent, handler: DriverEventHandler): void;
|
|
1802
|
+
/**
|
|
1803
|
+
* Removes all listeners for event.
|
|
1804
|
+
*/
|
|
1805
|
+
removeAllListeners(event?: DriverEvent): void;
|
|
1806
|
+
}
|
|
1807
|
+
/**
|
|
1808
|
+
* Options for SET command.
|
|
1809
|
+
*/
|
|
1810
|
+
interface ISetOptions {
|
|
1811
|
+
/**
|
|
1812
|
+
* Expiration in seconds (EX).
|
|
1813
|
+
*/
|
|
1814
|
+
ex?: number;
|
|
1815
|
+
/**
|
|
1816
|
+
* Expiration in milliseconds (PX).
|
|
1817
|
+
*/
|
|
1818
|
+
px?: number;
|
|
1819
|
+
/**
|
|
1820
|
+
* Expiration Unix timestamp in seconds (EXAT).
|
|
1821
|
+
*/
|
|
1822
|
+
exat?: number;
|
|
1823
|
+
/**
|
|
1824
|
+
* Expiration Unix timestamp in milliseconds (PXAT).
|
|
1825
|
+
*/
|
|
1826
|
+
pxat?: number;
|
|
1827
|
+
/**
|
|
1828
|
+
* Only set if key exists (XX).
|
|
1829
|
+
*/
|
|
1830
|
+
xx?: boolean;
|
|
1831
|
+
/**
|
|
1832
|
+
* Only set if key doesn't exist (NX).
|
|
1833
|
+
*/
|
|
1834
|
+
nx?: boolean;
|
|
1835
|
+
/**
|
|
1836
|
+
* Return previous value (GET).
|
|
1837
|
+
*/
|
|
1838
|
+
get?: boolean;
|
|
1839
|
+
/**
|
|
1840
|
+
* Keep existing TTL (KEEPTTL).
|
|
1841
|
+
*/
|
|
1842
|
+
keepttl?: boolean;
|
|
1843
|
+
}
|
|
1844
|
+
/**
|
|
1845
|
+
* Options for SCAN family commands.
|
|
1846
|
+
*/
|
|
1847
|
+
interface IScanOptions {
|
|
1848
|
+
/**
|
|
1849
|
+
* Match pattern.
|
|
1850
|
+
*/
|
|
1851
|
+
match?: string;
|
|
1852
|
+
/**
|
|
1853
|
+
* Count hint (not exact).
|
|
1854
|
+
*/
|
|
1855
|
+
count?: number;
|
|
1856
|
+
/**
|
|
1857
|
+
* Type filter (for SCAN only).
|
|
1858
|
+
*/
|
|
1859
|
+
type?: string;
|
|
1860
|
+
}
|
|
1861
|
+
/**
|
|
1862
|
+
* Pipeline for batching Redis commands.
|
|
1863
|
+
* Commands are buffered and sent to server in a single round-trip.
|
|
1864
|
+
*/
|
|
1865
|
+
interface IPipeline {
|
|
1866
|
+
/**
|
|
1867
|
+
* Executes all queued commands.
|
|
1868
|
+
* @returns Array of [error, result] tuples for each command
|
|
1869
|
+
*/
|
|
1870
|
+
exec(): Promise<Array<[Error | null, unknown]>>;
|
|
1871
|
+
get(key: string): this;
|
|
1872
|
+
set(key: string, value: string, options?: ISetOptions): this;
|
|
1873
|
+
del(...keys: string[]): this;
|
|
1874
|
+
mget(...keys: string[]): this;
|
|
1875
|
+
mset(data: Record<string, string>): this;
|
|
1876
|
+
expire(key: string, seconds: number): this;
|
|
1877
|
+
ttl(key: string): this;
|
|
1878
|
+
incr(key: string): this;
|
|
1879
|
+
incrby(key: string, increment: number): this;
|
|
1880
|
+
hget(key: string, field: string): this;
|
|
1881
|
+
hset(key: string, field: string, value: string): this;
|
|
1882
|
+
hmset(key: string, data: Record<string, string>): this;
|
|
1883
|
+
hgetall(key: string): this;
|
|
1884
|
+
lpush(key: string, ...values: string[]): this;
|
|
1885
|
+
rpush(key: string, ...values: string[]): this;
|
|
1886
|
+
sadd(key: string, ...members: string[]): this;
|
|
1887
|
+
srem(key: string, ...members: string[]): this;
|
|
1888
|
+
zadd(key: string, ...args: Array<number | string>): this;
|
|
1889
|
+
zrem(key: string, ...members: string[]): this;
|
|
1890
|
+
}
|
|
1891
|
+
/**
|
|
1892
|
+
* Multi/Exec transaction.
|
|
1893
|
+
* Commands are executed atomically and transactionally.
|
|
1894
|
+
*/
|
|
1895
|
+
interface IMulti extends IPipeline {
|
|
1896
|
+
/**
|
|
1897
|
+
* Discards transaction.
|
|
1898
|
+
*/
|
|
1899
|
+
discard(): void;
|
|
1900
|
+
}
|
|
1901
|
+
/**
|
|
1902
|
+
* Options for XADD command.
|
|
1903
|
+
*/
|
|
1904
|
+
interface IStreamAddOptions {
|
|
1905
|
+
/**
|
|
1906
|
+
* Maximum stream length (MAXLEN).
|
|
1907
|
+
*/
|
|
1908
|
+
maxLen?: number;
|
|
1909
|
+
/**
|
|
1910
|
+
* Use approximate trimming (~) for better performance.
|
|
1911
|
+
*/
|
|
1912
|
+
approximate?: boolean;
|
|
1913
|
+
/**
|
|
1914
|
+
* Only add if stream exists (NOMKSTREAM).
|
|
1915
|
+
*/
|
|
1916
|
+
noMkStream?: boolean;
|
|
1917
|
+
/**
|
|
1918
|
+
* Minimum ID for trimming (MINID).
|
|
1919
|
+
*/
|
|
1920
|
+
minId?: string;
|
|
1921
|
+
}
|
|
1922
|
+
/**
|
|
1923
|
+
* Options for XREAD command.
|
|
1924
|
+
*/
|
|
1925
|
+
interface IStreamReadOptions {
|
|
1926
|
+
/**
|
|
1927
|
+
* Maximum entries per stream.
|
|
1928
|
+
*/
|
|
1929
|
+
count?: number;
|
|
1930
|
+
/**
|
|
1931
|
+
* Block timeout in milliseconds (0 = forever).
|
|
1932
|
+
*/
|
|
1933
|
+
block?: number;
|
|
1934
|
+
}
|
|
1935
|
+
/**
|
|
1936
|
+
* Options for XREADGROUP command.
|
|
1937
|
+
*/
|
|
1938
|
+
interface IStreamReadGroupOptions extends IStreamReadOptions {
|
|
1939
|
+
/**
|
|
1940
|
+
* Don't add to pending list.
|
|
1941
|
+
*/
|
|
1942
|
+
noAck?: boolean;
|
|
1943
|
+
}
|
|
1944
|
+
/**
|
|
1945
|
+
* Single stream entry.
|
|
1946
|
+
*/
|
|
1947
|
+
interface IStreamEntry {
|
|
1948
|
+
/**
|
|
1949
|
+
* Entry ID (timestamp-sequence).
|
|
1950
|
+
*/
|
|
1951
|
+
id: string;
|
|
1952
|
+
/**
|
|
1953
|
+
* Entry fields.
|
|
1954
|
+
*/
|
|
1955
|
+
fields: Record<string, string>;
|
|
1956
|
+
}
|
|
1957
|
+
/**
|
|
1958
|
+
* Result from XREAD/XREADGROUP.
|
|
1959
|
+
*/
|
|
1960
|
+
type StreamReadResult = Array<{
|
|
1961
|
+
/**
|
|
1962
|
+
* Stream key.
|
|
1963
|
+
*/
|
|
1964
|
+
key: string;
|
|
1965
|
+
/**
|
|
1966
|
+
* Entries read from stream.
|
|
1967
|
+
*/
|
|
1968
|
+
entries: IStreamEntry[];
|
|
1969
|
+
}>;
|
|
1970
|
+
/**
|
|
1971
|
+
* Stream information from XINFO.
|
|
1972
|
+
*/
|
|
1973
|
+
interface IStreamInfo {
|
|
1974
|
+
/**
|
|
1975
|
+
* Number of entries.
|
|
1976
|
+
*/
|
|
1977
|
+
length: number;
|
|
1978
|
+
/**
|
|
1979
|
+
* Number of consumer groups.
|
|
1980
|
+
*/
|
|
1981
|
+
groups: number;
|
|
1982
|
+
/**
|
|
1983
|
+
* First entry ID.
|
|
1984
|
+
*/
|
|
1985
|
+
firstEntry: IStreamEntry | null;
|
|
1986
|
+
/**
|
|
1987
|
+
* Last entry ID.
|
|
1988
|
+
*/
|
|
1989
|
+
lastEntry: IStreamEntry | null;
|
|
1990
|
+
/**
|
|
1991
|
+
* Last generated ID.
|
|
1992
|
+
*/
|
|
1993
|
+
lastGeneratedId: string;
|
|
1994
|
+
/**
|
|
1995
|
+
* Radix tree keys.
|
|
1996
|
+
*/
|
|
1997
|
+
radixTreeKeys: number;
|
|
1998
|
+
/**
|
|
1999
|
+
* Radix tree nodes.
|
|
2000
|
+
*/
|
|
2001
|
+
radixTreeNodes: number;
|
|
2002
|
+
}
|
|
2003
|
+
/**
|
|
2004
|
+
* Pending messages summary from XPENDING.
|
|
2005
|
+
*/
|
|
2006
|
+
interface IStreamPendingInfo {
|
|
2007
|
+
/**
|
|
2008
|
+
* Total pending count.
|
|
2009
|
+
*/
|
|
2010
|
+
count: number;
|
|
2011
|
+
/**
|
|
2012
|
+
* Smallest pending ID.
|
|
2013
|
+
*/
|
|
2014
|
+
minId: string | null;
|
|
2015
|
+
/**
|
|
2016
|
+
* Largest pending ID.
|
|
2017
|
+
*/
|
|
2018
|
+
maxId: string | null;
|
|
2019
|
+
/**
|
|
2020
|
+
* Pending count per consumer.
|
|
2021
|
+
*/
|
|
2022
|
+
consumers: Array<{
|
|
2023
|
+
name: string;
|
|
2024
|
+
count: number;
|
|
2025
|
+
}>;
|
|
2026
|
+
}
|
|
2027
|
+
/**
|
|
2028
|
+
* Single pending entry from XPENDING with range.
|
|
2029
|
+
*/
|
|
2030
|
+
interface IStreamPendingEntry {
|
|
2031
|
+
/**
|
|
2032
|
+
* Entry ID.
|
|
2033
|
+
*/
|
|
2034
|
+
id: string;
|
|
2035
|
+
/**
|
|
2036
|
+
* Consumer name.
|
|
2037
|
+
*/
|
|
2038
|
+
consumer: string;
|
|
2039
|
+
/**
|
|
2040
|
+
* Idle time in milliseconds.
|
|
2041
|
+
*/
|
|
2042
|
+
idleTime: number;
|
|
2043
|
+
/**
|
|
2044
|
+
* Delivery count.
|
|
2045
|
+
*/
|
|
2046
|
+
deliveryCount: number;
|
|
2047
|
+
}
|
|
2048
|
+
/**
|
|
2049
|
+
* Driver events.
|
|
2050
|
+
*/
|
|
2051
|
+
declare enum DriverEvent {
|
|
2052
|
+
CONNECT = "connect",
|
|
2053
|
+
READY = "ready",
|
|
2054
|
+
DISCONNECT = "disconnect",
|
|
2055
|
+
CLOSE = "close",
|
|
2056
|
+
ERROR = "error",
|
|
2057
|
+
RECONNECTING = "reconnecting",
|
|
2058
|
+
END = "end"
|
|
2059
|
+
}
|
|
2060
|
+
/**
|
|
2061
|
+
* Driver event handler.
|
|
2062
|
+
*/
|
|
2063
|
+
type DriverEventHandler = (data?: unknown) => void;
|
|
2064
|
+
/**
|
|
2065
|
+
* Options for COPY command.
|
|
2066
|
+
*/
|
|
2067
|
+
interface ICopyOptions {
|
|
2068
|
+
/**
|
|
2069
|
+
* Target database number.
|
|
2070
|
+
*/
|
|
2071
|
+
db?: number;
|
|
2072
|
+
/**
|
|
2073
|
+
* Replace existing key.
|
|
2074
|
+
*/
|
|
2075
|
+
replace?: boolean;
|
|
2076
|
+
}
|
|
2077
|
+
/**
|
|
2078
|
+
* Options for RESTORE command.
|
|
2079
|
+
*/
|
|
2080
|
+
interface IRestoreOptions {
|
|
2081
|
+
/**
|
|
2082
|
+
* Replace existing key.
|
|
2083
|
+
*/
|
|
2084
|
+
replace?: boolean;
|
|
2085
|
+
/**
|
|
2086
|
+
* Absolute Unix timestamp (milliseconds) for expiration.
|
|
2087
|
+
*/
|
|
2088
|
+
absttl?: boolean;
|
|
2089
|
+
/**
|
|
2090
|
+
* Eviction time in seconds.
|
|
2091
|
+
*/
|
|
2092
|
+
idletime?: number;
|
|
2093
|
+
/**
|
|
2094
|
+
* Eviction frequency.
|
|
2095
|
+
*/
|
|
2096
|
+
freq?: number;
|
|
2097
|
+
}
|
|
2098
|
+
/**
|
|
2099
|
+
* Options for LPOS command.
|
|
2100
|
+
*/
|
|
2101
|
+
interface ILposOptions {
|
|
2102
|
+
/**
|
|
2103
|
+
* Search from Nth match.
|
|
2104
|
+
*/
|
|
2105
|
+
rank?: number;
|
|
2106
|
+
/**
|
|
2107
|
+
* Return count matches.
|
|
2108
|
+
*/
|
|
2109
|
+
count?: number;
|
|
2110
|
+
/**
|
|
2111
|
+
* Limit comparisons.
|
|
2112
|
+
*/
|
|
2113
|
+
maxlen?: number;
|
|
2114
|
+
}
|
|
2115
|
+
/**
|
|
2116
|
+
* Options for ZRANGEBYSCORE command.
|
|
2117
|
+
*/
|
|
2118
|
+
interface IZRangeByScoreOptions {
|
|
2119
|
+
/**
|
|
2120
|
+
* Include scores in result.
|
|
2121
|
+
*/
|
|
2122
|
+
withScores?: boolean;
|
|
2123
|
+
/**
|
|
2124
|
+
* Limit results.
|
|
2125
|
+
*/
|
|
2126
|
+
limit?: {
|
|
2127
|
+
offset: number;
|
|
2128
|
+
count: number;
|
|
2129
|
+
};
|
|
2130
|
+
}
|
|
2131
|
+
/**
|
|
2132
|
+
* Options for ZUNIONSTORE/ZINTERSTORE commands.
|
|
2133
|
+
*/
|
|
2134
|
+
interface IZStoreOptions {
|
|
2135
|
+
/**
|
|
2136
|
+
* Weight for each input key.
|
|
2137
|
+
*/
|
|
2138
|
+
weights?: number[];
|
|
2139
|
+
/**
|
|
2140
|
+
* How to aggregate scores.
|
|
2141
|
+
*/
|
|
2142
|
+
aggregate?: 'SUM' | 'MIN' | 'MAX';
|
|
2143
|
+
}
|
|
2144
|
+
/**
|
|
2145
|
+
* Geo distance unit.
|
|
2146
|
+
*/
|
|
2147
|
+
type GeoUnit = 'm' | 'km' | 'mi' | 'ft';
|
|
2148
|
+
/**
|
|
2149
|
+
* Options for GEOSEARCH command.
|
|
2150
|
+
*/
|
|
2151
|
+
interface IGeoSearchOptions {
|
|
2152
|
+
/**
|
|
2153
|
+
* Search from member.
|
|
2154
|
+
*/
|
|
2155
|
+
member?: string;
|
|
2156
|
+
/**
|
|
2157
|
+
* Search from coordinates.
|
|
2158
|
+
*/
|
|
2159
|
+
coord?: {
|
|
2160
|
+
longitude: number;
|
|
2161
|
+
latitude: number;
|
|
2162
|
+
};
|
|
2163
|
+
/**
|
|
2164
|
+
* Search by radius.
|
|
2165
|
+
*/
|
|
2166
|
+
radius?: {
|
|
2167
|
+
value: number;
|
|
2168
|
+
unit: GeoUnit;
|
|
2169
|
+
};
|
|
2170
|
+
/**
|
|
2171
|
+
* Search by box.
|
|
2172
|
+
*/
|
|
2173
|
+
box?: {
|
|
2174
|
+
width: number;
|
|
2175
|
+
height: number;
|
|
2176
|
+
unit: GeoUnit;
|
|
2177
|
+
};
|
|
2178
|
+
/**
|
|
2179
|
+
* Sort order.
|
|
2180
|
+
*/
|
|
2181
|
+
sort?: 'ASC' | 'DESC';
|
|
2182
|
+
/**
|
|
2183
|
+
* Limit results.
|
|
2184
|
+
*/
|
|
2185
|
+
count?: number;
|
|
2186
|
+
/**
|
|
2187
|
+
* Use ANY with count.
|
|
2188
|
+
*/
|
|
2189
|
+
any?: boolean;
|
|
2190
|
+
/**
|
|
2191
|
+
* Include coordinates.
|
|
2192
|
+
*/
|
|
2193
|
+
withCoord?: boolean;
|
|
2194
|
+
/**
|
|
2195
|
+
* Include distance.
|
|
2196
|
+
*/
|
|
2197
|
+
withDist?: boolean;
|
|
2198
|
+
/**
|
|
2199
|
+
* Include hash.
|
|
2200
|
+
*/
|
|
2201
|
+
withHash?: boolean;
|
|
2202
|
+
}
|
|
2203
|
+
/**
|
|
2204
|
+
* Geo search result with optional data.
|
|
2205
|
+
*/
|
|
2206
|
+
interface IGeoSearchResult {
|
|
2207
|
+
member: string;
|
|
2208
|
+
distance?: string;
|
|
2209
|
+
hash?: number;
|
|
2210
|
+
coordinates?: [string, string];
|
|
2211
|
+
}
|
|
2212
|
+
|
|
2213
|
+
/**
|
|
2214
|
+
* Redis client interface.
|
|
2215
|
+
*
|
|
2216
|
+
* Wraps IRedisDriver with additional client-level functionality.
|
|
2217
|
+
* Manages connection lifecycle, health checks, and metadata.
|
|
2218
|
+
*
|
|
2219
|
+
* @example
|
|
2220
|
+
* ```typescript
|
|
2221
|
+
* @Injectable()
|
|
2222
|
+
* export class MyService {
|
|
2223
|
+
* constructor(
|
|
2224
|
+
* @Inject(REDIS_CLIENT) private readonly client: IRedisClient
|
|
2225
|
+
* ) {}
|
|
2226
|
+
*
|
|
2227
|
+
* async getData() {
|
|
2228
|
+
* if (this.client.isHealthy()) {
|
|
2229
|
+
* return await this.client.get('key');
|
|
2230
|
+
* }
|
|
2231
|
+
* }
|
|
2232
|
+
* }
|
|
2233
|
+
* ```
|
|
2234
|
+
*/
|
|
2235
|
+
interface IRedisClient extends IRedisDriver {
|
|
2236
|
+
/**
|
|
2237
|
+
* Gets client name.
|
|
2238
|
+
*/
|
|
2239
|
+
readonly name: string;
|
|
2240
|
+
/**
|
|
2241
|
+
* Gets connection configuration.
|
|
2242
|
+
*/
|
|
2243
|
+
readonly config: ConnectionConfig;
|
|
2244
|
+
/**
|
|
2245
|
+
* Gets client metadata.
|
|
2246
|
+
*/
|
|
2247
|
+
getMetadata(): IClientMetadata;
|
|
2248
|
+
/**
|
|
2249
|
+
* Checks if client is healthy (connected and responsive).
|
|
2250
|
+
*/
|
|
2251
|
+
isHealthy(): boolean;
|
|
2252
|
+
/**
|
|
2253
|
+
* Gets connection uptime in milliseconds.
|
|
2254
|
+
* @returns Uptime or null if not connected
|
|
2255
|
+
*/
|
|
2256
|
+
getUptime(): number | null;
|
|
2257
|
+
/**
|
|
2258
|
+
* Measures latency by pinging server.
|
|
2259
|
+
* @returns Latency in milliseconds or null if disconnected
|
|
2260
|
+
*/
|
|
2261
|
+
getLatency(): Promise<number | null>;
|
|
2262
|
+
/**
|
|
2263
|
+
* Gets last error if any.
|
|
2264
|
+
*/
|
|
2265
|
+
getLastError(): Error | null;
|
|
2266
|
+
/**
|
|
2267
|
+
* Clears last error.
|
|
2268
|
+
*/
|
|
2269
|
+
clearLastError(): void;
|
|
2270
|
+
/**
|
|
2271
|
+
* Reconnects to Redis.
|
|
2272
|
+
* Disconnects if connected, then connects again.
|
|
2273
|
+
*/
|
|
2274
|
+
reconnect(): Promise<void>;
|
|
2275
|
+
/**
|
|
2276
|
+
* Quits gracefully.
|
|
2277
|
+
* Waits for pending commands to complete before disconnecting.
|
|
2278
|
+
*/
|
|
2279
|
+
quit(): Promise<void>;
|
|
2280
|
+
/**
|
|
2281
|
+
* Creates a namespaced client.
|
|
2282
|
+
* All keys will be prefixed with namespace.
|
|
2283
|
+
*
|
|
2284
|
+
* @example
|
|
2285
|
+
* ```typescript
|
|
2286
|
+
* const userClient = client.namespace('user');
|
|
2287
|
+
* await userClient.set('123', data); // Actually sets 'user:123'
|
|
2288
|
+
* ```
|
|
2289
|
+
*/
|
|
2290
|
+
namespace(prefix: string): IRedisClient;
|
|
2291
|
+
/**
|
|
2292
|
+
* Gets current namespace prefix.
|
|
2293
|
+
*/
|
|
2294
|
+
getNamespace(): string | null;
|
|
2295
|
+
}
|
|
2296
|
+
/**
|
|
2297
|
+
* Client manager interface.
|
|
2298
|
+
* Manages multiple named Redis clients.
|
|
2299
|
+
*/
|
|
2300
|
+
interface IClientManager {
|
|
2301
|
+
/**
|
|
2302
|
+
* Gets client by name.
|
|
2303
|
+
* @throws Error if client not found
|
|
2304
|
+
*/
|
|
2305
|
+
getClient(name?: string): IRedisClient;
|
|
2306
|
+
/**
|
|
2307
|
+
* Checks if client exists.
|
|
2308
|
+
*/
|
|
2309
|
+
hasClient(name: string): boolean;
|
|
2310
|
+
/**
|
|
2311
|
+
* Gets all client names.
|
|
2312
|
+
*/
|
|
2313
|
+
getClientNames(): string[];
|
|
2314
|
+
/**
|
|
2315
|
+
* Registers a new client.
|
|
2316
|
+
* @throws Error if client with same name already exists
|
|
2317
|
+
*/
|
|
2318
|
+
registerClient(name: string, client: IRedisClient): Promise<void>;
|
|
2319
|
+
/**
|
|
2320
|
+
* Removes and disconnects client.
|
|
2321
|
+
*/
|
|
2322
|
+
removeClient(name: string): Promise<void>;
|
|
2323
|
+
/**
|
|
2324
|
+
* Gets all clients.
|
|
2325
|
+
*/
|
|
2326
|
+
getAllClients(): Map<string, IRedisClient>;
|
|
2327
|
+
/**
|
|
2328
|
+
* Checks health of all clients.
|
|
2329
|
+
*/
|
|
2330
|
+
checkHealth(): Promise<Map<string, boolean>>;
|
|
2331
|
+
/**
|
|
2332
|
+
* Disconnects all clients.
|
|
2333
|
+
*/
|
|
2334
|
+
disconnectAll(): Promise<void>;
|
|
2335
|
+
}
|
|
2336
|
+
|
|
2337
|
+
/**
|
|
2338
|
+
* Health check status for Redis client.
|
|
2339
|
+
*/
|
|
2340
|
+
interface IHealthStatus {
|
|
2341
|
+
/**
|
|
2342
|
+
* Client name.
|
|
2343
|
+
*/
|
|
2344
|
+
name: string;
|
|
2345
|
+
/**
|
|
2346
|
+
* Whether client is healthy (connected and responsive).
|
|
2347
|
+
*/
|
|
2348
|
+
healthy: boolean;
|
|
2349
|
+
/**
|
|
2350
|
+
* Current connection status.
|
|
2351
|
+
*/
|
|
2352
|
+
status: ConnectionStatus;
|
|
2353
|
+
/**
|
|
2354
|
+
* Latency in milliseconds (from PING command).
|
|
2355
|
+
* null if not connected or ping failed.
|
|
2356
|
+
*/
|
|
2357
|
+
latency: number | null;
|
|
2358
|
+
/**
|
|
2359
|
+
* Last error if any.
|
|
2360
|
+
*/
|
|
2361
|
+
lastError: string | null;
|
|
2362
|
+
/**
|
|
2363
|
+
* Timestamp of last successful check.
|
|
2364
|
+
*/
|
|
2365
|
+
lastCheckAt: Date;
|
|
2366
|
+
/**
|
|
2367
|
+
* Additional metadata.
|
|
2368
|
+
*/
|
|
2369
|
+
metadata: {
|
|
2370
|
+
/**
|
|
2371
|
+
* Driver type (ioredis or node-redis).
|
|
2372
|
+
*/
|
|
2373
|
+
driverType: string;
|
|
2374
|
+
/**
|
|
2375
|
+
* Connection type (single, cluster, sentinel).
|
|
2376
|
+
*/
|
|
2377
|
+
connectionType: string;
|
|
2378
|
+
/**
|
|
2379
|
+
* Number of reconnection attempts.
|
|
2380
|
+
*/
|
|
2381
|
+
reconnectAttempts: number;
|
|
2382
|
+
/**
|
|
2383
|
+
* Uptime in milliseconds.
|
|
2384
|
+
*/
|
|
2385
|
+
uptime: number;
|
|
2386
|
+
};
|
|
2387
|
+
}
|
|
2388
|
+
/**
|
|
2389
|
+
* Connection statistics for all clients.
|
|
2390
|
+
*/
|
|
2391
|
+
interface IConnectionStats {
|
|
2392
|
+
/**
|
|
2393
|
+
* Total number of registered clients.
|
|
2394
|
+
*/
|
|
2395
|
+
totalClients: number;
|
|
2396
|
+
/**
|
|
2397
|
+
* Number of connected clients.
|
|
2398
|
+
*/
|
|
2399
|
+
connectedClients: number;
|
|
2400
|
+
/**
|
|
2401
|
+
* Number of disconnected clients.
|
|
2402
|
+
*/
|
|
2403
|
+
disconnectedClients: number;
|
|
2404
|
+
/**
|
|
2405
|
+
* Number of clients with errors.
|
|
2406
|
+
*/
|
|
2407
|
+
errorClients: number;
|
|
2408
|
+
/**
|
|
2409
|
+
* Per-client statistics.
|
|
2410
|
+
*/
|
|
2411
|
+
clients: Record<string, IClientStats>;
|
|
2412
|
+
/**
|
|
2413
|
+
* Timestamp when stats were collected.
|
|
2414
|
+
*/
|
|
2415
|
+
collectedAt: Date;
|
|
2416
|
+
}
|
|
2417
|
+
/**
|
|
2418
|
+
* Statistics for individual client.
|
|
2419
|
+
*/
|
|
2420
|
+
interface IClientStats {
|
|
2421
|
+
/**
|
|
2422
|
+
* Client name.
|
|
2423
|
+
*/
|
|
2424
|
+
name: string;
|
|
2425
|
+
/**
|
|
2426
|
+
* Current status.
|
|
2427
|
+
*/
|
|
2428
|
+
status: ConnectionStatus;
|
|
2429
|
+
/**
|
|
2430
|
+
* Total commands executed.
|
|
2431
|
+
*/
|
|
2432
|
+
commandsExecuted: number;
|
|
2433
|
+
/**
|
|
2434
|
+
* Total errors.
|
|
2435
|
+
*/
|
|
2436
|
+
errors: number;
|
|
2437
|
+
/**
|
|
2438
|
+
* Total reconnections.
|
|
2439
|
+
*/
|
|
2440
|
+
reconnections: number;
|
|
2441
|
+
/**
|
|
2442
|
+
* Average latency in milliseconds.
|
|
2443
|
+
*/
|
|
2444
|
+
averageLatency: number;
|
|
2445
|
+
/**
|
|
2446
|
+
* Peak latency in milliseconds.
|
|
2447
|
+
*/
|
|
2448
|
+
peakLatency: number;
|
|
2449
|
+
/**
|
|
2450
|
+
* Last activity timestamp.
|
|
2451
|
+
*/
|
|
2452
|
+
lastActivityAt: Date | null;
|
|
2453
|
+
/**
|
|
2454
|
+
* Connected since timestamp.
|
|
2455
|
+
*/
|
|
2456
|
+
connectedAt: Date | null;
|
|
2457
|
+
/**
|
|
2458
|
+
* Total uptime in milliseconds.
|
|
2459
|
+
*/
|
|
2460
|
+
uptime: number;
|
|
2461
|
+
}
|
|
2462
|
+
/**
|
|
2463
|
+
* Reconnection options.
|
|
2464
|
+
*/
|
|
2465
|
+
interface IReconnectionOptions {
|
|
2466
|
+
/**
|
|
2467
|
+
* Maximum number of reconnection attempts.
|
|
2468
|
+
* @default Infinity
|
|
2469
|
+
*/
|
|
2470
|
+
maxAttempts?: number;
|
|
2471
|
+
/**
|
|
2472
|
+
* Initial delay in milliseconds.
|
|
2473
|
+
* @default 1000
|
|
2474
|
+
*/
|
|
2475
|
+
initialDelay?: number;
|
|
2476
|
+
/**
|
|
2477
|
+
* Maximum delay in milliseconds.
|
|
2478
|
+
* @default 30000
|
|
2479
|
+
*/
|
|
2480
|
+
maxDelay?: number;
|
|
2481
|
+
/**
|
|
2482
|
+
* Exponential backoff multiplier.
|
|
2483
|
+
* @default 2
|
|
2484
|
+
*/
|
|
2485
|
+
backoffMultiplier?: number;
|
|
2486
|
+
/**
|
|
2487
|
+
* Enable jitter to prevent thundering herd.
|
|
2488
|
+
* @default true
|
|
2489
|
+
*/
|
|
2490
|
+
enableJitter?: boolean;
|
|
2491
|
+
}
|
|
2492
|
+
|
|
2493
|
+
/**
|
|
2494
|
+
* Redis driver manager interface.
|
|
2495
|
+
*
|
|
2496
|
+
* Manages multiple Redis driver connections with:
|
|
2497
|
+
* - Lazy connection (connect on first use)
|
|
2498
|
+
* - Automatic reconnection with exponential backoff
|
|
2499
|
+
* - Health monitoring
|
|
2500
|
+
* - Graceful shutdown
|
|
2501
|
+
* - Connection pooling
|
|
2502
|
+
*
|
|
2503
|
+
* @example
|
|
2504
|
+
* ```typescript
|
|
2505
|
+
* @Injectable()
|
|
2506
|
+
* export class CacheService {
|
|
2507
|
+
* constructor(
|
|
2508
|
+
* @Inject(CLIENT_MANAGER) private readonly clientManager: IRedisDriverManager
|
|
2509
|
+
* ) {}
|
|
2510
|
+
*
|
|
2511
|
+
* async get(key: string): Promise<string | null> {
|
|
2512
|
+
* const driver = await this.clientManager.getClient('cache');
|
|
2513
|
+
* return driver.get(key);
|
|
2514
|
+
* }
|
|
2515
|
+
* }
|
|
2516
|
+
* ```
|
|
2517
|
+
*/
|
|
2518
|
+
interface IRedisDriverManager {
|
|
2519
|
+
/**
|
|
2520
|
+
* Gets Redis driver by name.
|
|
2521
|
+
*
|
|
2522
|
+
* Performs lazy connection on first access.
|
|
2523
|
+
* Subsequent calls return the same connected driver.
|
|
2524
|
+
*
|
|
2525
|
+
* @param name - Client name (default: 'default')
|
|
2526
|
+
* @returns Redis driver instance
|
|
2527
|
+
* @throws Error if client not found or connection fails
|
|
2528
|
+
*
|
|
2529
|
+
* @example
|
|
2530
|
+
* ```typescript
|
|
2531
|
+
* const driver = await manager.getClient('cache');
|
|
2532
|
+
* await driver.set('key', 'value');
|
|
2533
|
+
* ```
|
|
2534
|
+
*/
|
|
2535
|
+
getClient(name?: string): Promise<IRedisDriver>;
|
|
2536
|
+
/**
|
|
2537
|
+
* Creates and registers a new Redis driver.
|
|
2538
|
+
*
|
|
2539
|
+
* @param name - Unique client name
|
|
2540
|
+
* @param config - Redis connection configuration
|
|
2541
|
+
* @param options - Optional client options
|
|
2542
|
+
* @returns Created driver instance
|
|
2543
|
+
* @throws Error if client with this name already exists
|
|
2544
|
+
*
|
|
2545
|
+
* @example
|
|
2546
|
+
* ```typescript
|
|
2547
|
+
* const driver = await manager.createClient('sessions', {
|
|
2548
|
+
* type: 'single',
|
|
2549
|
+
* host: 'localhost',
|
|
2550
|
+
* port: 6379,
|
|
2551
|
+
* db: 1,
|
|
2552
|
+
* });
|
|
2553
|
+
* ```
|
|
2554
|
+
*/
|
|
2555
|
+
createClient(name: string, config: ConnectionConfig, options?: {
|
|
2556
|
+
reconnection?: IReconnectionOptions;
|
|
2557
|
+
metadata?: Partial<IClientMetadata>;
|
|
2558
|
+
}): Promise<IRedisDriver>;
|
|
2559
|
+
/**
|
|
2560
|
+
* Checks if client exists.
|
|
2561
|
+
*
|
|
2562
|
+
* @param name - Client name
|
|
2563
|
+
* @returns true if client is registered
|
|
2564
|
+
*/
|
|
2565
|
+
hasClient(name: string): boolean;
|
|
2566
|
+
/**
|
|
2567
|
+
* Gets all registered client names.
|
|
2568
|
+
*
|
|
2569
|
+
* @returns Array of client names
|
|
2570
|
+
*/
|
|
2571
|
+
getClientNames(): string[];
|
|
2572
|
+
/**
|
|
2573
|
+
* Closes specific client connection.
|
|
2574
|
+
*
|
|
2575
|
+
* Gracefully disconnects and removes client from registry.
|
|
2576
|
+
*
|
|
2577
|
+
* @param name - Client name
|
|
2578
|
+
* @throws Error if client not found
|
|
2579
|
+
*
|
|
2580
|
+
* @example
|
|
2581
|
+
* ```typescript
|
|
2582
|
+
* await manager.closeClient('cache');
|
|
2583
|
+
* ```
|
|
2584
|
+
*/
|
|
2585
|
+
closeClient(name: string): Promise<void>;
|
|
2586
|
+
/**
|
|
2587
|
+
* Closes all client connections.
|
|
2588
|
+
*
|
|
2589
|
+
* Performs graceful shutdown of all clients in parallel.
|
|
2590
|
+
* Safe to call multiple times.
|
|
2591
|
+
*
|
|
2592
|
+
* @example
|
|
2593
|
+
* ```typescript
|
|
2594
|
+
* await manager.closeAll();
|
|
2595
|
+
* ```
|
|
2596
|
+
*/
|
|
2597
|
+
closeAll(): Promise<void>;
|
|
2598
|
+
/**
|
|
2599
|
+
* Performs health check on client(s).
|
|
2600
|
+
*
|
|
2601
|
+
* Executes PING command and measures latency.
|
|
2602
|
+
*
|
|
2603
|
+
* @param name - Client name (if omitted, checks all clients)
|
|
2604
|
+
* @returns Health status for specified client(s)
|
|
2605
|
+
*
|
|
2606
|
+
* @example
|
|
2607
|
+
* ```typescript
|
|
2608
|
+
* // Check single client
|
|
2609
|
+
* const health = await manager.healthCheck('cache');
|
|
2610
|
+
* if (!health.healthy) {
|
|
2611
|
+
* logger.error('Cache unhealthy', health);
|
|
2612
|
+
* }
|
|
2613
|
+
*
|
|
2614
|
+
* // Check all clients
|
|
2615
|
+
* const allHealth = await manager.healthCheck();
|
|
2616
|
+
* ```
|
|
2617
|
+
*/
|
|
2618
|
+
healthCheck(name?: string): Promise<IHealthStatus | IHealthStatus[]>;
|
|
2619
|
+
/**
|
|
2620
|
+
* Gets connection statistics.
|
|
2621
|
+
*
|
|
2622
|
+
* Returns aggregate stats for all clients.
|
|
2623
|
+
*
|
|
2624
|
+
* @returns Connection statistics
|
|
2625
|
+
*
|
|
2626
|
+
* @example
|
|
2627
|
+
* ```typescript
|
|
2628
|
+
* const stats = manager.getStats();
|
|
2629
|
+
* console.log(`Connected: ${stats.connectedClients}/${stats.totalClients}`);
|
|
2630
|
+
* ```
|
|
2631
|
+
*/
|
|
2632
|
+
getStats(): IConnectionStats;
|
|
2633
|
+
/**
|
|
2634
|
+
* Gets client metadata.
|
|
2635
|
+
*
|
|
2636
|
+
* @param name - Client name
|
|
2637
|
+
* @returns Client metadata
|
|
2638
|
+
* @throws Error if client not found
|
|
2639
|
+
*/
|
|
2640
|
+
getMetadata(name: string): IClientMetadata;
|
|
2641
|
+
/**
|
|
2642
|
+
* Updates client metadata.
|
|
2643
|
+
*
|
|
2644
|
+
* @param name - Client name
|
|
2645
|
+
* @param metadata - Partial metadata to merge
|
|
2646
|
+
*/
|
|
2647
|
+
updateMetadata(name: string, metadata: Partial<IClientMetadata>): void;
|
|
2648
|
+
/**
|
|
2649
|
+
* Registers event listener for all clients.
|
|
2650
|
+
*
|
|
2651
|
+
* @param event - Event name
|
|
2652
|
+
* @param handler - Event handler
|
|
2653
|
+
*
|
|
2654
|
+
* @example
|
|
2655
|
+
* ```typescript
|
|
2656
|
+
* manager.on('manager:reconnecting', (data) => {
|
|
2657
|
+
* logger.warn(`Client ${data.name} reconnecting...`);
|
|
2658
|
+
* });
|
|
2659
|
+
* ```
|
|
2660
|
+
*/
|
|
2661
|
+
on(event: ManagerEvent, handler: ManagerEventHandler): void;
|
|
2662
|
+
/**
|
|
2663
|
+
* Unregisters event listener.
|
|
2664
|
+
*
|
|
2665
|
+
* @param event - Event name
|
|
2666
|
+
* @param handler - Event handler
|
|
2667
|
+
*/
|
|
2668
|
+
off(event: ManagerEvent, handler: ManagerEventHandler): void;
|
|
2669
|
+
}
|
|
2670
|
+
/**
|
|
2671
|
+
* Manager-specific events.
|
|
2672
|
+
*/
|
|
2673
|
+
declare enum ManagerEvent {
|
|
2674
|
+
/**
|
|
2675
|
+
* Client connected.
|
|
2676
|
+
*/
|
|
2677
|
+
CONNECTED = "manager:connected",
|
|
2678
|
+
/**
|
|
2679
|
+
* Client disconnected.
|
|
2680
|
+
*/
|
|
2681
|
+
DISCONNECTED = "manager:disconnected",
|
|
2682
|
+
/**
|
|
2683
|
+
* Client reconnecting.
|
|
2684
|
+
*/
|
|
2685
|
+
RECONNECTING = "manager:reconnecting",
|
|
2686
|
+
/**
|
|
2687
|
+
* Client error.
|
|
2688
|
+
*/
|
|
2689
|
+
ERROR = "manager:error",
|
|
2690
|
+
/**
|
|
2691
|
+
* Client created.
|
|
2692
|
+
*/
|
|
2693
|
+
CREATED = "manager:created",
|
|
2694
|
+
/**
|
|
2695
|
+
* Client removed.
|
|
2696
|
+
*/
|
|
2697
|
+
REMOVED = "manager:removed"
|
|
2698
|
+
}
|
|
2699
|
+
/**
|
|
2700
|
+
* Manager event data.
|
|
2701
|
+
*/
|
|
2702
|
+
interface IManagerEventData {
|
|
2703
|
+
/**
|
|
2704
|
+
* Client name.
|
|
2705
|
+
*/
|
|
2706
|
+
name: string;
|
|
2707
|
+
/**
|
|
2708
|
+
* Event timestamp.
|
|
2709
|
+
*/
|
|
2710
|
+
timestamp: Date;
|
|
2711
|
+
/**
|
|
2712
|
+
* Error if any.
|
|
2713
|
+
*/
|
|
2714
|
+
error?: Error;
|
|
2715
|
+
/**
|
|
2716
|
+
* Additional context.
|
|
2717
|
+
*/
|
|
2718
|
+
metadata?: Record<string, unknown>;
|
|
2719
|
+
}
|
|
2720
|
+
/**
|
|
2721
|
+
* Manager event handler.
|
|
2722
|
+
*/
|
|
2723
|
+
type ManagerEventHandler = (data: IManagerEventData) => void;
|
|
2724
|
+
|
|
2725
|
+
/**
|
|
2726
|
+
* Redis Client Manager.
|
|
2727
|
+
*
|
|
2728
|
+
* Manages multiple Redis client connections with:
|
|
2729
|
+
* - Lazy connection (connect on first use)
|
|
2730
|
+
* - Automatic reconnection with exponential backoff
|
|
2731
|
+
* - Health monitoring and statistics
|
|
2732
|
+
* - Graceful shutdown
|
|
2733
|
+
* - Event notifications
|
|
2734
|
+
*
|
|
2735
|
+
* @example
|
|
2736
|
+
* ```typescript
|
|
2737
|
+
* @Injectable()
|
|
2738
|
+
* export class AppService {
|
|
2739
|
+
* constructor(
|
|
2740
|
+
* @Inject(CLIENT_MANAGER) private readonly clientManager: RedisClientManager
|
|
2741
|
+
* ) {}
|
|
2742
|
+
*
|
|
2743
|
+
* async cacheValue(key: string, value: string): Promise<void> {
|
|
2744
|
+
* const client = await this.clientManager.getClient('cache');
|
|
2745
|
+
* await client.set(key, value, { ex: 3600 });
|
|
2746
|
+
* }
|
|
2747
|
+
* }
|
|
2748
|
+
* ```
|
|
2749
|
+
*/
|
|
2750
|
+
declare class RedisClientManager implements IRedisDriverManager, OnModuleDestroy {
|
|
2751
|
+
private readonly logger;
|
|
2752
|
+
/**
|
|
2753
|
+
* Registered clients.
|
|
2754
|
+
*/
|
|
2755
|
+
private readonly clients;
|
|
2756
|
+
/**
|
|
2757
|
+
* Event emitter for client events.
|
|
2758
|
+
*/
|
|
2759
|
+
private readonly eventEmitter;
|
|
2760
|
+
/**
|
|
2761
|
+
* Whether manager is shutting down.
|
|
2762
|
+
*/
|
|
2763
|
+
private isShuttingDown;
|
|
2764
|
+
/**
|
|
2765
|
+
* Default reconnection options.
|
|
2766
|
+
*/
|
|
2767
|
+
private readonly defaultIReconnectionOptions;
|
|
2768
|
+
/**
|
|
2769
|
+
* Default driver type.
|
|
2770
|
+
*/
|
|
2771
|
+
private readonly defaultDriverType;
|
|
2772
|
+
/**
|
|
2773
|
+
* Gets Redis client by name with lazy connection.
|
|
2774
|
+
*/
|
|
2775
|
+
getClient(name?: string): Promise<IRedisDriver>;
|
|
2776
|
+
/**
|
|
2777
|
+
* Creates and registers a new Redis client.
|
|
2778
|
+
*/
|
|
2779
|
+
createClient(name: string, config: ConnectionConfig, options?: {
|
|
2780
|
+
reconnection?: IReconnectionOptions;
|
|
2781
|
+
metadata?: Partial<IClientMetadata>;
|
|
2782
|
+
driverType?: DriverType;
|
|
2783
|
+
}): Promise<IRedisDriver>;
|
|
2784
|
+
/**
|
|
2785
|
+
* Checks if client exists.
|
|
2786
|
+
*/
|
|
2787
|
+
hasClient(name: string): boolean;
|
|
2788
|
+
/**
|
|
2789
|
+
* Gets all registered client names.
|
|
2790
|
+
*/
|
|
2791
|
+
getClientNames(): string[];
|
|
2792
|
+
/**
|
|
2793
|
+
* Closes specific client connection.
|
|
2794
|
+
*/
|
|
2795
|
+
closeClient(name: string): Promise<void>;
|
|
2796
|
+
/**
|
|
2797
|
+
* Closes all client connections.
|
|
2798
|
+
*/
|
|
2799
|
+
closeAll(): Promise<void>;
|
|
2800
|
+
/**
|
|
2801
|
+
* Performs health check on client(s).
|
|
2802
|
+
*/
|
|
2803
|
+
healthCheck(name?: string): Promise<IHealthStatus | IHealthStatus[]>;
|
|
2804
|
+
/**
|
|
2805
|
+
* Gets connection statistics.
|
|
2806
|
+
*/
|
|
2807
|
+
getStats(): IConnectionStats;
|
|
2808
|
+
/**
|
|
2809
|
+
* Gets client metadata.
|
|
2810
|
+
*/
|
|
2811
|
+
getMetadata(name: string): IClientMetadata;
|
|
2812
|
+
/**
|
|
2813
|
+
* Updates client metadata.
|
|
2814
|
+
*/
|
|
2815
|
+
updateMetadata(name: string, metadata: Partial<IClientMetadata>): void;
|
|
2816
|
+
/**
|
|
2817
|
+
* Registers event listener.
|
|
2818
|
+
*/
|
|
2819
|
+
on(event: ManagerEvent, handler: ManagerEventHandler): void;
|
|
2820
|
+
/**
|
|
2821
|
+
* Unregisters event listener.
|
|
2822
|
+
*/
|
|
2823
|
+
off(event: ManagerEvent, handler: ManagerEventHandler): void;
|
|
2824
|
+
/**
|
|
2825
|
+
* NestJS lifecycle hook - cleanup on module destroy.
|
|
2826
|
+
*/
|
|
2827
|
+
onModuleDestroy(): Promise<void>;
|
|
2828
|
+
/**
|
|
2829
|
+
* Connects client with error handling.
|
|
2830
|
+
*/
|
|
2831
|
+
private connectClient;
|
|
2832
|
+
/**
|
|
2833
|
+
* Disconnects client gracefully.
|
|
2834
|
+
*/
|
|
2835
|
+
private disconnectClient;
|
|
2836
|
+
/**
|
|
2837
|
+
* Sets up driver event handlers for reconnection.
|
|
2838
|
+
*/
|
|
2839
|
+
private setupDriverEventHandlers;
|
|
2840
|
+
/**
|
|
2841
|
+
* Schedules reconnection with exponential backoff.
|
|
2842
|
+
*/
|
|
2843
|
+
private scheduleReconnection;
|
|
2844
|
+
/**
|
|
2845
|
+
* Performs health check on single client.
|
|
2846
|
+
*/
|
|
2847
|
+
private checkClientHealth;
|
|
2848
|
+
/**
|
|
2849
|
+
* Creates initial statistics for new client.
|
|
2850
|
+
*/
|
|
2851
|
+
private createInitialStats;
|
|
2852
|
+
/**
|
|
2853
|
+
* Updates latency statistics.
|
|
2854
|
+
*/
|
|
2855
|
+
private updateLatencyStats;
|
|
2856
|
+
/**
|
|
2857
|
+
* Calculates client uptime in milliseconds.
|
|
2858
|
+
*/
|
|
2859
|
+
private calculateUptime;
|
|
2860
|
+
/**
|
|
2861
|
+
* Emits manager event.
|
|
2862
|
+
*/
|
|
2863
|
+
private emitEvent;
|
|
2864
|
+
}
|
|
2865
|
+
|
|
2866
|
+
/**
|
|
2867
|
+
* Redis service - convenient wrapper over RedisClientManager.
|
|
2868
|
+
*
|
|
2869
|
+
* Provides direct access to Redis operations without manual client management.
|
|
2870
|
+
* All methods are proxied to the default Redis driver.
|
|
2871
|
+
*
|
|
2872
|
+
* @example
|
|
2873
|
+
* ```typescript
|
|
2874
|
+
* @Injectable()
|
|
2875
|
+
* export class UserService {
|
|
2876
|
+
* constructor(private readonly redis: RedisService) {}
|
|
2877
|
+
*
|
|
2878
|
+
* async cacheUser(id: string, user: User): Promise<void> {
|
|
2879
|
+
* await this.redis.set(`user:${id}`, JSON.stringify(user), { ex: 3600 });
|
|
2880
|
+
* }
|
|
2881
|
+
*
|
|
2882
|
+
* async getUser(id: string): Promise<User | null> {
|
|
2883
|
+
* const data = await this.redis.get(`user:${id}`);
|
|
2884
|
+
* return data ? JSON.parse(data) : null;
|
|
2885
|
+
* }
|
|
2886
|
+
*
|
|
2887
|
+
* async deleteUser(id: string): Promise<void> {
|
|
2888
|
+
* await this.redis.del(`user:${id}`);
|
|
2889
|
+
* }
|
|
2890
|
+
* }
|
|
2891
|
+
* ```
|
|
2892
|
+
*/
|
|
2893
|
+
declare class RedisService implements OnModuleDestroy {
|
|
2894
|
+
private readonly clientManager;
|
|
2895
|
+
/**
|
|
2896
|
+
* Default Redis driver instance.
|
|
2897
|
+
*/
|
|
2898
|
+
private driver;
|
|
2899
|
+
constructor(clientManager: RedisClientManager);
|
|
2900
|
+
/**
|
|
2901
|
+
* Gets default Redis driver.
|
|
2902
|
+
* Lazy loads on first access.
|
|
2903
|
+
*/
|
|
2904
|
+
private getDriver;
|
|
2905
|
+
/**
|
|
2906
|
+
* Gets a named Redis client.
|
|
2907
|
+
*
|
|
2908
|
+
* @param name - Client name
|
|
2909
|
+
* @returns Redis driver instance
|
|
2910
|
+
*
|
|
2911
|
+
* @example
|
|
2912
|
+
* ```typescript
|
|
2913
|
+
* const sessions = await this.redis.getClient('sessions');
|
|
2914
|
+
* await sessions.set('session:123', data);
|
|
2915
|
+
* ```
|
|
2916
|
+
*/
|
|
2917
|
+
getClient(name?: string): Promise<IRedisDriver>;
|
|
2918
|
+
/**
|
|
2919
|
+
* Checks if default client is connected.
|
|
2920
|
+
*/
|
|
2921
|
+
isConnected(): Promise<boolean>;
|
|
2922
|
+
/**
|
|
2923
|
+
* Pings Redis server.
|
|
2924
|
+
*/
|
|
2925
|
+
ping(message?: string): Promise<string>;
|
|
2926
|
+
/**
|
|
2927
|
+
* Selects database.
|
|
2928
|
+
*/
|
|
2929
|
+
select(db: number): Promise<void>;
|
|
2930
|
+
/**
|
|
2931
|
+
* Gets value by key.
|
|
2932
|
+
*/
|
|
2933
|
+
get(key: string): Promise<string | null>;
|
|
2934
|
+
/**
|
|
2935
|
+
* Sets key-value pair with optional TTL.
|
|
2936
|
+
*/
|
|
2937
|
+
set(key: string, value: string, options?: ISetOptions): Promise<'OK' | null>;
|
|
2938
|
+
/**
|
|
2939
|
+
* Gets multiple values.
|
|
2940
|
+
*/
|
|
2941
|
+
mget(...keys: string[]): Promise<Array<string | null>>;
|
|
2942
|
+
/**
|
|
2943
|
+
* Sets multiple key-value pairs.
|
|
2944
|
+
*/
|
|
2945
|
+
mset(data: Record<string, string>): Promise<'OK'>;
|
|
2946
|
+
/**
|
|
2947
|
+
* Sets value only if key doesn't exist.
|
|
2948
|
+
*/
|
|
2949
|
+
setnx(key: string, value: string): Promise<number>;
|
|
2950
|
+
/**
|
|
2951
|
+
* Sets value with expiration in seconds.
|
|
2952
|
+
*/
|
|
2953
|
+
setex(key: string, seconds: number, value: string): Promise<'OK'>;
|
|
2954
|
+
/**
|
|
2955
|
+
* Gets value and deletes key.
|
|
2956
|
+
*/
|
|
2957
|
+
getdel(key: string): Promise<string | null>;
|
|
2958
|
+
/**
|
|
2959
|
+
* Gets value and sets expiration.
|
|
2960
|
+
*/
|
|
2961
|
+
getex(key: string, options: {
|
|
2962
|
+
ex?: number;
|
|
2963
|
+
px?: number;
|
|
2964
|
+
}): Promise<string | null>;
|
|
2965
|
+
/**
|
|
2966
|
+
* Increments integer value by 1.
|
|
2967
|
+
*/
|
|
2968
|
+
incr(key: string): Promise<number>;
|
|
2969
|
+
/**
|
|
2970
|
+
* Increments integer value by amount.
|
|
2971
|
+
*/
|
|
2972
|
+
incrby(key: string, increment: number): Promise<number>;
|
|
2973
|
+
/**
|
|
2974
|
+
* Decrements integer value by 1.
|
|
2975
|
+
*/
|
|
2976
|
+
decr(key: string): Promise<number>;
|
|
2977
|
+
/**
|
|
2978
|
+
* Decrements integer value by amount.
|
|
2979
|
+
*/
|
|
2980
|
+
decrby(key: string, decrement: number): Promise<number>;
|
|
2981
|
+
/**
|
|
2982
|
+
* Appends value to key.
|
|
2983
|
+
*/
|
|
2984
|
+
append(key: string, value: string): Promise<number>;
|
|
2985
|
+
/**
|
|
2986
|
+
* Deletes one or more keys.
|
|
2987
|
+
*/
|
|
2988
|
+
del(...keys: string[]): Promise<number>;
|
|
2989
|
+
/**
|
|
2990
|
+
* Checks if keys exist.
|
|
2991
|
+
*/
|
|
2992
|
+
exists(...keys: string[]): Promise<number>;
|
|
2993
|
+
/**
|
|
2994
|
+
* Sets TTL on key (seconds).
|
|
2995
|
+
*/
|
|
2996
|
+
expire(key: string, seconds: number): Promise<number>;
|
|
2997
|
+
/**
|
|
2998
|
+
* Sets TTL on key (milliseconds).
|
|
2999
|
+
*/
|
|
3000
|
+
pexpire(key: string, milliseconds: number): Promise<number>;
|
|
3001
|
+
/**
|
|
3002
|
+
* Sets absolute expiration time.
|
|
3003
|
+
*/
|
|
3004
|
+
expireat(key: string, timestamp: number): Promise<number>;
|
|
3005
|
+
/**
|
|
3006
|
+
* Gets TTL of key (seconds).
|
|
3007
|
+
*/
|
|
3008
|
+
ttl(key: string): Promise<number>;
|
|
3009
|
+
/**
|
|
3010
|
+
* Gets TTL of key (milliseconds).
|
|
3011
|
+
*/
|
|
3012
|
+
pttl(key: string): Promise<number>;
|
|
3013
|
+
/**
|
|
3014
|
+
* Removes expiration from key.
|
|
3015
|
+
*/
|
|
3016
|
+
persist(key: string): Promise<number>;
|
|
3017
|
+
/**
|
|
3018
|
+
* Renames key.
|
|
3019
|
+
*/
|
|
3020
|
+
rename(key: string, newKey: string): Promise<'OK'>;
|
|
3021
|
+
/**
|
|
3022
|
+
* Renames key only if new key doesn't exist.
|
|
3023
|
+
*/
|
|
3024
|
+
renamenx(key: string, newKey: string): Promise<number>;
|
|
3025
|
+
/**
|
|
3026
|
+
* Gets type of value stored at key.
|
|
3027
|
+
*/
|
|
3028
|
+
type(key: string): Promise<string>;
|
|
3029
|
+
/**
|
|
3030
|
+
* Scans keys matching pattern.
|
|
3031
|
+
*/
|
|
3032
|
+
scan(cursor: number, options?: IScanOptions): Promise<[string, string[]]>;
|
|
3033
|
+
/**
|
|
3034
|
+
* Gets hash field value.
|
|
3035
|
+
*/
|
|
3036
|
+
hget(key: string, field: string): Promise<string | null>;
|
|
3037
|
+
/**
|
|
3038
|
+
* Sets hash field value.
|
|
3039
|
+
*/
|
|
3040
|
+
hset(key: string, field: string, value: string): Promise<number>;
|
|
3041
|
+
/**
|
|
3042
|
+
* Sets multiple hash fields.
|
|
3043
|
+
*/
|
|
3044
|
+
hmset(key: string, data: Record<string, string>): Promise<'OK'>;
|
|
3045
|
+
/**
|
|
3046
|
+
* Gets multiple hash field values.
|
|
3047
|
+
*/
|
|
3048
|
+
hmget(key: string, ...fields: string[]): Promise<Array<string | null>>;
|
|
3049
|
+
/**
|
|
3050
|
+
* Gets all fields and values of hash.
|
|
3051
|
+
*/
|
|
3052
|
+
hgetall(key: string): Promise<Record<string, string>>;
|
|
3053
|
+
/**
|
|
3054
|
+
* Deletes hash fields.
|
|
3055
|
+
*/
|
|
3056
|
+
hdel(key: string, ...fields: string[]): Promise<number>;
|
|
3057
|
+
/**
|
|
3058
|
+
* Checks if hash field exists.
|
|
3059
|
+
*/
|
|
3060
|
+
hexists(key: string, field: string): Promise<number>;
|
|
3061
|
+
/**
|
|
3062
|
+
* Gets all field names in hash.
|
|
3063
|
+
*/
|
|
3064
|
+
hkeys(key: string): Promise<string[]>;
|
|
3065
|
+
/**
|
|
3066
|
+
* Gets all values in hash.
|
|
3067
|
+
*/
|
|
3068
|
+
hvals(key: string): Promise<string[]>;
|
|
3069
|
+
/**
|
|
3070
|
+
* Gets number of fields in hash.
|
|
3071
|
+
*/
|
|
3072
|
+
hlen(key: string): Promise<number>;
|
|
3073
|
+
/**
|
|
3074
|
+
* Increments hash field by integer.
|
|
3075
|
+
*/
|
|
3076
|
+
hincrby(key: string, field: string, increment: number): Promise<number>;
|
|
3077
|
+
/**
|
|
3078
|
+
* Scans hash fields.
|
|
3079
|
+
*/
|
|
3080
|
+
hscan(key: string, cursor: number, options?: IScanOptions): Promise<[string, string[]]>;
|
|
3081
|
+
/**
|
|
3082
|
+
* Pushes values to left of list.
|
|
3083
|
+
*/
|
|
3084
|
+
lpush(key: string, ...values: string[]): Promise<number>;
|
|
3085
|
+
/**
|
|
3086
|
+
* Pushes values to right of list.
|
|
3087
|
+
*/
|
|
3088
|
+
rpush(key: string, ...values: string[]): Promise<number>;
|
|
3089
|
+
/**
|
|
3090
|
+
* Pops value from left of list.
|
|
3091
|
+
*/
|
|
3092
|
+
lpop(key: string): Promise<string | null>;
|
|
3093
|
+
/**
|
|
3094
|
+
* Pops value from right of list.
|
|
3095
|
+
*/
|
|
3096
|
+
rpop(key: string): Promise<string | null>;
|
|
3097
|
+
/**
|
|
3098
|
+
* Gets list length.
|
|
3099
|
+
*/
|
|
3100
|
+
llen(key: string): Promise<number>;
|
|
3101
|
+
/**
|
|
3102
|
+
* Gets list range.
|
|
3103
|
+
*/
|
|
3104
|
+
lrange(key: string, start: number, stop: number): Promise<string[]>;
|
|
3105
|
+
/**
|
|
3106
|
+
* Trims list to specified range.
|
|
3107
|
+
*/
|
|
3108
|
+
ltrim(key: string, start: number, stop: number): Promise<'OK'>;
|
|
3109
|
+
/**
|
|
3110
|
+
* Gets element at index.
|
|
3111
|
+
*/
|
|
3112
|
+
lindex(key: string, index: number): Promise<string | null>;
|
|
3113
|
+
/**
|
|
3114
|
+
* Sets element at index.
|
|
3115
|
+
*/
|
|
3116
|
+
lset(key: string, index: number, value: string): Promise<'OK'>;
|
|
3117
|
+
/**
|
|
3118
|
+
* Adds members to set.
|
|
3119
|
+
*/
|
|
3120
|
+
sadd(key: string, ...members: string[]): Promise<number>;
|
|
3121
|
+
/**
|
|
3122
|
+
* Removes members from set.
|
|
3123
|
+
*/
|
|
3124
|
+
srem(key: string, ...members: string[]): Promise<number>;
|
|
3125
|
+
/**
|
|
3126
|
+
* Gets all members of set.
|
|
3127
|
+
*/
|
|
3128
|
+
smembers(key: string): Promise<string[]>;
|
|
3129
|
+
/**
|
|
3130
|
+
* Checks if member is in set.
|
|
3131
|
+
*/
|
|
3132
|
+
sismember(key: string, member: string): Promise<number>;
|
|
3133
|
+
/**
|
|
3134
|
+
* Gets number of members in set.
|
|
3135
|
+
*/
|
|
3136
|
+
scard(key: string): Promise<number>;
|
|
3137
|
+
/**
|
|
3138
|
+
* Gets random member from set.
|
|
3139
|
+
*/
|
|
3140
|
+
srandmember(key: string, count?: number): Promise<string | string[] | null>;
|
|
3141
|
+
/**
|
|
3142
|
+
* Pops random member from set.
|
|
3143
|
+
*/
|
|
3144
|
+
spop(key: string, count?: number): Promise<string | string[] | null>;
|
|
3145
|
+
/**
|
|
3146
|
+
* Scans set members.
|
|
3147
|
+
*/
|
|
3148
|
+
sscan(key: string, cursor: number, options?: IScanOptions): Promise<[string, string[]]>;
|
|
3149
|
+
/**
|
|
3150
|
+
* Adds members to sorted set with scores.
|
|
3151
|
+
*/
|
|
3152
|
+
zadd(key: string, ...args: Array<number | string>): Promise<number>;
|
|
3153
|
+
/**
|
|
3154
|
+
* Removes members from sorted set.
|
|
3155
|
+
*/
|
|
3156
|
+
zrem(key: string, ...members: string[]): Promise<number>;
|
|
3157
|
+
/**
|
|
3158
|
+
* Gets members in range by index.
|
|
3159
|
+
*/
|
|
3160
|
+
zrange(key: string, start: number, stop: number, withScores?: boolean): Promise<string[]>;
|
|
3161
|
+
/**
|
|
3162
|
+
* Gets members in range by score.
|
|
3163
|
+
*/
|
|
3164
|
+
zrangebyscore(key: string, min: number | string, max: number | string, withScores?: boolean): Promise<string[]>;
|
|
3165
|
+
/**
|
|
3166
|
+
* Gets score of member.
|
|
3167
|
+
*/
|
|
3168
|
+
zscore(key: string, member: string): Promise<string | null>;
|
|
3169
|
+
/**
|
|
3170
|
+
* Gets number of members in sorted set.
|
|
3171
|
+
*/
|
|
3172
|
+
zcard(key: string): Promise<number>;
|
|
3173
|
+
/**
|
|
3174
|
+
* Gets rank of member.
|
|
3175
|
+
*/
|
|
3176
|
+
zrank(key: string, member: string): Promise<number | null>;
|
|
3177
|
+
/**
|
|
3178
|
+
* Increments score of member.
|
|
3179
|
+
*/
|
|
3180
|
+
zincrby(key: string, increment: number, member: string): Promise<string>;
|
|
3181
|
+
/**
|
|
3182
|
+
* Scans sorted set members.
|
|
3183
|
+
*/
|
|
3184
|
+
zscan(key: string, cursor: number, options?: IScanOptions): Promise<[string, string[]]>;
|
|
3185
|
+
/**
|
|
3186
|
+
* Publishes message to channel.
|
|
3187
|
+
*/
|
|
3188
|
+
publish(channel: string, message: string): Promise<number>;
|
|
3189
|
+
/**
|
|
3190
|
+
* Subscribes to channels.
|
|
3191
|
+
*/
|
|
3192
|
+
subscribe(...channels: string[]): Promise<void>;
|
|
3193
|
+
/**
|
|
3194
|
+
* Unsubscribes from channels.
|
|
3195
|
+
*/
|
|
3196
|
+
unsubscribe(...channels: string[]): Promise<void>;
|
|
3197
|
+
/**
|
|
3198
|
+
* Subscribes to channels by pattern.
|
|
3199
|
+
*/
|
|
3200
|
+
psubscribe(...patterns: string[]): Promise<void>;
|
|
3201
|
+
/**
|
|
3202
|
+
* Unsubscribes from channel patterns.
|
|
3203
|
+
*/
|
|
3204
|
+
punsubscribe(...patterns: string[]): Promise<void>;
|
|
3205
|
+
/**
|
|
3206
|
+
* Creates a pipeline for batching commands.
|
|
3207
|
+
*/
|
|
3208
|
+
pipeline(): Promise<IPipeline>;
|
|
3209
|
+
/**
|
|
3210
|
+
* Creates a multi/exec transaction.
|
|
3211
|
+
*/
|
|
3212
|
+
multi(): Promise<IMulti>;
|
|
3213
|
+
/**
|
|
3214
|
+
* Evaluates Lua script.
|
|
3215
|
+
*/
|
|
3216
|
+
eval(script: string, keys: string[], args: Array<string | number>): Promise<unknown>;
|
|
3217
|
+
/**
|
|
3218
|
+
* Evaluates Lua script by SHA.
|
|
3219
|
+
*/
|
|
3220
|
+
evalsha(sha: string, keys: string[], args: Array<string | number>): Promise<unknown>;
|
|
3221
|
+
/**
|
|
3222
|
+
* Loads Lua script and returns SHA.
|
|
3223
|
+
*/
|
|
3224
|
+
scriptLoad(script: string): Promise<string>;
|
|
3225
|
+
/**
|
|
3226
|
+
* Checks if scripts exist.
|
|
3227
|
+
*/
|
|
3228
|
+
scriptExists(...shas: string[]): Promise<number[]>;
|
|
3229
|
+
/**
|
|
3230
|
+
* Flushes all scripts from cache.
|
|
3231
|
+
*/
|
|
3232
|
+
scriptFlush(): Promise<'OK'>;
|
|
3233
|
+
/**
|
|
3234
|
+
* Flushes all keys from current database.
|
|
3235
|
+
*/
|
|
3236
|
+
flushdb(): Promise<'OK'>;
|
|
3237
|
+
/**
|
|
3238
|
+
* Flushes all keys from all databases.
|
|
3239
|
+
*/
|
|
3240
|
+
flushall(): Promise<'OK'>;
|
|
3241
|
+
/**
|
|
3242
|
+
* Gets server info.
|
|
3243
|
+
*/
|
|
3244
|
+
info(section?: string): Promise<string>;
|
|
3245
|
+
/**
|
|
3246
|
+
* Gets database size (number of keys).
|
|
3247
|
+
*/
|
|
3248
|
+
dbsize(): Promise<number>;
|
|
3249
|
+
/**
|
|
3250
|
+
* NestJS lifecycle hook - cleanup on module destroy.
|
|
3251
|
+
*/
|
|
3252
|
+
onModuleDestroy(): Promise<void>;
|
|
3253
|
+
}
|
|
3254
|
+
|
|
3255
|
+
/**
|
|
3256
|
+
* Injects Redis driver by name.
|
|
3257
|
+
*
|
|
3258
|
+
* Use this decorator to inject a specific Redis client into your service.
|
|
3259
|
+
* If no name is provided, the default client is injected.
|
|
3260
|
+
*
|
|
3261
|
+
* @param name - Client name (default: 'default')
|
|
3262
|
+
* @returns Property decorator
|
|
3263
|
+
*
|
|
3264
|
+
* @example
|
|
3265
|
+
* ```typescript
|
|
3266
|
+
* @Injectable()
|
|
3267
|
+
* export class CacheService {
|
|
3268
|
+
* constructor(
|
|
3269
|
+
* @InjectRedis() private readonly redis: IRedisDriver,
|
|
3270
|
+
* @InjectRedis('sessions') private readonly sessions: IRedisDriver,
|
|
3271
|
+
* ) {}
|
|
3272
|
+
*
|
|
3273
|
+
* async cacheUser(id: string, data: User): Promise<void> {
|
|
3274
|
+
* await this.redis.set(`user:${id}`, JSON.stringify(data), { ex: 3600 });
|
|
3275
|
+
* }
|
|
3276
|
+
*
|
|
3277
|
+
* async getSession(id: string): Promise<string | null> {
|
|
3278
|
+
* return this.sessions.get(`session:${id}`);
|
|
3279
|
+
* }
|
|
3280
|
+
* }
|
|
3281
|
+
* ```
|
|
3282
|
+
*/
|
|
3283
|
+
declare function InjectRedis(name?: string): ParameterDecorator;
|
|
3284
|
+
|
|
3285
|
+
/**
|
|
3286
|
+
* Base Redis driver implementation.
|
|
3287
|
+
*
|
|
3288
|
+
* Provides common functionality for all driver implementations.
|
|
3289
|
+
* Subclasses must implement abstract methods for specific Redis clients.
|
|
3290
|
+
*
|
|
3291
|
+
* Features:
|
|
3292
|
+
* - Event handling
|
|
3293
|
+
* - Connection state management
|
|
3294
|
+
* - Error wrapping
|
|
3295
|
+
* - Optional operation logging
|
|
3296
|
+
*
|
|
3297
|
+
* @abstract
|
|
3298
|
+
*/
|
|
3299
|
+
declare abstract class BaseRedisDriver implements IRedisDriver {
|
|
3300
|
+
protected readonly config: ConnectionConfig;
|
|
3301
|
+
protected readonly eventEmitter: EventEmitter;
|
|
3302
|
+
protected readonly logger: Logger;
|
|
3303
|
+
protected connected: boolean;
|
|
3304
|
+
protected connecting: boolean;
|
|
3305
|
+
protected readonly enableLogging: boolean;
|
|
3306
|
+
constructor(config: ConnectionConfig, options?: {
|
|
3307
|
+
enableLogging?: boolean;
|
|
3308
|
+
});
|
|
3309
|
+
/**
|
|
3310
|
+
* Establishes connection to Redis.
|
|
3311
|
+
* Must set `this.connected = true` on success.
|
|
3312
|
+
*/
|
|
3313
|
+
protected abstract doConnect(): Promise<void>;
|
|
3314
|
+
/**
|
|
3315
|
+
* Closes connection to Redis.
|
|
3316
|
+
* Must set `this.connected = false` on completion.
|
|
3317
|
+
*/
|
|
3318
|
+
protected abstract doDisconnect(): Promise<void>;
|
|
3319
|
+
/**
|
|
3320
|
+
* Executes raw Redis command.
|
|
3321
|
+
* @param command - Command name
|
|
3322
|
+
* @param args - Command arguments
|
|
3323
|
+
*/
|
|
3324
|
+
protected abstract executeCommand(command: string, ...args: unknown[]): Promise<unknown>;
|
|
3325
|
+
/**
|
|
3326
|
+
* Creates pipeline instance.
|
|
3327
|
+
*/
|
|
3328
|
+
protected abstract createPipeline(): IPipeline;
|
|
3329
|
+
/**
|
|
3330
|
+
* Creates multi/exec transaction instance.
|
|
3331
|
+
*/
|
|
3332
|
+
protected abstract createMulti(): IMulti;
|
|
3333
|
+
connect(): Promise<void>;
|
|
3334
|
+
disconnect(): Promise<void>;
|
|
3335
|
+
isConnected(): boolean;
|
|
3336
|
+
ping(message?: string): Promise<string>;
|
|
3337
|
+
select(db: number): Promise<void>;
|
|
3338
|
+
get(key: string): Promise<string | null>;
|
|
3339
|
+
set(key: string, value: string, options?: ISetOptions): Promise<'OK' | null>;
|
|
3340
|
+
mget(...keys: string[]): Promise<Array<string | null>>;
|
|
3341
|
+
mset(data: Record<string, string>): Promise<'OK'>;
|
|
3342
|
+
setnx(key: string, value: string): Promise<number>;
|
|
3343
|
+
setex(key: string, seconds: number, value: string): Promise<'OK'>;
|
|
3344
|
+
getdel(key: string): Promise<string | null>;
|
|
3345
|
+
getex(key: string, options: {
|
|
3346
|
+
ex?: number;
|
|
3347
|
+
px?: number;
|
|
3348
|
+
}): Promise<string | null>;
|
|
3349
|
+
incr(key: string): Promise<number>;
|
|
3350
|
+
incrby(key: string, increment: number): Promise<number>;
|
|
3351
|
+
decr(key: string): Promise<number>;
|
|
3352
|
+
decrby(key: string, decrement: number): Promise<number>;
|
|
3353
|
+
append(key: string, value: string): Promise<number>;
|
|
3354
|
+
strlen(key: string): Promise<number>;
|
|
3355
|
+
incrbyfloat(key: string, increment: number): Promise<string>;
|
|
3356
|
+
getrange(key: string, start: number, end: number): Promise<string>;
|
|
3357
|
+
setrange(key: string, offset: number, value: string): Promise<number>;
|
|
3358
|
+
msetnx(data: Record<string, string>): Promise<number>;
|
|
3359
|
+
del(...keys: string[]): Promise<number>;
|
|
3360
|
+
exists(...keys: string[]): Promise<number>;
|
|
3361
|
+
expire(key: string, seconds: number): Promise<number>;
|
|
3362
|
+
pexpire(key: string, milliseconds: number): Promise<number>;
|
|
3363
|
+
expireat(key: string, timestamp: number): Promise<number>;
|
|
3364
|
+
ttl(key: string): Promise<number>;
|
|
3365
|
+
pttl(key: string): Promise<number>;
|
|
3366
|
+
persist(key: string): Promise<number>;
|
|
3367
|
+
rename(key: string, newKey: string): Promise<'OK'>;
|
|
3368
|
+
renamenx(key: string, newKey: string): Promise<number>;
|
|
3369
|
+
type(key: string): Promise<string>;
|
|
3370
|
+
scan(cursor: number, options?: IScanOptions): Promise<[string, string[]]>;
|
|
3371
|
+
unlink(...keys: string[]): Promise<number>;
|
|
3372
|
+
copy(source: string, destination: string, options?: ICopyOptions): Promise<number>;
|
|
3373
|
+
keys(pattern: string): Promise<string[]>;
|
|
3374
|
+
touch(...keys: string[]): Promise<number>;
|
|
3375
|
+
object(subcommand: 'ENCODING' | 'FREQ' | 'IDLETIME' | 'REFCOUNT', key: string): Promise<string | number | null>;
|
|
3376
|
+
dump(key: string): Promise<string | null>;
|
|
3377
|
+
restore(key: string, ttl: number, serializedValue: string, options?: IRestoreOptions): Promise<'OK'>;
|
|
3378
|
+
time(): Promise<[string, string]>;
|
|
3379
|
+
hget(key: string, field: string): Promise<string | null>;
|
|
3380
|
+
hset(key: string, field: string, value: string): Promise<number>;
|
|
3381
|
+
hmset(key: string, data: Record<string, string>): Promise<'OK'>;
|
|
3382
|
+
hmget(key: string, ...fields: string[]): Promise<Array<string | null>>;
|
|
3383
|
+
hgetall(key: string): Promise<Record<string, string>>;
|
|
3384
|
+
hdel(key: string, ...fields: string[]): Promise<number>;
|
|
3385
|
+
hexists(key: string, field: string): Promise<number>;
|
|
3386
|
+
hkeys(key: string): Promise<string[]>;
|
|
3387
|
+
hvals(key: string): Promise<string[]>;
|
|
3388
|
+
hlen(key: string): Promise<number>;
|
|
3389
|
+
hincrby(key: string, field: string, increment: number): Promise<number>;
|
|
3390
|
+
hscan(key: string, cursor: number, options?: IScanOptions): Promise<[string, string[]]>;
|
|
3391
|
+
hsetnx(key: string, field: string, value: string): Promise<number>;
|
|
3392
|
+
hincrbyfloat(key: string, field: string, increment: number): Promise<string>;
|
|
3393
|
+
hstrlen(key: string, field: string): Promise<number>;
|
|
3394
|
+
hrandfield(key: string, count?: number, withValues?: boolean): Promise<string | string[] | null>;
|
|
3395
|
+
lpush(key: string, ...values: string[]): Promise<number>;
|
|
3396
|
+
rpush(key: string, ...values: string[]): Promise<number>;
|
|
3397
|
+
lpop(key: string): Promise<string | null>;
|
|
3398
|
+
rpop(key: string): Promise<string | null>;
|
|
3399
|
+
llen(key: string): Promise<number>;
|
|
3400
|
+
lrange(key: string, start: number, stop: number): Promise<string[]>;
|
|
3401
|
+
ltrim(key: string, start: number, stop: number): Promise<'OK'>;
|
|
3402
|
+
lindex(key: string, index: number): Promise<string | null>;
|
|
3403
|
+
lset(key: string, index: number, value: string): Promise<'OK'>;
|
|
3404
|
+
linsert(key: string, position: 'BEFORE' | 'AFTER', pivot: string, element: string): Promise<number>;
|
|
3405
|
+
lrem(key: string, count: number, element: string): Promise<number>;
|
|
3406
|
+
lpos(key: string, element: string, options?: ILposOptions): Promise<number | number[] | null>;
|
|
3407
|
+
blpop(keys: string[], timeout: number): Promise<[string, string] | null>;
|
|
3408
|
+
brpop(keys: string[], timeout: number): Promise<[string, string] | null>;
|
|
3409
|
+
lmove(source: string, destination: string, from: 'LEFT' | 'RIGHT', to: 'LEFT' | 'RIGHT'): Promise<string | null>;
|
|
3410
|
+
blmove(source: string, destination: string, from: 'LEFT' | 'RIGHT', to: 'LEFT' | 'RIGHT', timeout: number): Promise<string | null>;
|
|
3411
|
+
sadd(key: string, ...members: string[]): Promise<number>;
|
|
3412
|
+
srem(key: string, ...members: string[]): Promise<number>;
|
|
3413
|
+
smembers(key: string): Promise<string[]>;
|
|
3414
|
+
sismember(key: string, member: string): Promise<number>;
|
|
3415
|
+
scard(key: string): Promise<number>;
|
|
3416
|
+
srandmember(key: string, count?: number): Promise<string | string[] | null>;
|
|
3417
|
+
spop(key: string, count?: number): Promise<string | string[] | null>;
|
|
3418
|
+
sscan(key: string, cursor: number, options?: IScanOptions): Promise<[string, string[]]>;
|
|
3419
|
+
smove(source: string, destination: string, member: string): Promise<number>;
|
|
3420
|
+
sinter(...keys: string[]): Promise<string[]>;
|
|
3421
|
+
sinterstore(destination: string, ...keys: string[]): Promise<number>;
|
|
3422
|
+
sunion(...keys: string[]): Promise<string[]>;
|
|
3423
|
+
sunionstore(destination: string, ...keys: string[]): Promise<number>;
|
|
3424
|
+
sdiff(...keys: string[]): Promise<string[]>;
|
|
3425
|
+
sdiffstore(destination: string, ...keys: string[]): Promise<number>;
|
|
3426
|
+
smismember(key: string, ...members: string[]): Promise<number[]>;
|
|
3427
|
+
zadd(key: string, ...args: Array<number | string>): Promise<number>;
|
|
3428
|
+
zrem(key: string, ...members: string[]): Promise<number>;
|
|
3429
|
+
zrange(key: string, start: number, stop: number, withScores?: boolean): Promise<string[]>;
|
|
3430
|
+
zrangebyscore(key: string, min: number | string, max: number | string, withScores?: boolean): Promise<string[]>;
|
|
3431
|
+
zscore(key: string, member: string): Promise<string | null>;
|
|
3432
|
+
zcard(key: string): Promise<number>;
|
|
3433
|
+
zrank(key: string, member: string): Promise<number | null>;
|
|
3434
|
+
zincrby(key: string, increment: number, member: string): Promise<string>;
|
|
3435
|
+
zscan(key: string, cursor: number, options?: IScanOptions): Promise<[string, string[]]>;
|
|
3436
|
+
zrevrank(key: string, member: string): Promise<number | null>;
|
|
3437
|
+
zcount(key: string, min: number | string, max: number | string): Promise<number>;
|
|
3438
|
+
zlexcount(key: string, min: string, max: string): Promise<number>;
|
|
3439
|
+
zpopmin(key: string, count?: number): Promise<string[]>;
|
|
3440
|
+
zpopmax(key: string, count?: number): Promise<string[]>;
|
|
3441
|
+
bzpopmin(keys: string[], timeout: number): Promise<[string, string, string] | null>;
|
|
3442
|
+
bzpopmax(keys: string[], timeout: number): Promise<[string, string, string] | null>;
|
|
3443
|
+
zunionstore(destination: string, keys: string[], options?: IZStoreOptions): Promise<number>;
|
|
3444
|
+
zinterstore(destination: string, keys: string[], options?: IZStoreOptions): Promise<number>;
|
|
3445
|
+
zmscore(key: string, ...members: string[]): Promise<Array<string | null>>;
|
|
3446
|
+
zrandmember(key: string, count?: number, withScores?: boolean): Promise<string | string[] | null>;
|
|
3447
|
+
zrevrangebyscore(key: string, max: number | string, min: number | string, options?: IZRangeByScoreOptions): Promise<string[]>;
|
|
3448
|
+
publish(channel: string, message: string): Promise<number>;
|
|
3449
|
+
subscribe(...channels: string[]): Promise<void>;
|
|
3450
|
+
unsubscribe(...channels: string[]): Promise<void>;
|
|
3451
|
+
psubscribe(...patterns: string[]): Promise<void>;
|
|
3452
|
+
punsubscribe(...patterns: string[]): Promise<void>;
|
|
3453
|
+
xadd(key: string, id: string, fields: Record<string, string>, options?: IStreamAddOptions): Promise<string>;
|
|
3454
|
+
xread(streams: Array<{
|
|
3455
|
+
key: string;
|
|
3456
|
+
id: string;
|
|
3457
|
+
}>, options?: IStreamReadOptions): Promise<StreamReadResult | null>;
|
|
3458
|
+
xreadgroup(group: string, consumer: string, streams: Array<{
|
|
3459
|
+
key: string;
|
|
3460
|
+
id: string;
|
|
3461
|
+
}>, options?: IStreamReadGroupOptions): Promise<StreamReadResult | null>;
|
|
3462
|
+
xrange(key: string, start: string, end: string, options?: {
|
|
3463
|
+
count?: number;
|
|
3464
|
+
}): Promise<IStreamEntry[]>;
|
|
3465
|
+
xrevrange(key: string, end: string, start: string, options?: {
|
|
3466
|
+
count?: number;
|
|
3467
|
+
}): Promise<IStreamEntry[]>;
|
|
3468
|
+
xlen(key: string): Promise<number>;
|
|
3469
|
+
xinfo(key: string): Promise<IStreamInfo>;
|
|
3470
|
+
xtrim(key: string, maxLen: number, approximate?: boolean): Promise<number>;
|
|
3471
|
+
xgroupCreate(key: string, group: string, id: string, mkstream?: boolean): Promise<'OK'>;
|
|
3472
|
+
xgroupDestroy(key: string, group: string): Promise<number>;
|
|
3473
|
+
xgroupDelConsumer(key: string, group: string, consumer: string): Promise<number>;
|
|
3474
|
+
xgroupSetId(key: string, group: string, id: string): Promise<'OK'>;
|
|
3475
|
+
xack(key: string, group: string, ...ids: string[]): Promise<number>;
|
|
3476
|
+
xpending(key: string, group: string): Promise<IStreamPendingInfo>;
|
|
3477
|
+
xpendingRange(key: string, group: string, start: string, end: string, count: number, consumer?: string): Promise<IStreamPendingEntry[]>;
|
|
3478
|
+
xclaim(key: string, group: string, consumer: string, minIdleTime: number, ...ids: string[]): Promise<IStreamEntry[]>;
|
|
3479
|
+
xdel(key: string, ...ids: string[]): Promise<number>;
|
|
3480
|
+
private parseStreamReadResult;
|
|
3481
|
+
private parseStreamEntries;
|
|
3482
|
+
private parseFieldArray;
|
|
3483
|
+
private parseIStreamInfo;
|
|
3484
|
+
private parseIStreamPendingInfo;
|
|
3485
|
+
private parseStreamPendingEntries;
|
|
3486
|
+
pipeline(): IPipeline;
|
|
3487
|
+
multi(): IMulti;
|
|
3488
|
+
/** Registry mapping SHA → script source for NOSCRIPT fallback */
|
|
3489
|
+
private readonly scriptRegistry;
|
|
3490
|
+
eval(script: string, keys: string[], args: Array<string | number>): Promise<unknown>;
|
|
3491
|
+
evalsha(sha: string, keys: string[], args: Array<string | number>): Promise<unknown>;
|
|
3492
|
+
scriptLoad(script: string): Promise<string>;
|
|
3493
|
+
private isNoscriptError;
|
|
3494
|
+
scriptExists(...shas: string[]): Promise<number[]>;
|
|
3495
|
+
scriptFlush(): Promise<'OK'>;
|
|
3496
|
+
pfadd(key: string, ...elements: string[]): Promise<number>;
|
|
3497
|
+
pfcount(...keys: string[]): Promise<number>;
|
|
3498
|
+
pfmerge(destination: string, ...sources: string[]): Promise<'OK'>;
|
|
3499
|
+
geoadd(key: string, ...members: Array<number | string>): Promise<number>;
|
|
3500
|
+
geodist(key: string, member1: string, member2: string, unit?: GeoUnit): Promise<string | null>;
|
|
3501
|
+
geohash(key: string, ...members: string[]): Promise<Array<string | null>>;
|
|
3502
|
+
geopos(key: string, ...members: string[]): Promise<Array<[string, string] | null>>;
|
|
3503
|
+
geosearch(key: string, options: IGeoSearchOptions): Promise<Array<string | IGeoSearchResult>>;
|
|
3504
|
+
geosearchstore(destination: string, source: string, options: IGeoSearchOptions & {
|
|
3505
|
+
storedist?: boolean;
|
|
3506
|
+
}): Promise<number>;
|
|
3507
|
+
private parseIGeoSearchResult;
|
|
3508
|
+
setbit(key: string, offset: number, value: 0 | 1): Promise<number>;
|
|
3509
|
+
getbit(key: string, offset: number): Promise<number>;
|
|
3510
|
+
bitcount(key: string, start?: number, end?: number, mode?: 'BYTE' | 'BIT'): Promise<number>;
|
|
3511
|
+
bitop(operation: 'AND' | 'OR' | 'XOR' | 'NOT', destKey: string, ...keys: string[]): Promise<number>;
|
|
3512
|
+
bitpos(key: string, bit: 0 | 1, start?: number, end?: number, mode?: 'BYTE' | 'BIT'): Promise<number>;
|
|
3513
|
+
flushdb(): Promise<'OK'>;
|
|
3514
|
+
flushall(): Promise<'OK'>;
|
|
3515
|
+
info(section?: string): Promise<string>;
|
|
3516
|
+
dbsize(): Promise<number>;
|
|
3517
|
+
cluster(subcommand: string, ...args: Array<string | number>): Promise<unknown>;
|
|
3518
|
+
sentinel(subcommand: string, ...args: Array<string | number>): Promise<unknown>;
|
|
3519
|
+
on(event: DriverEvent, handler: DriverEventHandler): void;
|
|
3520
|
+
once(event: DriverEvent, handler: DriverEventHandler): void;
|
|
3521
|
+
off(event: DriverEvent, handler: DriverEventHandler): void;
|
|
3522
|
+
removeAllListeners(event?: DriverEvent): void;
|
|
3523
|
+
/**
|
|
3524
|
+
* Asserts that driver is connected.
|
|
3525
|
+
* @throws DriverError if not connected
|
|
3526
|
+
*/
|
|
3527
|
+
protected assertConnected(): void;
|
|
3528
|
+
/**
|
|
3529
|
+
* Emits driver event.
|
|
3530
|
+
*/
|
|
3531
|
+
protected emit(event: DriverEvent, data?: unknown): void;
|
|
3532
|
+
/**
|
|
3533
|
+
* Logs message if logging is enabled.
|
|
3534
|
+
*/
|
|
3535
|
+
protected log(message: string, data?: unknown): void;
|
|
3536
|
+
/**
|
|
3537
|
+
* Wraps execution with timeout.
|
|
3538
|
+
*/
|
|
3539
|
+
protected withTimeout<T>(promise: Promise<T>, timeoutMs: number, operation: string): Promise<T>;
|
|
3540
|
+
}
|
|
3541
|
+
|
|
3542
|
+
/**
|
|
3543
|
+
* IoRedis driver adapter.
|
|
3544
|
+
*
|
|
3545
|
+
* Implements IRedisDriver using ioredis library.
|
|
3546
|
+
* Supports single instance, cluster, and sentinel configurations.
|
|
3547
|
+
*
|
|
3548
|
+
* @example
|
|
3549
|
+
* ```typescript
|
|
3550
|
+
* const driver = new IoRedisAdapter({
|
|
3551
|
+
* host: 'localhost',
|
|
3552
|
+
* port: 6379,
|
|
3553
|
+
* });
|
|
3554
|
+
* await driver.connect();
|
|
3555
|
+
* ```
|
|
3556
|
+
*/
|
|
3557
|
+
declare class IoRedisAdapter extends BaseRedisDriver {
|
|
3558
|
+
private client;
|
|
3559
|
+
constructor(config: ConnectionConfig, options?: {
|
|
3560
|
+
enableLogging?: boolean;
|
|
3561
|
+
});
|
|
3562
|
+
protected doConnect(): Promise<void>;
|
|
3563
|
+
protected doDisconnect(): Promise<void>;
|
|
3564
|
+
protected executeCommand(command: string, ...args: unknown[]): Promise<unknown>;
|
|
3565
|
+
protected createPipeline(): IPipeline;
|
|
3566
|
+
protected createMulti(): IMulti;
|
|
3567
|
+
private createSingleClient;
|
|
3568
|
+
private createClusterClient;
|
|
3569
|
+
private createSentinelClient;
|
|
3570
|
+
private setupEventHandlers;
|
|
3571
|
+
/**
|
|
3572
|
+
* Gets underlying ioredis client.
|
|
3573
|
+
* For advanced usage only.
|
|
3574
|
+
*/
|
|
3575
|
+
getClient(): Redis | Cluster | null;
|
|
3576
|
+
}
|
|
3577
|
+
|
|
3578
|
+
/**
|
|
3579
|
+
* Union type for all supported node-redis client types.
|
|
3580
|
+
*/
|
|
3581
|
+
type NodeRedisClient = RedisClientType | RedisClusterType | RedisSentinelType;
|
|
3582
|
+
/**
|
|
3583
|
+
* Node-Redis driver adapter.
|
|
3584
|
+
*
|
|
3585
|
+
* Implements IRedisDriver using redis (node-redis v4+) library.
|
|
3586
|
+
* Supports single instance, cluster, and sentinel configurations.
|
|
3587
|
+
*
|
|
3588
|
+
* @example
|
|
3589
|
+
* ```typescript
|
|
3590
|
+
* // Single instance
|
|
3591
|
+
* const driver = new NodeRedisAdapter({
|
|
3592
|
+
* type: 'single',
|
|
3593
|
+
* host: 'localhost',
|
|
3594
|
+
* port: 6379,
|
|
3595
|
+
* });
|
|
3596
|
+
*
|
|
3597
|
+
* // Cluster
|
|
3598
|
+
* const clusterDriver = new NodeRedisAdapter({
|
|
3599
|
+
* type: 'cluster',
|
|
3600
|
+
* nodes: [{ host: 'node1', port: 7000 }],
|
|
3601
|
+
* });
|
|
3602
|
+
*
|
|
3603
|
+
* // Sentinel
|
|
3604
|
+
* const sentinelDriver = new NodeRedisAdapter({
|
|
3605
|
+
* type: 'sentinel',
|
|
3606
|
+
* sentinels: [{ host: 'sentinel1', port: 26379 }],
|
|
3607
|
+
* name: 'mymaster',
|
|
3608
|
+
* });
|
|
3609
|
+
*
|
|
3610
|
+
* await driver.connect();
|
|
3611
|
+
* ```
|
|
3612
|
+
*/
|
|
3613
|
+
declare class NodeRedisAdapter extends BaseRedisDriver {
|
|
3614
|
+
private client;
|
|
3615
|
+
private isSentinel;
|
|
3616
|
+
private isCluster;
|
|
3617
|
+
private readonly keyPrefix;
|
|
3618
|
+
constructor(config: ConnectionConfig, options?: {
|
|
3619
|
+
enableLogging?: boolean;
|
|
3620
|
+
});
|
|
3621
|
+
protected doConnect(): Promise<void>;
|
|
3622
|
+
protected doDisconnect(): Promise<void>;
|
|
3623
|
+
protected executeCommand(command: string, ...args: unknown[]): Promise<unknown>;
|
|
3624
|
+
protected createPipeline(): IPipeline;
|
|
3625
|
+
protected createMulti(): IMulti;
|
|
3626
|
+
/**
|
|
3627
|
+
* Override hgetall to convert array response to object.
|
|
3628
|
+
* Node-redis sendCommand returns ['field1', 'value1', 'field2', 'value2']
|
|
3629
|
+
* but we need { field1: 'value1', field2: 'value2' }
|
|
3630
|
+
*/
|
|
3631
|
+
hgetall(key: string): Promise<Record<string, string>>;
|
|
3632
|
+
/**
|
|
3633
|
+
* Override scan to normalize cursor response.
|
|
3634
|
+
* Node-redis sendCommand returns [cursor, [keys...]]
|
|
3635
|
+
*/
|
|
3636
|
+
scan(cursor: number, options?: {
|
|
3637
|
+
match?: string;
|
|
3638
|
+
count?: number;
|
|
3639
|
+
}): Promise<[string, string[]]>;
|
|
3640
|
+
/**
|
|
3641
|
+
* Override hscan to normalize cursor response.
|
|
3642
|
+
*/
|
|
3643
|
+
hscan(key: string, cursor: number, options?: {
|
|
3644
|
+
match?: string;
|
|
3645
|
+
count?: number;
|
|
3646
|
+
}): Promise<[string, string[]]>;
|
|
3647
|
+
/**
|
|
3648
|
+
* Override sscan to normalize cursor response.
|
|
3649
|
+
*/
|
|
3650
|
+
sscan(key: string, cursor: number, options?: {
|
|
3651
|
+
match?: string;
|
|
3652
|
+
count?: number;
|
|
3653
|
+
}): Promise<[string, string[]]>;
|
|
3654
|
+
/**
|
|
3655
|
+
* Override zscan to normalize cursor response.
|
|
3656
|
+
*/
|
|
3657
|
+
zscan(key: string, cursor: number, options?: {
|
|
3658
|
+
match?: string;
|
|
3659
|
+
count?: number;
|
|
3660
|
+
}): Promise<[string, string[]]>;
|
|
3661
|
+
/**
|
|
3662
|
+
* Override info to return string.
|
|
3663
|
+
*/
|
|
3664
|
+
info(section?: string): Promise<string>;
|
|
3665
|
+
private createSingleClient;
|
|
3666
|
+
private createClusterClient;
|
|
3667
|
+
/**
|
|
3668
|
+
* Creates a Redis Sentinel client using the proper createSentinel API.
|
|
3669
|
+
* Returns already connected sentinel instance.
|
|
3670
|
+
*
|
|
3671
|
+
* NOTE: node-redis does not support natMap/nodeAddressMap for Sentinel.
|
|
3672
|
+
* For Docker/NAT environments, use ioredis driver which supports sentinelOptions.natMap.
|
|
3673
|
+
*/
|
|
3674
|
+
private createSentinelClient;
|
|
3675
|
+
/**
|
|
3676
|
+
* Safely disconnect the client, ignoring errors.
|
|
3677
|
+
*/
|
|
3678
|
+
private safeDisconnect;
|
|
3679
|
+
/**
|
|
3680
|
+
* Default reconnection strategy: exponential backoff with max 30s delay.
|
|
3681
|
+
* Returns a function that calculates delay based on retry count.
|
|
3682
|
+
*/
|
|
3683
|
+
private getDefaultReconnectStrategy;
|
|
3684
|
+
/**
|
|
3685
|
+
* Get the first key from command arguments for cluster slot routing.
|
|
3686
|
+
* Returns undefined for commands that don't require a key.
|
|
3687
|
+
*/
|
|
3688
|
+
private getFirstKey;
|
|
3689
|
+
/**
|
|
3690
|
+
* Check if a command is readonly (doesn't modify data).
|
|
3691
|
+
* Used for cluster to route reads to replicas if enabled.
|
|
3692
|
+
*/
|
|
3693
|
+
private isReadonlyCommand;
|
|
3694
|
+
/**
|
|
3695
|
+
* Convert arguments to proper types for sendCommand.
|
|
3696
|
+
* sendCommand expects string[] but we need to handle numbers properly.
|
|
3697
|
+
*/
|
|
3698
|
+
private convertArgs;
|
|
3699
|
+
/**
|
|
3700
|
+
* Apply key prefix to key-based commands.
|
|
3701
|
+
* This emulates ioredis keyPrefix functionality.
|
|
3702
|
+
*/
|
|
3703
|
+
private applyKeyPrefix;
|
|
3704
|
+
private setupEventHandlers;
|
|
3705
|
+
/**
|
|
3706
|
+
* Gets underlying node-redis client.
|
|
3707
|
+
* For advanced usage only.
|
|
3708
|
+
*/
|
|
3709
|
+
getClient(): NodeRedisClient | null;
|
|
3710
|
+
/**
|
|
3711
|
+
* Returns true if connected to Redis Sentinel.
|
|
3712
|
+
*/
|
|
3713
|
+
isSentinelMode(): boolean;
|
|
3714
|
+
}
|
|
3715
|
+
|
|
3716
|
+
/**
|
|
3717
|
+
* Driver factory options.
|
|
3718
|
+
*/
|
|
3719
|
+
interface IDriverFactoryOptions {
|
|
3720
|
+
/**
|
|
3721
|
+
* Driver type to create.
|
|
3722
|
+
* @default 'ioredis'
|
|
3723
|
+
*/
|
|
3724
|
+
type?: DriverType;
|
|
3725
|
+
/**
|
|
3726
|
+
* Enable operation logging.
|
|
3727
|
+
* @default false
|
|
3728
|
+
*/
|
|
3729
|
+
enableLogging?: boolean;
|
|
3730
|
+
}
|
|
3731
|
+
/**
|
|
3732
|
+
* Factory for creating Redis drivers.
|
|
3733
|
+
*
|
|
3734
|
+
* Creates driver instances based on configuration.
|
|
3735
|
+
* Drivers are interchangeable - switching between ioredis and node-redis
|
|
3736
|
+
* requires no code changes.
|
|
3737
|
+
*
|
|
3738
|
+
* @example
|
|
3739
|
+
* ```typescript
|
|
3740
|
+
* // Create ioredis driver
|
|
3741
|
+
* const driver = createDriver(
|
|
3742
|
+
* { host: 'localhost', port: 6379 },
|
|
3743
|
+
* { type: 'ioredis' }
|
|
3744
|
+
* );
|
|
3745
|
+
*
|
|
3746
|
+
* // Switch to node-redis (same interface)
|
|
3747
|
+
* const driver = createDriver(
|
|
3748
|
+
* { host: 'localhost', port: 6379 },
|
|
3749
|
+
* { type: 'node-redis' }
|
|
3750
|
+
* );
|
|
3751
|
+
* ```
|
|
3752
|
+
*/
|
|
3753
|
+
declare function createDriver(config: ConnectionConfig, options?: IDriverFactoryOptions): IRedisDriver;
|
|
3754
|
+
/**
|
|
3755
|
+
* Driver factory class for dependency injection.
|
|
3756
|
+
*
|
|
3757
|
+
* @example
|
|
3758
|
+
* ```typescript
|
|
3759
|
+
* @Module({
|
|
3760
|
+
* providers: [
|
|
3761
|
+
* {
|
|
3762
|
+
* provide: DRIVER_FACTORY,
|
|
3763
|
+
* useClass: DriverFactory,
|
|
3764
|
+
* },
|
|
3765
|
+
* ],
|
|
3766
|
+
* })
|
|
3767
|
+
* export class MyModule {}
|
|
3768
|
+
* ```
|
|
3769
|
+
*/
|
|
3770
|
+
declare class DriverFactory {
|
|
3771
|
+
/**
|
|
3772
|
+
* Creates a driver instance.
|
|
3773
|
+
*/
|
|
3774
|
+
create(config: ConnectionConfig, options?: IDriverFactoryOptions): IRedisDriver;
|
|
3775
|
+
/**
|
|
3776
|
+
* Gets supported driver types.
|
|
3777
|
+
*/
|
|
3778
|
+
getSupportedTypes(): DriverType[];
|
|
3779
|
+
/**
|
|
3780
|
+
* Checks if driver type is supported.
|
|
3781
|
+
*/
|
|
3782
|
+
isSupported(type: string): type is DriverType;
|
|
3783
|
+
/**
|
|
3784
|
+
* Gets default driver type.
|
|
3785
|
+
*/
|
|
3786
|
+
getDefaultType(): DriverType;
|
|
3787
|
+
}
|
|
3788
|
+
/**
|
|
3789
|
+
* Creates multiple drivers from configurations.
|
|
3790
|
+
*
|
|
3791
|
+
* @example
|
|
3792
|
+
* ```typescript
|
|
3793
|
+
* const drivers = createDrivers({
|
|
3794
|
+
* default: { host: 'localhost', port: 6379 },
|
|
3795
|
+
* cache: { host: 'cache.local', port: 6379 },
|
|
3796
|
+
* });
|
|
3797
|
+
* ```
|
|
3798
|
+
*/
|
|
3799
|
+
declare function createDrivers(configs: Record<string, ConnectionConfig>, options?: IDriverFactoryOptions): Record<string, IRedisDriver>;
|
|
3800
|
+
/**
|
|
3801
|
+
* Driver type detection helper.
|
|
3802
|
+
* Attempts to detect available driver library.
|
|
3803
|
+
*/
|
|
3804
|
+
declare function detectAvailableDriver(): DriverType | null;
|
|
3805
|
+
/**
|
|
3806
|
+
* Gets recommended driver type based on environment.
|
|
3807
|
+
*/
|
|
3808
|
+
declare function getRecommendedDriver(): DriverType;
|
|
3809
|
+
|
|
3810
|
+
/**
|
|
3811
|
+
* Manages plugin lifecycle hooks and dependency ordering.
|
|
3812
|
+
*
|
|
3813
|
+
* Calls `onRegister()` and `onModuleInit()` on all plugins during
|
|
3814
|
+
* NestJS module initialization, and `onModuleDestroy()` during shutdown.
|
|
3815
|
+
* Plugins with `dependencies` are initialized in topological order.
|
|
3816
|
+
*/
|
|
3817
|
+
declare class PluginRegistryService implements OnModuleInit, OnModuleDestroy {
|
|
3818
|
+
private readonly plugins;
|
|
3819
|
+
private readonly clientManager;
|
|
3820
|
+
private readonly options;
|
|
3821
|
+
private readonly moduleRef;
|
|
3822
|
+
private readonly logger;
|
|
3823
|
+
constructor(plugins: IRedisXPlugin[], clientManager: RedisClientManager, options: IRedisModuleOptions, moduleRef: ModuleRef);
|
|
3824
|
+
onModuleInit(): Promise<void>;
|
|
3825
|
+
onModuleDestroy(): Promise<void>;
|
|
3826
|
+
private createContext;
|
|
3827
|
+
/**
|
|
3828
|
+
* Topological sort of plugins by dependencies (Kahn's algorithm).
|
|
3829
|
+
* Plugins without dependencies maintain their original order.
|
|
3830
|
+
* Throws on circular dependencies.
|
|
3831
|
+
*/
|
|
3832
|
+
sortByDependencies(plugins: IRedisXPlugin[]): IRedisXPlugin[];
|
|
3833
|
+
}
|
|
3834
|
+
|
|
3835
|
+
/**
|
|
3836
|
+
* All possible error codes in NestJS RedisX.
|
|
3837
|
+
* Organized by domain for easier categorization and handling.
|
|
3838
|
+
*
|
|
3839
|
+
* Naming convention: {DOMAIN}_{SPECIFIC_ERROR}
|
|
3840
|
+
*
|
|
3841
|
+
* Domains:
|
|
3842
|
+
* - CONN/DRIVER: Connection and networking errors
|
|
3843
|
+
* - OP: Redis operation errors
|
|
3844
|
+
* - CFG/CONFIG: Configuration and validation errors
|
|
3845
|
+
* - LOCK: Distributed lock errors
|
|
3846
|
+
* - CACHE: Caching errors
|
|
3847
|
+
* - RATE: Rate limiting errors
|
|
3848
|
+
* - STREAM: Stream processing errors
|
|
3849
|
+
* - PLUGIN: Plugin system errors
|
|
3850
|
+
* - IDEMPOTENCY: Idempotency errors
|
|
3851
|
+
*/
|
|
3852
|
+
declare enum ErrorCode {
|
|
3853
|
+
/** Failed to establish connection to Redis server */
|
|
3854
|
+
CONN_FAILED = "CONN_FAILED",
|
|
3855
|
+
/** Connection attempt timed out */
|
|
3856
|
+
CONN_TIMEOUT = "CONN_TIMEOUT",
|
|
3857
|
+
/** Lost connection to Redis server */
|
|
3858
|
+
CONN_DISCONNECTED = "CONN_DISCONNECTED",
|
|
3859
|
+
/** Connection was refused by Redis server */
|
|
3860
|
+
CONN_REFUSED = "CONN_REFUSED",
|
|
3861
|
+
/** Authentication failed */
|
|
3862
|
+
CONN_AUTH_FAILED = "CONN_AUTH_FAILED",
|
|
3863
|
+
/** TLS/SSL connection error */
|
|
3864
|
+
CONN_TLS_ERROR = "CONN_TLS_ERROR",
|
|
3865
|
+
/** Redis cluster is down or unreachable */
|
|
3866
|
+
CONN_CLUSTER_DOWN = "CONN_CLUSTER_DOWN",
|
|
3867
|
+
/** Redis cluster slot migration in progress */
|
|
3868
|
+
CONN_CLUSTER_MOVED = "CONN_CLUSTER_MOVED",
|
|
3869
|
+
/** Redis cluster ASK redirection */
|
|
3870
|
+
CONN_CLUSTER_ASK = "CONN_CLUSTER_ASK",
|
|
3871
|
+
/** Redis cluster error */
|
|
3872
|
+
CONN_CLUSTER_ERROR = "CONN_CLUSTER_ERROR",
|
|
3873
|
+
/** Sentinel failover in progress */
|
|
3874
|
+
CONN_SENTINEL_FAILOVER = "CONN_SENTINEL_FAILOVER",
|
|
3875
|
+
/** No Sentinel master found */
|
|
3876
|
+
CONN_SENTINEL_NO_MASTER = "CONN_SENTINEL_NO_MASTER",
|
|
3877
|
+
/** Sentinel error */
|
|
3878
|
+
CONN_SENTINEL_ERROR = "CONN_SENTINEL_ERROR",
|
|
3879
|
+
/** Driver not connected */
|
|
3880
|
+
DRIVER_NOT_CONNECTED = "DRIVER_NOT_CONNECTED",
|
|
3881
|
+
/** Maximum connection retries exceeded */
|
|
3882
|
+
CONN_MAX_RETRIES = "CONN_MAX_RETRIES",
|
|
3883
|
+
/** Connection pool exhausted */
|
|
3884
|
+
CONN_POOL_EXHAUSTED = "CONN_POOL_EXHAUSTED",
|
|
3885
|
+
/** Redis operation failed */
|
|
3886
|
+
OP_FAILED = "OP_FAILED",
|
|
3887
|
+
/** Redis operation timed out */
|
|
3888
|
+
OP_TIMEOUT = "OP_TIMEOUT",
|
|
3889
|
+
/** Redis key not found */
|
|
3890
|
+
OP_KEY_NOT_FOUND = "OP_KEY_NOT_FOUND",
|
|
3891
|
+
/** Wrong Redis data type for operation */
|
|
3892
|
+
OP_TYPE_MISMATCH = "OP_TYPE_MISMATCH",
|
|
3893
|
+
/** Redis script execution failed */
|
|
3894
|
+
OP_SCRIPT_ERROR = "OP_SCRIPT_ERROR",
|
|
3895
|
+
/** Redis script timeout */
|
|
3896
|
+
OP_SCRIPT_TIMEOUT = "OP_SCRIPT_TIMEOUT",
|
|
3897
|
+
/** Redis transaction failed */
|
|
3898
|
+
OP_TRANSACTION_FAILED = "OP_TRANSACTION_FAILED",
|
|
3899
|
+
/** Redis pipeline execution failed */
|
|
3900
|
+
OP_PIPELINE_FAILED = "OP_PIPELINE_FAILED",
|
|
3901
|
+
/** Invalid operation arguments */
|
|
3902
|
+
OP_INVALID_ARGS = "OP_INVALID_ARGS",
|
|
3903
|
+
/** Operation not supported by driver */
|
|
3904
|
+
OP_NOT_SUPPORTED = "OP_NOT_SUPPORTED",
|
|
3905
|
+
/** Redis out of memory */
|
|
3906
|
+
OP_OUT_OF_MEMORY = "OP_OUT_OF_MEMORY",
|
|
3907
|
+
/** Redis NOAUTH error - authentication required */
|
|
3908
|
+
OP_NO_AUTH = "OP_NO_AUTH",
|
|
3909
|
+
/** Redis WRONGPASS error - invalid password */
|
|
3910
|
+
OP_WRONG_PASS = "OP_WRONG_PASS",
|
|
3911
|
+
/** Redis READONLY error - can't write to replica */
|
|
3912
|
+
OP_READONLY = "OP_READONLY",
|
|
3913
|
+
/** Redis BUSYKEY error - target key already exists */
|
|
3914
|
+
OP_BUSY_KEY = "OP_BUSY_KEY",
|
|
3915
|
+
/** Operation requires driver to be connected */
|
|
3916
|
+
OP_NOT_CONNECTED = "OP_NOT_CONNECTED",
|
|
3917
|
+
/** Invalid configuration */
|
|
3918
|
+
CFG_INVALID = "CFG_INVALID",
|
|
3919
|
+
/** Missing required configuration */
|
|
3920
|
+
CFG_MISSING_REQUIRED = "CFG_MISSING_REQUIRED",
|
|
3921
|
+
/** Invalid connection type */
|
|
3922
|
+
CFG_INVALID_CONNECTION_TYPE = "CFG_INVALID_CONNECTION_TYPE",
|
|
3923
|
+
/** Invalid host or port */
|
|
3924
|
+
CFG_INVALID_HOST_PORT = "CFG_INVALID_HOST_PORT",
|
|
3925
|
+
/** Invalid database number */
|
|
3926
|
+
CFG_INVALID_DB = "CFG_INVALID_DB",
|
|
3927
|
+
/** Invalid TTL value */
|
|
3928
|
+
CFG_INVALID_TTL = "CFG_INVALID_TTL",
|
|
3929
|
+
/** Invalid timeout value */
|
|
3930
|
+
CFG_INVALID_TIMEOUT = "CFG_INVALID_TIMEOUT",
|
|
3931
|
+
/** Invalid retry configuration */
|
|
3932
|
+
CFG_INVALID_RETRY = "CFG_INVALID_RETRY",
|
|
3933
|
+
/** Validation failed */
|
|
3934
|
+
CFG_VALIDATION_FAILED = "CFG_VALIDATION_FAILED",
|
|
3935
|
+
/** Incompatible configuration options */
|
|
3936
|
+
CFG_INCOMPATIBLE = "CFG_INCOMPATIBLE",
|
|
3937
|
+
/** Driver type not supported */
|
|
3938
|
+
CFG_DRIVER_NOT_SUPPORTED = "CFG_DRIVER_NOT_SUPPORTED",
|
|
3939
|
+
/** Invalid cluster nodes configuration */
|
|
3940
|
+
CFG_INVALID_CLUSTER_NODES = "CFG_INVALID_CLUSTER_NODES",
|
|
3941
|
+
/** Invalid sentinel configuration */
|
|
3942
|
+
CFG_INVALID_SENTINEL = "CFG_INVALID_SENTINEL",
|
|
3943
|
+
/** Invalid TLS configuration */
|
|
3944
|
+
CFG_INVALID_TLS = "CFG_INVALID_TLS",
|
|
3945
|
+
/** Cache key is invalid */
|
|
3946
|
+
CACHE_KEY_INVALID = "CACHE_KEY_INVALID",
|
|
3947
|
+
/** Cache key exceeds maximum length */
|
|
3948
|
+
CACHE_KEY_TOO_LONG = "CACHE_KEY_TOO_LONG",
|
|
3949
|
+
/** Failed to serialize value */
|
|
3950
|
+
CACHE_SERIALIZATION_FAILED = "CACHE_SERIALIZATION_FAILED",
|
|
3951
|
+
/** Failed to deserialize value */
|
|
3952
|
+
CACHE_DESERIALIZATION_FAILED = "CACHE_DESERIALIZATION_FAILED",
|
|
3953
|
+
/** Cache tag index corrupted */
|
|
3954
|
+
CACHE_TAG_INDEX_CORRUPTED = "CACHE_TAG_INDEX_CORRUPTED",
|
|
3955
|
+
/** Cache stampede protection timeout */
|
|
3956
|
+
CACHE_STAMPEDE_TIMEOUT = "CACHE_STAMPEDE_TIMEOUT",
|
|
3957
|
+
/** Cache loader function failed */
|
|
3958
|
+
CACHE_LOADER_FAILED = "CACHE_LOADER_FAILED",
|
|
3959
|
+
/** L1 cache error */
|
|
3960
|
+
CACHE_L1_ERROR = "CACHE_L1_ERROR",
|
|
3961
|
+
/** L2 cache error */
|
|
3962
|
+
CACHE_L2_ERROR = "CACHE_L2_ERROR",
|
|
3963
|
+
/** Cache set operation failed */
|
|
3964
|
+
CACHE_SET_FAILED = "CACHE_SET_FAILED",
|
|
3965
|
+
/** Cache delete operation failed */
|
|
3966
|
+
CACHE_DELETE_FAILED = "CACHE_DELETE_FAILED",
|
|
3967
|
+
/** Cache clear operation failed */
|
|
3968
|
+
CACHE_CLEAR_FAILED = "CACHE_CLEAR_FAILED",
|
|
3969
|
+
/** Cache operation failed */
|
|
3970
|
+
CACHE_OPERATION_FAILED = "CACHE_OPERATION_FAILED",
|
|
3971
|
+
/** Cache operation timeout */
|
|
3972
|
+
CACHE_OPERATION_TIMEOUT = "CACHE_OPERATION_TIMEOUT",
|
|
3973
|
+
/** Tag invalidation failed */
|
|
3974
|
+
CACHE_TAG_INVALIDATION_FAILED = "CACHE_TAG_INVALIDATION_FAILED",
|
|
3975
|
+
/** Failed to acquire lock */
|
|
3976
|
+
LOCK_ACQUISITION_FAILED = "LOCK_ACQUISITION_FAILED",
|
|
3977
|
+
/** Lock acquisition timed out */
|
|
3978
|
+
LOCK_ACQUISITION_TIMEOUT = "LOCK_ACQUISITION_TIMEOUT",
|
|
3979
|
+
/** Failed to extend lock TTL */
|
|
3980
|
+
LOCK_EXTENSION_FAILED = "LOCK_EXTENSION_FAILED",
|
|
3981
|
+
/** Failed to release lock */
|
|
3982
|
+
LOCK_RELEASE_FAILED = "LOCK_RELEASE_FAILED",
|
|
3983
|
+
/** Attempting to release lock not owned by caller */
|
|
3984
|
+
LOCK_NOT_OWNED = "LOCK_NOT_OWNED",
|
|
3985
|
+
/** Lock expired before operation completed */
|
|
3986
|
+
LOCK_EXPIRED = "LOCK_EXPIRED",
|
|
3987
|
+
/** Rate limit exceeded */
|
|
3988
|
+
RATE_LIMIT_EXCEEDED = "RATE_LIMIT_EXCEEDED",
|
|
3989
|
+
/** Rate limit script error */
|
|
3990
|
+
RATE_LIMIT_SCRIPT_ERROR = "RATE_LIMIT_SCRIPT_ERROR",
|
|
3991
|
+
/** Idempotency key is invalid */
|
|
3992
|
+
IDEMPOTENCY_KEY_INVALID = "IDEMPOTENCY_KEY_INVALID",
|
|
3993
|
+
/** Operation already in progress */
|
|
3994
|
+
IDEMPOTENCY_IN_PROGRESS = "IDEMPOTENCY_IN_PROGRESS",
|
|
3995
|
+
/** Previous operation failed */
|
|
3996
|
+
IDEMPOTENCY_PREVIOUS_FAILED = "IDEMPOTENCY_PREVIOUS_FAILED",
|
|
3997
|
+
/** Consumer group operation failed */
|
|
3998
|
+
STREAM_CONSUMER_GROUP_ERROR = "STREAM_CONSUMER_GROUP_ERROR",
|
|
3999
|
+
/** Stream ACK failed */
|
|
4000
|
+
STREAM_ACK_FAILED = "STREAM_ACK_FAILED",
|
|
4001
|
+
/** Stream read failed */
|
|
4002
|
+
STREAM_READ_FAILED = "STREAM_READ_FAILED",
|
|
4003
|
+
/** Plugin is invalid */
|
|
4004
|
+
PLUGIN_INVALID = "PLUGIN_INVALID",
|
|
4005
|
+
/** Plugin already registered */
|
|
4006
|
+
PLUGIN_DUPLICATE = "PLUGIN_DUPLICATE",
|
|
4007
|
+
/** Plugin not found */
|
|
4008
|
+
PLUGIN_NOT_FOUND = "PLUGIN_NOT_FOUND",
|
|
4009
|
+
/** Plugin registration failed */
|
|
4010
|
+
PLUGIN_REGISTER_FAILED = "PLUGIN_REGISTER_FAILED",
|
|
4011
|
+
/** Plugin initialization failed */
|
|
4012
|
+
PLUGIN_INIT_FAILED = "PLUGIN_INIT_FAILED",
|
|
4013
|
+
/** Circular plugin dependency */
|
|
4014
|
+
PLUGIN_CIRCULAR_DEPENDENCY = "PLUGIN_CIRCULAR_DEPENDENCY",
|
|
4015
|
+
/** Required plugin dependency missing */
|
|
4016
|
+
PLUGIN_DEPENDENCY_MISSING = "PLUGIN_DEPENDENCY_MISSING",
|
|
4017
|
+
/** Client not found */
|
|
4018
|
+
CLIENT_NOT_FOUND = "CLIENT_NOT_FOUND",
|
|
4019
|
+
/** Client already exists */
|
|
4020
|
+
CLIENT_ALREADY_EXISTS = "CLIENT_ALREADY_EXISTS",
|
|
4021
|
+
/** Service not initialized */
|
|
4022
|
+
NOT_INITIALIZED = "NOT_INITIALIZED",
|
|
4023
|
+
/** Generic operation failed */
|
|
4024
|
+
OPERATION_FAILED = "OPERATION_FAILED",
|
|
4025
|
+
/** Generic operation timeout */
|
|
4026
|
+
OPERATION_TIMEOUT = "OPERATION_TIMEOUT",
|
|
4027
|
+
/** Generic serialization failed */
|
|
4028
|
+
SERIALIZATION_FAILED = "SERIALIZATION_FAILED",
|
|
4029
|
+
/** Generic validation failed */
|
|
4030
|
+
VALIDATION_FAILED = "VALIDATION_FAILED",
|
|
4031
|
+
/** Unknown error */
|
|
4032
|
+
UNKNOWN = "UNKNOWN"
|
|
4033
|
+
}
|
|
4034
|
+
/**
|
|
4035
|
+
* Type guard to check if a string is a valid ErrorCode.
|
|
4036
|
+
*/
|
|
4037
|
+
declare function isErrorCode(value: string): value is ErrorCode;
|
|
4038
|
+
/**
|
|
4039
|
+
* Get error domain from error code.
|
|
4040
|
+
*
|
|
4041
|
+
* @param code - Error code
|
|
4042
|
+
* @returns Domain prefix (e.g., 'CONN', 'OP', 'CFG')
|
|
4043
|
+
*
|
|
4044
|
+
* @example
|
|
4045
|
+
* ```typescript
|
|
4046
|
+
* getErrorDomain(ErrorCode.CONN_FAILED) // 'CONN'
|
|
4047
|
+
* getErrorDomain(ErrorCode.OP_TIMEOUT) // 'OP'
|
|
4048
|
+
* ```
|
|
4049
|
+
*/
|
|
4050
|
+
declare function getErrorDomain(code: ErrorCode): string;
|
|
4051
|
+
/**
|
|
4052
|
+
* Check if error code belongs to a domain.
|
|
4053
|
+
*
|
|
4054
|
+
* @param code - Error code to check
|
|
4055
|
+
* @param domain - Domain to check against
|
|
4056
|
+
* @returns True if code belongs to domain
|
|
4057
|
+
*
|
|
4058
|
+
* @example
|
|
4059
|
+
* ```typescript
|
|
4060
|
+
* isErrorDomain(ErrorCode.CONN_FAILED, 'CONN') // true
|
|
4061
|
+
* isErrorDomain(ErrorCode.OP_TIMEOUT, 'CONN') // false
|
|
4062
|
+
* ```
|
|
4063
|
+
*/
|
|
4064
|
+
declare function isErrorDomain(code: ErrorCode, domain: string): boolean;
|
|
4065
|
+
|
|
4066
|
+
/**
|
|
4067
|
+
* JSON representation of an error.
|
|
4068
|
+
* Used for serialization in logs and API responses.
|
|
4069
|
+
*/
|
|
4070
|
+
interface IErrorJSON {
|
|
4071
|
+
/** Error class name */
|
|
4072
|
+
name: string;
|
|
4073
|
+
/** Human-readable error message */
|
|
4074
|
+
message: string;
|
|
4075
|
+
/** Error code for programmatic handling */
|
|
4076
|
+
code: string;
|
|
4077
|
+
/** ISO timestamp when error occurred */
|
|
4078
|
+
timestamp: string;
|
|
4079
|
+
/** Additional context for debugging */
|
|
4080
|
+
context?: Record<string, unknown>;
|
|
4081
|
+
/** Stack trace */
|
|
4082
|
+
stack?: string;
|
|
4083
|
+
/** Cause error if wrapped */
|
|
4084
|
+
cause?: {
|
|
4085
|
+
name: string;
|
|
4086
|
+
message: string;
|
|
4087
|
+
stack?: string;
|
|
4088
|
+
};
|
|
4089
|
+
}
|
|
4090
|
+
/**
|
|
4091
|
+
* Base error class for all RedisX errors.
|
|
4092
|
+
*
|
|
4093
|
+
* Features:
|
|
4094
|
+
* - Structured error codes for programmatic handling
|
|
4095
|
+
* - Context preservation for debugging
|
|
4096
|
+
* - JSON serialization for logging
|
|
4097
|
+
* - Proper error chaining with cause
|
|
4098
|
+
* - Timestamp tracking
|
|
4099
|
+
*
|
|
4100
|
+
* While this class can be instantiated directly, it's recommended
|
|
4101
|
+
* to use or extend specific error classes for better error handling.
|
|
4102
|
+
*
|
|
4103
|
+
* @example
|
|
4104
|
+
* ```typescript
|
|
4105
|
+
* export class CacheError extends RedisXError {
|
|
4106
|
+
* constructor(message: string, cause?: Error) {
|
|
4107
|
+
* super(message, ErrorCode.CACHE_LOADER_FAILED, cause, {
|
|
4108
|
+
* key: 'user:123',
|
|
4109
|
+
* ttl: 3600,
|
|
4110
|
+
* });
|
|
4111
|
+
* }
|
|
4112
|
+
* }
|
|
4113
|
+
* ```
|
|
4114
|
+
*/
|
|
4115
|
+
declare class RedisXError extends Error {
|
|
4116
|
+
readonly code: ErrorCode;
|
|
4117
|
+
readonly cause?: Error | undefined;
|
|
4118
|
+
readonly context?: Record<string, unknown> | undefined;
|
|
4119
|
+
/**
|
|
4120
|
+
* Timestamp when error was created.
|
|
4121
|
+
*/
|
|
4122
|
+
readonly timestamp: Date;
|
|
4123
|
+
/**
|
|
4124
|
+
* Creates a new RedisXError.
|
|
4125
|
+
*
|
|
4126
|
+
* @param message - Human-readable error message
|
|
4127
|
+
* @param code - Error code for programmatic handling
|
|
4128
|
+
* @param cause - Original error that caused this error
|
|
4129
|
+
* @param context - Additional context for debugging
|
|
4130
|
+
*/
|
|
4131
|
+
constructor(message: string, code: ErrorCode, cause?: Error | undefined, context?: Record<string, unknown> | undefined);
|
|
4132
|
+
/**
|
|
4133
|
+
* Checks if error is of specific code.
|
|
4134
|
+
*
|
|
4135
|
+
* @param code - Error code to check
|
|
4136
|
+
* @returns True if error matches code
|
|
4137
|
+
*
|
|
4138
|
+
* @example
|
|
4139
|
+
* ```typescript
|
|
4140
|
+
* if (error.is(ErrorCode.CONN_FAILED)) {
|
|
4141
|
+
* // Handle connection error
|
|
4142
|
+
* }
|
|
4143
|
+
* ```
|
|
4144
|
+
*/
|
|
4145
|
+
is(code: ErrorCode): boolean;
|
|
4146
|
+
/**
|
|
4147
|
+
* Checks if error is any of specified codes.
|
|
4148
|
+
*
|
|
4149
|
+
* @param codes - Array of error codes to check
|
|
4150
|
+
* @returns True if error matches any code
|
|
4151
|
+
*
|
|
4152
|
+
* @example
|
|
4153
|
+
* ```typescript
|
|
4154
|
+
* if (error.isAnyOf([ErrorCode.LOCK_EXPIRED, ErrorCode.LOCK_NOT_OWNED])) {
|
|
4155
|
+
* // Handle lock error
|
|
4156
|
+
* }
|
|
4157
|
+
* ```
|
|
4158
|
+
*/
|
|
4159
|
+
isAnyOf(codes: ErrorCode[]): boolean;
|
|
4160
|
+
/**
|
|
4161
|
+
* Serializes error to JSON for logging.
|
|
4162
|
+
*
|
|
4163
|
+
* @returns JSON representation of error
|
|
4164
|
+
*
|
|
4165
|
+
* @example
|
|
4166
|
+
* ```typescript
|
|
4167
|
+
* logger.error('Operation failed', error.toJSON());
|
|
4168
|
+
* ```
|
|
4169
|
+
*/
|
|
4170
|
+
toJSON(): IErrorJSON;
|
|
4171
|
+
/**
|
|
4172
|
+
* Creates error string for logging.
|
|
4173
|
+
*
|
|
4174
|
+
* @returns Formatted error string
|
|
4175
|
+
*/
|
|
4176
|
+
toString(): string;
|
|
4177
|
+
/**
|
|
4178
|
+
* Wraps unknown error in RedisXError.
|
|
4179
|
+
*
|
|
4180
|
+
* @param error - Error to wrap
|
|
4181
|
+
* @param code - Error code to assign
|
|
4182
|
+
* @returns RedisXError instance
|
|
4183
|
+
*
|
|
4184
|
+
* @example
|
|
4185
|
+
* ```typescript
|
|
4186
|
+
* try {
|
|
4187
|
+
* await someOperation();
|
|
4188
|
+
* } catch (err) {
|
|
4189
|
+
* throw RedisXError.wrap(err, ErrorCode.CACHE_LOADER_FAILED);
|
|
4190
|
+
* }
|
|
4191
|
+
* ```
|
|
4192
|
+
*/
|
|
4193
|
+
static wrap(error: unknown, code?: ErrorCode): RedisXError;
|
|
4194
|
+
/**
|
|
4195
|
+
* Checks if value is a RedisXError.
|
|
4196
|
+
*
|
|
4197
|
+
* @param error - Value to check
|
|
4198
|
+
* @returns True if value is RedisXError
|
|
4199
|
+
*/
|
|
4200
|
+
static isRedisXError(error: unknown): error is RedisXError;
|
|
4201
|
+
}
|
|
4202
|
+
|
|
4203
|
+
/**
|
|
4204
|
+
* Base class for all connection-related errors.
|
|
4205
|
+
*
|
|
4206
|
+
* Provides common context for connection failures including
|
|
4207
|
+
* host, port, and connection type information.
|
|
4208
|
+
*/
|
|
4209
|
+
declare class RedisConnectionError extends RedisXError {
|
|
4210
|
+
readonly host?: string | undefined;
|
|
4211
|
+
readonly port?: number | undefined;
|
|
4212
|
+
constructor(message: string, code: ErrorCode, host?: string | undefined, port?: number | undefined, cause?: Error, context?: Record<string, unknown>);
|
|
4213
|
+
/**
|
|
4214
|
+
* Creates connection error with default code.
|
|
4215
|
+
*/
|
|
4216
|
+
static create(message: string, host?: string, port?: number, cause?: Error): RedisConnectionError;
|
|
4217
|
+
}
|
|
4218
|
+
/**
|
|
4219
|
+
* Error thrown when connection or operation times out.
|
|
4220
|
+
*
|
|
4221
|
+
* Includes timeout duration and operation details for debugging.
|
|
4222
|
+
*
|
|
4223
|
+
* @example
|
|
4224
|
+
* ```typescript
|
|
4225
|
+
* throw new RedisTimeoutError(
|
|
4226
|
+
* 'Connection',
|
|
4227
|
+
* 5000,
|
|
4228
|
+
* 'localhost',
|
|
4229
|
+
* 6379,
|
|
4230
|
+
* );
|
|
4231
|
+
* ```
|
|
4232
|
+
*/
|
|
4233
|
+
declare class RedisTimeoutError extends RedisConnectionError {
|
|
4234
|
+
readonly operation: string;
|
|
4235
|
+
readonly timeoutMs: number;
|
|
4236
|
+
constructor(operation: string, timeoutMs: number, host?: string, port?: number, cause?: Error);
|
|
4237
|
+
}
|
|
4238
|
+
/**
|
|
4239
|
+
* Error thrown for Redis Cluster-specific failures.
|
|
4240
|
+
*
|
|
4241
|
+
* Handles cluster slot redirections (MOVED, ASK), cluster down states,
|
|
4242
|
+
* and other cluster topology issues.
|
|
4243
|
+
*
|
|
4244
|
+
* @example
|
|
4245
|
+
* ```typescript
|
|
4246
|
+
* // Cluster down
|
|
4247
|
+
* throw new RedisClusterError(
|
|
4248
|
+
* 'Cluster is down',
|
|
4249
|
+
* ErrorCode.CONN_CLUSTER_DOWN,
|
|
4250
|
+
* );
|
|
4251
|
+
*
|
|
4252
|
+
* // Slot migration
|
|
4253
|
+
* throw new RedisClusterError(
|
|
4254
|
+
* 'Key moved to different slot',
|
|
4255
|
+
* ErrorCode.CONN_CLUSTER_MOVED,
|
|
4256
|
+
* undefined,
|
|
4257
|
+
* undefined,
|
|
4258
|
+
* undefined,
|
|
4259
|
+
* { slot: 1234, targetNode: 'node2:7001' },
|
|
4260
|
+
* );
|
|
4261
|
+
* ```
|
|
4262
|
+
*/
|
|
4263
|
+
declare class RedisClusterError extends RedisConnectionError {
|
|
4264
|
+
constructor(message: string, code: ErrorCode, host?: string, port?: number, cause?: Error, context?: Record<string, unknown>);
|
|
4265
|
+
/**
|
|
4266
|
+
* Creates cluster down error.
|
|
4267
|
+
*/
|
|
4268
|
+
static clusterDown(host?: string, port?: number): RedisClusterError;
|
|
4269
|
+
/**
|
|
4270
|
+
* Creates MOVED redirection error.
|
|
4271
|
+
*/
|
|
4272
|
+
static moved(slot: number, targetHost: string, targetPort: number, cause?: Error): RedisClusterError;
|
|
4273
|
+
/**
|
|
4274
|
+
* Creates ASK redirection error.
|
|
4275
|
+
*/
|
|
4276
|
+
static ask(slot: number, targetHost: string, targetPort: number, cause?: Error): RedisClusterError;
|
|
4277
|
+
/**
|
|
4278
|
+
* Creates generic cluster error.
|
|
4279
|
+
*/
|
|
4280
|
+
static generic(message: string, host?: string, port?: number, cause?: Error): RedisClusterError;
|
|
4281
|
+
}
|
|
4282
|
+
/**
|
|
4283
|
+
* Error thrown for Redis Sentinel-specific failures.
|
|
4284
|
+
*
|
|
4285
|
+
* Handles sentinel master discovery, failover events, and sentinel
|
|
4286
|
+
* connectivity issues.
|
|
4287
|
+
*
|
|
4288
|
+
* @example
|
|
4289
|
+
* ```typescript
|
|
4290
|
+
* // No master found
|
|
4291
|
+
* throw RedisSentinelError.noMaster('mymaster', [
|
|
4292
|
+
* { host: 'sentinel1', port: 26379 },
|
|
4293
|
+
* { host: 'sentinel2', port: 26379 },
|
|
4294
|
+
* ]);
|
|
4295
|
+
*
|
|
4296
|
+
* // Failover in progress
|
|
4297
|
+
* throw RedisSentinelError.failover(
|
|
4298
|
+
* 'mymaster',
|
|
4299
|
+
* 'old-master:6379',
|
|
4300
|
+
* 'new-master:6379',
|
|
4301
|
+
* );
|
|
4302
|
+
* ```
|
|
4303
|
+
*/
|
|
4304
|
+
declare class RedisSentinelError extends RedisConnectionError {
|
|
4305
|
+
readonly masterName?: string | undefined;
|
|
4306
|
+
constructor(message: string, code: ErrorCode, masterName?: string | undefined, host?: string, port?: number, cause?: Error, context?: Record<string, unknown>);
|
|
4307
|
+
/**
|
|
4308
|
+
* Creates no master found error.
|
|
4309
|
+
*/
|
|
4310
|
+
static noMaster(masterName: string, sentinels?: Array<{
|
|
4311
|
+
host: string;
|
|
4312
|
+
port: number;
|
|
4313
|
+
}>): RedisSentinelError;
|
|
4314
|
+
/**
|
|
4315
|
+
* Creates sentinel failover error.
|
|
4316
|
+
*/
|
|
4317
|
+
static failover(masterName: string, oldMaster?: string, newMaster?: string): RedisSentinelError;
|
|
4318
|
+
/**
|
|
4319
|
+
* Creates generic sentinel error.
|
|
4320
|
+
*/
|
|
4321
|
+
static generic(message: string, masterName?: string, cause?: Error): RedisSentinelError;
|
|
4322
|
+
}
|
|
4323
|
+
/**
|
|
4324
|
+
* Error thrown when authentication fails.
|
|
4325
|
+
*
|
|
4326
|
+
* @example
|
|
4327
|
+
* ```typescript
|
|
4328
|
+
* throw new RedisAuthError('Invalid password', 'localhost', 6379);
|
|
4329
|
+
* ```
|
|
4330
|
+
*/
|
|
4331
|
+
declare class RedisAuthError extends RedisConnectionError {
|
|
4332
|
+
constructor(message?: string, host?: string, port?: number, cause?: Error);
|
|
4333
|
+
}
|
|
4334
|
+
/**
|
|
4335
|
+
* Error thrown when TLS/SSL connection fails.
|
|
4336
|
+
*
|
|
4337
|
+
* @example
|
|
4338
|
+
* ```typescript
|
|
4339
|
+
* throw new RedisTLSError(
|
|
4340
|
+
* 'Certificate verification failed',
|
|
4341
|
+
* 'secure.redis.example.com',
|
|
4342
|
+
* 6380,
|
|
4343
|
+
* originalError,
|
|
4344
|
+
* );
|
|
4345
|
+
* ```
|
|
4346
|
+
*/
|
|
4347
|
+
declare class RedisTLSError extends RedisConnectionError {
|
|
4348
|
+
constructor(message?: string, host?: string, port?: number, cause?: Error);
|
|
4349
|
+
}
|
|
4350
|
+
/**
|
|
4351
|
+
* Error thrown when maximum connection retries exceeded.
|
|
4352
|
+
*
|
|
4353
|
+
* @example
|
|
4354
|
+
* ```typescript
|
|
4355
|
+
* throw new RedisMaxRetriesError(
|
|
4356
|
+
* 5,
|
|
4357
|
+
* 'localhost',
|
|
4358
|
+
* 6379,
|
|
4359
|
+
* lastError,
|
|
4360
|
+
* );
|
|
4361
|
+
* ```
|
|
4362
|
+
*/
|
|
4363
|
+
declare class RedisMaxRetriesError extends RedisConnectionError {
|
|
4364
|
+
readonly maxRetries: number;
|
|
4365
|
+
constructor(maxRetries: number, host?: string, port?: number, cause?: Error);
|
|
4366
|
+
}
|
|
4367
|
+
/**
|
|
4368
|
+
* Error thrown when connection pool is exhausted.
|
|
4369
|
+
*
|
|
4370
|
+
* @example
|
|
4371
|
+
* ```typescript
|
|
4372
|
+
* throw new RedisPoolExhaustedError(10, 100);
|
|
4373
|
+
* ```
|
|
4374
|
+
*/
|
|
4375
|
+
declare class RedisPoolExhaustedError extends RedisConnectionError {
|
|
4376
|
+
readonly poolSize: number;
|
|
4377
|
+
readonly waitingClients: number;
|
|
4378
|
+
constructor(poolSize: number, waitingClients: number, cause?: Error);
|
|
4379
|
+
}
|
|
4380
|
+
|
|
4381
|
+
/**
|
|
4382
|
+
* Base class for all Redis operation errors.
|
|
4383
|
+
*
|
|
4384
|
+
* Provides common context for operation failures including
|
|
4385
|
+
* command name and arguments.
|
|
4386
|
+
*/
|
|
4387
|
+
declare class RedisOperationError extends RedisXError {
|
|
4388
|
+
readonly command?: string | undefined;
|
|
4389
|
+
constructor(message: string, code: ErrorCode, command?: string | undefined, cause?: Error, context?: Record<string, unknown>);
|
|
4390
|
+
/**
|
|
4391
|
+
* Creates operation error with default code.
|
|
4392
|
+
*/
|
|
4393
|
+
static create(message: string, command?: string, cause?: Error): RedisOperationError;
|
|
4394
|
+
/**
|
|
4395
|
+
* Creates operation error from command and arguments.
|
|
4396
|
+
*/
|
|
4397
|
+
static fromCommand(command: string, args: unknown[], cause?: Error): RedisOperationError;
|
|
4398
|
+
}
|
|
4399
|
+
/**
|
|
4400
|
+
* Error thrown when Redis key is not found.
|
|
4401
|
+
*
|
|
4402
|
+
* Used for operations that require a key to exist.
|
|
4403
|
+
*
|
|
4404
|
+
* @example
|
|
4405
|
+
* ```typescript
|
|
4406
|
+
* const value = await redis.get('user:123');
|
|
4407
|
+
* if (!value) {
|
|
4408
|
+
* throw new RedisKeyNotFoundError('user:123', 'GET');
|
|
4409
|
+
* }
|
|
4410
|
+
* ```
|
|
4411
|
+
*/
|
|
4412
|
+
declare class RedisKeyNotFoundError extends RedisOperationError {
|
|
4413
|
+
readonly key: string;
|
|
4414
|
+
constructor(key: string, command?: string, cause?: Error);
|
|
4415
|
+
}
|
|
4416
|
+
/**
|
|
4417
|
+
* Error thrown when Redis value type doesn't match expected type.
|
|
4418
|
+
*
|
|
4419
|
+
* For example, trying to LPUSH to a string value.
|
|
4420
|
+
*
|
|
4421
|
+
* @example
|
|
4422
|
+
* ```typescript
|
|
4423
|
+
* // Trying to use list command on a string
|
|
4424
|
+
* throw new RedisTypeMismatchError(
|
|
4425
|
+
* 'mykey',
|
|
4426
|
+
* 'list',
|
|
4427
|
+
* 'string',
|
|
4428
|
+
* 'LPUSH',
|
|
4429
|
+
* );
|
|
4430
|
+
* ```
|
|
4431
|
+
*/
|
|
4432
|
+
declare class RedisTypeMismatchError extends RedisOperationError {
|
|
4433
|
+
readonly key: string;
|
|
4434
|
+
readonly expected: string;
|
|
4435
|
+
readonly actual: string;
|
|
4436
|
+
constructor(key: string, expected: string, actual: string, command?: string, cause?: Error);
|
|
4437
|
+
/**
|
|
4438
|
+
* Creates type mismatch from Redis WRONGTYPE error.
|
|
4439
|
+
*/
|
|
4440
|
+
static fromRedisError(key: string, command: string, cause: Error): RedisTypeMismatchError;
|
|
4441
|
+
}
|
|
4442
|
+
/**
|
|
4443
|
+
* Error thrown when Redis Lua script execution fails.
|
|
4444
|
+
*
|
|
4445
|
+
* Includes script SHA and error details for debugging.
|
|
4446
|
+
*
|
|
4447
|
+
* @example
|
|
4448
|
+
* ```typescript
|
|
4449
|
+
* throw new RedisScriptError(
|
|
4450
|
+
* 'Script execution failed: division by zero',
|
|
4451
|
+
* 'abc123...',
|
|
4452
|
+
* originalError,
|
|
4453
|
+
* { line: 42 },
|
|
4454
|
+
* );
|
|
4455
|
+
* ```
|
|
4456
|
+
*/
|
|
4457
|
+
declare class RedisScriptError extends RedisOperationError {
|
|
4458
|
+
readonly scriptSha?: string | undefined;
|
|
4459
|
+
constructor(message: string, scriptSha?: string | undefined, cause?: Error, context?: Record<string, unknown>);
|
|
4460
|
+
/**
|
|
4461
|
+
* Creates script timeout error.
|
|
4462
|
+
*/
|
|
4463
|
+
static timeout(timeoutMs: number, scriptSha?: string): RedisScriptError;
|
|
4464
|
+
/**
|
|
4465
|
+
* Creates script not found error (NOSCRIPT).
|
|
4466
|
+
*/
|
|
4467
|
+
static notFound(scriptSha: string): RedisScriptError;
|
|
4468
|
+
}
|
|
4469
|
+
/**
|
|
4470
|
+
* Error thrown when Redis transaction (MULTI/EXEC) fails.
|
|
4471
|
+
*
|
|
4472
|
+
* @example
|
|
4473
|
+
* ```typescript
|
|
4474
|
+
* throw new RedisTransactionError(
|
|
4475
|
+
* 'Transaction aborted due to WATCH key modification',
|
|
4476
|
+
* originalError,
|
|
4477
|
+
* );
|
|
4478
|
+
* ```
|
|
4479
|
+
*/
|
|
4480
|
+
declare class RedisTransactionError extends RedisOperationError {
|
|
4481
|
+
constructor(message: string, cause?: Error, context?: Record<string, unknown>);
|
|
4482
|
+
/**
|
|
4483
|
+
* Creates transaction aborted error (WATCH failure).
|
|
4484
|
+
*/
|
|
4485
|
+
static aborted(): RedisTransactionError;
|
|
4486
|
+
}
|
|
4487
|
+
/**
|
|
4488
|
+
* Error thrown when Redis pipeline execution fails.
|
|
4489
|
+
*
|
|
4490
|
+
* @example
|
|
4491
|
+
* ```typescript
|
|
4492
|
+
* throw new RedisPipelineError(
|
|
4493
|
+
* 'Pipeline execution failed: 3 of 10 commands failed',
|
|
4494
|
+
* 10,
|
|
4495
|
+
* 3,
|
|
4496
|
+
* originalError,
|
|
4497
|
+
* );
|
|
4498
|
+
* ```
|
|
4499
|
+
*/
|
|
4500
|
+
declare class RedisPipelineError extends RedisOperationError {
|
|
4501
|
+
readonly totalCommands: number;
|
|
4502
|
+
readonly failedCommands: number;
|
|
4503
|
+
constructor(message: string, totalCommands: number, failedCommands: number, cause?: Error);
|
|
4504
|
+
}
|
|
4505
|
+
/**
|
|
4506
|
+
* Error thrown when operation has invalid arguments.
|
|
4507
|
+
*
|
|
4508
|
+
* @example
|
|
4509
|
+
* ```typescript
|
|
4510
|
+
* throw new RedisInvalidArgsError(
|
|
4511
|
+
* 'SET',
|
|
4512
|
+
* 'TTL must be a positive number',
|
|
4513
|
+
* { ttl: -1 },
|
|
4514
|
+
* );
|
|
4515
|
+
* ```
|
|
4516
|
+
*/
|
|
4517
|
+
declare class RedisInvalidArgsError extends RedisOperationError {
|
|
4518
|
+
readonly args?: Record<string, unknown> | undefined;
|
|
4519
|
+
constructor(command: string, reason: string, args?: Record<string, unknown> | undefined);
|
|
4520
|
+
}
|
|
4521
|
+
/**
|
|
4522
|
+
* Error thrown when Redis returns out of memory error.
|
|
4523
|
+
*
|
|
4524
|
+
* @example
|
|
4525
|
+
* ```typescript
|
|
4526
|
+
* throw new RedisOutOfMemoryError('SET', 'user:123');
|
|
4527
|
+
* ```
|
|
4528
|
+
*/
|
|
4529
|
+
declare class RedisOutOfMemoryError extends RedisOperationError {
|
|
4530
|
+
readonly key?: string | undefined;
|
|
4531
|
+
constructor(command: string, key?: string | undefined, cause?: Error);
|
|
4532
|
+
}
|
|
4533
|
+
/**
|
|
4534
|
+
* Error thrown when attempting to write to a read-only replica.
|
|
4535
|
+
*
|
|
4536
|
+
* @example
|
|
4537
|
+
* ```typescript
|
|
4538
|
+
* throw new RedisReadOnlyError('SET', 'user:123');
|
|
4539
|
+
* ```
|
|
4540
|
+
*/
|
|
4541
|
+
declare class RedisReadOnlyError extends RedisOperationError {
|
|
4542
|
+
readonly key?: string | undefined;
|
|
4543
|
+
constructor(command: string, key?: string | undefined, cause?: Error);
|
|
4544
|
+
}
|
|
4545
|
+
/**
|
|
4546
|
+
* Error thrown when operation is not supported by current driver.
|
|
4547
|
+
*
|
|
4548
|
+
* @example
|
|
4549
|
+
* ```typescript
|
|
4550
|
+
* throw new RedisNotSupportedError(
|
|
4551
|
+
* 'GEOSEARCH',
|
|
4552
|
+
* 'Requires Redis 6.2+',
|
|
4553
|
+
* );
|
|
4554
|
+
* ```
|
|
4555
|
+
*/
|
|
4556
|
+
declare class RedisNotSupportedError extends RedisOperationError {
|
|
4557
|
+
readonly reason: string;
|
|
4558
|
+
constructor(command: string, reason: string);
|
|
4559
|
+
}
|
|
4560
|
+
/**
|
|
4561
|
+
* Error thrown when driver is not connected.
|
|
4562
|
+
*
|
|
4563
|
+
* @example
|
|
4564
|
+
* ```typescript
|
|
4565
|
+
* if (!this.isConnected()) {
|
|
4566
|
+
* throw new RedisNotConnectedError('GET');
|
|
4567
|
+
* }
|
|
4568
|
+
* ```
|
|
4569
|
+
*/
|
|
4570
|
+
declare class RedisNotConnectedError extends RedisOperationError {
|
|
4571
|
+
constructor(command?: string);
|
|
4572
|
+
}
|
|
4573
|
+
|
|
4574
|
+
/**
|
|
4575
|
+
* Base class for all configuration errors.
|
|
4576
|
+
*
|
|
4577
|
+
* Thrown during module initialization when configuration is invalid.
|
|
4578
|
+
*/
|
|
4579
|
+
declare class RedisConfigError extends RedisXError {
|
|
4580
|
+
constructor(message: string, code: ErrorCode, cause?: Error, context?: Record<string, unknown>);
|
|
4581
|
+
/**
|
|
4582
|
+
* Creates generic config error.
|
|
4583
|
+
*/
|
|
4584
|
+
static create(message: string, cause?: Error, context?: Record<string, unknown>): RedisConfigError;
|
|
4585
|
+
/**
|
|
4586
|
+
* Creates missing required field error.
|
|
4587
|
+
*/
|
|
4588
|
+
static missingRequired(field: string, parent?: string): RedisConfigError;
|
|
4589
|
+
/**
|
|
4590
|
+
* Creates invalid connection type error.
|
|
4591
|
+
*/
|
|
4592
|
+
static invalidConnectionType(type: string, validTypes: string[]): RedisConfigError;
|
|
4593
|
+
/**
|
|
4594
|
+
* Creates invalid host/port error.
|
|
4595
|
+
*/
|
|
4596
|
+
static invalidHostPort(host?: string, port?: number, reason?: string): RedisConfigError;
|
|
4597
|
+
/**
|
|
4598
|
+
* Creates invalid database number error.
|
|
4599
|
+
*/
|
|
4600
|
+
static invalidDb(db: number, max?: number): RedisConfigError;
|
|
4601
|
+
/**
|
|
4602
|
+
* Creates invalid TTL error.
|
|
4603
|
+
*/
|
|
4604
|
+
static invalidTTL(ttl: number, reason?: string): RedisConfigError;
|
|
4605
|
+
/**
|
|
4606
|
+
* Creates invalid timeout error.
|
|
4607
|
+
*/
|
|
4608
|
+
static invalidTimeout(timeout: number, field: string, reason?: string): RedisConfigError;
|
|
4609
|
+
/**
|
|
4610
|
+
* Creates invalid retry configuration error.
|
|
4611
|
+
*/
|
|
4612
|
+
static invalidRetry(reason: string, context?: Record<string, unknown>): RedisConfigError;
|
|
4613
|
+
/**
|
|
4614
|
+
* Creates incompatible configuration error.
|
|
4615
|
+
*/
|
|
4616
|
+
static incompatible(option1: string, option2: string, reason?: string): RedisConfigError;
|
|
4617
|
+
/**
|
|
4618
|
+
* Creates driver not supported error.
|
|
4619
|
+
*/
|
|
4620
|
+
static driverNotSupported(driver: string, supportedDrivers: string[]): RedisConfigError;
|
|
4621
|
+
/**
|
|
4622
|
+
* Creates invalid cluster nodes error.
|
|
4623
|
+
*/
|
|
4624
|
+
static invalidClusterNodes(reason: string, nodes?: Array<{
|
|
4625
|
+
host: string;
|
|
4626
|
+
port: number;
|
|
4627
|
+
}>): RedisConfigError;
|
|
4628
|
+
/**
|
|
4629
|
+
* Creates invalid sentinel configuration error.
|
|
4630
|
+
*/
|
|
4631
|
+
static invalidSentinel(reason: string, context?: Record<string, unknown>): RedisConfigError;
|
|
4632
|
+
/**
|
|
4633
|
+
* Creates invalid TLS configuration error.
|
|
4634
|
+
*/
|
|
4635
|
+
static invalidTLS(reason: string, context?: Record<string, unknown>): RedisConfigError;
|
|
4636
|
+
}
|
|
4637
|
+
/**
|
|
4638
|
+
* Error thrown when configuration validation fails.
|
|
4639
|
+
*
|
|
4640
|
+
* Used for complex validation rules and schema validation.
|
|
4641
|
+
*
|
|
4642
|
+
* @example
|
|
4643
|
+
* ```typescript
|
|
4644
|
+
* throw new RedisValidationError(
|
|
4645
|
+
* 'clients',
|
|
4646
|
+
* [
|
|
4647
|
+
* { field: 'host', message: 'Host is required' },
|
|
4648
|
+
* { field: 'port', message: 'Port must be between 1 and 65535' },
|
|
4649
|
+
* ],
|
|
4650
|
+
* );
|
|
4651
|
+
* ```
|
|
4652
|
+
*/
|
|
4653
|
+
declare class RedisValidationError extends RedisConfigError {
|
|
4654
|
+
readonly field: string;
|
|
4655
|
+
readonly errors: Array<{
|
|
4656
|
+
field: string;
|
|
4657
|
+
message: string;
|
|
4658
|
+
value?: unknown;
|
|
4659
|
+
}>;
|
|
4660
|
+
constructor(field: string, errors: Array<{
|
|
4661
|
+
field: string;
|
|
4662
|
+
message: string;
|
|
4663
|
+
value?: unknown;
|
|
4664
|
+
}>, cause?: Error);
|
|
4665
|
+
/**
|
|
4666
|
+
* Creates validation error from single field.
|
|
4667
|
+
*/
|
|
4668
|
+
static single(field: string, message: string, value?: unknown): RedisValidationError;
|
|
4669
|
+
/**
|
|
4670
|
+
* Creates validation error from multiple fields.
|
|
4671
|
+
*/
|
|
4672
|
+
static multiple(parent: string, errors: Array<{
|
|
4673
|
+
field: string;
|
|
4674
|
+
message: string;
|
|
4675
|
+
value?: unknown;
|
|
4676
|
+
}>): RedisValidationError;
|
|
4677
|
+
/**
|
|
4678
|
+
* Adds a validation error to the list.
|
|
4679
|
+
*/
|
|
4680
|
+
addError(field: string, message: string, value?: unknown): this;
|
|
4681
|
+
/**
|
|
4682
|
+
* Checks if validation has errors.
|
|
4683
|
+
*/
|
|
4684
|
+
hasErrors(): boolean;
|
|
4685
|
+
/**
|
|
4686
|
+
* Gets all error messages.
|
|
4687
|
+
*/
|
|
4688
|
+
getMessages(): string[];
|
|
4689
|
+
/**
|
|
4690
|
+
* Gets errors for specific field.
|
|
4691
|
+
*/
|
|
4692
|
+
getFieldErrors(field: string): Array<{
|
|
4693
|
+
field: string;
|
|
4694
|
+
message: string;
|
|
4695
|
+
value?: unknown;
|
|
4696
|
+
}>;
|
|
4697
|
+
}
|
|
4698
|
+
/**
|
|
4699
|
+
* Validation error collector for building up multiple validation errors.
|
|
4700
|
+
*
|
|
4701
|
+
* @example
|
|
4702
|
+
* ```typescript
|
|
4703
|
+
* const validator = new ValidationErrorCollector('connectionConfig');
|
|
4704
|
+
*
|
|
4705
|
+
* if (!config.host) {
|
|
4706
|
+
* validator.add('host', 'Host is required');
|
|
4707
|
+
* }
|
|
4708
|
+
*
|
|
4709
|
+
* if (config.port < 1 || config.port > 65535) {
|
|
4710
|
+
* validator.add('port', 'Port must be between 1 and 65535', config.port);
|
|
4711
|
+
* }
|
|
4712
|
+
*
|
|
4713
|
+
* validator.throwIfErrors();
|
|
4714
|
+
* ```
|
|
4715
|
+
*/
|
|
4716
|
+
declare class ValidationErrorCollector {
|
|
4717
|
+
private readonly parent;
|
|
4718
|
+
private errors;
|
|
4719
|
+
constructor(parent: string);
|
|
4720
|
+
/**
|
|
4721
|
+
* Adds a validation error.
|
|
4722
|
+
*/
|
|
4723
|
+
add(field: string, message: string, value?: unknown): this;
|
|
4724
|
+
/**
|
|
4725
|
+
* Checks if there are any errors.
|
|
4726
|
+
*/
|
|
4727
|
+
hasErrors(): boolean;
|
|
4728
|
+
/**
|
|
4729
|
+
* Gets error count.
|
|
4730
|
+
*/
|
|
4731
|
+
count(): number;
|
|
4732
|
+
/**
|
|
4733
|
+
* Throws if there are any errors.
|
|
4734
|
+
*/
|
|
4735
|
+
throwIfErrors(): void;
|
|
4736
|
+
/**
|
|
4737
|
+
* Gets all errors.
|
|
4738
|
+
*/
|
|
4739
|
+
getErrors(): Array<{
|
|
4740
|
+
field: string;
|
|
4741
|
+
message: string;
|
|
4742
|
+
value?: unknown;
|
|
4743
|
+
}>;
|
|
4744
|
+
/**
|
|
4745
|
+
* Clears all errors.
|
|
4746
|
+
*/
|
|
4747
|
+
clear(): void;
|
|
4748
|
+
}
|
|
4749
|
+
|
|
4750
|
+
/**
|
|
4751
|
+
* Driver-specific error classes with simplified constructors.
|
|
4752
|
+
* Used internally by driver adapters (ioredis, node-redis).
|
|
4753
|
+
*/
|
|
4754
|
+
|
|
4755
|
+
/**
|
|
4756
|
+
* Base class for driver-related errors.
|
|
4757
|
+
*/
|
|
4758
|
+
declare class DriverError extends RedisConnectionError {
|
|
4759
|
+
constructor(message: string, code: ErrorCode, cause?: Error, context?: Record<string, unknown>);
|
|
4760
|
+
}
|
|
4761
|
+
/**
|
|
4762
|
+
* Error thrown when connection to Redis fails.
|
|
4763
|
+
*/
|
|
4764
|
+
declare class ConnectionError extends RedisConnectionError {
|
|
4765
|
+
readonly host?: string | undefined;
|
|
4766
|
+
readonly port?: number | undefined;
|
|
4767
|
+
constructor(message: string, cause?: Error, host?: string | undefined, port?: number | undefined);
|
|
4768
|
+
}
|
|
4769
|
+
/**
|
|
4770
|
+
* Error thrown when operation times out.
|
|
4771
|
+
*/
|
|
4772
|
+
declare class TimeoutError extends RedisTimeoutError {
|
|
4773
|
+
constructor(operation: string, timeoutMs: number, cause?: Error);
|
|
4774
|
+
}
|
|
4775
|
+
/**
|
|
4776
|
+
* Error thrown when Redis command fails.
|
|
4777
|
+
*/
|
|
4778
|
+
declare class CommandError extends RedisOperationError {
|
|
4779
|
+
readonly command: string;
|
|
4780
|
+
readonly args: unknown[];
|
|
4781
|
+
constructor(command: string, args: unknown[], cause?: Error);
|
|
4782
|
+
}
|
|
4783
|
+
|
|
4784
|
+
/**
|
|
4785
|
+
* Dependency injection tokens for NestJS RedisX.
|
|
4786
|
+
*/
|
|
4787
|
+
/**
|
|
4788
|
+
* Token for injecting module options.
|
|
4789
|
+
* Used for synchronous and asynchronous configuration.
|
|
4790
|
+
*/
|
|
4791
|
+
declare const REDIS_MODULE_OPTIONS: unique symbol;
|
|
4792
|
+
/**
|
|
4793
|
+
* Token for injecting default Redis client.
|
|
4794
|
+
* Points to the 'default' named client.
|
|
4795
|
+
*/
|
|
4796
|
+
declare const REDIS_CLIENT: unique symbol;
|
|
4797
|
+
/**
|
|
4798
|
+
* Token for injecting Redis clients map.
|
|
4799
|
+
* Contains all registered named clients.
|
|
4800
|
+
*/
|
|
4801
|
+
declare const REDIS_CLIENTS_MAP: unique symbol;
|
|
4802
|
+
/**
|
|
4803
|
+
* Token for injecting client manager.
|
|
4804
|
+
* Manages lifecycle of all Redis clients.
|
|
4805
|
+
*/
|
|
4806
|
+
declare const CLIENT_MANAGER: unique symbol;
|
|
4807
|
+
/**
|
|
4808
|
+
* Token for injecting Redis driver.
|
|
4809
|
+
* Abstracts ioredis/node-redis implementation.
|
|
4810
|
+
*/
|
|
4811
|
+
declare const REDIS_DRIVER: unique symbol;
|
|
4812
|
+
/**
|
|
4813
|
+
* Token for injecting RedisX configuration.
|
|
4814
|
+
* Contains module-level and global configuration.
|
|
4815
|
+
*/
|
|
4816
|
+
declare const REDISX_CONFIG: unique symbol;
|
|
4817
|
+
/**
|
|
4818
|
+
* Token for injecting plugin registry.
|
|
4819
|
+
* Manages plugin lifecycle and dependencies.
|
|
4820
|
+
*/
|
|
4821
|
+
declare const PLUGIN_REGISTRY: unique symbol;
|
|
4822
|
+
/**
|
|
4823
|
+
* Token for injecting registered plugins array.
|
|
4824
|
+
* Used internally by PluginRegistryService.
|
|
4825
|
+
*/
|
|
4826
|
+
declare const REGISTERED_PLUGINS: unique symbol;
|
|
4827
|
+
/**
|
|
4828
|
+
* Token for injecting logger.
|
|
4829
|
+
* Provides structured logging for RedisX.
|
|
4830
|
+
*/
|
|
4831
|
+
declare const REDISX_LOGGER: unique symbol;
|
|
4832
|
+
/**
|
|
4833
|
+
* Creates a token for named Redis client.
|
|
4834
|
+
* @param name - Client name
|
|
4835
|
+
* @returns Injection token
|
|
4836
|
+
*
|
|
4837
|
+
* @example
|
|
4838
|
+
* ```typescript
|
|
4839
|
+
* @Injectable()
|
|
4840
|
+
* export class MyService {
|
|
4841
|
+
* constructor(
|
|
4842
|
+
* @Inject(getClientToken('cache'))
|
|
4843
|
+
* private readonly cacheClient: IRedisClient
|
|
4844
|
+
* ) {}
|
|
4845
|
+
* }
|
|
4846
|
+
* ```
|
|
4847
|
+
*/
|
|
4848
|
+
declare function getClientToken(name: string): symbol;
|
|
4849
|
+
/**
|
|
4850
|
+
* Creates a token for named driver.
|
|
4851
|
+
* @param name - Driver name
|
|
4852
|
+
* @returns Injection token
|
|
4853
|
+
*/
|
|
4854
|
+
declare function getDriverToken(name: string): symbol;
|
|
4855
|
+
/**
|
|
4856
|
+
* Default client name.
|
|
4857
|
+
*/
|
|
4858
|
+
declare const DEFAULT_CLIENT_NAME = "default";
|
|
4859
|
+
/**
|
|
4860
|
+
* Default driver type.
|
|
4861
|
+
*/
|
|
4862
|
+
declare const DEFAULT_DRIVER_TYPE = "ioredis";
|
|
4863
|
+
/**
|
|
4864
|
+
* Module name for logging.
|
|
4865
|
+
*/
|
|
4866
|
+
declare const MODULE_NAME = "RedisXModule";
|
|
4867
|
+
/**
|
|
4868
|
+
* Default connection timeout (ms).
|
|
4869
|
+
*/
|
|
4870
|
+
declare const DEFAULT_CONNECTION_TIMEOUT = 10000;
|
|
4871
|
+
/**
|
|
4872
|
+
* Default command timeout (ms).
|
|
4873
|
+
*/
|
|
4874
|
+
declare const DEFAULT_COMMAND_TIMEOUT = 5000;
|
|
4875
|
+
/**
|
|
4876
|
+
* Default graceful shutdown timeout (ms).
|
|
4877
|
+
*/
|
|
4878
|
+
declare const DEFAULT_GRACEFUL_SHUTDOWN_TIMEOUT = 5000;
|
|
4879
|
+
/**
|
|
4880
|
+
* Token for async clients initialization.
|
|
4881
|
+
* Used internally to ensure clients are created before injection.
|
|
4882
|
+
*/
|
|
4883
|
+
declare const REDIS_CLIENTS_INITIALIZATION: unique symbol;
|
|
4884
|
+
/**
|
|
4885
|
+
* Default health check interval (ms).
|
|
4886
|
+
*/
|
|
4887
|
+
declare const DEFAULT_HEALTH_CHECK_INTERVAL = 30000;
|
|
4888
|
+
|
|
4889
|
+
/**
|
|
4890
|
+
* Shared types for NestJS RedisX.
|
|
4891
|
+
*/
|
|
4892
|
+
/**
|
|
4893
|
+
* Generic async function type.
|
|
4894
|
+
*/
|
|
4895
|
+
type AsyncFunction<TArgs extends unknown[] = [], TReturn = unknown> = (...args: TArgs) => Promise<TReturn>;
|
|
4896
|
+
/**
|
|
4897
|
+
* Nullable type helper.
|
|
4898
|
+
*/
|
|
4899
|
+
type Nullable<T> = T | null;
|
|
4900
|
+
/**
|
|
4901
|
+
* Optional type helper.
|
|
4902
|
+
*/
|
|
4903
|
+
type Optional<T> = T | undefined;
|
|
4904
|
+
/**
|
|
4905
|
+
* Makes all properties optional recursively.
|
|
4906
|
+
*/
|
|
4907
|
+
type DeepPartial<T> = {
|
|
4908
|
+
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
|
|
4909
|
+
};
|
|
4910
|
+
/**
|
|
4911
|
+
* Makes all properties required recursively.
|
|
4912
|
+
*/
|
|
4913
|
+
type DeepRequired<T> = {
|
|
4914
|
+
[P in keyof T]-?: T[P] extends object ? DeepRequired<T[P]> : T[P];
|
|
4915
|
+
};
|
|
4916
|
+
|
|
4917
|
+
export { type AsyncFunction, BaseRedisDriver, CLIENT_MANAGER, CommandError, type ConnectionConfig, ConnectionError, ConnectionStatus, DEFAULT_CLIENT_NAME, DEFAULT_COMMAND_TIMEOUT, DEFAULT_CONNECTION_TIMEOUT, DEFAULT_DRIVER_TYPE, DEFAULT_GRACEFUL_SHUTDOWN_TIMEOUT, DEFAULT_HEALTH_CHECK_INTERVAL, type DeepPartial, type DeepRequired, DriverError, DriverEvent, type DriverEventHandler, DriverFactory, type DriverType, ErrorCode, type GeoUnit, type IBaseConnectionConfig, type IClientHealthStatus, type IClientManager, type IClientMetadata, type IClientStats, type IClusterConnectionConfig, type IConnectionStats, type ICopyOptions, type IDriverFactoryOptions, type IErrorJSON, type IGeoSearchOptions, type IGeoSearchResult, type IGlobalConfig, type IHealthCheckResult, type IHealthStatus, type ILposOptions, type IManagerEventData, type IMulti, type IPipeline, type IPluginContext, type IReconnectionOptions, type IRedisClient, type IRedisClientOptions, type IRedisDriver, type IRedisDriverManager, type IRedisModuleAsyncOptions, type IRedisModuleOptions, type IRedisModuleOptionsFactory, type IRedisXPlugin, type IRestoreOptions, type IScanOptions, type ISentinelConnectionConfig, type ISetOptions, type ISingleConnectionConfig, type IStreamAddOptions, type IStreamEntry, type IStreamInfo, type IStreamPendingEntry, type IStreamPendingInfo, type IStreamReadGroupOptions, type IStreamReadOptions, type ITlsConfig, type IZRangeByScoreOptions, type IZStoreOptions, InjectRedis, IoRedisAdapter, MODULE_NAME, ManagerEvent, type ManagerEventHandler, NodeRedisAdapter, type Nullable, type Optional, PLUGIN_REGISTRY, PluginRegistryService, REDISX_CONFIG, REDISX_LOGGER, REDIS_CLIENT, REDIS_CLIENTS_INITIALIZATION, REDIS_CLIENTS_MAP, REDIS_DRIVER, REDIS_MODULE_OPTIONS, REGISTERED_PLUGINS, RedisAuthError, RedisClientManager, RedisClusterError, RedisConfigError, RedisConnectionError, RedisInvalidArgsError, RedisKeyNotFoundError, RedisMaxRetriesError, RedisModule, RedisNotConnectedError, RedisNotSupportedError, RedisOperationError, RedisOutOfMemoryError, RedisPipelineError, RedisPoolExhaustedError, RedisReadOnlyError, RedisScriptError, RedisSentinelError, RedisService, RedisTLSError, RedisTimeoutError, RedisTransactionError, RedisTypeMismatchError, RedisValidationError, RedisXError, type StreamReadResult, TimeoutError, ValidationErrorCollector, createDriver, createDrivers, detectAvailableDriver, getClientToken, getDriverToken, getErrorDomain, getRecommendedDriver, hasClass, hasExisting, hasFactory, isClusterConnection, isErrorCode, isErrorDomain, isSentinelConnection, isSingleConnection };
|