import { interfaces } from 'inversify' ; import { ensureAcceptContext , createProperty , PropertyOptions } from './internal' ; interface ResolveDecorator { ( serviceIdentifier ) : ( target : any , name : string , descriptor ? : any ) => any ; ( target , name , descriptor ? ) : any ; optional : ResolveOptionalDecorator ; } interface ResolveOptionalDecorator { < T > ( serviceIdentifier , defaultValue ? ) : ( target : any , name : string , descriptor ? : any ) => any ; ( target , name , descriptor ? ) : any ; } function applyResolveDecorator ( target , name , type , options ) { ensureAcceptContext ( target . constructor ) ; return createProperty ( target , name , type , options ) ; } function getDesignType ( target , name ) { if ( ! name ) { throw new Error ( 'Decorator `resolve` failed to resolve property name' ) ; } if ( ! Reflect || ! Reflect . getMetadata ) { throw new Error ( 'Decorator `resolve` without specifying service identifier requires `reflect-metadata`' ) ; } const type = Reflect . getMetadata ( 'design:type' , target , name ) ; if ( ! type ) { throw new Error ( 'Failed to discover property type, is `emitDecoratorMetadata` enabled?' ) ; } return type ; } const resolve = < ResolveDecorator > function resolve ( target , name , descriptor ? ) { if ( typeof name !== 'undefined' ) { const type = getDesignType ( target , name ) ; return applyResolveDecorator ( target , name , type , { } ) ; } else { const serviceIdentifier = target as interfaces . ServiceIdentifier < unknown > ; if ( ! serviceIdentifier ) { throw new Error ( 'Invalid property type.' ) ; } return function ( target , name , descriptor ? ) { return applyResolveDecorator ( target , name , serviceIdentifier , { } ) ; } ; } } ; resolve . optional = < ResolveOptionalDecorator > function resolveOptional < T > ( ... args ) { if ( typeof args [ 1 ] === 'string' && args . length === 3 ) { const [ target , name , descriptor ] = args ; const type = getDesignType ( target , name ) ; return applyResolveDecorator ( target , name , type , { isOptional : true } ) ; } else { const serviceIdentifier = args [ 0 ] as interfaces . ServiceIdentifier < T > ; const defaultValue = args [ 1 ] as T | undefined ; return function ( target , name , descriptor ? ) { return applyResolveDecorator ( target , name , serviceIdentifier , { isOptional : true , defaultValue } ) ; } ; } } ; export { resolve } ; export default resolve ;