{"version":3,"sources":["../../../packages/core/data/http.ts"],"names":[],"mappings":"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","file":"http.d.ts","sourcesContent":["import { Observable, throwError } from 'rxjs';\r\nimport { ajax, AjaxError, AjaxRequest, AjaxResponse } from 'rxjs/ajax';\r\nimport { catchError, mergeMap, switchMap } from 'rxjs/operators';\r\nimport { Cookie } from './cookie';\r\nimport { ErrorExtended } from './error-extended';\r\nimport { headerConstants, HttpStatusCode } from './http-constants';\r\n\r\n/**\r\n * The Http Retry Handler interface. Describes an object that can handle specific status codes.\r\n * the handle function takes a status code, AjaxRequest and AjaxError.\r\n * It returns an observable for new AjaxRequest to try again\r\n */\r\nexport interface HttpResponseRetryHandler {\r\n    canHandle(code: HttpStatusCode, error: AjaxError): boolean;\r\n    handle?(code: HttpStatusCode, request: AjaxRequest, error: AjaxError): Observable<AjaxRequest>;\r\n    handleNoRetry?(code: HttpStatusCode, request: AjaxRequest, error: AjaxError): Observable<void>;\r\n}\r\n\r\n/**\r\n * Retry options for an http request\r\n */\r\nexport class HttpRetryOptions {\r\n    public maxRetry = 0;\r\n    public handlers: HttpResponseRetryHandler[] = [];\r\n}\r\n\r\n/**\r\n * Set of monitors for pre and post process of ajax.\r\n */\r\nexport interface HttpMonitorSet {\r\n    name: string;\r\n    preMonitor: (request: AjaxRequest) => Observable<AjaxRequest | Error>;\r\n    successMonitor: (response: AjaxResponse<any>) => Observable<AjaxResponse<any>>;\r\n    errorMonitor: (error: any) => Observable<AjaxResponse<any>>;\r\n}\r\n\r\n/**\r\n * Enum for http method types\r\n */\r\nexport enum HttpMethod {\r\n    Get = 'GET',\r\n    Post = 'POST',\r\n    Put = 'PUT',\r\n    Delete = 'DELETE',\r\n    Patch = 'PATCH',\r\n    Head = 'HEAD',\r\n    Options = 'OPTIONS'\r\n}\r\n\r\n/**\r\n * The Http observable based class.\r\n */\r\nexport class Http {\r\n    /**\r\n     * Default ajax options must be used for CORS.\r\n     */\r\n    public static defaultHttpOptions: AjaxRequest = <AjaxRequest>{ withCredentials: true, crossDomain: true };\r\n\r\n    /**\r\n     * The collection of set of monitors.\r\n     */\r\n    private static monitorSets: HttpMonitorSet[] = [];\r\n\r\n    /**\r\n     * The default retry options.\r\n     */\r\n    public defaultRetryOptions: HttpRetryOptions = new HttpRetryOptions();\r\n\r\n    /**\r\n     * Register the set of monitors.\r\n     *\r\n     * @param monitorSet The set of monitors.\r\n     */\r\n    public static registerMonitorSet(monitorSet: HttpMonitorSet): void {\r\n        const found = Http.monitorSets.find(monitors => monitors.name === monitorSet.name);\r\n        if (found) {\r\n            return;\r\n        }\r\n\r\n        Http.monitorSets.push(monitorSet);\r\n    }\r\n\r\n    /**\r\n     * Unregister the set of monitors.\r\n     *\r\n     * @param name The name of set of monitors.\r\n     * @returns boolean true if unregistered the named set.\r\n     */\r\n    public static unregisterMonitors(name: string): boolean {\r\n        const found = Http.monitorSets.find(monitors => monitors.name === name);\r\n        if (found) {\r\n            Http.monitorSets.remove(found);\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    }\r\n\r\n    /**\r\n     * The common request method.\r\n     * Adds default responseType, contentType, Accept values if they are not already included in the request\r\n     *\r\n     * @param request the request options.\r\n     * @param options the retry options.\r\n     */\r\n    public request(request: AjaxRequest, retryOptions?: HttpRetryOptions): Observable<AjaxResponse<any>> {\r\n        if (!request) {\r\n            request = <AjaxRequest>{};\r\n        }\r\n\r\n        if (!retryOptions) {\r\n            retryOptions = this.defaultRetryOptions;\r\n        }\r\n\r\n        if (!request.headers) {\r\n            request.headers = {};\r\n        }\r\n\r\n        if (!request.responseType) {\r\n            request.responseType = 'json';\r\n        }\r\n\r\n        if (request.headers && !request.headers[headerConstants.CONTENT_TYPE]) {\r\n            (<any>request).headers[headerConstants.CONTENT_TYPE] = 'application/json; charset=utf-8';\r\n        }\r\n\r\n        // Fix for file transfer\r\n        if (request.body instanceof FormData) {\r\n            delete (<any>request).headers[headerConstants.CONTENT_TYPE];\r\n        }\r\n\r\n        if (request.method === HttpMethod.Get || request.method === HttpMethod.Delete || request.method === HttpMethod.Head) {\r\n            delete (<any>request).headers[headerConstants.CONTENT_TYPE];\r\n            request.body = undefined;\r\n        }\r\n\r\n        if (request.headers && !request.headers[headerConstants.ACCEPT]) {\r\n            (<any>request).headers[headerConstants.ACCEPT] = 'application/json, text/plain, */*';\r\n        }\r\n\r\n        if (request.headers && !request.headers[headerConstants.CROSS_SITE_REQUEST_FORGERY_TOKEN]) {\r\n            const token = Cookie.getCrossSiteRequestForgeryToken();\r\n            if (token) {\r\n                (<any>request).headers[headerConstants.CROSS_SITE_REQUEST_FORGERY_TOKEN] = token;\r\n            }\r\n        }\r\n\r\n        if (retryOptions.maxRetry > 0 && retryOptions.handlers && retryOptions.handlers.length > 0) {\r\n            return this.requestWithHandlers(request, retryOptions);\r\n        }\r\n\r\n        return this.monitorAjax(request);\r\n    }\r\n\r\n    /**\r\n     * Performs a request without modification.\r\n     * If the result is an error, we will retry with the handlers in options\r\n     *\r\n     * @param request the request options.\r\n     * @param options the retry options.\r\n     * @param count the current iteration of the retry cycle.\r\n     */\r\n    private requestWithHandlers(request: AjaxRequest, retryOptions: HttpRetryOptions, count: number = 0): Observable<AjaxResponse<any>> {\r\n        return this.monitorAjax(request)\r\n            .pipe(\r\n                catchError((error: AjaxError, caught: any) => {\r\n                    // original request is replaced with latest instance. it must take current error request.\r\n                    const caughtRequest = caught.source.request || (caught.source.source && caught.source.source.value) || request;\r\n                    if (++count > retryOptions.maxRetry) {\r\n                        return throwError(() => error);\r\n                    }\r\n\r\n                    const handler = retryOptions.handlers.find(handler2 => handler2.canHandle(error.status, error));\r\n                    if (handler) {\r\n                        if (handler.handleNoRetry) {\r\n                            return handler.handleNoRetry(error.status, caughtRequest, error)\r\n                                .pipe(mergeMap(() => throwError(() => error)));\r\n                        } else if (handler.handle) {\r\n                            return handler.handle(error.status, caughtRequest, error)\r\n                                .pipe(\r\n                                    catchError(handlerError => {\r\n                                        // if the handler throws, return the original error with an inserted\r\n                                        // property for the handler error\r\n                                        error['handlerError'] = handlerError;\r\n                                        return throwError(() => error);\r\n                                    }),\r\n                                    switchMap(() => this.monitorAjax(caughtRequest)));\r\n                        }\r\n                    }\r\n\r\n                    return throwError(() => error);\r\n                }));\r\n    }\r\n\r\n    /**\r\n     * Performs a request with `get` http method.\r\n     *\r\n     * @param url the url.\r\n     * @param request the request options.\r\n     * @param options the retry options.\r\n     */\r\n    public get(url: string, request?: AjaxRequest, options?: HttpRetryOptions): Observable<AjaxResponse<any>> {\r\n        request = request ? request : <AjaxRequest>{};\r\n        request.url = url;\r\n        request.method = HttpMethod.Get;\r\n        return this.request(request, options);\r\n    }\r\n\r\n    /**\r\n     * Performs a request with `post` http method.\r\n     *\r\n     * @param url the url.\r\n     * @param body the body content.\r\n     * @param request the request options.\r\n     * @param options the retry options.\r\n     */\r\n    public post(url: string, body: any, request?: AjaxRequest, options?: HttpRetryOptions): Observable<AjaxResponse<any>> {\r\n        request = request ? request : <AjaxRequest>{};\r\n        request.url = url;\r\n        request.method = HttpMethod.Post;\r\n        request.body = body;\r\n        return this.request(request, options);\r\n    }\r\n\r\n    /**\r\n     * Performs a request with `put` http method.\r\n     *\r\n     * @param url the url.\r\n     * @param body the body content.\r\n     * @param request the request options.\r\n     * @param options the retry options.\r\n     */\r\n    public put(url: string, body: any, request?: AjaxRequest, options?: HttpRetryOptions): Observable<AjaxResponse<any>> {\r\n        request = request ? request : <AjaxRequest>{};\r\n        request.url = url;\r\n        request.method = HttpMethod.Put;\r\n        request.body = body;\r\n        return this.request(request, options);\r\n    }\r\n\r\n    /**\r\n     * Performs a request with `delete` http method.\r\n     *\r\n     * @param url the url.\r\n     * @param request the request options.\r\n     * @param options the retry options.\r\n     */\r\n    public delete(url: string, request?: AjaxRequest, options?: HttpRetryOptions): Observable<AjaxResponse<any>> {\r\n        request = request ? request : <AjaxRequest>{};\r\n        request.url = url;\r\n        request.method = HttpMethod.Delete;\r\n        return this.request(request, options);\r\n    }\r\n\r\n    /**\r\n     * Performs a request with `patch` http method.\r\n     *\r\n     * @param url the url.\r\n     * @param body the body content.\r\n     * @param request the request options.\r\n     * @param options the retry options.\r\n     */\r\n    public patch(url: string, body: any, request?: AjaxRequest, options?: HttpRetryOptions): Observable<AjaxResponse<any>> {\r\n        request = request ? request : <AjaxRequest>{};\r\n        request.url = url;\r\n        request.method = HttpMethod.Patch;\r\n        request.body = body;\r\n        return this.request(request, options);\r\n    }\r\n\r\n    /**\r\n     * Performs a request with `head` http method.\r\n     *\r\n     * @param url the url.\r\n     * @param request the request options.\r\n     * @param options the retry options.\r\n     */\r\n    public head(url: string, request?: AjaxRequest, options?: HttpRetryOptions): Observable<AjaxResponse<any>> {\r\n        request = request ? request : <AjaxRequest>{};\r\n        request.url = url;\r\n        request.method = HttpMethod.Head;\r\n        return this.request(request, options);\r\n    }\r\n\r\n    /**\r\n     * Performs a request with `options` http method.\r\n     *\r\n     * @param url the url.\r\n     * @param request the request options.\r\n     * @param options the retry options.\r\n     */\r\n    public options(url: string, request?: AjaxRequest, options?: HttpRetryOptions): Observable<AjaxResponse<any>> {\r\n        request = request ? request : <AjaxRequest>{};\r\n        request.url = url;\r\n        request.method = HttpMethod.Options;\r\n        return this.request(request, options);\r\n    }\r\n\r\n    /**\r\n     * Performs a request with 'get' http method with cache control.\r\n     *\r\n     * @param url the uri for GET call.\r\n     * @return the observable for GET result data.\r\n     */\r\n    public getNoCache(\r\n        url: string, noCache = true, responseType: XMLHttpRequestResponseType = '', withCredentials = true): Observable<AjaxResponse<any>> {\r\n        const publish = new Observable<AjaxResponse<any>>(observer => {\r\n            const request = new XMLHttpRequest();\r\n            const handler = () => {\r\n                if (request.readyState === XMLHttpRequest.DONE) {\r\n                    if (request.status === 200) {\r\n                        try {\r\n                            let response: string;\r\n                            if (responseType === '') {\r\n                                response = JSON.parse(request.response);\r\n                            } else {\r\n                                response = request.response;\r\n                            }\r\n\r\n                            observer.next(<AjaxResponse<any>>{\r\n                                status: request.status,\r\n                                response\r\n                            });\r\n                            observer.complete();\r\n                        } catch (e) {\r\n                            observer.error(e);\r\n                        }\r\n                    } else {\r\n                        const error = new ErrorExtended<{ status: number, url: string }>(request.statusText);\r\n                        error.extendedSource = ErrorExtended.sources.getNoCache;\r\n                        error.extended = { status: request.status, url };\r\n                        observer.error(error);\r\n                    }\r\n                }\r\n            };\r\n\r\n            request.open('Get', url);\r\n            request.withCredentials = withCredentials;\r\n            request.responseType = responseType;\r\n            request.setRequestHeader(headerConstants.ACCEPT, 'application/json, text/plain, */*');\r\n\r\n            if (noCache) {\r\n                request.setRequestHeader('Cache-control', 'no-cache');\r\n            }\r\n\r\n            request.onreadystatechange = handler;\r\n            request.send();\r\n        });\r\n\r\n        return publish;\r\n    }\r\n\r\n    /**\r\n     * Performs a request with 'delete' http method without waiting for the response.\r\n     *\r\n     * @param url the uri for GET call.\r\n     */\r\n    public deleteQuick(url: string, headers: any): void {\r\n        const request = new XMLHttpRequest();\r\n        request.open('Delete', url);\r\n        request.withCredentials = true;\r\n        request.responseType = 'json';\r\n        request.setRequestHeader(headerConstants.ACCEPT, 'application/json, text/plain, */*');\r\n        request.setRequestHeader(headerConstants.CONTENT_TYPE, 'application/json; charset=utf-8');\r\n        request.setRequestHeader(headerConstants.CACHE_CONTROL, 'no-cache');\r\n\r\n        let xsrf = false;\r\n        if (headers) {\r\n            for (const key in headers) {\r\n                if (key) {\r\n                    request.setRequestHeader(key, headers[key]);\r\n                    if (key.toLowerCase() === headerConstants.CROSS_SITE_REQUEST_FORGERY_TOKEN.toLowerCase()) {\r\n                        xsrf = true;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        const token = Cookie.getCrossSiteRequestForgeryToken();\r\n        if (token && !xsrf) {\r\n            request.setRequestHeader(headerConstants.CROSS_SITE_REQUEST_FORGERY_TOKEN, token);\r\n        }\r\n\r\n        // not watching any response.\r\n        request.send();\r\n    }\r\n\r\n    private monitorAjax(request: AjaxRequest): Observable<AjaxResponse<any>> {\r\n        let monitored: (request: AjaxRequest) => Observable<AjaxResponse<any>> = ajax;\r\n        for (const monitorSet of Http.monitorSets) {\r\n            monitored = this.monitor(monitored, monitorSet);\r\n        }\r\n\r\n        return monitored(request);\r\n    }\r\n\r\n    private monitor(target: (request: AjaxRequest) => Observable<AjaxResponse<any>>, monitorSet: HttpMonitorSet): (request: AjaxRequest) => Observable<AjaxResponse<any>> {\r\n\r\n        return function (request) {\r\n            return monitorSet.preMonitor(request)\r\n                .pipe(switchMap(monitoredRequest => {\r\n                    if (monitoredRequest instanceof Error) {\r\n                        return throwError(() => monitoredRequest);\r\n                    }\r\n\r\n                    return target(monitoredRequest).pipe(\r\n                        catchError((error: AjaxError) => {\r\n                            return monitorSet.errorMonitor(error);\r\n                        }),\r\n                        switchMap(response => monitorSet.successMonitor(response))\r\n                    );\r\n                }));\r\n        };\r\n    }\r\n}\r\n"]}