@nest-boot/request-context 7.4.1 → 7.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/create-request-context.decorator.d.ts +57 -2
- package/dist/create-request-context.decorator.js +53 -0
- package/dist/create-request-context.decorator.js.map +1 -1
- package/dist/repl.d.ts +43 -1
- package/dist/repl.js +41 -0
- package/dist/repl.js.map +1 -1
- package/dist/request-context.constants.d.ts +22 -0
- package/dist/request-context.constants.js +22 -0
- package/dist/request-context.constants.js.map +1 -1
- package/dist/request-context.d.ts +286 -3
- package/dist/request-context.interceptor.d.ts +30 -0
- package/dist/request-context.interceptor.js +30 -0
- package/dist/request-context.interceptor.js.map +1 -1
- package/dist/request-context.js +250 -0
- package/dist/request-context.js.map +1 -1
- package/dist/request-context.middleware.d.ts +27 -0
- package/dist/request-context.middleware.js +27 -0
- package/dist/request-context.middleware.js.map +1 -1
- package/dist/request-context.module.d.ts +41 -0
- package/dist/request-context.module.js +41 -0
- package/dist/request-context.module.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +19 -10
|
@@ -1,4 +1,59 @@
|
|
|
1
1
|
import { RequestContext } from "./request-context";
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Helper type that extracts the argument types of a method.
|
|
4
|
+
*/
|
|
5
|
+
export type MethodArgs<T, M extends keyof T> = T[M] extends (...args: infer A) => any ? A : never;
|
|
6
|
+
/**
|
|
7
|
+
* Method decorator that wraps the method execution in a new request context.
|
|
8
|
+
*
|
|
9
|
+
* This is useful for creating request contexts for background jobs, event handlers,
|
|
10
|
+
* or any other code that runs outside of HTTP request handling.
|
|
11
|
+
*
|
|
12
|
+
* @typeParam T - The class type containing the method
|
|
13
|
+
* @typeParam P - The property key of the method
|
|
14
|
+
* @param fn - A function that creates the RequestContext, receiving the class instance and method arguments
|
|
15
|
+
* @returns A method decorator
|
|
16
|
+
*
|
|
17
|
+
* @example Basic usage with a job processor
|
|
18
|
+
* ```typescript
|
|
19
|
+
* import { CreateRequestContext, RequestContext } from '@nest-boot/request-context';
|
|
20
|
+
*
|
|
21
|
+
* class JobProcessor {
|
|
22
|
+
* @CreateRequestContext((instance, jobData) =>
|
|
23
|
+
* new RequestContext({ type: 'job', id: jobData.id })
|
|
24
|
+
* )
|
|
25
|
+
* async processJob(jobData: { id: string; payload: any }) {
|
|
26
|
+
* // This code runs within a request context
|
|
27
|
+
* console.log(`Processing job ${RequestContext.id}`);
|
|
28
|
+
* // ...
|
|
29
|
+
* }
|
|
30
|
+
* }
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* @example With service injection
|
|
34
|
+
* ```typescript
|
|
35
|
+
* import { Injectable } from '@nestjs/common';
|
|
36
|
+
* import { CreateRequestContext, RequestContext } from '@nest-boot/request-context';
|
|
37
|
+
*
|
|
38
|
+
* @Injectable()
|
|
39
|
+
* class EventHandler {
|
|
40
|
+
* @CreateRequestContext((instance, event) =>
|
|
41
|
+
* new RequestContext({
|
|
42
|
+
* type: 'event',
|
|
43
|
+
* id: event.correlationId,
|
|
44
|
+
* })
|
|
45
|
+
* )
|
|
46
|
+
* async handleEvent(event: { correlationId: string; data: any }) {
|
|
47
|
+
* // Access context within the handler
|
|
48
|
+
* RequestContext.set('eventType', event.data.type);
|
|
49
|
+
* await this.processEvent(event);
|
|
50
|
+
* }
|
|
51
|
+
*
|
|
52
|
+
* private async processEvent(event: any) {
|
|
53
|
+
* // Context is still available here
|
|
54
|
+
* const eventType = RequestContext.get('eventType');
|
|
55
|
+
* }
|
|
56
|
+
* }
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
3
59
|
export declare function CreateRequestContext<T extends object, P extends keyof T>(fn: (instance: T, ...args: MethodArgs<T, P>) => RequestContext): (_target: T, _propertyKey: P, descriptor: PropertyDescriptor) => PropertyDescriptor;
|
|
4
|
-
export {};
|
|
@@ -2,6 +2,59 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CreateRequestContext = CreateRequestContext;
|
|
4
4
|
const request_context_1 = require("./request-context");
|
|
5
|
+
/**
|
|
6
|
+
* Method decorator that wraps the method execution in a new request context.
|
|
7
|
+
*
|
|
8
|
+
* This is useful for creating request contexts for background jobs, event handlers,
|
|
9
|
+
* or any other code that runs outside of HTTP request handling.
|
|
10
|
+
*
|
|
11
|
+
* @typeParam T - The class type containing the method
|
|
12
|
+
* @typeParam P - The property key of the method
|
|
13
|
+
* @param fn - A function that creates the RequestContext, receiving the class instance and method arguments
|
|
14
|
+
* @returns A method decorator
|
|
15
|
+
*
|
|
16
|
+
* @example Basic usage with a job processor
|
|
17
|
+
* ```typescript
|
|
18
|
+
* import { CreateRequestContext, RequestContext } from '@nest-boot/request-context';
|
|
19
|
+
*
|
|
20
|
+
* class JobProcessor {
|
|
21
|
+
* @CreateRequestContext((instance, jobData) =>
|
|
22
|
+
* new RequestContext({ type: 'job', id: jobData.id })
|
|
23
|
+
* )
|
|
24
|
+
* async processJob(jobData: { id: string; payload: any }) {
|
|
25
|
+
* // This code runs within a request context
|
|
26
|
+
* console.log(`Processing job ${RequestContext.id}`);
|
|
27
|
+
* // ...
|
|
28
|
+
* }
|
|
29
|
+
* }
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* @example With service injection
|
|
33
|
+
* ```typescript
|
|
34
|
+
* import { Injectable } from '@nestjs/common';
|
|
35
|
+
* import { CreateRequestContext, RequestContext } from '@nest-boot/request-context';
|
|
36
|
+
*
|
|
37
|
+
* @Injectable()
|
|
38
|
+
* class EventHandler {
|
|
39
|
+
* @CreateRequestContext((instance, event) =>
|
|
40
|
+
* new RequestContext({
|
|
41
|
+
* type: 'event',
|
|
42
|
+
* id: event.correlationId,
|
|
43
|
+
* })
|
|
44
|
+
* )
|
|
45
|
+
* async handleEvent(event: { correlationId: string; data: any }) {
|
|
46
|
+
* // Access context within the handler
|
|
47
|
+
* RequestContext.set('eventType', event.data.type);
|
|
48
|
+
* await this.processEvent(event);
|
|
49
|
+
* }
|
|
50
|
+
*
|
|
51
|
+
* private async processEvent(event: any) {
|
|
52
|
+
* // Context is still available here
|
|
53
|
+
* const eventType = RequestContext.get('eventType');
|
|
54
|
+
* }
|
|
55
|
+
* }
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
5
58
|
function CreateRequestContext(fn) {
|
|
6
59
|
return (_target, _propertyKey, descriptor) => {
|
|
7
60
|
if (descriptor.value) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-request-context.decorator.js","sourceRoot":"","sources":["../src/create-request-context.decorator.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"create-request-context.decorator.js","sourceRoot":"","sources":["../src/create-request-context.decorator.ts"],"names":[],"mappings":";;AAgEA,oDAeC;AA/ED,uDAAmD;AAWnD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AACH,SAAgB,oBAAoB,CAClC,EAA8D;IAE9D,OAAO,CAAC,OAAU,EAAE,YAAe,EAAE,UAA8B,EAAE,EAAE;QACrE,IAAI,UAAU,CAAC,KAAK,EAAE,CAAC;YACrB,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC;YAElC,UAAU,CAAC,KAAK,GAAG,UAAmB,GAAG,IAAsB;gBAC7D,MAAM,GAAG,GAAG,EAAE,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,CAAC;gBAC9B,OAAO,gCAAc,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;YACnE,CAAC,CAAC;QACJ,CAAC;QAED,OAAO,UAAU,CAAC;IACpB,CAAC,CAAC;AACJ,CAAC"}
|
package/dist/repl.d.ts
CHANGED
|
@@ -1,2 +1,44 @@
|
|
|
1
1
|
import { DynamicModule, Type } from "@nestjs/common";
|
|
2
|
-
|
|
2
|
+
import type { REPLServer } from "repl";
|
|
3
|
+
/**
|
|
4
|
+
* Starts a REPL (Read-Eval-Print Loop) session with request context support.
|
|
5
|
+
*
|
|
6
|
+
* This function creates a NestJS application context and starts an interactive
|
|
7
|
+
* REPL session where all commands run within a request context. This is useful
|
|
8
|
+
* for debugging and testing services that depend on request context.
|
|
9
|
+
*
|
|
10
|
+
* The REPL session:
|
|
11
|
+
* - Runs within a request context of type 'repl'
|
|
12
|
+
* - Has access to all NestJS providers
|
|
13
|
+
* - Maintains context across async operations
|
|
14
|
+
*
|
|
15
|
+
* @param module - The NestJS module (class or DynamicModule) to create the context from
|
|
16
|
+
* @returns A promise that resolves to the REPL server instance
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* // repl.ts
|
|
21
|
+
* import { repl } from '@nest-boot/request-context';
|
|
22
|
+
* import { AppModule } from './app.module';
|
|
23
|
+
*
|
|
24
|
+
* async function bootstrap() {
|
|
25
|
+
* await repl(AppModule);
|
|
26
|
+
* }
|
|
27
|
+
*
|
|
28
|
+
* bootstrap();
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* @example Running the REPL
|
|
32
|
+
* ```bash
|
|
33
|
+
* npx ts-node -r tsconfig-paths/register repl.ts
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* @example Using services in REPL
|
|
37
|
+
* ```typescript
|
|
38
|
+
* // In the REPL session:
|
|
39
|
+
* > const userService = get(UserService)
|
|
40
|
+
* > await userService.findAll()
|
|
41
|
+
* > RequestContext.id // Access current context ID
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export declare function repl(module: Type | DynamicModule): Promise<REPLServer>;
|
package/dist/repl.js
CHANGED
|
@@ -45,6 +45,47 @@ const repl_native_commands_1 = require("@nestjs/core/repl/repl-native-commands")
|
|
|
45
45
|
const async_hooks_1 = require("async_hooks");
|
|
46
46
|
const stream_1 = require("stream");
|
|
47
47
|
const request_context_1 = require("./request-context");
|
|
48
|
+
/**
|
|
49
|
+
* Starts a REPL (Read-Eval-Print Loop) session with request context support.
|
|
50
|
+
*
|
|
51
|
+
* This function creates a NestJS application context and starts an interactive
|
|
52
|
+
* REPL session where all commands run within a request context. This is useful
|
|
53
|
+
* for debugging and testing services that depend on request context.
|
|
54
|
+
*
|
|
55
|
+
* The REPL session:
|
|
56
|
+
* - Runs within a request context of type 'repl'
|
|
57
|
+
* - Has access to all NestJS providers
|
|
58
|
+
* - Maintains context across async operations
|
|
59
|
+
*
|
|
60
|
+
* @param module - The NestJS module (class or DynamicModule) to create the context from
|
|
61
|
+
* @returns A promise that resolves to the REPL server instance
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```typescript
|
|
65
|
+
* // repl.ts
|
|
66
|
+
* import { repl } from '@nest-boot/request-context';
|
|
67
|
+
* import { AppModule } from './app.module';
|
|
68
|
+
*
|
|
69
|
+
* async function bootstrap() {
|
|
70
|
+
* await repl(AppModule);
|
|
71
|
+
* }
|
|
72
|
+
*
|
|
73
|
+
* bootstrap();
|
|
74
|
+
* ```
|
|
75
|
+
*
|
|
76
|
+
* @example Running the REPL
|
|
77
|
+
* ```bash
|
|
78
|
+
* npx ts-node -r tsconfig-paths/register repl.ts
|
|
79
|
+
* ```
|
|
80
|
+
*
|
|
81
|
+
* @example Using services in REPL
|
|
82
|
+
* ```typescript
|
|
83
|
+
* // In the REPL session:
|
|
84
|
+
* > const userService = get(UserService)
|
|
85
|
+
* > await userService.findAll()
|
|
86
|
+
* > RequestContext.id // Access current context ID
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
48
89
|
async function repl(module) {
|
|
49
90
|
const app = await core_1.NestFactory.createApplicationContext(module, {
|
|
50
91
|
abortOnError: false,
|
package/dist/repl.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repl.js","sourceRoot":"","sources":["../src/repl.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"repl.js","sourceRoot":"","sources":["../src/repl.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuDA,oBA+CC;AAtGD,2CAA6D;AAC7D,0EAA2D;AAC3D,uCAA2C;AAC3C,mFAAyE;AACzE,2DAAuE;AACvE,iEAA6D;AAC7D,+DAA2D;AAC3D,iFAAqF;AACrF,6CAA4C;AAE5C,mCAAmC;AAEnC,uDAAmD;AAEnD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACI,KAAK,UAAU,IAAI,CAAC,MAA4B;IACrD,MAAM,GAAG,GAAG,MAAM,kBAAW,CAAC,wBAAwB,CAAC,MAAM,EAAE;QAC7D,YAAY,EAAE,KAAK;QACnB,MAAM,EAAE,IAAI,wBAAU,EAAE;KACzB,CAAC,CAAC;IAEH,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;IAEjB,MAAM,WAAW,GAAG,IAAI,0BAAW,CAAC,GAAG,CAAC,CAAC;IACzC,eAAM,CAAC,GAAG,CAAC,oCAAwB,CAAC,CAAC;IAErC,OAAO,MAAM,gCAAc,CAAC,GAAG,CAC7B,IAAI,gCAAc,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EACpC,KAAK,IAAI,EAAE;QACT,MAAM,aAAa,GAAG,IAAI,2BAAa,CAAC,MAAM,CAAC,CAAC;QAEhD,MAAM,UAAU,GAAG,CAAC,wDAAa,MAAM,GAAC,CAAC,CAAC,KAAK,CAAC;YAC9C,KAAK,EAAE,IAAI,KAAK,CACd,OAAO,CAAC,KAAK,CAAC,IAAI,CAChB,IAAI,kBAAS,CAAC;gBACZ,SAAS,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ;oBACjC,aAAa,CAAC,eAAe,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;gBAC7D,CAAC;aACF,CAAC,CACH,EACD;gBACE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ;oBACxB,IAAI,IAAI,IAAI,MAAM,EAAE,CAAC;wBACnB,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;oBAC7C,CAAC;yBAAM,IAAI,IAAI,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;wBACjC,OAAO,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;oBACpD,CAAC;gBACH,CAAC;aACF,CACF;YACD,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,MAAM,EAAE,qBAAG,CAAC,KAAK,CAAC,IAAI,CAAC;YACvB,eAAe,EAAE,IAAI;SACtB,CAAC,CAAC;QAEH,IAAA,sCAAc,EAAC,UAAU,CAAC,OAAO,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC;QAE5D,IAAA,kDAA2B,EAAC,UAAU,CAAC,CAAC;QAExC,OAAO,UAAU,CAAC;IACpB,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -1,2 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token for storing the HTTP request object in the request context.
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```typescript
|
|
6
|
+
* import { REQUEST } from '@nest-boot/request-context';
|
|
7
|
+
* import { Request } from 'express';
|
|
8
|
+
*
|
|
9
|
+
* const req = RequestContext.get<Request>(REQUEST);
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
1
12
|
export declare const REQUEST = "REQUEST";
|
|
13
|
+
/**
|
|
14
|
+
* Token for storing the HTTP response object in the request context.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* import { RESPONSE } from '@nest-boot/request-context';
|
|
19
|
+
* import { Response } from 'express';
|
|
20
|
+
*
|
|
21
|
+
* const res = RequestContext.get<Response>(RESPONSE);
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
2
24
|
export declare const RESPONSE = "RESPONSE";
|
|
@@ -1,6 +1,28 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.RESPONSE = exports.REQUEST = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Token for storing the HTTP request object in the request context.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { REQUEST } from '@nest-boot/request-context';
|
|
10
|
+
* import { Request } from 'express';
|
|
11
|
+
*
|
|
12
|
+
* const req = RequestContext.get<Request>(REQUEST);
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
4
15
|
exports.REQUEST = "REQUEST";
|
|
16
|
+
/**
|
|
17
|
+
* Token for storing the HTTP response object in the request context.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* import { RESPONSE } from '@nest-boot/request-context';
|
|
22
|
+
* import { Response } from 'express';
|
|
23
|
+
*
|
|
24
|
+
* const res = RequestContext.get<Response>(RESPONSE);
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
5
27
|
exports.RESPONSE = "RESPONSE";
|
|
6
28
|
//# sourceMappingURL=request-context.constants.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request-context.constants.js","sourceRoot":"","sources":["../src/request-context.constants.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"request-context.constants.js","sourceRoot":"","sources":["../src/request-context.constants.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;;GAUG;AACU,QAAA,OAAO,GAAG,SAAS,CAAC;AAEjC;;;;;;;;;;GAUG;AACU,QAAA,QAAQ,GAAG,UAAU,CAAC"}
|
|
@@ -1,33 +1,316 @@
|
|
|
1
1
|
import { type Type } from "@nestjs/common";
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Middleware function type for request context.
|
|
4
|
+
* Middlewares are executed in order when running a request context.
|
|
5
|
+
*
|
|
6
|
+
* @typeParam T - The return type of the middleware chain
|
|
7
|
+
* @param ctx - The current request context
|
|
8
|
+
* @param next - Function to call the next middleware in the chain
|
|
9
|
+
* @returns A promise resolving to the result of the middleware chain
|
|
10
|
+
*/
|
|
11
|
+
export type RequestContextMiddlewareType = <T>(ctx: RequestContext, next: () => Promise<T>) => Promise<T>;
|
|
12
|
+
/**
|
|
13
|
+
* Options for creating a new RequestContext instance.
|
|
14
|
+
*/
|
|
3
15
|
export interface RequestContextCreateOptions {
|
|
16
|
+
/**
|
|
17
|
+
* Unique identifier for the request context.
|
|
18
|
+
* If not provided, a random UUID will be generated.
|
|
19
|
+
*/
|
|
4
20
|
id?: string;
|
|
21
|
+
/**
|
|
22
|
+
* The type of context (e.g., 'http', 'graphql', 'repl', 'job').
|
|
23
|
+
*/
|
|
5
24
|
type: string;
|
|
25
|
+
/**
|
|
26
|
+
* Parent context for creating nested/child contexts.
|
|
27
|
+
* Child contexts can access values from parent contexts.
|
|
28
|
+
*/
|
|
6
29
|
parent?: RequestContext;
|
|
7
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* RequestContext provides a way to store and access request-scoped data
|
|
33
|
+
* throughout the lifecycle of a request using AsyncLocalStorage.
|
|
34
|
+
*
|
|
35
|
+
* This is useful for storing data like the current user, request ID,
|
|
36
|
+
* database transactions, and other request-specific information that
|
|
37
|
+
* needs to be accessed across different parts of the application.
|
|
38
|
+
*
|
|
39
|
+
* @example Basic usage
|
|
40
|
+
* ```typescript
|
|
41
|
+
* import { RequestContext } from '@nest-boot/request-context';
|
|
42
|
+
*
|
|
43
|
+
* // Get the current request ID
|
|
44
|
+
* const requestId = RequestContext.id;
|
|
45
|
+
*
|
|
46
|
+
* // Store a value in the context
|
|
47
|
+
* RequestContext.set('userId', 123);
|
|
48
|
+
*
|
|
49
|
+
* // Retrieve a value from the context
|
|
50
|
+
* const userId = RequestContext.get<number>('userId');
|
|
51
|
+
* ```
|
|
52
|
+
*
|
|
53
|
+
* @example Running code in a new context
|
|
54
|
+
* ```typescript
|
|
55
|
+
* await RequestContext.run(
|
|
56
|
+
* new RequestContext({ type: 'job' }),
|
|
57
|
+
* async (ctx) => {
|
|
58
|
+
* ctx.set('jobId', 'abc123');
|
|
59
|
+
* await processJob();
|
|
60
|
+
* }
|
|
61
|
+
* );
|
|
62
|
+
* ```
|
|
63
|
+
*
|
|
64
|
+
* @example Creating a child context
|
|
65
|
+
* ```typescript
|
|
66
|
+
* await RequestContext.child(async (childCtx) => {
|
|
67
|
+
* // Child context inherits values from parent
|
|
68
|
+
* // but can have its own values that don't affect parent
|
|
69
|
+
* childCtx.set('tempValue', 'only in child');
|
|
70
|
+
* });
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
8
73
|
export declare class RequestContext {
|
|
74
|
+
/**
|
|
75
|
+
* Unique identifier for this request context.
|
|
76
|
+
* Automatically generated as a UUID if not provided.
|
|
77
|
+
*/
|
|
9
78
|
readonly id: string;
|
|
79
|
+
/**
|
|
80
|
+
* The type of this context (e.g., 'http', 'graphql', 'repl', 'job').
|
|
81
|
+
*/
|
|
10
82
|
readonly type: string;
|
|
83
|
+
/**
|
|
84
|
+
* Parent context, if this is a child context.
|
|
85
|
+
* Values not found in this context will be looked up in the parent.
|
|
86
|
+
*/
|
|
11
87
|
readonly parent?: RequestContext;
|
|
88
|
+
/** Internal storage map for context values. @internal */
|
|
12
89
|
private readonly container;
|
|
90
|
+
/** Async local storage backing the request context. @internal */
|
|
13
91
|
private static readonly storage;
|
|
92
|
+
/** Registered middleware map keyed by name. @internal */
|
|
14
93
|
private static readonly middlewares;
|
|
94
|
+
/** Dependency graph for middleware ordering. @internal */
|
|
15
95
|
private static readonly middlewareDependencies;
|
|
96
|
+
/** Topologically-sorted middleware execution stack. @internal */
|
|
16
97
|
private static middlewaresStack;
|
|
98
|
+
/** Creates a new RequestContext instance.
|
|
99
|
+
* @param options - Options for creating the request context (id, type, parent)
|
|
100
|
+
*/
|
|
17
101
|
constructor(options: RequestContextCreateOptions);
|
|
102
|
+
/**
|
|
103
|
+
* Gets a value from the context by its token.
|
|
104
|
+
* If not found in this context, looks up the parent context.
|
|
105
|
+
*
|
|
106
|
+
* @typeParam T - The expected type of the value
|
|
107
|
+
* @param token - The key to look up (string, symbol, function, or class)
|
|
108
|
+
* @returns The value if found, otherwise undefined
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```typescript
|
|
112
|
+
* const ctx = RequestContext.current();
|
|
113
|
+
* const user = ctx.get<User>('currentUser');
|
|
114
|
+
* const service = ctx.get(MyService);
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
18
117
|
get<T>(token: string | symbol | Function | Type<T>): T | undefined;
|
|
118
|
+
/**
|
|
119
|
+
* Sets a value in the context.
|
|
120
|
+
*
|
|
121
|
+
* @typeParam T - The type of the value
|
|
122
|
+
* @param typeOrToken - The key to store the value under
|
|
123
|
+
* @param value - The value to store
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```typescript
|
|
127
|
+
* const ctx = RequestContext.current();
|
|
128
|
+
* ctx.set('userId', 123);
|
|
129
|
+
* ctx.set(UserService, userServiceInstance);
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
19
132
|
set<T>(typeOrToken: string | symbol | Type<T>, value: T): void;
|
|
133
|
+
/**
|
|
134
|
+
* Gets a value from the context, or sets it if not present.
|
|
135
|
+
*
|
|
136
|
+
* @typeParam T - The type of the value
|
|
137
|
+
* @param typeOrToken - The key to look up or store under
|
|
138
|
+
* @param value - The value to set if not already present
|
|
139
|
+
* @returns The existing value or the newly set value
|
|
140
|
+
*
|
|
141
|
+
* @example
|
|
142
|
+
* ```typescript
|
|
143
|
+
* const ctx = RequestContext.current();
|
|
144
|
+
* const cache = ctx.getOrSet('cache', new Map());
|
|
145
|
+
* ```
|
|
146
|
+
*/
|
|
20
147
|
getOrSet<T>(typeOrToken: string | symbol | Type<T>, value: T): T;
|
|
148
|
+
/**
|
|
149
|
+
* Gets a value from the current context by its key.
|
|
150
|
+
* Static method that accesses the current context automatically.
|
|
151
|
+
*
|
|
152
|
+
* @typeParam T - The expected type of the value
|
|
153
|
+
* @param key - The key to look up
|
|
154
|
+
* @returns The value if found, otherwise undefined
|
|
155
|
+
* @throws Error if no request context is active
|
|
156
|
+
*
|
|
157
|
+
* @example
|
|
158
|
+
* ```typescript
|
|
159
|
+
* const userId = RequestContext.get<number>('userId');
|
|
160
|
+
* ```
|
|
161
|
+
*/
|
|
21
162
|
static get<T>(key: string | symbol | Function | Type<T>): T | undefined;
|
|
163
|
+
/**
|
|
164
|
+
* Sets a value in the current context.
|
|
165
|
+
* Static method that accesses the current context automatically.
|
|
166
|
+
*
|
|
167
|
+
* @typeParam T - The type of the value
|
|
168
|
+
* @param key - The key to store the value under
|
|
169
|
+
* @param value - The value to store
|
|
170
|
+
* @throws Error if no request context is active
|
|
171
|
+
*
|
|
172
|
+
* @example
|
|
173
|
+
* ```typescript
|
|
174
|
+
* RequestContext.set('userId', 123);
|
|
175
|
+
* ```
|
|
176
|
+
*/
|
|
22
177
|
static set<T>(key: string | symbol | Type<T>, value: T): void;
|
|
178
|
+
/**
|
|
179
|
+
* Gets a value from the current context, or sets it if not present.
|
|
180
|
+
* Static method that accesses the current context automatically.
|
|
181
|
+
*
|
|
182
|
+
* @typeParam T - The type of the value
|
|
183
|
+
* @param key - The key to look up or store under
|
|
184
|
+
* @param value - The value to set if not already present
|
|
185
|
+
* @returns The existing value or the newly set value
|
|
186
|
+
* @throws Error if no request context is active
|
|
187
|
+
*
|
|
188
|
+
* @example
|
|
189
|
+
* ```typescript
|
|
190
|
+
* const cache = RequestContext.getOrSet('cache', new Map());
|
|
191
|
+
* ```
|
|
192
|
+
*/
|
|
23
193
|
static getOrSet<T>(key: string | symbol | Type<T>, value: T): T;
|
|
194
|
+
/**
|
|
195
|
+
* Gets the ID of the current request context.
|
|
196
|
+
*
|
|
197
|
+
* @returns The unique identifier of the current context
|
|
198
|
+
* @throws Error if no request context is active
|
|
199
|
+
*
|
|
200
|
+
* @example
|
|
201
|
+
* ```typescript
|
|
202
|
+
* console.log(`Processing request ${RequestContext.id}`);
|
|
203
|
+
* ```
|
|
204
|
+
*/
|
|
24
205
|
static get id(): string;
|
|
206
|
+
/**
|
|
207
|
+
* Gets the current request context.
|
|
208
|
+
*
|
|
209
|
+
* @returns The current RequestContext instance
|
|
210
|
+
* @throws Error if no request context is active
|
|
211
|
+
*
|
|
212
|
+
* @example
|
|
213
|
+
* ```typescript
|
|
214
|
+
* const ctx = RequestContext.current();
|
|
215
|
+
* console.log(ctx.type); // 'http'
|
|
216
|
+
* ```
|
|
217
|
+
*/
|
|
25
218
|
static current(): RequestContext;
|
|
219
|
+
/**
|
|
220
|
+
* Checks if a request context is currently active.
|
|
221
|
+
*
|
|
222
|
+
* @returns true if a context is active, false otherwise
|
|
223
|
+
*
|
|
224
|
+
* @example
|
|
225
|
+
* ```typescript
|
|
226
|
+
* if (RequestContext.isActive()) {
|
|
227
|
+
* const userId = RequestContext.get('userId');
|
|
228
|
+
* }
|
|
229
|
+
* ```
|
|
230
|
+
*/
|
|
26
231
|
static isActive(): boolean;
|
|
232
|
+
/**
|
|
233
|
+
* Runs a callback within a request context.
|
|
234
|
+
* All registered middlewares are executed before the callback.
|
|
235
|
+
*
|
|
236
|
+
* @typeParam T - The return type of the callback
|
|
237
|
+
* @param ctx - The request context to run within
|
|
238
|
+
* @param callback - The function to execute within the context
|
|
239
|
+
* @returns A promise resolving to the callback's return value
|
|
240
|
+
*
|
|
241
|
+
* @example
|
|
242
|
+
* ```typescript
|
|
243
|
+
* const result = await RequestContext.run(
|
|
244
|
+
* new RequestContext({ type: 'job' }),
|
|
245
|
+
* async (ctx) => {
|
|
246
|
+
* ctx.set('jobId', 'abc123');
|
|
247
|
+
* return await processJob();
|
|
248
|
+
* }
|
|
249
|
+
* );
|
|
250
|
+
* ```
|
|
251
|
+
*/
|
|
27
252
|
static run<T>(ctx: RequestContext, callback: (ctx: RequestContext) => T | Promise<T>): Promise<T>;
|
|
253
|
+
/**
|
|
254
|
+
* Creates and runs a child context that inherits from the current context.
|
|
255
|
+
* Child contexts can read values from parent contexts but modifications
|
|
256
|
+
* are isolated to the child.
|
|
257
|
+
*
|
|
258
|
+
* @typeParam T - The return type of the callback
|
|
259
|
+
* @param callback - The function to execute within the child context
|
|
260
|
+
* @returns A promise resolving to the callback's return value
|
|
261
|
+
* @throws Error if no request context is active
|
|
262
|
+
*
|
|
263
|
+
* @example
|
|
264
|
+
* ```typescript
|
|
265
|
+
* // In parent context
|
|
266
|
+
* RequestContext.set('userId', 123);
|
|
267
|
+
*
|
|
268
|
+
* await RequestContext.child(async (childCtx) => {
|
|
269
|
+
* // Can read parent values
|
|
270
|
+
* const userId = childCtx.get('userId'); // 123
|
|
271
|
+
*
|
|
272
|
+
* // Child-only values don't affect parent
|
|
273
|
+
* childCtx.set('tempData', 'child only');
|
|
274
|
+
* });
|
|
275
|
+
*
|
|
276
|
+
* // Parent context unchanged
|
|
277
|
+
* RequestContext.get('tempData'); // undefined
|
|
278
|
+
* ```
|
|
279
|
+
*/
|
|
28
280
|
static child<T>(callback: (ctx: RequestContext) => T | Promise<T>): Promise<T>;
|
|
29
|
-
|
|
281
|
+
/**
|
|
282
|
+
* Registers a middleware to be executed when running a request context.
|
|
283
|
+
* Middlewares are executed in dependency order.
|
|
284
|
+
*
|
|
285
|
+
* @param name - Unique name for the middleware
|
|
286
|
+
* @param middleware - The middleware function to register
|
|
287
|
+
* @param dependencies - Names of middlewares that must run before this one
|
|
288
|
+
*
|
|
289
|
+
* @example
|
|
290
|
+
* ```typescript
|
|
291
|
+
* RequestContext.registerMiddleware(
|
|
292
|
+
* 'auth',
|
|
293
|
+
* async (ctx, next) => {
|
|
294
|
+
* ctx.set('user', await loadUser());
|
|
295
|
+
* return next();
|
|
296
|
+
* }
|
|
297
|
+
* );
|
|
298
|
+
*
|
|
299
|
+
* // Middleware with dependencies
|
|
300
|
+
* RequestContext.registerMiddleware(
|
|
301
|
+
* 'permissions',
|
|
302
|
+
* async (ctx, next) => {
|
|
303
|
+
* const user = ctx.get('user');
|
|
304
|
+
* ctx.set('permissions', await loadPermissions(user));
|
|
305
|
+
* return next();
|
|
306
|
+
* },
|
|
307
|
+
* ['auth'] // Runs after 'auth' middleware
|
|
308
|
+
* );
|
|
309
|
+
* ```
|
|
310
|
+
*/
|
|
311
|
+
static registerMiddleware(name: string, middleware: RequestContextMiddlewareType, dependencies?: string[]): void;
|
|
312
|
+
/** Resolves middleware dependencies via topological sort. @internal */
|
|
30
313
|
private static resolveDependencies;
|
|
314
|
+
/** Rebuilds the middleware execution stack after registration changes. @internal */
|
|
31
315
|
private static generateMiddlewaresStack;
|
|
32
316
|
}
|
|
33
|
-
export {};
|
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
import { type CallHandler, type ExecutionContext, type NestInterceptor } from "@nestjs/common";
|
|
2
2
|
import { Observable } from "rxjs";
|
|
3
|
+
/**
|
|
4
|
+
* NestJS interceptor that creates request context for HTTP and GraphQL requests.
|
|
5
|
+
*
|
|
6
|
+
* This interceptor serves as a fallback for cases where the middleware doesn't
|
|
7
|
+
* run (e.g., GraphQL resolvers). It:
|
|
8
|
+
* - Creates a new RequestContext if one doesn't already exist
|
|
9
|
+
* - Uses the `x-request-id` header as the context ID if provided
|
|
10
|
+
* - Supports both HTTP and GraphQL execution contexts
|
|
11
|
+
*
|
|
12
|
+
* The interceptor is automatically registered by RequestContextModule.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* The interceptor is typically used automatically, but can be applied manually:
|
|
16
|
+
* ```typescript
|
|
17
|
+
* import { Controller, UseInterceptors } from '@nestjs/common';
|
|
18
|
+
* import { RequestContextInterceptor } from '@nest-boot/request-context';
|
|
19
|
+
*
|
|
20
|
+
* @Controller()
|
|
21
|
+
* @UseInterceptors(RequestContextInterceptor)
|
|
22
|
+
* export class MyController {}
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
3
25
|
export declare class RequestContextInterceptor implements NestInterceptor {
|
|
26
|
+
/**
|
|
27
|
+
* Intercepts the request and wraps execution in a request context.
|
|
28
|
+
*
|
|
29
|
+
* @typeParam T - The type of the response
|
|
30
|
+
* @param executionContext - The NestJS execution context
|
|
31
|
+
* @param next - The call handler for the next interceptor or handler
|
|
32
|
+
* @returns An observable of the response
|
|
33
|
+
*/
|
|
4
34
|
intercept<T>(executionContext: ExecutionContext, next: CallHandler<T>): Observable<T>;
|
|
5
35
|
}
|
|
@@ -10,7 +10,37 @@ exports.RequestContextInterceptor = void 0;
|
|
|
10
10
|
const common_1 = require("@nestjs/common");
|
|
11
11
|
const rxjs_1 = require("rxjs");
|
|
12
12
|
const request_context_1 = require("./request-context");
|
|
13
|
+
/**
|
|
14
|
+
* NestJS interceptor that creates request context for HTTP and GraphQL requests.
|
|
15
|
+
*
|
|
16
|
+
* This interceptor serves as a fallback for cases where the middleware doesn't
|
|
17
|
+
* run (e.g., GraphQL resolvers). It:
|
|
18
|
+
* - Creates a new RequestContext if one doesn't already exist
|
|
19
|
+
* - Uses the `x-request-id` header as the context ID if provided
|
|
20
|
+
* - Supports both HTTP and GraphQL execution contexts
|
|
21
|
+
*
|
|
22
|
+
* The interceptor is automatically registered by RequestContextModule.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* The interceptor is typically used automatically, but can be applied manually:
|
|
26
|
+
* ```typescript
|
|
27
|
+
* import { Controller, UseInterceptors } from '@nestjs/common';
|
|
28
|
+
* import { RequestContextInterceptor } from '@nest-boot/request-context';
|
|
29
|
+
*
|
|
30
|
+
* @Controller()
|
|
31
|
+
* @UseInterceptors(RequestContextInterceptor)
|
|
32
|
+
* export class MyController {}
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
13
35
|
let RequestContextInterceptor = class RequestContextInterceptor {
|
|
36
|
+
/**
|
|
37
|
+
* Intercepts the request and wraps execution in a request context.
|
|
38
|
+
*
|
|
39
|
+
* @typeParam T - The type of the response
|
|
40
|
+
* @param executionContext - The NestJS execution context
|
|
41
|
+
* @param next - The call handler for the next interceptor or handler
|
|
42
|
+
* @returns An observable of the response
|
|
43
|
+
*/
|
|
14
44
|
intercept(executionContext, next) {
|
|
15
45
|
if (request_context_1.RequestContext.isActive() ||
|
|
16
46
|
!["http", "graphql"].includes(executionContext.getType())) {
|