@nestjs/cqrs 10.2.8 → 11.0.0-next.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/.circleci/config.yml +29 -1
- package/dist/classes/command.d.ts +9 -0
- package/dist/classes/command.js +7 -0
- package/dist/classes/constants.d.ts +1 -0
- package/dist/classes/constants.js +4 -0
- package/dist/classes/index.d.ts +2 -0
- package/dist/classes/index.js +18 -0
- package/dist/classes/query.d.ts +9 -0
- package/dist/classes/query.js +7 -0
- package/dist/command-bus.d.ts +26 -7
- package/dist/command-bus.js +57 -21
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +1 -0
- package/dist/cqrs.module.d.ts +5 -4
- package/dist/cqrs.module.js +21 -11
- package/dist/decorators/command-handler.decorator.d.ts +3 -1
- package/dist/decorators/command-handler.decorator.js +8 -3
- package/dist/decorators/events-handler.decorator.d.ts +3 -1
- package/dist/decorators/events-handler.decorator.js +9 -2
- package/dist/decorators/index.d.ts +1 -0
- package/dist/decorators/index.js +6 -1
- package/dist/decorators/publishable.decorator.d.ts +5 -0
- package/dist/decorators/publishable.decorator.js +13 -0
- package/dist/decorators/query-handler.decorator.d.ts +3 -1
- package/dist/decorators/query-handler.decorator.js +8 -3
- package/dist/event-bus.d.ts +51 -10
- package/dist/event-bus.js +106 -31
- package/dist/event-publisher.d.ts +5 -2
- package/dist/event-publisher.js +10 -8
- package/dist/exceptions/command-not-found.exception.js +1 -1
- package/dist/exceptions/index.d.ts +1 -0
- package/dist/exceptions/index.js +6 -1
- package/dist/exceptions/invalid-command-handler.exception.js +1 -1
- package/dist/exceptions/invalid-events-handler.exception.js +1 -1
- package/dist/exceptions/invalid-query-handler.exception.js +1 -1
- package/dist/exceptions/invalid-saga.exception.js +1 -1
- package/dist/exceptions/query-not-found.exception.js +1 -1
- package/dist/exceptions/unsupported-saga-scope.exception.d.ts +3 -0
- package/dist/exceptions/unsupported-saga-scope.exception.js +9 -0
- package/dist/helpers/default-event-id-provider.d.ts +6 -0
- package/dist/helpers/default-event-id-provider.js +10 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +7 -1
- package/dist/interfaces/commands/command-bus.interface.d.ts +18 -1
- package/dist/interfaces/commands/command-handler.interface.d.ts +9 -2
- package/dist/interfaces/cqrs-module-options.interface.d.ts +38 -8
- package/dist/interfaces/events/event-bus.interface.d.ts +41 -4
- package/dist/interfaces/events/event-id-provider.interface.d.ts +11 -0
- package/dist/interfaces/events/event-id-provider.interface.js +2 -0
- package/dist/interfaces/events/event-publisher.interface.d.ts +7 -4
- package/dist/interfaces/index.d.ts +2 -0
- package/dist/interfaces/index.js +7 -1
- package/dist/interfaces/providers-introspection-result.interface.d.ts +10 -0
- package/dist/interfaces/providers-introspection-result.interface.js +2 -0
- package/dist/interfaces/queries/query-bus.interface.d.ts +18 -1
- package/dist/interfaces/queries/query-handler.interface.d.ts +9 -2
- package/dist/interfaces/saga.type.d.ts +1 -1
- package/dist/operators/index.js +5 -1
- package/dist/operators/of-type.d.ts +1 -1
- package/dist/operators/of-type.js +1 -2
- package/dist/query-bus.d.ts +26 -6
- package/dist/query-bus.js +49 -20
- package/dist/scopes/async.context.d.ts +30 -0
- package/dist/scopes/async.context.js +58 -0
- package/dist/scopes/index.d.ts +1 -0
- package/dist/scopes/index.js +17 -0
- package/dist/services/explorer.service.d.ts +4 -6
- package/dist/services/explorer.service.js +14 -14
- package/dist/storages/aggregate-root.storage.d.ts +8 -0
- package/dist/storages/aggregate-root.storage.js +21 -0
- package/dist/unhandled-exception-bus.d.ts +4 -3
- package/dist/unhandled-exception-bus.js +18 -5
- package/dist/utils/index.js +5 -1
- package/jest.config.js +5 -0
- package/package.json +29 -17
- package/renovate.json +8 -7
- package/test/e2e/basic-flows.spec.ts +98 -0
- package/test/e2e/generics.spec.ts +198 -0
- package/test/e2e/request-scope.spec.ts +141 -0
- package/test/e2e/unhandled-exceptions.spec.ts +73 -0
- package/test/jest-e2e.json +9 -0
- package/test/utils/wait-immediate.ts +2 -0
- package/tsconfig.build.json +10 -0
package/.circleci/config.yml
CHANGED
|
@@ -17,7 +17,7 @@ jobs:
|
|
|
17
17
|
build:
|
|
18
18
|
working_directory: ~/nest
|
|
19
19
|
docker:
|
|
20
|
-
- image: cimg/node:
|
|
20
|
+
- image: cimg/node:22.3
|
|
21
21
|
steps:
|
|
22
22
|
- checkout
|
|
23
23
|
- run:
|
|
@@ -35,9 +35,37 @@ jobs:
|
|
|
35
35
|
- run:
|
|
36
36
|
name: Build
|
|
37
37
|
command: npm run build
|
|
38
|
+
e2e_test:
|
|
39
|
+
working_directory: ~/nest
|
|
40
|
+
docker:
|
|
41
|
+
- image: cimg/node:22.3
|
|
42
|
+
steps:
|
|
43
|
+
- checkout
|
|
44
|
+
- *restore-cache
|
|
45
|
+
- *install-deps
|
|
46
|
+
- run:
|
|
47
|
+
name: e2e tests
|
|
48
|
+
command: npm run test:e2e
|
|
49
|
+
test:
|
|
50
|
+
working_directory: ~/nest
|
|
51
|
+
docker:
|
|
52
|
+
- image: cimg/node:22.3
|
|
53
|
+
steps:
|
|
54
|
+
- checkout
|
|
55
|
+
- *restore-cache
|
|
56
|
+
- *install-deps
|
|
57
|
+
- run:
|
|
58
|
+
name: Unit tests
|
|
59
|
+
command: npm run test
|
|
38
60
|
|
|
39
61
|
workflows:
|
|
40
62
|
version: 2
|
|
41
63
|
build-and-test:
|
|
42
64
|
jobs:
|
|
43
65
|
- build
|
|
66
|
+
- test:
|
|
67
|
+
requires:
|
|
68
|
+
- build
|
|
69
|
+
- e2e_test:
|
|
70
|
+
requires:
|
|
71
|
+
- build
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ICommand } from '../interfaces';
|
|
2
|
+
import { RESULT_TYPE_SYMBOL } from './constants';
|
|
3
|
+
/**
|
|
4
|
+
* Utility type to extract the result type of a command.
|
|
5
|
+
*/
|
|
6
|
+
export type CommandResult<C extends Command<unknown>> = C extends Command<infer R> ? R : never;
|
|
7
|
+
export declare class Command<T> implements ICommand {
|
|
8
|
+
readonly [RESULT_TYPE_SYMBOL]: T;
|
|
9
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const RESULT_TYPE_SYMBOL: unique symbol;
|
|
@@ -0,0 +1,18 @@
|
|
|
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("./command"), exports);
|
|
18
|
+
__exportStar(require("./query"), exports);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { IQuery } from '../interfaces';
|
|
2
|
+
import { RESULT_TYPE_SYMBOL } from './constants';
|
|
3
|
+
/**
|
|
4
|
+
* Utility type to extract the result type of a query.
|
|
5
|
+
*/
|
|
6
|
+
export type QueryResult<C extends Query<unknown>> = C extends Query<infer R> ? R : never;
|
|
7
|
+
export declare class Query<T> implements IQuery {
|
|
8
|
+
readonly [RESULT_TYPE_SYMBOL]: T;
|
|
9
|
+
}
|
package/dist/command-bus.d.ts
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import { Type } from '@nestjs/common';
|
|
2
2
|
import { ModuleRef } from '@nestjs/core';
|
|
3
|
+
import { InstanceWrapper } from '@nestjs/core/injector/instance-wrapper';
|
|
3
4
|
import 'reflect-metadata';
|
|
4
|
-
import {
|
|
5
|
+
import { Command } from './classes';
|
|
6
|
+
import { CqrsModuleOptions, ICommand, ICommandBus, ICommandHandler, ICommandPublisher } from './interfaces/index';
|
|
7
|
+
import { AsyncContext } from './scopes/async.context';
|
|
5
8
|
import { ObservableBus } from './utils/observable-bus';
|
|
6
|
-
export
|
|
9
|
+
export type CommandHandlerType<T extends ICommand = ICommand> = Type<ICommandHandler<T>>;
|
|
7
10
|
export declare class CommandBus<CommandBase extends ICommand = ICommand> extends ObservableBus<CommandBase> implements ICommandBus<CommandBase> {
|
|
8
11
|
private readonly moduleRef;
|
|
12
|
+
private readonly options?;
|
|
13
|
+
private readonly logger;
|
|
9
14
|
private handlers;
|
|
10
15
|
private _publisher;
|
|
11
|
-
constructor(moduleRef: ModuleRef);
|
|
16
|
+
constructor(moduleRef: ModuleRef, options?: CqrsModuleOptions | undefined);
|
|
12
17
|
/**
|
|
13
18
|
* Returns the publisher.
|
|
14
19
|
* Default publisher is `DefaultCommandPubSub` (in memory).
|
|
@@ -25,10 +30,24 @@ export declare class CommandBus<CommandBase extends ICommand = ICommand> extends
|
|
|
25
30
|
* @param command The command to execute.
|
|
26
31
|
* @returns A promise that, when resolved, will contain the result returned by the command's handler.
|
|
27
32
|
*/
|
|
28
|
-
execute<
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
33
|
+
execute<R = void>(command: Command<R>): Promise<R>;
|
|
34
|
+
/**
|
|
35
|
+
* Executes a command.
|
|
36
|
+
* @param command The command to execute.
|
|
37
|
+
* @param context The context to use. Optional.
|
|
38
|
+
* @returns A promise that, when resolved, will contain the result returned by the command's handler.
|
|
39
|
+
*/
|
|
40
|
+
execute<R = void>(command: Command<R>, context?: AsyncContext): Promise<R>;
|
|
41
|
+
/**
|
|
42
|
+
* Executes a command.
|
|
43
|
+
* @param command The command to execute.
|
|
44
|
+
* @param context The context to use. Optional.
|
|
45
|
+
* @returns A promise that, when resolved, will contain the result returned by the command's handler.
|
|
46
|
+
*/
|
|
47
|
+
execute<T extends CommandBase, R = any>(command: T, context?: AsyncContext): Promise<R>;
|
|
48
|
+
bind<T extends CommandBase>(handler: InstanceWrapper<ICommandHandler<T>>, id: string): void;
|
|
49
|
+
register(handlers?: InstanceWrapper<ICommandHandler<CommandBase>>[]): void;
|
|
50
|
+
protected registerHandler(handler: InstanceWrapper<ICommandHandler<CommandBase>>): void;
|
|
32
51
|
private getCommandId;
|
|
33
52
|
private getCommandName;
|
|
34
53
|
private reflectCommandId;
|
package/dist/command-bus.js
CHANGED
|
@@ -8,22 +8,35 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
8
8
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
9
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
10
|
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
var CommandBus_1;
|
|
11
15
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
16
|
exports.CommandBus = void 0;
|
|
13
17
|
const common_1 = require("@nestjs/common");
|
|
14
18
|
const core_1 = require("@nestjs/core");
|
|
15
19
|
require("reflect-metadata");
|
|
16
|
-
const constants_1 = require("./
|
|
20
|
+
const constants_1 = require("./constants");
|
|
21
|
+
const constants_2 = require("./decorators/constants");
|
|
17
22
|
const command_not_found_exception_1 = require("./exceptions/command-not-found.exception");
|
|
18
23
|
const default_command_pubsub_1 = require("./helpers/default-command-pubsub");
|
|
19
24
|
const index_1 = require("./index");
|
|
25
|
+
const async_context_1 = require("./scopes/async.context");
|
|
20
26
|
const observable_bus_1 = require("./utils/observable-bus");
|
|
21
|
-
let CommandBus = class CommandBus extends observable_bus_1.ObservableBus {
|
|
22
|
-
constructor(moduleRef) {
|
|
27
|
+
let CommandBus = CommandBus_1 = class CommandBus extends observable_bus_1.ObservableBus {
|
|
28
|
+
constructor(moduleRef, options) {
|
|
23
29
|
super();
|
|
24
30
|
this.moduleRef = moduleRef;
|
|
31
|
+
this.options = options;
|
|
32
|
+
this.logger = new common_1.Logger(CommandBus_1.name);
|
|
25
33
|
this.handlers = new Map();
|
|
26
|
-
this.
|
|
34
|
+
if (this.options?.commandPublisher) {
|
|
35
|
+
this._publisher = this.options.commandPublisher;
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
this.useDefaultPublisher();
|
|
39
|
+
}
|
|
27
40
|
}
|
|
28
41
|
/**
|
|
29
42
|
* Returns the publisher.
|
|
@@ -43,38 +56,59 @@ let CommandBus = class CommandBus extends observable_bus_1.ObservableBus {
|
|
|
43
56
|
/**
|
|
44
57
|
* Executes a command.
|
|
45
58
|
* @param command The command to execute.
|
|
59
|
+
* @param context The context to use. Optional.
|
|
46
60
|
* @returns A promise that, when resolved, will contain the result returned by the command's handler.
|
|
47
61
|
*/
|
|
48
|
-
execute(command) {
|
|
62
|
+
execute(command, context) {
|
|
49
63
|
const commandId = this.getCommandId(command);
|
|
50
|
-
const
|
|
51
|
-
if (!
|
|
64
|
+
const executeFn = this.handlers.get(commandId);
|
|
65
|
+
if (!executeFn) {
|
|
52
66
|
const commandName = this.getCommandName(command);
|
|
53
67
|
throw new command_not_found_exception_1.CommandHandlerNotFoundException(commandName);
|
|
54
68
|
}
|
|
55
69
|
this._publisher.publish(command);
|
|
56
|
-
return
|
|
70
|
+
return executeFn(command, context);
|
|
57
71
|
}
|
|
58
72
|
bind(handler, id) {
|
|
59
|
-
|
|
73
|
+
if (handler.isDependencyTreeStatic()) {
|
|
74
|
+
const instance = handler.instance;
|
|
75
|
+
if (!instance.execute) {
|
|
76
|
+
throw new index_1.InvalidCommandHandlerException();
|
|
77
|
+
}
|
|
78
|
+
this.handlers.set(id, (command) => instance.execute(command));
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
this.handlers.set(id, async (command, context) => {
|
|
82
|
+
context ??= async_context_1.AsyncContext.of(command) ?? new async_context_1.AsyncContext();
|
|
83
|
+
if (!async_context_1.AsyncContext.isAttached(context)) {
|
|
84
|
+
// Commands returned by sagas may already have an async context set
|
|
85
|
+
// and a corresponding request provider registered.
|
|
86
|
+
this.moduleRef.registerRequestByContextId(context, context.id);
|
|
87
|
+
context.attachTo(command);
|
|
88
|
+
}
|
|
89
|
+
const instance = await this.moduleRef.resolve(handler.metatype, context.id, {
|
|
90
|
+
strict: false,
|
|
91
|
+
});
|
|
92
|
+
return instance.execute(command);
|
|
93
|
+
});
|
|
60
94
|
}
|
|
61
95
|
register(handlers = []) {
|
|
62
96
|
handlers.forEach((handler) => this.registerHandler(handler));
|
|
63
97
|
}
|
|
64
98
|
registerHandler(handler) {
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
const target = this.reflectCommandId(handler);
|
|
99
|
+
const typeRef = handler.metatype;
|
|
100
|
+
const target = this.reflectCommandId(typeRef);
|
|
70
101
|
if (!target) {
|
|
71
102
|
throw new index_1.InvalidCommandHandlerException();
|
|
72
103
|
}
|
|
73
|
-
this.
|
|
104
|
+
if (this.handlers.has(target)) {
|
|
105
|
+
this.logger.warn(`Command handler [${typeRef.name}] is already registered. Overriding previously registered handler.`);
|
|
106
|
+
}
|
|
107
|
+
this.bind(handler, target);
|
|
74
108
|
}
|
|
75
109
|
getCommandId(command) {
|
|
76
110
|
const { constructor: commandType } = Object.getPrototypeOf(command);
|
|
77
|
-
const commandMetadata = Reflect.getMetadata(
|
|
111
|
+
const commandMetadata = Reflect.getMetadata(constants_2.COMMAND_METADATA, commandType);
|
|
78
112
|
if (!commandMetadata) {
|
|
79
113
|
throw new command_not_found_exception_1.CommandHandlerNotFoundException(commandType.name);
|
|
80
114
|
}
|
|
@@ -85,16 +119,18 @@ let CommandBus = class CommandBus extends observable_bus_1.ObservableBus {
|
|
|
85
119
|
return constructor.name;
|
|
86
120
|
}
|
|
87
121
|
reflectCommandId(handler) {
|
|
88
|
-
const command = Reflect.getMetadata(
|
|
89
|
-
const commandMetadata = Reflect.getMetadata(
|
|
122
|
+
const command = Reflect.getMetadata(constants_2.COMMAND_HANDLER_METADATA, handler);
|
|
123
|
+
const commandMetadata = Reflect.getMetadata(constants_2.COMMAND_METADATA, command);
|
|
90
124
|
return commandMetadata.id;
|
|
91
125
|
}
|
|
92
126
|
useDefaultPublisher() {
|
|
93
127
|
this._publisher = new default_command_pubsub_1.DefaultCommandPubSub(this.subject$);
|
|
94
128
|
}
|
|
95
129
|
};
|
|
96
|
-
CommandBus =
|
|
130
|
+
exports.CommandBus = CommandBus;
|
|
131
|
+
exports.CommandBus = CommandBus = CommandBus_1 = __decorate([
|
|
97
132
|
(0, common_1.Injectable)(),
|
|
98
|
-
|
|
133
|
+
__param(1, (0, common_1.Optional)()),
|
|
134
|
+
__param(1, (0, common_1.Inject)(constants_1.CQRS_MODULE_OPTIONS)),
|
|
135
|
+
__metadata("design:paramtypes", [core_1.ModuleRef, Object])
|
|
99
136
|
], CommandBus);
|
|
100
|
-
exports.CommandBus = CommandBus;
|
package/dist/constants.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const CQRS_MODULE_OPTIONS =
|
|
1
|
+
export declare const CQRS_MODULE_OPTIONS = "CQRS_MODULE_OPTIONS";
|
package/dist/constants.js
CHANGED
package/dist/cqrs.module.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DynamicModule, OnApplicationBootstrap } from '@nestjs/common';
|
|
2
2
|
import { CommandBus } from './command-bus';
|
|
3
3
|
import { EventBus } from './event-bus';
|
|
4
|
-
import { IEvent } from './interfaces';
|
|
4
|
+
import { CqrsModuleOptions, IEvent } from './interfaces';
|
|
5
5
|
import { QueryBus } from './query-bus';
|
|
6
6
|
import { ExplorerService } from './services/explorer.service';
|
|
7
7
|
export declare class CqrsModule<EventBase extends IEvent = IEvent> implements OnApplicationBootstrap {
|
|
@@ -10,10 +10,11 @@ export declare class CqrsModule<EventBase extends IEvent = IEvent> implements On
|
|
|
10
10
|
private readonly commandBus;
|
|
11
11
|
private readonly queryBus;
|
|
12
12
|
/**
|
|
13
|
-
* Registers
|
|
14
|
-
* @
|
|
13
|
+
* Registers CQRS module globally.
|
|
14
|
+
* @param options CQRS module options.
|
|
15
|
+
* @returns A dynamic module.
|
|
15
16
|
*/
|
|
16
|
-
static forRoot(): DynamicModule;
|
|
17
|
+
static forRoot(options?: CqrsModuleOptions): DynamicModule;
|
|
17
18
|
constructor(explorerService: ExplorerService<EventBase>, eventBus: EventBus<EventBase>, commandBus: CommandBus, queryBus: QueryBus);
|
|
18
19
|
onApplicationBootstrap(): void;
|
|
19
20
|
}
|
package/dist/cqrs.module.js
CHANGED
|
@@ -13,37 +13,48 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
13
13
|
exports.CqrsModule = void 0;
|
|
14
14
|
const common_1 = require("@nestjs/common");
|
|
15
15
|
const command_bus_1 = require("./command-bus");
|
|
16
|
+
const constants_1 = require("./constants");
|
|
16
17
|
const event_bus_1 = require("./event-bus");
|
|
17
18
|
const event_publisher_1 = require("./event-publisher");
|
|
18
19
|
const query_bus_1 = require("./query-bus");
|
|
19
20
|
const explorer_service_1 = require("./services/explorer.service");
|
|
20
21
|
const unhandled_exception_bus_1 = require("./unhandled-exception-bus");
|
|
22
|
+
const aggregate_root_storage_1 = require("./storages/aggregate-root.storage");
|
|
21
23
|
let CqrsModule = CqrsModule_1 = class CqrsModule {
|
|
22
|
-
constructor(explorerService, eventBus, commandBus, queryBus) {
|
|
23
|
-
this.explorerService = explorerService;
|
|
24
|
-
this.eventBus = eventBus;
|
|
25
|
-
this.commandBus = commandBus;
|
|
26
|
-
this.queryBus = queryBus;
|
|
27
|
-
}
|
|
28
24
|
/**
|
|
29
|
-
* Registers
|
|
30
|
-
* @
|
|
25
|
+
* Registers CQRS module globally.
|
|
26
|
+
* @param options CQRS module options.
|
|
27
|
+
* @returns A dynamic module.
|
|
31
28
|
*/
|
|
32
|
-
static forRoot() {
|
|
29
|
+
static forRoot(options) {
|
|
33
30
|
return {
|
|
34
31
|
module: CqrsModule_1,
|
|
32
|
+
providers: [
|
|
33
|
+
{
|
|
34
|
+
provide: constants_1.CQRS_MODULE_OPTIONS,
|
|
35
|
+
useValue: options ?? {},
|
|
36
|
+
},
|
|
37
|
+
],
|
|
35
38
|
global: true,
|
|
36
39
|
};
|
|
37
40
|
}
|
|
41
|
+
constructor(explorerService, eventBus, commandBus, queryBus) {
|
|
42
|
+
this.explorerService = explorerService;
|
|
43
|
+
this.eventBus = eventBus;
|
|
44
|
+
this.commandBus = commandBus;
|
|
45
|
+
this.queryBus = queryBus;
|
|
46
|
+
}
|
|
38
47
|
onApplicationBootstrap() {
|
|
39
48
|
const { events, queries, sagas, commands } = this.explorerService.explore();
|
|
40
49
|
this.eventBus.register(events);
|
|
41
50
|
this.commandBus.register(commands);
|
|
42
51
|
this.queryBus.register(queries);
|
|
43
52
|
this.eventBus.registerSagas(sagas);
|
|
53
|
+
aggregate_root_storage_1.AggregateRootStorage.mergeContext(this.eventBus);
|
|
44
54
|
}
|
|
45
55
|
};
|
|
46
|
-
CqrsModule =
|
|
56
|
+
exports.CqrsModule = CqrsModule;
|
|
57
|
+
exports.CqrsModule = CqrsModule = CqrsModule_1 = __decorate([
|
|
47
58
|
(0, common_1.Module)({
|
|
48
59
|
providers: [
|
|
49
60
|
command_bus_1.CommandBus,
|
|
@@ -66,4 +77,3 @@ CqrsModule = CqrsModule_1 = __decorate([
|
|
|
66
77
|
command_bus_1.CommandBus,
|
|
67
78
|
query_bus_1.QueryBus])
|
|
68
79
|
], CqrsModule);
|
|
69
|
-
exports.CqrsModule = CqrsModule;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { InjectableOptions } from '@nestjs/common';
|
|
1
2
|
import 'reflect-metadata';
|
|
2
3
|
import { ICommand } from '../index';
|
|
3
4
|
/**
|
|
@@ -7,7 +8,8 @@ import { ICommand } from '../index';
|
|
|
7
8
|
* The decorated class must implement the `ICommandHandler` interface.
|
|
8
9
|
*
|
|
9
10
|
* @param command command *type* to be handled by this handler.
|
|
11
|
+
* @param options injectable options passed on to the "@Injectable" decorator.
|
|
10
12
|
*
|
|
11
13
|
* @see https://docs.nestjs.com/recipes/cqrs#commands
|
|
12
14
|
*/
|
|
13
|
-
export declare const CommandHandler: (command: ICommand | (new (...args: any[]) => ICommand)) => ClassDecorator;
|
|
15
|
+
export declare const CommandHandler: (command: ICommand | (new (...args: any[]) => ICommand), options?: InjectableOptions) => ClassDecorator;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CommandHandler = void 0;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
const crypto_1 = require("crypto");
|
|
4
6
|
require("reflect-metadata");
|
|
5
7
|
const constants_1 = require("./constants");
|
|
6
|
-
const uuid_1 = require("uuid");
|
|
7
8
|
/**
|
|
8
9
|
* Decorator that marks a class as a Nest command handler. A command handler
|
|
9
10
|
* handles commands (actions) executed by your application code.
|
|
@@ -11,15 +12,19 @@ const uuid_1 = require("uuid");
|
|
|
11
12
|
* The decorated class must implement the `ICommandHandler` interface.
|
|
12
13
|
*
|
|
13
14
|
* @param command command *type* to be handled by this handler.
|
|
15
|
+
* @param options injectable options passed on to the "@Injectable" decorator.
|
|
14
16
|
*
|
|
15
17
|
* @see https://docs.nestjs.com/recipes/cqrs#commands
|
|
16
18
|
*/
|
|
17
|
-
const CommandHandler = (command) => {
|
|
19
|
+
const CommandHandler = (command, options) => {
|
|
18
20
|
return (target) => {
|
|
19
21
|
if (!Reflect.hasOwnMetadata(constants_1.COMMAND_METADATA, command)) {
|
|
20
|
-
Reflect.defineMetadata(constants_1.COMMAND_METADATA, { id: (0,
|
|
22
|
+
Reflect.defineMetadata(constants_1.COMMAND_METADATA, { id: (0, crypto_1.randomUUID)() }, command);
|
|
21
23
|
}
|
|
22
24
|
Reflect.defineMetadata(constants_1.COMMAND_HANDLER_METADATA, command, target);
|
|
25
|
+
if (options) {
|
|
26
|
+
(0, common_1.Injectable)(options)(target);
|
|
27
|
+
}
|
|
23
28
|
};
|
|
24
29
|
};
|
|
25
30
|
exports.CommandHandler = CommandHandler;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { InjectableOptions } from '@nestjs/common';
|
|
1
2
|
import 'reflect-metadata';
|
|
2
3
|
import { IEvent } from '../index';
|
|
3
4
|
/**
|
|
@@ -7,7 +8,8 @@ import { IEvent } from '../index';
|
|
|
7
8
|
* The decorated class must implement the `IEventHandler` interface.
|
|
8
9
|
*
|
|
9
10
|
* @param events one or more event *types* to be handled by this handler.
|
|
11
|
+
* @param options injectable options passed on to the "@Injectable" decorator.
|
|
10
12
|
*
|
|
11
13
|
* @see https://docs.nestjs.com/recipes/cqrs#events
|
|
12
14
|
*/
|
|
13
|
-
export declare const EventsHandler: (...events: (IEvent | (new (...args: any[]) => IEvent))[]) => ClassDecorator;
|
|
15
|
+
export declare const EventsHandler: (...events: (IEvent | (new (...args: any[]) => IEvent) | InjectableOptions)[]) => ClassDecorator;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.EventsHandler = void 0;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
const crypto_1 = require("crypto");
|
|
4
6
|
require("reflect-metadata");
|
|
5
7
|
const constants_1 = require("./constants");
|
|
6
|
-
const uuid_1 = require("uuid");
|
|
7
8
|
/**
|
|
8
9
|
* Decorator that marks a class as a Nest event handler. An event handler
|
|
9
10
|
* handles events executed by your application code.
|
|
@@ -11,14 +12,20 @@ const uuid_1 = require("uuid");
|
|
|
11
12
|
* The decorated class must implement the `IEventHandler` interface.
|
|
12
13
|
*
|
|
13
14
|
* @param events one or more event *types* to be handled by this handler.
|
|
15
|
+
* @param options injectable options passed on to the "@Injectable" decorator.
|
|
14
16
|
*
|
|
15
17
|
* @see https://docs.nestjs.com/recipes/cqrs#events
|
|
16
18
|
*/
|
|
17
19
|
const EventsHandler = (...events) => {
|
|
18
20
|
return (target) => {
|
|
21
|
+
const last = events[events.length - 1];
|
|
22
|
+
if (typeof last !== 'function' && 'scope' in last) {
|
|
23
|
+
(0, common_1.Injectable)(last)(target);
|
|
24
|
+
events.pop();
|
|
25
|
+
}
|
|
19
26
|
events.forEach((event) => {
|
|
20
27
|
if (!Reflect.hasOwnMetadata(constants_1.EVENT_METADATA, event)) {
|
|
21
|
-
Reflect.defineMetadata(constants_1.EVENT_METADATA, { id: (0,
|
|
28
|
+
Reflect.defineMetadata(constants_1.EVENT_METADATA, { id: (0, crypto_1.randomUUID)() }, event);
|
|
22
29
|
}
|
|
23
30
|
});
|
|
24
31
|
Reflect.defineMetadata(constants_1.EVENTS_HANDLER_METADATA, events, target);
|
package/dist/decorators/index.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
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);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
|
@@ -14,3 +18,4 @@ __exportStar(require("./command-handler.decorator"), exports);
|
|
|
14
18
|
__exportStar(require("./events-handler.decorator"), exports);
|
|
15
19
|
__exportStar(require("./query-handler.decorator"), exports);
|
|
16
20
|
__exportStar(require("./saga.decorator"), exports);
|
|
21
|
+
__exportStar(require("./publishable.decorator"), exports);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Publishable = Publishable;
|
|
4
|
+
const aggregate_root_storage_1 = require("../storages/aggregate-root.storage");
|
|
5
|
+
/**
|
|
6
|
+
* Merges event publisher with the decorated class.
|
|
7
|
+
* Implements the `publish` and `publishAll` methods in a similar way to {@link EventPublisher#mergeClassContext}.
|
|
8
|
+
*/
|
|
9
|
+
function Publishable() {
|
|
10
|
+
return (target) => {
|
|
11
|
+
aggregate_root_storage_1.AggregateRootStorage.add(target);
|
|
12
|
+
};
|
|
13
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { InjectableOptions } from '@nestjs/common';
|
|
1
2
|
import 'reflect-metadata';
|
|
2
3
|
import { IQuery } from '../interfaces';
|
|
3
4
|
/**
|
|
@@ -7,7 +8,8 @@ import { IQuery } from '../interfaces';
|
|
|
7
8
|
* The decorated class must implement the `IQueryHandler` interface.
|
|
8
9
|
*
|
|
9
10
|
* @param query query *type* to be handled by this handler.
|
|
11
|
+
* @param options injectable options passed on to the "@Injectable" decorator.
|
|
10
12
|
*
|
|
11
13
|
* @see https://docs.nestjs.com/recipes/cqrs#queries
|
|
12
14
|
*/
|
|
13
|
-
export declare const QueryHandler: (query: IQuery) => ClassDecorator;
|
|
15
|
+
export declare const QueryHandler: (query: IQuery, options?: InjectableOptions) => ClassDecorator;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.QueryHandler = void 0;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
const crypto_1 = require("crypto");
|
|
4
6
|
require("reflect-metadata");
|
|
5
7
|
const constants_1 = require("./constants");
|
|
6
|
-
const uuid_1 = require("uuid");
|
|
7
8
|
/**
|
|
8
9
|
* Decorator that marks a class as a Nest query handler. A query handler
|
|
9
10
|
* handles queries executed by your application code.
|
|
@@ -11,15 +12,19 @@ const uuid_1 = require("uuid");
|
|
|
11
12
|
* The decorated class must implement the `IQueryHandler` interface.
|
|
12
13
|
*
|
|
13
14
|
* @param query query *type* to be handled by this handler.
|
|
15
|
+
* @param options injectable options passed on to the "@Injectable" decorator.
|
|
14
16
|
*
|
|
15
17
|
* @see https://docs.nestjs.com/recipes/cqrs#queries
|
|
16
18
|
*/
|
|
17
|
-
const QueryHandler = (query) => {
|
|
19
|
+
const QueryHandler = (query, options) => {
|
|
18
20
|
return (target) => {
|
|
19
21
|
if (!Reflect.hasOwnMetadata(constants_1.QUERY_METADATA, query)) {
|
|
20
|
-
Reflect.defineMetadata(constants_1.QUERY_METADATA, { id: (0,
|
|
22
|
+
Reflect.defineMetadata(constants_1.QUERY_METADATA, { id: (0, crypto_1.randomUUID)() }, query);
|
|
21
23
|
}
|
|
22
24
|
Reflect.defineMetadata(constants_1.QUERY_HANDLER_METADATA, query, target);
|
|
25
|
+
if (options) {
|
|
26
|
+
(0, common_1.Injectable)(options)(target);
|
|
27
|
+
}
|
|
23
28
|
};
|
|
24
29
|
};
|
|
25
30
|
exports.QueryHandler = QueryHandler;
|