@common-stack/store-redis 8.2.5-alpha.33 → 8.2.5-alpha.35
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/lib/containers/container.d.ts +2 -0
- package/lib/containers/container.js +9 -0
- package/lib/containers/index.d.ts +1 -0
- package/lib/core/index.d.ts +3 -0
- package/lib/core/ioredis.d.ts +15 -0
- package/lib/core/ioredis.js +31 -0
- package/lib/core/keyBuilder/generate-query-cache-key.d.ts +57 -0
- package/lib/core/keyBuilder/generate-query-cache-key.js +88 -0
- package/lib/core/keyBuilder/index.d.ts +18 -0
- package/lib/core/keyBuilder/index.js +27 -0
- package/lib/core/keyBuilder/redis-key-builder.d.ts +152 -0
- package/lib/core/keyBuilder/redis-key-builder.js +185 -0
- package/lib/core/keyBuilder/sanitize-redis-key.d.ts +118 -0
- package/lib/core/keyBuilder/sanitize-redis-key.js +120 -0
- package/lib/core/upstash-redis.d.ts +14 -0
- package/lib/core/upstash-redis.js +27 -0
- package/lib/index.d.ts +2 -1
- package/lib/index.js +7 -3
- package/lib/interfaces/index.d.ts +1 -6
- package/lib/interfaces/redis.d.ts +11 -0
- package/lib/module.d.ts +2 -0
- package/lib/module.js +9 -0
- package/lib/services/RedisCacheManager.d.ts +77 -0
- package/lib/services/RedisCacheManager.js +185 -0
- package/lib/services/index.d.ts +1 -5
- package/lib/templates/constants/SERVER_TYPES.ts.template +0 -1
- package/lib/templates/repositories/IRedisKeyBuilder.ts.template +4 -4
- package/lib/templates/repositories/redisCommonTypes.ts.template +2 -163
- package/lib/templates/{repositories/IRedisCacheManager.ts.template → services/RedisCacheManager.ts.template} +7 -7
- package/package.json +8 -7
- package/lib/interfaces/cache-manager.d.ts +0 -28
- package/lib/interfaces/redis-key-options.d.ts +0 -35
- package/lib/interfaces/redis-key-options.js +0 -17
- package/lib/interfaces/storage-backend.d.ts +0 -17
- package/lib/templates/repositories/IRedisService.ts.template +0 -236
- package/lib/templates/repositories/IRedisStorageBackend.ts.template +0 -229
- package/lib/utils/index.d.ts +0 -5
- package/lib/utils/redis-key-builder.d.ts +0 -32
- package/lib/utils/redis-key-builder.js +0 -68
- package/lib/utils/redis-key-sanitizer.d.ts +0 -30
- package/lib/utils/redis-key-sanitizer.js +0 -54
|
@@ -1,229 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
/**
|
|
3
|
-
* @file IRedisStorageBackend.ts
|
|
4
|
-
* @description Defines the IRedisStorageBackend interface for simple key-value storage operations using Redis.
|
|
5
|
-
* This interface provides a clean abstraction for basic Redis operations, suitable for request-scoped storage,
|
|
6
|
-
* temporary data, session storage, and other simple caching scenarios.
|
|
7
|
-
*
|
|
8
|
-
* The storage backend is designed for:
|
|
9
|
-
* - Request-scoped temporary data
|
|
10
|
-
* - Session storage
|
|
11
|
-
* - Simple key-value caching
|
|
12
|
-
* - Temporary flags and state
|
|
13
|
-
*
|
|
14
|
-
* Unlike RedisCacheManager which is optimized for GraphQL query caching with hashing,
|
|
15
|
-
* this storage backend provides straightforward get/set/delete operations for simple use cases.
|
|
16
|
-
*
|
|
17
|
-
* Key features:
|
|
18
|
-
* - Simple key-value operations
|
|
19
|
-
* - TTL support for automatic expiration
|
|
20
|
-
* - Bulk operations for efficiency
|
|
21
|
-
* - Clear operations for cleanup
|
|
22
|
-
* - Type-safe with generics
|
|
23
|
-
*
|
|
24
|
-
* @see IRedisCacheManager - For complex caching with GraphQL queries
|
|
25
|
-
* @see IRedisKeyBuilder - For standardized key generation
|
|
26
|
-
*/
|
|
27
|
-
|
|
28
|
-
export interface IRedisStorageBackend {
|
|
29
|
-
/**
|
|
30
|
-
* Get a value by key
|
|
31
|
-
* Returns null if key doesn't exist
|
|
32
|
-
*
|
|
33
|
-
* @param key - Redis key to retrieve
|
|
34
|
-
* @returns Promise resolving to the value or null
|
|
35
|
-
*
|
|
36
|
-
* @example
|
|
37
|
-
* // Get session data
|
|
38
|
-
* const sessionData = await storage.get('session:user-123');
|
|
39
|
-
* if (sessionData) {
|
|
40
|
-
* const session = JSON.parse(sessionData);
|
|
41
|
-
* }
|
|
42
|
-
*/
|
|
43
|
-
get(key: string): Promise<string | null>;
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Get multiple values by keys
|
|
47
|
-
* Returns array with same order as keys, null for missing keys
|
|
48
|
-
*
|
|
49
|
-
* @param keys - Array of Redis keys to retrieve
|
|
50
|
-
* @returns Promise resolving to array of values
|
|
51
|
-
*
|
|
52
|
-
* @example
|
|
53
|
-
* // Get multiple user preferences
|
|
54
|
-
* const keys = ['pref:user-1', 'pref:user-2', 'pref:user-3'];
|
|
55
|
-
* const values = await storage.getMany(keys);
|
|
56
|
-
*/
|
|
57
|
-
getMany(keys: string[]): Promise<(string | null)[]>;
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Set a value for a key
|
|
61
|
-
* Optionally specify TTL in seconds
|
|
62
|
-
*
|
|
63
|
-
* @param key - Redis key to set
|
|
64
|
-
* @param value - Value to store (will be stringified if object)
|
|
65
|
-
* @param ttl - Optional time-to-live in seconds
|
|
66
|
-
* @returns Promise that resolves when set is complete
|
|
67
|
-
*
|
|
68
|
-
* @example
|
|
69
|
-
* // Store session with 1 hour expiration
|
|
70
|
-
* await storage.set('session:user-123', JSON.stringify(sessionData), 3600);
|
|
71
|
-
*
|
|
72
|
-
* @example
|
|
73
|
-
* // Store temporary flag
|
|
74
|
-
* await storage.set('flag:processing', 'true', 300); // 5 minutes
|
|
75
|
-
*/
|
|
76
|
-
set(key: string, value: string, ttl?: number): Promise<void>;
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Set multiple key-value pairs
|
|
80
|
-
* Efficiently stores multiple entries in one operation
|
|
81
|
-
*
|
|
82
|
-
* @param entries - Array of key-value pairs to set
|
|
83
|
-
* @param ttl - Optional TTL to apply to all entries
|
|
84
|
-
* @returns Promise that resolves when all are set
|
|
85
|
-
*
|
|
86
|
-
* @example
|
|
87
|
-
* // Set multiple user preferences
|
|
88
|
-
* await storage.setMany([
|
|
89
|
-
* { key: 'pref:theme', value: 'dark' },
|
|
90
|
-
* { key: 'pref:lang', value: 'en' }
|
|
91
|
-
* ], 86400); // 24 hours
|
|
92
|
-
*/
|
|
93
|
-
setMany(entries: Array<{ key: string; value: string }>, ttl?: number): Promise<void>;
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Delete a value by key
|
|
97
|
-
* Returns true if key existed and was deleted
|
|
98
|
-
*
|
|
99
|
-
* @param key - Redis key to delete
|
|
100
|
-
* @returns Promise resolving to deletion success
|
|
101
|
-
*
|
|
102
|
-
* @example
|
|
103
|
-
* // Delete session on logout
|
|
104
|
-
* const deleted = await storage.delete('session:user-123');
|
|
105
|
-
*/
|
|
106
|
-
delete(key: string): Promise<boolean>;
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Delete multiple keys
|
|
110
|
-
* Returns number of keys that were deleted
|
|
111
|
-
*
|
|
112
|
-
* @param keys - Array of Redis keys to delete
|
|
113
|
-
* @returns Promise resolving to count of deleted keys
|
|
114
|
-
*
|
|
115
|
-
* @example
|
|
116
|
-
* // Delete multiple cache entries
|
|
117
|
-
* const deletedCount = await storage.deleteMany([
|
|
118
|
-
* 'cache:user-1',
|
|
119
|
-
* 'cache:user-2'
|
|
120
|
-
* ]);
|
|
121
|
-
*/
|
|
122
|
-
deleteMany(keys: string[]): Promise<number>;
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Check if a key exists
|
|
126
|
-
*
|
|
127
|
-
* @param key - Redis key to check
|
|
128
|
-
* @returns Promise resolving to true if key exists
|
|
129
|
-
*
|
|
130
|
-
* @example
|
|
131
|
-
* // Check if session exists
|
|
132
|
-
* const hasSession = await storage.exists('session:user-123');
|
|
133
|
-
*/
|
|
134
|
-
exists(key: string): Promise<boolean>;
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Get remaining TTL for a key in seconds
|
|
138
|
-
* Returns -1 if key has no expiration
|
|
139
|
-
* Returns -2 if key doesn't exist
|
|
140
|
-
*
|
|
141
|
-
* @param key - Redis key to check
|
|
142
|
-
* @returns Promise resolving to TTL in seconds
|
|
143
|
-
*
|
|
144
|
-
* @example
|
|
145
|
-
* // Check session expiration
|
|
146
|
-
* const ttl = await storage.getTTL('session:user-123');
|
|
147
|
-
* if (ttl < 300) {
|
|
148
|
-
* // Session expires in less than 5 minutes
|
|
149
|
-
* }
|
|
150
|
-
*/
|
|
151
|
-
getTTL(key: string): Promise<number>;
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Set TTL for an existing key
|
|
155
|
-
* Updates expiration time without changing the value
|
|
156
|
-
*
|
|
157
|
-
* @param key - Redis key to update
|
|
158
|
-
* @param ttl - New TTL in seconds
|
|
159
|
-
* @returns Promise resolving to true if TTL was set
|
|
160
|
-
*
|
|
161
|
-
* @example
|
|
162
|
-
* // Extend session by 1 hour
|
|
163
|
-
* await storage.setTTL('session:user-123', 3600);
|
|
164
|
-
*/
|
|
165
|
-
setTTL(key: string, ttl: number): Promise<boolean>;
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* Clear all keys matching a pattern
|
|
169
|
-
* Uses SCAN to find keys, then deletes them
|
|
170
|
-
*
|
|
171
|
-
* @param pattern - Redis pattern to match (supports wildcards)
|
|
172
|
-
* @returns Promise resolving to count of deleted keys
|
|
173
|
-
*
|
|
174
|
-
* @example
|
|
175
|
-
* // Clear all session keys for a tenant
|
|
176
|
-
* const cleared = await storage.clearPattern('APP:tenant-123:session:*');
|
|
177
|
-
*
|
|
178
|
-
* @example
|
|
179
|
-
* // Clear all temporary keys
|
|
180
|
-
* await storage.clearPattern('APP:*:temp:*');
|
|
181
|
-
*/
|
|
182
|
-
clearPattern(pattern: string): Promise<number>;
|
|
183
|
-
|
|
184
|
-
/**
|
|
185
|
-
* Clear all keys in this storage's namespace
|
|
186
|
-
* Useful for cleanup operations
|
|
187
|
-
*
|
|
188
|
-
* @returns Promise that resolves when clear is complete
|
|
189
|
-
*
|
|
190
|
-
* @example
|
|
191
|
-
* // Clear all storage on request end
|
|
192
|
-
* res.on('finish', async () => {
|
|
193
|
-
* await storage.clear();
|
|
194
|
-
* });
|
|
195
|
-
*/
|
|
196
|
-
clear(): Promise<void>;
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* Increment a numeric value
|
|
200
|
-
* Creates key with value 0 if it doesn't exist
|
|
201
|
-
*
|
|
202
|
-
* @param key - Redis key to increment
|
|
203
|
-
* @param amount - Amount to increment by (default: 1)
|
|
204
|
-
* @returns Promise resolving to new value
|
|
205
|
-
*
|
|
206
|
-
* @example
|
|
207
|
-
* // Increment counter
|
|
208
|
-
* const newCount = await storage.increment('counter:requests');
|
|
209
|
-
*
|
|
210
|
-
* @example
|
|
211
|
-
* // Add to score
|
|
212
|
-
* const score = await storage.increment('score:user-123', 10);
|
|
213
|
-
*/
|
|
214
|
-
increment(key: string, amount?: number): Promise<number>;
|
|
215
|
-
|
|
216
|
-
/**
|
|
217
|
-
* Decrement a numeric value
|
|
218
|
-
* Creates key with value 0 if it doesn't exist
|
|
219
|
-
*
|
|
220
|
-
* @param key - Redis key to decrement
|
|
221
|
-
* @param amount - Amount to decrement by (default: 1)
|
|
222
|
-
* @returns Promise resolving to new value
|
|
223
|
-
*
|
|
224
|
-
* @example
|
|
225
|
-
* // Decrement available slots
|
|
226
|
-
* const remaining = await storage.decrement('slots:available');
|
|
227
|
-
*/
|
|
228
|
-
decrement(key: string, amount?: number): Promise<number>;
|
|
229
|
-
}
|
package/lib/utils/index.d.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import type { RedisKeyOptions } from '../interfaces/redis-key-options';
|
|
2
|
-
/**
|
|
3
|
-
* Build a standardized Redis key with proper formatting and sanitization
|
|
4
|
-
*
|
|
5
|
-
* Format: <APP_NAME>:<tenantId>:<namespace>:<segments...>
|
|
6
|
-
*
|
|
7
|
-
* @example
|
|
8
|
-
* buildRedisKey({
|
|
9
|
-
* tenantId: 'tenant-123',
|
|
10
|
-
* namespace: RedisNamespace.CACHE,
|
|
11
|
-
* segments: ['user', 'profile']
|
|
12
|
-
* })
|
|
13
|
-
* // Returns: "APP_NAME:tenant-123:cache:user:profile"
|
|
14
|
-
*/
|
|
15
|
-
export declare function buildRedisKey(options: RedisKeyOptions): string;
|
|
16
|
-
/**
|
|
17
|
-
* Build a Redis key pattern for wildcard matching
|
|
18
|
-
*
|
|
19
|
-
* @example
|
|
20
|
-
* buildRedisKeyPattern({
|
|
21
|
-
* tenantId: 'tenant-123',
|
|
22
|
-
* namespace: RedisNamespace.CACHE,
|
|
23
|
-
* segments: ['user', '*']
|
|
24
|
-
* })
|
|
25
|
-
* // Returns: "APP_NAME:tenant-123:cache:user:*"
|
|
26
|
-
*/
|
|
27
|
-
export declare function buildRedisKeyPattern(options: RedisKeyOptions): string;
|
|
28
|
-
/**
|
|
29
|
-
* Validate if a string is a valid Redis key
|
|
30
|
-
* Redis keys can be up to 512MB but should be kept reasonable
|
|
31
|
-
*/
|
|
32
|
-
export declare function isValidRedisKey(key: string): boolean;
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { sanitizeKeyComponent } from './redis-key-sanitizer.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Get application name from environment or config
|
|
5
|
-
* This will be replaced with actual config import during migration
|
|
6
|
-
*/
|
|
7
|
-
const getAppName = () => {
|
|
8
|
-
return process.env.APP_NAME || 'APP';
|
|
9
|
-
};
|
|
10
|
-
/**
|
|
11
|
-
* Build a standardized Redis key with proper formatting and sanitization
|
|
12
|
-
*
|
|
13
|
-
* Format: <APP_NAME>:<tenantId>:<namespace>:<segments...>
|
|
14
|
-
*
|
|
15
|
-
* @example
|
|
16
|
-
* buildRedisKey({
|
|
17
|
-
* tenantId: 'tenant-123',
|
|
18
|
-
* namespace: RedisNamespace.CACHE,
|
|
19
|
-
* segments: ['user', 'profile']
|
|
20
|
-
* })
|
|
21
|
-
* // Returns: "APP_NAME:tenant-123:cache:user:profile"
|
|
22
|
-
*/
|
|
23
|
-
function buildRedisKey(options) {
|
|
24
|
-
const { tenantId = 'default', namespace, segments, userId } = options;
|
|
25
|
-
// Sanitize all components
|
|
26
|
-
const sanitizedTenantId = sanitizeKeyComponent(tenantId);
|
|
27
|
-
const sanitizedNamespace = sanitizeKeyComponent(namespace);
|
|
28
|
-
const sanitizedSegments = segments.map(sanitizeKeyComponent);
|
|
29
|
-
// Build key parts
|
|
30
|
-
const parts = [getAppName(), sanitizedTenantId, sanitizedNamespace, ...sanitizedSegments];
|
|
31
|
-
// Add userId if provided
|
|
32
|
-
if (userId) {
|
|
33
|
-
parts.splice(2, 0, sanitizeKeyComponent(userId));
|
|
34
|
-
}
|
|
35
|
-
return parts.join(':');
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Build a Redis key pattern for wildcard matching
|
|
39
|
-
*
|
|
40
|
-
* @example
|
|
41
|
-
* buildRedisKeyPattern({
|
|
42
|
-
* tenantId: 'tenant-123',
|
|
43
|
-
* namespace: RedisNamespace.CACHE,
|
|
44
|
-
* segments: ['user', '*']
|
|
45
|
-
* })
|
|
46
|
-
* // Returns: "APP_NAME:tenant-123:cache:user:*"
|
|
47
|
-
*/
|
|
48
|
-
function buildRedisKeyPattern(options) {
|
|
49
|
-
// Same as buildRedisKey but allows '*' in segments
|
|
50
|
-
return buildRedisKey(options);
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Validate if a string is a valid Redis key
|
|
54
|
-
* Redis keys can be up to 512MB but should be kept reasonable
|
|
55
|
-
*/
|
|
56
|
-
function isValidRedisKey(key) {
|
|
57
|
-
// Basic validation rules
|
|
58
|
-
if (!key || key.length === 0)
|
|
59
|
-
return false;
|
|
60
|
-
if (key.length > 1024)
|
|
61
|
-
return false; // Reasonable limit
|
|
62
|
-
// Check for invalid characters after sanitization
|
|
63
|
-
// After sanitization, keys should only contain alphanumeric, colons, hyphens, underscores
|
|
64
|
-
const validPattern = /^[a-zA-Z0-9:_-]+$/;
|
|
65
|
-
return validPattern.test(key);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export { buildRedisKey, buildRedisKeyPattern, isValidRedisKey };
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Sanitize a Redis key component to ensure it's valid and safe
|
|
3
|
-
*
|
|
4
|
-
* Redis keys can contain any binary sequence, but for best practices:
|
|
5
|
-
* - Avoid whitespace (spaces, tabs, newlines) - replace with underscores
|
|
6
|
-
* - Avoid control characters (0x00-0x1F, 0x7F) - remove them
|
|
7
|
-
* - Avoid quotes and backslashes that could cause escaping issues - remove them
|
|
8
|
-
* - Replace pipes (|) with hyphens since Auth0 userIds use pipes (auth0|123)
|
|
9
|
-
*
|
|
10
|
-
* @param component - The key component to sanitize
|
|
11
|
-
* @returns Sanitized key component
|
|
12
|
-
*/
|
|
13
|
-
export declare function sanitizeKeyComponent(component: string): string;
|
|
14
|
-
/**
|
|
15
|
-
* Sanitize an entire Redis key (all components)
|
|
16
|
-
* Useful for keys that are already constructed
|
|
17
|
-
*
|
|
18
|
-
* @param key - The complete Redis key to sanitize
|
|
19
|
-
* @returns Sanitized Redis key
|
|
20
|
-
*/
|
|
21
|
-
export declare function sanitizeRedisKey(key: string): string;
|
|
22
|
-
/**
|
|
23
|
-
* Escape special Redis pattern characters for exact matching
|
|
24
|
-
* Useful when you want to search for keys containing wildcards literally
|
|
25
|
-
* Note: Hyphens are not escaped as they're commonly used in keys
|
|
26
|
-
*
|
|
27
|
-
* @param pattern - The pattern to escape
|
|
28
|
-
* @returns Escaped pattern
|
|
29
|
-
*/
|
|
30
|
-
export declare function escapeRedisPattern(pattern: string): string;
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Sanitize a Redis key component to ensure it's valid and safe
|
|
3
|
-
*
|
|
4
|
-
* Redis keys can contain any binary sequence, but for best practices:
|
|
5
|
-
* - Avoid whitespace (spaces, tabs, newlines) - replace with underscores
|
|
6
|
-
* - Avoid control characters (0x00-0x1F, 0x7F) - remove them
|
|
7
|
-
* - Avoid quotes and backslashes that could cause escaping issues - remove them
|
|
8
|
-
* - Replace pipes (|) with hyphens since Auth0 userIds use pipes (auth0|123)
|
|
9
|
-
*
|
|
10
|
-
* @param component - The key component to sanitize
|
|
11
|
-
* @returns Sanitized key component
|
|
12
|
-
*/
|
|
13
|
-
function sanitizeKeyComponent(component) {
|
|
14
|
-
if (!component)
|
|
15
|
-
return '';
|
|
16
|
-
return component
|
|
17
|
-
.trim() // Trim first to remove leading/trailing whitespace
|
|
18
|
-
.replace(/[\s\r\n\t]+/g, '_') // Replace whitespace with underscore
|
|
19
|
-
.replace(/\|/g, '-') // Replace pipe with hyphen (Auth0 userIds: auth0|123 → auth0-123)
|
|
20
|
-
.replace(/[\x00-\x1F\x7F]/g, '') // Remove control characters
|
|
21
|
-
.replace(/["'\\]/g, ''); // Remove quotes and backslashes
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Sanitize an entire Redis key (all components)
|
|
25
|
-
* Useful for keys that are already constructed
|
|
26
|
-
*
|
|
27
|
-
* @param key - The complete Redis key to sanitize
|
|
28
|
-
* @returns Sanitized Redis key
|
|
29
|
-
*/
|
|
30
|
-
function sanitizeRedisKey(key) {
|
|
31
|
-
if (!key)
|
|
32
|
-
return '';
|
|
33
|
-
// Split by colon, sanitize each part, rejoin
|
|
34
|
-
return key
|
|
35
|
-
.split(':')
|
|
36
|
-
.map(sanitizeKeyComponent)
|
|
37
|
-
.filter((part) => part.length > 0)
|
|
38
|
-
.join(':');
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Escape special Redis pattern characters for exact matching
|
|
42
|
-
* Useful when you want to search for keys containing wildcards literally
|
|
43
|
-
* Note: Hyphens are not escaped as they're commonly used in keys
|
|
44
|
-
*
|
|
45
|
-
* @param pattern - The pattern to escape
|
|
46
|
-
* @returns Escaped pattern
|
|
47
|
-
*/
|
|
48
|
-
function escapeRedisPattern(pattern) {
|
|
49
|
-
// Escape Redis KEYS pattern special characters: * ? [ ] ^ \
|
|
50
|
-
// Note: We don't escape hyphen (-) as it's not special outside character classes
|
|
51
|
-
return pattern.replace(/[*?[\]^\\]/g, '\\$&');
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export { escapeRedisPattern, sanitizeKeyComponent, sanitizeRedisKey };
|