@common-stack/store-redis 8.2.5-alpha.33 → 8.2.5-alpha.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/lib/containers/container.d.ts +2 -0
  2. package/lib/containers/container.js +3 -0
  3. package/lib/containers/container.js.map +1 -0
  4. package/lib/containers/index.d.ts +1 -0
  5. package/lib/core/index.d.ts +3 -0
  6. package/lib/core/ioredis.d.ts +15 -0
  7. package/lib/core/ioredis.js +27 -0
  8. package/lib/core/ioredis.js.map +1 -0
  9. package/lib/core/keyBuilder/generate-query-cache-key.d.ts +57 -0
  10. package/lib/core/keyBuilder/generate-query-cache-key.js +82 -0
  11. package/lib/core/keyBuilder/generate-query-cache-key.js.map +1 -0
  12. package/lib/core/keyBuilder/index.d.ts +18 -0
  13. package/lib/core/keyBuilder/index.js +20 -0
  14. package/lib/core/keyBuilder/index.js.map +1 -0
  15. package/lib/core/keyBuilder/redis-key-builder.d.ts +152 -0
  16. package/lib/core/keyBuilder/redis-key-builder.js +181 -0
  17. package/lib/core/keyBuilder/redis-key-builder.js.map +1 -0
  18. package/lib/core/keyBuilder/sanitize-redis-key.d.ts +118 -0
  19. package/lib/core/keyBuilder/sanitize-redis-key.js +115 -0
  20. package/lib/core/keyBuilder/sanitize-redis-key.js.map +1 -0
  21. package/lib/core/upstash-redis.d.ts +14 -0
  22. package/lib/core/upstash-redis.js +23 -0
  23. package/lib/core/upstash-redis.js.map +1 -0
  24. package/lib/graphql/schema/base-services.graphql +134 -0
  25. package/lib/index.d.ts +2 -1
  26. package/lib/index.js +1 -3
  27. package/lib/index.js.map +1 -0
  28. package/lib/interfaces/index.d.ts +1 -6
  29. package/lib/interfaces/redis.d.ts +11 -0
  30. package/lib/module.d.ts +2 -0
  31. package/lib/module.js +4 -0
  32. package/lib/module.js.map +1 -0
  33. package/lib/services/RedisCacheManager.d.ts +77 -0
  34. package/lib/services/RedisCacheManager.js +177 -0
  35. package/lib/services/RedisCacheManager.js.map +1 -0
  36. package/lib/services/index.d.ts +1 -5
  37. package/lib/templates/constants/SERVER_TYPES.ts.template +0 -1
  38. package/lib/templates/repositories/IRedisKeyBuilder.ts.template +4 -4
  39. package/lib/templates/repositories/redisCommonTypes.ts.template +2 -163
  40. package/lib/templates/{repositories/IRedisCacheManager.ts.template → services/RedisCacheManager.ts.template} +7 -7
  41. package/package.json +8 -7
  42. package/lib/interfaces/cache-manager.d.ts +0 -28
  43. package/lib/interfaces/redis-key-options.d.ts +0 -35
  44. package/lib/interfaces/redis-key-options.js +0 -17
  45. package/lib/interfaces/storage-backend.d.ts +0 -17
  46. package/lib/templates/repositories/IRedisService.ts.template +0 -236
  47. package/lib/templates/repositories/IRedisStorageBackend.ts.template +0 -229
  48. package/lib/utils/index.d.ts +0 -5
  49. package/lib/utils/redis-key-builder.d.ts +0 -32
  50. package/lib/utils/redis-key-builder.js +0 -68
  51. package/lib/utils/redis-key-sanitizer.d.ts +0 -30
  52. package/lib/utils/redis-key-sanitizer.js +0 -54
@@ -1,236 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
- /**
3
- * @file IRedisService.ts
4
- * @description Defines the IRedisService interface for advanced Redis operations and patterns.
5
- * This interface provides high-level Redis operations beyond simple key-value storage,
6
- * including pub/sub, streams, sorted sets, and distributed locking.
7
- *
8
- * The Redis service is designed for:
9
- * - Pub/Sub messaging patterns
10
- * - Distributed locking (mutex)
11
- * - Rate limiting
12
- * - Leaderboards and rankings (sorted sets)
13
- * - Event streams
14
- * - Queue management
15
- *
16
- * Key features:
17
- * - Pub/Sub for real-time messaging
18
- * - Distributed locks for resource coordination
19
- * - Rate limiting for API throttling
20
- * - Sorted sets for rankings and leaderboards
21
- * - Redis Streams for event sourcing
22
- * - Pipeline operations for performance
23
- *
24
- * This service layer provides advanced Redis patterns that go beyond simple caching
25
- * and storage, enabling sophisticated distributed system architectures.
26
- *
27
- * @see IRedisCacheManager - For query caching
28
- * @see IRedisStorageBackend - For simple key-value storage
29
- */
30
-
31
- export interface IRedisService {
32
- /**
33
- * Publish a message to a Redis channel
34
- * Part of the Pub/Sub pattern for real-time messaging
35
- *
36
- * @param channel - Channel name to publish to
37
- * @param message - Message to publish (will be stringified if object)
38
- * @returns Promise resolving to number of subscribers that received the message
39
- *
40
- * @example
41
- * // Publish user update event
42
- * await redisService.publish('user:updates', JSON.stringify({
43
- * userId: '123',
44
- * action: 'updated'
45
- * }));
46
- */
47
- publish(channel: string, message: string): Promise<number>;
48
-
49
- /**
50
- * Subscribe to a Redis channel
51
- * Receives messages published to the channel
52
- *
53
- * @param channel - Channel name to subscribe to
54
- * @param callback - Function called when message received
55
- * @returns Promise that resolves when subscribed
56
- *
57
- * @example
58
- * // Subscribe to user updates
59
- * await redisService.subscribe('user:updates', (message) => {
60
- * const event = JSON.parse(message);
61
- * console.log(`User ${event.userId} was ${event.action}`);
62
- * });
63
- */
64
- subscribe(channel: string, callback: (message: string) => void): Promise<void>;
65
-
66
- /**
67
- * Unsubscribe from a Redis channel
68
- *
69
- * @param channel - Channel name to unsubscribe from
70
- * @returns Promise that resolves when unsubscribed
71
- *
72
- * @example
73
- * // Unsubscribe from updates
74
- * await redisService.unsubscribe('user:updates');
75
- */
76
- unsubscribe(channel: string): Promise<void>;
77
-
78
- /**
79
- * Acquire a distributed lock
80
- * Ensures only one process can execute critical section
81
- *
82
- * @param key - Lock key (unique identifier for the resource)
83
- * @param ttl - Lock TTL in milliseconds (auto-release if process dies)
84
- * @param retries - Number of retry attempts
85
- * @returns Promise resolving to lock token (needed for release) or null if failed
86
- *
87
- * @example
88
- * // Acquire lock for order processing
89
- * const lock = await redisService.acquireLock('order:123:processing', 5000);
90
- * if (lock) {
91
- * try {
92
- * await processOrder('123');
93
- * } finally {
94
- * await redisService.releaseLock('order:123:processing', lock);
95
- * }
96
- * }
97
- */
98
- acquireLock(key: string, ttl: number, retries?: number): Promise<string | null>;
99
-
100
- /**
101
- * Release a distributed lock
102
- * Only the process that acquired the lock can release it
103
- *
104
- * @param key - Lock key
105
- * @param token - Lock token returned from acquireLock
106
- * @returns Promise resolving to true if lock was released
107
- *
108
- * @example
109
- * // Release lock after critical section
110
- * await redisService.releaseLock('resource:123', lockToken);
111
- */
112
- releaseLock(key: string, token: string): Promise<boolean>;
113
-
114
- /**
115
- * Check rate limit for a key
116
- * Implements sliding window rate limiting
117
- *
118
- * @param key - Rate limit key (e.g., userId or IP address)
119
- * @param limit - Maximum requests allowed
120
- * @param window - Time window in seconds
121
- * @returns Promise resolving to object with allowed status and remaining count
122
- *
123
- * @example
124
- * // Check API rate limit
125
- * const rateLimitStatus = await redisService.checkRateLimit(
126
- * `api:user:${userId}`,
127
- * 100, // 100 requests
128
- * 3600 // per hour
129
- * );
130
- *
131
- * if (!rateLimitStatus.allowed) {
132
- * throw new Error('Rate limit exceeded');
133
- * }
134
- */
135
- checkRateLimit(
136
- key: string,
137
- limit: number,
138
- window: number
139
- ): Promise<{
140
- allowed: boolean;
141
- remaining: number;
142
- resetAt: number;
143
- }>;
144
-
145
- /**
146
- * Add member to sorted set with score
147
- * Useful for leaderboards, rankings, and time-ordered data
148
- *
149
- * @param key - Sorted set key
150
- * @param score - Score for ordering (lower scores first)
151
- * @param member - Member to add
152
- * @returns Promise resolving to number of elements added
153
- *
154
- * @example
155
- * // Add user score to leaderboard
156
- * await redisService.sortedSetAdd('leaderboard:game1', 1000, 'user-123');
157
- */
158
- sortedSetAdd(key: string, score: number, member: string): Promise<number>;
159
-
160
- /**
161
- * Get top members from sorted set
162
- *
163
- * @param key - Sorted set key
164
- * @param start - Start index (0-based)
165
- * @param stop - Stop index (-1 for all)
166
- * @param withScores - Whether to include scores in result
167
- * @returns Promise resolving to array of members (and scores if requested)
168
- *
169
- * @example
170
- * // Get top 10 players
171
- * const topPlayers = await redisService.sortedSetRange(
172
- * 'leaderboard:game1',
173
- * 0,
174
- * 9,
175
- * true
176
- * );
177
- * // Result: [{member: 'user-1', score: 1500}, {member: 'user-2', score: 1400}, ...]
178
- */
179
- sortedSetRange(
180
- key: string,
181
- start: number,
182
- stop: number,
183
- withScores?: boolean
184
- ): Promise<Array<{ member: string; score?: number }>>;
185
-
186
- /**
187
- * Get member rank in sorted set
188
- *
189
- * @param key - Sorted set key
190
- * @param member - Member to get rank for
191
- * @returns Promise resolving to rank (0-based) or null if not found
192
- *
193
- * @example
194
- * // Get user's leaderboard position
195
- * const rank = await redisService.sortedSetRank('leaderboard:game1', 'user-123');
196
- * console.log(`You are ranked #${rank + 1}`);
197
- */
198
- sortedSetRank(key: string, member: string): Promise<number | null>;
199
-
200
- /**
201
- * Add entry to Redis Stream
202
- * Useful for event sourcing and message queues
203
- *
204
- * @param key - Stream key
205
- * @param fields - Fields to add to stream entry
206
- * @returns Promise resolving to entry ID
207
- *
208
- * @example
209
- * // Add event to stream
210
- * const entryId = await redisService.streamAdd('events:user-actions', {
211
- * userId: '123',
212
- * action: 'login',
213
- * timestamp: Date.now().toString()
214
- * });
215
- */
216
- streamAdd(key: string, fields: Record<string, string>): Promise<string>;
217
-
218
- /**
219
- * Read entries from Redis Stream
220
- *
221
- * @param key - Stream key
222
- * @param options - Read options (count, id to start from)
223
- * @returns Promise resolving to array of stream entries
224
- *
225
- * @example
226
- * // Read last 100 events
227
- * const events = await redisService.streamRead('events:user-actions', {
228
- * count: 100,
229
- * id: '0' // Start from beginning
230
- * });
231
- */
232
- streamRead(
233
- key: string,
234
- options?: { count?: number; id?: string }
235
- ): Promise<Array<{ id: string; fields: Record<string, string> }>>;
236
- }
@@ -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
- }
@@ -1,5 +0,0 @@
1
- /**
2
- * Redis utility functions
3
- */
4
- export * from './redis-key-builder';
5
- export * from './redis-key-sanitizer';
@@ -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 };