import { Schema , SchemaValidator } from '@0x/json-schemas' ; import { ValidationError as SchemaValidationError } from 'jsonschema' ; import * as _ from 'lodash' ; import { ValidationError , ValidationErrorCodes , ValidationErrorItem } from './errors' ; const schemaValidator = new SchemaValidator ( ) ; export const utils = { log : ( ... args ) => { console . log ( ... args ) ; } , validateSchema ( instance , schema ) { const validationResult = schemaValidator . validate ( instance , schema ) ; if ( _ . isEmpty ( validationResult . errors ) ) { return ; } else { const validationErrorItems = _ . map ( validationResult . errors , ( schemaValidationError ) => schemaValidationErrorToValidationErrorItem ( schemaValidationError ) ) ; throw new ValidationError ( validationErrorItems ) ; } } , async delayAsync ( ms ) { return new Promise < void > ( resolve => setTimeout ( resolve , ms ) ) ; } , async attemptAsync < T > ( fn , opts = { interval : 1000 , maxRetries : 10 } ) { let result ; let attempt = 0 ; let error ; let isSuccess = false ; while ( ! result && attempt < opts . maxRetries ) { attempt ++ ; try { result = await fn ( ) ; isSuccess = true ; error = undefined ; } catch ( err ) { error = err ; await utils . delayAsync ( opts . interval ) ; } } if ( ! isSuccess ) { throw error ; } return result as T ; } , } ; function schemaValidationErrorToValidationErrorItem ( schemaValidationError ) { if ( _ . includes ( [ 'type' , 'anyOf' , 'allOf' , 'oneOf' , 'additionalProperties' , 'minProperties' , 'maxProperties' , 'pattern' , 'format' , 'uniqueItems' , 'items' , 'dependencies' , ] , schemaValidationError . name ) ) { return { field : schemaValidationError . property , code : ValidationErrorCodes . IncorrectFormat , reason : schemaValidationError . message , } ; } else if ( _ . includes ( [ 'minimum' , 'maximum' , 'minLength' , 'maxLength' , 'minItems' , 'maxItems' , 'enum' , 'const' ] , schemaValidationError . name ) ) { return { field : schemaValidationError . property , code : ValidationErrorCodes . ValueOutOfRange , reason : schemaValidationError . message , } ; } else if ( schemaValidationError . name === 'required' ) { return { field : schemaValidationError . argument , code : ValidationErrorCodes . RequiredField , reason : schemaValidationError . message , } ; } else if ( schemaValidationError . name === 'not' ) { return { field : schemaValidationError . property , code : ValidationErrorCodes . UnsupportedOption , reason : schemaValidationError . message , } ; } else { throw new Error ( `Unknnown schema validation error name: ${ schemaValidationError . name }` ) ; } }