-
Notifications
You must be signed in to change notification settings - Fork 12
/
regular.ts
62 lines (54 loc) · 1.78 KB
/
regular.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import { compose } from './compose.ts';
import { HookContext } from './base.ts';
export type RegularMiddleware<T extends HookContext = any> = (
context: T,
) => Promise<any> | any;
export interface RegularHookMap {
before?: RegularMiddleware[];
after?: RegularMiddleware[];
error?: RegularMiddleware[];
}
const runHook = (hook: RegularMiddleware, context: any, type?: string) => {
if (type) context.type = type;
return Promise.resolve(hook.call(context.self, context))
.then((res: any) => {
if (type) context.type = null;
if (res && res !== context) {
Object.assign(context, res);
}
});
};
export function fromBeforeHook(hook: RegularMiddleware) {
return (context: any, next: any) => {
return runHook(hook, context, 'before').then(next);
};
}
export function fromAfterHook(hook: RegularMiddleware) {
return (context: any, next: any) => {
return next().then(() => runHook(hook, context, 'after'));
};
}
export function fromErrorHook(hook: RegularMiddleware) {
return (context: any, next: any) => {
return next().catch((error: any) => {
if (context.error !== error || context.result !== undefined) {
(context as any).original = { ...context };
context.error = error;
delete context.result;
}
return runHook(hook, context, 'error').then(() => {
if (context.result === undefined && context.error !== undefined) {
throw context.error;
}
});
});
};
}
export function collect(
{ before = [], after = [], error = [] }: RegularHookMap,
) {
const beforeHooks = before.map(fromBeforeHook);
const afterHooks = [...after].reverse().map(fromAfterHook);
const errorHooks: any = error.map(fromErrorHook);
return compose([...errorHooks, ...afterHooks, ...beforeHooks]);
}