Skip to content

Commit

Permalink
feat(config): allows for root module configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
jmcdo29 committed Dec 16, 2019
1 parent ea9cab7 commit c610566
Show file tree
Hide file tree
Showing 10 changed files with 161 additions and 32 deletions.
21 changes: 21 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"test:e2e": "jest --config ./test/jest-e2e.json"
},
"dependencies": {
"@golevelup/nestjs-modules": "^0.3.0",
"ogma": "0.0.2"
},
"devDependencies": {
Expand Down Expand Up @@ -69,7 +70,7 @@
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"coverageDirectory": "./coverage",
"coverageDirectory": "../coverage",
"testEnvironment": "node"
},
"engines": {
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './ogma.module';
export * from './ogma.service';
export * from './interfaces/ogma-options.interface';
7 changes: 7 additions & 0 deletions src/interfaces/ogma-options.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export interface OgmaModuleOptions {
logLevel?: string;
color?: boolean;
stream?: {
write: (message: any) => void;
};
}
14 changes: 14 additions & 0 deletions src/ogma-core.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { createConfigurableDynamicRootModule } from '@golevelup/nestjs-modules';
import { Module } from '@nestjs/common';
import { OgmaModuleOptions } from './interfaces/ogma-options.interface';
import { OGMA_OPTIONS } from './ogma.constants';

@Module({
exports: [OGMA_OPTIONS],
})
export class OgmaCoreModule extends createConfigurableDynamicRootModule<
OgmaCoreModule,
OgmaModuleOptions
>(OGMA_OPTIONS) {
static Deferred = OgmaCoreModule.externallyConfigured(OgmaCoreModule, 500);
}
1 change: 1 addition & 0 deletions src/ogma.constants.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export const OGMA_INSTANCE = Symbol('OGMA_INSTANCE');
export const OGMA_CONTEXT = Symbol('OGMA_CONTEXT');
export const OGMA_OPTIONS = 'OGMA_OPTIONS';
67 changes: 67 additions & 0 deletions src/ogma.module.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { Test } from '@nestjs/testing';
import { OgmaModule } from './ogma.module';
import { OgmaService } from './ogma.service';

describe('OgmaModule', () => {
let service: OgmaService;

describe.each(['TEST_CONTEXT', '', undefined])(
'create context then use that context',
(options: string | undefined) => {
beforeEach(async () => {
const module = await Test.createTestingModule({
imports: [
OgmaModule.forRoot({ color: false }),
OgmaModule.forFeature(options),
],
}).compile();
service = await module.resolve(OgmaService);
});

it(
'should have OgmaService defined with options ' +
JSON.stringify(options),
() => {
expect(service).toBeDefined();
expect(service).toHaveProperty('context');
expect((service as any).context).toBe(options ?? '');
},
);
},
);
describe('create context then use new context', () => {
it('should create multiple ogma instances', async () => {
const module = await Test.createTestingModule({
imports: [
OgmaModule.forRoot({ color: true, logLevel: 'ERROR' }),
OgmaModule.forFeature('NEW CONTEXT', {
color: false,
logLevel: 'ALL',
}),
],
}).compile();
service = await module.resolve(OgmaService);
expect((service as any).ogma.options.logLevel).toBeDefined();
expect((service as any).ogma.options.color).toBeDefined();
});
});
describe('create context with async config', () => {
it('should create the async configuration', async () => {
const module = await Test.createTestingModule({
imports: [
OgmaModule.forRootAsync({
useFactory: () => {
return {
color: false,
logLevel: 'DEBUG',
};
},
}),
OgmaModule.forFeature('TEST CONTEXT'),
],
}).compile();
service = await module.resolve(OgmaService);
expect((service as any).ogma.options.logLevel).toBeDefined();
});
});
});
42 changes: 37 additions & 5 deletions src/ogma.module.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,57 @@
import { AsyncModuleConfig } from '@golevelup/nestjs-modules';
import { DynamicModule, Module, Scope } from '@nestjs/common';
import { OgmaOptions } from 'ogma';
import { OGMA_CONTEXT, OGMA_INSTANCE } from './ogma.constants';
import { LogLevel, Ogma, OgmaOptions } from 'ogma';
import { OgmaModuleOptions } from './interfaces/ogma-options.interface';
import { OgmaCoreModule } from './ogma-core.module';
import { OGMA_CONTEXT, OGMA_INSTANCE, OGMA_OPTIONS } from './ogma.constants';
import { createOgmaProvider } from './ogma.provider';
import { OgmaService } from './ogma.service';

@Module({})
export class OgmaModule {
static ogmaInstance: Ogma;

static forRoot(options: OgmaModuleOptions): DynamicModule {
OgmaModule.ogmaInstance = createOgmaProvider({
logLevel: options.logLevel as keyof typeof LogLevel,
color: options.color,
stream: options.stream,
});
return OgmaCoreModule.forRoot(OgmaCoreModule, options);
}

static forRootAsync(
options: AsyncModuleConfig<OgmaModuleOptions>,
): DynamicModule {
return OgmaCoreModule.forRootAsync(OgmaCoreModule, options);
}

static forFeature(
options?: Partial<{ context: string } & OgmaOptions>,
context?: string,
options?: Partial<OgmaOptions>,
): DynamicModule {
return {
module: OgmaModule,
imports: [OgmaCoreModule.Deferred],
providers: [
{
provide: OGMA_CONTEXT,
useValue: options?.context,
useValue: context,
scope: Scope.TRANSIENT,
},
{
provide: OGMA_INSTANCE,
useValue: createOgmaProvider({ ...options }),
useFactory: (moduleOptions: OgmaOptions) => {
if (options) {
return createOgmaProvider(options);
}
if (!(OgmaModule.ogmaInstance as any).options.logLevel) {
OgmaModule.ogmaInstance = createOgmaProvider(moduleOptions);
}
return OgmaModule.ogmaInstance;
},
inject: [OGMA_OPTIONS],
scope: Scope.TRANSIENT,
},
OgmaService,
],
Expand Down
27 changes: 4 additions & 23 deletions src/ogma.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ describe('OgmaService', () => {
provide: OGMA_INSTANCE,
useFactory: () => {
const ogma = new Ogma(options);
(ogma as any).options = {
...(ogma as any).options,
...options,
};
ogmaSpy = jest.spyOn(ogma, level as any);
return ogma;
},
Expand Down Expand Up @@ -92,26 +96,3 @@ describe.each([new Ogma(), undefined])(
});
},
);

describe.each([{ context: 'TEST_CONTEXT' }, {}, undefined])(
'OgmaModule',
(options: any) => {
let service: OgmaService;

beforeEach(async () => {
const module = await Test.createTestingModule({
imports: [OgmaModule.forFeature(options)],
}).compile();
service = await module.resolve(OgmaService);
});

it(
'should have OgmaService defined with options ' + JSON.stringify(options),
() => {
expect(service).toBeDefined();
expect(service).toHaveProperty('context');
expect((service as any).context).toBe(options?.context ?? '');
},
);
},
);
10 changes: 7 additions & 3 deletions src/ogma.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import {
Scope,
} from '@nestjs/common';
import { color, Ogma } from 'ogma';
import { OGMA_CONTEXT, OGMA_INSTANCE } from './ogma.constants';
import { OgmaModuleOptions } from './interfaces/ogma-options.interface';
import { OGMA_CONTEXT, OGMA_INSTANCE, OGMA_OPTIONS } from './ogma.constants';

@Injectable({ scope: Scope.TRANSIENT })
export class OgmaService implements LoggerService {
Expand Down Expand Up @@ -63,8 +64,11 @@ export class OgmaService implements LoggerService {
context?: string,
): void {
context = context ?? this.context;
context = context ? color.cyan('[' + context + ']') : '';
const nest = color.yellow('[Nest]');
context = context ? '[' + context + ']' : '';
context = (this.ogma as any).options.color ? color.cyan(context) : context;
const nest = (this.ogma as any).options.color
? color.yellow('[Nest]')
: '[Nest]';
if (typeof message === 'object' && message !== null) {
this.ogma[levelString](nest + ' ' + process.pid + ' ' + context + ' |');
this.ogma[levelString](message);
Expand Down

0 comments on commit c610566

Please sign in to comment.