import { DependencyDescriptor } from './dependencyDescriptor' ; import { DependencyIdentifier , IdentifierDecorator , IdentifierDecoratorSymbol } from './dependencyIdentifier' ; import { Ctor , prettyPrintIdentifier } from './dependencyItem' ; import { LookUp , Quantity } from './types' ; import { RediError } from './error' ; export const TARGET = Symbol ( '$$TARGET' ) ; export const DEPENDENCIES = Symbol ( '$$DEPENDENCIES' ) ; class DependencyDescriptorNotFoundError extends RediError { constructor ( index , target ) { const msg = `Could not find dependency registered on the ${ index + 1 } parameter of the constructor of "${ prettyPrintIdentifier ( target ) }".` ; super ( msg ) ; } } export class IdentifierUndefinedError extends RediError { constructor ( target , index ) { const msg = `It seems that you register "undefined" as dependency on the ${ index + 1 } parameter of "${ prettyPrintIdentifier ( target ) }". Please make sure that there is not cyclic dependency among your TypeScript files, or consider using "forwardRef".` ; super ( msg ) ; } } param registerTarget returns export function getDependencies < T > ( registerTarget ) { const target = registerTarget as any ; return target [ DEPENDENCIES ] || [ ] ; } export function getDependencyByIndex < T > ( registerTarget , index ) { const allDependencies = getDependencies ( registerTarget ) ; const dep = allDependencies . find ( ( descriptor ) => descriptor . paramIndex === index ) ; if ( ! dep ) { throw new DependencyDescriptorNotFoundError ( index , registerTarget ) ; } return dep ; } param registerTarget param identifier param paramIndex param quantity param lookUp export function setDependency < T , U > ( registerTarget , identifier , paramIndex , quantity = Quantity . REQUIRED , lookUp ? ) { const descriptor = { paramIndex , identifier , quantity , lookUp , } ; if ( typeof identifier === 'undefined' ) { throw new IdentifierUndefinedError ( registerTarget , paramIndex ) ; } const target = registerTarget as any ; if ( target [ TARGET ] === target ) { target [ DEPENDENCIES ] . push ( descriptor ) ; } else { target [ DEPENDENCIES ] = [ descriptor ] ; target [ TARGET ] = target ; } } const knownIdentifiers = new Set < string > ( ) ; export function createIdentifier < T > ( id ) { if ( knownIdentifiers . has ( id ) ) { throw new RediError ( `Identifier "${ id }" already exists.` ) ; } else { knownIdentifiers . add ( id ) ; } const decorator = function ( registerTarget , _key , index ) : void { setDependency ( registerTarget , decorator , index ) ; } as IdentifierDecorator < T > ; decorator . toString = ( ) => id ; decorator [ IdentifierDecoratorSymbol ] = true ; return decorator ; } export function TEST_ONLY_clearKnownIdentifiers ( ) { knownIdentifiers . clear ( ) ; }