import type { CompiledDefinition , CompiledPath } from './compiler' ; export interface ValidationError { where ? : string ; name ? : string ; actual : any ; expected : any ; error ? : any ; } const Undefined = ( ( ) => { } ) ( ) ; function isEmpty ( value ) { return typeof value === 'undefined' || value === '' || Object . keys ( value ) . length === 0 ; } function validate ( value , schema ) { if ( typeof schema === 'undefined' ) { return { actual : value , expected : { schema , } , } ; } const valid = schema . validator ( value ) ; if ( valid ) { return ; } const error = { actual : value , expected : { schema : schema . schema , type : schema . type , format : schema . format , } , } ; const errorDetail = ( schema . validator as any ) . error ; if ( errorDetail ) { error . error = errorDetail ; } if ( typeof error . expected . schema === 'undefined' ) { delete error . expected . schema ; } if ( typeof error . expected . type === 'undefined' ) { delete error . expected . type ; } if ( typeof error . expected . format === 'undefined' ) { delete error . expected . format ; } if ( Object . keys ( error . expected ) . length === 0 ) { error . expected = Undefined ; } return error ; } export function request ( compiledPath , method , query ? , body ? , headers ? , pathParameters ? ) { if ( typeof compiledPath === 'undefined' ) { return ; } const operation = ( compiledPath . path as any ) [ method . toLowerCase ( ) ] ; if ( typeof operation === 'undefined' ) { return ; } const parameters = operation . resolvedParameters ; const validationErrors = [ ] ; let bodyDefined = false ; if ( parameters . length === 0 ) { const error = validate ( body , { validator : isEmpty } ) ; if ( typeof error !== 'undefined' ) { error . where = 'body' ; validationErrors . push ( error ) ; } if ( typeof query !== 'undefined' && Object . keys ( query ) . length > 0 ) { Object . keys ( query ) . forEach ( ( key ) => { validationErrors . push ( { where : 'query' , name : key , actual : query [ key ] , expected : { } , } ) ; } ) ; } return validationErrors ; } parameters . forEach ( ( parameter ) => { let value ; switch ( parameter . in ) { case 'query' : value = ( query || { } ) [ parameter . name ] ; break ; case 'path' : if ( pathParameters ) { value = pathParameters [ parameter . name ] ; } else { const actual = ( compiledPath . requestPath || '' ) . match ( /[^\/]+/g ) ; const valueIndex = compiledPath . expected . indexOf ( `{${ parameter . name }}` ) ; value = actual ? actual [ valueIndex ] : Undefined ; } break ; case 'body' : value = body ; bodyDefined = true ; break ; case 'header' : value = ( headers || { } ) [ parameter . name ] ; break ; case 'formData' : value = ( body || { } ) [ parameter . name ] ; bodyDefined = true ; break ; default : } const error = validate ( value , parameter ) ; if ( typeof error !== 'undefined' ) { error . where = parameter . in ; validationErrors . push ( error ) ; } } ) ; if ( ! bodyDefined && typeof body !== 'undefined' ) { const error = validate ( body , { validator : isEmpty } ) ; if ( typeof error !== 'undefined' ) { error . where = 'body' ; validationErrors . push ( error ) ; } } return validationErrors ; } export function response ( compiledPath , method , status , body ? ) { if ( typeof compiledPath === 'undefined' ) { return { actual : 'UNDEFINED_PATH' , expected : 'PATH' , } ; } const operation = ( compiledPath . path as any ) [ method . toLowerCase ( ) ] ; let schema = operation . responses [ status ] ; if ( typeof schema === 'undefined' ) { schema = operation . responses . default ; } return validate ( body , schema ) ; }