import { isArray , isUndefined , negate , pickBy } from 'lodash' ; import { DECORATORS } from '../constants' ; import { METADATA_FACTORY_NAME } from '../plugin/plugin-constants' ; export function createMethodDecorator < T = any > ( metakey , metadata ) { return ( target , key , descriptor ) => { Reflect . defineMetadata ( metakey , metadata , descriptor . value ) ; return descriptor ; } ; } export function createClassDecorator < T extends Array < any > = any > ( metakey , metadata = [ ] as T ) { return ( target ) => { const prevValue = Reflect . getMetadata ( metakey , target ) || [ ] ; Reflect . defineMetadata ( metakey , [ ... prevValue , ... metadata ] , target ) ; return target ; } ; } export function createPropertyDecorator < T extends Record < string , any > = any > ( metakey , metadata , overrideExisting = true ) { return ( target , propertyKey ) => { const properties = Reflect . getMetadata ( DECORATORS . API_MODEL_PROPERTIES_ARRAY , target ) || [ ] ; const key = `:${ propertyKey }` ; if ( ! properties . includes ( key ) ) { Reflect . defineMetadata ( DECORATORS . API_MODEL_PROPERTIES_ARRAY , [ ... properties , `:${ propertyKey }` ] , target ) ; } const existingMetadata = Reflect . getMetadata ( metakey , target , propertyKey ) ; if ( existingMetadata ) { const newMetadata = pickBy ( metadata , negate ( isUndefined ) ) ; const metadataToSave = overrideExisting ? { ... existingMetadata , ... newMetadata } : { ... newMetadata , ... existingMetadata } ; Reflect . defineMetadata ( metakey , metadataToSave , target , propertyKey ) ; } else { const type = target ?. constructor ?. [ METADATA_FACTORY_NAME ] ?. ( ) [ propertyKey ] ?. type ?? Reflect . getMetadata ( 'design:type' , target , propertyKey ) ; Reflect . defineMetadata ( metakey , { type , ... pickBy ( metadata , negate ( isUndefined ) ) } , target , propertyKey ) ; } } ; } export function createMixedDecorator < T = any > ( metakey , metadata ) { return ( target , key ? , descriptor ? ) : any => { if ( descriptor ) { Reflect . defineMetadata ( metakey , metadata , descriptor . value ) ; return descriptor ; } Reflect . defineMetadata ( metakey , metadata , target ) ; return target ; } ; } export function createParamDecorator < T extends Record < string , any > = any > ( metadata , initial ) { return ( target , key , descriptor ) => { const parameters = Reflect . getMetadata ( DECORATORS . API_PARAMETERS , descriptor . value ) || [ ] ; Reflect . defineMetadata ( DECORATORS . API_PARAMETERS , [ ... parameters , { ... initial , ... pickBy ( metadata , negate ( isUndefined ) ) } ] , descriptor . value ) ; return descriptor ; } ; } export function getTypeIsArrayTuple ( input , isArrayFlag ) { if ( ! input ) { return [ input as undefined , isArrayFlag ] ; } if ( isArrayFlag ) { return [ input as Function , isArrayFlag ] ; } const isInputArray = isArray ( input ) ; const type = isInputArray ? input [ 0 ] : input ; return [ type , isInputArray ] ; }