@cqrs-ddd/nestjs 0.5.0
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/COMMERCIAL_LICENSE.txt +34 -0
- package/LICENSE +661 -0
- package/README.md +46 -0
- package/dist/correlation.d.ts +22 -0
- package/dist/correlation.d.ts.map +1 -0
- package/dist/correlation.js +35 -0
- package/dist/correlation.js.map +1 -0
- package/dist/filters/error.filter.d.ts +19 -0
- package/dist/filters/error.filter.d.ts.map +1 -0
- package/dist/filters/error.filter.js +42 -0
- package/dist/filters/error.filter.js.map +1 -0
- package/dist/filters/http-exception.d.ts +53 -0
- package/dist/filters/http-exception.d.ts.map +1 -0
- package/dist/filters/http-exception.js +118 -0
- package/dist/filters/http-exception.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/job-context.d.ts +39 -0
- package/dist/job-context.d.ts.map +1 -0
- package/dist/job-context.js +81 -0
- package/dist/job-context.js.map +1 -0
- package/dist/pipeline/pipeline.bootstrap.d.ts +38 -0
- package/dist/pipeline/pipeline.bootstrap.d.ts.map +1 -0
- package/dist/pipeline/pipeline.bootstrap.js +189 -0
- package/dist/pipeline/pipeline.bootstrap.js.map +1 -0
- package/dist/pipeline/pipeline.module.d.ts +28 -0
- package/dist/pipeline/pipeline.module.d.ts.map +1 -0
- package/dist/pipeline/pipeline.module.js +50 -0
- package/dist/pipeline/pipeline.module.js.map +1 -0
- package/package.json +119 -0
package/README.md
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# @cqrs-ddd/nestjs
|
|
2
|
+
|
|
3
|
+
The NestJS adapter of the [`@cqrs-ddd`](https://github.com/aristoteliss/ddd-cqrs) packages.
|
|
4
|
+
Your application keeps NestJS and official `@nestjs/cqrs`; this package adds what NestJS
|
|
5
|
+
lacks:
|
|
6
|
+
|
|
7
|
+
- `PipelineModule.forRoot({ globalBehaviors, sources, diagnostics })` runs every
|
|
8
|
+
`@nestjs/cqrs` handler through the behaviors of its `@UsePipeline`. Each module provides
|
|
9
|
+
the behaviors it configures under their class; startup fails on a missing or doubly
|
|
10
|
+
provided behavior and on a request-scoped handler that runs behaviors.
|
|
11
|
+
- `ErrorFilter` (global, `APP_FILTER`) answers every `@cqrs-ddd` error as a NestJS
|
|
12
|
+
`HttpException` with NestJS's body (`statusCode`, `message`, `error`); `toHttpException`
|
|
13
|
+
and `httpAnswer` do the conversion alone.
|
|
14
|
+
- `@cqrs-ddd/nestjs/correlation`: `CorrelationMiddleware`.
|
|
15
|
+
- `@cqrs-ddd/nestjs/job-context`: `JobContextModule.forRoot({ principal, tenants, sources })`.
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
@Module({
|
|
19
|
+
imports: [
|
|
20
|
+
CqrsModule.forRoot(),
|
|
21
|
+
PipelineModule.forRoot({
|
|
22
|
+
sources: { tenantId: tenantSource, correlationId: correlationSource },
|
|
23
|
+
globalBehaviors: [{ scope: 'all', before: [logging()] }],
|
|
24
|
+
}),
|
|
25
|
+
],
|
|
26
|
+
providers: [
|
|
27
|
+
{ provide: LoggingBehavior, useFactory: () => new LoggingBehavior(new Logger('Pipeline')) },
|
|
28
|
+
{ provide: APP_FILTER, useClass: ErrorFilter },
|
|
29
|
+
],
|
|
30
|
+
})
|
|
31
|
+
export class AppModule {}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Install
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pnpm add @cqrs-ddd/nestjs @cqrs-ddd/pipeline @cqrs-ddd/core
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Peers: `@nestjs/common`, `@nestjs/core` and `@nestjs/cqrs` 12, `@cqrs-ddd/pipeline` and
|
|
41
|
+
`@cqrs-ddd/core` 0.5. The behavior packages (`-zod`, `-casl`, `-feature-flags`,
|
|
42
|
+
`-rate-limit`, `-idempotency`, `-correlation`, `-job-context`) are optional peers: their
|
|
43
|
+
errors are converted when they are installed. Node.js 22.12 or newer.
|
|
44
|
+
|
|
45
|
+
Guide: https://aristoteliss.github.io/ddd-cqrs/packages/nestjs/. A complete NestJS
|
|
46
|
+
application: [nestjs-pipeline `api/`](https://github.com/aristoteliss/nestjs-pipeline/tree/master/api).
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
|
+
import { type NestMiddleware } from '@nestjs/common';
|
|
3
|
+
/**
|
|
4
|
+
* Takes the correlation id of every request from its header, or creates one,
|
|
5
|
+
* runs the request with it so the pipelines it starts take it, and echoes it
|
|
6
|
+
* on the response: `httpCorrelation()` of `@cqrs-ddd/pipeline-correlation` as
|
|
7
|
+
* a NestJS middleware.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* export class AppModule implements NestModule {
|
|
12
|
+
* configure(consumer: MiddlewareConsumer) {
|
|
13
|
+
* consumer.apply(CorrelationMiddleware).forRoutes('*');
|
|
14
|
+
* }
|
|
15
|
+
* }
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export declare class CorrelationMiddleware implements NestMiddleware {
|
|
19
|
+
private readonly correlate;
|
|
20
|
+
use(request: IncomingMessage, response: ServerResponse, next: () => void): void;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=correlation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"correlation.d.ts","sourceRoot":"","sources":["../src/correlation.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEjE,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEjE;;;;;;;;;;;;;;GAcG;AACH,qBACa,qBAAsB,YAAW,cAAc;IAC1D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqB;IAE/C,GAAG,CAAC,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,IAAI,QAEvE;CACF"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/* Copyright (C) 2026-present Aristotelis — see repository license. */
|
|
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
|
+
import { httpCorrelation } from '@cqrs-ddd/pipeline-correlation';
|
|
9
|
+
import { Injectable } from '@nestjs/common';
|
|
10
|
+
/**
|
|
11
|
+
* Takes the correlation id of every request from its header, or creates one,
|
|
12
|
+
* runs the request with it so the pipelines it starts take it, and echoes it
|
|
13
|
+
* on the response: `httpCorrelation()` of `@cqrs-ddd/pipeline-correlation` as
|
|
14
|
+
* a NestJS middleware.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* export class AppModule implements NestModule {
|
|
19
|
+
* configure(consumer: MiddlewareConsumer) {
|
|
20
|
+
* consumer.apply(CorrelationMiddleware).forRoutes('*');
|
|
21
|
+
* }
|
|
22
|
+
* }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
let CorrelationMiddleware = class CorrelationMiddleware {
|
|
26
|
+
correlate = httpCorrelation();
|
|
27
|
+
use(request, response, next) {
|
|
28
|
+
this.correlate(request, response, next);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
CorrelationMiddleware = __decorate([
|
|
32
|
+
Injectable()
|
|
33
|
+
], CorrelationMiddleware);
|
|
34
|
+
export { CorrelationMiddleware };
|
|
35
|
+
//# sourceMappingURL=correlation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"correlation.js","sourceRoot":"","sources":["../src/correlation.ts"],"names":[],"mappings":"AAAA,sEAAsE;;;;;;;AAGtE,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,UAAU,EAAuB,MAAM,gBAAgB,CAAC;AAEjE;;;;;;;;;;;;;;GAcG;AAEI,IAAM,qBAAqB,GAA3B,MAAM,qBAAqB;IACf,SAAS,GAAG,eAAe,EAAE,CAAC;IAE/C,GAAG,CAAC,OAAwB,EAAE,QAAwB,EAAE,IAAgB;QACtE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC1C,CAAC;CACF,CAAA;AANY,qBAAqB;IADjC,UAAU,EAAE;GACA,qBAAqB,CAMjC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type ArgumentsHost } from '@nestjs/common';
|
|
2
|
+
import { BaseExceptionFilter } from '@nestjs/core';
|
|
3
|
+
/**
|
|
4
|
+
* Answers every error through NestJS's own exception handling: an error of a
|
|
5
|
+
* `@cqrs-ddd` package is first converted to its NestJS `HttpException` (see
|
|
6
|
+
* `httpAnswer`), with its headers such as `Retry-After`; anything else is
|
|
7
|
+
* handled exactly as Nest handles it by default. It works on Express and
|
|
8
|
+
* Fastify, also for errors thrown in middleware.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* @Module({ providers: [{ provide: APP_FILTER, useClass: ErrorFilter }] })
|
|
13
|
+
* export class AppModule {}
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export declare class ErrorFilter extends BaseExceptionFilter {
|
|
17
|
+
catch(exception: unknown, host: ArgumentsHost): void;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=error.filter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.filter.d.ts","sourceRoot":"","sources":["../../src/filters/error.filter.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAA0B,MAAM,gBAAgB,CAAC;AAC5E,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAGnD;;;;;;;;;;;;GAYG;AACH,qBACa,WAAY,SAAQ,mBAAmB;IAClD,KAAK,CAAC,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,GAAG,IAAI,CAWnD;CACF"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/* Copyright (C) 2026-present Aristotelis — see repository license. */
|
|
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
|
+
import { Catch } from '@nestjs/common';
|
|
9
|
+
import { BaseExceptionFilter } from '@nestjs/core';
|
|
10
|
+
import { httpAnswer } from './http-exception.js';
|
|
11
|
+
/**
|
|
12
|
+
* Answers every error through NestJS's own exception handling: an error of a
|
|
13
|
+
* `@cqrs-ddd` package is first converted to its NestJS `HttpException` (see
|
|
14
|
+
* `httpAnswer`), with its headers such as `Retry-After`; anything else is
|
|
15
|
+
* handled exactly as Nest handles it by default. It works on Express and
|
|
16
|
+
* Fastify, also for errors thrown in middleware.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* @Module({ providers: [{ provide: APP_FILTER, useClass: ErrorFilter }] })
|
|
21
|
+
* export class AppModule {}
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
let ErrorFilter = class ErrorFilter extends BaseExceptionFilter {
|
|
25
|
+
catch(exception, host) {
|
|
26
|
+
const answer = httpAnswer(exception);
|
|
27
|
+
if (answer) {
|
|
28
|
+
const adapter = (this.httpAdapterHost?.httpAdapter ??
|
|
29
|
+
this.applicationRef);
|
|
30
|
+
const response = host.getArgByIndex(1);
|
|
31
|
+
for (const [name, value] of Object.entries(answer.headers)) {
|
|
32
|
+
adapter.setHeader(response, name, value);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
super.catch(answer?.exception ?? exception, host);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
ErrorFilter = __decorate([
|
|
39
|
+
Catch()
|
|
40
|
+
], ErrorFilter);
|
|
41
|
+
export { ErrorFilter };
|
|
42
|
+
//# sourceMappingURL=error.filter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.filter.js","sourceRoot":"","sources":["../../src/filters/error.filter.ts"],"names":[],"mappings":"AAAA,sEAAsE;;;;;;;AAEtE,OAAO,EAAsB,KAAK,EAAmB,MAAM,gBAAgB,CAAC;AAC5E,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD;;;;;;;;;;;;GAYG;AAEI,IAAM,WAAW,GAAjB,MAAM,WAAY,SAAQ,mBAAmB;IAClD,KAAK,CAAC,SAAkB,EAAE,IAAmB;QAC3C,MAAM,MAAM,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;QACrC,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,eAAe,EAAE,WAAW;gBAChD,IAAI,CAAC,cAAc,CAAe,CAAC;YACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;YACvC,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC3D,OAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;YAC3C,CAAC;QACH,CAAC;QACD,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI,SAAS,EAAE,IAAI,CAAC,CAAC;IACpD,CAAC;CACF,CAAA;AAbY,WAAW;IADvB,KAAK,EAAE;GACK,WAAW,CAavB"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { HttpException } from '@nestjs/common';
|
|
2
|
+
/** A NestJS exception for a package error, and the headers its answer carries. */
|
|
3
|
+
export interface HttpAnswer {
|
|
4
|
+
readonly exception: HttpException;
|
|
5
|
+
readonly headers: Readonly<Record<string, string>>;
|
|
6
|
+
}
|
|
7
|
+
/** The flattened issues a `ZodValidationError` carries in `details`. */
|
|
8
|
+
export interface ValidationDetails {
|
|
9
|
+
readonly formErrors: readonly string[];
|
|
10
|
+
readonly fieldErrors: Readonly<Record<string, readonly string[] | undefined>>;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* The validation messages of NestJS's `StandardSchemaValidationPipe` for
|
|
14
|
+
* flattened Zod issues: a form error as it is, a field error as
|
|
15
|
+
* `field: message`.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* validationMessages({ formErrors: [], fieldErrors: { email: ['Invalid email'] } });
|
|
20
|
+
* // ['email: Invalid email']
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export declare function validationMessages(details: ValidationDetails): string[];
|
|
24
|
+
/**
|
|
25
|
+
* The NestJS exception and headers for an error of a `@cqrs-ddd` package, or
|
|
26
|
+
* `undefined` for any other error. A `ZodValidationError` becomes the
|
|
27
|
+
* `BadRequestException` NestJS's validation pipe throws (`message` lists the
|
|
28
|
+
* issues); a denied action, a disabled feature, an exceeded rate limit and an
|
|
29
|
+
* idempotency conflict take the status, body and headers their package's
|
|
30
|
+
* `toHttpResponse` defines; a `@cqrs-ddd/core` domain error takes
|
|
31
|
+
* `domainErrorHttpStatus`. Every body has NestJS's `statusCode`, `message` and
|
|
32
|
+
* `error`.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```ts
|
|
36
|
+
* const answer = httpAnswer(new RateLimitExceededError(details));
|
|
37
|
+
* answer?.exception.getStatus(); // 429
|
|
38
|
+
* answer?.headers; // { 'Retry-After': '3' }
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export declare function httpAnswer(error: unknown): HttpAnswer | undefined;
|
|
42
|
+
/**
|
|
43
|
+
* The NestJS `HttpException` for an error of a `@cqrs-ddd` package, or
|
|
44
|
+
* `undefined` for any other error; see {@link httpAnswer}, which also gives the
|
|
45
|
+
* headers.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```ts
|
|
49
|
+
* throw toHttpException(error) ?? error;
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export declare function toHttpException(error: unknown): HttpException | undefined;
|
|
53
|
+
//# sourceMappingURL=http-exception.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-exception.d.ts","sourceRoot":"","sources":["../../src/filters/http-exception.ts"],"names":[],"mappings":"AAIA,OAAO,EAAuB,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpE,kFAAkF;AAClF,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACpD;AAED,wEAAwE;AACxE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC;CAC/E;AAUD;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,EAAE,CAOvE;AAmFD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,CAMjE;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,aAAa,GAAG,SAAS,CAEzE"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/* Copyright (C) 2026-present Aristotelis — see repository license. */
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
import { domainErrorHttpStatus } from '@cqrs-ddd/core/http';
|
|
4
|
+
import { BadRequestException, HttpException } from '@nestjs/common';
|
|
5
|
+
/**
|
|
6
|
+
* The validation messages of NestJS's `StandardSchemaValidationPipe` for
|
|
7
|
+
* flattened Zod issues: a form error as it is, a field error as
|
|
8
|
+
* `field: message`.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* validationMessages({ formErrors: [], fieldErrors: { email: ['Invalid email'] } });
|
|
13
|
+
* // ['email: Invalid email']
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export function validationMessages(details) {
|
|
17
|
+
return [
|
|
18
|
+
...details.formErrors,
|
|
19
|
+
...Object.entries(details.fieldErrors).flatMap(([field, messages]) => (messages ?? []).map((message) => `${field}: ${message}`)),
|
|
20
|
+
];
|
|
21
|
+
}
|
|
22
|
+
const require = createRequire(import.meta.url);
|
|
23
|
+
function installed(name) {
|
|
24
|
+
try {
|
|
25
|
+
require.resolve(name);
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function optional(name) {
|
|
33
|
+
return installed(name)
|
|
34
|
+
? require(name)
|
|
35
|
+
: undefined;
|
|
36
|
+
}
|
|
37
|
+
// Errors are matched by name, not by class, so an error from a second copy of its
|
|
38
|
+
// package (a bundled one) converts too; every package error sets its `name`.
|
|
39
|
+
function named(error, name) {
|
|
40
|
+
return error instanceof Error && error.name === name;
|
|
41
|
+
}
|
|
42
|
+
function packageConverter(name, errorName) {
|
|
43
|
+
const toHttpResponse = optional(`${name}/http`)?.toHttpResponse;
|
|
44
|
+
if (!toHttpResponse)
|
|
45
|
+
return undefined;
|
|
46
|
+
return (error) => {
|
|
47
|
+
if (!named(error, errorName))
|
|
48
|
+
return undefined;
|
|
49
|
+
const { status, body, headers } = toHttpResponse(error);
|
|
50
|
+
return { exception: new HttpException(body, status), headers };
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
const validationConverter = (error) => named(error, 'ZodValidationError')
|
|
54
|
+
? {
|
|
55
|
+
exception: new BadRequestException(validationMessages(error.details)),
|
|
56
|
+
headers: {},
|
|
57
|
+
}
|
|
58
|
+
: undefined;
|
|
59
|
+
const domainConverter = (error) => {
|
|
60
|
+
const status = domainErrorHttpStatus(error);
|
|
61
|
+
if (!status)
|
|
62
|
+
return undefined;
|
|
63
|
+
const { statusCode, error: reason, message } = status;
|
|
64
|
+
return {
|
|
65
|
+
exception: new HttpException({ statusCode, message, error: reason }, statusCode),
|
|
66
|
+
headers: {},
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
// Behavior packages are optional peers: each converts only when installed.
|
|
70
|
+
const converters = [
|
|
71
|
+
validationConverter,
|
|
72
|
+
...[
|
|
73
|
+
packageConverter('@cqrs-ddd/pipeline-casl', 'UnauthorizedActionException'),
|
|
74
|
+
packageConverter('@cqrs-ddd/pipeline-feature-flags', 'FeatureDisabledError'),
|
|
75
|
+
packageConverter('@cqrs-ddd/pipeline-rate-limit', 'RateLimitExceededError'),
|
|
76
|
+
packageConverter('@cqrs-ddd/pipeline-idempotency', 'IdempotencyConflictError'),
|
|
77
|
+
].filter((convert) => convert !== undefined),
|
|
78
|
+
domainConverter,
|
|
79
|
+
];
|
|
80
|
+
/**
|
|
81
|
+
* The NestJS exception and headers for an error of a `@cqrs-ddd` package, or
|
|
82
|
+
* `undefined` for any other error. A `ZodValidationError` becomes the
|
|
83
|
+
* `BadRequestException` NestJS's validation pipe throws (`message` lists the
|
|
84
|
+
* issues); a denied action, a disabled feature, an exceeded rate limit and an
|
|
85
|
+
* idempotency conflict take the status, body and headers their package's
|
|
86
|
+
* `toHttpResponse` defines; a `@cqrs-ddd/core` domain error takes
|
|
87
|
+
* `domainErrorHttpStatus`. Every body has NestJS's `statusCode`, `message` and
|
|
88
|
+
* `error`.
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```ts
|
|
92
|
+
* const answer = httpAnswer(new RateLimitExceededError(details));
|
|
93
|
+
* answer?.exception.getStatus(); // 429
|
|
94
|
+
* answer?.headers; // { 'Retry-After': '3' }
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
export function httpAnswer(error) {
|
|
98
|
+
for (const convert of converters) {
|
|
99
|
+
const answer = convert(error);
|
|
100
|
+
if (answer)
|
|
101
|
+
return answer;
|
|
102
|
+
}
|
|
103
|
+
return undefined;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* The NestJS `HttpException` for an error of a `@cqrs-ddd` package, or
|
|
107
|
+
* `undefined` for any other error; see {@link httpAnswer}, which also gives the
|
|
108
|
+
* headers.
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```ts
|
|
112
|
+
* throw toHttpException(error) ?? error;
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
export function toHttpException(error) {
|
|
116
|
+
return httpAnswer(error)?.exception;
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=http-exception.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-exception.js","sourceRoot":"","sources":["../../src/filters/http-exception.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAsBpE;;;;;;;;;;GAUG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAA0B;IAC3D,OAAO;QACL,GAAG,OAAO,CAAC,UAAU;QACrB,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE,EAAE,CACnE,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,KAAK,KAAK,OAAO,EAAE,CAAC,CAC1D;KACF,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;AAE/C,SAAS,SAAS,CAAC,IAAY;IAC7B,IAAI,CAAC;QACH,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY;IAC5B,OAAO,SAAS,CAAC,IAAI,CAAC;QACpB,CAAC,CAAE,OAAO,CAAC,IAAI,CAA6B;QAC5C,CAAC,CAAC,SAAS,CAAC;AAChB,CAAC;AAED,kFAAkF;AAClF,6EAA6E;AAC7E,SAAS,KAAK,CAAC,KAAc,EAAE,IAAY;IACzC,OAAO,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC;AACvD,CAAC;AAED,SAAS,gBAAgB,CACvB,IAAY,EACZ,SAAiB;IAEjB,MAAM,cAAc,GAAG,QAAQ,CAAC,GAAG,IAAI,OAAO,CAAC,EAAE,cAEpC,CAAC;IACd,IAAI,CAAC,cAAc;QAAE,OAAO,SAAS,CAAC;IACtC,OAAO,CAAC,KAAK,EAAE,EAAE;QACf,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,SAAS,CAAC;YAAE,OAAO,SAAS,CAAC;QAC/C,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;QACxD,OAAO,EAAE,SAAS,EAAE,IAAI,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;IACjE,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,mBAAmB,GAAY,CAAC,KAAK,EAAE,EAAE,CAC7C,KAAK,CAAC,KAAK,EAAE,oBAAoB,CAAC;IAChC,CAAC,CAAC;QACE,SAAS,EAAE,IAAI,mBAAmB,CAChC,kBAAkB,CACf,KAAmD,CAAC,OAAO,CAC7D,CACF;QACD,OAAO,EAAE,EAAE;KACZ;IACH,CAAC,CAAC,SAAS,CAAC;AAEhB,MAAM,eAAe,GAAY,CAAC,KAAK,EAAE,EAAE;IACzC,MAAM,MAAM,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAC;IAC5C,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IAC9B,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;IACtD,OAAO;QACL,SAAS,EAAE,IAAI,aAAa,CAC1B,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EACtC,UAAU,CACX;QACD,OAAO,EAAE,EAAE;KACZ,CAAC;AACJ,CAAC,CAAC;AAEF,2EAA2E;AAC3E,MAAM,UAAU,GAAuB;IACrC,mBAAmB;IACnB,GAAG;QACD,gBAAgB,CAAC,yBAAyB,EAAE,6BAA6B,CAAC;QAC1E,gBAAgB,CACd,kCAAkC,EAClC,sBAAsB,CACvB;QACD,gBAAgB,CAAC,+BAA+B,EAAE,wBAAwB,CAAC;QAC3E,gBAAgB,CACd,gCAAgC,EAChC,0BAA0B,CAC3B;KACF,CAAC,MAAM,CAAC,CAAC,OAAO,EAAsB,EAAE,CAAC,OAAO,KAAK,SAAS,CAAC;IAChE,eAAe;CAChB,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,KAAK,MAAM,OAAO,IAAI,UAAU,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;QAC9B,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC;IAC5B,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,eAAe,CAAC,KAAc;IAC5C,OAAO,UAAU,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC;AACtC,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The NestJS adapter: `PipelineModule` runs official `@nestjs/cqrs` handlers through
|
|
3
|
+
* their pipelines, and `ErrorFilter` answers every package error as a NestJS
|
|
4
|
+
* `HttpException`. Correlation and job context are the `@cqrs-ddd/nestjs/correlation`
|
|
5
|
+
* and `@cqrs-ddd/nestjs/job-context` entry points.
|
|
6
|
+
*
|
|
7
|
+
* @module main
|
|
8
|
+
*/
|
|
9
|
+
export { ErrorFilter } from './filters/error.filter.js';
|
|
10
|
+
export { type HttpAnswer, httpAnswer, toHttpException, type ValidationDetails, validationMessages, } from './filters/http-exception.js';
|
|
11
|
+
export { PIPELINE_OPTIONS, PipelineBootstrap, type PipelineOptions, } from './pipeline/pipeline.bootstrap.js';
|
|
12
|
+
export { PipelineModule } from './pipeline/pipeline.module.js';
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EACL,KAAK,UAAU,EACf,UAAU,EACV,eAAe,EACf,KAAK,iBAAiB,EACtB,kBAAkB,GACnB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,KAAK,eAAe,GACrB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/* Copyright (C) 2026-present Aristotelis — see repository license. */
|
|
2
|
+
/**
|
|
3
|
+
* The NestJS adapter: `PipelineModule` runs official `@nestjs/cqrs` handlers through
|
|
4
|
+
* their pipelines, and `ErrorFilter` answers every package error as a NestJS
|
|
5
|
+
* `HttpException`. Correlation and job context are the `@cqrs-ddd/nestjs/correlation`
|
|
6
|
+
* and `@cqrs-ddd/nestjs/job-context` entry points.
|
|
7
|
+
*
|
|
8
|
+
* @module main
|
|
9
|
+
*/
|
|
10
|
+
export { ErrorFilter } from './filters/error.filter.js';
|
|
11
|
+
export { httpAnswer, toHttpException, validationMessages, } from './filters/http-exception.js';
|
|
12
|
+
export { PIPELINE_OPTIONS, PipelineBootstrap, } from './pipeline/pipeline.bootstrap.js';
|
|
13
|
+
export { PipelineModule } from './pipeline/pipeline.module.js';
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE;;;;;;;GAOG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAEL,UAAU,EACV,eAAe,EAEf,kBAAkB,GACnB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,gBAAgB,EAChB,iBAAiB,GAElB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type IJobPrincipal, type JobContextSources } from '@cqrs-ddd/pipeline-job-context';
|
|
2
|
+
import { type DynamicModule, type ModuleMetadata, type Type } from '@nestjs/common';
|
|
3
|
+
/** How `JobContextModule` registers the job context. */
|
|
4
|
+
export interface JobContextModuleOptions {
|
|
5
|
+
/** Modules that provide the principal's dependencies. */
|
|
6
|
+
readonly imports?: ModuleMetadata['imports'];
|
|
7
|
+
/** The provider that loads a job's principal again. */
|
|
8
|
+
readonly principal: Type<IJobPrincipal>;
|
|
9
|
+
/** The tenants a job may name, or a function read when the module starts. */
|
|
10
|
+
readonly tenants: readonly string[] | (() => readonly string[]);
|
|
11
|
+
/** Where the tenant and correlation id are read and restored. */
|
|
12
|
+
readonly sources: JobContextSources;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Lets the jobs a request enqueues carry its tenant, correlation id and
|
|
16
|
+
* principal (`withJobContext`), and restores them in processors
|
|
17
|
+
* (`@InJobContext()`): registers the application's job principal, tenants and
|
|
18
|
+
* context sources with `@cqrs-ddd/pipeline-job-context` when the module starts,
|
|
19
|
+
* and unregisters them on shutdown.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* @Module({
|
|
24
|
+
* imports: [
|
|
25
|
+
* JobContextModule.forRoot({
|
|
26
|
+
* imports: [AuthsModule],
|
|
27
|
+
* principal: SessionJobPrincipal,
|
|
28
|
+
* tenants: () => persistenceConfig().tenants,
|
|
29
|
+
* sources: { tenantId: tenantSource, correlationId: correlationSource },
|
|
30
|
+
* }),
|
|
31
|
+
* ],
|
|
32
|
+
* })
|
|
33
|
+
* export class AppModule {}
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare class JobContextModule {
|
|
37
|
+
static forRoot(options: JobContextModuleOptions): DynamicModule;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=job-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job-context.d.ts","sourceRoot":"","sources":["../src/job-context.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,aAAa,EAElB,KAAK,iBAAiB,EAEvB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,KAAK,aAAa,EAIlB,KAAK,cAAc,EAEnB,KAAK,IAAI,EACV,MAAM,gBAAgB,CAAC;AAExB,wDAAwD;AACxD,MAAM,WAAW,uBAAuB;IACtC,yDAAyD;IACzD,QAAQ,CAAC,OAAO,CAAC,EAAE,cAAc,CAAC,SAAS,CAAC,CAAC;IAC7C,uDAAuD;IACvD,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;IACxC,6EAA6E;IAC7E,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,CAAC,MAAM,SAAS,MAAM,EAAE,CAAC,CAAC;IAChE,iEAAiE;IACjE,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAC;CACrC;AAkBD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBACa,gBAAgB;IAC3B,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,uBAAuB,GAAG,aAAa,CAmB9D;CACF"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/* Copyright (C) 2026-present Aristotelis — see repository license. */
|
|
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
|
+
var JobContextModule_1;
|
|
15
|
+
import { registerJobContext, } from '@cqrs-ddd/pipeline-job-context';
|
|
16
|
+
import { Inject, Injectable, Module, } from '@nestjs/common';
|
|
17
|
+
const JOB_PRINCIPAL = Symbol('JOB_PRINCIPAL');
|
|
18
|
+
const JOB_CONTEXT = Symbol('JOB_CONTEXT');
|
|
19
|
+
let JobContextRegistration = class JobContextRegistration {
|
|
20
|
+
unregister;
|
|
21
|
+
constructor(options) {
|
|
22
|
+
this.unregister = registerJobContext(options);
|
|
23
|
+
}
|
|
24
|
+
onApplicationShutdown() {
|
|
25
|
+
this.unregister();
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
JobContextRegistration = __decorate([
|
|
29
|
+
Injectable(),
|
|
30
|
+
__param(0, Inject(JOB_CONTEXT)),
|
|
31
|
+
__metadata("design:paramtypes", [Object])
|
|
32
|
+
], JobContextRegistration);
|
|
33
|
+
/**
|
|
34
|
+
* Lets the jobs a request enqueues carry its tenant, correlation id and
|
|
35
|
+
* principal (`withJobContext`), and restores them in processors
|
|
36
|
+
* (`@InJobContext()`): registers the application's job principal, tenants and
|
|
37
|
+
* context sources with `@cqrs-ddd/pipeline-job-context` when the module starts,
|
|
38
|
+
* and unregisters them on shutdown.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```ts
|
|
42
|
+
* @Module({
|
|
43
|
+
* imports: [
|
|
44
|
+
* JobContextModule.forRoot({
|
|
45
|
+
* imports: [AuthsModule],
|
|
46
|
+
* principal: SessionJobPrincipal,
|
|
47
|
+
* tenants: () => persistenceConfig().tenants,
|
|
48
|
+
* sources: { tenantId: tenantSource, correlationId: correlationSource },
|
|
49
|
+
* }),
|
|
50
|
+
* ],
|
|
51
|
+
* })
|
|
52
|
+
* export class AppModule {}
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
let JobContextModule = JobContextModule_1 = class JobContextModule {
|
|
56
|
+
static forRoot(options) {
|
|
57
|
+
const { tenants, sources } = options;
|
|
58
|
+
return {
|
|
59
|
+
module: JobContextModule_1,
|
|
60
|
+
imports: options.imports ?? [],
|
|
61
|
+
providers: [
|
|
62
|
+
{ provide: JOB_PRINCIPAL, useClass: options.principal },
|
|
63
|
+
{
|
|
64
|
+
provide: JOB_CONTEXT,
|
|
65
|
+
inject: [JOB_PRINCIPAL],
|
|
66
|
+
useFactory: (principal) => ({
|
|
67
|
+
principal,
|
|
68
|
+
tenants: typeof tenants === 'function' ? tenants() : tenants,
|
|
69
|
+
sources,
|
|
70
|
+
}),
|
|
71
|
+
},
|
|
72
|
+
JobContextRegistration,
|
|
73
|
+
],
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
JobContextModule = JobContextModule_1 = __decorate([
|
|
78
|
+
Module({})
|
|
79
|
+
], JobContextModule);
|
|
80
|
+
export { JobContextModule };
|
|
81
|
+
//# sourceMappingURL=job-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job-context.js","sourceRoot":"","sources":["../src/job-context.ts"],"names":[],"mappings":"AAAA,sEAAsE;;;;;;;;;;;;;;AAEtE,OAAO,EAIL,kBAAkB,GACnB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAEL,MAAM,EACN,UAAU,EACV,MAAM,GAIP,MAAM,gBAAgB,CAAC;AAcxB,MAAM,aAAa,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC;AAC9C,MAAM,WAAW,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC;AAE1C,IACM,sBAAsB,GAD5B,MACM,sBAAsB;IACT,UAAU,CAAa;IAExC,YAAiC,OAA0B;QACzD,IAAI,CAAC,UAAU,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAChD,CAAC;IAED,qBAAqB;QACnB,IAAI,CAAC,UAAU,EAAE,CAAC;IACpB,CAAC;CACF,CAAA;AAVK,sBAAsB;IAD3B,UAAU,EAAE;IAIE,WAAA,MAAM,CAAC,WAAW,CAAC,CAAA;;GAH5B,sBAAsB,CAU3B;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEI,IAAM,gBAAgB,wBAAtB,MAAM,gBAAgB;IACpB,AAAP,MAAM,CAAC,OAAO,CAAC,OAAgC;QAC7C,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;QACrC,OAAO;YACL,MAAM,oBAAkB;YACxB,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,EAAE;YAC9B,SAAS,EAAE;gBACT,EAAE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,OAAO,CAAC,SAAS,EAAE;gBACvD;oBACE,OAAO,EAAE,WAAW;oBACpB,MAAM,EAAE,CAAC,aAAa,CAAC;oBACvB,UAAU,EAAE,CAAC,SAAwB,EAAqB,EAAE,CAAC,CAAC;wBAC5D,SAAS;wBACT,OAAO,EAAE,OAAO,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO;wBAC5D,OAAO;qBACR,CAAC;iBACH;gBACD,sBAAsB;aACvB;SACF,CAAC;IACJ,CAAC;CACF,CAAA;AArBY,gBAAgB;IAD5B,MAAM,CAAC,EAAE,CAAC;GACE,gBAAgB,CAqB5B"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type ContextSources, type GlobalBehaviorsOptions } from '@cqrs-ddd/pipeline';
|
|
2
|
+
import { type OnApplicationBootstrap, type OnModuleDestroy } from '@nestjs/common';
|
|
3
|
+
import { DiscoveryService } from '@nestjs/core';
|
|
4
|
+
/** What every handler's pipeline shares. */
|
|
5
|
+
export interface PipelineOptions {
|
|
6
|
+
readonly globalBehaviors?: GlobalBehaviorsOptions | GlobalBehaviorsOptions[];
|
|
7
|
+
readonly sources?: ContextSources;
|
|
8
|
+
/** `'strict'` (default) fails startup on a contract violation, `'warn'` logs it. */
|
|
9
|
+
readonly diagnostics?: 'strict' | 'warn' | 'off';
|
|
10
|
+
}
|
|
11
|
+
export declare const PIPELINE_OPTIONS: unique symbol;
|
|
12
|
+
/**
|
|
13
|
+
* Wraps every `@nestjs/cqrs` handler that runs behaviors with its pipeline, at
|
|
14
|
+
* application bootstrap: `execute` of command and query handlers, `handle` of
|
|
15
|
+
* event handlers. The buses read the method at call time, so they dispatch
|
|
16
|
+
* through the pipeline unchanged.
|
|
17
|
+
*
|
|
18
|
+
* A handler's pipeline comes from its `@UsePipeline`/`@SkipPipeline` and the
|
|
19
|
+
* global behaviors, compiled once. Each behavior instance is the one provider a
|
|
20
|
+
* module registers under the behavior class; this provider never builds one.
|
|
21
|
+
* Startup fails when a behavior has no provider or several, when a handler that
|
|
22
|
+
* runs behaviors is request-scoped (Nest builds such a handler per request, so a
|
|
23
|
+
* wrapped instance would never run), and, in `'strict'` mode, when a behavior's
|
|
24
|
+
* contract is broken. Only this application's own handler instances are wrapped,
|
|
25
|
+
* never their class, and they are restored when the application closes.
|
|
26
|
+
*/
|
|
27
|
+
export declare class PipelineBootstrap implements OnApplicationBootstrap, OnModuleDestroy {
|
|
28
|
+
private readonly discovery;
|
|
29
|
+
private readonly options;
|
|
30
|
+
private readonly logger;
|
|
31
|
+
private readonly restores;
|
|
32
|
+
constructor(discovery: DiscoveryService, options: PipelineOptions);
|
|
33
|
+
onApplicationBootstrap(): void;
|
|
34
|
+
onModuleDestroy(): void;
|
|
35
|
+
private wrapHandlers;
|
|
36
|
+
private wrap;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=pipeline.bootstrap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline.bootstrap.d.ts","sourceRoot":"","sources":["../../src/pipeline/pipeline.bootstrap.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,cAAc,EAInB,KAAK,sBAAsB,EAM5B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAIL,KAAK,sBAAsB,EAC3B,KAAK,eAAe,EACrB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGhD,4CAA4C;AAC5C,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,eAAe,CAAC,EAAE,sBAAsB,GAAG,sBAAsB,EAAE,CAAC;IAC7E,QAAQ,CAAC,OAAO,CAAC,EAAE,cAAc,CAAC;IAClC,oFAAoF;IACpF,QAAQ,CAAC,WAAW,CAAC,EAAE,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAC;CAClD;AAED,eAAO,MAAM,gBAAgB,eAA6B,CAAC;AAwB3D;;;;;;;;;;;;;;GAcG;AACH,qBACa,iBACX,YAAW,sBAAsB,EAAE,eAAe;IAMhD,OAAO,CAAC,QAAQ,CAAC,SAAS;IACA,OAAO,CAAC,QAAQ,CAAC,OAAO;IALpD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsC;IAC7D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAyB;IAElD,YACmB,SAAS,EAAE,gBAAgB,EACD,OAAO,EAAE,eAAe,EACjE;IAEJ,sBAAsB,IAAI,IAAI,CAO7B;IAED,eAAe,IAAI,IAAI,CAEtB;IAED,OAAO,CAAC,YAAY;IA0CpB,OAAO,CAAC,IAAI;CA2Eb"}
|