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

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.
@@ -0,0 +1,236 @@
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
+ }
@@ -0,0 +1,229 @@
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
+ }
@@ -0,0 +1,189 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ /**
3
+ * @file redisCommonTypes.ts
4
+ * @description Defines common types and interfaces used across the Redis data access layer.
5
+ * These types provide a standardized approach to working with Redis operations, including
6
+ * key management, caching, and storage patterns.
7
+ *
8
+ * Key components include:
9
+ * - RedisKeyOptions: Configuration for building standardized Redis keys
10
+ * - RedisNamespace: Enum for organizing keys into logical namespaces
11
+ * - CacheContext: Context information for cache operations (tenant, user, org)
12
+ * - CachePolicy: Configuration for cache TTL and scope
13
+ * - RedisValue: Union type for values that can be stored in Redis
14
+ * - RedisHashValue: Type for Redis hash field values
15
+ * - RedisScanOptions: Options for scanning Redis keys
16
+ *
17
+ * These types ensure consistency across Redis operations, providing type safety and
18
+ * clear contracts for data caching and storage throughout the application.
19
+ *
20
+ * @see IRedisCacheManager - Cache manager interface using these types
21
+ * @see IRedisStorageBackend - Storage backend interface using these types
22
+ * @see IRedisKeyBuilder - Key builder interface using these types
23
+ */
24
+
25
+ /**
26
+ * Options for building Redis keys with standardized format
27
+ *
28
+ * @property tenantId - Tenant ID for multi-tenant isolation (defaults to 'default')
29
+ * @property namespace - Namespace to categorize keys (e.g., 'cache', 'session', 'storage')
30
+ * @property segments - Additional key segments to append
31
+ * @property userId - Optional user ID for user-specific keys
32
+ *
33
+ * @example
34
+ * const keyOptions: RedisKeyOptions = {
35
+ * tenantId: 'tenant-123',
36
+ * namespace: RedisNamespace.CACHE,
37
+ * segments: ['user', 'profile']
38
+ * };
39
+ * // Produces key: APP_NAME:tenant-123:cache:user:profile
40
+ */
41
+ export interface RedisKeyOptions {
42
+ tenantId?: string;
43
+ namespace: string;
44
+ segments: string[];
45
+ userId?: string;
46
+ }
47
+
48
+ /**
49
+ * Standard Redis namespaces for organizing keys
50
+ * Using namespaces helps prevent key collisions and makes bulk operations easier
51
+ *
52
+ * @example
53
+ * // Use namespaces to organize cache keys
54
+ * const cacheKey = buildRedisKey({
55
+ * tenantId: 'tenant-123',
56
+ * namespace: RedisNamespace.CACHE,
57
+ * segments: ['query', 'users']
58
+ * });
59
+ */
60
+ export enum RedisNamespace {
61
+ CACHE = 'cache',
62
+ SESSION = 'session',
63
+ TENANT = 'tenant',
64
+ CONFIG = 'config',
65
+ EXTENSION = 'extension',
66
+ CONTRIBUTION = 'contribution',
67
+ STORAGE = 'storage',
68
+ PERMISSION = 'permission',
69
+ TEMP = 'temp',
70
+ QUEUE = 'queue',
71
+ LOCK = 'lock',
72
+ }
73
+
74
+ /**
75
+ * Context for cache operations
76
+ * Provides tenant, user, and organization isolation for cached data
77
+ *
78
+ * @property tenantId - Tenant identifier for multi-tenant applications
79
+ * @property userId - User identifier for user-specific caching
80
+ * @property orgId - Organization identifier for org-level caching
81
+ *
82
+ * @example
83
+ * const ctx: CacheContext = {
84
+ * tenantId: 'tenant-123',
85
+ * userId: 'user-456',
86
+ * orgId: 'org-789'
87
+ * };
88
+ */
89
+ export interface CacheContext {
90
+ tenantId?: string;
91
+ userId?: string;
92
+ orgId?: string;
93
+ }
94
+
95
+ /**
96
+ * Cache policy for controlling cache behavior
97
+ *
98
+ * @property maxAge - Maximum age in seconds (TTL)
99
+ * @property scope - Cache scope (PUBLIC, PRIVATE, etc.)
100
+ *
101
+ * @example
102
+ * const policy: CachePolicy = {
103
+ * maxAge: 3600, // 1 hour
104
+ * scope: 'PRIVATE'
105
+ * };
106
+ */
107
+ export interface CachePolicy {
108
+ maxAge: number;
109
+ scope?: string;
110
+ }
111
+
112
+ /**
113
+ * Union type for values that can be stored in Redis
114
+ * Covers most common data types stored in Redis
115
+ */
116
+ export type RedisValue = string | number | Buffer | null;
117
+
118
+ /**
119
+ * Type for Redis hash field values
120
+ * Hashes in Redis store field-value pairs
121
+ */
122
+ export type RedisHashValue = Record<string, string>;
123
+
124
+ /**
125
+ * Options for scanning Redis keys
126
+ * Used for iterating through keys matching a pattern
127
+ *
128
+ * @property match - Pattern to match keys (supports wildcards)
129
+ * @property count - Number of keys to return per iteration
130
+ * @property type - Optional Redis data type to filter by
131
+ *
132
+ * @example
133
+ * const scanOptions: RedisScanOptions = {
134
+ * match: 'APP:tenant-*:cache:*',
135
+ * count: 100,
136
+ * type: 'string'
137
+ * };
138
+ */
139
+ export interface RedisScanOptions {
140
+ match?: string;
141
+ count?: number;
142
+ type?: 'string' | 'list' | 'set' | 'zset' | 'hash' | 'stream';
143
+ }
144
+
145
+ /**
146
+ * Result from a Redis SCAN operation
147
+ *
148
+ * @property cursor - Next cursor position (0 means scan is complete)
149
+ * @property keys - Array of keys matching the scan criteria
150
+ */
151
+ export interface RedisScanResult {
152
+ cursor: string;
153
+ keys: string[];
154
+ }
155
+
156
+ /**
157
+ * Options for Redis bulk operations
158
+ * Used when performing operations on multiple keys
159
+ *
160
+ * @property pipeline - Whether to use Redis pipeline for batch operations
161
+ * @property transaction - Whether to wrap operations in a MULTI/EXEC transaction
162
+ */
163
+ export interface RedisBulkOptions {
164
+ pipeline?: boolean;
165
+ transaction?: boolean;
166
+ }
167
+
168
+ /**
169
+ * Redis connection configuration
170
+ *
171
+ * @property host - Redis server host
172
+ * @property port - Redis server port
173
+ * @property password - Optional password for authentication
174
+ * @property db - Database number to use
175
+ * @property keyPrefix - Prefix to add to all keys
176
+ * @property maxRetriesPerRequest - Maximum retry attempts
177
+ * @property enableReadyCheck - Whether to check connection is ready
178
+ * @property lazyConnect - Whether to delay connection until first command
179
+ */
180
+ export interface RedisConnectionConfig {
181
+ host?: string;
182
+ port?: number;
183
+ password?: string;
184
+ db?: number;
185
+ keyPrefix?: string;
186
+ maxRetriesPerRequest?: number;
187
+ enableReadyCheck?: boolean;
188
+ lazyConnect?: boolean;
189
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Redis utility functions
3
+ */
4
+ export * from './redis-key-builder';
5
+ export * from './redis-key-sanitizer';
@@ -0,0 +1,32 @@
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;