@rolandsall24/nest-mediator 0.4.3 → 0.5.1
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/README.md +492 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/behaviors/exception-handling.behavior.d.ts +46 -0
- package/dist/lib/behaviors/exception-handling.behavior.d.ts.map +1 -0
- package/dist/lib/behaviors/exception-handling.behavior.js +76 -0
- package/dist/lib/behaviors/exception-handling.behavior.js.map +1 -0
- package/dist/lib/behaviors/index.d.ts +5 -0
- package/dist/lib/behaviors/index.d.ts.map +1 -0
- package/dist/lib/behaviors/index.js +21 -0
- package/dist/lib/behaviors/index.js.map +1 -0
- package/dist/lib/behaviors/logging.behavior.d.ts +26 -0
- package/dist/lib/behaviors/logging.behavior.d.ts.map +1 -0
- package/dist/lib/behaviors/logging.behavior.js +64 -0
- package/dist/lib/behaviors/logging.behavior.js.map +1 -0
- package/dist/lib/behaviors/performance.behavior.d.ts +41 -0
- package/dist/lib/behaviors/performance.behavior.d.ts.map +1 -0
- package/dist/lib/behaviors/performance.behavior.js +71 -0
- package/dist/lib/behaviors/performance.behavior.js.map +1 -0
- package/dist/lib/behaviors/validation.behavior.d.ts +69 -0
- package/dist/lib/behaviors/validation.behavior.d.ts.map +1 -0
- package/dist/lib/behaviors/validation.behavior.js +137 -0
- package/dist/lib/behaviors/validation.behavior.js.map +1 -0
- package/dist/lib/decorators/index.d.ts +2 -0
- package/dist/lib/decorators/index.d.ts.map +1 -1
- package/dist/lib/decorators/index.js +2 -0
- package/dist/lib/decorators/index.js.map +1 -1
- package/dist/lib/decorators/pipeline-behavior.decorator.d.ts +51 -0
- package/dist/lib/decorators/pipeline-behavior.decorator.d.ts.map +1 -0
- package/dist/lib/decorators/pipeline-behavior.decorator.js +68 -0
- package/dist/lib/decorators/pipeline-behavior.decorator.js.map +1 -0
- package/dist/lib/decorators/skip-behavior.decorator.d.ts +52 -0
- package/dist/lib/decorators/skip-behavior.decorator.d.ts.map +1 -0
- package/dist/lib/decorators/skip-behavior.decorator.js +61 -0
- package/dist/lib/decorators/skip-behavior.decorator.js.map +1 -0
- package/dist/lib/exceptions/handler-not-found.exception.d.ts +20 -0
- package/dist/lib/exceptions/handler-not-found.exception.d.ts.map +1 -0
- package/dist/lib/exceptions/handler-not-found.exception.js +33 -0
- package/dist/lib/exceptions/handler-not-found.exception.js.map +1 -0
- package/dist/lib/exceptions/index.d.ts +3 -0
- package/dist/lib/exceptions/index.d.ts.map +1 -0
- package/dist/lib/exceptions/index.js +19 -0
- package/dist/lib/exceptions/index.js.map +1 -0
- package/dist/lib/exceptions/validation.exception.d.ts +62 -0
- package/dist/lib/exceptions/validation.exception.d.ts.map +1 -0
- package/dist/lib/exceptions/validation.exception.js +66 -0
- package/dist/lib/exceptions/validation.exception.js.map +1 -0
- package/dist/lib/interfaces/index.d.ts +1 -0
- package/dist/lib/interfaces/index.d.ts.map +1 -1
- package/dist/lib/interfaces/index.js +1 -0
- package/dist/lib/interfaces/index.js.map +1 -1
- package/dist/lib/interfaces/pipeline-behavior.interface.d.ts +60 -0
- package/dist/lib/interfaces/pipeline-behavior.interface.d.ts.map +1 -0
- package/dist/lib/interfaces/pipeline-behavior.interface.js +3 -0
- package/dist/lib/interfaces/pipeline-behavior.interface.js.map +1 -0
- package/dist/lib/nest-mediator.module.d.ts +73 -4
- package/dist/lib/nest-mediator.module.d.ts.map +1 -1
- package/dist/lib/nest-mediator.module.js +63 -7
- package/dist/lib/nest-mediator.module.js.map +1 -1
- package/dist/lib/services/mediator.bus.d.ts +54 -4
- package/dist/lib/services/mediator.bus.d.ts.map +1 -1
- package/dist/lib/services/mediator.bus.js +104 -9
- package/dist/lib/services/mediator.bus.js.map +1 -1
- package/package.json +6 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exception-handling.behavior.js","sourceRoot":"","sources":["../../../src/lib/behaviors/exception-handling.behavior.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAoD;AAEpD,iGAAgF;AAkBhF;;;;;;;;;;;;;;;;;;GAkBG;AAGI,IAAM,yBAAyB,GAA/B,MAAM,yBAAyB;IAA/B;QAGY,WAAM,GAAG,IAAI,eAAM,CAAC,aAAa,CAAC,CAAC;QACnC,sBAAiB,GAAwB,EAAE,CAAC;IAqD/D,CAAC;IAnDC;;OAEG;IACH,wBAAwB,CAAC,OAA0B;QACjD,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,MAAM,CACV,OAAiB,EACjB,IAA8B;QAE9B,IAAI,CAAC;YACH,OAAO,MAAM,IAAI,EAAE,CAAC;QACtB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAChD,KAAc,EACd,OAAO,CACR,CAAC;YACF,MAAM,cAAc,CAAC;QACvB,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAC5B,KAAY,EACZ,OAAiB;QAEjB,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QAEjD,oBAAoB;QACpB,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,gBAAgB,WAAW,KAAK,KAAK,CAAC,OAAO,EAAE,EAC/C,KAAK,CAAC,KAAK,CACZ,CAAC;QAEF,gCAAgC;QAChC,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC7C,IAAI,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC7B,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YACxC,CAAC;QACH,CAAC;QAED,mDAAmD;QACnD,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,cAAc,CAAC,OAAiB;QACtC,IAAI,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;YAClE,OAAO,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC;QAClC,CAAC;QACD,OAAO,gBAAgB,CAAC;IAC1B,CAAC;CACF,CAAA;AAzDY,8DAAyB;oCAAzB,yBAAyB;IAFrC,IAAA,mBAAU,GAAE;IACZ,IAAA,iDAAgB,EAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;GACtC,yBAAyB,CAyDrC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/behaviors/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,kCAAkC,CAAC;AACjD,cAAc,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./logging.behavior.js"), exports);
|
|
18
|
+
__exportStar(require("./validation.behavior.js"), exports);
|
|
19
|
+
__exportStar(require("./exception-handling.behavior.js"), exports);
|
|
20
|
+
__exportStar(require("./performance.behavior.js"), exports);
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/behaviors/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,wDAAsC;AACtC,2DAAyC;AACzC,mEAAiD;AACjD,4DAA0C"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { IPipelineBehavior } from '../interfaces/pipeline-behavior.interface.js';
|
|
2
|
+
/**
|
|
3
|
+
* Pipeline behavior that logs request handling.
|
|
4
|
+
* Logs before execution, after successful execution (with duration), and on errors.
|
|
5
|
+
*
|
|
6
|
+
* Priority: 0 (executes early, wraps most other behaviors)
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* Output:
|
|
10
|
+
* ```
|
|
11
|
+
* [MediatorBus] Handling CreateUserCommand...
|
|
12
|
+
* [MediatorBus] Handled CreateUserCommand successfully in 45ms
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* On error:
|
|
16
|
+
* ```
|
|
17
|
+
* [MediatorBus] Handling CreateUserCommand...
|
|
18
|
+
* [MediatorBus] Failed CreateUserCommand after 12ms: User already exists
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare class LoggingBehavior<TRequest = any, TResponse = any> implements IPipelineBehavior<TRequest, TResponse> {
|
|
22
|
+
private readonly logger;
|
|
23
|
+
handle(request: TRequest, next: () => Promise<TResponse>): Promise<TResponse>;
|
|
24
|
+
private getRequestName;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=logging.behavior.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logging.behavior.d.ts","sourceRoot":"","sources":["../../../src/lib/behaviors/logging.behavior.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,8CAA8C,CAAC;AAGjF;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAEa,eAAe,CAAC,QAAQ,GAAG,GAAG,EAAE,SAAS,GAAG,GAAG,CAC1D,YAAW,iBAAiB,CAAC,QAAQ,EAAE,SAAS,CAAC;IAEjD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA6B;IAE9C,MAAM,CACV,OAAO,EAAE,QAAQ,EACjB,IAAI,EAAE,MAAM,OAAO,CAAC,SAAS,CAAC,GAC7B,OAAO,CAAC,SAAS,CAAC;IA0BrB,OAAO,CAAC,cAAc;CAMvB"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.LoggingBehavior = void 0;
|
|
10
|
+
const common_1 = require("@nestjs/common");
|
|
11
|
+
const pipeline_behavior_decorator_js_1 = require("../decorators/pipeline-behavior.decorator.js");
|
|
12
|
+
/**
|
|
13
|
+
* Pipeline behavior that logs request handling.
|
|
14
|
+
* Logs before execution, after successful execution (with duration), and on errors.
|
|
15
|
+
*
|
|
16
|
+
* Priority: 0 (executes early, wraps most other behaviors)
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* Output:
|
|
20
|
+
* ```
|
|
21
|
+
* [MediatorBus] Handling CreateUserCommand...
|
|
22
|
+
* [MediatorBus] Handled CreateUserCommand successfully in 45ms
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* On error:
|
|
26
|
+
* ```
|
|
27
|
+
* [MediatorBus] Handling CreateUserCommand...
|
|
28
|
+
* [MediatorBus] Failed CreateUserCommand after 12ms: User already exists
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
let LoggingBehavior = class LoggingBehavior {
|
|
32
|
+
constructor() {
|
|
33
|
+
this.logger = new common_1.Logger('MediatorBus');
|
|
34
|
+
}
|
|
35
|
+
async handle(request, next) {
|
|
36
|
+
const requestName = this.getRequestName(request);
|
|
37
|
+
const startTime = Date.now();
|
|
38
|
+
this.logger.log(`Handling ${requestName}...`);
|
|
39
|
+
try {
|
|
40
|
+
const response = await next();
|
|
41
|
+
const elapsed = Date.now() - startTime;
|
|
42
|
+
this.logger.log(`Handled ${requestName} successfully in ${elapsed}ms`);
|
|
43
|
+
return response;
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
const elapsed = Date.now() - startTime;
|
|
47
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
48
|
+
this.logger.error(`Failed ${requestName} after ${elapsed}ms: ${errorMessage}`);
|
|
49
|
+
throw error;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
getRequestName(request) {
|
|
53
|
+
if (request && typeof request === 'object' && request.constructor) {
|
|
54
|
+
return request.constructor.name;
|
|
55
|
+
}
|
|
56
|
+
return 'UnknownRequest';
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
exports.LoggingBehavior = LoggingBehavior;
|
|
60
|
+
exports.LoggingBehavior = LoggingBehavior = __decorate([
|
|
61
|
+
(0, common_1.Injectable)(),
|
|
62
|
+
(0, pipeline_behavior_decorator_js_1.PipelineBehavior)({ priority: 0, scope: 'all' })
|
|
63
|
+
], LoggingBehavior);
|
|
64
|
+
//# sourceMappingURL=logging.behavior.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logging.behavior.js","sourceRoot":"","sources":["../../../src/lib/behaviors/logging.behavior.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAoD;AAEpD,iGAAgF;AAEhF;;;;;;;;;;;;;;;;;;GAkBG;AAGI,IAAM,eAAe,GAArB,MAAM,eAAe;IAArB;QAGY,WAAM,GAAG,IAAI,eAAM,CAAC,aAAa,CAAC,CAAC;IAqCtD,CAAC;IAnCC,KAAK,CAAC,MAAM,CACV,OAAiB,EACjB,IAA8B;QAE9B,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QACjD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE7B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,YAAY,WAAW,KAAK,CAAC,CAAC;QAE9C,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,IAAI,EAAE,CAAC;YAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;YAEvC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,WAAW,oBAAoB,OAAO,IAAI,CAAC,CAAC;YAEvE,OAAO,QAAQ,CAAC;QAClB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;YACvC,MAAM,YAAY,GAChB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;YAE3D,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,UAAU,WAAW,UAAU,OAAO,OAAO,YAAY,EAAE,CAC5D,CAAC;YAEF,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAEO,cAAc,CAAC,OAAiB;QACtC,IAAI,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;YAClE,OAAO,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC;QAClC,CAAC;QACD,OAAO,gBAAgB,CAAC;IAC1B,CAAC;CACF,CAAA;AAxCY,0CAAe;0BAAf,eAAe;IAF3B,IAAA,mBAAU,GAAE;IACZ,IAAA,iDAAgB,EAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;GACnC,eAAe,CAwC3B"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { IPipelineBehavior } from '../interfaces/pipeline-behavior.interface.js';
|
|
2
|
+
/**
|
|
3
|
+
* Injection token for PerformanceBehavior options
|
|
4
|
+
*/
|
|
5
|
+
export declare const PERFORMANCE_BEHAVIOR_OPTIONS = "PERFORMANCE_BEHAVIOR_OPTIONS";
|
|
6
|
+
/**
|
|
7
|
+
* Configuration options for PerformanceBehavior
|
|
8
|
+
*/
|
|
9
|
+
export interface PerformanceBehaviorOptions {
|
|
10
|
+
/**
|
|
11
|
+
* Threshold in milliseconds. Requests exceeding this will be logged as warnings.
|
|
12
|
+
* Default: 500ms
|
|
13
|
+
*/
|
|
14
|
+
thresholdMs?: number;
|
|
15
|
+
/**
|
|
16
|
+
* Whether to log all requests or only slow ones.
|
|
17
|
+
* Default: false (only log slow requests)
|
|
18
|
+
*/
|
|
19
|
+
logAllRequests?: boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Pipeline behavior that tracks request performance.
|
|
23
|
+
* Logs warnings for requests that exceed a configurable threshold.
|
|
24
|
+
*
|
|
25
|
+
* Priority: 10 (executes early to measure total pipeline time)
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
29
|
+
* // Slow request output:
|
|
30
|
+
* // [Performance] SLOW REQUEST: GetAllUsersQuery took 1234ms (threshold: 500ms)
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare class PerformanceBehavior<TRequest = any, TResponse = any> implements IPipelineBehavior<TRequest, TResponse> {
|
|
34
|
+
private readonly logger;
|
|
35
|
+
private readonly thresholdMs;
|
|
36
|
+
private readonly logAllRequests;
|
|
37
|
+
constructor(options?: PerformanceBehaviorOptions);
|
|
38
|
+
handle(request: TRequest, next: () => Promise<TResponse>): Promise<TResponse>;
|
|
39
|
+
private getRequestName;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=performance.behavior.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"performance.behavior.d.ts","sourceRoot":"","sources":["../../../src/lib/behaviors/performance.behavior.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,8CAA8C,CAAC;AAGjF;;GAEG;AACH,eAAO,MAAM,4BAA4B,iCAAiC,CAAC;AAE3E;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;;;;;;;GAWG;AACH,qBAEa,mBAAmB,CAAC,QAAQ,GAAG,GAAG,EAAE,SAAS,GAAG,GAAG,CAC9D,YAAW,iBAAiB,CAAC,QAAQ,EAAE,SAAS,CAAC;IAEjD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA6B;IACpD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAU;gBAKvC,OAAO,CAAC,EAAE,0BAA0B;IAMhC,MAAM,CACV,OAAO,EAAE,QAAQ,EACjB,IAAI,EAAE,MAAM,OAAO,CAAC,SAAS,CAAC,GAC7B,OAAO,CAAC,SAAS,CAAC;IAmBrB,OAAO,CAAC,cAAc;CAMvB"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.PerformanceBehavior = exports.PERFORMANCE_BEHAVIOR_OPTIONS = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const pipeline_behavior_decorator_js_1 = require("../decorators/pipeline-behavior.decorator.js");
|
|
18
|
+
/**
|
|
19
|
+
* Injection token for PerformanceBehavior options
|
|
20
|
+
*/
|
|
21
|
+
exports.PERFORMANCE_BEHAVIOR_OPTIONS = 'PERFORMANCE_BEHAVIOR_OPTIONS';
|
|
22
|
+
/**
|
|
23
|
+
* Pipeline behavior that tracks request performance.
|
|
24
|
+
* Logs warnings for requests that exceed a configurable threshold.
|
|
25
|
+
*
|
|
26
|
+
* Priority: 10 (executes early to measure total pipeline time)
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* // Slow request output:
|
|
31
|
+
* // [Performance] SLOW REQUEST: GetAllUsersQuery took 1234ms (threshold: 500ms)
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
let PerformanceBehavior = class PerformanceBehavior {
|
|
35
|
+
constructor(options) {
|
|
36
|
+
this.logger = new common_1.Logger('Performance');
|
|
37
|
+
this.thresholdMs = options?.thresholdMs ?? 500;
|
|
38
|
+
this.logAllRequests = options?.logAllRequests ?? false;
|
|
39
|
+
}
|
|
40
|
+
async handle(request, next) {
|
|
41
|
+
const requestName = this.getRequestName(request);
|
|
42
|
+
const startTime = performance.now();
|
|
43
|
+
try {
|
|
44
|
+
return await next();
|
|
45
|
+
}
|
|
46
|
+
finally {
|
|
47
|
+
const elapsed = Math.round(performance.now() - startTime);
|
|
48
|
+
if (elapsed > this.thresholdMs) {
|
|
49
|
+
this.logger.warn(`SLOW REQUEST: ${requestName} took ${elapsed}ms (threshold: ${this.thresholdMs}ms)`);
|
|
50
|
+
}
|
|
51
|
+
else if (this.logAllRequests) {
|
|
52
|
+
this.logger.debug(`${requestName} completed in ${elapsed}ms`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
getRequestName(request) {
|
|
57
|
+
if (request && typeof request === 'object' && request.constructor) {
|
|
58
|
+
return request.constructor.name;
|
|
59
|
+
}
|
|
60
|
+
return 'UnknownRequest';
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
exports.PerformanceBehavior = PerformanceBehavior;
|
|
64
|
+
exports.PerformanceBehavior = PerformanceBehavior = __decorate([
|
|
65
|
+
(0, common_1.Injectable)(),
|
|
66
|
+
(0, pipeline_behavior_decorator_js_1.PipelineBehavior)({ priority: 10, scope: 'all' }),
|
|
67
|
+
__param(0, (0, common_1.Optional)()),
|
|
68
|
+
__param(0, (0, common_1.Inject)(exports.PERFORMANCE_BEHAVIOR_OPTIONS)),
|
|
69
|
+
__metadata("design:paramtypes", [Object])
|
|
70
|
+
], PerformanceBehavior);
|
|
71
|
+
//# sourceMappingURL=performance.behavior.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"performance.behavior.js","sourceRoot":"","sources":["../../../src/lib/behaviors/performance.behavior.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAAsE;AAEtE,iGAAgF;AAEhF;;GAEG;AACU,QAAA,4BAA4B,GAAG,8BAA8B,CAAC;AAmB3E;;;;;;;;;;;GAWG;AAGI,IAAM,mBAAmB,GAAzB,MAAM,mBAAmB;IAO9B,YAGE,OAAoC;QAPrB,WAAM,GAAG,IAAI,eAAM,CAAC,aAAa,CAAC,CAAC;QASlD,IAAI,CAAC,WAAW,GAAG,OAAO,EAAE,WAAW,IAAI,GAAG,CAAC;QAC/C,IAAI,CAAC,cAAc,GAAG,OAAO,EAAE,cAAc,IAAI,KAAK,CAAC;IACzD,CAAC;IAED,KAAK,CAAC,MAAM,CACV,OAAiB,EACjB,IAA8B;QAE9B,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QACjD,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAEpC,IAAI,CAAC;YACH,OAAO,MAAM,IAAI,EAAE,CAAC;QACtB,CAAC;gBAAS,CAAC;YACT,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,CAAC;YAE1D,IAAI,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;gBAC/B,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,iBAAiB,WAAW,SAAS,OAAO,kBAAkB,IAAI,CAAC,WAAW,KAAK,CACpF,CAAC;YACJ,CAAC;iBAAM,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;gBAC/B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,WAAW,iBAAiB,OAAO,IAAI,CAAC,CAAC;YAChE,CAAC;QACH,CAAC;IACH,CAAC;IAEO,cAAc,CAAC,OAAiB;QACtC,IAAI,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;YAClE,OAAO,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC;QAClC,CAAC;QACD,OAAO,gBAAgB,CAAC;IAC1B,CAAC;CACF,CAAA;AA5CY,kDAAmB;8BAAnB,mBAAmB;IAF/B,IAAA,mBAAU,GAAE;IACZ,IAAA,iDAAgB,EAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IAS5C,WAAA,IAAA,iBAAQ,GAAE,CAAA;IACV,WAAA,IAAA,eAAM,EAAC,oCAA4B,CAAC,CAAA;;GAT5B,mBAAmB,CA4C/B"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { IPipelineBehavior } from '../interfaces/pipeline-behavior.interface.js';
|
|
2
|
+
import { ValidationError } from '../exceptions/validation.exception.js';
|
|
3
|
+
/**
|
|
4
|
+
* Interface for custom validators.
|
|
5
|
+
* Implement this interface to create validators for specific request types.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* @Injectable()
|
|
10
|
+
* export class CreateUserCommandValidator implements IValidator<CreateUserCommand> {
|
|
11
|
+
* async validate(request: CreateUserCommand): Promise<ValidationError[]> {
|
|
12
|
+
* const errors: ValidationError[] = [];
|
|
13
|
+
*
|
|
14
|
+
* if (!request.email) {
|
|
15
|
+
* errors.push({ property: 'email', message: 'Email is required' });
|
|
16
|
+
* }
|
|
17
|
+
*
|
|
18
|
+
* return errors;
|
|
19
|
+
* }
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export interface IValidator<TRequest> {
|
|
24
|
+
/**
|
|
25
|
+
* Validate the request and return any validation errors.
|
|
26
|
+
* Return an empty array if validation passes.
|
|
27
|
+
*/
|
|
28
|
+
validate(request: TRequest): Promise<ValidationError[]>;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Metadata key for validator registration
|
|
32
|
+
*/
|
|
33
|
+
export declare const VALIDATOR_METADATA = "VALIDATOR_METADATA";
|
|
34
|
+
/**
|
|
35
|
+
* Pipeline behavior that performs validation using class-validator.
|
|
36
|
+
* Validates request objects decorated with class-validator decorators.
|
|
37
|
+
*
|
|
38
|
+
* Priority: 100 (executes after logging but before handler)
|
|
39
|
+
*
|
|
40
|
+
* This behavior integrates with class-validator if available.
|
|
41
|
+
* It will validate any request object that has class-validator decorators.
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```typescript
|
|
45
|
+
* // Request with class-validator decorators
|
|
46
|
+
* class CreateUserCommand implements ICommand {
|
|
47
|
+
* @IsEmail()
|
|
48
|
+
* email: string;
|
|
49
|
+
*
|
|
50
|
+
* @IsString()
|
|
51
|
+
* @MinLength(2)
|
|
52
|
+
* name: string;
|
|
53
|
+
* }
|
|
54
|
+
*
|
|
55
|
+
* // The ValidationBehavior will automatically validate this command
|
|
56
|
+
* await mediator.send(new CreateUserCommand('invalid', 'a'));
|
|
57
|
+
* // Throws ValidationException with details about the errors
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export declare class ValidationBehavior<TRequest = any, TResponse = any> implements IPipelineBehavior<TRequest, TResponse> {
|
|
61
|
+
private classValidatorAvailable;
|
|
62
|
+
private validateFn;
|
|
63
|
+
private getMetadataStorageFn;
|
|
64
|
+
handle(request: TRequest, next: () => Promise<TResponse>): Promise<TResponse>;
|
|
65
|
+
private validateRequest;
|
|
66
|
+
private loadClassValidator;
|
|
67
|
+
private transformClassValidatorErrors;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=validation.behavior.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.behavior.d.ts","sourceRoot":"","sources":["../../../src/lib/behaviors/validation.behavior.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,8CAA8C,CAAC;AAEjF,OAAO,EAEL,eAAe,EAChB,MAAM,uCAAuC,CAAC;AAE/C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,UAAU,CAAC,QAAQ;IAClC;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;CACzD;AAED;;GAEG;AACH,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AAEvD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,qBAEa,kBAAkB,CAAC,QAAQ,GAAG,GAAG,EAAE,SAAS,GAAG,GAAG,CAC7D,YAAW,iBAAiB,CAAC,QAAQ,EAAE,SAAS,CAAC;IAEjD,OAAO,CAAC,uBAAuB,CAAwB;IACvD,OAAO,CAAC,UAAU,CAAkD;IACpE,OAAO,CAAC,oBAAoB,CAA4B;IAElD,MAAM,CACV,OAAO,EAAE,QAAQ,EACjB,IAAI,EAAE,MAAM,OAAO,CAAC,SAAS,CAAC,GAC7B,OAAO,CAAC,SAAS,CAAC;YAeP,eAAe;YAmCf,kBAAkB;IAwBhC,OAAO,CAAC,6BAA6B;CA6BtC"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.ValidationBehavior = exports.VALIDATOR_METADATA = void 0;
|
|
10
|
+
const common_1 = require("@nestjs/common");
|
|
11
|
+
const pipeline_behavior_decorator_js_1 = require("../decorators/pipeline-behavior.decorator.js");
|
|
12
|
+
const validation_exception_js_1 = require("../exceptions/validation.exception.js");
|
|
13
|
+
/**
|
|
14
|
+
* Metadata key for validator registration
|
|
15
|
+
*/
|
|
16
|
+
exports.VALIDATOR_METADATA = 'VALIDATOR_METADATA';
|
|
17
|
+
/**
|
|
18
|
+
* Pipeline behavior that performs validation using class-validator.
|
|
19
|
+
* Validates request objects decorated with class-validator decorators.
|
|
20
|
+
*
|
|
21
|
+
* Priority: 100 (executes after logging but before handler)
|
|
22
|
+
*
|
|
23
|
+
* This behavior integrates with class-validator if available.
|
|
24
|
+
* It will validate any request object that has class-validator decorators.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* // Request with class-validator decorators
|
|
29
|
+
* class CreateUserCommand implements ICommand {
|
|
30
|
+
* @IsEmail()
|
|
31
|
+
* email: string;
|
|
32
|
+
*
|
|
33
|
+
* @IsString()
|
|
34
|
+
* @MinLength(2)
|
|
35
|
+
* name: string;
|
|
36
|
+
* }
|
|
37
|
+
*
|
|
38
|
+
* // The ValidationBehavior will automatically validate this command
|
|
39
|
+
* await mediator.send(new CreateUserCommand('invalid', 'a'));
|
|
40
|
+
* // Throws ValidationException with details about the errors
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
let ValidationBehavior = class ValidationBehavior {
|
|
44
|
+
constructor() {
|
|
45
|
+
this.classValidatorAvailable = null;
|
|
46
|
+
this.validateFn = null;
|
|
47
|
+
this.getMetadataStorageFn = null;
|
|
48
|
+
}
|
|
49
|
+
async handle(request, next) {
|
|
50
|
+
// Only validate objects
|
|
51
|
+
if (!request || typeof request !== 'object') {
|
|
52
|
+
return next();
|
|
53
|
+
}
|
|
54
|
+
const errors = await this.validateRequest(request);
|
|
55
|
+
if (errors.length > 0) {
|
|
56
|
+
throw new validation_exception_js_1.ValidationException(errors);
|
|
57
|
+
}
|
|
58
|
+
return next();
|
|
59
|
+
}
|
|
60
|
+
async validateRequest(request) {
|
|
61
|
+
// Try to use class-validator if available
|
|
62
|
+
await this.loadClassValidator();
|
|
63
|
+
if (this.validateFn && this.getMetadataStorageFn) {
|
|
64
|
+
try {
|
|
65
|
+
// Check if the class has any validation decorators
|
|
66
|
+
const metadataStorage = this.getMetadataStorageFn();
|
|
67
|
+
const targetConstructor = request.constructor;
|
|
68
|
+
// Get validation metadata for this class
|
|
69
|
+
const targetMetadatas = metadataStorage.getTargetValidationMetadatas(targetConstructor, targetConstructor.name, true, // always
|
|
70
|
+
false // strictGroups
|
|
71
|
+
) || [];
|
|
72
|
+
// If no validation decorators, skip validation
|
|
73
|
+
if (targetMetadatas.length === 0) {
|
|
74
|
+
return [];
|
|
75
|
+
}
|
|
76
|
+
const classValidatorErrors = await this.validateFn(request);
|
|
77
|
+
return this.transformClassValidatorErrors(classValidatorErrors);
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
// class-validator failed, skip validation
|
|
81
|
+
return [];
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return [];
|
|
85
|
+
}
|
|
86
|
+
async loadClassValidator() {
|
|
87
|
+
if (this.classValidatorAvailable !== null) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
try {
|
|
91
|
+
// Dynamic import to avoid hard dependency on class-validator
|
|
92
|
+
// Using Function constructor to prevent TypeScript from resolving the module
|
|
93
|
+
const importFn = new Function('moduleName', 'return import(moduleName)');
|
|
94
|
+
const classValidator = await importFn('class-validator');
|
|
95
|
+
this.validateFn = classValidator.validate;
|
|
96
|
+
this.getMetadataStorageFn = classValidator.getMetadataStorage;
|
|
97
|
+
this.classValidatorAvailable = true;
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
this.classValidatorAvailable = false;
|
|
101
|
+
this.validateFn = null;
|
|
102
|
+
this.getMetadataStorageFn = null;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
transformClassValidatorErrors(errors) {
|
|
106
|
+
const result = [];
|
|
107
|
+
for (const error of errors) {
|
|
108
|
+
if (error.constraints) {
|
|
109
|
+
const messages = Object.values(error.constraints);
|
|
110
|
+
for (const message of messages) {
|
|
111
|
+
result.push({
|
|
112
|
+
property: error.property,
|
|
113
|
+
message,
|
|
114
|
+
value: error.value,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// Handle nested validation errors
|
|
119
|
+
if (error.children && error.children.length > 0) {
|
|
120
|
+
const childErrors = this.transformClassValidatorErrors(error.children);
|
|
121
|
+
for (const childError of childErrors) {
|
|
122
|
+
result.push({
|
|
123
|
+
...childError,
|
|
124
|
+
property: `${error.property}.${childError.property}`,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return result;
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
exports.ValidationBehavior = ValidationBehavior;
|
|
133
|
+
exports.ValidationBehavior = ValidationBehavior = __decorate([
|
|
134
|
+
(0, common_1.Injectable)(),
|
|
135
|
+
(0, pipeline_behavior_decorator_js_1.PipelineBehavior)({ priority: 100, scope: 'all' })
|
|
136
|
+
], ValidationBehavior);
|
|
137
|
+
//# sourceMappingURL=validation.behavior.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.behavior.js","sourceRoot":"","sources":["../../../src/lib/behaviors/validation.behavior.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/decorators/index.ts"],"names":[],"mappings":"AAAA,cAAc,gCAAgC,CAAC;AAC/C,cAAc,8BAA8B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/decorators/index.ts"],"names":[],"mappings":"AAAA,cAAc,gCAAgC,CAAC;AAC/C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,kCAAkC,CAAC;AACjD,cAAc,8BAA8B,CAAC"}
|
|
@@ -16,4 +16,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./command-handler.decorator.js"), exports);
|
|
18
18
|
__exportStar(require("./query-handler.decorator.js"), exports);
|
|
19
|
+
__exportStar(require("./pipeline-behavior.decorator.js"), exports);
|
|
20
|
+
__exportStar(require("./skip-behavior.decorator.js"), exports);
|
|
19
21
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/decorators/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,iEAA+C;AAC/C,+DAA6C"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/decorators/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,iEAA+C;AAC/C,+DAA6C;AAC7C,mEAAiD;AACjD,+DAA6C"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { PipelineBehaviorOptions } from '../interfaces/pipeline-behavior.interface.js';
|
|
2
|
+
/**
|
|
3
|
+
* Metadata key for pipeline behavior registration
|
|
4
|
+
*/
|
|
5
|
+
export declare const PIPELINE_BEHAVIOR_METADATA = "PIPELINE_BEHAVIOR_METADATA";
|
|
6
|
+
/**
|
|
7
|
+
* Decorator that marks a class as a pipeline behavior.
|
|
8
|
+
* Pipeline behaviors execute around request handlers, enabling cross-cutting concerns.
|
|
9
|
+
*
|
|
10
|
+
* @param options - Configuration options for the behavior
|
|
11
|
+
* @returns Class decorator
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* // Basic usage - applies to all requests with default priority
|
|
16
|
+
* @Injectable()
|
|
17
|
+
* @PipelineBehavior()
|
|
18
|
+
* export class LoggingBehavior implements IPipelineBehavior {
|
|
19
|
+
* async handle(request, next) {
|
|
20
|
+
* console.log('Handling:', request);
|
|
21
|
+
* return next();
|
|
22
|
+
* }
|
|
23
|
+
* }
|
|
24
|
+
*
|
|
25
|
+
* // With priority - lower numbers execute first (outermost)
|
|
26
|
+
* @Injectable()
|
|
27
|
+
* @PipelineBehavior({ priority: -100 })
|
|
28
|
+
* export class ExceptionHandlingBehavior implements IPipelineBehavior {
|
|
29
|
+
* async handle(request, next) {
|
|
30
|
+
* try {
|
|
31
|
+
* return await next();
|
|
32
|
+
* } catch (error) {
|
|
33
|
+
* // Handle error
|
|
34
|
+
* throw error;
|
|
35
|
+
* }
|
|
36
|
+
* }
|
|
37
|
+
* }
|
|
38
|
+
*
|
|
39
|
+
* // Scoped to commands only
|
|
40
|
+
* @Injectable()
|
|
41
|
+
* @PipelineBehavior({ priority: 100, scope: 'command' })
|
|
42
|
+
* export class CommandValidationBehavior implements IPipelineBehavior {
|
|
43
|
+
* async handle(request, next) {
|
|
44
|
+
* await this.validate(request);
|
|
45
|
+
* return next();
|
|
46
|
+
* }
|
|
47
|
+
* }
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export declare const PipelineBehavior: (options?: PipelineBehaviorOptions) => ClassDecorator;
|
|
51
|
+
//# sourceMappingURL=pipeline-behavior.decorator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline-behavior.decorator.d.ts","sourceRoot":"","sources":["../../../src/lib/decorators/pipeline-behavior.decorator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,8CAA8C,CAAC;AAEvF;;GAEG;AACH,eAAO,MAAM,0BAA0B,+BAA+B,CAAC;AAUvE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,eAAO,MAAM,gBAAgB,GAC3B,UAAU,uBAAuB,KAChC,cAMF,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PipelineBehavior = exports.PIPELINE_BEHAVIOR_METADATA = void 0;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
/**
|
|
6
|
+
* Metadata key for pipeline behavior registration
|
|
7
|
+
*/
|
|
8
|
+
exports.PIPELINE_BEHAVIOR_METADATA = 'PIPELINE_BEHAVIOR_METADATA';
|
|
9
|
+
/**
|
|
10
|
+
* Default options for pipeline behaviors
|
|
11
|
+
*/
|
|
12
|
+
const DEFAULT_OPTIONS = {
|
|
13
|
+
priority: 0,
|
|
14
|
+
scope: 'all',
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Decorator that marks a class as a pipeline behavior.
|
|
18
|
+
* Pipeline behaviors execute around request handlers, enabling cross-cutting concerns.
|
|
19
|
+
*
|
|
20
|
+
* @param options - Configuration options for the behavior
|
|
21
|
+
* @returns Class decorator
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* // Basic usage - applies to all requests with default priority
|
|
26
|
+
* @Injectable()
|
|
27
|
+
* @PipelineBehavior()
|
|
28
|
+
* export class LoggingBehavior implements IPipelineBehavior {
|
|
29
|
+
* async handle(request, next) {
|
|
30
|
+
* console.log('Handling:', request);
|
|
31
|
+
* return next();
|
|
32
|
+
* }
|
|
33
|
+
* }
|
|
34
|
+
*
|
|
35
|
+
* // With priority - lower numbers execute first (outermost)
|
|
36
|
+
* @Injectable()
|
|
37
|
+
* @PipelineBehavior({ priority: -100 })
|
|
38
|
+
* export class ExceptionHandlingBehavior implements IPipelineBehavior {
|
|
39
|
+
* async handle(request, next) {
|
|
40
|
+
* try {
|
|
41
|
+
* return await next();
|
|
42
|
+
* } catch (error) {
|
|
43
|
+
* // Handle error
|
|
44
|
+
* throw error;
|
|
45
|
+
* }
|
|
46
|
+
* }
|
|
47
|
+
* }
|
|
48
|
+
*
|
|
49
|
+
* // Scoped to commands only
|
|
50
|
+
* @Injectable()
|
|
51
|
+
* @PipelineBehavior({ priority: 100, scope: 'command' })
|
|
52
|
+
* export class CommandValidationBehavior implements IPipelineBehavior {
|
|
53
|
+
* async handle(request, next) {
|
|
54
|
+
* await this.validate(request);
|
|
55
|
+
* return next();
|
|
56
|
+
* }
|
|
57
|
+
* }
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
const PipelineBehavior = (options) => {
|
|
61
|
+
const mergedOptions = {
|
|
62
|
+
...DEFAULT_OPTIONS,
|
|
63
|
+
...options,
|
|
64
|
+
};
|
|
65
|
+
return (0, common_1.SetMetadata)(exports.PIPELINE_BEHAVIOR_METADATA, mergedOptions);
|
|
66
|
+
};
|
|
67
|
+
exports.PipelineBehavior = PipelineBehavior;
|
|
68
|
+
//# sourceMappingURL=pipeline-behavior.decorator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline-behavior.decorator.js","sourceRoot":"","sources":["../../../src/lib/decorators/pipeline-behavior.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAA6C;AAG7C;;GAEG;AACU,QAAA,0BAA0B,GAAG,4BAA4B,CAAC;AAEvE;;GAEG;AACH,MAAM,eAAe,GAA4B;IAC/C,QAAQ,EAAE,CAAC;IACX,KAAK,EAAE,KAAK;CACb,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACI,MAAM,gBAAgB,GAAG,CAC9B,OAAiC,EACjB,EAAE;IAClB,MAAM,aAAa,GAA4B;QAC7C,GAAG,eAAe;QAClB,GAAG,OAAO;KACX,CAAC;IACF,OAAO,IAAA,oBAAW,EAAC,kCAA0B,EAAE,aAAa,CAAC,CAAC;AAChE,CAAC,CAAC;AARW,QAAA,gBAAgB,oBAQ3B"}
|