Skip to content

Commit

Permalink
feat: Chainable configuration (#23)
Browse files Browse the repository at this point in the history
  • Loading branch information
bertho-zero committed Feb 15, 2020
1 parent 9a77e81 commit c534827
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 6 deletions.
19 changes: 17 additions & 2 deletions packages/hooks/src/decorator.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import { functionHooks } from './function';
import { HookContext, registerMiddleware, normalizeOptions, HookSettings } from './base';
import {
HookContext,
registerMiddleware,
normalizeOptions,
HookSettings, withParams
} from './base';

export const hookDecorator = <T> (hooks: HookSettings<T> = []) => {
return (_target: any, method: string, descriptor: TypedPropertyDescriptor<any>): TypedPropertyDescriptor<any> => {
const wrapper: any = (_target: any, method: string, descriptor: TypedPropertyDescriptor<any>): TypedPropertyDescriptor<any> => {
const { context, ...options } = normalizeOptions(hooks);

if (!descriptor) {
Expand All @@ -29,4 +34,14 @@ export const hookDecorator = <T> (hooks: HookSettings<T> = []) => {

return descriptor;
};

function params (...args: Array<string | [string, any]>): typeof wrapper {
const { context, ...options } = normalizeOptions(hooks);
return {
...options,
context: [...context, withParams(...args)]
};
}

return Object.assign(wrapper, { params });
};
9 changes: 7 additions & 2 deletions packages/hooks/src/function.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import {
registerContextUpdater,
normalizeOptions,
collectContextUpdaters,
HookSettings
HookSettings,
withParams
} from './base';

function getOriginal (fn: any): any {
Expand Down Expand Up @@ -79,5 +80,9 @@ export const functionHooks = <F, T = any>(original: F, opts: HookSettings<T>) =>
}
}

return Object.assign(wrapper, { original, collect });
function params (...args: Array<string | [string, any]>): typeof wrapper {
return registerContextUpdater(wrapper, [withParams(...args)]);
}

return Object.assign(wrapper, { original, collect, params });
};
5 changes: 3 additions & 2 deletions packages/hooks/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@ export * from './function';
export * from './compose';
export * from './base';

export interface OriginalAddon<F> {
export interface WrapperAddon<F, T = any> {
original: F;
params: (...params: Array<string | [string, any]>) => F&((...rest: any[]) => Promise<T>);
}

// hooks(fn, hookSettings)
export function hooks<F, T = any> (
fn: F, hooks: HookSettings
): F&((...rest: any[]) => Promise<T>)&OriginalAddon<F>;
): F&((...rest: any[]) => Promise<T>)&WrapperAddon<F, T>;
// hooks(object, hookMap)
export function hooks<O> (obj: O, hookMap: HookMap): O;
// @hooks(hookSettings)
Expand Down
32 changes: 32 additions & 0 deletions packages/hooks/test/function.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,38 @@ describe('functionHooks', () => {
assert.equal(called, 1);
});

it('is chainable with .params on function', async () => {
const hook = async function (this: any, context: HookContext, next: NextFunction) {
await next();
context.result += '!';
};
const exclamation = hooks(hello, [hook]).params(['name', 'Dave']);

const result = await exclamation();

assert.equal(result, 'Hello Dave!');
});

it('is chainable with .params on object', async () => {
const hook = async function (this: any, context: HookContext, next: NextFunction) {
await next();
context.result += '!';
};
const obj = {
sayHi (name: any) {
return `Hi ${name}`;
}
};

hooks(obj, {
sayHi: hooks([hook]).params('name')
});

const result = await obj.sayHi('Dave');

assert.equal(result, 'Hi Dave!');
});

it('conserves method properties', async () => {
const TEST = Symbol('test');
const hello = (name: any) => `Hi ${name}`;
Expand Down

0 comments on commit c534827

Please sign in to comment.