diff --git a/README.md b/README.md index 86a8ebd..632465c 100644 --- a/README.md +++ b/README.md @@ -1,209 +1,219 @@ - # Nestjs Redis Redis component for NestJs. - ### Installation **Yarn** + ```bash yarn add nestjs-redis ``` **NPM** + ```bash npm install nestjs-redis --save ``` ### Getting Started + Let's register the RedisModule in `app.module.ts` ```typescript -import { Module } from '@nestjs/common' -import { RedisModule} from 'nestjs-redis' +import { Module } from '@nestjs/common'; +import { RedisModule } from 'nestjs-redis'; @Module({ - imports: [ - RedisModule.register(options) - ], + imports: [RedisModule.register(options)], }) export class AppModule {} ``` + With Async + ```typescript import { Module } from '@nestjs/common'; -import { RedisModule} from 'nestjs-redis' +import { RedisModule } from 'nestjs-redis'; @Module({ - imports: [ - RedisModule.forRootAsync({ - useFactory: (configService: ConfigService) => configService.get('redis'), // or use async method - //useFactory: async (configService: ConfigService) => configService.get('redis'), - inject:[ConfigService] - }), - ], + imports: [ + RedisModule.forRootAsync({ + useFactory: (configService: ConfigService) => configService.get('redis'), // or use async method + //useFactory: async (configService: ConfigService) => configService.get('redis'), + inject: [ConfigService], + }), + ], }) export class AppModule {} ``` + And the config file look like this With single client + ```typescript export default { - host: process.env.REDIS_HOST, - port: parseInt(process.env.REDIS_PORT), - db: parseInt(process.env.REDIS_DB), - password: process.env.REDIS_PASSWORD, - keyPrefix: process.env.REDIS_PRIFIX, -} -Or + host: process.env.REDIS_HOST, + port: parseInt(process.env.REDIS_PORT), + db: parseInt(process.env.REDIS_DB), + password: process.env.REDIS_PASSWORD, + keyPrefix: process.env.REDIS_PREFIX, +}; +Or; export default { - url: 'redis://:authpassword@127.0.0.1:6380/4', -} + url: 'redis://:authpassword@127.0.0.1:6380/4', +}; ``` + With custom error handler + ```typescript export default { - url: 'redis://:authpassword@127.0.0.1:6380/4', - onClientReady: (client) => { - client.on('error', (err) => {} - )}, -} + url: 'redis://:authpassword@127.0.0.1:6380/4', + onClientReady: (client) => { + client.on('error', (err) => {}); + }, +}; ``` + With multi client + ```typescript export default [ - { - name:'test1', - url: 'redis://:authpassword@127.0.0.1:6380/4', - }, - { - name:'test2', - host: process.env.REDIS_HOST, - port: parseInt(process.env.REDIS_PORT), - db: parseInt(process.env.REDIS_DB), - password: process.env.REDIS_PASSWORD, - keyPrefix: process.env.REDIS_PRIFIX, - }, -] + { + clientName: 'test1', + url: 'redis://:authpassword@127.0.0.1:6380/4', + }, + { + clientName: 'test2', + host: process.env.REDIS_HOST, + port: parseInt(process.env.REDIS_PORT), + db: parseInt(process.env.REDIS_DB), + password: process.env.REDIS_PASSWORD, + keyPrefix: process.env.REDIS_PRIFIX, + }, +]; ``` + And use in your service + ```typescript import { Injectable } from '@nestjs/common'; import { RedisService } from 'nestjs-redis'; @Injectable() export class TestService { - constructor( - private readonly redisService: RedisService, - ) { } + constructor(private readonly redisService: RedisService) {} async root(): Promise { - const client = await this.redisService.getClient('test') - return true + const client = await this.redisService.getClient('test'); + return true; } } ``` + Options + ```typescript interface RedisOptions { - /** - * client name. default is a uuid, unique. - */ - name?: string; - url?: string; - port?: number; - host?: string; - /** - * 4 (IPv4) or 6 (IPv6), Defaults to 4. - */ - family?: number; - /** - * Local domain socket path. If set the port, host and family will be ignored. - */ - path?: string; - /** - * TCP KeepAlive on the socket with a X ms delay before start. Set to a non-number value to disable keepAlive. - */ - keepAlive?: number; - connectionName?: string; - /** - * If set, client will send AUTH command with the value of this option when connected. - */ - password?: string; - /** - * Database index to use. - */ - db?: number; - /** - * When a connection is established to the Redis server, the server might still be loading - * the database from disk. While loading, the server not respond to any commands. - * To work around this, when this option is true, ioredis will check the status of the Redis server, - * and when the Redis server is able to process commands, a ready event will be emitted. - */ - enableReadyCheck?: boolean; - keyPrefix?: string; - /** - * When the return value isn't a number, ioredis will stop trying to reconnect. - * Fixed in: https://github.com/DefinitelyTyped/DefinitelyTyped/pull/15858 - */ - retryStrategy?(times: number): number | false; - /** - * By default, all pending commands will be flushed with an error every - * 20 retry attempts. That makes sure commands won't wait forever when - * the connection is down. You can change this behavior by setting - * `maxRetriesPerRequest`. - * - * Set maxRetriesPerRequest to `null` to disable this behavior, and - * every command will wait forever until the connection is alive again - * (which is the default behavior before ioredis v4). - */ - maxRetriesPerRequest?: number | null; - /** - * 1/true means reconnect, 2 means reconnect and resend failed command. Returning false will ignore - * the error and do nothing. - */ - reconnectOnError?(error: Error): boolean | 1 | 2; - /** - * By default, if there is no active connection to the Redis server, commands are added to a queue - * and are executed once the connection is "ready" (when enableReadyCheck is true, "ready" means - * the Redis server has loaded the database from disk, otherwise means the connection to the Redis - * server has been established). If this option is false, when execute the command when the connection - * isn't ready, an error will be returned. - */ - enableOfflineQueue?: boolean; - /** - * The milliseconds before a timeout occurs during the initial connection to the Redis server. - * default: 10000. - */ - connectTimeout?: number; - /** - * After reconnected, if the previous connection was in the subscriber mode, client will auto re-subscribe these channels. - * default: true. - */ - autoResubscribe?: boolean; - /** - * If true, client will resend unfulfilled commands(e.g. block commands) in the previous connection when reconnected. - * default: true. - */ - autoResendUnfulfilledCommands?: boolean; - lazyConnect?: boolean; - tls?: tls.ConnectionOptions; - sentinels?: Array<{ host: string; port: number; }>; - name?: string; - /** - * Enable READONLY mode for the connection. Only available for cluster mode. - * default: false. - */ - readOnly?: boolean; - /** - * If you are using the hiredis parser, it's highly recommended to enable this option. - * Create another instance with dropBufferSupport disabled for other commands that you want to return binary instead of string - */ - dropBufferSupport?: boolean; - /** - * Whether to show a friendly error stack. Will decrease the performance significantly. - */ - showFriendlyErrorStack?: boolean; + /** + * client name. default is a uuid, unique. + */ + clientName?: string; + url?: string; + port?: number; + host?: string; + /** + * 4 (IPv4) or 6 (IPv6), Defaults to 4. + */ + family?: number; + /** + * Local domain socket path. If set the port, host and family will be ignored. + */ + path?: string; + /** + * TCP KeepAlive on the socket with a X ms delay before start. Set to a non-number value to disable keepAlive. + */ + keepAlive?: number; + connectionName?: string; + /** + * If set, client will send AUTH command with the value of this option when connected. + */ + password?: string; + /** + * Database index to use. + */ + db?: number; + /** + * When a connection is established to the Redis server, the server might still be loading + * the database from disk. While loading, the server not respond to any commands. + * To work around this, when this option is true, ioredis will check the status of the Redis server, + * and when the Redis server is able to process commands, a ready event will be emitted. + */ + enableReadyCheck?: boolean; + keyPrefix?: string; + /** + * When the return value isn't a number, ioredis will stop trying to reconnect. + * Fixed in: https://github.com/DefinitelyTyped/DefinitelyTyped/pull/15858 + */ + retryStrategy?(times: number): number | false; + /** + * By default, all pending commands will be flushed with an error every + * 20 retry attempts. That makes sure commands won't wait forever when + * the connection is down. You can change this behavior by setting + * `maxRetriesPerRequest`. + * + * Set maxRetriesPerRequest to `null` to disable this behavior, and + * every command will wait forever until the connection is alive again + * (which is the default behavior before ioredis v4). + */ + maxRetriesPerRequest?: number | null; + /** + * 1/true means reconnect, 2 means reconnect and resend failed command. Returning false will ignore + * the error and do nothing. + */ + reconnectOnError?(error: Error): boolean | 1 | 2; + /** + * By default, if there is no active connection to the Redis server, commands are added to a queue + * and are executed once the connection is "ready" (when enableReadyCheck is true, "ready" means + * the Redis server has loaded the database from disk, otherwise means the connection to the Redis + * server has been established). If this option is false, when execute the command when the connection + * isn't ready, an error will be returned. + */ + enableOfflineQueue?: boolean; + /** + * The milliseconds before a timeout occurs during the initial connection to the Redis server. + * default: 10000. + */ + connectTimeout?: number; + /** + * After reconnected, if the previous connection was in the subscriber mode, client will auto re-subscribe these channels. + * default: true. + */ + autoResubscribe?: boolean; + /** + * If true, client will resend unfulfilled commands(e.g. block commands) in the previous connection when reconnected. + * default: true. + */ + autoResendUnfulfilledCommands?: boolean; + lazyConnect?: boolean; + tls?: tls.ConnectionOptions; + sentinels?: Array<{ host: string; port: number }>; + name?: string; + /** + * Enable READONLY mode for the connection. Only available for cluster mode. + * default: false. + */ + readOnly?: boolean; + /** + * If you are using the hiredis parser, it's highly recommended to enable this option. + * Create another instance with dropBufferSupport disabled for other commands that you want to return binary instead of string + */ + dropBufferSupport?: boolean; + /** + * Whether to show a friendly error stack. Will decrease the performance significantly. + */ + showFriendlyErrorStack?: boolean; } ``` + That's it! diff --git a/dist/cluster-core.module.d.ts b/dist/cluster-core.module.d.ts new file mode 100644 index 0000000..2d511ba --- /dev/null +++ b/dist/cluster-core.module.d.ts @@ -0,0 +1,11 @@ +import { DynamicModule, OnModuleDestroy } from '@nestjs/common'; +import { ModuleRef } from '@nestjs/core'; +import type { RedisClusterModuleAsyncOptions, RedisClusterModuleOptions } from './cluster.interface'; +export declare class ClusterCoreModule implements OnModuleDestroy { + private readonly options; + private readonly moduleRef; + constructor(options: RedisClusterModuleOptions | RedisClusterModuleOptions[], moduleRef: ModuleRef); + static register(options: RedisClusterModuleOptions | RedisClusterModuleOptions[]): DynamicModule; + static forRootAsync(options: RedisClusterModuleAsyncOptions): DynamicModule; + onModuleDestroy(): void; +} diff --git a/dist/cluster-core.module.js b/dist/cluster-core.module.js new file mode 100644 index 0000000..799bdd1 --- /dev/null +++ b/dist/cluster-core.module.js @@ -0,0 +1,73 @@ +"use strict"; +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +var __param = (this && this.__param) || function (paramIndex, decorator) { + return function (target, key) { decorator(target, key, paramIndex); } +}; +var ClusterCoreModule_1; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ClusterCoreModule = void 0; +const common_1 = require("@nestjs/common"); +const core_1 = require("@nestjs/core"); +const cluster_provider_1 = require("./cluster.provider"); +const cluster_constants_1 = require("./cluster.constants"); +const cluster_service_1 = require("./cluster.service"); +let ClusterCoreModule = ClusterCoreModule_1 = class ClusterCoreModule { + constructor(options, moduleRef) { + this.options = options; + this.moduleRef = moduleRef; + } + static register(options) { + return { + module: ClusterCoreModule_1, + providers: [ + cluster_provider_1.createCluster(), + { provide: cluster_constants_1.REDIS_CLUSTER_MODULE_OPTIONS, useValue: options }, + ], + exports: [cluster_service_1.RedisClusterService], + }; + } + static forRootAsync(options) { + return { + module: ClusterCoreModule_1, + imports: options.imports, + providers: [cluster_provider_1.createCluster(), cluster_provider_1.createAsyncClusterOptions(options)], + exports: [cluster_service_1.RedisClusterService], + }; + } + onModuleDestroy() { + const closeConnection = ({ clusters, defaultKey, }) => options => { + const name = options.name || defaultKey; + const cluster = clusters.get(name); + if (cluster && !options.keepAlive) { + cluster.disconnect(); + } + }; + const provider = this.moduleRef.get(cluster_constants_1.REDIS_CLUSTER); + const closeClusterConnection = closeConnection(provider); + if (Array.isArray(this.options)) { + this.options.forEach(closeClusterConnection); + } + else { + closeClusterConnection(this.options); + } + } +}; +ClusterCoreModule = ClusterCoreModule_1 = __decorate([ + common_1.Global(), + common_1.Module({ + providers: [cluster_service_1.RedisClusterService], + exports: [cluster_service_1.RedisClusterService], + }), + __param(0, common_1.Inject(cluster_constants_1.REDIS_CLUSTER_MODULE_OPTIONS)), + __metadata("design:paramtypes", [Object, core_1.ModuleRef]) +], ClusterCoreModule); +exports.ClusterCoreModule = ClusterCoreModule; +//# sourceMappingURL=cluster-core.module.js.map \ No newline at end of file diff --git a/dist/cluster-core.module.js.map b/dist/cluster-core.module.js.map new file mode 100644 index 0000000..65056cc --- /dev/null +++ b/dist/cluster-core.module.js.map @@ -0,0 +1 @@ +{"version":3,"file":"cluster-core.module.js","sourceRoot":"","sources":["../lib/cluster-core.module.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AACA,2CAMwB;AACxB,uCAAyC;AAMzC,yDAI4B;AAC5B,2DAG6B;AAC7B,uDAAwD;AAOxD,IAAa,iBAAiB,yBAA9B,MAAa,iBAAiB;IAC5B,YAEmB,OAEc,EACd,SAAoB;QAHpB,YAAO,GAAP,OAAO,CAEO;QACd,cAAS,GAAT,SAAS,CAAW;IACpC,CAAC;IAEJ,MAAM,CAAC,QAAQ,CACb,OAAgE;QAEhE,OAAO;YACL,MAAM,EAAE,mBAAiB;YACzB,SAAS,EAAE;gBACT,gCAAa,EAAE;gBACf,EAAE,OAAO,EAAE,gDAA4B,EAAE,QAAQ,EAAE,OAAO,EAAE;aAC7D;YACD,OAAO,EAAE,CAAC,qCAAmB,CAAC;SAC/B,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,YAAY,CAAC,OAAuC;QACzD,OAAO;YACL,MAAM,EAAE,mBAAiB;YACzB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,SAAS,EAAE,CAAC,gCAAa,EAAE,EAAE,4CAAyB,CAAC,OAAO,CAAC,CAAC;YAChE,OAAO,EAAE,CAAC,qCAAmB,CAAC;SAC/B,CAAC;IACJ,CAAC;IAED,eAAe;QACb,MAAM,eAAe,GAAG,CAAC,EACvB,QAAQ,EACR,UAAU,GACW,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE;YACpC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,UAAU,CAAC;YACxC,MAAM,OAAO,GAAY,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAE5C,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE;gBACjC,OAAO,CAAC,UAAU,EAAE,CAAC;aACtB;QACH,CAAC,CAAC;QAEF,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAuB,iCAAa,CAAC,CAAC;QACzE,MAAM,sBAAsB,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;QAEzD,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;YAC/B,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;SAC9C;aAAM;YACL,sBAAsB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;SACtC;IACH,CAAC;CACF,CAAA;AArDY,iBAAiB;IAL7B,eAAM,EAAE;IACR,eAAM,CAAC;QACN,SAAS,EAAE,CAAC,qCAAmB,CAAC;QAChC,OAAO,EAAE,CAAC,qCAAmB,CAAC;KAC/B,CAAC;IAGG,WAAA,eAAM,CAAC,gDAA4B,CAAC,CAAA;6CAIT,gBAAS;GAN5B,iBAAiB,CAqD7B;AArDY,8CAAiB"} \ No newline at end of file diff --git a/dist/cluster.constants.d.ts b/dist/cluster.constants.d.ts new file mode 100644 index 0000000..258c021 --- /dev/null +++ b/dist/cluster.constants.d.ts @@ -0,0 +1,2 @@ +export declare const REDIS_CLUSTER_MODULE_OPTIONS: unique symbol; +export declare const REDIS_CLUSTER: unique symbol; diff --git a/dist/cluster.constants.js b/dist/cluster.constants.js new file mode 100644 index 0000000..706f6be --- /dev/null +++ b/dist/cluster.constants.js @@ -0,0 +1,6 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.REDIS_CLUSTER = exports.REDIS_CLUSTER_MODULE_OPTIONS = void 0; +exports.REDIS_CLUSTER_MODULE_OPTIONS = Symbol('REDIS_CLUSTER_MODULE_OPTIONS'); +exports.REDIS_CLUSTER = Symbol('REDIS_CLUSTER'); +//# sourceMappingURL=cluster.constants.js.map \ No newline at end of file diff --git a/dist/cluster.constants.js.map b/dist/cluster.constants.js.map new file mode 100644 index 0000000..1b0d931 --- /dev/null +++ b/dist/cluster.constants.js.map @@ -0,0 +1 @@ +{"version":3,"file":"cluster.constants.js","sourceRoot":"","sources":["../lib/cluster.constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,4BAA4B,GAAG,MAAM,CAChD,8BAA8B,CAC/B,CAAC;AACW,QAAA,aAAa,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC"} \ No newline at end of file diff --git a/dist/cluster.interface.d.ts b/dist/cluster.interface.d.ts new file mode 100644 index 0000000..192681c --- /dev/null +++ b/dist/cluster.interface.d.ts @@ -0,0 +1,11 @@ +import type { ModuleMetadata } from '@nestjs/common/interfaces'; +import type { Cluster, ClusterOptions } from 'ioredis'; +export interface RedisClusterModuleOptions extends ClusterOptions { + clientName?: string; + nodes: (string | number | object)[]; + onClusterReady?(cluster: Cluster): Promise; +} +export interface RedisClusterModuleAsyncOptions extends Pick { + useFactory?: (...args: any[]) => RedisClusterModuleOptions | RedisClusterModuleOptions[] | Promise | Promise; + inject?: any[]; +} diff --git a/dist/cluster.interface.js b/dist/cluster.interface.js new file mode 100644 index 0000000..c4f41dc --- /dev/null +++ b/dist/cluster.interface.js @@ -0,0 +1,3 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +//# sourceMappingURL=cluster.interface.js.map \ No newline at end of file diff --git a/dist/cluster.interface.js.map b/dist/cluster.interface.js.map new file mode 100644 index 0000000..f4d916c --- /dev/null +++ b/dist/cluster.interface.js.map @@ -0,0 +1 @@ +{"version":3,"file":"cluster.interface.js","sourceRoot":"","sources":["../lib/cluster.interface.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/dist/cluster.module.d.ts b/dist/cluster.module.d.ts new file mode 100644 index 0000000..3feff9e --- /dev/null +++ b/dist/cluster.module.d.ts @@ -0,0 +1,6 @@ +import { DynamicModule } from '@nestjs/common'; +import type { RedisClusterModuleAsyncOptions, RedisClusterModuleOptions } from './cluster.interface'; +export declare class RedisClusterModule { + static register(options: RedisClusterModuleOptions | RedisClusterModuleOptions[]): DynamicModule; + static forRootAsync(options: RedisClusterModuleAsyncOptions): DynamicModule; +} diff --git a/dist/cluster.module.js b/dist/cluster.module.js new file mode 100644 index 0000000..8005be0 --- /dev/null +++ b/dist/cluster.module.js @@ -0,0 +1,31 @@ +"use strict"; +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var RedisClusterModule_1; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.RedisClusterModule = void 0; +const common_1 = require("@nestjs/common"); +const cluster_core_module_1 = require("./cluster-core.module"); +let RedisClusterModule = RedisClusterModule_1 = class RedisClusterModule { + static register(options) { + return { + module: RedisClusterModule_1, + imports: [cluster_core_module_1.ClusterCoreModule.register(options)], + }; + } + static forRootAsync(options) { + return { + module: RedisClusterModule_1, + imports: [cluster_core_module_1.ClusterCoreModule.forRootAsync(options)], + }; + } +}; +RedisClusterModule = RedisClusterModule_1 = __decorate([ + common_1.Module({}) +], RedisClusterModule); +exports.RedisClusterModule = RedisClusterModule; +//# sourceMappingURL=cluster.module.js.map \ No newline at end of file diff --git a/dist/cluster.module.js.map b/dist/cluster.module.js.map new file mode 100644 index 0000000..87309f8 --- /dev/null +++ b/dist/cluster.module.js.map @@ -0,0 +1 @@ +{"version":3,"file":"cluster.module.js","sourceRoot":"","sources":["../lib/cluster.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAAuD;AAMvD,+DAA0D;AAG1D,IAAa,kBAAkB,0BAA/B,MAAa,kBAAkB;IAC7B,MAAM,CAAC,QAAQ,CACb,OAAgE;QAEhE,OAAO;YACL,MAAM,EAAE,oBAAkB;YAC1B,OAAO,EAAE,CAAC,uCAAiB,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;SAC/C,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,YAAY,CAAC,OAAuC;QACzD,OAAO;YACL,MAAM,EAAE,oBAAkB;YAC1B,OAAO,EAAE,CAAC,uCAAiB,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;SACnD,CAAC;IACJ,CAAC;CACF,CAAA;AAhBY,kBAAkB;IAD9B,eAAM,CAAC,EAAE,CAAC;GACE,kBAAkB,CAgB9B;AAhBY,gDAAkB"} \ No newline at end of file diff --git a/dist/cluster.provider.d.ts b/dist/cluster.provider.d.ts new file mode 100644 index 0000000..855518b --- /dev/null +++ b/dist/cluster.provider.d.ts @@ -0,0 +1,16 @@ +import { Provider } from '@nestjs/common'; +import { Cluster } from 'ioredis'; +import type { RedisClusterModuleAsyncOptions, RedisClusterModuleOptions } from './cluster.interface'; +export declare class RedisClusterError extends Error { +} +export interface RedisClusterProvider { + defaultKey: string; + clusters: Map; + size: number; +} +export declare const createCluster: () => Provider; +export declare const createAsyncClusterOptions: (options: RedisClusterModuleAsyncOptions) => { + provide: symbol; + useFactory: (...args: any[]) => RedisClusterModuleOptions | Promise | RedisClusterModuleOptions[] | Promise; + inject: any[]; +}; diff --git a/dist/cluster.provider.js b/dist/cluster.provider.js new file mode 100644 index 0000000..33896df --- /dev/null +++ b/dist/cluster.provider.js @@ -0,0 +1,51 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.createAsyncClusterOptions = exports.createCluster = exports.RedisClusterError = void 0; +const uuid_1 = require("uuid"); +const ioredis_1 = require("ioredis"); +const cluster_constants_1 = require("./cluster.constants"); +class RedisClusterError extends Error { +} +exports.RedisClusterError = RedisClusterError; +async function getCluster(options) { + const { onClusterReady, nodes, ...opt } = options; + const cluster = new ioredis_1.Cluster(nodes, opt); + if (onClusterReady) { + onClusterReady(cluster); + } + return cluster; +} +exports.createCluster = () => ({ + provide: cluster_constants_1.REDIS_CLUSTER, + useFactory: async (options) => { + const clusters = new Map(); + let defaultKey = uuid_1.v4(); + if (Array.isArray(options)) { + await Promise.all(options.map(async (o) => { + const key = o.clientName || defaultKey; + if (clusters.has(key)) { + throw new RedisClusterError(`${o.clientName || 'default'} cluster already exists`); + } + clusters.set(key, await getCluster(o)); + })); + } + else { + if (options.clientName && options.clientName.length !== 0) { + defaultKey = options.clientName; + } + clusters.set(defaultKey, await getCluster(options)); + } + return { + defaultKey, + clusters, + size: clusters.size, + }; + }, + inject: [cluster_constants_1.REDIS_CLUSTER_MODULE_OPTIONS], +}); +exports.createAsyncClusterOptions = (options) => ({ + provide: cluster_constants_1.REDIS_CLUSTER_MODULE_OPTIONS, + useFactory: options.useFactory, + inject: options.inject, +}); +//# sourceMappingURL=cluster.provider.js.map \ No newline at end of file diff --git a/dist/cluster.provider.js.map b/dist/cluster.provider.js.map new file mode 100644 index 0000000..691f58f --- /dev/null +++ b/dist/cluster.provider.js.map @@ -0,0 +1 @@ +{"version":3,"file":"cluster.provider.js","sourceRoot":"","sources":["../lib/cluster.provider.ts"],"names":[],"mappings":";;;AAAA,+BAAkC;AAElC,qCAAkC;AAMlC,2DAG6B;AAE7B,MAAa,iBAAkB,SAAQ,KAAK;CAAG;AAA/C,8CAA+C;AAO/C,KAAK,UAAU,UAAU,CAAC,OAAkC;IAC1D,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,GAAG,GAAG,EAAE,GAAG,OAAO,CAAC;IAClD,MAAM,OAAO,GAAG,IAAI,iBAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAExC,IAAI,cAAc,EAAE;QAClB,cAAc,CAAC,OAAO,CAAC,CAAC;KACzB;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAEY,QAAA,aAAa,GAAG,GAAa,EAAE,CAAC,CAAC;IAC5C,OAAO,EAAE,iCAAa;IACtB,UAAU,EAAE,KAAK,EACf,OAAgE,EACjC,EAAE;QACjC,MAAM,QAAQ,GAAyB,IAAI,GAAG,EAAmB,CAAC;QAClE,IAAI,UAAU,GAAG,SAAI,EAAE,CAAC;QAExB,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;YAC1B,MAAM,OAAO,CAAC,GAAG,CACf,OAAO,CAAC,GAAG,CAAC,KAAK,EAAC,CAAC,EAAC,EAAE;gBACpB,MAAM,GAAG,GAAW,CAAC,CAAC,UAAU,IAAI,UAAU,CAAC;gBAC/C,IAAI,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;oBACrB,MAAM,IAAI,iBAAiB,CACzB,GAAG,CAAC,CAAC,UAAU,IAAI,SAAS,yBAAyB,CACtD,CAAC;iBACH;gBACD,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;YACzC,CAAC,CAAC,CACH,CAAC;SACH;aAAM;YACL,IAAI,OAAO,CAAC,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE;gBACzD,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;aACjC;YACD,QAAQ,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;SACrD;QAED,OAAO;YACL,UAAU;YACV,QAAQ;YACR,IAAI,EAAE,QAAQ,CAAC,IAAI;SACpB,CAAC;IACJ,CAAC;IACD,MAAM,EAAE,CAAC,gDAA4B,CAAC;CACvC,CAAC,CAAC;AAEU,QAAA,yBAAyB,GAAG,CACvC,OAAuC,EACvC,EAAE,CAAC,CAAC;IACJ,OAAO,EAAE,gDAA4B;IACrC,UAAU,EAAE,OAAO,CAAC,UAAU;IAC9B,MAAM,EAAE,OAAO,CAAC,MAAM;CACvB,CAAC,CAAC"} \ No newline at end of file diff --git a/dist/cluster.service.d.ts b/dist/cluster.service.d.ts new file mode 100644 index 0000000..00ca5ef --- /dev/null +++ b/dist/cluster.service.d.ts @@ -0,0 +1,8 @@ +import { Cluster } from 'ioredis'; +import { RedisClusterProvider } from './cluster.provider'; +export declare class RedisClusterService { + private readonly provider; + constructor(provider: RedisClusterProvider); + getCluster(clientName?: string): Cluster; + getClusters(): Map; +} diff --git a/dist/cluster.service.js b/dist/cluster.service.js new file mode 100644 index 0000000..35954e0 --- /dev/null +++ b/dist/cluster.service.js @@ -0,0 +1,42 @@ +"use strict"; +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +var __param = (this && this.__param) || function (paramIndex, decorator) { + return function (target, key) { decorator(target, key, paramIndex); } +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.RedisClusterService = void 0; +const common_1 = require("@nestjs/common"); +const cluster_constants_1 = require("./cluster.constants"); +const cluster_provider_1 = require("./cluster.provider"); +let RedisClusterService = class RedisClusterService { + constructor(provider) { + this.provider = provider; + } + getCluster(clientName) { + if (!clientName) { + clientName = this.provider.defaultKey; + } + if (!this.provider.clusters.has(clientName)) { + throw new cluster_provider_1.RedisClusterError(`cluster ${clientName} does not exist`); + } + return this.provider.clusters.get(clientName); + } + getClusters() { + return this.provider.clusters; + } +}; +RedisClusterService = __decorate([ + common_1.Injectable(), + __param(0, common_1.Inject(cluster_constants_1.REDIS_CLUSTER)), + __metadata("design:paramtypes", [Object]) +], RedisClusterService); +exports.RedisClusterService = RedisClusterService; +//# sourceMappingURL=cluster.service.js.map \ No newline at end of file diff --git a/dist/cluster.service.js.map b/dist/cluster.service.js.map new file mode 100644 index 0000000..dbd152d --- /dev/null +++ b/dist/cluster.service.js.map @@ -0,0 +1 @@ +{"version":3,"file":"cluster.service.js","sourceRoot":"","sources":["../lib/cluster.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAAoD;AACpD,2DAAoD;AAEpD,yDAA6E;AAG7E,IAAa,mBAAmB,GAAhC,MAAa,mBAAmB;IAC9B,YAC0C,QAA8B;QAA9B,aAAQ,GAAR,QAAQ,CAAsB;IACrE,CAAC;IAEJ,UAAU,CAAC,UAAmB;QAC5B,IAAI,CAAC,UAAU,EAAE;YACf,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC;SACvC;QAED,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE;YAC3C,MAAM,IAAI,oCAAiB,CAAC,WAAW,UAAU,iBAAiB,CAAC,CAAC;SACrE;QACD,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAChD,CAAC;IAED,WAAW;QACT,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;IAChC,CAAC;CACF,CAAA;AAnBY,mBAAmB;IAD/B,mBAAU,EAAE;IAGR,WAAA,eAAM,CAAC,iCAAa,CAAC,CAAA;;GAFb,mBAAmB,CAmB/B;AAnBY,kDAAmB"} \ No newline at end of file diff --git a/dist/index.d.ts b/dist/index.d.ts index 3aae4f1..8c026e3 100644 --- a/dist/index.d.ts +++ b/dist/index.d.ts @@ -1,3 +1,6 @@ export * from './redis.service'; export * from './redis.module'; export * from './redis.interface'; +export * from './cluster.service'; +export * from './cluster.module'; +export * from './cluster.interface'; diff --git a/dist/index.js b/dist/index.js index 2c4f126..4a73d76 100644 --- a/dist/index.js +++ b/dist/index.js @@ -13,3 +13,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); __exportStar(require("./redis.service"), exports); __exportStar(require("./redis.module"), exports); __exportStar(require("./redis.interface"), exports); +__exportStar(require("./cluster.service"), exports); +__exportStar(require("./cluster.module"), exports); +__exportStar(require("./cluster.interface"), exports); +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/index.js.map b/dist/index.js.map new file mode 100644 index 0000000..f72f149 --- /dev/null +++ b/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,kDAAgC;AAChC,iDAA+B;AAC/B,oDAAkC;AAClC,oDAAkC;AAClC,mDAAiC;AACjC,sDAAoC"} \ No newline at end of file diff --git a/dist/redis-core.module.d.ts b/dist/redis-core.module.d.ts index 7dae789..1df24c8 100644 --- a/dist/redis-core.module.d.ts +++ b/dist/redis-core.module.d.ts @@ -1,6 +1,6 @@ +import type { RedisModuleAsyncOptions, RedisModuleOptions } from './redis.interface'; import { DynamicModule, OnModuleDestroy } from '@nestjs/common'; import { ModuleRef } from '@nestjs/core'; -import { RedisModuleAsyncOptions, RedisModuleOptions } from './redis.interface'; export declare class RedisCoreModule implements OnModuleDestroy { private readonly options; private readonly moduleRef; diff --git a/dist/redis-core.module.js b/dist/redis-core.module.js index fb3b7bf..6d7691d 100644 --- a/dist/redis-core.module.js +++ b/dist/redis-core.module.js @@ -16,8 +16,8 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.RedisCoreModule = void 0; const common_1 = require("@nestjs/common"); const core_1 = require("@nestjs/core"); -const redis_client_provider_1 = require("./redis-client.provider"); const redis_constants_1 = require("./redis.constants"); +const redis_provider_1 = require("./redis.provider"); const redis_service_1 = require("./redis.service"); let RedisCoreModule = RedisCoreModule_1 = class RedisCoreModule { constructor(options, moduleRef) { @@ -28,7 +28,7 @@ let RedisCoreModule = RedisCoreModule_1 = class RedisCoreModule { return { module: RedisCoreModule_1, providers: [ - redis_client_provider_1.createClient(), + redis_provider_1.createClient(), { provide: redis_constants_1.REDIS_MODULE_OPTIONS, useValue: options }, ], exports: [redis_service_1.RedisService], @@ -38,7 +38,7 @@ let RedisCoreModule = RedisCoreModule_1 = class RedisCoreModule { return { module: RedisCoreModule_1, imports: options.imports, - providers: [redis_client_provider_1.createClient(), redis_client_provider_1.createAsyncClientOptions(options)], + providers: [redis_provider_1.createClient(), redis_provider_1.createAsyncClientOptions(options)], exports: [redis_service_1.RedisService], }; } @@ -70,3 +70,4 @@ RedisCoreModule = RedisCoreModule_1 = __decorate([ __metadata("design:paramtypes", [Object, core_1.ModuleRef]) ], RedisCoreModule); exports.RedisCoreModule = RedisCoreModule; +//# sourceMappingURL=redis-core.module.js.map \ No newline at end of file diff --git a/dist/redis-core.module.js.map b/dist/redis-core.module.js.map new file mode 100644 index 0000000..f0b3d14 --- /dev/null +++ b/dist/redis-core.module.js.map @@ -0,0 +1 @@ +{"version":3,"file":"redis-core.module.js","sourceRoot":"","sources":["../lib/redis-core.module.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AACA,2CAMwB;AACxB,uCAAyC;AAEzC,uDAAuE;AACvE,qDAI0B;AAC1B,mDAA+C;AAO/C,IAAa,eAAe,uBAA5B,MAAa,eAAe;IAC1B,YAEmB,OAAkD,EAClD,SAAoB;QADpB,YAAO,GAAP,OAAO,CAA2C;QAClD,cAAS,GAAT,SAAS,CAAW;IACpC,CAAC;IAEJ,MAAM,CAAC,QAAQ,CACb,OAAkD;QAElD,OAAO;YACL,MAAM,EAAE,iBAAe;YACvB,SAAS,EAAE;gBACT,6BAAY,EAAE;gBACd,EAAE,OAAO,EAAE,sCAAoB,EAAE,QAAQ,EAAE,OAAO,EAAE;aACrD;YACD,OAAO,EAAE,CAAC,4BAAY,CAAC;SACxB,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,YAAY,CAAC,OAAgC;QAClD,OAAO;YACL,MAAM,EAAE,iBAAe;YACvB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,SAAS,EAAE,CAAC,6BAAY,EAAE,EAAE,yCAAwB,CAAC,OAAO,CAAC,CAAC;YAC9D,OAAO,EAAE,CAAC,4BAAY,CAAC;SACxB,CAAC;IACJ,CAAC;IAED,eAAe;QACb,MAAM,eAAe,GAAG,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE;YAC7D,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,UAAU,CAAC;YACxC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAEjC,IAAI,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE;gBAChC,MAAM,CAAC,UAAU,EAAE,CAAC;aACrB;QACH,CAAC,CAAC;QAEF,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAc,8BAAY,CAAC,CAAC;QAClE,MAAM,qBAAqB,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;QAE3D,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;YAC/B,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC;SAC7C;aAAM;YACL,qBAAqB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;SACrC;IACH,CAAC;CACF,CAAA;AAhDY,eAAe;IAL3B,eAAM,EAAE;IACR,eAAM,CAAC;QACN,SAAS,EAAE,CAAC,4BAAY,CAAC;QACzB,OAAO,EAAE,CAAC,4BAAY,CAAC;KACxB,CAAC;IAGG,WAAA,eAAM,CAAC,sCAAoB,CAAC,CAAA;6CAED,gBAAS;GAJ5B,eAAe,CAgD3B;AAhDY,0CAAe"} \ No newline at end of file diff --git a/dist/redis.constants.js b/dist/redis.constants.js index cbc6ad9..58deca1 100644 --- a/dist/redis.constants.js +++ b/dist/redis.constants.js @@ -3,3 +3,4 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.REDIS_CLIENT = exports.REDIS_MODULE_OPTIONS = void 0; exports.REDIS_MODULE_OPTIONS = Symbol('REDIS_MODULE_OPTIONS'); exports.REDIS_CLIENT = Symbol('REDIS_CLIENT'); +//# sourceMappingURL=redis.constants.js.map \ No newline at end of file diff --git a/dist/redis.constants.js.map b/dist/redis.constants.js.map new file mode 100644 index 0000000..cee136d --- /dev/null +++ b/dist/redis.constants.js.map @@ -0,0 +1 @@ +{"version":3,"file":"redis.constants.js","sourceRoot":"","sources":["../lib/redis.constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,oBAAoB,GAAG,MAAM,CAAC,sBAAsB,CAAC,CAAC;AACtD,QAAA,YAAY,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC"} \ No newline at end of file diff --git a/dist/redis.interface.d.ts b/dist/redis.interface.d.ts index 2d0bbe1..fbbc05e 100644 --- a/dist/redis.interface.d.ts +++ b/dist/redis.interface.d.ts @@ -1,7 +1,7 @@ -import { ModuleMetadata } from '@nestjs/common/interfaces'; -import { Redis, RedisOptions } from 'ioredis'; +import type { ModuleMetadata } from '@nestjs/common/interfaces'; +import type { Redis, RedisOptions } from 'ioredis'; export interface RedisModuleOptions extends RedisOptions { - name?: string; + clientName?: string; url?: string; onClientReady?(client: Redis): Promise; } diff --git a/dist/redis.interface.js b/dist/redis.interface.js index c8ad2e5..b11e575 100644 --- a/dist/redis.interface.js +++ b/dist/redis.interface.js @@ -1,2 +1,3 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); +//# sourceMappingURL=redis.interface.js.map \ No newline at end of file diff --git a/dist/redis.interface.js.map b/dist/redis.interface.js.map new file mode 100644 index 0000000..add791d --- /dev/null +++ b/dist/redis.interface.js.map @@ -0,0 +1 @@ +{"version":3,"file":"redis.interface.js","sourceRoot":"","sources":["../lib/redis.interface.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/dist/redis.module.d.ts b/dist/redis.module.d.ts index e44de87..4548f8e 100644 --- a/dist/redis.module.d.ts +++ b/dist/redis.module.d.ts @@ -1,5 +1,5 @@ +import type { RedisModuleAsyncOptions, RedisModuleOptions } from './redis.interface'; import { DynamicModule } from '@nestjs/common'; -import { RedisModuleAsyncOptions, RedisModuleOptions } from './redis.interface'; export declare class RedisModule { static register(options: RedisModuleOptions | RedisModuleOptions[]): DynamicModule; static forRootAsync(options: RedisModuleAsyncOptions): DynamicModule; diff --git a/dist/redis.module.js b/dist/redis.module.js index 8f2e37d..51aa1b7 100644 --- a/dist/redis.module.js +++ b/dist/redis.module.js @@ -28,3 +28,4 @@ RedisModule = RedisModule_1 = __decorate([ common_1.Module({}) ], RedisModule); exports.RedisModule = RedisModule; +//# sourceMappingURL=redis.module.js.map \ No newline at end of file diff --git a/dist/redis.module.js.map b/dist/redis.module.js.map new file mode 100644 index 0000000..1871fe4 --- /dev/null +++ b/dist/redis.module.js.map @@ -0,0 +1 @@ +{"version":3,"file":"redis.module.js","sourceRoot":"","sources":["../lib/redis.module.ts"],"names":[],"mappings":";;;;;;;;;;AACA,2CAAuD;AAEvD,2DAAsD;AAGtD,IAAa,WAAW,mBAAxB,MAAa,WAAW;IACtB,MAAM,CAAC,QAAQ,CACb,OAAkD;QAElD,OAAO;YACL,MAAM,EAAE,aAAW;YACnB,OAAO,EAAE,CAAC,mCAAe,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;SAC7C,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,YAAY,CAAC,OAAgC;QAClD,OAAO;YACL,MAAM,EAAE,aAAW;YACnB,OAAO,EAAE,CAAC,mCAAe,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;SACjD,CAAC;IACJ,CAAC;CACF,CAAA;AAhBY,WAAW;IADvB,eAAM,CAAC,EAAE,CAAC;GACE,WAAW,CAgBvB;AAhBY,kCAAW"} \ No newline at end of file diff --git a/dist/redis-client.provider.d.ts b/dist/redis.provider.d.ts similarity index 94% rename from dist/redis-client.provider.d.ts rename to dist/redis.provider.d.ts index 731646b..61763c1 100644 --- a/dist/redis-client.provider.d.ts +++ b/dist/redis.provider.d.ts @@ -1,4 +1,4 @@ -import * as Redis from 'ioredis'; +import Redis from 'ioredis'; import { Provider } from '@nestjs/common'; import { RedisModuleAsyncOptions, RedisModuleOptions } from './redis.interface'; export declare class RedisClientError extends Error { diff --git a/dist/redis-client.provider.js b/dist/redis.provider.js similarity index 69% rename from dist/redis-client.provider.js rename to dist/redis.provider.js index 6ad362d..89287b1 100644 --- a/dist/redis-client.provider.js +++ b/dist/redis.provider.js @@ -1,7 +1,10 @@ "use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; Object.defineProperty(exports, "__esModule", { value: true }); exports.createAsyncClientOptions = exports.createClient = exports.RedisClientError = void 0; -const Redis = require("ioredis"); +const ioredis_1 = __importDefault(require("ioredis")); const uuid_1 = require("uuid"); const redis_constants_1 = require("./redis.constants"); class RedisClientError extends Error { @@ -9,7 +12,7 @@ class RedisClientError extends Error { exports.RedisClientError = RedisClientError; async function getClient(options) { const { onClientReady, url, ...opt } = options; - const client = url ? new Redis(url) : new Redis(opt); + const client = url ? new ioredis_1.default(url) : new ioredis_1.default(opt); if (onClientReady) { onClientReady(client); } @@ -22,16 +25,16 @@ exports.createClient = () => ({ let defaultKey = uuid_1.v4(); if (Array.isArray(options)) { await Promise.all(options.map(async (o) => { - const key = o.name || defaultKey; + const key = o.clientName || defaultKey; if (clients.has(key)) { - throw new RedisClientError(`${o.name || 'default'} client is exists`); + throw new RedisClientError(`${o.clientName || 'default'} client is exists`); } clients.set(key, await getClient(o)); })); } else { - if (options.name && options.name.length !== 0) { - defaultKey = options.name; + if (options.clientName && options.clientName.length !== 0) { + defaultKey = options.clientName; } clients.set(defaultKey, await getClient(options)); } @@ -48,3 +51,4 @@ exports.createAsyncClientOptions = (options) => ({ useFactory: options.useFactory, inject: options.inject, }); +//# sourceMappingURL=redis.provider.js.map \ No newline at end of file diff --git a/dist/redis.provider.js.map b/dist/redis.provider.js.map new file mode 100644 index 0000000..e5c18d2 --- /dev/null +++ b/dist/redis.provider.js.map @@ -0,0 +1 @@ +{"version":3,"file":"redis.provider.js","sourceRoot":"","sources":["../lib/redis.provider.ts"],"names":[],"mappings":";;;;;;AAAA,sDAA4B;AAC5B,+BAAkC;AAGlC,uDAAuE;AAGvE,MAAa,gBAAiB,SAAQ,KAAK;CAAG;AAA9C,4CAA8C;AAO9C,KAAK,UAAU,SAAS,CAAC,OAA2B;IAClD,MAAM,EAAE,aAAa,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,GAAG,OAAO,CAAC;IAC/C,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,iBAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,iBAAK,CAAC,GAAG,CAAC,CAAC;IACrD,IAAI,aAAa,EAAE;QACjB,aAAa,CAAC,MAAM,CAAC,CAAA;KACtB;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAEY,QAAA,YAAY,GAAG,GAAa,EAAE,CAAC,CAAC;IAC3C,OAAO,EAAE,8BAAY;IACrB,UAAU,EAAE,KAAK,EAAE,OAAkD,EAAwB,EAAE;QAC7F,MAAM,OAAO,GAAG,IAAI,GAAG,EAAuB,CAAC;QAC/C,IAAI,UAAU,GAAG,SAAI,EAAE,CAAC;QAExB,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;YAC1B,MAAM,OAAO,CAAC,GAAG,CACf,OAAO,CAAC,GAAG,CAAC,KAAK,EAAC,CAAC,EAAC,EAAE;gBACpB,MAAM,GAAG,GAAG,CAAC,CAAC,UAAU,IAAI,UAAU,CAAC;gBACvC,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;oBACpB,MAAM,IAAI,gBAAgB,CAAC,GAAG,CAAC,CAAC,UAAU,IAAI,SAAS,mBAAmB,CAAC,CAAC;iBAC7E;gBACD,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;YACvC,CAAC,CAAC,CACH,CAAC;SACH;aAAM;YACL,IAAI,OAAO,CAAC,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE;gBACzD,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;aACjC;YACD,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;SACnD;QAED,OAAO;YACL,UAAU;YACV,OAAO;YACP,IAAI,EAAE,OAAO,CAAC,IAAI;SACnB,CAAC;IACJ,CAAC;IACD,MAAM,EAAE,CAAC,sCAAoB,CAAC;CAC/B,CAAC,CAAC;AAEU,QAAA,wBAAwB,GAAG,CAAC,OAAgC,EAAE,EAAE,CAAC,CAAC;IAC7E,OAAO,EAAE,sCAAoB;IAC7B,UAAU,EAAE,OAAO,CAAC,UAAU;IAC9B,MAAM,EAAE,OAAO,CAAC,MAAM;CACvB,CAAC,CAAC"} \ No newline at end of file diff --git a/dist/redis.service.d.ts b/dist/redis.service.d.ts index 2259b1a..b20f9a8 100644 --- a/dist/redis.service.d.ts +++ b/dist/redis.service.d.ts @@ -1,8 +1,8 @@ -import { Redis } from 'ioredis'; -import { RedisClient } from './redis-client.provider'; +import type { Redis } from 'ioredis'; +import { RedisClient } from './redis.provider'; export declare class RedisService { private readonly redisClient; constructor(redisClient: RedisClient); - getClient(name?: string): Redis; + getClient(clientName?: string): Redis; getClients(): Map; } diff --git a/dist/redis.service.js b/dist/redis.service.js index 6fa2f8a..fa1358d 100644 --- a/dist/redis.service.js +++ b/dist/redis.service.js @@ -15,19 +15,19 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.RedisService = void 0; const common_1 = require("@nestjs/common"); const redis_constants_1 = require("./redis.constants"); -const redis_client_provider_1 = require("./redis-client.provider"); +const redis_provider_1 = require("./redis.provider"); let RedisService = class RedisService { constructor(redisClient) { this.redisClient = redisClient; } - getClient(name) { - if (!name) { - name = this.redisClient.defaultKey; + getClient(clientName) { + if (!clientName) { + clientName = this.redisClient.defaultKey; } - if (!this.redisClient.clients.has(name)) { - throw new redis_client_provider_1.RedisClientError(`client ${name} does not exist`); + if (!this.redisClient.clients.has(clientName)) { + throw new redis_provider_1.RedisClientError(`client ${clientName} does not exist`); } - return this.redisClient.clients.get(name); + return this.redisClient.clients.get(clientName); } getClients() { return this.redisClient.clients; @@ -39,3 +39,4 @@ RedisService = __decorate([ __metadata("design:paramtypes", [Object]) ], RedisService); exports.RedisService = RedisService; +//# sourceMappingURL=redis.service.js.map \ No newline at end of file diff --git a/dist/redis.service.js.map b/dist/redis.service.js.map new file mode 100644 index 0000000..09efce5 --- /dev/null +++ b/dist/redis.service.js.map @@ -0,0 +1 @@ +{"version":3,"file":"redis.service.js","sourceRoot":"","sources":["../lib/redis.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AACA,2CAAoD;AAEpD,uDAAiD;AACjD,qDAAiE;AAGjE,IAAa,YAAY,GAAzB,MAAa,YAAY;IACvB,YACyC,WAAwB;QAAxB,gBAAW,GAAX,WAAW,CAAa;IAC9D,CAAC;IAEJ,SAAS,CAAC,UAAmB;QAC3B,IAAI,CAAC,UAAU,EAAE;YACf,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC;SAC1C;QACD,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE;YAC7C,MAAM,IAAI,iCAAgB,CAAC,UAAU,UAAU,iBAAiB,CAAC,CAAC;SACnE;QACD,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAClD,CAAC;IAED,UAAU;QACR,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC;IAClC,CAAC;CACF,CAAA;AAlBY,YAAY;IADxB,mBAAU,EAAE;IAGR,WAAA,eAAM,CAAC,8BAAY,CAAC,CAAA;;GAFZ,YAAY,CAkBxB;AAlBY,oCAAY"} \ No newline at end of file diff --git a/index.js b/index.js index 9368dd3..70e3613 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,13 @@ "use strict"; -function __export(m) { - for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; -} +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __exportStar = (this && this.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); +}; exports.__esModule = true; -__export(require("./dist")); +__exportStar(require("./dist"), exports); diff --git a/lib/cluster-core.module.ts b/lib/cluster-core.module.ts new file mode 100644 index 0000000..979fc75 --- /dev/null +++ b/lib/cluster-core.module.ts @@ -0,0 +1,84 @@ +import type { Cluster } from 'ioredis'; +import { + DynamicModule, + Global, + Module, + Inject, + OnModuleDestroy, +} from '@nestjs/common'; +import { ModuleRef } from '@nestjs/core'; + +import type { + RedisClusterModuleAsyncOptions, + RedisClusterModuleOptions, +} from './cluster.interface'; +import { + createAsyncClusterOptions, + createCluster, + RedisClusterProvider, +} from './cluster.provider'; +import { + REDIS_CLUSTER_MODULE_OPTIONS, + REDIS_CLUSTER, +} from './cluster.constants'; +import { RedisClusterService } from './cluster.service'; + +@Global() +@Module({ + providers: [RedisClusterService], + exports: [RedisClusterService], +}) +export class ClusterCoreModule implements OnModuleDestroy { + constructor( + @Inject(REDIS_CLUSTER_MODULE_OPTIONS) + private readonly options: + | RedisClusterModuleOptions + | RedisClusterModuleOptions[], + private readonly moduleRef: ModuleRef, + ) {} + + static register( + options: RedisClusterModuleOptions | RedisClusterModuleOptions[], + ): DynamicModule { + return { + module: ClusterCoreModule, + providers: [ + createCluster(), + { provide: REDIS_CLUSTER_MODULE_OPTIONS, useValue: options }, + ], + exports: [RedisClusterService], + }; + } + + static forRootAsync(options: RedisClusterModuleAsyncOptions): DynamicModule { + return { + module: ClusterCoreModule, + imports: options.imports, + providers: [createCluster(), createAsyncClusterOptions(options)], + exports: [RedisClusterService], + }; + } + + onModuleDestroy() { + const closeConnection = ({ + clusters, + defaultKey, + }: RedisClusterProvider) => options => { + const name = options.name || defaultKey; + const cluster: Cluster = clusters.get(name); + + if (cluster && !options.keepAlive) { + cluster.disconnect(); + } + }; + + const provider = this.moduleRef.get(REDIS_CLUSTER); + const closeClusterConnection = closeConnection(provider); + + if (Array.isArray(this.options)) { + this.options.forEach(closeClusterConnection); + } else { + closeClusterConnection(this.options); + } + } +} diff --git a/lib/cluster.constants.ts b/lib/cluster.constants.ts new file mode 100644 index 0000000..2ef4d23 --- /dev/null +++ b/lib/cluster.constants.ts @@ -0,0 +1,4 @@ +export const REDIS_CLUSTER_MODULE_OPTIONS = Symbol( + 'REDIS_CLUSTER_MODULE_OPTIONS', +); +export const REDIS_CLUSTER = Symbol('REDIS_CLUSTER'); diff --git a/lib/cluster.interface.ts b/lib/cluster.interface.ts new file mode 100644 index 0000000..dfd5538 --- /dev/null +++ b/lib/cluster.interface.ts @@ -0,0 +1,20 @@ +import type { ModuleMetadata } from '@nestjs/common/interfaces'; +import type { Cluster, ClusterOptions } from 'ioredis'; + +export interface RedisClusterModuleOptions extends ClusterOptions { + clientName?: string; + nodes: (string | number | object)[]; + onClusterReady?(cluster: Cluster): Promise; +} + +export interface RedisClusterModuleAsyncOptions + extends Pick { + useFactory?: ( + ...args: any[] + ) => + | RedisClusterModuleOptions + | RedisClusterModuleOptions[] + | Promise + | Promise; + inject?: any[]; +} diff --git a/lib/cluster.module.ts b/lib/cluster.module.ts new file mode 100644 index 0000000..f77702c --- /dev/null +++ b/lib/cluster.module.ts @@ -0,0 +1,26 @@ +import { DynamicModule, Module } from '@nestjs/common'; + +import type { + RedisClusterModuleAsyncOptions, + RedisClusterModuleOptions, +} from './cluster.interface'; +import { ClusterCoreModule } from './cluster-core.module'; + +@Module({}) +export class RedisClusterModule { + static register( + options: RedisClusterModuleOptions | RedisClusterModuleOptions[], + ): DynamicModule { + return { + module: RedisClusterModule, + imports: [ClusterCoreModule.register(options)], + }; + } + + static forRootAsync(options: RedisClusterModuleAsyncOptions): DynamicModule { + return { + module: RedisClusterModule, + imports: [ClusterCoreModule.forRootAsync(options)], + }; + } +} diff --git a/lib/cluster.provider.ts b/lib/cluster.provider.ts new file mode 100644 index 0000000..fef9675 --- /dev/null +++ b/lib/cluster.provider.ts @@ -0,0 +1,74 @@ +import { v4 as uuid } from 'uuid'; +import { Provider } from '@nestjs/common'; +import { Cluster } from 'ioredis'; + +import type { + RedisClusterModuleAsyncOptions, + RedisClusterModuleOptions, +} from './cluster.interface'; +import { + REDIS_CLUSTER, + REDIS_CLUSTER_MODULE_OPTIONS, +} from './cluster.constants'; + +export class RedisClusterError extends Error {} +export interface RedisClusterProvider { + defaultKey: string; + clusters: Map; + size: number; +} + +async function getCluster(options: RedisClusterModuleOptions): Promise { + const { onClusterReady, nodes, ...opt } = options; + const cluster = new Cluster(nodes, opt); + + if (onClusterReady) { + onClusterReady(cluster); + } + + return cluster; +} + +export const createCluster = (): Provider => ({ + provide: REDIS_CLUSTER, + useFactory: async ( + options: RedisClusterModuleOptions | RedisClusterModuleOptions[], + ): Promise => { + const clusters: Map = new Map(); + let defaultKey = uuid(); + + if (Array.isArray(options)) { + await Promise.all( + options.map(async o => { + const key: string = o.clientName || defaultKey; + if (clusters.has(key)) { + throw new RedisClusterError( + `${o.clientName || 'default'} cluster already exists`, + ); + } + clusters.set(key, await getCluster(o)); + }), + ); + } else { + if (options.clientName && options.clientName.length !== 0) { + defaultKey = options.clientName; + } + clusters.set(defaultKey, await getCluster(options)); + } + + return { + defaultKey, + clusters, + size: clusters.size, + }; + }, + inject: [REDIS_CLUSTER_MODULE_OPTIONS], +}); + +export const createAsyncClusterOptions = ( + options: RedisClusterModuleAsyncOptions, +) => ({ + provide: REDIS_CLUSTER_MODULE_OPTIONS, + useFactory: options.useFactory, + inject: options.inject, +}); diff --git a/lib/cluster.service.ts b/lib/cluster.service.ts new file mode 100644 index 0000000..1734e36 --- /dev/null +++ b/lib/cluster.service.ts @@ -0,0 +1,26 @@ +import { Injectable, Inject } from '@nestjs/common'; +import { REDIS_CLUSTER } from './cluster.constants'; +import { Cluster } from 'ioredis'; +import { RedisClusterProvider, RedisClusterError } from './cluster.provider'; + +@Injectable() +export class RedisClusterService { + constructor( + @Inject(REDIS_CLUSTER) private readonly provider: RedisClusterProvider, + ) {} + + getCluster(clientName?: string): Cluster { + if (!clientName) { + clientName = this.provider.defaultKey; + } + + if (!this.provider.clusters.has(clientName)) { + throw new RedisClusterError(`cluster ${clientName} does not exist`); + } + return this.provider.clusters.get(clientName); + } + + getClusters(): Map { + return this.provider.clusters; + } +} diff --git a/lib/index.ts b/lib/index.ts index 3aae4f1..8c026e3 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -1,3 +1,6 @@ export * from './redis.service'; export * from './redis.module'; export * from './redis.interface'; +export * from './cluster.service'; +export * from './cluster.module'; +export * from './cluster.interface'; diff --git a/lib/redis-core.module.ts b/lib/redis-core.module.ts index baabc58..650b83b 100644 --- a/lib/redis-core.module.ts +++ b/lib/redis-core.module.ts @@ -1,3 +1,4 @@ +import type { RedisModuleAsyncOptions, RedisModuleOptions } from './redis.interface'; import { DynamicModule, Global, @@ -6,14 +7,13 @@ import { OnModuleDestroy, } from '@nestjs/common'; import { ModuleRef } from '@nestjs/core'; -import { RedisModuleAsyncOptions, RedisModuleOptions } from './redis.interface'; + +import { REDIS_MODULE_OPTIONS, REDIS_CLIENT } from './redis.constants'; import { createAsyncClientOptions, createClient, RedisClient, -} from './redis-client.provider'; - -import { REDIS_MODULE_OPTIONS, REDIS_CLIENT } from './redis.constants'; +} from './redis.provider'; import { RedisService } from './redis.service'; @Global() diff --git a/lib/redis.interface.ts b/lib/redis.interface.ts index a6d4db0..9391746 100644 --- a/lib/redis.interface.ts +++ b/lib/redis.interface.ts @@ -1,13 +1,14 @@ -import { ModuleMetadata } from '@nestjs/common/interfaces'; -import { Redis, RedisOptions } from 'ioredis'; +import type { ModuleMetadata } from '@nestjs/common/interfaces'; +import type { Redis, RedisOptions } from 'ioredis'; export interface RedisModuleOptions extends RedisOptions { - name?: string; + clientName?: string; url?: string; onClientReady?(client: Redis): Promise; } -export interface RedisModuleAsyncOptions extends Pick { +export interface RedisModuleAsyncOptions + extends Pick { useFactory?: ( ...args: any[] ) => diff --git a/lib/redis.module.ts b/lib/redis.module.ts index c521eda..dc99ae5 100644 --- a/lib/redis.module.ts +++ b/lib/redis.module.ts @@ -1,5 +1,5 @@ +import type { RedisModuleAsyncOptions, RedisModuleOptions } from './redis.interface'; import { DynamicModule, Module } from '@nestjs/common'; -import { RedisModuleAsyncOptions, RedisModuleOptions } from './redis.interface'; import { RedisCoreModule } from './redis-core.module'; diff --git a/lib/redis-client.provider.ts b/lib/redis.provider.ts similarity index 80% rename from lib/redis-client.provider.ts rename to lib/redis.provider.ts index eac33a1..2e27db9 100644 --- a/lib/redis-client.provider.ts +++ b/lib/redis.provider.ts @@ -1,5 +1,5 @@ -import * as Redis from 'ioredis'; -import { v4 as uuidv4 } from 'uuid'; +import Redis from 'ioredis'; +import { v4 as uuid } from 'uuid'; import { Provider } from '@nestjs/common'; import { REDIS_CLIENT, REDIS_MODULE_OPTIONS } from './redis.constants'; @@ -25,21 +25,21 @@ export const createClient = (): Provider => ({ provide: REDIS_CLIENT, useFactory: async (options: RedisModuleOptions | RedisModuleOptions[]): Promise => { const clients = new Map(); - let defaultKey = uuidv4(); + let defaultKey = uuid(); if (Array.isArray(options)) { await Promise.all( options.map(async o => { - const key = o.name || defaultKey; + const key = o.clientName || defaultKey; if (clients.has(key)) { - throw new RedisClientError(`${o.name || 'default'} client is exists`); + throw new RedisClientError(`${o.clientName || 'default'} client is exists`); } clients.set(key, await getClient(o)); }), ); } else { - if (options.name && options.name.length !== 0) { - defaultKey = options.name; + if (options.clientName && options.clientName.length !== 0) { + defaultKey = options.clientName; } clients.set(defaultKey, await getClient(options)); } diff --git a/lib/redis.service.ts b/lib/redis.service.ts index 7bd77b2..4bddcd3 100644 --- a/lib/redis.service.ts +++ b/lib/redis.service.ts @@ -1,7 +1,8 @@ +import type { Redis } from 'ioredis'; import { Injectable, Inject } from '@nestjs/common'; + import { REDIS_CLIENT } from './redis.constants'; -import { Redis } from 'ioredis'; -import { RedisClient, RedisClientError } from './redis-client.provider'; +import { RedisClient, RedisClientError } from './redis.provider'; @Injectable() export class RedisService { @@ -9,14 +10,14 @@ export class RedisService { @Inject(REDIS_CLIENT) private readonly redisClient: RedisClient, ) {} - getClient(name?: string): Redis { - if (!name) { - name = this.redisClient.defaultKey; + getClient(clientName?: string): Redis { + if (!clientName) { + clientName = this.redisClient.defaultKey; } - if (!this.redisClient.clients.has(name)) { - throw new RedisClientError(`client ${name} does not exist`); + if (!this.redisClient.clients.has(clientName)) { + throw new RedisClientError(`client ${clientName} does not exist`); } - return this.redisClient.clients.get(name); + return this.redisClient.clients.get(clientName); } getClients(): Map { diff --git a/nest-cli.json b/nest-cli.json index 0dde5f8..f0cfd23 100644 --- a/nest-cli.json +++ b/nest-cli.json @@ -1,5 +1,5 @@ { "language": "ts", "collection": "@nestjs/schematics", - "sourceRoot": "src" + "sourceRoot": "lib" } diff --git a/nodemon-debug.json b/nodemon-debug.json deleted file mode 100644 index 7caf94b..0000000 --- a/nodemon-debug.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "watch": ["src"], - "ext": "ts", - "ignore": ["src/**/*.spec.ts"], - "exec": "node --inspect-brk -r ts-node/register src/main.ts" -} \ No newline at end of file diff --git a/nodemon.json b/nodemon.json deleted file mode 100644 index 583bb42..0000000 --- a/nodemon.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "watch": ["src"], - "ext": "ts", - "ignore": ["src/**/*.spec.ts"], - "exec": "ts-node -r tsconfig-paths/register src/main.ts" -} diff --git a/package.json b/package.json index d92e57a..5a8f960 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,12 @@ { - "name": "nest-redis", - "version": "1.3.2", + "name": "nestjs-redis", + "version": "1.4.1", "description": "a NestJS ioRedis module", - "author": "Stanislav V Vyaliy", + "author": "skunight", "license": "MIT", "repository": { "type": "git", - "url": "https://github.com/wisekaa03/nestjs-ioredis.git" + "url": "https://github.com/skunight/nestjs-redis.git" }, "scripts": { "build": "rimraf dist && tsc -p tsconfig.json", @@ -22,16 +22,14 @@ "dependencies": { "@nestjs/common": "^7", "@nestjs/core": "^7", - "@types/ioredis": "*", - "@types/uuid": "*", - "ioredis": "^4", - "reflect-metadata": "*", - "rxjs": "^6", + "ioredis": "*", "uuid": "^8" }, "devDependencies": { "@nestjs/testing": "^7", + "@types/ioredis": "*", "@types/node": "*", + "@types/uuid": "*", "@typescript-eslint/eslint-plugin": "^4", "@typescript-eslint/parser": "^4", "cz-conventional-changelog": "^3", @@ -41,7 +39,9 @@ "eslint-plugin-prettier": "^3", "jest": "^26", "prettier": "^2", + "reflect-metadata": "*", "rimraf": "*", + "rxjs": "^6", "ts-jest": "^26", "typescript": "^4" }, diff --git a/tsconfig.json b/tsconfig.json index 256c414..572c805 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,18 +1,20 @@ { "compilerOptions": { - "module": "CommonJS", - "target": "ES2018", + "module": "commonjs", + "target": "es2018", "declaration": true, + "moduleResolution": "node", "noImplicitAny": false, "removeComments": true, "noLib": false, + "esModuleInterop": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, - "sourceMap": false, + "sourceMap": true, "outDir": "./dist", "rootDir": "./lib", "skipLibCheck": true }, - "include": ["lib/**/*", "../index.ts"], + "include": ["lib/**/*"], "exclude": ["node_modules", "**/*.spec.ts"] } diff --git a/yarn.lock b/yarn.lock index 24a1c5b..b9c3ae6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -258,9 +258,9 @@ lodash "^4.17.19" "@babel/types@^7.0.0", "@babel/types@^7.10.4", "@babel/types@^7.11.0", "@babel/types@^7.12.1", "@babel/types@^7.12.5", "@babel/types@^7.3.0", "@babel/types@^7.3.3": - version "7.12.5" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.5.tgz#5d6b4590cfe90c0c8d7396c83ffd9fc28b5a6450" - integrity sha512-gyTcvz7JFa4V45C0Zklv//GmFOAal5fL23OWpBLqc4nZ4Yrz67s4kCNwSK1Gu0MXGTU8mRY3zJYtacLdKXlzig== + version "7.12.6" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.6.tgz#ae0e55ef1cce1fbc881cd26f8234eb3e657edc96" + integrity sha512-hwyjw6GvjBLiyy3W0YQf0Z5Zf4NpYejUnKFcfcUhZCSffoBBp30w6wP2Wn6pk31jMYZvcOrB/1b7cGXvEoKogA== dependencies: "@babel/helper-validator-identifier" "^7.10.4" lodash "^4.17.19" @@ -1597,7 +1597,7 @@ escodegen@^1.14.1: optionalDependencies: source-map "~0.6.1" -eslint-config-prettier@^6.15.0: +eslint-config-prettier@^6: version "6.15.0" resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.15.0.tgz#7f93f6cb7d45a92f1537a70ecc06366e1ac6fed9" integrity sha512-a1+kOYLR8wMGustcgAjdydMsQ2A/2ipRPwRKUmfYaSxc9ZPcrku080Ctl6zrZzZNs/U82MjSv+qKREkoq3bJaw== @@ -1611,7 +1611,7 @@ eslint-plugin-jest@^24: dependencies: "@typescript-eslint/experimental-utils" "^4.0.1" -eslint-plugin-prettier@^3.1.4: +eslint-plugin-prettier@^3: version "3.1.4" resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.4.tgz#168ab43154e2ea57db992a2cd097c828171f75c2" integrity sha512-jZDa8z76klRqo+TdGDTFJSavwbnWK2ZpqGKNZ+VvweMW516pDUMmQ2koXvxEE4JhzNvTv+radye/bWGBmA6jmg== @@ -2025,9 +2025,9 @@ fs.realpath@^1.0.0: integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= fsevents@^2.1.2: - version "2.2.0" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.2.0.tgz#4150396a427ecb5baa747725b70270a72b17bc17" - integrity sha512-pKnaUh2TNvk+/egJdBw1h46LwyLx8BzEq+MGCf/RMCVfEHHsGOCWG00dqk91kUPPArIIwMBg9T/virxwzP03cA== + version "2.2.1" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.2.1.tgz#1fb02ded2036a8ac288d507a65962bd87b97628d" + integrity sha512-bTLYHSeC0UH/EFXS9KqWnXuOl/wHK5Z/d+ghd5AsFMYN7wIGkUCOJyzy88+wJKkZPGON8u4Z9f6U4FdgURE9qA== function-bind@^1.1.1: version "1.1.1" @@ -2351,7 +2351,7 @@ inquirer@6.5.2: strip-ansi "^5.1.0" through "^2.3.6" -ioredis@^4: +ioredis@*: version "4.19.2" resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-4.19.2.tgz#e3eab394c653cea5aea07c0c784d8c772dce8801" integrity sha512-SZSIwMrbd96b7rJvJwyTWSP6XQ0m1kAIIqBnwglJKrIJ6na7TeY4F2EV2vDY0xm/fLrUY8cEg81dR7kVFt2sKA== @@ -2404,9 +2404,9 @@ is-ci@^2.0.0: ci-info "^2.0.0" is-core-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.0.0.tgz#58531b70aed1db7c0e8d4eb1a0a2d1ddd64bd12d" - integrity sha512-jq1AH6C8MuteOoBPwkxHafmByhL9j5q4OaPGdbuD+ZtQJVzH+i6E3BJDQcBA09k57i2Hh2yQbEG8yObZ0jdlWw== + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.1.0.tgz#a4cc031d9b1aca63eecbd18a650e13cb4eeab946" + integrity sha512-YcV7BgVMRFRua2FqQzKtTDMz8iCuLEyGKjr70q8Zm1yy2qKcurbFEd79PAdHV77oL3NrAaOVQIbMmiHQCHB7ZA== dependencies: has "^1.0.3"