From 33d364dd0fad9fab02c6f6ff1f1f247035341989 Mon Sep 17 00:00:00 2001 From: Matthew James Davis Date: Sat, 28 Apr 2018 17:25:49 +0900 Subject: [PATCH] feat(http-client): Expose buildRequest helper API buildRequest was a private method. This commit makes it a public method that developers can use to build a `Request` object. This is particularly useful when returning a `Request` from a response interceptor. --- src/http-client.js | 71 ++++++++++++++++++++-------------------- test/http-client.spec.js | 14 ++++++-- 2 files changed, 47 insertions(+), 38 deletions(-) diff --git a/src/http-client.js b/src/http-client.js index 3c8a498..08cc51a 100644 --- a/src/http-client.js +++ b/src/http-client.js @@ -104,7 +104,7 @@ export class HttpClient { fetch(input: Request|string, init?: RequestInit): Promise { this::trackRequestStart(); - let request = this::buildRequest(input, init, this.defaults); + let request = this.buildRequest(input, init); return processRequest(request, this.interceptors) .then(result => { let response = null; @@ -122,13 +122,46 @@ export class HttpClient { }) .then(result => { if (Request.prototype.isPrototypeOf(result)) { - debugger; return this.fetch(result); } this::trackRequestEnd(); return result; }); } + + buildRequest(input: string, init: RequestInit): Request { + let defaults = this.defaults || {}; + let request; + let body; + let requestContentType; + + let parsedDefaultHeaders = parseHeaderValues(defaults.headers); + if (Request.prototype.isPrototypeOf(input)) { + request = input; + requestContentType = new Headers(request.headers).get('Content-Type'); + } else { + init || (init = {}); + body = init.body; + let bodyObj = body ? { body } : null; + let requestInit = Object.assign({}, defaults, { headers: {} }, init, bodyObj); + requestContentType = new Headers(requestInit.headers).get('Content-Type'); + request = new Request(getRequestUrl(this.baseUrl, input), requestInit); + } + if (!requestContentType) { + if (new Headers(parsedDefaultHeaders).has('content-type')) { + request.headers.set('Content-Type', new Headers(parsedDefaultHeaders).get('content-type')); + } else if (body && isJSON(body)) { + request.headers.set('Content-Type', 'application/json'); + } + } + setDefaultHeaders(request.headers, parsedDefaultHeaders); + if (body && Blob.prototype.isPrototypeOf(body) && body.type) { + // work around bug in IE & Edge where the Blob type is ignored in the request + // https://connect.microsoft.com/IE/feedback/details/2136163 + request.headers.set('Content-Type', body.type); + } + return request; + } } const absoluteUrlRegexp = /^([a-z][a-z0-9+\-.]*:)?\/\//i; @@ -157,40 +190,6 @@ function parseHeaderValues(headers) { return parsedHeaders; } -function buildRequest(input, init) { - let defaults = this.defaults || {}; - let request; - let body; - let requestContentType; - - let parsedDefaultHeaders = parseHeaderValues(defaults.headers); - if (Request.prototype.isPrototypeOf(input)) { - request = input; - requestContentType = new Headers(request.headers).get('Content-Type'); - } else { - init || (init = {}); - body = init.body; - let bodyObj = body ? { body } : null; - let requestInit = Object.assign({}, defaults, { headers: {} }, init, bodyObj); - requestContentType = new Headers(requestInit.headers).get('Content-Type'); - request = new Request(getRequestUrl(this.baseUrl, input), requestInit); - } - if (!requestContentType) { - if (new Headers(parsedDefaultHeaders).has('content-type')) { - request.headers.set('Content-Type', new Headers(parsedDefaultHeaders).get('content-type')); - } else if (body && isJSON(body)) { - request.headers.set('Content-Type', 'application/json'); - } - } - setDefaultHeaders(request.headers, parsedDefaultHeaders); - if (body && Blob.prototype.isPrototypeOf(body) && body.type) { - // work around bug in IE & Edge where the Blob type is ignored in the request - // https://connect.microsoft.com/IE/feedback/details/2136163 - request.headers.set('Content-Type', body.type); - } - return request; -} - function getRequestUrl(baseUrl, url) { if (absoluteUrlRegexp.test(url)) { return url; diff --git a/test/http-client.spec.js b/test/http-client.spec.js index 4a7aa62..e95b98a 100644 --- a/test/http-client.spec.js +++ b/test/http-client.spec.js @@ -1,6 +1,6 @@ import 'aurelia-polyfills'; import {json} from '../src/util'; -import {HttpClient} from '../src/http-client'; +import {HttpClient, buildRequest} from '../src/http-client'; import {HttpClientConfiguration} from '../src/http-client-configuration'; describe('HttpClient', () => { @@ -274,7 +274,17 @@ describe('HttpClient', () => { const path = 'retry'; let retry = 3; fetch.and.returnValue(Promise.reject(new Response(null, { status: 500 }))); - let interceptor = { response(r) { return r; }, responseError(r) { if (retry--) { return new Request(path) } else { throw r; } } }; + let interceptor = { + response(r) { return r; }, + responseError(r) { + if (retry--) { + let request = client.buildRequest(path); + return request; + } else { + throw r; + } + } + }; spyOn(interceptor, 'response').and.callThrough(); spyOn(interceptor, 'responseError').and.callThrough();