import * as Ajv from 'ajv' ; import { Request } from 'express' ; import { ValidationError } from '../framework/types' ; export class ContentType { public readonly contentType : string = null ; public readonly mediaType : string = null ; public readonly charSet : string = null ; public readonly withoutBoundary : string = null ; public readonly isWildCard : boolean ; private constructor ( contentType ) { this . contentType = contentType ; if ( contentType ) { this . withoutBoundary = contentType . replace ( /;\s{0,}boundary.*/ , '' ) . toLowerCase ( ) ; this . mediaType = this . withoutBoundary . split ( ';' ) [ 0 ] . toLowerCase ( ) . trim ( ) ; this . charSet = this . withoutBoundary . split ( ';' ) [ 1 ] ?. toLowerCase ( ) ; this . isWildCard = RegExp ( /^[a-z]+\/\*$/ ) . test ( this . contentType ) ; if ( this . charSet ) { this . charSet = this . charSet . toLowerCase ( ) . trim ( ) ; } } } public static from ( req ) { return new ContentType ( req . headers [ 'content-type' ] ) ; } public static fromString ( type ) { return new ContentType ( type ) ; } public equivalents ( ) { if ( ! this . withoutBoundary ) return [ ] ; if ( this . charSet ) { return [ this . mediaType , `${ this . mediaType }; ${ this . charSet }` ] ; } return [ this . withoutBoundary , `${ this . mediaType }; charset=utf-8` ] ; } } param errors export function augmentAjvErrors ( errors = [ ] ) { errors . forEach ( ( e ) => { if ( e . keyword === 'enum' ) { const params = e . params ; const allowedEnumValues = params ?. allowedValues ; e . message = ! ! allowedEnumValues ? `${ e . message }: ${ allowedEnumValues . join ( ', ' ) }` : e . message ; } } ) ; return errors ; } export function ajvErrorsToValidatorError ( status , errors ) { return { status , errors : errors . map ( ( e ) => { const params = e . params ; const required = params ?. missingProperty && e . dataPath + '.' + params . missingProperty ; const additionalProperty = params ?. additionalProperty && e . dataPath + '.' + params . additionalProperty ; const path = required ?? additionalProperty ?? e . dataPath ?? e . schemaPath ; return { path , message : e . message , errorCode : `${ e . keyword }.openapi.validation` , } ; } ) , } ; } export const deprecationWarning = process . env . NODE_ENV !== 'production' ? console . warn : ( ) => { } ; param accepts param expectedTypes returns export const findResponseContent = function ( accepts , expectedTypes ) : string { const expectedTypesSet = new Set ( expectedTypes ) ; for ( const accept of accepts ) { const act = ContentType . fromString ( accept ) ; if ( act . contentType === '*/*' ) { return expectedTypes [ 0 ] ; } else if ( expectedTypesSet . has ( act . contentType ) ) { return act . contentType ; } else if ( expectedTypesSet . has ( act . mediaType ) ) { return act . mediaType ; } else if ( act . isWildCard ) { const [ type ] = act . contentType . split ( '/' , 1 ) ; for ( const expectedType of expectedTypesSet ) { if ( new RegExp ( `^${ type }\/.+$` ) . test ( expectedType ) ) { return expectedType ; } } } else { for ( const expectedType of expectedTypes ) { const ect = ContentType . fromString ( expectedType ) ; if ( ect . mediaType === act . mediaType ) { return expectedType ; } } } } return null ; } ;