import { encodeXml , IFormat } from '../utils' ; import { IHeadersMap , HeaderNames } from './Parser' ; see https export class Event { private _headers : IHeadersMap = { } ; private _type : string ; private _subclass : string ; private _body : string ; private _headerIndex = - 1 ; constructor ( headers , body ? ) ; constructor ( type , subclass ? ) ; constructor ( typeOrHeaders , subclassOrBody ? ) { if ( typeof typeOrHeaders === 'string' ) { this . _type = typeOrHeaders ; this . _subclass = subclassOrBody || '' ; this . _body = '' ; this . addHeader ( HeaderNames . EventName , this . _type ) ; if ( this . _subclass ) this . addHeader ( HeaderNames . EventSubclass , this . _subclass ) ; } else { this . _type = typeOrHeaders [ HeaderNames . EventName ] || '' ; this . _subclass = typeOrHeaders [ HeaderNames . EventSubclass ] || '' ; this . _body = subclassOrBody || typeOrHeaders . _body || '' ; this . _headers = typeOrHeaders ; delete this . _headers . _body ; } this . delHeader ( 'Content-Length' ) ; } get type ( ) { return this . _type ; } get body ( ) { return this . _body ; } get headers ( ) : Readonly < IHeadersMap > { return this . _headers ; } /**
     * Turns an event into colon-separated 'name: value'
     * pairs similar to a sip/email packet
     * (the way it looks on '/events plain all').
     */ serialize ( format = 'json' ) { switch ( format ) { case 'json' : { const obj = Object . assign ( { } , this . _headers ) ; if ( this . _body ) { obj [ HeaderNames . ContentLength ] = Buffer . byteLength ( this . _body , 'utf8' ) . toString ( ) ; obj . _body = this . _body ; } else { delete obj [ HeaderNames . ContentLength ] ; } return JSON . stringify ( obj , null , 4 ) ; } case 'plain' : { let output = '' ; const keys = Object . keys ( this . _headers ) ; for ( let i = 0 ; i < keys . length ; ++ i ) { const key = keys [ i ] ; if ( key === 'Content-Length' ) continue ; const value = this . _headers [ key ] ; output += `${ key }: ${ value }\n` ; } if ( this . _body ) { const bodyLen = Buffer . byteLength ( this . _body , 'utf8' ) ; output += `${ HeaderNames . ContentLength }: ${ bodyLen }\n\n` ; output += this . _body ; } return output ; } case 'xml' : { let output = '' ; const keys = Object . keys ( this . _headers ) ; output += '<event>\n' ; output += '    <headers>\n' ; for ( let i = 0 ; i < keys . length ; ++ i ) { const key = keys [ i ] ; if ( key === 'Content-Length' ) continue ; const value = this . _headers [ key ] ; const encodedValue = typeof value === 'string' ? encodeXml ( value ) : value ; output += `        <${ key }>${ encodedValue }</${ key }>\n` ; } if ( this . _body ) { const xmlEncodedBody = encodeXml ( this . _body ) ; const key = HeaderNames . ContentLength ; const value = Buffer . byteLength ( xmlEncodedBody , 'utf8' ) ; output += `        <${ key }>${ value }</${ key }>\n` ; output += '    </headers>\n' ; output += `    <body>${ xmlEncodedBody }</body>\n` ; } else { output += '    </headers>\n' ; } output += '</event>' ; return output ; } } return '' ; } /**
     * Sets the priority of an event to `priority` in case it's fired.
     */ setPriority ( priority ) { this . addHeader ( 'priority' , priority . toString ( ) ) ; } /**
     * Gets the header with the key of `name` from the event object.
     */ getHeader ( name ) { return this . _headers [ name ] || null ; } /**
     * Gets the body of the event object.
     */ getBody ( ) { return this . _body ; } /**
     * Gets the event type of the event object.
     */ getType ( ) { return this . _type ; } returns addBody ( value ) { return this . _body += value ; } /**
     * Add a header with `name` and `value` to the event object.
     * This can be called multiple times
     * for the same event object.
     */ addHeader ( name , value ) { this . _headers [ name ] = value ; } /**
     * Delete the header with key `name` from the event object.
     */ delHeader ( name ) { delete this . _headers [ name ] ; } /**
     * Sets the pointer to the first header in the event object,
     * and returns it's key name. This must be called before nextHeader is called.
     *
     * If there are no headers, then it will return `null`.
     */ firstHeader ( ) { this . _headerIndex = 0 ; const keys = Object . keys ( this . _headers ) ; if ( keys . length === 0 ) return null ; return keys [ 0 ] ; } /**
     * Moves the pointer to the next header in the event object,
     * and returns it's key name. `firstHeader` must be called
     * before this method to set the pointer. If you're already
     * on the last header when this method is called, then it will return `null`.
     */ nextHeader ( ) { if ( this . _headerIndex === - 1 ) return null ; const keys = Object . keys ( this . _headers ) ; if ( this . _headerIndex === ( keys . length - 1 ) ) { this . _headerIndex = - 1 ; return null ; } ++ this . _headerIndex ; return keys [ this . _headerIndex ] ; } }