@nestjs/cqrs 10.2.8 → 11.0.0-next.2

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.
Files changed (85) hide show
  1. package/.circleci/config.yml +29 -1
  2. package/.husky/commit-msg +0 -3
  3. package/.husky/pre-commit +0 -3
  4. package/dist/classes/command.d.ts +9 -0
  5. package/dist/classes/command.js +7 -0
  6. package/dist/classes/constants.d.ts +1 -0
  7. package/dist/classes/constants.js +4 -0
  8. package/dist/classes/index.d.ts +2 -0
  9. package/dist/classes/index.js +18 -0
  10. package/dist/classes/query.d.ts +9 -0
  11. package/dist/classes/query.js +7 -0
  12. package/dist/command-bus.d.ts +26 -7
  13. package/dist/command-bus.js +57 -21
  14. package/dist/constants.d.ts +1 -1
  15. package/dist/constants.js +1 -0
  16. package/dist/cqrs.module.d.ts +5 -4
  17. package/dist/cqrs.module.js +21 -11
  18. package/dist/decorators/command-handler.decorator.d.ts +3 -1
  19. package/dist/decorators/command-handler.decorator.js +8 -3
  20. package/dist/decorators/events-handler.decorator.d.ts +3 -1
  21. package/dist/decorators/events-handler.decorator.js +9 -2
  22. package/dist/decorators/index.d.ts +1 -0
  23. package/dist/decorators/index.js +6 -1
  24. package/dist/decorators/publishable.decorator.d.ts +5 -0
  25. package/dist/decorators/publishable.decorator.js +13 -0
  26. package/dist/decorators/query-handler.decorator.d.ts +3 -1
  27. package/dist/decorators/query-handler.decorator.js +8 -3
  28. package/dist/event-bus.d.ts +51 -10
  29. package/dist/event-bus.js +108 -31
  30. package/dist/event-publisher.d.ts +5 -2
  31. package/dist/event-publisher.js +10 -8
  32. package/dist/exceptions/command-not-found.exception.js +1 -1
  33. package/dist/exceptions/index.d.ts +1 -0
  34. package/dist/exceptions/index.js +6 -1
  35. package/dist/exceptions/invalid-command-handler.exception.js +1 -1
  36. package/dist/exceptions/invalid-events-handler.exception.js +1 -1
  37. package/dist/exceptions/invalid-query-handler.exception.js +1 -1
  38. package/dist/exceptions/invalid-saga.exception.js +1 -1
  39. package/dist/exceptions/query-not-found.exception.js +1 -1
  40. package/dist/exceptions/unsupported-saga-scope.exception.d.ts +3 -0
  41. package/dist/exceptions/unsupported-saga-scope.exception.js +9 -0
  42. package/dist/helpers/default-event-id-provider.d.ts +7 -0
  43. package/dist/helpers/default-event-id-provider.js +10 -0
  44. package/dist/index.d.ts +2 -0
  45. package/dist/index.js +7 -1
  46. package/dist/interfaces/commands/command-bus.interface.d.ts +18 -1
  47. package/dist/interfaces/commands/command-handler.interface.d.ts +9 -2
  48. package/dist/interfaces/cqrs-module-options.interface.d.ts +38 -8
  49. package/dist/interfaces/events/event-bus.interface.d.ts +41 -4
  50. package/dist/interfaces/events/event-id-provider.interface.d.ts +12 -0
  51. package/dist/interfaces/events/event-id-provider.interface.js +2 -0
  52. package/dist/interfaces/events/event-publisher.interface.d.ts +7 -4
  53. package/dist/interfaces/index.d.ts +2 -0
  54. package/dist/interfaces/index.js +7 -1
  55. package/dist/interfaces/providers-introspection-result.interface.d.ts +10 -0
  56. package/dist/interfaces/providers-introspection-result.interface.js +2 -0
  57. package/dist/interfaces/queries/query-bus.interface.d.ts +18 -1
  58. package/dist/interfaces/queries/query-handler.interface.d.ts +9 -2
  59. package/dist/interfaces/saga.type.d.ts +1 -1
  60. package/dist/operators/index.js +5 -1
  61. package/dist/operators/of-type.d.ts +1 -1
  62. package/dist/operators/of-type.js +1 -2
  63. package/dist/query-bus.d.ts +26 -6
  64. package/dist/query-bus.js +49 -20
  65. package/dist/scopes/async.context.d.ts +30 -0
  66. package/dist/scopes/async.context.js +58 -0
  67. package/dist/scopes/index.d.ts +1 -0
  68. package/dist/scopes/index.js +17 -0
  69. package/dist/services/explorer.service.d.ts +4 -6
  70. package/dist/services/explorer.service.js +14 -14
  71. package/dist/storages/aggregate-root.storage.d.ts +8 -0
  72. package/dist/storages/aggregate-root.storage.js +21 -0
  73. package/dist/unhandled-exception-bus.d.ts +4 -3
  74. package/dist/unhandled-exception-bus.js +18 -5
  75. package/dist/utils/index.js +5 -1
  76. package/jest.config.js +5 -0
  77. package/package.json +29 -17
  78. package/renovate.json +8 -7
  79. package/test/e2e/basic-flows.spec.ts +106 -0
  80. package/test/e2e/generics.spec.ts +198 -0
  81. package/test/e2e/request-scope.spec.ts +141 -0
  82. package/test/e2e/unhandled-exceptions.spec.ts +73 -0
  83. package/test/jest-e2e.json +9 -0
  84. package/test/utils/wait-immediate.ts +2 -0
  85. package/tsconfig.build.json +10 -0
@@ -17,7 +17,7 @@ jobs:
17
17
  build:
18
18
  working_directory: ~/nest
19
19
  docker:
20
- - image: cimg/node:21.6
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
package/.husky/commit-msg CHANGED
@@ -1,4 +1 @@
1
- #!/bin/sh
2
- . "$(dirname "$0")/_/husky.sh"
3
-
4
1
  npx --no-install commitlint --edit $1
package/.husky/pre-commit CHANGED
@@ -1,4 +1 @@
1
- #!/bin/sh
2
- . "$(dirname "$0")/_/husky.sh"
3
-
4
1
  npx --no-install lint-staged
@@ -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,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Command = void 0;
4
+ const constants_1 = require("./constants");
5
+ class Command {
6
+ }
7
+ exports.Command = Command;
@@ -0,0 +1 @@
1
+ export declare const RESULT_TYPE_SYMBOL: unique symbol;
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RESULT_TYPE_SYMBOL = void 0;
4
+ exports.RESULT_TYPE_SYMBOL = Symbol('RESULT_TYPE');
@@ -0,0 +1,2 @@
1
+ export * from './command';
2
+ export * from './query';
@@ -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
+ }
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Query = void 0;
4
+ const constants_1 = require("./constants");
5
+ class Query {
6
+ }
7
+ exports.Query = Query;
@@ -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 { ICommand, ICommandBus, ICommandHandler, ICommandPublisher } from './interfaces/index';
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 declare type CommandHandlerType = Type<ICommandHandler<ICommand>>;
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<T extends CommandBase, R = any>(command: T): Promise<R>;
29
- bind<T extends CommandBase>(handler: ICommandHandler<T>, id: string): void;
30
- register(handlers?: CommandHandlerType[]): void;
31
- protected registerHandler(handler: CommandHandlerType): void;
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;
@@ -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("./decorators/constants");
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.useDefaultPublisher();
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 handler = this.handlers.get(commandId);
51
- if (!handler) {
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 handler.execute(command);
70
+ return executeFn(command, context);
57
71
  }
58
72
  bind(handler, id) {
59
- this.handlers.set(id, handler);
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 instance = this.moduleRef.get(handler, { strict: false });
66
- if (!instance) {
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.bind(instance, target);
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(constants_1.COMMAND_METADATA, commandType);
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(constants_1.COMMAND_HANDLER_METADATA, handler);
89
- const commandMetadata = Reflect.getMetadata(constants_1.COMMAND_METADATA, command);
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 = __decorate([
130
+ exports.CommandBus = CommandBus;
131
+ exports.CommandBus = CommandBus = CommandBus_1 = __decorate([
97
132
  (0, common_1.Injectable)(),
98
- __metadata("design:paramtypes", [core_1.ModuleRef])
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;
@@ -1 +1 @@
1
- export declare const CQRS_MODULE_OPTIONS = 'CQRS_MODULE_OPTIONS';
1
+ export declare const CQRS_MODULE_OPTIONS = "CQRS_MODULE_OPTIONS";
package/dist/constants.js CHANGED
@@ -1,3 +1,4 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CQRS_MODULE_OPTIONS = void 0;
3
4
  exports.CQRS_MODULE_OPTIONS = 'CQRS_MODULE_OPTIONS';
@@ -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 the CQRS Module globally.
14
- * @returns DynamicModule
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
  }
@@ -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 the CQRS Module globally.
30
- * @returns DynamicModule
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 = CqrsModule_1 = __decorate([
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, uuid_1.v4)() }, command);
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, uuid_1.v4)() }, event);
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);
@@ -2,3 +2,4 @@ export * from './command-handler.decorator';
2
2
  export * from './events-handler.decorator';
3
3
  export * from './query-handler.decorator';
4
4
  export * from './saga.decorator';
5
+ export * from './publishable.decorator';
@@ -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.defineProperty(o, k2, { enumerable: true, get: function() { return m[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);
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,5 @@
1
+ /**
2
+ * Merges event publisher with the decorated class.
3
+ * Implements the `publish` and `publishAll` methods in a similar way to {@link EventPublisher#mergeClassContext}.
4
+ */
5
+ export declare function Publishable(): ClassDecorator;
@@ -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, uuid_1.v4)() }, query);
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;