Skip to content

Commit a2dcebe

Browse files
committed
Update commands to return TE
1 parent 3a79810 commit a2dcebe

File tree

16 files changed

+97
-32
lines changed

16 files changed

+97
-32
lines changed

src/authentication/verify-email/landing-page.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,17 +61,27 @@ export const landing =
6161

6262
// Note that we don't need to check isAuthorized here because we are authorised
6363
// by the user clicking the verification link.
64-
const resultantEvents = verifyEmail.process({
64+
const resultantEvents = await verifyEmail.process({
6565
events: resourceEvents.right.events,
6666
command: {
6767
emailAddress: decoded.right.emailAddress,
6868
memberNumber: decoded.right.memberNumber,
6969
actor: {'tag': 'system'}
70-
}
71-
});
70+
},
71+
deps,
72+
})();
73+
74+
if (E.isLeft(resultantEvents)) {
75+
deps.logger.error(
76+
resultantEvents.left,
77+
'Failed to process verification link'
78+
);
79+
res.send(invalidLink());
80+
return;
81+
}
7282

73-
if (O.isSome(resultantEvents)) {
74-
const commitEvent = await deps.commitEvent(resource, resourceEvents.right.version)(resultantEvents.value)();
83+
if (O.isSome(resultantEvents.right)) {
84+
const commitEvent = await deps.commitEvent(resource, resourceEvents.right.version)(resultantEvents.right.value)();
7585
if (E.isLeft(commitEvent)) {
7686
deps.logger.error(
7787
commitEvent.left,

src/commands/area/add-owner.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import * as RA from 'fp-ts/ReadonlyArray';
33
import * as t from 'io-ts';
44
import * as tt from 'io-ts-types';
55
import * as O from 'fp-ts/Option';
6+
import * as TE from 'fp-ts/TaskEither';
67
import {pipe} from 'fp-ts/lib/function';
78
import {Command} from '../command';
89
import {isAdminOrSuperUser} from '../is-admin-or-super-user';
@@ -16,10 +17,10 @@ export type AddOwner = t.TypeOf<typeof codec>;
1617

1718
const process: Command<AddOwner>['process'] = input => {
1819
if (input.events.length === 0) {
19-
return O.none;
20+
return TE.right(O.none);
2021
}
2122
if (pipe(input.events, RA.some(isEventOfType('AreaRemoved')))) {
22-
return O.none;
23+
return TE.right(O.none);
2324
}
2425

2526
const happyPathEvent = pipe(
@@ -39,7 +40,8 @@ const process: Command<AddOwner>['process'] = input => {
3940
case 'OwnerRemoved':
4041
return happyPathEvent;
4142
}
42-
})
43+
}),
44+
TE.right
4345
);
4446
};
4547

src/commands/area/remove-area.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {constructEvent, isEventOfType} from '../../types';
22
import * as RA from 'fp-ts/ReadonlyArray';
3+
import * as TE from 'fp-ts/TaskEither';
34
import * as t from 'io-ts';
45
import * as tt from 'io-ts-types';
56
import * as O from 'fp-ts/Option';
@@ -15,15 +16,16 @@ type RemoveArea = t.TypeOf<typeof codec>;
1516

1617
const process: Command<RemoveArea>['process'] = input => {
1718
if (input.events.length === 0) {
18-
return O.none;
19+
return TE.right(O.none);
1920
}
2021
return pipe(
2122
input.events,
2223
RA.filter(isEventOfType('AreaRemoved')),
2324
RA.match(
2425
() => O.some(constructEvent('AreaRemoved')(input.command)),
2526
() => O.none
26-
)
27+
),
28+
TE.right,
2729
);
2830
};
2931

src/commands/area/remove-owner.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as t from 'io-ts';
22
import * as tt from 'io-ts-types';
33
import * as O from 'fp-ts/Option';
4+
import * as TE from 'fp-ts/TaskEither';
45
import {Command} from '../command';
56
import {isAdminOrSuperUser} from '../is-admin-or-super-user';
67
import {pipe} from 'fp-ts/lib/function';
@@ -16,7 +17,7 @@ type RemoveOwner = t.TypeOf<typeof codec>;
1617

1718
const process: Command<RemoveOwner>['process'] = input => {
1819
if (pipe(input.events, RA.some(isEventOfType('AreaRemoved')))) {
19-
return O.none;
20+
return TE.right(O.none);
2021
}
2122

2223
return pipe(
@@ -36,7 +37,8 @@ const process: Command<RemoveOwner>['process'] = input => {
3637
}),
3738
RA.last,
3839
O.filter(isEventOfType('OwnerAdded')),
39-
O.map(() => constructEvent('OwnerRemoved')(input.command))
40+
O.map(() => constructEvent('OwnerRemoved')(input.command)),
41+
TE.right,
4042
);
4143
}
4244

src/commands/equipment/add.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import * as RA from 'fp-ts/ReadonlyArray';
33
import * as t from 'io-ts';
44
import * as tt from 'io-ts-types';
55
import * as O from 'fp-ts/Option';
6+
import * as TE from 'fp-ts/TaskEither';
67
import {pipe} from 'fp-ts/lib/function';
78
import {Command} from '../command';
89
import {isAdminOrSuperUser} from '../is-admin-or-super-user';
@@ -21,7 +22,8 @@ const process: Command<AddEquipment>['process'] = input =>
2122
RA.match(
2223
() => O.some(constructEvent('EquipmentAdded')(input.command)),
2324
() => O.none
24-
)
25+
),
26+
TE.right
2527
);
2628

2729
const resource: Command<AddEquipment>['resource'] = command => ({

src/commands/equipment/register-training-sheet.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as t from 'io-ts';
22
import * as tt from 'io-ts-types';
33
import * as O from 'fp-ts/Option';
4+
import * as TE from 'fp-ts/TaskEither';
45
import {DomainEvent, constructEvent} from '../../types';
56
import {Actor} from '../../types/actor';
67
import {Command, WithActor} from '../command';
@@ -18,9 +19,9 @@ export type RegisterTrainingSheet = t.TypeOf<typeof codec>;
1819
const process = (input: {
1920
command: WithActor<RegisterTrainingSheet>;
2021
events: ReadonlyArray<DomainEvent>;
21-
}): O.Option<DomainEvent> =>
22+
}) =>
2223
// No idempotency check required here currently. If the training sheet already matches the current then we still record the duplicate event.
23-
O.some(constructEvent('EquipmentTrainingSheetRegistered')(input.command));
24+
TE.right(O.some(constructEvent('EquipmentTrainingSheetRegistered')(input.command)));
2425

2526
const resource = (command: RegisterTrainingSheet) => ({
2627
type: 'Equipment',

src/commands/equipment/remove-training-sheet.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as t from 'io-ts';
22
import * as tt from 'io-ts-types';
33
import * as O from 'fp-ts/Option';
4+
import * as TE from 'fp-ts/TaskEither';
45
import {DomainEvent, constructEvent} from '../../types';
56
import {Actor} from '../../types/actor';
67
import {Command, WithActor} from '../command';
@@ -17,8 +18,8 @@ type RemoveTrainingSheet = t.TypeOf<typeof codec>;
1718
const process = (input: {
1819
command: WithActor<RemoveTrainingSheet>;
1920
events: ReadonlyArray<DomainEvent>;
20-
}): O.Option<DomainEvent> =>
21-
O.some(constructEvent('EquipmentTrainingSheetRemoved')(input.command));
21+
}) =>
22+
TE.right(O.some(constructEvent('EquipmentTrainingSheetRemoved')(input.command)));
2223

2324
const resource = (command: RemoveTrainingSheet) => ({
2425
type: 'Equipment',

src/commands/members/verify-email.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as O from 'fp-ts/Option';
2+
import * as TE from 'fp-ts/TaskEither';
23
import * as t from 'io-ts';
34
import {Command} from '../command';
45
import {EmailAddressCodec, constructEvent} from '../../types';
@@ -18,22 +19,22 @@ const process: Command<VerifyMemberEmail>['process'] = input => {
1819
input.command.memberNumber
1920
);
2021
if (state === undefined) {
21-
return O.none;
22+
return TE.right(O.none);
2223
}
2324

2425
const emailAddress = normaliseEmailAddress(input.command.emailAddress);
2526
const email = state.emails[emailAddress];
2627
if (!email || email.verified) {
27-
return O.none;
28+
return TE.right(O.none);
2829
}
2930

30-
return O.some(
31+
return TE.right(O.some(
3132
constructEvent('MemberEmailVerified')({
3233
actor: input.command.actor,
3334
memberNumber: input.command.memberNumber,
3435
email: input.command.emailAddress,
3536
})
36-
);
37+
));
3738
};
3839

3940
const resource = () => ({

src/commands/super-user/declare.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {constructEvent} from '../../types';
22
import * as t from 'io-ts';
33
import * as tt from 'io-ts-types';
44
import * as O from 'fp-ts/Option';
5+
import * as TE from 'fp-ts/TaskEither';
56
import {Command} from '../command';
67
import {isAdminOrSuperUser} from '../is-admin-or-super-user';
78
import {resource} from './resource';
@@ -13,7 +14,7 @@ const codec = t.strict({
1314
export type DeclareSuperUserCommand = t.TypeOf<typeof codec>;
1415

1516
const process: Command<DeclareSuperUserCommand>['process'] = input =>
16-
O.some(constructEvent('SuperUserDeclared')(input.command));
17+
TE.right(O.some(constructEvent('SuperUserDeclared')(input.command)));
1718

1819
export const declare: Command<DeclareSuperUserCommand> = {
1920
process,

src/commands/super-user/revoke.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {constructEvent} from '../../types';
22
import * as t from 'io-ts';
33
import * as tt from 'io-ts-types';
44
import * as O from 'fp-ts/Option';
5+
import * as TE from 'fp-ts/TaskEither';
56
import {Command} from '../command';
67
import * as RA from 'fp-ts/ReadonlyArray';
78
import {isAdminOrSuperUser} from '../is-admin-or-super-user';
@@ -27,7 +28,8 @@ const process: Command<RevokeSuperUser>['process'] = input =>
2728
event.type === 'SuperUserDeclared'
2829
? O.some(constructEvent('SuperUserRevoked')(input.command))
2930
: O.none
30-
)
31+
),
32+
TE.right
3133
);
3234

3335
export const revoke: Command<RevokeSuperUser> = {

0 commit comments

Comments
 (0)