import { IRequest , IRequestHeader } from "@fluidframework/core-interfaces" ; /**
 * The Request Parser takes an IRequest provides parsing and sub request creation
 */ export class RequestParser implements IRequest { param url public static getPathParts ( url ) { const queryStartIndex = url . indexOf ( "?" ) ; return url . substring ( 0 , queryStartIndex < 0 ? url . length : queryStartIndex ) . split ( "/" ) . reduce < string [ ] > ( ( pv , cv ) => { if ( cv !== undefined && cv . length > 0 ) { pv . push ( decodeURIComponent ( cv ) ) ; } return pv ; } , [ ] ) ; } private requestPathParts : readonly string [ ] | undefined ; public readonly query : string ; public static create ( request ) { if ( request instanceof RequestParser ) { return request ; } return new RequestParser ( request ) ; } protected constructor ( private readonly request ) { const queryStartIndex = this . request . url . indexOf ( "?" ) ; if ( queryStartIndex >= 0 ) { this . query = this . request . url . substring ( queryStartIndex ) ; } else { this . query = "" ; } } public get url ( ) : string { return this . request . url ; } public get headers ( ) : IRequestHeader | undefined { return this . request . headers ; } /**
     * Returns the decoded path parts of the request's url
     */ public get pathParts ( ) : readonly string [ ] { if ( this . requestPathParts === undefined ) { this . requestPathParts = RequestParser . getPathParts ( this . url ) ; } return this . requestPathParts ; } param elements public isLeaf ( elements ) { return this . query === "" && this . pathParts . length === elements ; } param startingPathIndex public createSubRequest ( startingPathIndex ) { const pathLen = this . pathParts . length ; if ( startingPathIndex < 0 || startingPathIndex > pathLen ) { throw new Error ( "incorrect sub-request" ) ; } if ( startingPathIndex === pathLen && this . url . includes ( "?" ) ) { return { url : `/${ this . query }` , headers : this . headers } ; } const path = `/${ this . pathParts . slice ( startingPathIndex ) . join ( "/" ) }` ; return { url : this . query === "" ? path : `${ path }/${ this . query }` , headers : this . headers } ; } }