-
Notifications
You must be signed in to change notification settings - Fork 12
/
index.ts
104 lines (88 loc) · 2.43 KB
/
index.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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import { AsyncMiddleware } from './compose.ts';
import { HookContext, HookContextConstructor, HookContextData, HookManager, HookOptions } from './base.ts';
import { functionHooks, hookDecorator, HookMap, objectHooks } from './hooks.ts';
export * from './hooks.ts';
export * from './compose.ts';
export * from './base.ts';
export * from './regular.ts';
export interface WrapperAddon<F> {
original: F;
Context: HookContextConstructor;
createContext: (data?: HookContextData) => HookContext;
}
export type WrappedFunction<F, T> =
& F
& ((...rest: any[]) => Promise<T> | Promise<HookContext>)
& WrapperAddon<F>;
export type MiddlewareOptions = {
params?: any;
defaults?: any;
props?: any;
};
/**
* Initializes a hook settings object with the given middleware.
* @param mw The list of middleware
* @param options Middleware options (params, default, props)
*/
export function middleware(
mw?: AsyncMiddleware[],
options?: MiddlewareOptions,
) {
const manager = new HookManager().middleware(mw);
if (options) {
if (options.params) {
manager.params(...options.params);
}
if (options.defaults) {
manager.defaults(options.defaults);
}
if (options.props) {
manager.props(options.props);
}
}
return manager;
}
/**
* Returns a new function that wraps an existing async function
* with hooks.
*
* @param fn The async function to add hooks to.
* @param manager An array of middleware or hook settings
* (`middleware([]).params()` etc.)
*/
export function hooks<F, T = any>(
fn: F & (() => void),
manager?: HookManager,
): WrappedFunction<F, T>;
/**
* Add hooks to one or more methods on an object or class.
* @param obj The object to add hooks to
* @param hookMap A map of middleware settings where the
* key is the method name.
*/
export function hooks<O>(
obj: O | (new (...args: any[]) => O),
hookMap: HookMap<O> | AsyncMiddleware[],
): O;
/**
* Decorate a class method with hooks.
* @param manager The hooks settings
*/
export function hooks<T = any>(
manager?: HookOptions,
): any;
// Fallthrough to actual implementation
export function hooks(...args: any[]) {
const [target, _hooks] = args;
if (
typeof target === 'function' &&
(_hooks instanceof HookManager || Array.isArray(_hooks) ||
args.length === 1)
) {
return functionHooks(target, _hooks);
}
if (args.length === 2) {
return objectHooks(target, _hooks);
}
return hookDecorator(target);
}