@nauth-toolkit/storage-redis 0.1.14 → 0.1.18
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/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -1
- package/dist/redis-client.interface.d.ts +63 -0
- package/dist/redis-client.interface.d.ts.map +1 -1
- package/dist/redis-storage.adapter.d.ts +207 -0
- package/dist/redis-storage.adapter.d.ts.map +1 -1
- package/dist/redis-storage.adapter.js +263 -0
- package/dist/redis-storage.adapter.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Redis Storage Adapter Package
|
|
3
|
+
*
|
|
4
|
+
* Provides RedisStorageAdapter for high-performance transient state storage
|
|
5
|
+
* using the `redis` package (node-redis). Supports both single-instance Redis
|
|
6
|
+
* and Redis Cluster for high-availability production deployments.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* import { createClient } from 'redis';
|
|
11
|
+
* import { RedisStorageAdapter } from '@nauth-toolkit/storage-redis';
|
|
12
|
+
*
|
|
13
|
+
* const redisClient = createClient({ url: 'redis://localhost:6379' });
|
|
14
|
+
* await redisClient.connect();
|
|
15
|
+
*
|
|
16
|
+
* AuthModule.forRoot({
|
|
17
|
+
* storageAdapter: new RedisStorageAdapter(redisClient),
|
|
18
|
+
* });
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
1
21
|
export { RedisStorageAdapter } from './redis-storage.adapter';
|
|
2
22
|
export { RedisClientLike } from './redis-client.interface';
|
|
3
23
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,24 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Redis Storage Adapter Package
|
|
4
|
+
*
|
|
5
|
+
* Provides RedisStorageAdapter for high-performance transient state storage
|
|
6
|
+
* using the `redis` package (node-redis). Supports both single-instance Redis
|
|
7
|
+
* and Redis Cluster for high-availability production deployments.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { createClient } from 'redis';
|
|
12
|
+
* import { RedisStorageAdapter } from '@nauth-toolkit/storage-redis';
|
|
13
|
+
*
|
|
14
|
+
* const redisClient = createClient({ url: 'redis://localhost:6379' });
|
|
15
|
+
* await redisClient.connect();
|
|
16
|
+
*
|
|
17
|
+
* AuthModule.forRoot({
|
|
18
|
+
* storageAdapter: new RedisStorageAdapter(redisClient),
|
|
19
|
+
* });
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
2
22
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
23
|
exports.RedisStorageAdapter = void 0;
|
|
4
24
|
var redis_storage_adapter_1 = require("./redis-storage.adapter");
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;GAmBG;;;AAEH,iEAA8D;AAArD,4HAAA,mBAAmB,OAAA"}
|
|
@@ -1,22 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Redis Client Interface
|
|
3
|
+
*
|
|
4
|
+
* Minimal interface for Redis clients from the `redis` package (node-redis).
|
|
5
|
+
* Supports both single-instance Redis clients and Redis Cluster clients.
|
|
6
|
+
*
|
|
7
|
+
* Consumer applications must provide a Redis client instance from the `redis` package.
|
|
8
|
+
* Works with:
|
|
9
|
+
* - `redis` package (node-redis v5+) - single instance
|
|
10
|
+
* - `redis` package (node-redis v5+) - Redis Cluster via createCluster()
|
|
11
|
+
* - Dragonfly (Redis-protocol compatible, works with same client)
|
|
12
|
+
*/
|
|
1
13
|
export interface RedisClientLike {
|
|
14
|
+
/**
|
|
15
|
+
* Get a value by key
|
|
16
|
+
*/
|
|
2
17
|
get(key: string): Promise<string | null>;
|
|
18
|
+
/**
|
|
19
|
+
* Set a key-value pair with optional expiration
|
|
20
|
+
* node-redis supports { EX: seconds, NX: true } options
|
|
21
|
+
*/
|
|
3
22
|
set(key: string, value: string, options?: {
|
|
4
23
|
EX?: number;
|
|
5
24
|
NX?: boolean;
|
|
6
25
|
}): Promise<string | void>;
|
|
26
|
+
/**
|
|
27
|
+
* Delete one or more keys
|
|
28
|
+
*/
|
|
7
29
|
del(key: string): Promise<number>;
|
|
30
|
+
/**
|
|
31
|
+
* Increment a counter
|
|
32
|
+
*/
|
|
8
33
|
incr(key: string): Promise<number>;
|
|
34
|
+
/**
|
|
35
|
+
* Decrement a counter
|
|
36
|
+
*/
|
|
9
37
|
decr(key: string): Promise<number>;
|
|
38
|
+
/**
|
|
39
|
+
* Set expiration time on a key
|
|
40
|
+
* Returns boolean (client may return boolean or number depending on implementation)
|
|
41
|
+
*/
|
|
10
42
|
expire(key: string, seconds: number): Promise<boolean | number>;
|
|
43
|
+
/**
|
|
44
|
+
* Check if a key exists
|
|
45
|
+
* Returns number or boolean depending on client
|
|
46
|
+
*/
|
|
11
47
|
exists(key: string): Promise<number | boolean>;
|
|
48
|
+
/**
|
|
49
|
+
* Get time to live for a key
|
|
50
|
+
*/
|
|
12
51
|
ttl(key: string): Promise<number>;
|
|
52
|
+
/**
|
|
53
|
+
* Get a field value from a hash
|
|
54
|
+
*/
|
|
13
55
|
hget(key: string, field: string): Promise<string | null>;
|
|
56
|
+
/**
|
|
57
|
+
* Set a field value in a hash
|
|
58
|
+
*/
|
|
14
59
|
hset(key: string, field: string, value: string): Promise<number>;
|
|
60
|
+
/**
|
|
61
|
+
* Get all fields and values from a hash
|
|
62
|
+
*/
|
|
15
63
|
hgetall(key: string): Promise<Record<string, string>>;
|
|
64
|
+
/**
|
|
65
|
+
* Delete one or more fields from a hash
|
|
66
|
+
*/
|
|
16
67
|
hdel(key: string, ...fields: string[]): Promise<number>;
|
|
68
|
+
/**
|
|
69
|
+
* Push value to the left of a list
|
|
70
|
+
*/
|
|
17
71
|
lpush(key: string, value: string): Promise<number>;
|
|
72
|
+
/**
|
|
73
|
+
* Get a range of elements from a list
|
|
74
|
+
*/
|
|
18
75
|
lrange(key: string, start: number, stop: number): Promise<string[]>;
|
|
76
|
+
/**
|
|
77
|
+
* Get the length of a list
|
|
78
|
+
*/
|
|
19
79
|
llen(key: string): Promise<number>;
|
|
80
|
+
/**
|
|
81
|
+
* Ping the Redis server
|
|
82
|
+
*/
|
|
20
83
|
ping(): Promise<string>;
|
|
21
84
|
}
|
|
22
85
|
//# sourceMappingURL=redis-client.interface.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redis-client.interface.d.ts","sourceRoot":"","sources":["../src/redis-client.interface.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"redis-client.interface.d.ts","sourceRoot":"","sources":["../src/redis-client.interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAEzC;;;OAGG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,EAAE,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAEjG;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAElC;;OAEG;IACH,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEnC;;OAEG;IACH,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEnC;;;OAGG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,MAAM,CAAC,CAAC;IAEhE;;;OAGG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,CAAC;IAE/C;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAElC;;OAEG;IACH,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAEzD;;OAEG;IACH,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEjE;;OAEG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAEtD;;OAEG;IACH,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAExD;;OAEG;IACH,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEnD;;OAEG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAEpE;;OAEG;IACH,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEnC;;OAEG;IACH,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CACzB"}
|
|
@@ -1,34 +1,241 @@
|
|
|
1
1
|
import { StorageAdapter, LoggerService } from '@nauth-toolkit/core';
|
|
2
|
+
/**
|
|
3
|
+
* Redis Storage Adapter
|
|
4
|
+
*
|
|
5
|
+
* Implements StorageAdapter interface using the `redis` package (node-redis).
|
|
6
|
+
*
|
|
7
|
+
* **Key Features:**
|
|
8
|
+
* - Uses node-redis package (redis)
|
|
9
|
+
* - Supports both single-instance Redis and Redis Cluster
|
|
10
|
+
* - Automatic key prefixing: all keys prefixed with `nauth_` to avoid collisions
|
|
11
|
+
* - Multi-server compatible (shared Redis instance/cluster)
|
|
12
|
+
* - Native TTL support via Redis EXPIRE
|
|
13
|
+
* - High performance for transient state
|
|
14
|
+
* - Production-ready with Redis Cluster support for high-availability deployments
|
|
15
|
+
*
|
|
16
|
+
* **Usage:**
|
|
17
|
+
* ```typescript
|
|
18
|
+
* import { createClient } from 'redis';
|
|
19
|
+
* import { RedisStorageAdapter } from '@nauth-toolkit/storage-redis';
|
|
20
|
+
*
|
|
21
|
+
* const redisClient = createClient({ url: 'redis://localhost:6379' });
|
|
22
|
+
* await redisClient.connect();
|
|
23
|
+
*
|
|
24
|
+
* AuthModule.forRoot({
|
|
25
|
+
* storageAdapter: new RedisStorageAdapter(redisClient),
|
|
26
|
+
* });
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```typescript
|
|
31
|
+
* // Using node-redis (recommended)
|
|
32
|
+
* import { createClient } from 'redis';
|
|
33
|
+
* const client = createClient({ url: 'redis://localhost:6379' });
|
|
34
|
+
* await client.connect();
|
|
35
|
+
* const adapter = new RedisStorageAdapter(client);
|
|
36
|
+
*
|
|
37
|
+
* // Or use the factory function (handles connection automatically)
|
|
38
|
+
* import { createRedisStorageAdapter } from '@nauth-toolkit/nestjs';
|
|
39
|
+
* const adapter = createRedisStorageAdapter('redis://localhost:6379');
|
|
40
|
+
* await adapter.initialize();
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
2
43
|
export declare class RedisStorageAdapter implements StorageAdapter {
|
|
3
44
|
private readonly redisClient;
|
|
4
45
|
private logger?;
|
|
5
46
|
private readonly keyPrefix;
|
|
47
|
+
/**
|
|
48
|
+
* Creates a new RedisStorageAdapter instance
|
|
49
|
+
*
|
|
50
|
+
* @param redisClient - Redis client instance from `redis` package (node-redis)
|
|
51
|
+
* @param logger - Logger service for error and debug logging (optional, will be injected by NestJS if not provided)
|
|
52
|
+
* @throws {NAuthException} If client is missing required methods or is invalid
|
|
53
|
+
*/
|
|
6
54
|
constructor(redisClient: unknown, logger?: LoggerService | undefined);
|
|
55
|
+
/**
|
|
56
|
+
* Validate that the client is a Redis-compatible client
|
|
57
|
+
* Type guard to ensure client implements RedisClientLike interface
|
|
58
|
+
*
|
|
59
|
+
* In node-redis v5+, command methods (get, hget, etc.) are dynamically added
|
|
60
|
+
* and may not be available until after connection. We check for known Redis client
|
|
61
|
+
* indicators instead of individual command methods.
|
|
62
|
+
*
|
|
63
|
+
* @param client - Client instance to validate
|
|
64
|
+
* @throws NAuthException if client doesn't appear to be a Redis client
|
|
65
|
+
*/
|
|
7
66
|
private validateClient;
|
|
67
|
+
/**
|
|
68
|
+
* Set logger instance (called by AuthModule to inject logger after factory creation)
|
|
69
|
+
*
|
|
70
|
+
* @param logger - Logger service instance
|
|
71
|
+
*/
|
|
8
72
|
setLogger(logger: LoggerService): void;
|
|
73
|
+
/**
|
|
74
|
+
* Get prefixed key to avoid collisions with other application keys
|
|
75
|
+
*
|
|
76
|
+
* @param key - Original key
|
|
77
|
+
* @returns Prefixed key
|
|
78
|
+
*/
|
|
9
79
|
private getPrefixedKey;
|
|
80
|
+
/**
|
|
81
|
+
* Initialize the storage adapter
|
|
82
|
+
* Performs health check via PING command
|
|
83
|
+
* Connects the Redis client if not already connected (node-redis v4+)
|
|
84
|
+
*
|
|
85
|
+
* @throws {NAuthException} If Redis connection health check fails or client is invalid
|
|
86
|
+
*/
|
|
10
87
|
initialize(): Promise<void>;
|
|
88
|
+
/**
|
|
89
|
+
* Check if the storage adapter is healthy
|
|
90
|
+
* Uses PING command to verify Redis connectivity
|
|
91
|
+
*
|
|
92
|
+
* @returns True if Redis is accessible
|
|
93
|
+
*/
|
|
11
94
|
isHealthy(): Promise<boolean>;
|
|
95
|
+
/**
|
|
96
|
+
* Get a value by key
|
|
97
|
+
*
|
|
98
|
+
* @param key - The key to retrieve
|
|
99
|
+
* @returns The stored value or null if not found
|
|
100
|
+
*/
|
|
12
101
|
get(key: string): Promise<string | null>;
|
|
102
|
+
/**
|
|
103
|
+
* Set a key-value pair with optional TTL (time to live)
|
|
104
|
+
*
|
|
105
|
+
* @param key - The key to store
|
|
106
|
+
* @param value - The value to store
|
|
107
|
+
* @param ttlSeconds - Time to live in seconds (optional)
|
|
108
|
+
* @param options - Additional options like nx (set if not exists)
|
|
109
|
+
* @returns The value if set successfully, null if nx is true and key already exists
|
|
110
|
+
*/
|
|
13
111
|
set(key: string, value: string, ttlSeconds?: number, options?: {
|
|
14
112
|
nx?: boolean;
|
|
15
113
|
}): Promise<string | null>;
|
|
114
|
+
/**
|
|
115
|
+
* Delete a key from storage
|
|
116
|
+
*
|
|
117
|
+
* @param key - The key to delete
|
|
118
|
+
*/
|
|
16
119
|
del(key: string): Promise<void>;
|
|
120
|
+
/**
|
|
121
|
+
* Check if a key exists
|
|
122
|
+
*
|
|
123
|
+
* @param key - The key to check
|
|
124
|
+
* @returns True if key exists, false otherwise
|
|
125
|
+
*/
|
|
17
126
|
exists(key: string): Promise<boolean>;
|
|
127
|
+
/**
|
|
128
|
+
* Increment a counter stored at key
|
|
129
|
+
* Uses Redis native INCR for atomic operation
|
|
130
|
+
*
|
|
131
|
+
* @param key - The key to increment
|
|
132
|
+
* @param ttlSeconds - Optional TTL in seconds to set when creating a new key (only applied if key doesn't exist)
|
|
133
|
+
* @returns The new value after incrementing
|
|
134
|
+
*/
|
|
18
135
|
incr(key: string, ttlSeconds?: number): Promise<number>;
|
|
136
|
+
/**
|
|
137
|
+
* Decrement a counter stored at key
|
|
138
|
+
* Uses Redis native DECR for atomic operation
|
|
139
|
+
*
|
|
140
|
+
* @param key - The key to decrement
|
|
141
|
+
* @returns The new value after decrementing
|
|
142
|
+
*/
|
|
19
143
|
decr(key: string): Promise<number>;
|
|
144
|
+
/**
|
|
145
|
+
* Set expiration time on an existing key
|
|
146
|
+
*
|
|
147
|
+
* @param key - The key to set expiration on
|
|
148
|
+
* @param ttl - Time to live in seconds
|
|
149
|
+
*/
|
|
20
150
|
expire(key: string, ttl: number): Promise<void>;
|
|
151
|
+
/**
|
|
152
|
+
* Get the time to live (TTL) for a key
|
|
153
|
+
*
|
|
154
|
+
* @param key - The key to check
|
|
155
|
+
* @returns Seconds until expiration, -1 if no expiration, -2 if key doesn't exist
|
|
156
|
+
*/
|
|
21
157
|
ttl(key: string): Promise<number>;
|
|
158
|
+
/**
|
|
159
|
+
* Get a field value from a hash
|
|
160
|
+
*
|
|
161
|
+
* @param key - Hash key
|
|
162
|
+
* @param field - Field name
|
|
163
|
+
* @returns Field value or null if not found
|
|
164
|
+
*/
|
|
22
165
|
hget(key: string, field: string): Promise<string | null>;
|
|
166
|
+
/**
|
|
167
|
+
* Set a field value in a hash
|
|
168
|
+
*
|
|
169
|
+
* @param key - Hash key
|
|
170
|
+
* @param field - Field name
|
|
171
|
+
* @param value - Field value
|
|
172
|
+
*/
|
|
23
173
|
hset(key: string, field: string, value: string): Promise<void>;
|
|
174
|
+
/**
|
|
175
|
+
* Get all fields and values from a hash
|
|
176
|
+
*
|
|
177
|
+
* @param key - Hash key
|
|
178
|
+
* @returns Object with all field-value pairs
|
|
179
|
+
*/
|
|
24
180
|
hgetall(key: string): Promise<Record<string, string>>;
|
|
181
|
+
/**
|
|
182
|
+
* Delete one or more fields from a hash
|
|
183
|
+
*
|
|
184
|
+
* @param key - Hash key
|
|
185
|
+
* @param fields - Field names to delete
|
|
186
|
+
* @returns Number of fields deleted
|
|
187
|
+
*/
|
|
25
188
|
hdel(key: string, ...fields: string[]): Promise<number>;
|
|
189
|
+
/**
|
|
190
|
+
* Push value to the left (beginning) of a list
|
|
191
|
+
*
|
|
192
|
+
* @param key - List key
|
|
193
|
+
* @param value - Value to push
|
|
194
|
+
*/
|
|
26
195
|
lpush(key: string, value: string): Promise<void>;
|
|
196
|
+
/**
|
|
197
|
+
* Get a range of elements from a list
|
|
198
|
+
*
|
|
199
|
+
* @param key - List key
|
|
200
|
+
* @param start - Start index (0-based)
|
|
201
|
+
* @param stop - Stop index (-1 for end of list)
|
|
202
|
+
* @returns Array of values in range
|
|
203
|
+
*/
|
|
27
204
|
lrange(key: string, start: number, stop: number): Promise<string[]>;
|
|
205
|
+
/**
|
|
206
|
+
* Get the length of a list
|
|
207
|
+
*
|
|
208
|
+
* @param key - List key
|
|
209
|
+
* @returns List length
|
|
210
|
+
*/
|
|
28
211
|
llen(key: string): Promise<number>;
|
|
212
|
+
/**
|
|
213
|
+
* Find all keys matching a pattern
|
|
214
|
+
* Uses SCAN under the hood to avoid blocking the Redis server.
|
|
215
|
+
*
|
|
216
|
+
* @param pattern - Glob pattern (* and ? wildcards)
|
|
217
|
+
* @returns Array of matching keys (without prefix)
|
|
218
|
+
*/
|
|
29
219
|
keys(pattern: string): Promise<string[]>;
|
|
220
|
+
/**
|
|
221
|
+
* Iterate over keys matching a pattern (cursor-based)
|
|
222
|
+
* Uses Redis SCAN command (recommended for production)
|
|
223
|
+
*
|
|
224
|
+
* @param cursor - Cursor position (0 to start)
|
|
225
|
+
* @param pattern - Glob pattern
|
|
226
|
+
* @param count - Number of keys to return per iteration
|
|
227
|
+
* @returns Tuple of [new cursor, keys array] (keys without prefix)
|
|
228
|
+
*/
|
|
30
229
|
scan(cursor: number, pattern: string, count: number): Promise<[number, string[]]>;
|
|
230
|
+
/**
|
|
231
|
+
* Run cleanup of expired keys
|
|
232
|
+
* No-op for Redis (expiration is handled automatically)
|
|
233
|
+
*/
|
|
31
234
|
cleanup(): Promise<void>;
|
|
235
|
+
/**
|
|
236
|
+
* Disconnect and cleanup all resources
|
|
237
|
+
* No-op for Redis (client connection managed by consumer)
|
|
238
|
+
*/
|
|
32
239
|
disconnect(): Promise<void>;
|
|
33
240
|
}
|
|
34
241
|
//# sourceMappingURL=redis-storage.adapter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redis-storage.adapter.d.ts","sourceRoot":"","sources":["../src/redis-storage.adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAiC,aAAa,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"redis-storage.adapter.d.ts","sourceRoot":"","sources":["../src/redis-storage.adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,23 +2,92 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.RedisStorageAdapter = void 0;
|
|
4
4
|
const core_1 = require("@nauth-toolkit/core");
|
|
5
|
+
/**
|
|
6
|
+
* Redis Storage Adapter
|
|
7
|
+
*
|
|
8
|
+
* Implements StorageAdapter interface using the `redis` package (node-redis).
|
|
9
|
+
*
|
|
10
|
+
* **Key Features:**
|
|
11
|
+
* - Uses node-redis package (redis)
|
|
12
|
+
* - Supports both single-instance Redis and Redis Cluster
|
|
13
|
+
* - Automatic key prefixing: all keys prefixed with `nauth_` to avoid collisions
|
|
14
|
+
* - Multi-server compatible (shared Redis instance/cluster)
|
|
15
|
+
* - Native TTL support via Redis EXPIRE
|
|
16
|
+
* - High performance for transient state
|
|
17
|
+
* - Production-ready with Redis Cluster support for high-availability deployments
|
|
18
|
+
*
|
|
19
|
+
* **Usage:**
|
|
20
|
+
* ```typescript
|
|
21
|
+
* import { createClient } from 'redis';
|
|
22
|
+
* import { RedisStorageAdapter } from '@nauth-toolkit/storage-redis';
|
|
23
|
+
*
|
|
24
|
+
* const redisClient = createClient({ url: 'redis://localhost:6379' });
|
|
25
|
+
* await redisClient.connect();
|
|
26
|
+
*
|
|
27
|
+
* AuthModule.forRoot({
|
|
28
|
+
* storageAdapter: new RedisStorageAdapter(redisClient),
|
|
29
|
+
* });
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```typescript
|
|
34
|
+
* // Using node-redis (recommended)
|
|
35
|
+
* import { createClient } from 'redis';
|
|
36
|
+
* const client = createClient({ url: 'redis://localhost:6379' });
|
|
37
|
+
* await client.connect();
|
|
38
|
+
* const adapter = new RedisStorageAdapter(client);
|
|
39
|
+
*
|
|
40
|
+
* // Or use the factory function (handles connection automatically)
|
|
41
|
+
* import { createRedisStorageAdapter } from '@nauth-toolkit/nestjs';
|
|
42
|
+
* const adapter = createRedisStorageAdapter('redis://localhost:6379');
|
|
43
|
+
* await adapter.initialize();
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
5
46
|
class RedisStorageAdapter {
|
|
6
47
|
redisClient;
|
|
7
48
|
logger;
|
|
8
49
|
keyPrefix = 'nauth_';
|
|
50
|
+
/**
|
|
51
|
+
* Creates a new RedisStorageAdapter instance
|
|
52
|
+
*
|
|
53
|
+
* @param redisClient - Redis client instance from `redis` package (node-redis)
|
|
54
|
+
* @param logger - Logger service for error and debug logging (optional, will be injected by NestJS if not provided)
|
|
55
|
+
* @throws {NAuthException} If client is missing required methods or is invalid
|
|
56
|
+
*/
|
|
9
57
|
constructor(redisClient, logger) {
|
|
10
58
|
this.redisClient = redisClient;
|
|
11
59
|
this.logger = logger;
|
|
60
|
+
// Validation deferred to initialize() because:
|
|
61
|
+
// - node-redis v4+ methods are available before connection, but we validate during init
|
|
62
|
+
// - This allows factory to create adapter with unconnected client
|
|
63
|
+
// Logger is optional - will be injected by NestJS when adapter is used as a provider
|
|
12
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* Validate that the client is a Redis-compatible client
|
|
67
|
+
* Type guard to ensure client implements RedisClientLike interface
|
|
68
|
+
*
|
|
69
|
+
* In node-redis v5+, command methods (get, hget, etc.) are dynamically added
|
|
70
|
+
* and may not be available until after connection. We check for known Redis client
|
|
71
|
+
* indicators instead of individual command methods.
|
|
72
|
+
*
|
|
73
|
+
* @param client - Client instance to validate
|
|
74
|
+
* @throws NAuthException if client doesn't appear to be a Redis client
|
|
75
|
+
*/
|
|
13
76
|
validateClient(client) {
|
|
14
77
|
if (!client || typeof client !== 'object') {
|
|
15
78
|
throw new core_1.NAuthException(core_1.AuthErrorCode.VALIDATION_FAILED, 'Redis client must be an object instance');
|
|
16
79
|
}
|
|
17
80
|
const clientObj = client;
|
|
81
|
+
// Check for known Redis client indicators:
|
|
82
|
+
// - node-redis v4+: has sendCommand method
|
|
83
|
+
// - node-redis v5+: has sendCommand or command methods (may be dynamic)
|
|
84
|
+
// - Other Redis clients: typically have sendCommand or ping method
|
|
18
85
|
const hasSendCommand = typeof clientObj.sendCommand === 'function';
|
|
19
86
|
const hasPing = typeof clientObj.ping === 'function';
|
|
20
87
|
const hasGet = typeof clientObj.get === 'function';
|
|
88
|
+
// At least one of these should exist for a valid Redis client
|
|
21
89
|
if (!hasSendCommand && !hasPing && !hasGet) {
|
|
90
|
+
// Additional check: some clients expose connect/command methods even before connection
|
|
22
91
|
const hasConnect = typeof clientObj.connect === 'function';
|
|
23
92
|
const hasCommand = typeof clientObj.command === 'function';
|
|
24
93
|
if (!hasConnect && !hasCommand) {
|
|
@@ -28,18 +97,44 @@ class RedisStorageAdapter {
|
|
|
28
97
|
'Use createClient from the "redis" package or createRedisStorageAdapter() factory function.');
|
|
29
98
|
}
|
|
30
99
|
}
|
|
100
|
+
// Note: We don't validate individual command methods here because:
|
|
101
|
+
// 1. node-redis v5+ adds them dynamically
|
|
102
|
+
// 2. They're accessed via Proxy or similar mechanism
|
|
103
|
+
// 3. Actual method availability is verified during runtime calls
|
|
31
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* Set logger instance (called by AuthModule to inject logger after factory creation)
|
|
107
|
+
*
|
|
108
|
+
* @param logger - Logger service instance
|
|
109
|
+
*/
|
|
32
110
|
setLogger(logger) {
|
|
33
111
|
this.logger = logger;
|
|
34
112
|
}
|
|
113
|
+
/**
|
|
114
|
+
* Get prefixed key to avoid collisions with other application keys
|
|
115
|
+
*
|
|
116
|
+
* @param key - Original key
|
|
117
|
+
* @returns Prefixed key
|
|
118
|
+
*/
|
|
35
119
|
getPrefixedKey(key) {
|
|
36
120
|
return `${this.keyPrefix}${key}`;
|
|
37
121
|
}
|
|
122
|
+
/**
|
|
123
|
+
* Initialize the storage adapter
|
|
124
|
+
* Performs health check via PING command
|
|
125
|
+
* Connects the Redis client if not already connected (node-redis v4+)
|
|
126
|
+
*
|
|
127
|
+
* @throws {NAuthException} If Redis connection health check fails or client is invalid
|
|
128
|
+
*/
|
|
38
129
|
async initialize() {
|
|
130
|
+
// Validate client before attempting connection
|
|
39
131
|
this.validateClient(this.redisClient);
|
|
40
132
|
try {
|
|
133
|
+
// Ensure Redis client is connected (for node-redis v4+)
|
|
41
134
|
const client = this.redisClient;
|
|
42
135
|
if (client.connect && typeof client.connect === 'function') {
|
|
136
|
+
// Attempt to connect (safe to call multiple times - will handle already-connected state)
|
|
137
|
+
// Must call connect() on the client object to preserve 'this' context
|
|
43
138
|
try {
|
|
44
139
|
if (this.logger?.debug) {
|
|
45
140
|
this.logger.debug('Connecting Redis client...');
|
|
@@ -47,8 +142,10 @@ class RedisStorageAdapter {
|
|
|
47
142
|
await client.connect();
|
|
48
143
|
}
|
|
49
144
|
catch (connectError) {
|
|
145
|
+
// Ignore "already connected" errors - client might already be connected
|
|
50
146
|
const errorMsg = connectError instanceof Error ? connectError.message : String(connectError);
|
|
51
147
|
if (!errorMsg.includes('already') && !errorMsg.includes('connected')) {
|
|
148
|
+
// Re-throw non-connection errors
|
|
52
149
|
throw connectError;
|
|
53
150
|
}
|
|
54
151
|
}
|
|
@@ -68,6 +165,12 @@ class RedisStorageAdapter {
|
|
|
68
165
|
throw error;
|
|
69
166
|
}
|
|
70
167
|
}
|
|
168
|
+
/**
|
|
169
|
+
* Check if the storage adapter is healthy
|
|
170
|
+
* Uses PING command to verify Redis connectivity
|
|
171
|
+
*
|
|
172
|
+
* @returns True if Redis is accessible
|
|
173
|
+
*/
|
|
71
174
|
async isHealthy() {
|
|
72
175
|
try {
|
|
73
176
|
const client = this.redisClient;
|
|
@@ -81,23 +184,47 @@ class RedisStorageAdapter {
|
|
|
81
184
|
return false;
|
|
82
185
|
}
|
|
83
186
|
}
|
|
187
|
+
// ============================================================================
|
|
188
|
+
// Basic Key-Value Operations
|
|
189
|
+
// ============================================================================
|
|
190
|
+
/**
|
|
191
|
+
* Get a value by key
|
|
192
|
+
*
|
|
193
|
+
* @param key - The key to retrieve
|
|
194
|
+
* @returns The stored value or null if not found
|
|
195
|
+
*/
|
|
84
196
|
async get(key) {
|
|
85
197
|
const client = this.redisClient;
|
|
86
198
|
return await client.get(this.getPrefixedKey(key));
|
|
87
199
|
}
|
|
200
|
+
/**
|
|
201
|
+
* Set a key-value pair with optional TTL (time to live)
|
|
202
|
+
*
|
|
203
|
+
* @param key - The key to store
|
|
204
|
+
* @param value - The value to store
|
|
205
|
+
* @param ttlSeconds - Time to live in seconds (optional)
|
|
206
|
+
* @param options - Additional options like nx (set if not exists)
|
|
207
|
+
* @returns The value if set successfully, null if nx is true and key already exists
|
|
208
|
+
*/
|
|
88
209
|
async set(key, value, ttlSeconds, options) {
|
|
89
210
|
const client = this.redisClient;
|
|
90
211
|
const prefixedKey = this.getPrefixedKey(key);
|
|
91
212
|
if (options?.nx) {
|
|
213
|
+
// Use SET with NX option (only set if key does not exist)
|
|
214
|
+
// Redis SET key value NX EX seconds - returns 'OK' if set, null if key exists
|
|
215
|
+
// node-redis (redis package): SET key value { EX: seconds, NX: true }
|
|
92
216
|
const setOptions = { NX: true };
|
|
93
217
|
if (ttlSeconds) {
|
|
94
218
|
setOptions.EX = ttlSeconds;
|
|
95
219
|
}
|
|
96
220
|
const result = await client.set(prefixedKey, value, setOptions);
|
|
221
|
+
// Redis returns 'OK' on success, null on failure (key exists)
|
|
97
222
|
return result === 'OK' ? value : null;
|
|
98
223
|
}
|
|
99
224
|
else {
|
|
225
|
+
// Regular SET operation (overwrites existing key)
|
|
100
226
|
if (ttlSeconds) {
|
|
227
|
+
// node-redis supports { EX: seconds } option
|
|
101
228
|
await client.set(prefixedKey, value, { EX: ttlSeconds });
|
|
102
229
|
}
|
|
103
230
|
else {
|
|
@@ -106,66 +233,174 @@ class RedisStorageAdapter {
|
|
|
106
233
|
return value;
|
|
107
234
|
}
|
|
108
235
|
}
|
|
236
|
+
/**
|
|
237
|
+
* Delete a key from storage
|
|
238
|
+
*
|
|
239
|
+
* @param key - The key to delete
|
|
240
|
+
*/
|
|
109
241
|
async del(key) {
|
|
110
242
|
const client = this.redisClient;
|
|
111
243
|
await client.del(this.getPrefixedKey(key));
|
|
112
244
|
}
|
|
245
|
+
/**
|
|
246
|
+
* Check if a key exists
|
|
247
|
+
*
|
|
248
|
+
* @param key - The key to check
|
|
249
|
+
* @returns True if key exists, false otherwise
|
|
250
|
+
*/
|
|
113
251
|
async exists(key) {
|
|
114
252
|
const client = this.redisClient;
|
|
115
253
|
const result = await client.exists(this.getPrefixedKey(key));
|
|
254
|
+
// Handle both boolean (ioredis) and number (redis) return types
|
|
116
255
|
return typeof result === 'boolean' ? result : result > 0;
|
|
117
256
|
}
|
|
257
|
+
// ============================================================================
|
|
258
|
+
// Atomic Operations (for counters and rate limiting)
|
|
259
|
+
// ============================================================================
|
|
260
|
+
/**
|
|
261
|
+
* Increment a counter stored at key
|
|
262
|
+
* Uses Redis native INCR for atomic operation
|
|
263
|
+
*
|
|
264
|
+
* @param key - The key to increment
|
|
265
|
+
* @param ttlSeconds - Optional TTL in seconds to set when creating a new key (only applied if key doesn't exist)
|
|
266
|
+
* @returns The new value after incrementing
|
|
267
|
+
*/
|
|
118
268
|
async incr(key, ttlSeconds) {
|
|
119
269
|
const client = this.redisClient;
|
|
120
270
|
const prefixedKey = this.getPrefixedKey(key);
|
|
271
|
+
// Check if key exists to determine if we should set TTL
|
|
121
272
|
const exists = await client.exists(prefixedKey);
|
|
122
273
|
const value = await client.incr(prefixedKey);
|
|
274
|
+
// If key didn't exist before incrementing (value is now 1) and TTL provided, set expiration
|
|
123
275
|
if (ttlSeconds !== undefined && exists === 0 && value === 1) {
|
|
124
276
|
await client.expire(prefixedKey, ttlSeconds);
|
|
125
277
|
}
|
|
126
278
|
return value;
|
|
127
279
|
}
|
|
280
|
+
/**
|
|
281
|
+
* Decrement a counter stored at key
|
|
282
|
+
* Uses Redis native DECR for atomic operation
|
|
283
|
+
*
|
|
284
|
+
* @param key - The key to decrement
|
|
285
|
+
* @returns The new value after decrementing
|
|
286
|
+
*/
|
|
128
287
|
async decr(key) {
|
|
129
288
|
const client = this.redisClient;
|
|
130
289
|
return await client.decr(this.getPrefixedKey(key));
|
|
131
290
|
}
|
|
291
|
+
/**
|
|
292
|
+
* Set expiration time on an existing key
|
|
293
|
+
*
|
|
294
|
+
* @param key - The key to set expiration on
|
|
295
|
+
* @param ttl - Time to live in seconds
|
|
296
|
+
*/
|
|
132
297
|
async expire(key, ttl) {
|
|
133
298
|
const client = this.redisClient;
|
|
134
299
|
await client.expire(this.getPrefixedKey(key), ttl);
|
|
135
300
|
}
|
|
301
|
+
/**
|
|
302
|
+
* Get the time to live (TTL) for a key
|
|
303
|
+
*
|
|
304
|
+
* @param key - The key to check
|
|
305
|
+
* @returns Seconds until expiration, -1 if no expiration, -2 if key doesn't exist
|
|
306
|
+
*/
|
|
136
307
|
async ttl(key) {
|
|
137
308
|
const client = this.redisClient;
|
|
138
309
|
return await client.ttl(this.getPrefixedKey(key));
|
|
139
310
|
}
|
|
311
|
+
// ============================================================================
|
|
312
|
+
// Hash Operations
|
|
313
|
+
// ============================================================================
|
|
314
|
+
/**
|
|
315
|
+
* Get a field value from a hash
|
|
316
|
+
*
|
|
317
|
+
* @param key - Hash key
|
|
318
|
+
* @param field - Field name
|
|
319
|
+
* @returns Field value or null if not found
|
|
320
|
+
*/
|
|
140
321
|
async hget(key, field) {
|
|
141
322
|
const client = this.redisClient;
|
|
142
323
|
return await client.hget(this.getPrefixedKey(key), field);
|
|
143
324
|
}
|
|
325
|
+
/**
|
|
326
|
+
* Set a field value in a hash
|
|
327
|
+
*
|
|
328
|
+
* @param key - Hash key
|
|
329
|
+
* @param field - Field name
|
|
330
|
+
* @param value - Field value
|
|
331
|
+
*/
|
|
144
332
|
async hset(key, field, value) {
|
|
145
333
|
const client = this.redisClient;
|
|
146
334
|
await client.hset(this.getPrefixedKey(key), field, value);
|
|
147
335
|
}
|
|
336
|
+
/**
|
|
337
|
+
* Get all fields and values from a hash
|
|
338
|
+
*
|
|
339
|
+
* @param key - Hash key
|
|
340
|
+
* @returns Object with all field-value pairs
|
|
341
|
+
*/
|
|
148
342
|
async hgetall(key) {
|
|
149
343
|
const client = this.redisClient;
|
|
150
344
|
return await client.hgetall(this.getPrefixedKey(key));
|
|
151
345
|
}
|
|
346
|
+
/**
|
|
347
|
+
* Delete one or more fields from a hash
|
|
348
|
+
*
|
|
349
|
+
* @param key - Hash key
|
|
350
|
+
* @param fields - Field names to delete
|
|
351
|
+
* @returns Number of fields deleted
|
|
352
|
+
*/
|
|
152
353
|
async hdel(key, ...fields) {
|
|
153
354
|
const client = this.redisClient;
|
|
154
355
|
return await client.hdel(this.getPrefixedKey(key), ...fields);
|
|
155
356
|
}
|
|
357
|
+
// ============================================================================
|
|
358
|
+
// List Operations
|
|
359
|
+
// ============================================================================
|
|
360
|
+
/**
|
|
361
|
+
* Push value to the left (beginning) of a list
|
|
362
|
+
*
|
|
363
|
+
* @param key - List key
|
|
364
|
+
* @param value - Value to push
|
|
365
|
+
*/
|
|
156
366
|
async lpush(key, value) {
|
|
157
367
|
const client = this.redisClient;
|
|
158
368
|
await client.lpush(this.getPrefixedKey(key), value);
|
|
159
369
|
}
|
|
370
|
+
/**
|
|
371
|
+
* Get a range of elements from a list
|
|
372
|
+
*
|
|
373
|
+
* @param key - List key
|
|
374
|
+
* @param start - Start index (0-based)
|
|
375
|
+
* @param stop - Stop index (-1 for end of list)
|
|
376
|
+
* @returns Array of values in range
|
|
377
|
+
*/
|
|
160
378
|
async lrange(key, start, stop) {
|
|
161
379
|
const client = this.redisClient;
|
|
162
380
|
return await client.lrange(this.getPrefixedKey(key), start, stop);
|
|
163
381
|
}
|
|
382
|
+
/**
|
|
383
|
+
* Get the length of a list
|
|
384
|
+
*
|
|
385
|
+
* @param key - List key
|
|
386
|
+
* @returns List length
|
|
387
|
+
*/
|
|
164
388
|
async llen(key) {
|
|
165
389
|
const client = this.redisClient;
|
|
166
390
|
return await client.llen(this.getPrefixedKey(key));
|
|
167
391
|
}
|
|
392
|
+
// ============================================================================
|
|
393
|
+
// Pattern Operations
|
|
394
|
+
// ============================================================================
|
|
395
|
+
/**
|
|
396
|
+
* Find all keys matching a pattern
|
|
397
|
+
* Uses SCAN under the hood to avoid blocking the Redis server.
|
|
398
|
+
*
|
|
399
|
+
* @param pattern - Glob pattern (* and ? wildcards)
|
|
400
|
+
* @returns Array of matching keys (without prefix)
|
|
401
|
+
*/
|
|
168
402
|
async keys(pattern) {
|
|
403
|
+
// Implement using iterative SCAN to avoid blocking in production
|
|
169
404
|
const allKeys = [];
|
|
170
405
|
let cursor = 0;
|
|
171
406
|
const countPerScan = 1000;
|
|
@@ -178,10 +413,22 @@ class RedisStorageAdapter {
|
|
|
178
413
|
} while (cursor !== 0);
|
|
179
414
|
return allKeys;
|
|
180
415
|
}
|
|
416
|
+
/**
|
|
417
|
+
* Iterate over keys matching a pattern (cursor-based)
|
|
418
|
+
* Uses Redis SCAN command (recommended for production)
|
|
419
|
+
*
|
|
420
|
+
* @param cursor - Cursor position (0 to start)
|
|
421
|
+
* @param pattern - Glob pattern
|
|
422
|
+
* @param count - Number of keys to return per iteration
|
|
423
|
+
* @returns Tuple of [new cursor, keys array] (keys without prefix)
|
|
424
|
+
*/
|
|
181
425
|
async scan(cursor, pattern, count) {
|
|
182
426
|
const client = this.redisClient;
|
|
183
427
|
const prefixedPattern = `${this.keyPrefix}${pattern}`;
|
|
428
|
+
// Use SCAN command (both clients support it)
|
|
429
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
184
430
|
const result = await client.scan(cursor, 'MATCH', prefixedPattern, 'COUNT', count);
|
|
431
|
+
// Handle both array format [cursor, keys] and object format { cursor, keys }
|
|
185
432
|
let newCursor;
|
|
186
433
|
let keys;
|
|
187
434
|
if (Array.isArray(result)) {
|
|
@@ -191,15 +438,31 @@ class RedisStorageAdapter {
|
|
|
191
438
|
newCursor = result.cursor;
|
|
192
439
|
keys = result.keys || [];
|
|
193
440
|
}
|
|
441
|
+
// Remove prefix from keys
|
|
194
442
|
const unprefixedKeys = keys.map((key) => key.replace(new RegExp(`^${this.keyPrefix}`), ''));
|
|
195
443
|
return [newCursor, unprefixedKeys];
|
|
196
444
|
}
|
|
445
|
+
// ============================================================================
|
|
446
|
+
// Cleanup & Lifecycle
|
|
447
|
+
// ============================================================================
|
|
448
|
+
/**
|
|
449
|
+
* Run cleanup of expired keys
|
|
450
|
+
* No-op for Redis (expiration is handled automatically)
|
|
451
|
+
*/
|
|
197
452
|
async cleanup() {
|
|
453
|
+
// Redis handles expiration automatically via TTL
|
|
454
|
+
// No manual cleanup needed
|
|
198
455
|
if (this.logger?.debug) {
|
|
199
456
|
this.logger.debug('RedisStorageAdapter cleanup: expiration handled automatically by Redis');
|
|
200
457
|
}
|
|
201
458
|
}
|
|
459
|
+
/**
|
|
460
|
+
* Disconnect and cleanup all resources
|
|
461
|
+
* No-op for Redis (client connection managed by consumer)
|
|
462
|
+
*/
|
|
202
463
|
async disconnect() {
|
|
464
|
+
// Consumer manages Redis client lifecycle
|
|
465
|
+
// Adapter doesn't own the connection
|
|
203
466
|
if (this.logger?.debug) {
|
|
204
467
|
this.logger.debug('RedisStorageAdapter disconnected');
|
|
205
468
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redis-storage.adapter.js","sourceRoot":"","sources":["../src/redis-storage.adapter.ts"],"names":[],"mappings":";;;AAAA,8CAAmG;
|
|
1
|
+
{"version":3,"file":"redis-storage.adapter.js","sourceRoot":"","sources":["../src/redis-storage.adapter.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nauth-toolkit/storage-redis",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.18",
|
|
4
4
|
"description": "Redis storage adapter for nauth-toolkit using the redis package (node-redis)",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"format:check": "prettier --check \"src/**/*.ts\""
|
|
15
15
|
},
|
|
16
16
|
"peerDependencies": {
|
|
17
|
-
"@nauth-toolkit/core": "^0.1.
|
|
17
|
+
"@nauth-toolkit/core": "^0.1.18",
|
|
18
18
|
"redis": "^4.6.0 || ^5.0.0"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|