import Redis from 'ioredis'; import { DynamicModule, Module, OnApplicationShutdown, Provider } from '@nestjs/common'; import { ModuleRef } from '@nestjs/core'; import { CacheService } from './redis.service'; import { REDIS_CLIENT, REDIS_OPTIONS } from './redis.constants'; import { RedisModuleOptions, RedisModuleAsyncOptions } from './redis.interfaces'; @Module({}) export class RedisModule implements OnApplicationShutdown { constructor(private moduleRef: ModuleRef) { } /** * Registers the module with default configuration. * * @param isGlobal - Register in the global scope * @returns A DynamicModule */ static forRootWithConfig(isGlobal = false): DynamicModule { const redisConfig = { host: '10.10.2.15', port: 6379, password: 'your_strong_password_here' }; return RedisModule.forRoot({ config: redisConfig }, isGlobal); } /** * Registers the module synchronously. * * @param options - The module options * @param isGlobal - Register in the global scope * @returns A DynamicModule */ static forRoot(options?: RedisModuleOptions, isGlobal = false): DynamicModule { const redisOptionsProvider: Provider = { provide: REDIS_OPTIONS, useValue: options || {}, }; const redisClientProvider: Provider = { provide: REDIS_CLIENT, useFactory: () => { if (!options || !options.config) { return new Redis() } const { host, port, password } = options.config; return new Redis({ host, port, password }); }, }; return { module: RedisModule, providers: [redisOptionsProvider, redisClientProvider, CacheService], exports: [CacheService], global: isGlobal, }; } /** * Registers the module asynchronously. * * @param options - The async module options * @param isGlobal - Register in the global scope * @returns A DynamicModule */ static forRootAsync(options: RedisModuleAsyncOptions, isGlobal = false): DynamicModule { const redisOptionsProvider: Provider = { provide: REDIS_OPTIONS, useFactory: options.useFactory || (() => ({})), inject: options.inject || [], }; const redisClientProvider: Provider = { provide: REDIS_CLIENT, useFactory: (redisOptions: RedisModuleOptions) => { if (!redisOptions || !redisOptions.config) { return new Redis() } const { host, port, password } = redisOptions.config; return new Redis({ host, port, password }) }, inject: [REDIS_OPTIONS], }; return { module: RedisModule, imports: options.imports || [], providers: [redisOptionsProvider, redisClientProvider, CacheService], exports: [CacheService], global: isGlobal, }; } async onApplicationShutdown() { const client = this.moduleRef.get(REDIS_CLIENT, { strict: false }); if (client && typeof client.quit === 'function') { await client.quit() } } }