Skip to content

Commit 48da8a2

Browse files
authored
feat(core): mark parts of old plugin API as deprecated, update docs (#217)
Better and more flexible plugin API coming up!
1 parent bcbd528 commit 48da8a2

File tree

7 files changed

+2508
-2482
lines changed

7 files changed

+2508
-2482
lines changed

docs/docs/04_api/01_service-interface.md

+40-45
Original file line numberDiff line numberDiff line change
@@ -6,72 +6,67 @@ The injectable `ClsService` provides the following API to manipulate the cls con
66

77
The `S` type parameter is used as the type of custom `ClsStore`.
88

9-
- **_`get`_**`(): S`
10-
Get the entire CLS context.
9+
- **_`get`_**`(): S`
10+
Get the entire CLS context.
1111

12-
- **_`get`_**`(key?: keyof S): S[key]`
13-
Retrieve a value from the CLS context by key.
12+
- **_`get`_**`(key?: keyof S): S[key]`
13+
Retrieve a value from the CLS context by key.
1414

15-
- **_`getId`_**`(): string;`
16-
Retrieve the request ID (a shorthand for `cls.get(CLS_ID)`)
15+
- **_`getId`_**`(): string;`
16+
Retrieve the request ID (a shorthand for `cls.get(CLS_ID)`)
1717

18-
- **_`has`_**`(key: keyof S): boolean`
19-
Check if a key is in the CLS context.
18+
- **_`has`_**`(key: keyof S): boolean`
19+
Check if a key is in the CLS context.
2020

21-
- **_`set`_**`(key: keyof S, value: S[key]): void`
22-
Set a value on the CLS context.
21+
- **_`set`_**`(key: keyof S, value: S[key]): void`
22+
Set a value on the CLS context.
2323

24-
- **_`setIfUndefined`_**`(key: keyof S, value: S[key]): void`
25-
Set a value on the CLS context _only_ if it hasn't been already set. Useful for ensuring idempotence if you have multiple entry points.
24+
- **_`setIfUndefined`_**`(key: keyof S, value: S[key]): void`
25+
Set a value on the CLS context _only_ if it hasn't been already set. Useful for ensuring idempotence if you have multiple entry points.
2626

27-
- **_`run`_**`(callback: () => T): T`
28-
**_`run`_**`(options: ClsContextOptions, callback: () => T): T;`
29-
Run the callback in a shared CLS context. Optionally takes an [options object](#clscontextoptions) as the first parameter.
27+
- **_`run`_**`(callback: () => T): T`
28+
**_`run`_**`(options: ClsContextOptions, callback: () => T): T;`
29+
Run the callback in a shared CLS context. Optionally takes an [options object](#clscontextoptions) as the first parameter.
3030

31-
- **_`runWith`_**`(store: S, callback: () => T): T`
32-
Run the callback in a new CLS context (while supplying the default store).
31+
- **_`runWith`_**`(store: S, callback: () => T): T`
32+
Run the callback in a new CLS context (while supplying the default store).
3333

34-
- **_`enter`_**`(): void;`
35-
**_`enter`_**`(options: ClsContextOptions): void`
36-
Run any following code in a shared CLS context. Optionally takes an [options object](#clscontextoptions) as the first parameter.
34+
- **_`enter`_**`(): void;`
35+
**_`enter`_**`(options: ClsContextOptions): void`
36+
Run any following code in a shared CLS context. Optionally takes an [options object](#clscontextoptions) as the first parameter.
3737

38-
- **_`enterWith`_**`(store: S): void`
39-
Run any following code in a new CLS context (while supplying the default store).
38+
- **_`enterWith`_**`(store: S): void`
39+
Run any following code in a new CLS context (while supplying the default store).
4040

41-
- **_`exit`_**`(callback: () => T): T`
42-
Run the callback _without_ access to a shared CLS context.
41+
- **_`exit`_**`(callback: () => T): T`
42+
Run the callback _without_ access to a shared CLS context.
4343

44-
- **_`isActive`_**`(): boolean`
45-
Whether the current code runs within an active CLS context.
44+
- **_`isActive`_**`(): boolean`
45+
Whether the current code runs within an active CLS context.
4646

4747
The following methods only apply to the [Proxy](../03_features-and-use-cases/06_proxy-providers.md) feature:
4848

49-
- **_`getProxy`_**`(proxyToken: any): any`
50-
Retrieve a Proxy provider from the CLS context based on its injection token.
49+
- **_`getProxy`_**`(proxyToken: any): any`
50+
Retrieve a Proxy provider from the CLS context based on its injection token.
5151

52-
- **_`setProxy`_**`(proxyToken: any, value? any): any`
53-
Replace an instance of a Proxy provider in the CLS context based on its injection token.
52+
- **_`setProxy`_**`(proxyToken: any, value? any): any`
53+
Replace an instance of a Proxy provider in the CLS context based on its injection token.
5454

55-
- **_`resolveProxyProviders`_**`(proxyTokens?: any[]): Promise<void>`
56-
Manually trigger resolution of registered Proxy Providers. If an array of injection tokens is provided, resolves only those Proxy Providers.
57-
58-
The following methods involve the [plugin lifecycle](../06_plugins/02_plugin-api.md):
59-
60-
- **_`initializePlugins`_**`(): Promise<void>`
61-
Manually trigger `onClsInit` hooks of registered plugins.
55+
- **_`resolveProxyProviders`_**`(proxyTokens?: any[]): Promise<void>`
56+
Manually trigger resolution of registered Proxy Providers. If an array of injection tokens is provided, resolves only those Proxy Providers.
6257

6358
## ClsContextOptions
6459

6560
The `run` and `enter` methods can take an additional options object with the following settings:
6661

67-
- **_`ifNested?:`_**`'inherit' | 'reuse' | 'override'`
68-
Sets the behavior of nested CLS context creation in case the method is invoked in an existing context. It has no effect if no parent context exist.
69-
- `inherit` (default) - Run the callback with a shallow copy of the parent context.
70-
Re-assignments of top-level properties will not be reflected in the parent context. However, modifications of existing properties _will_ be reflected.
71-
- `reuse` - Reuse existing context without creating a new one. All modifications to the
72-
existing context will be reflected.
73-
- `override` - Run the callback with an new empty context.
74-
No values from the parent context will be accessible within the wrapped code.
62+
- **_`ifNested?:`_**`'inherit' | 'reuse' | 'override'`
63+
Sets the behavior of nested CLS context creation in case the method is invoked in an existing context. It has no effect if no parent context exist.
64+
- `inherit` (default) - Run the callback with a shallow copy of the parent context.
65+
Re-assignments of top-level properties will not be reflected in the parent context. However, modifications of existing properties _will_ be reflected.
66+
- `reuse` - Reuse existing context without creating a new one. All modifications to the
67+
existing context will be reflected.
68+
- `override` - Run the callback with an new empty context.
69+
No values from the parent context will be accessible within the wrapped code.
7570

7671
::: Note
7772

docs/docs/04_api/02_module-options.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ All of the **`Cls{Middleware,Guard,Interceptor}Options`** take the following par
8383
Whether to automatically resolve Proxy Providers in the enhancer (if any are registered).
8484

8585
- **_`initializePlugins?:`_**`boolean` (default _`true`_)
86-
Whether to run the `onClsInit` hook for plugins as a part of the CLS context registration (runs before `resolveProxyProviders` just after `setup`).
86+
Whether to run the initialization hooks for plugins as a part of the CLS context registration.
8787

8888
The `ClsMiddlewareOptions` additionally takes the following parameters:
8989

docs/docs/06_plugins/index.md

+16-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Plugins can hook into the lifecycle of the `ClsModule` and the CLS context setup
88

99
## Usage
1010

11-
To use a plugin, pass it to the `forRoot` method of the `ClsModule`:
11+
To use a plugin, pass it to the `forRoot` or `forRootAsync` method of the `ClsModule`:
1212

1313
```ts
1414
ClsModule.forRoot({
@@ -18,12 +18,26 @@ ClsModule.forRoot({
1818
});
1919
```
2020

21-
If you need to inject Plugins from an external module, use the `ClsModule.registerPlugins()` registration to import the containing module.
21+
```ts
22+
ClsModule.forRootAsync({
23+
// highlight-start
24+
plugins: [new MyPlugin()],
25+
// highlight-end
26+
});
27+
```
28+
29+
~~If you need to inject Plugins from an external module, use the `ClsModule.registerPlugins()` registration to import the containing module.~~
2230

2331
```ts
2432
ClsModule.registerPlugins([new MyPlugin()]);
2533
```
2634

35+
:::warning
36+
37+
The `ClsModule.registerPlugins` method is deprecated and will be removed in a future release due to a major refactor of the plugin architecture. All plugins must be registered via the root method.
38+
39+
:::
40+
2741
## Available plugins
2842

2943
For a list of plugins managed by the author of `nestjs-cls`, see the [Available Plugins](./01_available-plugins/index.md) page.

packages/core/src/lib/cls-module/cls.module.ts

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { DynamicModule, Module, Type } from '@nestjs/common';
1+
import { DynamicModule, Logger, Module, Type } from '@nestjs/common';
22
import { ClsModuleAsyncOptions, ClsModuleOptions } from '../cls.options';
33
import { ClsPluginManager } from '../plugin/cls-plugin-manager';
44

@@ -83,8 +83,18 @@ export class ClsModule {
8383

8484
/**
8585
* Registers the given Plugins the module along with `ClsService`.
86+
* @deprecated
87+
* All plugins must be registered in the `ClsModule.forRoot` or `ClsModule.forRootAsync` options.
88+
*
89+
* Since the plugin API is still experimental, this method will print a warning, throw error
90+
* and will be eventually removed, possibly in a minor release.
8691
*/
8792
static registerPlugins(plugins: ClsPlugin[]): DynamicModule {
93+
const logger = new Logger('ClsModule');
94+
logger.warn(
95+
'The `ClsModule.registerPlugins` method is deprecated and will be removed in a future release. ' +
96+
'All plugins must be registered in the `ClsModule.forRoot` or `ClsModule.forRootAsync` options.',
97+
);
8898
return {
8999
module: ClsModule,
90100
imports: ClsPluginManager.registerPlugins(plugins),

packages/core/src/lib/cls.options.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,8 @@ export class ClsInitializerCommonOptions {
9797
resolveProxyProviders? = true;
9898

9999
/**
100-
* Whether to run the onClsInit hook for plugins as a part
101-
* of the CLS context registration (runs before `resolveProxyProviders` just after `setup`)
100+
* Whether to run the initialization hooks for plugins as a part
101+
* of the CLS context registration in this initializer
102102
*
103103
* Default: `true`
104104
*/

packages/core/src/lib/cls.service.ts

+7
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,13 @@ export class ClsService<S extends ClsStore = ClsStore> {
236236
await ProxyProviderManager.resolveProxyProviders(proxySymbols);
237237
}
238238

239+
/**
240+
* @deprecated This method will be removed in a future release and replaced
241+
* with a different mechanism for plugin initialization.
242+
*
243+
* Since the plugin API is still experimental, this method will become a np-op
244+
* and will be eventually removed, possibly in a minor release.
245+
*/
239246
async initializePlugins() {
240247
const { ClsPluginManager } = await import(
241248
'./plugin/cls-plugin-manager'

0 commit comments

Comments
 (0)