From 5e3a082ca0dbba5596e805c3a63d2a15743a12e6 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 9 May 2024 13:50:09 +0400 Subject: [PATCH] refactor: Use module definition to build dynamic module BREAKING CHANGE: Methods renamed `forRoot(Async)` to `register(Async)` --- src/nestolog-options.ts | 2 -- src/nestolog.module-definition.ts | 8 ++++++ src/nestolog.module.ts | 36 +++++------------------ src/nestologger.service.ts | 9 +++--- src/test-app.ts | 48 +++++++++++++++++++++++++++++++ 5 files changed, 68 insertions(+), 35 deletions(-) create mode 100644 src/nestolog.module-definition.ts create mode 100644 src/test-app.ts diff --git a/src/nestolog-options.ts b/src/nestolog-options.ts index 902441d..3160317 100644 --- a/src/nestolog-options.ts +++ b/src/nestolog-options.ts @@ -2,8 +2,6 @@ import ololog from 'ololog'; import { Entry } from './types'; -export const NESTOLOG_OPTIONS = Symbol('NESTOLOG_OPTIONS'); - export type NestologOptions = typeof nestologOptionsDefaults & Parameters[0]; diff --git a/src/nestolog.module-definition.ts b/src/nestolog.module-definition.ts new file mode 100644 index 0000000..b7fa360 --- /dev/null +++ b/src/nestolog.module-definition.ts @@ -0,0 +1,8 @@ +import { ConfigurableModuleBuilder } from '@nestjs/common'; + +import { NestologOptions } from './nestolog-options'; + +export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } = + new ConfigurableModuleBuilder>({ + optionsInjectionToken: 'NESTOLOG_OPTIONS', + }).build(); diff --git a/src/nestolog.module.ts b/src/nestolog.module.ts index 6467274..205ef9c 100644 --- a/src/nestolog.module.ts +++ b/src/nestolog.module.ts @@ -1,32 +1,10 @@ -import { DynamicModule, Module } from '@nestjs/common'; +import { Logger, Module } from '@nestjs/common'; -// import { asyncStorageProvider } from './async-storage.provider'; -import { - NESTOLOG_OPTIONS, - NestologOptions, - nestologOptionsDefaults, -} from './nestolog-options'; +import { ConfigurableModuleClass } from './nestolog.module-definition'; import { NestoLogger } from './nestologger.service'; -@Module({}) -export class NestologModule { - static forRoot(options: Partial = {}): DynamicModule { - options = { ...nestologOptionsDefaults, ...options }; - return { - module: NestologModule, - providers: [ - // { - // provide: APP_INTERCEPTOR, - // useClass: AsyncStorageInterceptor, - // }, - // asyncStorageProvider, - { - provide: NESTOLOG_OPTIONS, - useValue: options, - }, - NestoLogger, - ], - exports: [NestoLogger], - }; - } -} +@Module({ + providers: [NestoLogger, Logger], + exports: [NestoLogger, Logger], +}) +export class NestologModule extends ConfigurableModuleClass {} diff --git a/src/nestologger.service.ts b/src/nestologger.service.ts index 5ab12b9..e4e79b1 100644 --- a/src/nestologger.service.ts +++ b/src/nestologger.service.ts @@ -6,10 +6,11 @@ import tinydate from 'tinydate'; import wrapAnsi from 'wrap-ansi'; import { messageColumnWidth } from './message-column-width'; +import { MODULE_OPTIONS_TOKEN } from './nestolog.module-definition'; import { - type NestologOptions, customLocateDefault, - NESTOLOG_OPTIONS, + type NestologOptions, + nestologOptionsDefaults, } from './nestolog-options'; import { bullet, stringify } from './string'; import { Entry } from './types'; @@ -19,14 +20,14 @@ export class NestoLogger implements LoggerService { verbose = this.debug.bind(this); constructor( - @Inject(NESTOLOG_OPTIONS) private readonly options: NestologOptions, + @Inject(MODULE_OPTIONS_TOKEN) private readonly options: NestologOptions, @Inject('ololog') @Optional() private readonly logger = ololog, ) { this.logger = this.createLogger(logger); } private createLogger(logger: ololog) { - logger = logger.configure(this.options); + logger = logger.configure({ ...nestologOptionsDefaults, ...this.options }); const width = this.options.messageColumnWidth || messageColumnWidth(this.options, logger); diff --git a/src/test-app.ts b/src/test-app.ts new file mode 100644 index 0000000..7203ef9 --- /dev/null +++ b/src/test-app.ts @@ -0,0 +1,48 @@ +import { Injectable, Logger, Module } from '@nestjs/common'; +import { NestFactory } from '@nestjs/core'; + +import { NestologModule } from './nestolog.module'; +import { NestoLogger } from './nestologger.service'; + +const loggerModule = NestologModule.register({}); + +@Injectable() +class UserService { + constructor( + private readonly logger: Logger, + private readonly nestoLogger: NestoLogger, + ) { + nestoLogger.log('Hello from user service constructor'); + logger.log('Hello from user service constructor'); + } + + testLog() { + this.nestoLogger.log('Hello from user service testLog'); + this.logger.log('Hello from user service testLog'); + } +} + +@Module({ + imports: [loggerModule], + providers: [UserService], +}) +export class UserModule {} + +@Module({ + imports: [UserModule, loggerModule], +}) +export class AppModule {} + +const bootstrap = async (): Promise => { + const app = await NestFactory.create(AppModule); + const port = process.env.PORT ?? 3333; + app.useLogger(app.get(NestoLogger)); + + await app.listen(port, () => { + Logger.log(`Listening at http://localhost:${port}`); + + app.get(UserService).testLog(); + }); +}; + +void bootstrap();