deno.land / x / hooks@v0.6.5 / src / hooks.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
105
106
107
108
109
110
111
112
113
114
115
116
import { compose, Middleware } from './compose';import { HookContext, setManager, HookContextData, HookOptions, convertOptions, setMiddleware} from './base';import { copyFnProperties, copyProperties } from './utils';
export function getOriginal (fn: any): any { return typeof fn.original === 'function' ? getOriginal(fn.original) : fn;}
export function functionHooks <F> (fn: F, managerOrMiddleware: HookOptions) { if (typeof fn !== 'function') { throw new Error('Can not apply hooks to non-function'); }
const manager = convertOptions(managerOrMiddleware); const wrapper: any = function (this: any, ...args: any[]) { const { Context, original } = wrapper; // If we got passed an existing HookContext instance, we want to return it as well const returnContext = args[args.length - 1] instanceof Context; // Use existing context or default const base = returnContext ? (args.pop() as HookContext) : new Context(); // Initialize the context const context = manager.initializeContext(this, args, base); // Assemble the hook chain const hookChain: Middleware[] = [ // Return `ctx.result` or the context (ctx, next) => next().then(() => returnContext ? ctx : ctx.result) ];
// Create the hook chain by calling the `collectMiddleware function const mw = manager.collectMiddleware(this, args);
if (mw) { Array.prototype.push.apply(hookChain, mw); }
// Runs the actual original method if `ctx.result` is not already set hookChain.push((ctx, next) => { if (!Object.prototype.hasOwnProperty.call(context, 'result')) { return Promise.resolve(original.apply(this, ctx.arguments)).then(result => { ctx.result = result;
return next(); }); }
return next(); });
return compose(hookChain).call(this, context); };
copyFnProperties(wrapper, fn); copyProperties(wrapper, fn); setManager(wrapper, manager);
return Object.assign(wrapper, { original: getOriginal(fn), Context: manager.getContextClass(), createContext: (data: HookContextData = {}) => { return new wrapper.Context(data); } });};
export type HookMap<O = any> = { [L in keyof O]?: HookOptions;}
export function objectHooks (_obj: any, hooks: HookMap|Middleware[]) { const obj = typeof _obj === 'function' ? _obj.prototype : _obj;
if (Array.isArray(hooks)) { return setMiddleware(obj, hooks); }
return Object.keys(hooks).reduce((result, method) => { const fn = obj[method];
if (typeof fn !== 'function') { throw new Error(`Can not apply hooks. '${method}' is not a function`); }
const manager = convertOptions(hooks[method]);
result[method] = functionHooks(fn, manager.props({ method }));
return result; }, obj);};
export const hookDecorator = (managerOrMiddleware?: HookOptions) => { const wrapper: any = (_target: any, method: string, descriptor: TypedPropertyDescriptor<any>): TypedPropertyDescriptor<any> => { const manager = convertOptions(managerOrMiddleware);
if (!descriptor) { setManager(_target.prototype, manager);
return _target; }
const fn = descriptor.value;
if (typeof fn !== 'function') { throw new Error(`Can not apply hooks. '${method}' is not a function`); }
descriptor.value = functionHooks(fn, manager.props({ method }));
return descriptor; };
return wrapper;};
hooks

Version Info

Tagged at
3 years ago