@nestjs/cqrs 7.0.0 → 8.0.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.
- package/.circleci/config.yml +1 -1
- package/.github/ISSUE_TEMPLATE/Bug_report.yml +106 -0
- package/.github/ISSUE_TEMPLATE/Feature_request.yml +52 -0
- package/.github/ISSUE_TEMPLATE/Regression.yml +78 -0
- package/.github/ISSUE_TEMPLATE/config.yml +7 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +10 -14
- package/CONTRIBUTING.md +4 -3
- package/LICENSE +21 -0
- package/dist/aggregate-root.d.ts +4 -2
- package/dist/aggregate-root.js +2 -1
- package/dist/command-bus.d.ts +4 -4
- package/dist/command-bus.js +56 -53
- package/dist/cqrs.module.js +25 -28
- package/dist/decorators/command-handler.decorator.d.ts +10 -0
- package/dist/decorators/command-handler.decorator.js +16 -1
- package/dist/decorators/constants.d.ts +4 -1
- package/dist/decorators/constants.js +5 -2
- package/dist/decorators/events-handler.decorator.d.ts +10 -0
- package/dist/decorators/events-handler.decorator.js +18 -1
- package/dist/decorators/index.js +2 -2
- package/dist/decorators/query-handler.decorator.d.ts +10 -0
- package/dist/decorators/query-handler.decorator.js +16 -1
- package/dist/decorators/saga.decorator.d.ts +5 -0
- package/dist/decorators/saga.decorator.js +7 -1
- package/dist/event-bus.d.ts +4 -4
- package/dist/event-bus.js +78 -81
- package/dist/event-publisher.js +29 -26
- package/dist/exceptions/index.js +2 -2
- package/dist/helpers/default-get-event-id.d.ts +4 -0
- package/dist/helpers/default-get-event-id.js +13 -0
- package/dist/helpers/default-get-event-name.js +2 -1
- package/dist/index.js +8 -2
- package/dist/interfaces/commands/command-bus.interface.d.ts +1 -1
- package/dist/interfaces/commands/command-metadata.interface.d.ts +3 -0
- package/dist/interfaces/commands/command-metadata.interface.js +2 -0
- package/dist/interfaces/index.js +2 -2
- package/dist/interfaces/queries/query-metadata.interface.d.ts +3 -0
- package/dist/interfaces/queries/query-metadata.interface.js +2 -0
- package/dist/operators/index.js +2 -2
- package/dist/operators/of-type.d.ts +8 -0
- package/dist/operators/of-type.js +9 -1
- package/dist/query-bus.d.ts +3 -3
- package/dist/query-bus.js +59 -56
- package/dist/services/explorer.service.js +35 -38
- package/dist/utils/index.js +2 -2
- package/package.json +26 -23
- package/.github/ISSUE_TEMPLATE.md +0 -46
package/.circleci/config.yml
CHANGED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
name: "\U0001F41B Bug Report"
|
|
2
|
+
description: "If something isn't working as expected \U0001F914"
|
|
3
|
+
labels: ["needs triage", "bug"]
|
|
4
|
+
body:
|
|
5
|
+
- type: markdown
|
|
6
|
+
attributes:
|
|
7
|
+
value: |
|
|
8
|
+
## :warning: We use GitHub Issues to track bug reports, feature requests and regressions
|
|
9
|
+
|
|
10
|
+
If you are not sure that your issue is a bug, you could:
|
|
11
|
+
|
|
12
|
+
- use our [Discord community](https://discord.gg/NestJS)
|
|
13
|
+
- use [StackOverflow using the tag `nestjs`](https://stackoverflow.com/questions/tagged/nestjs)
|
|
14
|
+
- If it's just a quick question you can ping [our Twitter](https://twitter.com/nestframework)
|
|
15
|
+
|
|
16
|
+
**NOTE:** You don't need to answer questions that you know that aren't relevant.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
- type: checkboxes
|
|
21
|
+
attributes:
|
|
22
|
+
label: "Is there an existing issue for this?"
|
|
23
|
+
description: "Please search [here](./?q=is%3Aissue) to see if an issue already exists for the bug you encountered"
|
|
24
|
+
options:
|
|
25
|
+
- label: "I have searched the existing issues"
|
|
26
|
+
required: true
|
|
27
|
+
|
|
28
|
+
- type: textarea
|
|
29
|
+
validations:
|
|
30
|
+
required: true
|
|
31
|
+
attributes:
|
|
32
|
+
label: "Current behavior"
|
|
33
|
+
description: "How the issue manifests?"
|
|
34
|
+
|
|
35
|
+
- type: input
|
|
36
|
+
validations:
|
|
37
|
+
required: true
|
|
38
|
+
attributes:
|
|
39
|
+
label: "Minimum reproduction code"
|
|
40
|
+
description: "An URL to some git repository or gist that reproduces this issue. [Wtf is a minimum reproduction?](https://jmcdo29.github.io/wtf-is-a-minimum-reproduction)"
|
|
41
|
+
placeholder: "https://github.com/..."
|
|
42
|
+
|
|
43
|
+
- type: textarea
|
|
44
|
+
attributes:
|
|
45
|
+
label: "Steps to reproduce"
|
|
46
|
+
description: |
|
|
47
|
+
How the issue manifests?
|
|
48
|
+
You could leave this blank if you alread write this in your reproduction code/repo
|
|
49
|
+
placeholder: |
|
|
50
|
+
1. `npm i`
|
|
51
|
+
2. `npm start:dev`
|
|
52
|
+
3. See error...
|
|
53
|
+
|
|
54
|
+
- type: textarea
|
|
55
|
+
validations:
|
|
56
|
+
required: true
|
|
57
|
+
attributes:
|
|
58
|
+
label: "Expected behavior"
|
|
59
|
+
description: "A clear and concise description of what you expected to happend (or code)"
|
|
60
|
+
|
|
61
|
+
- type: markdown
|
|
62
|
+
attributes:
|
|
63
|
+
value: |
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
- type: input
|
|
67
|
+
validations:
|
|
68
|
+
required: true
|
|
69
|
+
attributes:
|
|
70
|
+
label: "Package version"
|
|
71
|
+
description: |
|
|
72
|
+
Which version of `@nestjs/cqrs` are you using?
|
|
73
|
+
**Tip**: Make sure that all of yours `@nestjs/*` dependencies are in sync!
|
|
74
|
+
placeholder: "8.1.3"
|
|
75
|
+
|
|
76
|
+
- type: input
|
|
77
|
+
attributes:
|
|
78
|
+
label: "NestJS version"
|
|
79
|
+
description: "Which version of `@nestjs/core` are you using?"
|
|
80
|
+
placeholder: "8.1.3"
|
|
81
|
+
|
|
82
|
+
- type: input
|
|
83
|
+
attributes:
|
|
84
|
+
label: "Node.js version"
|
|
85
|
+
description: "Which version of Node.js are you using?"
|
|
86
|
+
placeholder: "14.17.6"
|
|
87
|
+
|
|
88
|
+
- type: checkboxes
|
|
89
|
+
attributes:
|
|
90
|
+
label: "In which operating systems have you tested?"
|
|
91
|
+
options:
|
|
92
|
+
- label: macOS
|
|
93
|
+
- label: Windows
|
|
94
|
+
- label: Linux
|
|
95
|
+
|
|
96
|
+
- type: markdown
|
|
97
|
+
attributes:
|
|
98
|
+
value: |
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
- type: textarea
|
|
102
|
+
attributes:
|
|
103
|
+
label: "Other"
|
|
104
|
+
description: |
|
|
105
|
+
Anything else relevant? eg: Logs, OS version, IDE, package manager, etc.
|
|
106
|
+
**Tip:** You can attach images, recordings or log files by clicking this area to highlight it and then dragging files in
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
name: "\U0001F680 Feature Request"
|
|
2
|
+
description: "I have a suggestion \U0001F63B!"
|
|
3
|
+
labels: ["feature"]
|
|
4
|
+
body:
|
|
5
|
+
- type: markdown
|
|
6
|
+
attributes:
|
|
7
|
+
value: |
|
|
8
|
+
## :warning: We use GitHub Issues to track bug reports, feature requests and regressions
|
|
9
|
+
|
|
10
|
+
If you are not sure that your issue is a bug, you could:
|
|
11
|
+
|
|
12
|
+
- use our [Discord community](https://discord.gg/NestJS)
|
|
13
|
+
- use [StackOverflow using the tag `nestjs`](https://stackoverflow.com/questions/tagged/nestjs)
|
|
14
|
+
- If it's just a quick question you can ping [our Twitter](https://twitter.com/nestframework)
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
- type: checkboxes
|
|
19
|
+
attributes:
|
|
20
|
+
label: "Is there an existing issue that is already proposing this?"
|
|
21
|
+
description: "Please search [here](./?q=is%3Aissue) to see if an issue already exists for the feature you are requesting"
|
|
22
|
+
options:
|
|
23
|
+
- label: "I have searched the existing issues"
|
|
24
|
+
required: true
|
|
25
|
+
|
|
26
|
+
- type: textarea
|
|
27
|
+
validations:
|
|
28
|
+
required: true
|
|
29
|
+
attributes:
|
|
30
|
+
label: "Is your feature request related to a problem? Please describe it"
|
|
31
|
+
description: "A clear and concise description of what the problem is"
|
|
32
|
+
placeholder: |
|
|
33
|
+
I have an issue when ...
|
|
34
|
+
|
|
35
|
+
- type: textarea
|
|
36
|
+
validations:
|
|
37
|
+
required: true
|
|
38
|
+
attributes:
|
|
39
|
+
label: "Describe the solution you'd like"
|
|
40
|
+
description: "A clear and concise description of what you want to happen. Add any considered drawbacks"
|
|
41
|
+
|
|
42
|
+
- type: textarea
|
|
43
|
+
attributes:
|
|
44
|
+
label: "Teachability, documentation, adoption, migration strategy"
|
|
45
|
+
description: "If you can, explain how users will be able to use this and possibly write out a version the docs. Maybe a screenshot or design?"
|
|
46
|
+
|
|
47
|
+
- type: textarea
|
|
48
|
+
validations:
|
|
49
|
+
required: true
|
|
50
|
+
attributes:
|
|
51
|
+
label: "What is the motivation / use case for changing the behavior?"
|
|
52
|
+
description: "Describe the motivation or the concrete use case"
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
name: "\U0001F4A5 Regression"
|
|
2
|
+
description: "Report an unexpected behavior while upgrading your Nest application!"
|
|
3
|
+
labels: ["needs triage"]
|
|
4
|
+
body:
|
|
5
|
+
- type: markdown
|
|
6
|
+
attributes:
|
|
7
|
+
value: |
|
|
8
|
+
## :warning: We use GitHub Issues to track bug reports, feature requests and regressions
|
|
9
|
+
|
|
10
|
+
If you are not sure that your issue is a bug, you could:
|
|
11
|
+
|
|
12
|
+
- use our [Discord community](https://discord.gg/NestJS)
|
|
13
|
+
- use [StackOverflow using the tag `nestjs`](https://stackoverflow.com/questions/tagged/nestjs)
|
|
14
|
+
- If it's just a quick question you can ping [our Twitter](https://twitter.com/nestframework)
|
|
15
|
+
|
|
16
|
+
**NOTE:** You don't need to answer questions that you know that aren't relevant.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
- type: checkboxes
|
|
21
|
+
attributes:
|
|
22
|
+
label: "Did you read the migration guide?"
|
|
23
|
+
description: "Check out the [migration guide here](https://docs.nestjs.com/migration-guide)!"
|
|
24
|
+
options:
|
|
25
|
+
- label: "I have read the whole migration guide"
|
|
26
|
+
required: false
|
|
27
|
+
|
|
28
|
+
- type: checkboxes
|
|
29
|
+
attributes:
|
|
30
|
+
label: "Is there an existing issue that is already proposing this?"
|
|
31
|
+
description: "Please search [here](./?q=is%3Aissue) to see if an issue already exists for the feature you are requesting"
|
|
32
|
+
options:
|
|
33
|
+
- label: "I have searched the existing issues"
|
|
34
|
+
required: true
|
|
35
|
+
|
|
36
|
+
- type: input
|
|
37
|
+
attributes:
|
|
38
|
+
label: "Potential Commit/PR that introduced the regression"
|
|
39
|
+
description: "If you have time to investigate, what PR/date/version introduced this issue"
|
|
40
|
+
placeholder: "PR #123 or commit 5b3c4a4"
|
|
41
|
+
|
|
42
|
+
- type: input
|
|
43
|
+
attributes:
|
|
44
|
+
label: "Versions"
|
|
45
|
+
description: "From which version of `@nestjs/cqrs` to which version you are upgrading"
|
|
46
|
+
placeholder: "8.1.0 -> 8.1.3"
|
|
47
|
+
|
|
48
|
+
- type: textarea
|
|
49
|
+
validations:
|
|
50
|
+
required: true
|
|
51
|
+
attributes:
|
|
52
|
+
label: "Describe the regression"
|
|
53
|
+
description: "A clear and concise description of what the regression is"
|
|
54
|
+
|
|
55
|
+
- type: textarea
|
|
56
|
+
attributes:
|
|
57
|
+
label: "Minimum reproduction code"
|
|
58
|
+
description: |
|
|
59
|
+
Please share a git repo, a gist, or step-by-step instructions. [Wtf is a minimum reproduction?](https://jmcdo29.github.io/wtf-is-a-minimum-reproduction)
|
|
60
|
+
**Tip:** If you leave a minimum repository, we will understand your issue faster!
|
|
61
|
+
value: |
|
|
62
|
+
```ts
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
- type: textarea
|
|
67
|
+
validations:
|
|
68
|
+
required: true
|
|
69
|
+
attributes:
|
|
70
|
+
label: "Expected behavior"
|
|
71
|
+
description: "A clear and concise description of what you expected to happend (or code)"
|
|
72
|
+
|
|
73
|
+
- type: textarea
|
|
74
|
+
attributes:
|
|
75
|
+
label: "Other"
|
|
76
|
+
description: |
|
|
77
|
+
Anything else relevant? eg: Logs, OS version, IDE, package manager, etc.
|
|
78
|
+
**Tip:** You can attach images, recordings or log files by clicking this area to highlight it and then dragging files in
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
## To encourage contributors to use issue templates, we don't allow blank issues
|
|
2
|
+
blank_issues_enabled: false
|
|
3
|
+
|
|
4
|
+
contact_links:
|
|
5
|
+
- name: "\u2753 Discord Community of NestJS"
|
|
6
|
+
url: "https://discord.gg/NestJS"
|
|
7
|
+
about: "Please ask support questions or discuss suggestions/enhancements here."
|
|
@@ -10,15 +10,13 @@ Please check if your PR fulfills the following requirements:
|
|
|
10
10
|
What kind of change does this PR introduce?
|
|
11
11
|
|
|
12
12
|
<!-- Please check the one that applies to this PR using "x". -->
|
|
13
|
-
|
|
14
|
-
[ ]
|
|
15
|
-
[ ]
|
|
16
|
-
[ ]
|
|
17
|
-
[ ]
|
|
18
|
-
[ ]
|
|
19
|
-
[ ]
|
|
20
|
-
[ ] Other... Please describe:
|
|
21
|
-
```
|
|
13
|
+
- [ ] Bugfix
|
|
14
|
+
- [ ] Feature
|
|
15
|
+
- [ ] Code style update (formatting, local variables)
|
|
16
|
+
- [ ] Refactoring (no functional changes, no api changes)
|
|
17
|
+
- [ ] Build related changes
|
|
18
|
+
- [ ] CI related changes
|
|
19
|
+
- [ ] Other... Please describe:
|
|
22
20
|
|
|
23
21
|
## What is the current behavior?
|
|
24
22
|
<!-- Please describe the current behavior that you are modifying, or link to a relevant issue. -->
|
|
@@ -30,12 +28,10 @@ Issue Number: N/A
|
|
|
30
28
|
|
|
31
29
|
|
|
32
30
|
## Does this PR introduce a breaking change?
|
|
33
|
-
|
|
34
|
-
[ ]
|
|
35
|
-
[ ] No
|
|
36
|
-
```
|
|
31
|
+
- [ ] Yes
|
|
32
|
+
- [ ] No
|
|
37
33
|
|
|
38
34
|
<!-- If this PR contains a breaking change, please describe the impact and migration path for existing applications below. -->
|
|
39
35
|
|
|
40
36
|
|
|
41
|
-
## Other information
|
|
37
|
+
## Other information
|
package/CONTRIBUTING.md
CHANGED
|
@@ -186,7 +186,7 @@ Samples: (even more [samples](https://github.com/nestjs/nest/commits/master))
|
|
|
186
186
|
docs(changelog) update change log to beta.5
|
|
187
187
|
```
|
|
188
188
|
```
|
|
189
|
-
|
|
189
|
+
fix(@nestjs/core) need to depend on latest rxjs and zone.js
|
|
190
190
|
|
|
191
191
|
The version in our package.json gets copied to the one we publish, and users need the latest of these.
|
|
192
192
|
```
|
|
@@ -198,10 +198,11 @@ If the commit reverts a previous commit, it should begin with `revert: `, follow
|
|
|
198
198
|
Must be one of the following:
|
|
199
199
|
|
|
200
200
|
* **build**: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
|
|
201
|
+
* **chore**: Updating tasks etc; no production code change
|
|
201
202
|
* **ci**: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)
|
|
202
203
|
* **docs**: Documentation only changes
|
|
203
|
-
* **
|
|
204
|
-
* **
|
|
204
|
+
* **feat**: A new feature
|
|
205
|
+
* **fix**: A bug fix
|
|
205
206
|
* **perf**: A code change that improves performance
|
|
206
207
|
* **refactor**: A code change that neither fixes a bug nor adds a feature
|
|
207
208
|
* **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2017-2021 Kamil Mysliwiec <https://kamilmysliwiec.com>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/aggregate-root.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { IEvent } from './interfaces';
|
|
1
|
+
import { IEvent, IEventHandler } from './interfaces';
|
|
2
|
+
import { Type } from '@nestjs/common';
|
|
2
3
|
declare const INTERNAL_EVENTS: unique symbol;
|
|
3
4
|
declare const IS_AUTO_COMMIT_ENABLED: unique symbol;
|
|
4
5
|
export declare abstract class AggregateRoot<EventBase extends IEvent = IEvent> {
|
|
@@ -7,12 +8,13 @@ export declare abstract class AggregateRoot<EventBase extends IEvent = IEvent> {
|
|
|
7
8
|
set autoCommit(value: boolean);
|
|
8
9
|
get autoCommit(): boolean;
|
|
9
10
|
publish<T extends EventBase = EventBase>(event: T): void;
|
|
11
|
+
publishAll<T extends EventBase = EventBase>(event: T[]): void;
|
|
10
12
|
commit(): void;
|
|
11
13
|
uncommit(): void;
|
|
12
14
|
getUncommittedEvents(): EventBase[];
|
|
13
15
|
loadFromHistory(history: EventBase[]): void;
|
|
14
16
|
apply<T extends EventBase = EventBase>(event: T, isFromHistory?: boolean): void;
|
|
15
|
-
|
|
17
|
+
protected getEventHandler<T extends EventBase = EventBase>(event: T): Type<IEventHandler> | undefined;
|
|
16
18
|
protected getEventName(event: any): string;
|
|
17
19
|
}
|
|
18
20
|
export {};
|
package/dist/aggregate-root.js
CHANGED
|
@@ -16,8 +16,9 @@ class AggregateRoot {
|
|
|
16
16
|
return this[IS_AUTO_COMMIT_ENABLED];
|
|
17
17
|
}
|
|
18
18
|
publish(event) { }
|
|
19
|
+
publishAll(event) { }
|
|
19
20
|
commit() {
|
|
20
|
-
this[INTERNAL_EVENTS]
|
|
21
|
+
this.publishAll(this[INTERNAL_EVENTS]);
|
|
21
22
|
this[INTERNAL_EVENTS].length = 0;
|
|
22
23
|
}
|
|
23
24
|
uncommit() {
|
package/dist/command-bus.d.ts
CHANGED
|
@@ -11,11 +11,11 @@ export declare class CommandBus<CommandBase extends ICommand = ICommand> extends
|
|
|
11
11
|
constructor(moduleRef: ModuleRef);
|
|
12
12
|
get publisher(): ICommandPublisher<CommandBase>;
|
|
13
13
|
set publisher(_publisher: ICommandPublisher<CommandBase>);
|
|
14
|
-
execute<T extends CommandBase>(command: T): Promise<
|
|
15
|
-
bind<T extends CommandBase>(handler: ICommandHandler<T>,
|
|
14
|
+
execute<T extends CommandBase, R = any>(command: T): Promise<R>;
|
|
15
|
+
bind<T extends CommandBase>(handler: ICommandHandler<T>, id: string): void;
|
|
16
16
|
register(handlers?: CommandHandlerType[]): void;
|
|
17
17
|
protected registerHandler(handler: CommandHandlerType): void;
|
|
18
|
-
private
|
|
19
|
-
private
|
|
18
|
+
private getCommandId;
|
|
19
|
+
private reflectCommandId;
|
|
20
20
|
private useDefaultPublisher;
|
|
21
21
|
}
|
package/dist/command-bus.js
CHANGED
|
@@ -18,61 +18,64 @@ const command_not_found_exception_1 = require("./exceptions/command-not-found.ex
|
|
|
18
18
|
const default_command_pubsub_1 = require("./helpers/default-command-pubsub");
|
|
19
19
|
const index_1 = require("./index");
|
|
20
20
|
const observable_bus_1 = require("./utils/observable-bus");
|
|
21
|
-
let CommandBus =
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
21
|
+
let CommandBus = class CommandBus extends observable_bus_1.ObservableBus {
|
|
22
|
+
constructor(moduleRef) {
|
|
23
|
+
super();
|
|
24
|
+
this.moduleRef = moduleRef;
|
|
25
|
+
this.handlers = new Map();
|
|
26
|
+
this.useDefaultPublisher();
|
|
27
|
+
}
|
|
28
|
+
get publisher() {
|
|
29
|
+
return this._publisher;
|
|
30
|
+
}
|
|
31
|
+
set publisher(_publisher) {
|
|
32
|
+
this._publisher = _publisher;
|
|
33
|
+
}
|
|
34
|
+
execute(command) {
|
|
35
|
+
const commandId = this.getCommandId(command);
|
|
36
|
+
const handler = this.handlers.get(commandId);
|
|
37
|
+
if (!handler) {
|
|
38
|
+
throw new command_not_found_exception_1.CommandHandlerNotFoundException(commandId);
|
|
28
39
|
}
|
|
29
|
-
|
|
30
|
-
|
|
40
|
+
this.subject$.next(command);
|
|
41
|
+
return handler.execute(command);
|
|
42
|
+
}
|
|
43
|
+
bind(handler, id) {
|
|
44
|
+
this.handlers.set(id, handler);
|
|
45
|
+
}
|
|
46
|
+
register(handlers = []) {
|
|
47
|
+
handlers.forEach((handler) => this.registerHandler(handler));
|
|
48
|
+
}
|
|
49
|
+
registerHandler(handler) {
|
|
50
|
+
const instance = this.moduleRef.get(handler, { strict: false });
|
|
51
|
+
if (!instance) {
|
|
52
|
+
return;
|
|
31
53
|
}
|
|
32
|
-
|
|
33
|
-
|
|
54
|
+
const target = this.reflectCommandId(handler);
|
|
55
|
+
if (!target) {
|
|
56
|
+
throw new index_1.InvalidCommandHandlerException();
|
|
34
57
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
return handler.execute(command);
|
|
58
|
+
this.bind(instance, target);
|
|
59
|
+
}
|
|
60
|
+
getCommandId(command) {
|
|
61
|
+
const { constructor: commandType } = Object.getPrototypeOf(command);
|
|
62
|
+
const commandMetadata = Reflect.getMetadata(constants_1.COMMAND_METADATA, commandType);
|
|
63
|
+
if (!commandMetadata) {
|
|
64
|
+
throw new command_not_found_exception_1.CommandHandlerNotFoundException(commandType.name);
|
|
43
65
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
this.bind(instance, target.name);
|
|
60
|
-
}
|
|
61
|
-
getCommandName(command) {
|
|
62
|
-
const { constructor } = Object.getPrototypeOf(command);
|
|
63
|
-
return constructor.name;
|
|
64
|
-
}
|
|
65
|
-
reflectCommandName(handler) {
|
|
66
|
-
return Reflect.getMetadata(constants_1.COMMAND_HANDLER_METADATA, handler);
|
|
67
|
-
}
|
|
68
|
-
useDefaultPublisher() {
|
|
69
|
-
this._publisher = new default_command_pubsub_1.DefaultCommandPubSub(this.subject$);
|
|
70
|
-
}
|
|
71
|
-
};
|
|
72
|
-
CommandBus = __decorate([
|
|
73
|
-
common_1.Injectable(),
|
|
74
|
-
__metadata("design:paramtypes", [core_1.ModuleRef])
|
|
75
|
-
], CommandBus);
|
|
76
|
-
return CommandBus;
|
|
77
|
-
})();
|
|
66
|
+
return commandMetadata.id;
|
|
67
|
+
}
|
|
68
|
+
reflectCommandId(handler) {
|
|
69
|
+
const command = Reflect.getMetadata(constants_1.COMMAND_HANDLER_METADATA, handler);
|
|
70
|
+
const commandMetadata = Reflect.getMetadata(constants_1.COMMAND_METADATA, command);
|
|
71
|
+
return commandMetadata.id;
|
|
72
|
+
}
|
|
73
|
+
useDefaultPublisher() {
|
|
74
|
+
this._publisher = new default_command_pubsub_1.DefaultCommandPubSub(this.subject$);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
CommandBus = __decorate([
|
|
78
|
+
(0, common_1.Injectable)(),
|
|
79
|
+
__metadata("design:paramtypes", [core_1.ModuleRef])
|
|
80
|
+
], CommandBus);
|
|
78
81
|
exports.CommandBus = CommandBus;
|
package/dist/cqrs.module.js
CHANGED
|
@@ -16,32 +16,29 @@ const event_bus_1 = require("./event-bus");
|
|
|
16
16
|
const event_publisher_1 = require("./event-publisher");
|
|
17
17
|
const query_bus_1 = require("./query-bus");
|
|
18
18
|
const explorer_service_1 = require("./services/explorer.service");
|
|
19
|
-
let CqrsModule =
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
], CqrsModule);
|
|
45
|
-
return CqrsModule;
|
|
46
|
-
})();
|
|
19
|
+
let CqrsModule = class CqrsModule {
|
|
20
|
+
constructor(explorerService, eventsBus, commandsBus, queryBus) {
|
|
21
|
+
this.explorerService = explorerService;
|
|
22
|
+
this.eventsBus = eventsBus;
|
|
23
|
+
this.commandsBus = commandsBus;
|
|
24
|
+
this.queryBus = queryBus;
|
|
25
|
+
}
|
|
26
|
+
onApplicationBootstrap() {
|
|
27
|
+
const { events, queries, sagas, commands } = this.explorerService.explore();
|
|
28
|
+
this.eventsBus.register(events);
|
|
29
|
+
this.commandsBus.register(commands);
|
|
30
|
+
this.queryBus.register(queries);
|
|
31
|
+
this.eventsBus.registerSagas(sagas);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
CqrsModule = __decorate([
|
|
35
|
+
(0, common_1.Module)({
|
|
36
|
+
providers: [command_bus_1.CommandBus, query_bus_1.QueryBus, event_bus_1.EventBus, event_publisher_1.EventPublisher, explorer_service_1.ExplorerService],
|
|
37
|
+
exports: [command_bus_1.CommandBus, query_bus_1.QueryBus, event_bus_1.EventBus, event_publisher_1.EventPublisher],
|
|
38
|
+
}),
|
|
39
|
+
__metadata("design:paramtypes", [explorer_service_1.ExplorerService,
|
|
40
|
+
event_bus_1.EventBus,
|
|
41
|
+
command_bus_1.CommandBus,
|
|
42
|
+
query_bus_1.QueryBus])
|
|
43
|
+
], CqrsModule);
|
|
47
44
|
exports.CqrsModule = CqrsModule;
|
|
@@ -1,3 +1,13 @@
|
|
|
1
1
|
import 'reflect-metadata';
|
|
2
2
|
import { ICommand } from '../index';
|
|
3
|
+
/**
|
|
4
|
+
* Decorator that marks a class as a Nest command handler. A command handler
|
|
5
|
+
* handles commands (actions) executed by your application code.
|
|
6
|
+
*
|
|
7
|
+
* The decorated class must implement the `ICommandHandler` interface.
|
|
8
|
+
*
|
|
9
|
+
* @param command command *type* to be handled by this handler.
|
|
10
|
+
*
|
|
11
|
+
* @see https://docs.nestjs.com/recipes/cqrs#commands
|
|
12
|
+
*/
|
|
3
13
|
export declare const CommandHandler: (command: ICommand) => ClassDecorator;
|
|
@@ -3,8 +3,23 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.CommandHandler = void 0;
|
|
4
4
|
require("reflect-metadata");
|
|
5
5
|
const constants_1 = require("./constants");
|
|
6
|
-
|
|
6
|
+
const uuid_1 = require("uuid");
|
|
7
|
+
/**
|
|
8
|
+
* Decorator that marks a class as a Nest command handler. A command handler
|
|
9
|
+
* handles commands (actions) executed by your application code.
|
|
10
|
+
*
|
|
11
|
+
* The decorated class must implement the `ICommandHandler` interface.
|
|
12
|
+
*
|
|
13
|
+
* @param command command *type* to be handled by this handler.
|
|
14
|
+
*
|
|
15
|
+
* @see https://docs.nestjs.com/recipes/cqrs#commands
|
|
16
|
+
*/
|
|
17
|
+
const CommandHandler = (command) => {
|
|
7
18
|
return (target) => {
|
|
19
|
+
if (!Reflect.hasMetadata(constants_1.COMMAND_METADATA, command)) {
|
|
20
|
+
Reflect.defineMetadata(constants_1.COMMAND_METADATA, { id: (0, uuid_1.v4)() }, command);
|
|
21
|
+
}
|
|
8
22
|
Reflect.defineMetadata(constants_1.COMMAND_HANDLER_METADATA, command, target);
|
|
9
23
|
};
|
|
10
24
|
};
|
|
25
|
+
exports.CommandHandler = CommandHandler;
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
export declare const COMMAND_METADATA = "__command__";
|
|
1
2
|
export declare const COMMAND_HANDLER_METADATA = "__commandHandler__";
|
|
3
|
+
export declare const QUERY_METADATA = "__query__";
|
|
2
4
|
export declare const QUERY_HANDLER_METADATA = "__queryHandler__";
|
|
3
|
-
export declare const
|
|
5
|
+
export declare const EVENT_METADATA = "__event__";
|
|
6
|
+
export declare const EVENTS_HANDLER_METADATA = "__eventsHandler__";
|
|
4
7
|
export declare const SAGA_METADATA = "__saga__";
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SAGA_METADATA = exports.EVENTS_HANDLER_METADATA = exports.QUERY_HANDLER_METADATA = exports.COMMAND_HANDLER_METADATA = void 0;
|
|
3
|
+
exports.SAGA_METADATA = exports.EVENTS_HANDLER_METADATA = exports.EVENT_METADATA = exports.QUERY_HANDLER_METADATA = exports.QUERY_METADATA = exports.COMMAND_HANDLER_METADATA = exports.COMMAND_METADATA = void 0;
|
|
4
|
+
exports.COMMAND_METADATA = '__command__';
|
|
4
5
|
exports.COMMAND_HANDLER_METADATA = '__commandHandler__';
|
|
6
|
+
exports.QUERY_METADATA = '__query__';
|
|
5
7
|
exports.QUERY_HANDLER_METADATA = '__queryHandler__';
|
|
6
|
-
exports.
|
|
8
|
+
exports.EVENT_METADATA = '__event__';
|
|
9
|
+
exports.EVENTS_HANDLER_METADATA = '__eventsHandler__';
|
|
7
10
|
exports.SAGA_METADATA = '__saga__';
|
|
@@ -1,3 +1,13 @@
|
|
|
1
1
|
import 'reflect-metadata';
|
|
2
2
|
import { IEvent } from '../index';
|
|
3
|
+
/**
|
|
4
|
+
* Decorator that marks a class as a Nest event handler. An event handler
|
|
5
|
+
* handles events executed by your application code.
|
|
6
|
+
*
|
|
7
|
+
* The decorated class must implement the `IEventHandler` interface.
|
|
8
|
+
*
|
|
9
|
+
* @param events one or more event *types* to be handled by this handler.
|
|
10
|
+
*
|
|
11
|
+
* @see https://docs.nestjs.com/recipes/cqrs#events
|
|
12
|
+
*/
|
|
3
13
|
export declare const EventsHandler: (...events: IEvent[]) => ClassDecorator;
|