/// module formsjs { export class CustomValidator extends AbstractValidator { /** * @inheritDoc * @override */ public validate(value:any, formData:any, validatableAttribute:ValidatableAttribute):Array> { var promises:Array> = []; if (validatableAttribute.validators) { validatableAttribute.validators.forEach( (validatorFunction:ValidatorFunction) => { var resolution:any = validatorFunction(value, formData); // Custom validators can return 3 types of data: a Promise, a string, or a truthy/falsy value. // If a Promise is returned we must decorate it in order to ensure a reasonable failure message. // Else if a (non-empty) string is returned we should consider it a failed validation. // Lastly if a falsy value is returned we should consider it a failed validation as well. // All of the above cases should be wrapped in a Promise to be consistent with the validator interface. if (resolution instanceof Promise) { promises.push( new Promise( (resolve, reject) => { resolution.then( () => { resolve(); }, (error) => { var failureMessage = error || this.strings.customValidationFailed; failureMessage = failureMessage.replace('${value}', value); reject(failureMessage); }); })); } else if (typeof resolution === 'string' && resolution) { promises.push(Promise.reject(resolution)); } else if (!resolution) { promises.push( Promise.reject( this.strings.customValidationFailed.replace('${value}', value))); } }); } return promises; } } }