import { Enum as EnumNS } from './ServerStateEnum' ; import AbstractEnum = EnumNS . AbstractEnum ; import { Param as ParamNS } from './ParamSignature' ; import IParamSignature = ParamNS . IParamSignature ; /**
 *
 */ export namespace Protocol { /**
     *
     */ export interface IProtocolLogic { resolve ( protocol ) : Array < IParamSignature > ; } /**
     *
     */ export abstract class AbstractProtocolLogic implements IProtocolLogic { protected fields : Array < string | AbstractEnum > ; /**
         *
         */ constructor ( ... fields ) { this . fields = fields ; } /**
         *
         */ abstract resolve ( protocol ) ; } /**
     *
     */ export class Depends extends AbstractProtocolLogic { /**
         *
         */ constructor ( dependant , dependee ) ; constructor ( ... fields ) ; constructor ( ... fields ) { super ( ... fields ) ; } /**
         * This will apply the validation only when this condition is met
         */ public if ( target , mustBe ) { let resolveRef = this . resolve ; this . resolve = ( protocol ) : Array < IParamSignature > => { for ( let param of protocol ) { if ( param . name === target && param . payload === mustBe . toString ( ) ) { return resolveRef . call ( this , protocol ) ; } } return protocol ; } ; return this ; } /**
         * This will apply the validation only when this condition is not met
         */ public ifNot ( target , cantBe ) { let resolveRef = this . resolve ; this . resolve = ( protocol ) : Array < IParamSignature > => { for ( let param of protocol ) { if ( param . name === target && param . payload === cantBe . toString ( ) ) { return protocol ; } } return resolveRef . call ( this , protocol ) ; } ; return this ; } /**
         * This will only include the field when this condition is met
         */ public mustBe ( target , mustBe ) { let resolveRef = this . resolve ; this . resolve = ( protocol ) : Array < IParamSignature > => { for ( let param of protocol ) { if ( param . name === target && param . payload === mustBe . toString ( ) ) { return resolveRef . call ( this , protocol ) ; } } return this . stripField ( protocol ) ; } ; return this ; } /**
         * This will only include the field when this condition is not met
         */ public mustNotBe ( target , cantBe ) { let resolveRef = this . resolve ; this . resolve = ( protocol ) : Array < IParamSignature > => { for ( let param of protocol ) { if ( param . name === target && ( param . payload === cantBe . toString ( ) || param . payload === null ) ) { return this . stripField ( protocol ) ; } } return resolveRef . call ( this , protocol ) ; } ; return this ; } /**
         *
         */ public resolve ( protocol ) { let valids = protocol . filter ( ( param ) => param . resolved && param . name === this . fields [ 1 ] ) ; if ( valids . length === 1 ) { return protocol ; } else { return this . stripField ( protocol ) ; } } private stripField ( protocol ) { return protocol . map ( ( param ) => { if ( param . name === this . fields [ 0 ] ) { param . payload = null ; } return param ; } ) ; } } /**
     *
     */ export class OneOf extends AbstractProtocolLogic { /**
         *
         */ constructor ( either , or ) ; constructor ( ... fields ) ; constructor ( ... fields ) { super ( ... fields ) ; } /**
         *
         */ public resolve ( protocol ) { let valids = protocol . filter ( ( param ) => param . resolved && this . fields . indexOf ( param . name ) > - 1 ) ; if ( valids . length === 1 ) { return protocol ; } return [ ] ; } } /**
     *
     */ export class Coupled extends AbstractProtocolLogic { /**
         *
         */ constructor ( partnerA , partnerB ) ; constructor ( ... fields ) ; constructor ( ... fields ) { super ( ... fields ) ; } /**
         *
         */ public resolve ( protocol ) { let valids = protocol . filter ( ( param ) => this . fields . indexOf ( param . name ) > - 1 && param . resolved === true ) ; if ( valids . length >= this . fields . length ) { return protocol ; } else { return protocol . map ( ( param ) => { if ( this . fields . indexOf ( param . name ) > - 1 ) { param . payload = null ; } return param ; } ) ; } } } }