UNPKG

@lakutata/core

Version:

Lakutata Framework Core

81 lines (78 loc) 3.47 kB
import {AnySchema} from 'yup/lib/schema' import {InvalidMethodReturnException} from '../exceptions/InvalidMethodReturnException' import {InvalidMethodAcceptException} from '../exceptions/InvalidMethodAcceptException' /** * 返回方法验证装饰器 * @param {AnySchema} returnSchema * @param {{strict?: boolean, stripUnknown?: boolean}} options * @returns {(target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<(...args: any[]) => any>) => TypedPropertyDescriptor<(...args: any[]) => any>} * @constructor */ export const Return = (returnSchema: AnySchema, options: { strict?: boolean, stripUnknown?: boolean } = { strict: true, stripUnknown: true }) => { return (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<(...args: any[]) => any | Promise<any>>) => { descriptor.writable = false const originalMethod: (...args: any[]) => any | Promise<any> = descriptor.value as any returnSchema = returnSchema.label(`Method [${propertyKey}] return value`).nullable(false).required(`Method [${propertyKey}] must return ${returnSchema.type}`) descriptor.value = function (...args: any[]) { const originalMethodResult = originalMethod.apply(this, args) if (originalMethodResult instanceof Promise) { return new Promise((resolve, reject) => { return originalMethodResult.then(originalAsyncMethodResult => { try { const methodResult = returnSchema.validateSync(originalAsyncMethodResult, options) resolve(methodResult) } catch (e) { reject(new InvalidMethodReturnException((e as Error).message)) } }).catch(reject) }) } else { try { return returnSchema.validateSync(originalMethodResult, options) } catch (e) { if (target['generateException']) { throw target['generateException'](InvalidMethodReturnException, (e as Error).message) } else { throw new InvalidMethodReturnException((e as Error).message) } } } } return descriptor } } /** * 方法接收参数验证装饰器 * @param {AnySchema | AnySchema[]} argumentSchemas * @param {{strict?: boolean, stripUnknown?: boolean}} options * @returns {(target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<(...args: any[]) => any>) => TypedPropertyDescriptor<(...args: any[]) => any>} * @constructor */ export const Accept = (argumentSchemas: AnySchema | AnySchema[], options: { strict?: boolean, stripUnknown?: boolean } = { strict: false, stripUnknown: true }) => { return (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<(...args: any[]) => any | Promise<any>>) => { descriptor.writable = false const originalMethod: (...args: any[]) => any | Promise<any> = descriptor.value as any descriptor.value = function (...args: any[]) { const schemas: AnySchema[] = Array.isArray(argumentSchemas) ? argumentSchemas : [argumentSchemas] try { for (let argumentIndex = 0; argumentIndex < schemas.length; argumentIndex++) { args[argumentIndex] = schemas[argumentIndex].label(`Method [${propertyKey}] accept argument[${argumentIndex}]`).validateSync(args[argumentIndex], options) } } catch (e) { if (target['generateException']) { throw target['generateException'](InvalidMethodAcceptException, (e as Error).message) } else { throw new InvalidMethodAcceptException((e as Error).message) } } return originalMethod.apply(this, args) } return descriptor } }