Skip to content

Commit

Permalink
docs: update readme and document proxy options
Browse files Browse the repository at this point in the history
  • Loading branch information
Papooch committed Oct 7, 2022
1 parent 6320ae6 commit f3513c3
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 22 deletions.
2 changes: 1 addition & 1 deletion .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
node_modules
tmp
test
./src
src
dist/test
gqlschema.gql
tsconfig.tsbuildinfo
Expand Down
92 changes: 71 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -622,18 +622,25 @@ The injectable `ClsService` provides the following API to manipulate the cls con

- **_`set`_**`(key: string, value: any): void`
Set a value on the CLS context.

- **_`get`_**`(key?: string): any`
Retrieve a value from the CLS context by key. Get the whole store if key is omitted.

- **_`has`_**`(key: string): boolean`
Check if a key is in the CLS context.

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

- **_`enter`_**`(): void;`
Run any following code in a shared CLS context.

- **_`enterWith`_**`(store: any): void;`
Run any following code in a shared CLS context (while supplying the default contents).

- **_`run`_**`(callback: () => T): T;`
Run the callback in a shared CLS context.

- **_`runWith`_**`(store: any, callback: () => T): T;`
Run the callback in a shared CLS context (while supplying the default contents).
- **_`isActive`_**`(): boolean`
Expand All @@ -643,41 +650,84 @@ The injectable `ClsService` provides the following API to manipulate the cls con

## Module Options

The `ClsModule.forRoot()` method takes the following `ClsModuleOptions`:
### Root

The `ClsModule.forRoot()` method takes the following **`ClsModuleOptions`**:

- **_`middleware:`_ `ClsMiddlewareOptions`**
An object with additional options for the `ClsMiddleware`, see below
- **_`guard:`_ `ClsGuardOptions`**
An object with additional options for the `ClsGuard`, see below
- **_`interceptor:`_ `ClsInterceptorOptions`**
An object with additional options for the `ClsInterceptor`, see below
- **_`global:`_ `boolean`** (default _`false`_)
- **_`middleware?:`_ `ClsMiddlewareOptions`**
An object with additional options for the `ClsMiddleware`, see [below](#enhancer-options).

- **_`guard?:`_ `ClsGuardOptions`**
An object with additional options for the `ClsGuard`, see [below](#enhancer-options).

- **_`interceptor?:`_ `ClsInterceptorOptions`**
An object with additional options for the `ClsInterceptor`, see [below](#enhancer-options).

- **_`global?:`_ `boolean`** (default _`false`_)
Whether to make the module global, so you do not have to import `ClsModule.forFeature()` in other modules.
- **_`namespaceName`_: `string`** (default _unset_)
The namespace that will be set up. When used, `ClsService` must be injected using the `@InjectCls('name')` decorator. (most of the time you will not need to touch this setting)

- **_`proxyProviders?:`_ `Type[]`**
Array of [Proxy Providers](#proxy-providers) that should be registered in the root module. Currently only accepts sync class Proxy providers, use `ClsModule.forFeatureAsync()` for more complex use-cases.

> **Please note**: the `middleware`, `guard` and `interceptor` options should be _mutually exclusive_ - do not use more than one of them, otherwise the context will be overwritten by the one that runs after.
`ClsModule.forRootAsync()` is also available. You can supply the usual `imports`, `inject` and `useFactory` parameters.

All of the `Cls{Middleware,Guard,Interceptor}Options` take the following parameters (either in `ClsModuleOptions` or directly when instantiating them manually):
### Feature

The `ClsModule.forFeature()` method can be used to register a [Proxy Providers](#proxy-providers). The Sync method only accepts Class Proxy providers.

The `ClsModule.forFeatureAsync()` method accepts either `ClsModuleProxyClassProviderOptions` or `ClsModuleProxyFactoryProviderOptions` that both accept these options:

- **_`provide?:`_ `any`**
Custom injection token to use for the provider. In case of a class provider, this parameter is optional, as the class reference passed to `useClass` will be used by default.

- **_`mount`_: `boolean`** (default _`false`_)
Whether to automatically mount the middleware/guard/interceptor to every route (not applicable when instantiating manually)
- **_`generateId`_: `boolean`** (default _`false`_)
Whether to automatically generate request IDs.
- **_`idGenerator`_: `(req: Request | ExecutionContext) => string | Promise<string>`**
- **_`imports?`_ `any[]`**
Optional list of imported modules that export the providers which are required for the provider.

- **_`extraProviders?:`_ `Provider[]`**
Optional list of additional providers that should be available to the Proxy. Useful for passing configuration from a parent dynamic module.

The `ClsModuleProxyClassProviderOptions` interface further accepts:

- **_`useClass:`_ `Type`**
The target class that will be used by this Proxy Provider. Make sure it is decorated with `@InjectableProxy`.

The `ClsModuleProxyFactoryProviderOptions` interface further accepts:

- **_`inject:`_ `any[]`**
An array of injection tokens for providers used in the `useFactory`.

- **_`useFactory:`_ `(...args: any[]) => any`**
Factory function that accepts an array of providers in the order of the according tokens in the `inject` array. Returns (or resolves with) an object (or a function) that will be used by this Proxy Provider.

### Enhancer options

All of the **`Cls{Middleware,Guard,Interceptor}Options`** take the following parameters (either in `ClsModuleOptions` or directly when instantiating them manually):

- **_`mount?:`_ `boolean`** (default _`false`_)
Whether to automatically mount the middleware/guard/interceptor to every route (not applicable when instantiating them manually)

- **_`generateId?:`_ `boolean`** (default _`false`_)
Whether to automatically generate a request ID. It will be available under the `CLS_ID` key.

- **_`idGenerator?:`_ `(req: Request) => string | Promise<string>`**
**_`idGenerator?:`_ `(ctx: ExecutionContext) => string | Promise<string>`**
An optional function for generating the request ID. It takes the `Request` object (or the `ExecutionContext` in case of a Guard or Interceptor) as an argument and (synchronously or asynchronously) returns a string. The default implementation uses `Math.random()` to generate a string of 8 characters.
- **_`setup`_: `(cls: ClsService, req: Request) => void | Promise<void>;`**
Function that executes after the CLS context has been initialised. It can be used to put additional variables in the CLS context.

- **_`setup?:`_ `(cls: ClsService, req: Request) => void | Promise<void>;`**
**_`setup?:`_ `(cls: ClsService, ctx: ExecutionContext) => void | Promise<void>;`**
Function that executes after the CLS context had been initialised. It can be used to put additional variables in the CLS context.

The `ClsMiddlewareOptions` additionally takes the following parameters:

- **_`saveReq`_: `boolean`** (default _`true`_)
- **_`saveReq?:`_ `boolean`** (default _`true`_)
Whether to store the _Request_ object to the context. It will be available under the `CLS_REQ` key.
- **_`saveRes`_: `boolean`** (default _`false`_)

- **_`saveRes?:`_ `boolean`** (default _`false`_)
Whether to store the _Response_ object to the context. It will be available under the `CLS_RES` key
- **_`useEnterWith`_: `boolean`** (default _`false`_)

- **_`useEnterWith?:`_ `boolean`** (default _`false`_)
Set to `true` to set up the context using a call to [`AsyncLocalStorage#enterWith`](https://nodejs.org/api/async_context.html#async_context_asynclocalstorage_enterwith_store) instead of wrapping the `next()` call with the safer [`AsyncLocalStorage#run`](https://nodejs.org/api/async_context.html#async_context_asynclocalstorage_run_store_callback_args). Most of the time this should not be necessary, but [some frameworks](#graphql) are known to lose the context with `run`.

# Security considerations
Expand Down
41 changes: 41 additions & 0 deletions src/lib/proxy-provider/proxy-provider.interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,57 @@ import { Provider, Type } from '@nestjs/common';
import { ModuleRef } from '@nestjs/core';

export interface ClsModuleProxyClassProviderOptions {
/**
* Custom injection token to use for the provider. In case of a class provider,
* this parameter is optional, as the class reference passed to `useClass` will
* be used by default.
*/
provide?: any;

/**
* Optional list of imported modules that export the providers which are required for the provider.
*/
imports?: any[];

/**
* Optional list of additional providers that should be available to the Proxy.
* Useful for passing configuration from a parent dynamic module.
*/
extraProviders?: Provider[];

/**
* The target class that will be used by this Proxy Provider. Make sure it is decorated with `@InjectableProxy`.
*/
useClass: Type;
}
export interface ClsModuleProxyFactoryProviderOptions {
/**
* Custom injection token to use for the provider. In case of a class provider,
* this parameter is optional, as the class reference passed to `useClass` will
* be used by default.
*/
provide: any;

/**
* Optional list of imported modules that export the providers which are required for the provider.
*/
imports?: any[];

/**
* Optional list of additional providers that should be available to the Proxy.
* Useful for passing configuration from a parent dynamic module.
*/
extraProviders?: Provider[];

/**
* An array of injection tokens for providers used in the `useFactory`.
*/
inject?: any[];

/**
* Factory function that accepts an array of providers in the order of the according tokens in the `inject` array.
* Returns (or resolves with) an object (or a function) that will be used by this Proxy Provider.
*/
useFactory: (...args: any[]) => any;
}

Expand Down

0 comments on commit f3513c3

Please sign in to comment.