Skip to content

Commit

Permalink
fix: request and response decorators oldFunc call miss arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaojue committed Mar 5, 2021
1 parent 802e2d1 commit e6846fa
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 8 deletions.
114 changes: 114 additions & 0 deletions example/07-plugin/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import {
Constructor,
controller,
Daruk,
DarukContext,
DarukServer,
get,
inject,
plugin,
PluginClass,
provide,
type
} from '../../src';

// type
type PromiseVoidFunc = () => Promise<void>;
type PromiseVoidArgsFunc = (...args: any[]) => Promise<void>;
type ClassFunc<
Name extends string | symbol = string | symbol,
Func extends Function = PromiseVoidArgsFunc
> = { [key in Name]: Func };

// ReflectList
class ReflectList<
T extends Object = Object,
K = any,
V = any,
P extends string | symbol = string | symbol
> {
public Append(target: T, key: K, value: V, propertyKey?: P) {
const list = this.Get(target, key);
const newList = [value].concat(list);
Reflect.defineMetadata(key, newList, target, propertyKey as string);
}

public Get(target: T, key: K, propertyKey?: P): V[] {
return Reflect.getMetadata(key, target, propertyKey as string) || [];
}
}

// ParamPlugin
const ParamReflect = new ReflectList<
any,
string,
{ index: number; name: string; type: Constructor },
'param'
>();

export default function Param(name: string, type: Constructor = String) {
return (target: any, targetKey: string, index: number) => {
ParamReflect.Append(target.constructor, targetKey, { index, name, type }, 'param');
};
}

@plugin()
class ParamPlugin implements PluginClass {
public async initPlugin(daruk: Daruk) {
const controllers: any[] = Reflect.getMetadata('daruk:controller_class', Reflect) || [];
for (const controller of controllers) {
const routeFuncs: string[] =
Reflect.getMetadata('daruk:controller_func_name', controller) || [];
for (const func of routeFuncs) {
const prototype: ClassFunc<string, PromiseVoidArgsFunc> = controller.prototype;
const params = ParamReflect.Get(controller, func, 'param');
if (params.length > 0) {
const origin = prototype[func];
prototype[func] = async function (
ctx: DarukContext,
next: PromiseVoidFunc,
...args: any[]
) {
const params = ParamReflect.Get(controller, func, 'param');
for (const { index, name, type } of params) {
args[index - 2] = new type(ctx.query[name]);
}
await origin.call(this, ctx, next, ...args);
};
}
}
}
}
}

// main
const main = async function () {
try {
const app = DarukServer();

@provide('Db')
class Db {
public async FindByName(name: string) {
return { name, address: '127.0.0.1' };
}
}

@controller()
class mainController {
@inject('Db') private Db!: Db;

@get(`find_by_name`)
@type('application/json') // 如果函数`findByName`加上`type`装饰器 无法读取第二个及以后的参数
public async findByName(ctx: DarukContext, _: any, @Param('name') name: string) {
ctx.body = await this.Db.FindByName(name);
}
}

await app.binding();
app.listen(8899);
} catch (error) {
console.log(error);
}
};

main(); // http://127.0.0.1:8899/find_by_name?name=ddkk
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "daruk",
"version": "2.3.5",
"version": "2.3.6",
"description": "a node.js web framework",
"main": "build/index.js",
"scripts": {
Expand Down
6 changes: 3 additions & 3 deletions src/decorators/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export function validate(method: method, key: string, validateFunc: validateFunc
if (is.string(ret)) ctx.validateError.push(ret);
}
// tslint:disable-next-line:no-invalid-this
await oldFunc.call(this, ctx, next);
await oldFunc.call(this, ...arguments);
await next();
};
};
Expand Down Expand Up @@ -53,7 +53,7 @@ export function required(config: { body?: string[]; query?: string[]; params?: s
check(query, config.query, 'query') ||
check(params, config.params, 'params');
// tslint:disable-next-line:no-invalid-this
await oldFunc.call(this, ctx, next);
await oldFunc.call(this, ...arguments);
await next();
};
};
Expand Down Expand Up @@ -100,7 +100,7 @@ export function typeParse(config: { body?: ParseType; query?: ParseType; params?
ctx.parseQuery = parse(config.query, ctx.query);
ctx.parseParams = parse(config.params, ctx.params);
// tslint:disable-next-line:no-invalid-this
await oldFunc.call(this, ctx, next);
await oldFunc.call(this, ...arguments);
await next();
};
};
Expand Down
8 changes: 4 additions & 4 deletions src/decorators/response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export function json() {

descriptor.value = async function jsonWrap(ctx: koa.Context, next: () => Promise<void>) {
// tslint:disable-next-line:no-invalid-this
const val = await oldFunc.call(this, ctx);
const val = await oldFunc.call(this, ...arguments);
// 确保是Object类型
ctx.body = { ...val };
await next();
Expand Down Expand Up @@ -104,7 +104,7 @@ export function type(type: string) {
const oldFunc = descriptor.value;
descriptor.value = async function typeWrap(ctx: koa.Context, next: () => Promise<void>) {
// tslint:disable-next-line:no-invalid-this
await oldFunc.call(this, ctx);
await oldFunc.call(this, ...arguments);
ctx.type = type;
await next();
};
Expand Down Expand Up @@ -137,7 +137,7 @@ export function header(key: string | { [key: string]: string }, value?: string)
const oldFunc = descriptor.value;
descriptor.value = async function headerWrap(ctx: koa.Context, next: () => Promise<void>) {
// tslint:disable-next-line:no-invalid-this
await oldFunc.call(this, ctx);
await oldFunc.call(this, ...arguments);
ctx.set(headers);
await next();
};
Expand All @@ -155,7 +155,7 @@ export function cache(callback: (cacheKey: string, shouldCacheData?: string) =>
ctx.body = cacheData;
} else {
// tslint:disable-next-line:no-invalid-this
await oldFunc.call(this, ctx);
await oldFunc.call(this, ...arguments);
await callback(cacheKey, ctx.body);
}
await next();
Expand Down

0 comments on commit e6846fa

Please sign in to comment.