import {getInstanceMethods} from "../../util" import {PojoType} from "../../type/type" import AspectInterceptor from "./AspectInterceptor" import {IComponent, IDao} from "../../type/interface" import ContextContainer from "../ContextContainer" import ControllInterceptor from "./ControllerInterceptor" import TransactionInterceptor from "./TransactionInterceptor" import InstanceBuilder from "../instance/InstanceBuilder" export default class Interceptor{ private instanceBuilder!: InstanceBuilder public parse(instance: PojoType = {}): void{ if(instance){ this.interceptorMethods(instance) const {props} = instance.meta.component props.forEach((propComponent: IComponent) => { const propName: string = Object.keys(propComponent)[0] instance[propName] && this.parse(instance[propName]) }) new ControllInterceptor(instance) } } public handler(instanceBuilder: InstanceBuilder): void{ this.instanceBuilder = instanceBuilder const entrys = >ContextContainer.getResource('entrys') || [] entrys.forEach((entry: PojoType) => { this.parse(entry) }) } public interceptorMethods(instance: PojoType): void{ if(instance){ const aspectInterceptor = new AspectInterceptor(instance) const transactionInterceptor = new TransactionInterceptor(instance, this.instanceBuilder) const {ownMethods = [], prototypeMethods = []}: PojoType = getInstanceMethods(instance) const map: Map, boolean> = new Map([[ownMethods, false], [prototypeMethods, true]]) const methodss: Array> = [...map.keys()] methodss.forEach((methods) => { const isPrototype = map.get(methods) this.createProxyHandler(instance, methods, isPrototype, aspectInterceptor, transactionInterceptor) }) } } public createProxyHandler( instance: PojoType, methods: Array, isPrototype: boolean, aspectInterceptor: AspectInterceptor, transactionInterceptor: TransactionInterceptor ): void{ methods && methods.forEach((method: Function) => { const proxyHandler = { apply: async (target: any, ctx: PojoType, args: Array) => { try{ let process: any = null let {target: beforeTarget, ctx: beforeCtx, args: beforeArgs} = await aspectInterceptor.beforeHandler(target, ctx, args) let {instance, transaction = false, process: transactionProcess} = await transactionInterceptor.handler(beforeTarget, beforeCtx, beforeArgs, method) if(!transaction){ process = await Reflect.apply(beforeTarget, instance, beforeArgs) }else{ process = transactionProcess } await aspectInterceptor.afterHandler(beforeTarget, beforeCtx, beforeArgs, process) return process }catch(err){ throw err } } } if(isPrototype){ instance.__proto__[method.name] = new Proxy(method, proxyHandler) }else{ instance[method.name] = new Proxy(method, proxyHandler) } }) } }