UNPKG

1.79 kBJavaScriptView Raw
1'use strict';
2
3const { asyncParamApiCallback, noop } = require('../../utils');
4
5const commandBuilder = require('./commandBuilder');
6const eventBuilder = require('./eventBuilder');
7
8const generateAggregateApi = require('../apis/generateAggregateApi');
9
10const addCommandToAggregate = (aggregate, {
11 preLoadConditions,
12 preConditions,
13 validator,
14 command,
15}) => {
16 if (validator)
17 command.defineValidation(validator);
18
19 aggregate.addCommand(command);
20 preLoadConditions.forEach(cnd => command.addPreLoadCondition(cnd));
21 preConditions.forEach(cnd => command.addPreCondition(cnd));
22};
23
24const addEventToAggregate = (aggregate, { event }) => {
25 aggregate.addEvent(event);
26};
27
28module.exports = async (context, aggregateName,
29 {
30 commands = {}, events = {}, initialState = {}, eventEnricher, idGenerator, options = {},
31 }, {
32 Aggregate,
33 ...definitions
34 },
35 customApiBuilder = noop,
36) => {
37 const aggregate = new Aggregate({
38 name: aggregateName,
39 context: context.name,
40 ...options,
41 }, { ...initialState });
42
43 if (idGenerator)
44 aggregate.defineCommandAwareAggregateIdGenerator(asyncParamApiCallback(idGenerator, customApiBuilder, 'cmd'));
45
46 context.addAggregate(aggregate);
47
48 // define eventModels - it is important to do so before defining commands so we could generate the aggregateAPI
49 Object.entries(events).map(([eventName, event]) => addEventToAggregate(aggregate, eventBuilder({ eventName, event }, definitions)));
50
51 // generate aggregateApi class
52 const AggregateApi = generateAggregateApi(aggregate, eventEnricher);
53
54 // define commandModels
55 await Promise.all(Object.entries(commands).map(async ([commandName, command]) => addCommandToAggregate(aggregate, await commandBuilder({ commandName, command, AggregateApi }, definitions, customApiBuilder))));
56
57 return aggregate;
58};