@nestjs/cqrs 11.0.2 → 12.0.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/.circleci/config.yml +3 -3
- package/.nvmrc +1 -0
- package/README.md +0 -1
- package/dist/aggregate-root.d.ts +3 -67
- package/dist/aggregate-root.js +6 -83
- package/dist/classes/command.d.ts +2 -2
- package/dist/classes/command.js +2 -6
- package/dist/classes/constants.js +1 -4
- package/dist/classes/index.d.ts +2 -2
- package/dist/classes/index.js +2 -18
- package/dist/classes/query.d.ts +2 -2
- package/dist/classes/query.js +2 -6
- package/dist/command-bus.d.ts +8 -5
- package/dist/command-bus.js +32 -32
- package/dist/constants.js +1 -4
- package/dist/cqrs.module.d.ts +8 -5
- package/dist/cqrs.module.js +37 -37
- package/dist/decorators/command-handler.decorator.d.ts +3 -1
- package/dist/decorators/command-handler.decorator.js +11 -13
- package/dist/decorators/constants.js +7 -10
- package/dist/decorators/events-handler.decorator.d.ts +3 -1
- package/dist/decorators/events-handler.decorator.js +12 -14
- package/dist/decorators/index.d.ts +5 -5
- package/dist/decorators/index.js +5 -21
- package/dist/decorators/publishable.decorator.d.ts +2 -0
- package/dist/decorators/publishable.decorator.js +5 -6
- package/dist/decorators/query-handler.decorator.d.ts +3 -1
- package/dist/decorators/query-handler.decorator.js +11 -13
- package/dist/decorators/saga.decorator.d.ts +2 -0
- package/dist/decorators/saga.decorator.js +7 -9
- package/dist/event-bus.d.ts +13 -8
- package/dist/event-bus.js +54 -51
- package/dist/event-publisher.d.ts +9 -7
- package/dist/event-publisher.js +10 -10
- package/dist/exceptions/command-not-found.exception.d.ts +3 -0
- package/dist/exceptions/command-not-found.exception.js +4 -5
- package/dist/exceptions/index.d.ts +7 -7
- package/dist/exceptions/index.js +7 -23
- package/dist/exceptions/invalid-command-handler.exception.d.ts +3 -0
- package/dist/exceptions/invalid-command-handler.exception.js +4 -5
- package/dist/exceptions/invalid-events-handler.exception.d.ts +3 -0
- package/dist/exceptions/invalid-events-handler.exception.js +4 -5
- package/dist/exceptions/invalid-query-handler.exception.js +1 -5
- package/dist/exceptions/invalid-saga.exception.d.ts +3 -0
- package/dist/exceptions/invalid-saga.exception.js +4 -5
- package/dist/exceptions/query-not-found.exception.d.ts +3 -0
- package/dist/exceptions/query-not-found.exception.js +4 -5
- package/dist/exceptions/unsupported-saga-scope.exception.d.ts +3 -0
- package/dist/exceptions/unsupported-saga-scope.exception.js +4 -5
- package/dist/helpers/default-command-pubsub.d.ts +1 -1
- package/dist/helpers/default-command-pubsub.js +1 -5
- package/dist/helpers/default-event-id-provider.d.ts +1 -1
- package/dist/helpers/default-event-id-provider.js +3 -6
- package/dist/helpers/default-pubsub.d.ts +1 -1
- package/dist/helpers/default-pubsub.js +1 -5
- package/dist/helpers/default-query-pubsub.d.ts +1 -1
- package/dist/helpers/default-query-pubsub.js +1 -5
- package/dist/helpers/default-unhandled-exception-pubsub.d.ts +1 -1
- package/dist/helpers/default-unhandled-exception-pubsub.js +1 -5
- package/dist/index.d.ts +15 -14
- package/dist/index.js +15 -30
- package/dist/interfaces/aggregate-root.interface.d.ts +53 -0
- package/dist/interfaces/aggregate-root.interface.js +1 -0
- package/dist/interfaces/commands/command-bus.interface.d.ts +5 -3
- package/dist/interfaces/commands/command-bus.interface.js +1 -2
- package/dist/interfaces/commands/command-handler.interface.d.ts +4 -2
- package/dist/interfaces/commands/command-handler.interface.js +1 -2
- package/dist/interfaces/commands/command-metadata.interface.js +1 -2
- package/dist/interfaces/commands/command-publisher.interface.d.ts +6 -1
- package/dist/interfaces/commands/command-publisher.interface.js +1 -2
- package/dist/interfaces/commands/command.interface.js +1 -2
- package/dist/interfaces/cqrs-module-options.interface.d.ts +17 -5
- package/dist/interfaces/cqrs-module-options.interface.js +1 -2
- package/dist/interfaces/events/event-bus.interface.d.ts +2 -2
- package/dist/interfaces/events/event-bus.interface.js +1 -2
- package/dist/interfaces/events/event-handler.interface.d.ts +1 -1
- package/dist/interfaces/events/event-handler.interface.js +1 -2
- package/dist/interfaces/events/event-id-provider.interface.d.ts +1 -1
- package/dist/interfaces/events/event-id-provider.interface.js +1 -2
- package/dist/interfaces/events/event-publisher.interface.d.ts +2 -2
- package/dist/interfaces/events/event-publisher.interface.js +1 -2
- package/dist/interfaces/events/event.interface.js +1 -2
- package/dist/interfaces/events/message-source.interface.d.ts +1 -1
- package/dist/interfaces/events/message-source.interface.js +1 -2
- package/dist/interfaces/exceptions/unhandled-exception-info.interface.d.ts +2 -2
- package/dist/interfaces/exceptions/unhandled-exception-info.interface.js +1 -2
- package/dist/interfaces/exceptions/unhandled-exception-publisher.interface.d.ts +3 -3
- package/dist/interfaces/exceptions/unhandled-exception-publisher.interface.js +1 -2
- package/dist/interfaces/index.d.ts +20 -19
- package/dist/interfaces/index.js +20 -35
- package/dist/interfaces/providers-introspection-result.interface.d.ts +4 -4
- package/dist/interfaces/providers-introspection-result.interface.js +1 -2
- package/dist/interfaces/queries/query-bus.interface.d.ts +5 -3
- package/dist/interfaces/queries/query-bus.interface.js +1 -2
- package/dist/interfaces/queries/query-handler.interface.d.ts +4 -2
- package/dist/interfaces/queries/query-handler.interface.js +1 -2
- package/dist/interfaces/queries/query-metadata.interface.js +1 -2
- package/dist/interfaces/queries/query-publisher.interface.d.ts +6 -1
- package/dist/interfaces/queries/query-publisher.interface.js +1 -2
- package/dist/interfaces/queries/query-result.interface.js +1 -2
- package/dist/interfaces/queries/query.interface.js +1 -2
- package/dist/interfaces/saga.type.d.ts +2 -2
- package/dist/interfaces/saga.type.js +1 -2
- package/dist/mixins/index.d.ts +1 -0
- package/dist/mixins/index.js +1 -0
- package/dist/mixins/with-aggregate-root.mixin.d.ts +11 -0
- package/dist/mixins/with-aggregate-root.mixin.js +67 -0
- package/dist/operators/index.d.ts +1 -1
- package/dist/operators/index.js +1 -17
- package/dist/operators/of-type.d.ts +1 -1
- package/dist/operators/of-type.js +3 -6
- package/dist/query-bus.d.ts +8 -5
- package/dist/query-bus.js +31 -31
- package/dist/scopes/async.context.js +9 -13
- package/dist/scopes/index.d.ts +1 -1
- package/dist/scopes/index.js +1 -17
- package/dist/services/explorer.service.d.ts +5 -5
- package/dist/services/explorer.service.js +14 -20
- package/dist/storages/aggregate-root.storage.d.ts +3 -3
- package/dist/storages/aggregate-root.storage.js +1 -5
- package/dist/unhandled-exception-bus.d.ts +2 -2
- package/dist/unhandled-exception-bus.js +14 -17
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js +1 -17
- package/dist/utils/observable-bus.js +3 -7
- package/package.json +35 -27
- package/test/e2e/basic-flows.spec.ts +46 -26
- package/test/e2e/generics.spec.ts +3 -3
- package/test/e2e/request-scope.spec.ts +23 -22
- package/test/e2e/sync-event-handlers-app.spec.ts +123 -0
- package/test/e2e/unhandled-exceptions.spec.ts +36 -20
- package/tsconfig.build.json +3 -2
- package/vitest.config.e2e.ts +13 -0
- package/vitest.config.ts +8 -0
- package/dist/exceptions/invalid-module-ref.exception.d.ts +0 -3
- package/dist/exceptions/invalid-module-ref.exception.js +0 -8
- package/dist/helpers/default-get-event-id.d.ts +0 -9
- package/dist/helpers/default-get-event-id.js +0 -18
- package/dist/helpers/default-get-event-name.d.ts +0 -2
- package/dist/helpers/default-get-event-name.js +0 -8
- package/dist/interfaces/cqrs-options.interface.d.ts +0 -10
- package/dist/interfaces/cqrs-options.interface.js +0 -2
- package/dist/interfaces/event-observable.interface.d.ts +0 -4
- package/dist/interfaces/event-observable.interface.js +0 -2
- package/dist/utils/command-handler.decorator.d.ts +0 -3
- package/dist/utils/command-handler.decorator.js +0 -9
- package/dist/utils/constants.d.ts +0 -2
- package/dist/utils/constants.js +0 -4
- package/dist/utils/default-pubsub.d.ts +0 -9
- package/dist/utils/default-pubsub.js +0 -14
- package/dist/utils/events-handler.decorator.d.ts +0 -3
- package/dist/utils/events-handler.decorator.js +0 -9
- package/eslint.config.mjs +0 -42
- package/index.d.ts +0 -1
- package/index.js +0 -6
- package/jest.config.js +0 -9
- package/test/jest-e2e.json +0 -9
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
2
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
3
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -8,21 +7,19 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
8
7
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
8
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
9
|
};
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const modules_container_1 = require("@nestjs/core/injector/modules-container");
|
|
15
|
-
const constants_1 = require("../decorators/constants");
|
|
10
|
+
import { Injectable } from '@nestjs/common';
|
|
11
|
+
import { ModulesContainer } from '@nestjs/core/injector/modules-container.js';
|
|
12
|
+
import { COMMAND_HANDLER_METADATA, EVENTS_HANDLER_METADATA, QUERY_HANDLER_METADATA, SAGA_METADATA, } from '../decorators/constants.js';
|
|
16
13
|
let ExplorerService = class ExplorerService {
|
|
17
14
|
constructor(modulesContainer) {
|
|
18
15
|
this.modulesContainer = modulesContainer;
|
|
19
16
|
}
|
|
20
17
|
explore() {
|
|
21
18
|
const modules = [...this.modulesContainer.values()];
|
|
22
|
-
const commands = this.flatMap(modules, (instance) => this.filterByMetadataKey(instance,
|
|
23
|
-
const queries = this.flatMap(modules, (instance) => this.filterByMetadataKey(instance,
|
|
24
|
-
const events = this.flatMap(modules, (instance) => this.filterByMetadataKey(instance,
|
|
25
|
-
const sagas = this.flatMap(modules, (instance) => this.filterByMetadataKey(instance,
|
|
19
|
+
const commands = this.flatMap(modules, (instance) => this.filterByMetadataKey(instance, COMMAND_HANDLER_METADATA));
|
|
20
|
+
const queries = this.flatMap(modules, (instance) => this.filterByMetadataKey(instance, QUERY_HANDLER_METADATA));
|
|
21
|
+
const events = this.flatMap(modules, (instance) => this.filterByMetadataKey(instance, EVENTS_HANDLER_METADATA));
|
|
22
|
+
const sagas = this.flatMap(modules, (instance) => this.filterByMetadataKey(instance, SAGA_METADATA));
|
|
26
23
|
return { commands, queries, events, sagas };
|
|
27
24
|
}
|
|
28
25
|
flatMap(modules, callback) {
|
|
@@ -32,22 +29,19 @@ let ExplorerService = class ExplorerService {
|
|
|
32
29
|
return items.filter((item) => !!item);
|
|
33
30
|
}
|
|
34
31
|
filterByMetadataKey(wrapper, metadataKey) {
|
|
35
|
-
const
|
|
36
|
-
if (!
|
|
32
|
+
const clsRef = wrapper.instance?.constructor ?? wrapper.metatype;
|
|
33
|
+
if (!clsRef) {
|
|
37
34
|
return;
|
|
38
35
|
}
|
|
39
|
-
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
const metadata = Reflect.getMetadata(metadataKey, instance.constructor);
|
|
36
|
+
const metadata = Reflect.getMetadata(metadataKey, clsRef);
|
|
43
37
|
if (!metadata) {
|
|
44
38
|
return;
|
|
45
39
|
}
|
|
46
40
|
return wrapper;
|
|
47
41
|
}
|
|
48
42
|
};
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
(
|
|
52
|
-
__metadata("design:paramtypes", [modules_container_1.ModulesContainer])
|
|
43
|
+
ExplorerService = __decorate([
|
|
44
|
+
Injectable(),
|
|
45
|
+
__metadata("design:paramtypes", [ModulesContainer])
|
|
53
46
|
], ExplorerService);
|
|
47
|
+
export { ExplorerService };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Type } from '@nestjs/common';
|
|
2
|
-
import {
|
|
3
|
-
import { EventBus } from '../event-bus';
|
|
2
|
+
import { IAggregateRoot } from '../interfaces/index.js';
|
|
3
|
+
import { EventBus } from '../event-bus.js';
|
|
4
4
|
export declare class AggregateRootStorage {
|
|
5
5
|
private static storage;
|
|
6
|
-
static add(type: Type<
|
|
6
|
+
static add(type: Type<IAggregateRoot>): void;
|
|
7
7
|
static mergeContext(eventBus: EventBus): void;
|
|
8
8
|
}
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AggregateRootStorage = void 0;
|
|
4
|
-
class AggregateRootStorage {
|
|
1
|
+
export class AggregateRootStorage {
|
|
5
2
|
static add(type) {
|
|
6
3
|
this.storage.push(type);
|
|
7
4
|
}
|
|
@@ -17,5 +14,4 @@ class AggregateRootStorage {
|
|
|
17
14
|
this.storage = [];
|
|
18
15
|
}
|
|
19
16
|
}
|
|
20
|
-
exports.AggregateRootStorage = AggregateRootStorage;
|
|
21
17
|
AggregateRootStorage.storage = [];
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Type } from '@nestjs/common';
|
|
2
2
|
import 'reflect-metadata';
|
|
3
3
|
import { Observable } from 'rxjs';
|
|
4
|
-
import { CqrsModuleOptions, ICommand, IEvent, IUnhandledExceptionPublisher, UnhandledExceptionInfo } from './interfaces';
|
|
5
|
-
import { ObservableBus } from './utils/observable-bus';
|
|
4
|
+
import { CqrsModuleOptions, ICommand, IEvent, IUnhandledExceptionPublisher, UnhandledExceptionInfo } from './interfaces/index.js';
|
|
5
|
+
import { ObservableBus } from './utils/observable-bus.js';
|
|
6
6
|
/**
|
|
7
7
|
* A bus that publishes unhandled exceptions.
|
|
8
8
|
* @template Cause The type of the cause of the exception.
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
2
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
3
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -11,19 +10,17 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
11
10
|
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
11
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
12
|
};
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const default_unhandled_exception_pubsub_1 = require("./helpers/default-unhandled-exception-pubsub");
|
|
21
|
-
const observable_bus_1 = require("./utils/observable-bus");
|
|
13
|
+
import { Inject, Injectable, Optional } from '@nestjs/common';
|
|
14
|
+
import 'reflect-metadata';
|
|
15
|
+
import { filter } from 'rxjs';
|
|
16
|
+
import { CQRS_MODULE_OPTIONS } from './constants.js';
|
|
17
|
+
import { DefaultUnhandledExceptionPubSub } from './helpers/default-unhandled-exception-pubsub.js';
|
|
18
|
+
import { ObservableBus } from './utils/observable-bus.js';
|
|
22
19
|
/**
|
|
23
20
|
* A bus that publishes unhandled exceptions.
|
|
24
21
|
* @template Cause The type of the cause of the exception.
|
|
25
22
|
*/
|
|
26
|
-
let UnhandledExceptionBus = class UnhandledExceptionBus extends
|
|
23
|
+
let UnhandledExceptionBus = class UnhandledExceptionBus extends ObservableBus {
|
|
27
24
|
constructor(options) {
|
|
28
25
|
super();
|
|
29
26
|
this.options = options;
|
|
@@ -44,7 +41,7 @@ let UnhandledExceptionBus = class UnhandledExceptionBus extends observable_bus_1
|
|
|
44
41
|
*/
|
|
45
42
|
static ofType(...types) {
|
|
46
43
|
const isInstanceOf = (exceptionInfo) => !!types.find((classType) => exceptionInfo.exception instanceof classType);
|
|
47
|
-
return (source) => source.pipe(
|
|
44
|
+
return (source) => source.pipe(filter(isInstanceOf));
|
|
48
45
|
}
|
|
49
46
|
/**
|
|
50
47
|
* Gets the publisher of the bus.
|
|
@@ -66,13 +63,13 @@ let UnhandledExceptionBus = class UnhandledExceptionBus extends observable_bus_1
|
|
|
66
63
|
return this._publisher.publish(info);
|
|
67
64
|
}
|
|
68
65
|
useDefaultPublisher() {
|
|
69
|
-
this._publisher = new
|
|
66
|
+
this._publisher = new DefaultUnhandledExceptionPubSub(this.subject$);
|
|
70
67
|
}
|
|
71
68
|
};
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
(0,
|
|
75
|
-
__param(0, (
|
|
76
|
-
__param(0, (0, common_1.Inject)(constants_1.CQRS_MODULE_OPTIONS)),
|
|
69
|
+
UnhandledExceptionBus = __decorate([
|
|
70
|
+
Injectable(),
|
|
71
|
+
__param(0, Optional()),
|
|
72
|
+
__param(0, Inject(CQRS_MODULE_OPTIONS)),
|
|
77
73
|
__metadata("design:paramtypes", [Object])
|
|
78
74
|
], UnhandledExceptionBus);
|
|
75
|
+
export { UnhandledExceptionBus };
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from './observable-bus';
|
|
1
|
+
export * from './observable-bus.js';
|
package/dist/utils/index.js
CHANGED
|
@@ -1,17 +1 @@
|
|
|
1
|
-
|
|
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("./observable-bus"), exports);
|
|
1
|
+
export * from './observable-bus.js';
|
|
@@ -1,15 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.ObservableBus = void 0;
|
|
4
|
-
const rxjs_1 = require("rxjs");
|
|
5
|
-
class ObservableBus extends rxjs_1.Observable {
|
|
1
|
+
import { Observable, Subject } from 'rxjs';
|
|
2
|
+
export class ObservableBus extends Observable {
|
|
6
3
|
constructor() {
|
|
7
4
|
super();
|
|
8
|
-
this._subject$ = new
|
|
5
|
+
this._subject$ = new Subject();
|
|
9
6
|
this.source = this._subject$;
|
|
10
7
|
}
|
|
11
8
|
get subject$() {
|
|
12
9
|
return this._subject$;
|
|
13
10
|
}
|
|
14
11
|
}
|
|
15
|
-
exports.ObservableBus = ObservableBus;
|
package/package.json
CHANGED
|
@@ -1,14 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nestjs/cqrs",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "12.0.0",
|
|
4
4
|
"description": "A lightweight CQRS module for Nest framework (node.js)",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"require": "./dist/index.js",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"./package.json": "./package.json"
|
|
16
|
+
},
|
|
17
|
+
"engines": {
|
|
18
|
+
"node": "^20.19.0 || >=22.12.0"
|
|
19
|
+
},
|
|
5
20
|
"license": "MIT",
|
|
6
21
|
"url": "https://github.com/nestjs/cqrs#readme",
|
|
7
22
|
"scripts": {
|
|
8
|
-
"test": "
|
|
23
|
+
"test": "vitest run",
|
|
9
24
|
"build": "tsc -p tsconfig.build.json",
|
|
10
25
|
"format": "prettier --write \"**/*.ts\"",
|
|
11
|
-
"lint": "
|
|
26
|
+
"lint": "oxlint src/",
|
|
12
27
|
"prepublish:next": "npm run build",
|
|
13
28
|
"publish:next": "npm publish --access public --tag next",
|
|
14
29
|
"prepublish:npm": "npm run build",
|
|
@@ -16,36 +31,29 @@
|
|
|
16
31
|
"prerelease": "npm run build",
|
|
17
32
|
"release": "release-it",
|
|
18
33
|
"prepare": "husky",
|
|
19
|
-
"test:e2e": "
|
|
34
|
+
"test:e2e": "vitest run --config vitest.config.e2e.ts"
|
|
20
35
|
},
|
|
21
36
|
"devDependencies": {
|
|
22
|
-
"@commitlint/cli": "
|
|
23
|
-
"@commitlint/config-angular": "
|
|
24
|
-
"@
|
|
25
|
-
"@
|
|
26
|
-
"@nestjs/
|
|
27
|
-
"@
|
|
28
|
-
"@nestjs/testing": "11.0.9",
|
|
29
|
-
"@types/jest": "29.5.14",
|
|
30
|
-
"@types/node": "22.13.1",
|
|
31
|
-
"eslint": "9.20.1",
|
|
32
|
-
"eslint-config-prettier": "10.0.1",
|
|
33
|
-
"eslint-plugin-prettier": "5.2.3",
|
|
34
|
-
"globals": "15.14.0",
|
|
37
|
+
"@commitlint/cli": "21.2.2",
|
|
38
|
+
"@commitlint/config-angular": "21.2.2",
|
|
39
|
+
"@nestjs/common": "12.0.1",
|
|
40
|
+
"@nestjs/core": "12.0.1",
|
|
41
|
+
"@nestjs/testing": "12.0.1",
|
|
42
|
+
"@types/node": "24.13.3",
|
|
35
43
|
"husky": "9.1.7",
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"prettier": "3.
|
|
44
|
+
"lint-staged": "17.3.0",
|
|
45
|
+
"oxlint": "1.80.0",
|
|
46
|
+
"prettier": "3.9.6",
|
|
39
47
|
"reflect-metadata": "0.2.2",
|
|
40
|
-
"release-it": "
|
|
41
|
-
"rxjs": "7.8.
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
48
|
+
"release-it": "21.0.2",
|
|
49
|
+
"rxjs": "7.8.2",
|
|
50
|
+
"typescript": "7.0.2",
|
|
51
|
+
"vite": "8.2.2",
|
|
52
|
+
"vitest": "4.1.11"
|
|
45
53
|
},
|
|
46
54
|
"peerDependencies": {
|
|
47
|
-
"@nestjs/common": "^
|
|
48
|
-
"@nestjs/core": "^
|
|
55
|
+
"@nestjs/common": "^12.0.0",
|
|
56
|
+
"@nestjs/core": "^12.0.0",
|
|
49
57
|
"reflect-metadata": "^0.1.13 || ^0.2.0",
|
|
50
58
|
"rxjs": "^7.2.0"
|
|
51
59
|
},
|
|
@@ -1,20 +1,24 @@
|
|
|
1
1
|
import { Test, TestingModule } from '@nestjs/testing';
|
|
2
2
|
import { setTimeout } from 'timers/promises';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
3
|
+
import type { MockInstance } from 'vitest';
|
|
4
|
+
import { CommandBus, QueryBus } from '../../src/index.js';
|
|
5
|
+
import { AppModule } from '../src/app.module.js';
|
|
6
|
+
import { DropAncientItemHandler } from '../src/heroes/commands/handlers/drop-ancient-item.handler.js';
|
|
7
|
+
import { KillDragonHandler } from '../src/heroes/commands/handlers/kill-dragon.handler.js';
|
|
8
|
+
import { DropAncientItemCommand } from '../src/heroes/commands/impl/drop-ancient-item.command.js';
|
|
9
|
+
import { KillDragonCommand } from '../src/heroes/commands/impl/kill-dragon.command.js';
|
|
10
|
+
import { DragonDiedHandler } from '../src/heroes/events/handlers/dragon-died.handler.js';
|
|
11
|
+
import { HeroFoundItemHandler } from '../src/heroes/events/handlers/hero-found-item.handler.js';
|
|
12
|
+
import { HeroKilledDragonHandler } from '../src/heroes/events/handlers/hero-killed-dragon.handler.js';
|
|
13
|
+
import { DragonDiedEvent } from '../src/heroes/events/impl/dragon-died.event.js';
|
|
14
|
+
import { HeroFoundItemEvent } from '../src/heroes/events/impl/hero-found-item.event.js';
|
|
15
|
+
import { HeroKilledDragonEvent } from '../src/heroes/events/impl/hero-killed-dragon.event.js';
|
|
16
|
+
import { DRAGON_ID } from '../src/heroes/repository/fixtures/dragon.js';
|
|
17
|
+
import { GetHeroesQuery, GetHeroQuery } from '../src/heroes/queries/impl/index.js';
|
|
18
|
+
import { HERO_ID } from '../src/heroes/repository/fixtures/user.js';
|
|
19
|
+
import { ANCIENT_ITEM_ID } from '../src/heroes/sagas/heroes.sagas.js';
|
|
20
|
+
import { NoopHandler } from '../src/noop/events/handlers/noop.handler.js';
|
|
21
|
+
import { waitImmediate } from '../utils/wait-immediate.js';
|
|
18
22
|
|
|
19
23
|
describe('Basic flows', () => {
|
|
20
24
|
let moduleRef: TestingModule;
|
|
@@ -28,23 +32,26 @@ describe('Basic flows', () => {
|
|
|
28
32
|
});
|
|
29
33
|
|
|
30
34
|
describe('when "KillDragonCommand" command is dispatched', () => {
|
|
31
|
-
let killDragonExecuteSpy:
|
|
32
|
-
let heroKilledDragonHandleSpy:
|
|
33
|
-
let
|
|
35
|
+
let killDragonExecuteSpy: MockInstance;
|
|
36
|
+
let heroKilledDragonHandleSpy: MockInstance;
|
|
37
|
+
let dragonDiedHandleSpy: MockInstance;
|
|
38
|
+
let noopEventHandleSpy: MockInstance;
|
|
34
39
|
let command: KillDragonCommand;
|
|
35
40
|
|
|
36
41
|
beforeAll(async () => {
|
|
37
42
|
const killDragonHandler = moduleRef.get(KillDragonHandler);
|
|
38
43
|
const heroKilledDragonHandler = moduleRef.get(HeroKilledDragonHandler);
|
|
44
|
+
const dragonDiedHandler = moduleRef.get(DragonDiedHandler);
|
|
39
45
|
const noopHandler = moduleRef.get(NoopHandler);
|
|
40
46
|
|
|
41
|
-
killDragonExecuteSpy =
|
|
42
|
-
heroKilledDragonHandleSpy =
|
|
43
|
-
|
|
47
|
+
killDragonExecuteSpy = vi.spyOn(killDragonHandler, 'execute');
|
|
48
|
+
heroKilledDragonHandleSpy = vi.spyOn(heroKilledDragonHandler, 'handle');
|
|
49
|
+
dragonDiedHandleSpy = vi.spyOn(dragonDiedHandler, 'handle');
|
|
50
|
+
noopEventHandleSpy = vi.spyOn(noopHandler, 'handle');
|
|
44
51
|
|
|
45
52
|
const commandBus = moduleRef.get(CommandBus);
|
|
46
53
|
const heroId = HERO_ID;
|
|
47
|
-
const dragonId =
|
|
54
|
+
const dragonId = DRAGON_ID;
|
|
48
55
|
|
|
49
56
|
command = new KillDragonCommand(heroId, dragonId);
|
|
50
57
|
await commandBus.execute(command);
|
|
@@ -60,19 +67,24 @@ describe('Basic flows', () => {
|
|
|
60
67
|
expect(heroKilledDragonHandleSpy).toHaveBeenCalledWith(event);
|
|
61
68
|
});
|
|
62
69
|
|
|
70
|
+
it('should handle "DragonDiedEvent" event from aggregate root', () => {
|
|
71
|
+
const event = new DragonDiedEvent(DRAGON_ID);
|
|
72
|
+
expect(dragonDiedHandleSpy).toHaveBeenCalledWith(event);
|
|
73
|
+
});
|
|
74
|
+
|
|
63
75
|
it('should not trigger "NoopHandler" event', () => {
|
|
64
76
|
expect(noopEventHandleSpy).not.toHaveBeenCalled();
|
|
65
77
|
});
|
|
66
78
|
|
|
67
79
|
describe('when saga triggered', () => {
|
|
68
|
-
let dropAncientExecuteSpy:
|
|
69
|
-
let heroFoundItemSpy:
|
|
80
|
+
let dropAncientExecuteSpy: MockInstance;
|
|
81
|
+
let heroFoundItemSpy: MockInstance;
|
|
70
82
|
|
|
71
83
|
beforeAll(async () => {
|
|
72
84
|
const dropAncientItemHandler = moduleRef.get(DropAncientItemHandler);
|
|
73
85
|
const heroFoundItemHandler = moduleRef.get(HeroFoundItemHandler);
|
|
74
|
-
dropAncientExecuteSpy =
|
|
75
|
-
heroFoundItemSpy =
|
|
86
|
+
dropAncientExecuteSpy = vi.spyOn(dropAncientItemHandler, 'execute');
|
|
87
|
+
heroFoundItemSpy = vi.spyOn(heroFoundItemHandler, 'handle');
|
|
76
88
|
|
|
77
89
|
// Wait 1 second for saga to be triggered
|
|
78
90
|
await setTimeout(1000);
|
|
@@ -100,6 +112,14 @@ describe('Basic flows', () => {
|
|
|
100
112
|
});
|
|
101
113
|
});
|
|
102
114
|
|
|
115
|
+
describe('when "GetHeroQuery" query is executed', () => {
|
|
116
|
+
it('should return a single hero', async () => {
|
|
117
|
+
const queryBus = moduleRef.get(QueryBus);
|
|
118
|
+
const hero = await queryBus.execute(new GetHeroQuery(1234));
|
|
119
|
+
expect(hero).toEqual(expect.objectContaining({ id: HERO_ID }));
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
|
|
103
123
|
afterAll(async () => {
|
|
104
124
|
await moduleRef.close();
|
|
105
125
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { InstanceWrapper } from '@nestjs/core/injector/instance-wrapper';
|
|
1
|
+
import { InstanceWrapper } from '@nestjs/core/injector/instance-wrapper.js';
|
|
2
2
|
import { Test, TestingModule } from '@nestjs/testing';
|
|
3
3
|
import {
|
|
4
4
|
Command,
|
|
@@ -6,8 +6,8 @@ import {
|
|
|
6
6
|
ICommandHandler,
|
|
7
7
|
Query,
|
|
8
8
|
QueryBus,
|
|
9
|
-
} from '../../src';
|
|
10
|
-
import { AppModule } from '../src/app.module';
|
|
9
|
+
} from '../../src/index.js';
|
|
10
|
+
import { AppModule } from '../src/app.module.js';
|
|
11
11
|
|
|
12
12
|
describe('Generics', () => {
|
|
13
13
|
let moduleRef: TestingModule;
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import { Test, TestingModule } from '@nestjs/testing';
|
|
2
2
|
import { setTimeout } from 'timers/promises';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
3
|
+
import type { MockInstance } from 'vitest';
|
|
4
|
+
import { AsyncContext, CommandBus, QueryBus } from '../../src/index.js';
|
|
5
|
+
import { AppModule } from '../src/app.module.js';
|
|
6
|
+
import { HERO_ID } from '../src/heroes/repository/fixtures/user.js';
|
|
7
|
+
import { ANCIENT_ITEM_ID } from '../src/heroes/sagas/heroes.sagas.js';
|
|
8
|
+
import { ScopedDropAncientItemHandler } from '../src/scoped/commands/handlers/scoped-drop-ancient-item.handler.js';
|
|
9
|
+
import { ScopedKillDragonHandler } from '../src/scoped/commands/handlers/scoped-kill-dragon.handler.js';
|
|
10
|
+
import { ScopedDropAncientItemCommand } from '../src/scoped/commands/impl/scoped-drop-ancient-item.command.js';
|
|
11
|
+
import { ScopedKillDragonCommand } from '../src/scoped/commands/impl/scoped-kill-dragon.command.js';
|
|
12
|
+
import { ScopedHeroFoundItemHandler } from '../src/scoped/events/handlers/scoped-hero-found-item.handler.js';
|
|
13
|
+
import { ScopedHeroKilledDragonHandler } from '../src/scoped/events/handlers/scoped-hero-killed-dragon.handler.js';
|
|
14
|
+
import { ScopedHeroFoundItemEvent } from '../src/scoped/events/impl/hero-found-item.event.js';
|
|
15
|
+
import { ScopedHeroKilledDragonEvent } from '../src/scoped/events/impl/hero-killed-dragon.event.js';
|
|
16
|
+
import { ScopedGetHeroesQuery } from '../src/scoped/queries/impl/index.js';
|
|
17
|
+
import { waitImmediate } from '../utils/wait-immediate.js';
|
|
17
18
|
|
|
18
19
|
describe('Request scope', () => {
|
|
19
20
|
let moduleRef: TestingModule;
|
|
@@ -29,8 +30,8 @@ describe('Request scope', () => {
|
|
|
29
30
|
describe('when "ScopedKillDragonCommand" command is dispatched', () => {
|
|
30
31
|
const asyncContext = new AsyncContext();
|
|
31
32
|
|
|
32
|
-
let killDragonExecuteSpy:
|
|
33
|
-
let heroKilledDragonHandleSpy:
|
|
33
|
+
let killDragonExecuteSpy: MockInstance;
|
|
34
|
+
let heroKilledDragonHandleSpy: MockInstance;
|
|
34
35
|
let command: ScopedKillDragonCommand;
|
|
35
36
|
|
|
36
37
|
beforeAll(async () => {
|
|
@@ -45,8 +46,8 @@ describe('Request scope', () => {
|
|
|
45
46
|
asyncContext.id,
|
|
46
47
|
);
|
|
47
48
|
|
|
48
|
-
killDragonExecuteSpy =
|
|
49
|
-
heroKilledDragonHandleSpy =
|
|
49
|
+
killDragonExecuteSpy = vi.spyOn(killDragonHandler, 'execute');
|
|
50
|
+
heroKilledDragonHandleSpy = vi.spyOn(heroKilledDragonHandler, 'handle');
|
|
50
51
|
|
|
51
52
|
const commandBus = moduleRef.get(CommandBus);
|
|
52
53
|
const heroId = HERO_ID;
|
|
@@ -70,8 +71,8 @@ describe('Request scope', () => {
|
|
|
70
71
|
});
|
|
71
72
|
|
|
72
73
|
describe('when saga triggered', () => {
|
|
73
|
-
let dropAncientExecuteSpy:
|
|
74
|
-
let heroFoundItemSpy:
|
|
74
|
+
let dropAncientExecuteSpy: MockInstance;
|
|
75
|
+
let heroFoundItemSpy: MockInstance;
|
|
75
76
|
|
|
76
77
|
beforeAll(async () => {
|
|
77
78
|
const dropAncientItemHandler = await moduleRef.resolve(
|
|
@@ -82,8 +83,8 @@ describe('Request scope', () => {
|
|
|
82
83
|
ScopedHeroFoundItemHandler,
|
|
83
84
|
asyncContext.id,
|
|
84
85
|
);
|
|
85
|
-
dropAncientExecuteSpy =
|
|
86
|
-
heroFoundItemSpy =
|
|
86
|
+
dropAncientExecuteSpy = vi.spyOn(dropAncientItemHandler, 'execute');
|
|
87
|
+
heroFoundItemSpy = vi.spyOn(heroFoundItemHandler, 'handle');
|
|
87
88
|
|
|
88
89
|
// Wait 1 second for saga to be triggered
|
|
89
90
|
await setTimeout(1000);
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { Test, TestingModule } from '@nestjs/testing';
|
|
2
|
+
import { MockInstance, vi } from 'vitest';
|
|
3
|
+
import { AsyncHandlersAppModule } from '../src/sync-event-handlers/async-handlers-app.module.js';
|
|
4
|
+
import { EventBus } from '../../src/event-bus.js';
|
|
5
|
+
import { HeroKilledDragon2SlowHandler } from '../src/sync-event-handlers/events/handlers/hero-killed-dragon2-slow.handler.js';
|
|
6
|
+
import { HeroKilledDragonSlowHandler } from '../src/sync-event-handlers/events/handlers/hero-killed-dragon-slow.handler.js';
|
|
7
|
+
import { HeroFoundItemSlowHandler } from '../src/sync-event-handlers/events/handlers/hero-found-item-slow.handler.js';
|
|
8
|
+
import { SyncHandlersAppModule } from '../src/sync-event-handlers/sync-handlers-app.module.js';
|
|
9
|
+
import { HeroFoundItemEvent } from '../src/heroes/events/impl/hero-found-item.event.js';
|
|
10
|
+
import { HeroKilledDragonEvent } from '../src/heroes/events/impl/hero-killed-dragon.event.js';
|
|
11
|
+
|
|
12
|
+
describe('Sync event handlers', () => {
|
|
13
|
+
let moduleRef: TestingModule;
|
|
14
|
+
let eventBus: EventBus;
|
|
15
|
+
let heroFoundItemHandler: HeroFoundItemSlowHandler;
|
|
16
|
+
let heroFoundItemEnded: MockInstance;
|
|
17
|
+
let heroKilledDragonHandler: HeroKilledDragonSlowHandler;
|
|
18
|
+
let heroKilledDragonEnded: MockInstance;
|
|
19
|
+
let heroKilledDragon2Handler: HeroKilledDragon2SlowHandler;
|
|
20
|
+
let heroKilledDragon2Ended: MockInstance;
|
|
21
|
+
|
|
22
|
+
beforeEach(() => {
|
|
23
|
+
heroFoundItemEnded.mockClear();
|
|
24
|
+
heroKilledDragonEnded.mockClear();
|
|
25
|
+
heroKilledDragon2Ended.mockClear();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
describe('when event handlers are fully asynchronous', () => {
|
|
29
|
+
beforeAll(async () => {
|
|
30
|
+
moduleRef = await Test.createTestingModule({
|
|
31
|
+
imports: [AsyncHandlersAppModule],
|
|
32
|
+
}).compile();
|
|
33
|
+
|
|
34
|
+
await moduleRef.init();
|
|
35
|
+
eventBus = moduleRef.get(EventBus);
|
|
36
|
+
heroFoundItemHandler = moduleRef.get(HeroFoundItemSlowHandler);
|
|
37
|
+
heroKilledDragonHandler = moduleRef.get(HeroKilledDragonSlowHandler);
|
|
38
|
+
heroKilledDragon2Handler = moduleRef.get(HeroKilledDragon2SlowHandler);
|
|
39
|
+
heroFoundItemEnded = vi.spyOn(heroFoundItemHandler, 'end');
|
|
40
|
+
heroKilledDragonEnded = vi.spyOn(heroKilledDragonHandler, 'end');
|
|
41
|
+
heroKilledDragon2Ended = vi.spyOn(heroKilledDragon2Handler, 'end');
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
describe('when "HeroFoundItemEvent" event is published', () => {
|
|
45
|
+
it('should wait for the event handlers to complete', async () => {
|
|
46
|
+
const event = new HeroFoundItemEvent('hero1', 'item1');
|
|
47
|
+
|
|
48
|
+
await eventBus.publish(event);
|
|
49
|
+
|
|
50
|
+
expect(heroFoundItemEnded).not.toHaveBeenCalled();
|
|
51
|
+
expect(heroKilledDragonEnded).not.toHaveBeenCalled();
|
|
52
|
+
expect(heroKilledDragon2Ended).not.toHaveBeenCalled();
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
describe('when "HeroKilledDragonEvent" event is published', () => {
|
|
57
|
+
it('should wait for the event handlers to complete', async () => {
|
|
58
|
+
const event = new HeroKilledDragonEvent('hero1', 'dragon1');
|
|
59
|
+
|
|
60
|
+
await eventBus.publish(event);
|
|
61
|
+
|
|
62
|
+
expect(heroFoundItemEnded).not.toHaveBeenCalled();
|
|
63
|
+
expect(heroKilledDragonEnded).not.toHaveBeenCalled();
|
|
64
|
+
expect(heroKilledDragon2Ended).not.toHaveBeenCalled();
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
describe('when event handlers are synchronous', () => {
|
|
70
|
+
beforeAll(async () => {
|
|
71
|
+
moduleRef = await Test.createTestingModule({
|
|
72
|
+
imports: [SyncHandlersAppModule],
|
|
73
|
+
}).compile();
|
|
74
|
+
|
|
75
|
+
await moduleRef.init();
|
|
76
|
+
eventBus = moduleRef.get(EventBus);
|
|
77
|
+
heroFoundItemHandler = moduleRef.get(HeroFoundItemSlowHandler);
|
|
78
|
+
heroKilledDragonHandler = moduleRef.get(HeroKilledDragonSlowHandler);
|
|
79
|
+
heroKilledDragon2Handler = moduleRef.get(HeroKilledDragon2SlowHandler);
|
|
80
|
+
heroFoundItemEnded = vi.spyOn(heroFoundItemHandler, 'end');
|
|
81
|
+
heroKilledDragonEnded = vi.spyOn(heroKilledDragonHandler, 'end');
|
|
82
|
+
heroKilledDragon2Ended = vi.spyOn(heroKilledDragon2Handler, 'end');
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
describe('when "HeroFoundItemEvent" event is published', () => {
|
|
86
|
+
it('should wait for the event handlers to complete', async () => {
|
|
87
|
+
const event = new HeroFoundItemEvent('hero1', 'item1');
|
|
88
|
+
|
|
89
|
+
await eventBus.publish(event);
|
|
90
|
+
|
|
91
|
+
expect(heroFoundItemEnded).toHaveBeenCalledTimes(1);
|
|
92
|
+
expect(heroKilledDragonEnded).not.toHaveBeenCalled();
|
|
93
|
+
expect(heroKilledDragon2Ended).not.toHaveBeenCalled();
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
describe('when "HeroKilledDragonEvent" event is published', () => {
|
|
98
|
+
it('should wait for the event handlers to complete', async () => {
|
|
99
|
+
const event = new HeroKilledDragonEvent('hero1', 'dragon1');
|
|
100
|
+
|
|
101
|
+
await eventBus.publish(event);
|
|
102
|
+
|
|
103
|
+
expect(heroFoundItemEnded).not.toHaveBeenCalled();
|
|
104
|
+
expect(heroKilledDragonEnded).toHaveBeenCalledTimes(1);
|
|
105
|
+
expect(heroKilledDragon2Ended).toHaveBeenCalledTimes(1);
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
describe('when an unknown event is published', () => {
|
|
110
|
+
it('should return directly', async () => {
|
|
111
|
+
await eventBus.publish({ id: 'unknown event' });
|
|
112
|
+
|
|
113
|
+
expect(heroFoundItemEnded).not.toHaveBeenCalled();
|
|
114
|
+
expect(heroKilledDragonEnded).not.toHaveBeenCalled();
|
|
115
|
+
expect(heroKilledDragon2Ended).not.toHaveBeenCalled();
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
afterAll(async () => {
|
|
121
|
+
await moduleRef.close();
|
|
122
|
+
});
|
|
123
|
+
});
|