diff --git a/libs/app/app.module.ts b/libs/app/app.module.ts index e056237..17e4e4d 100644 --- a/libs/app/app.module.ts +++ b/libs/app/app.module.ts @@ -1,5 +1,7 @@ import { Module, OnApplicationBootstrap } from '@nestjs/common'; +import { ConfigModule, ConfigService } from '@nestjs/config'; +import { REDIS_CONFIG, RedisConfig } from './redis.config'; import { OnRedisPub, RedisPubPayloadParam } from '../decorators'; import { RedisPubPayload } from '../implements'; import { RedisModule } from '../redis.module'; @@ -7,12 +9,19 @@ import { RedisPub } from '../redis.pub'; @Module({ imports: [ - RedisModule.register({ - host: 'localhost', - port: 6380, - db: 0, - pub: { use: true }, - sub: { use: true, channels: ['welcome'] }, + ConfigModule.forRoot({ + isGlobal: true, + load: [RedisConfig], + }), + RedisModule.forRootAsync({ + inject: [ConfigService], + useFactory(configService: ConfigService) { + return { + ...configService.get(REDIS_CONFIG), + pub: { use: true }, + sub: { use: true, channels: ['welcome'] }, + }; + }, }), ], }) diff --git a/libs/app/redis.config.ts b/libs/app/redis.config.ts new file mode 100644 index 0000000..b1488df --- /dev/null +++ b/libs/app/redis.config.ts @@ -0,0 +1,12 @@ +import { registerAs } from '@nestjs/config'; +import { RedisModuleOptions } from 'libs/interfaces'; + +export const REDIS_CONFIG = '__REDIS_CONFIG__'; +export const RedisConfig = registerAs( + REDIS_CONFIG, + (): RedisModuleOptions => ({ + host: 'localhost', + port: 6380, + db: 0, + }), +); diff --git a/libs/interfaces/redis-module-options.interface.ts b/libs/interfaces/redis-module-options.interface.ts index abac43e..d591653 100644 --- a/libs/interfaces/redis-module-options.interface.ts +++ b/libs/interfaces/redis-module-options.interface.ts @@ -5,7 +5,6 @@ import { RedisPubOptions } from './redis-pub-options.interface'; import { RedisSubOptions } from './redis-sub-options.interface'; export interface RedisModuleOptions extends RedisOptions { - global?: boolean; pub?: RedisPubOptions; sub?: RedisSubOptions; } diff --git a/libs/redis.module.ts b/libs/redis.module.ts index f3172d5..5cae838 100644 --- a/libs/redis.module.ts +++ b/libs/redis.module.ts @@ -1,14 +1,14 @@ import { DynamicModule, Module, Provider, Type } from '@nestjs/common'; import { EventEmitterModule, EventEmitter2 } from '@nestjs/event-emitter'; -import { Redis, RedisOptions } from 'ioredis'; +import { Redis } from 'ioredis'; -import { RedisModuleAsyncOptions, RedisModuleOptions, RedisPubOptions, RedisSubOptions } from './interfaces'; +import { RedisModuleAsyncOptions, RedisModuleOptions } from './interfaces'; import { RedisPub } from './redis.pub'; import { RedisSub } from './redis.sub'; @Module({}) export class RedisModule { - private static createProviders(redisOptions: RedisOptions, pubOptions?: RedisPubOptions, subOptions?: RedisSubOptions) { + static forRoot({ pub, sub, ...redisOptions }: RedisModuleOptions): DynamicModule { const providers: Array | Provider> = [ { provide: Redis, @@ -18,32 +18,28 @@ export class RedisModule { }, ]; - if (pubOptions?.use) { + if (pub?.use) { providers.push({ inject: [Redis], provide: RedisPub, useFactory(redis: Redis) { - return new RedisPub(redis.duplicate(), pubOptions); + return new RedisPub(redis.duplicate(), pub); }, }); } - if (subOptions?.use) { + if (sub?.use) { providers.push({ inject: [Redis, EventEmitter2], provide: RedisSub, useFactory(redis: Redis, eventEmitter: EventEmitter2) { - return new RedisSub(redis.duplicate(), subOptions, eventEmitter); + return new RedisSub(redis.duplicate(), sub, eventEmitter); }, }); } - return providers; - } - - private static createDynamicModule(providers: Array>, global?: boolean): DynamicModule { return { - global, + global: true, module: RedisModule, imports: [EventEmitterModule.forRoot({ global: false })], providers, @@ -51,11 +47,46 @@ export class RedisModule { }; } - static register({ global, pub, sub, ...redisOptions }: RedisModuleOptions): DynamicModule { - return this.createDynamicModule(this.createProviders(redisOptions, pub, sub), global); - } + static async forRootAsync(moduleAsyncOptions: RedisModuleAsyncOptions) { + const providers: Array | Provider> = [ + { + provide: Redis, + inject: moduleAsyncOptions.inject, + async useFactory(...dependencies) { + const options = await moduleAsyncOptions.useFactory(...dependencies); + return new Redis(options); + }, + }, + { + provide: RedisPub, + inject: [Redis, ...moduleAsyncOptions.inject], + async useFactory(redis, ...dependencies) { + const options = await moduleAsyncOptions.useFactory(...dependencies); - static async registerAsync(moduleAsyncOptions: RedisModuleAsyncOptions) { - return this.register(await moduleAsyncOptions.useFactory(...moduleAsyncOptions.inject)); + if (options.pub?.use) { + return new RedisPub(redis, options.pub); + } + }, + }, + { + provide: RedisSub, + inject: [Redis, EventEmitter2, ...moduleAsyncOptions.inject], + async useFactory(redis: Redis, eventEmitter, ...dependencies) { + const options = await moduleAsyncOptions.useFactory(...dependencies); + + if (options.sub?.use) { + return new RedisSub(redis.duplicate(), options.sub, eventEmitter); + } + }, + }, + ]; + + return { + global: true, + module: RedisModule, + imports: [EventEmitterModule.forRoot({ global: false })], + providers, + exports: providers, + }; } } diff --git a/package-lock.json b/package-lock.json index 682595f..554fb35 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "reflect-metadata": "^0.2.1" }, "devDependencies": { + "@nestjs/config": "^3.2.0", "@nestjs/core": "^10.3.3", "@nestjs/platform-express": "^10.3.3", "@typescript-eslint/eslint-plugin": "^7.2.0", @@ -207,6 +208,22 @@ } } }, + "node_modules/@nestjs/config": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@nestjs/config/-/config-3.2.0.tgz", + "integrity": "sha512-BpYRn57shg7CH35KGT6h+hT7ZucB6Qn2B3NBNdvhD4ApU8huS5pX/Wc2e/aO5trIha606Bz2a9t9/vbiuTBTww==", + "dev": true, + "dependencies": { + "dotenv": "16.4.1", + "dotenv-expand": "10.0.0", + "lodash": "4.17.21", + "uuid": "9.0.1" + }, + "peerDependencies": { + "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0", + "rxjs": "^7.1.0" + } + }, "node_modules/@nestjs/core": { "version": "10.3.3", "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-10.3.3.tgz", @@ -1392,6 +1409,27 @@ "node": ">=6.0.0" } }, + "node_modules/dotenv": { + "version": "16.4.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.1.tgz", + "integrity": "sha512-CjA3y+Dr3FyFDOAMnxZEGtnW9KBR2M0JvvUtXNW+dYJL5ROWxP9DUHCwgFqpMk0OXCc0ljhaNTr2w/kutYIcHQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/motdotla/dotenv?sponsor=1" + } + }, + "node_modules/dotenv-expand": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-10.0.0.tgz", + "integrity": "sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==", + "dev": true, + "engines": { + "node": ">=12" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -3062,6 +3100,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, "node_modules/lodash.defaults": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", @@ -4904,6 +4948,19 @@ "node": ">= 0.4.0" } }, + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", diff --git a/package.json b/package.json index d4b6439..5fac222 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "reflect-metadata": "^0.2.1" }, "devDependencies": { + "@nestjs/config": "^3.2.0", "@nestjs/core": "^10.3.3", "@nestjs/platform-express": "^10.3.3", "@typescript-eslint/eslint-plugin": "^7.2.0",