egg-aop
Advanced tools
Comparing version 0.4.2 to 0.5.0
0.5.0 / 2018-04-19 | ||
================== | ||
* refactor: aspect function params. | ||
BREAKING CHANGE: | ||
- aspect function param sign. | ||
0.4.2 / 2018-04-19 | ||
@@ -3,0 +11,0 @@ ================== |
export declare type Throwable = Error | any; | ||
export interface FunctionContext<T = any> { | ||
readonly inst: T; | ||
readonly functionName: string; | ||
args: any[]; | ||
ret: any; | ||
err: Error; | ||
} | ||
export interface AspectPoint<T = any> { | ||
before?: (inst: T, args?: any[]) => any[] | void; | ||
after?: (inst: T, ret?: any) => any | void; | ||
onError?: (inst: T, error: Error) => Throwable | void; | ||
before?: (context: FunctionContext<T>) => void; | ||
after?: (context: FunctionContext<T>) => void; | ||
error?: (context: FunctionContext<T>) => void; | ||
} | ||
@@ -7,0 +14,0 @@ export declare function aspect<T = any>(point?: AspectPoint<T>): (target: any, key: string, descriptor: any) => { |
@@ -7,9 +7,12 @@ "use strict"; | ||
} | ||
function getFinalData(target, data, func) { | ||
if (!func) { | ||
return data; | ||
} | ||
const newData = func(target, data); | ||
return newData === undefined ? data : newData; | ||
function run(func, context) { | ||
func && func(context); | ||
} | ||
function createContext(inst, fn, args) { | ||
return { | ||
functionName: fn.__name || fn.name, | ||
inst, | ||
args, | ||
}; | ||
} | ||
function funcWrapper(point, fn) { | ||
@@ -19,8 +22,15 @@ let newFn; | ||
newFn = function* (...args) { | ||
const context = createContext(this, fn, args); | ||
try { | ||
let result = yield fn.apply(this, getFinalData(this, args, point.before)); | ||
return getFinalData(this, result, point.after); | ||
run(point.before, context); | ||
context.ret = yield fn.apply(this, context.args); | ||
run(point.after, context); | ||
return context.ret; | ||
} | ||
catch (error) { | ||
throw getFinalData(this, error, point.onError); | ||
context.err = error; | ||
run(point.error, context); | ||
if (context.err) { | ||
throw context.err; | ||
} | ||
} | ||
@@ -32,22 +42,35 @@ }; | ||
newFn = function (...args) { | ||
const context = createContext(this, fn, args); | ||
try { | ||
let result = fn.apply(this, getFinalData(this, args, point.before)); | ||
if (result instanceof Promise) { | ||
result = result.then((ret) => { | ||
return getFinalData(this, ret, point.after); | ||
run(point.before, context); | ||
context.ret = fn.apply(this, context.args); | ||
if (context.ret instanceof Promise) { | ||
context.ret = context.ret.then((ret) => { | ||
context.ret = ret; | ||
run(point.after, context); | ||
return context.ret; | ||
}); | ||
if (point.onError) { | ||
result = result | ||
if (point.error) { | ||
context.ret = context.ret | ||
.catch(error => { | ||
throw getFinalData(this, error, point.onError); | ||
context.err = error; | ||
run(point.error, context); | ||
if (context.err) { | ||
throw context.err; | ||
} | ||
}); | ||
} | ||
return result; | ||
return context.ret; | ||
} | ||
else { | ||
return getFinalData(this, result, point.after); | ||
run(point.after, context); | ||
return context.ret; | ||
} | ||
} | ||
catch (error) { | ||
throw getFinalData(this, error, point.onError); | ||
context.err = error; | ||
run(point.error, context); | ||
if (context.err) { | ||
throw context.err; | ||
} | ||
} | ||
@@ -54,0 +77,0 @@ }; |
@@ -8,16 +8,28 @@ const generatorFuncPrototype = Object.getPrototypeOf(function* (): any { }); | ||
export interface FunctionContext<T = any> { | ||
readonly inst: T; | ||
readonly functionName: string; | ||
args: any[]; | ||
ret: any; | ||
err: Error; | ||
} | ||
export interface AspectPoint<T = any> { | ||
before?: (inst: T, args?: any[]) => any[] | void; | ||
after?: (inst: T, ret?: any) => any | void; | ||
onError?: (inst: T, error: Error) => Throwable | void; | ||
before?: (context: FunctionContext<T>) => void; | ||
after?: (context: FunctionContext<T>) => void; | ||
error?: (context: FunctionContext<T>) => void; | ||
} | ||
function getFinalData(target: any, data: any, func: any) { | ||
if (!func) { | ||
return data; | ||
} | ||
const newData = func(target, data); | ||
return newData === undefined ? data : newData; | ||
function run(func: any, context: FunctionContext) { | ||
func && func(context); | ||
} | ||
function createContext(inst: any, fn: Function, args: any[]) { | ||
return { | ||
functionName: (fn as any).__name || fn.name, | ||
inst, | ||
args, | ||
} as FunctionContext; | ||
} | ||
function funcWrapper(point: AspectPoint, fn: Function) { | ||
@@ -28,7 +40,14 @@ let newFn: any; | ||
newFn = function* (...args: any[]) { | ||
const context = createContext(this, fn, args); | ||
try { | ||
let result = yield fn.apply(this, getFinalData(this, args, point.before)); | ||
return getFinalData(this, result, point.after); | ||
run(point.before, context); | ||
context.ret = yield fn.apply(this, context.args); | ||
run(point.after, context); | ||
return context.ret; | ||
} catch (error) { | ||
throw getFinalData(this, error, point.onError); | ||
context.err = error; | ||
run(point.error, context); | ||
if (context.err) { | ||
throw context.err; | ||
} | ||
} | ||
@@ -39,20 +58,33 @@ }; | ||
newFn = function (...args: any[]) { | ||
const context = createContext(this, fn, args); | ||
try { | ||
let result = fn.apply(this, getFinalData(this, args, point.before)); | ||
if (result instanceof Promise) { | ||
result = result.then((ret) => { | ||
return getFinalData(this, ret, point.after); | ||
run(point.before, context); | ||
context.ret = fn.apply(this, context.args); | ||
if (context.ret instanceof Promise) { | ||
context.ret = context.ret.then((ret) => { | ||
context.ret = ret; | ||
run(point.after, context); | ||
return context.ret; | ||
}); | ||
if (point.onError) { | ||
result = (result as Promise<any>) | ||
if (point.error) { | ||
context.ret = (context.ret as Promise<any>) | ||
.catch(error => { | ||
throw getFinalData(this, error, point.onError); | ||
context.err = error; | ||
run(point.error, context); | ||
if (context.err) { | ||
throw context.err; | ||
} | ||
}); | ||
} | ||
return result; | ||
return context.ret; | ||
} else { | ||
return getFinalData(this, result, point.after); | ||
run(point.after, context); | ||
return context.ret; | ||
} | ||
} catch (error) { | ||
throw getFinalData(this, error, point.onError); | ||
context.err = error; | ||
run(point.error, context); | ||
if (context.err) { | ||
throw context.err; | ||
} | ||
} | ||
@@ -59,0 +91,0 @@ }; |
{ | ||
"name": "egg-aop", | ||
"version": "0.4.2", | ||
"version": "0.5.0", | ||
"description": "aop for egg.", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
@@ -50,7 +50,7 @@ # egg-aop | ||
// before method running | ||
before: (inst, args) => { /* log code */ }, | ||
before: (context) => { /* log code */ }, | ||
// after method running | ||
after: (inst, ret) => { /* log code */ }, | ||
after: (context) => { /* log code */ }, | ||
// when method throw error | ||
onError: (inst, err) => { /* log code */ }, | ||
onError: (context) => { /* log code */ }, | ||
}) | ||
@@ -65,2 +65,11 @@ } | ||
} | ||
/* FunctionContext type define */ | ||
export interface FunctionContext<T = any> { | ||
readonly inst: T; | ||
readonly functionName: string; | ||
args: any[]; | ||
ret: any; | ||
err: Error; | ||
} | ||
``` | ||
@@ -67,0 +76,0 @@ |
29808
803
79