import { RedisClientType } from 'redis'; /** * Extract all possible cache key types from a cache key definition object * Recursively extracts string literals and function return types * * @example * ```typescript * const CACHE_KEYS = { * users: { * profile: (userId: number) => `user:${userId}:profile` as const, * }, * } as const; * * type CacheKey = ExtractCacheKeyType; * // Result: "user:${number}:profile" * ``` */ type ExtractCacheKeyType = T extends string ? T : T extends (...args: any[]) => infer R ? R extends string ? R : never : T extends Record ? { [K in keyof T]: ExtractCacheKeyType; }[keyof T] : never; interface RedisGenericClientConfig { prefix: string; isEnabled: boolean; } /** * Generic Redis client with optional type-safe cache keys * @template TCacheKeys - Optional type for cache keys (defaults to string) */ declare class RedisGenericClient { private readonly keyPrefix; private readonly isEnabled; constructor(config: RedisGenericClientConfig); private addPrefix; private removePrefix; isClientEnabled(): boolean; isClientConnected(): boolean; getStatus(): { isEnabled: boolean; prefix: string; isConnected: boolean; isConnecting: boolean; initializationAttempted: boolean; }; set(key: TCacheKeys, value: string): Promise; setObj(key: TCacheKeys, value: T): Promise; setEx(key: TCacheKeys, seconds: number, value: string): Promise; setObjEx(key: TCacheKeys, seconds: number, value: T): Promise; get(key: TCacheKeys): Promise; getObj(key: TCacheKeys): Promise; del(key: TCacheKeys): Promise; delMultiple(keys: TCacheKeys[]): Promise; /** * Delete all keys matching a pattern (Production-safe using SCAN) * @param pattern - Pattern to match (e.g., "games:*" to delete all keys starting with "games:") * @param batchSize - Number of keys to scan per iteration (default: 100) * @returns Number of keys deleted, or null if client is disabled * * @example * ```typescript * // Delete all game-related keys * await cache.delByPattern("games:*"); * * // With type-safe patterns * await cache.delByPattern(CACHE_KEYS.games._pattern); * ``` */ delByPattern(pattern: TCacheKeys | string, batchSize?: number): Promise; exists(key: TCacheKeys): Promise; expire(key: TCacheKeys, seconds: number): Promise; ttl(key: TCacheKeys): Promise; incr(key: TCacheKeys): Promise; incrBy(key: TCacheKeys, increment: number): Promise; decr(key: TCacheKeys): Promise; keys(pattern: string): Promise; hSet(key: TCacheKeys, field: string, value: string): Promise; hGet(key: TCacheKeys, field: string): Promise; hGetAll(key: TCacheKeys): Promise | null>; hDel(key: TCacheKeys, fields: string | string[]): Promise; lPush(key: TCacheKeys, ...elements: string[]): Promise; rPush(key: TCacheKeys, ...elements: string[]): Promise; lPop(key: TCacheKeys): Promise; rPop(key: TCacheKeys): Promise; lRange(key: TCacheKeys, start: number, stop: number): Promise; sAdd(key: TCacheKeys, ...members: string[]): Promise; sMembers(key: TCacheKeys): Promise; sRem(key: TCacheKeys, ...members: string[]): Promise; safeExecute(operation: (client: RedisClientType, addPrefix: (key: string) => string) => Promise): Promise; } type TCreateRedisClient = { prefix: string; isEnabled?: boolean; }; /** * Create a Redis client instance * * @example * ```typescript * // Without type safety (accepts any string) * const cache = createRedisGenericClient({ prefix: "myapp" }); * await cache.set("any:key", "value"); * * // With type safety (only accepts defined cache keys) * const CACHE_KEYS = { * users: { * profile: (userId: number) => `user:${userId}:profile` as const, * }, * } as const; * * type CacheKey = ExtractCacheKeyType; * const cache = createRedisGenericClient({ prefix: "myapp" }); * await cache.set(CACHE_KEYS.users.profile(123), "value"); // ✅ Valid * await cache.set("random:key", "value"); // ❌ Type error * ``` */ declare const createRedisGenericClient: ({ prefix, isEnabled, }: TCreateRedisClient) => RedisGenericClient; export { type ExtractCacheKeyType, RedisGenericClient, createRedisGenericClient };