Skip to content

Commit

Permalink
feat(core): adds ClsModule.registerPlugins to inject Plugins from an …
Browse files Browse the repository at this point in the history
…external module
  • Loading branch information
JonnyBGod committed Dec 6, 2024
1 parent d2dd762 commit ef2299d
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 5 deletions.
6 changes: 6 additions & 0 deletions docs/docs/06_plugins/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ ClsModule.forRoot({
});
```

If you need to inject Plugins from an external module, use the `ClsModule.registerPlugins()` registration to import the containing module.

```ts
ClsModule.registerPlugins([new MyPlugin()]);
```

## Available plugins

For a list of plugins managed by the author of `nestjs-cls`, see the [Available Plugins](./01_available-plugins/index.md) page.
Expand Down
13 changes: 13 additions & 0 deletions packages/core/src/lib/cls.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import { ClsPluginManager } from './plugin/cls-plugin-manager';

import { ProxyProviderManager } from './proxy-provider/proxy-provider-manager';
import { ClsModuleProxyProviderOptions } from './proxy-provider/proxy-provider.interfaces';
import { ClsPlugin } from './plugin/cls-plugin.interface';

const clsServiceProvider: ValueProvider<ClsService> = {
provide: ClsService,
Expand Down Expand Up @@ -192,6 +193,18 @@ export class ClsModule implements NestModule {
};
}

/**
* Registers the given Plugins the module along with `ClsService`.
*/
static registerPlugins(plugins: ClsPlugin[]): DynamicModule {
return {
module: ClsModule,
imports: ClsPluginManager.registerPlugins(plugins),
providers: commonProviders,
exports: commonProviders,
};
}

private static createProxyClassProviders(
proxyProviderClasses?: Array<Type>,
) {
Expand Down
76 changes: 71 additions & 5 deletions packages/core/test/plugin/plugin.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ import { NestFactory } from '@nestjs/core';
import { Controller, Get, Module } from '@nestjs/common';
import supertest from 'supertest';

function providerToken(name: string) {
return `${name}ProviderToken`;
}

function pluginInitializedToken(name: string) {
return `${name.toLocaleUpperCase()}_PLUGIN_INITIALIZED`;
}

function createDummyPlugin(name: string) {
const watchers = {
initHasRun: false,
Expand All @@ -18,11 +26,11 @@ function createDummyPlugin(name: string) {
watchers.destroyHasRun = true;
},
onClsInit: (cls) => {
cls.set('PLUGIN_INITIALIZED', true);
cls.set(pluginInitializedToken(name), true);
},
providers: [
{
provide: 'providerFromPlugin',
provide: providerToken(name),
useValue: 'valueFromPlugin',
},
],
Expand Down Expand Up @@ -51,7 +59,7 @@ describe('Plugins', () => {
await module.init();

expect(watchers.initHasRun).toBe(true);
expect(module.get('providerFromPlugin')).toBe('valueFromPlugin');
expect(module.get(providerToken('forRoot'))).toBe('valueFromPlugin');
expect(watchers.destroyHasRun).toBe(false);

await module.close();
Expand All @@ -78,7 +86,9 @@ describe('Plugins', () => {
await module.init();

expect(watchers.initHasRun).toBe(true);
expect(module.get('providerFromPlugin')).toBe('valueFromPlugin');
expect(module.get(providerToken('forRootAsync'))).toBe(
'valueFromPlugin',
);
expect(watchers.destroyHasRun).toBe(false);

await module.close();
Expand All @@ -96,7 +106,7 @@ describe('Plugins', () => {
constructor(private readonly cls: ClsService) {}
@Get()
get() {
return this.cls.get('PLUGIN_INITIALIZED');
return this.cls.get(pluginInitializedToken('onClsInit'));
}
}

Expand All @@ -123,4 +133,60 @@ describe('Plugins', () => {
await module.close();
},
);

it('should register plugin and run module lifecycle and onClsInit methods (registerPlugins)', async () => {
const root = createDummyPlugin('root');
const feature = createDummyPlugin('feature');

@Controller()
class TestController {
constructor(private readonly cls: ClsService) {}
@Get()
get() {
return (
this.cls.get(pluginInitializedToken('root')) &&
this.cls.get(pluginInitializedToken('feature'))
);
}
}
@Module({
imports: [
ClsModule.forRoot({
middleware: {
mount: true,
},
plugins: [root.plugin],
}),
ClsModule.registerPlugins([feature.plugin]),
],
controllers: [TestController],
})
class TestAppModule {}

const module = await NestFactory.create(TestAppModule);

expect(root.watchers.initHasRun).toBe(false);
expect(feature.watchers.initHasRun).toBe(false);

await module.init();

expect(root.watchers.initHasRun).toBe(true);
expect(feature.watchers.initHasRun).toBe(true);

expect(module.get(providerToken('root'))).toBe('valueFromPlugin');
expect(module.get(providerToken('feature'))).toBe('valueFromPlugin');

expect(root.watchers.destroyHasRun).toBe(false);
expect(feature.watchers.destroyHasRun).toBe(false);

await supertest(module.getHttpServer())
.get('/')
.expect(200)
.expect('true');

await module.close();

expect(root.watchers.destroyHasRun).toBe(true);
expect(feature.watchers.destroyHasRun).toBe(true);
});
});

0 comments on commit ef2299d

Please sign in to comment.