1 | System.register(['aurelia-pal'], function (exports, module) {
|
2 | 'use strict';
|
3 | var PLATFORM, DOM;
|
4 | return {
|
5 | setters: [function (module) {
|
6 | PLATFORM = module.PLATFORM;
|
7 | DOM = module.DOM;
|
8 | }],
|
9 | execute: function () {
|
10 |
|
11 | exports('json', json);
|
12 |
|
13 | function json(body, replacer) {
|
14 | return JSON.stringify((body !== undefined ? body : {}), replacer);
|
15 | }
|
16 |
|
17 | var retryStrategy = exports('retryStrategy', {
|
18 | fixed: 0,
|
19 | incremental: 1,
|
20 | exponential: 2,
|
21 | random: 3
|
22 | });
|
23 | var defaultRetryConfig = {
|
24 | maxRetries: 3,
|
25 | interval: 1000,
|
26 | strategy: retryStrategy.fixed
|
27 | };
|
28 | var RetryInterceptor = exports('RetryInterceptor', (function () {
|
29 | function RetryInterceptor(retryConfig) {
|
30 | this.retryConfig = Object.assign({}, defaultRetryConfig, retryConfig || {});
|
31 | if (this.retryConfig.strategy === retryStrategy.exponential &&
|
32 | this.retryConfig.interval <= 1000) {
|
33 | throw new Error('An interval less than or equal to 1 second is not allowed when using the exponential retry strategy');
|
34 | }
|
35 | }
|
36 | RetryInterceptor.prototype.request = function (request) {
|
37 | var $r = request;
|
38 | if (!$r.retryConfig) {
|
39 | $r.retryConfig = Object.assign({}, this.retryConfig);
|
40 | $r.retryConfig.counter = 0;
|
41 | }
|
42 | $r.retryConfig.requestClone = request.clone();
|
43 | return request;
|
44 | };
|
45 | RetryInterceptor.prototype.response = function (response, request) {
|
46 | delete request.retryConfig;
|
47 | return response;
|
48 | };
|
49 | RetryInterceptor.prototype.responseError = function (error, request, httpClient) {
|
50 | var retryConfig = request.retryConfig;
|
51 | var requestClone = retryConfig.requestClone;
|
52 | return Promise.resolve().then(function () {
|
53 | if (retryConfig.counter < retryConfig.maxRetries) {
|
54 | var result = retryConfig.doRetry ? retryConfig.doRetry(error, request) : true;
|
55 | return Promise.resolve(result).then(function (doRetry) {
|
56 | if (doRetry) {
|
57 | retryConfig.counter++;
|
58 | return new Promise(function (resolve) { return PLATFORM.global.setTimeout(resolve, calculateDelay(retryConfig) || 0); })
|
59 | .then(function () {
|
60 | var newRequest = requestClone.clone();
|
61 | if (typeof (retryConfig.beforeRetry) === 'function') {
|
62 | return retryConfig.beforeRetry(newRequest, httpClient);
|
63 | }
|
64 | return newRequest;
|
65 | })
|
66 | .then(function (newRequest) {
|
67 | return httpClient.fetch(Object.assign(newRequest, { retryConfig: retryConfig }));
|
68 | });
|
69 | }
|
70 | delete request.retryConfig;
|
71 | throw error;
|
72 | });
|
73 | }
|
74 | delete request.retryConfig;
|
75 | throw error;
|
76 | });
|
77 | };
|
78 | return RetryInterceptor;
|
79 | }()));
|
80 | function calculateDelay(retryConfig) {
|
81 | var interval = retryConfig.interval, strategy = retryConfig.strategy, minRandomInterval = retryConfig.minRandomInterval, maxRandomInterval = retryConfig.maxRandomInterval, counter = retryConfig.counter;
|
82 | if (typeof (strategy) === 'function') {
|
83 | return retryConfig.strategy(counter);
|
84 | }
|
85 | switch (strategy) {
|
86 | case (retryStrategy.fixed):
|
87 | return retryStrategies[retryStrategy.fixed](interval);
|
88 | case (retryStrategy.incremental):
|
89 | return retryStrategies[retryStrategy.incremental](counter, interval);
|
90 | case (retryStrategy.exponential):
|
91 | return retryStrategies[retryStrategy.exponential](counter, interval);
|
92 | case (retryStrategy.random):
|
93 | return retryStrategies[retryStrategy.random](counter, interval, minRandomInterval, maxRandomInterval);
|
94 | default:
|
95 | throw new Error('Unrecognized retry strategy');
|
96 | }
|
97 | }
|
98 | var retryStrategies = [
|
99 | function (interval) { return interval; },
|
100 | function (retryCount, interval) { return interval * retryCount; },
|
101 | function (retryCount, interval) { return retryCount === 1 ? interval : Math.pow(interval, retryCount) / 1000; },
|
102 | function (retryCount, interval, minRandomInterval, maxRandomInterval) {
|
103 | if (minRandomInterval === void 0) { minRandomInterval = 0; }
|
104 | if (maxRandomInterval === void 0) { maxRandomInterval = 60000; }
|
105 | return Math.random() * (maxRandomInterval - minRandomInterval) + minRandomInterval;
|
106 | }
|
107 | ];
|
108 |
|
109 | var HttpClientConfiguration = exports('HttpClientConfiguration', (function () {
|
110 | function HttpClientConfiguration() {
|
111 | this.baseUrl = '';
|
112 | this.defaults = {};
|
113 | this.interceptors = [];
|
114 | }
|
115 | HttpClientConfiguration.prototype.withBaseUrl = function (baseUrl) {
|
116 | this.baseUrl = baseUrl;
|
117 | return this;
|
118 | };
|
119 | HttpClientConfiguration.prototype.withDefaults = function (defaults) {
|
120 | this.defaults = defaults;
|
121 | return this;
|
122 | };
|
123 | HttpClientConfiguration.prototype.withInterceptor = function (interceptor) {
|
124 | this.interceptors.push(interceptor);
|
125 | return this;
|
126 | };
|
127 | HttpClientConfiguration.prototype.useStandardConfiguration = function () {
|
128 | var standardConfig = { credentials: 'same-origin' };
|
129 | Object.assign(this.defaults, standardConfig, this.defaults);
|
130 | return this.rejectErrorResponses();
|
131 | };
|
132 | HttpClientConfiguration.prototype.rejectErrorResponses = function () {
|
133 | return this.withInterceptor({ response: rejectOnError });
|
134 | };
|
135 | HttpClientConfiguration.prototype.withRetry = function (config) {
|
136 | var interceptor = new RetryInterceptor(config);
|
137 | return this.withInterceptor(interceptor);
|
138 | };
|
139 | return HttpClientConfiguration;
|
140 | }()));
|
141 | function rejectOnError(response) {
|
142 | if (!response.ok) {
|
143 | throw response;
|
144 | }
|
145 | return response;
|
146 | }
|
147 |
|
148 | var HttpClient = exports('HttpClient', (function () {
|
149 | function HttpClient() {
|
150 | this.activeRequestCount = 0;
|
151 | this.isRequesting = false;
|
152 | this.isConfigured = false;
|
153 | this.baseUrl = '';
|
154 | this.defaults = null;
|
155 | this.interceptors = [];
|
156 | if (typeof fetch === 'undefined') {
|
157 | throw new Error('HttpClient requires a Fetch API implementation, but the current environment doesn\'t support it. You may need to load a polyfill such as https://github.com/github/fetch');
|
158 | }
|
159 | }
|
160 | HttpClient.prototype.configure = function (config) {
|
161 | var normalizedConfig;
|
162 | if (typeof config === 'object') {
|
163 | normalizedConfig = { defaults: config };
|
164 | }
|
165 | else if (typeof config === 'function') {
|
166 | normalizedConfig = new HttpClientConfiguration();
|
167 | normalizedConfig.baseUrl = this.baseUrl;
|
168 | normalizedConfig.defaults = Object.assign({}, this.defaults);
|
169 | normalizedConfig.interceptors = this.interceptors;
|
170 | var c = config(normalizedConfig);
|
171 | if (HttpClientConfiguration.prototype.isPrototypeOf(c)) {
|
172 | normalizedConfig = c;
|
173 | }
|
174 | }
|
175 | else {
|
176 | throw new Error('invalid config');
|
177 | }
|
178 | var defaults = normalizedConfig.defaults;
|
179 | if (defaults && Headers.prototype.isPrototypeOf(defaults.headers)) {
|
180 | throw new Error('Default headers must be a plain object.');
|
181 | }
|
182 | var interceptors = normalizedConfig.interceptors;
|
183 | if (interceptors && interceptors.length) {
|
184 | if (interceptors.filter(function (x) { return RetryInterceptor.prototype.isPrototypeOf(x); }).length > 1) {
|
185 | throw new Error('Only one RetryInterceptor is allowed.');
|
186 | }
|
187 | var retryInterceptorIndex = interceptors.findIndex(function (x) { return RetryInterceptor.prototype.isPrototypeOf(x); });
|
188 | if (retryInterceptorIndex >= 0 && retryInterceptorIndex !== interceptors.length - 1) {
|
189 | throw new Error('The retry interceptor must be the last interceptor defined.');
|
190 | }
|
191 | }
|
192 | this.baseUrl = normalizedConfig.baseUrl;
|
193 | this.defaults = defaults;
|
194 | this.interceptors = normalizedConfig.interceptors || [];
|
195 | this.isConfigured = true;
|
196 | return this;
|
197 | };
|
198 | HttpClient.prototype.fetch = function (input, init) {
|
199 | var _this = this;
|
200 | trackRequestStart(this);
|
201 | var request = this.buildRequest(input, init);
|
202 | return processRequest(request, this.interceptors, this).then(function (result) {
|
203 | var response = null;
|
204 | if (Response.prototype.isPrototypeOf(result)) {
|
205 | response = Promise.resolve(result);
|
206 | }
|
207 | else if (Request.prototype.isPrototypeOf(result)) {
|
208 | request = result;
|
209 | response = fetch(result);
|
210 | }
|
211 | else {
|
212 | throw new Error("An invalid result was returned by the interceptor chain. Expected a Request or Response instance, but got [" + result + "]");
|
213 | }
|
214 | return processResponse(response, _this.interceptors, request, _this);
|
215 | })
|
216 | .then(function (result) {
|
217 | if (Request.prototype.isPrototypeOf(result)) {
|
218 | return _this.fetch(result);
|
219 | }
|
220 | return result;
|
221 | })
|
222 | .then(function (result) {
|
223 | trackRequestEnd(_this);
|
224 | return result;
|
225 | }, function (error) {
|
226 | trackRequestEnd(_this);
|
227 | throw error;
|
228 | });
|
229 | };
|
230 | HttpClient.prototype.buildRequest = function (input, init) {
|
231 | var defaults = this.defaults || {};
|
232 | var request;
|
233 | var body;
|
234 | var requestContentType;
|
235 | var parsedDefaultHeaders = parseHeaderValues(defaults.headers);
|
236 | if (Request.prototype.isPrototypeOf(input)) {
|
237 | request = input;
|
238 | requestContentType = new Headers(request.headers).get('Content-Type');
|
239 | }
|
240 | else {
|
241 | if (!init) {
|
242 | init = {};
|
243 | }
|
244 | body = init.body;
|
245 | var bodyObj = body ? { body: body } : null;
|
246 | var requestInit = Object.assign({}, defaults, { headers: {} }, init, bodyObj);
|
247 | requestContentType = new Headers(requestInit.headers).get('Content-Type');
|
248 | request = new Request(getRequestUrl(this.baseUrl, input), requestInit);
|
249 | }
|
250 | if (!requestContentType) {
|
251 | if (new Headers(parsedDefaultHeaders).has('content-type')) {
|
252 | request.headers.set('Content-Type', new Headers(parsedDefaultHeaders).get('content-type'));
|
253 | }
|
254 | else if (body && isJSON(body)) {
|
255 | request.headers.set('Content-Type', 'application/json');
|
256 | }
|
257 | }
|
258 | setDefaultHeaders(request.headers, parsedDefaultHeaders);
|
259 | if (body && Blob.prototype.isPrototypeOf(body) && body.type) {
|
260 | request.headers.set('Content-Type', body.type);
|
261 | }
|
262 | return request;
|
263 | };
|
264 | HttpClient.prototype.get = function (input, init) {
|
265 | return this.fetch(input, init);
|
266 | };
|
267 | HttpClient.prototype.post = function (input, body, init) {
|
268 | return callFetch(this, input, body, init, 'POST');
|
269 | };
|
270 | HttpClient.prototype.put = function (input, body, init) {
|
271 | return callFetch(this, input, body, init, 'PUT');
|
272 | };
|
273 | HttpClient.prototype.patch = function (input, body, init) {
|
274 | return callFetch(this, input, body, init, 'PATCH');
|
275 | };
|
276 | HttpClient.prototype.delete = function (input, body, init) {
|
277 | return callFetch(this, input, body, init, 'DELETE');
|
278 | };
|
279 | return HttpClient;
|
280 | }()));
|
281 | var absoluteUrlRegexp = /^([a-z][a-z0-9+\-.]*:)?\/\//i;
|
282 | function trackRequestStart(client) {
|
283 | client.isRequesting = !!(++client.activeRequestCount);
|
284 | if (client.isRequesting) {
|
285 | var evt_1 = DOM.createCustomEvent('aurelia-fetch-client-request-started', { bubbles: true, cancelable: true });
|
286 | setTimeout(function () { return DOM.dispatchEvent(evt_1); }, 1);
|
287 | }
|
288 | }
|
289 | function trackRequestEnd(client) {
|
290 | client.isRequesting = !!(--client.activeRequestCount);
|
291 | if (!client.isRequesting) {
|
292 | var evt_2 = DOM.createCustomEvent('aurelia-fetch-client-requests-drained', { bubbles: true, cancelable: true });
|
293 | setTimeout(function () { return DOM.dispatchEvent(evt_2); }, 1);
|
294 | }
|
295 | }
|
296 | function parseHeaderValues(headers) {
|
297 | var parsedHeaders = {};
|
298 | for (var name_1 in headers || {}) {
|
299 | if (headers.hasOwnProperty(name_1)) {
|
300 | parsedHeaders[name_1] = (typeof headers[name_1] === 'function') ? headers[name_1]() : headers[name_1];
|
301 | }
|
302 | }
|
303 | return parsedHeaders;
|
304 | }
|
305 | function getRequestUrl(baseUrl, url) {
|
306 | if (absoluteUrlRegexp.test(url)) {
|
307 | return url;
|
308 | }
|
309 | return (baseUrl || '') + url;
|
310 | }
|
311 | function setDefaultHeaders(headers, defaultHeaders) {
|
312 | for (var name_2 in defaultHeaders || {}) {
|
313 | if (defaultHeaders.hasOwnProperty(name_2) && !headers.has(name_2)) {
|
314 | headers.set(name_2, defaultHeaders[name_2]);
|
315 | }
|
316 | }
|
317 | }
|
318 | function processRequest(request, interceptors, http) {
|
319 | return applyInterceptors(request, interceptors, 'request', 'requestError', http);
|
320 | }
|
321 | function processResponse(response, interceptors, request, http) {
|
322 | return applyInterceptors(response, interceptors, 'response', 'responseError', request, http);
|
323 | }
|
324 | function applyInterceptors(input, interceptors, successName, errorName) {
|
325 | var interceptorArgs = [];
|
326 | for (var _i = 4; _i < arguments.length; _i++) {
|
327 | interceptorArgs[_i - 4] = arguments[_i];
|
328 | }
|
329 | return (interceptors || [])
|
330 | .reduce(function (chain, interceptor) {
|
331 | var successHandler = interceptor[successName];
|
332 | var errorHandler = interceptor[errorName];
|
333 | return chain.then(successHandler && (function (value) { return successHandler.call.apply(successHandler, [interceptor, value].concat(interceptorArgs)); }) || identity, errorHandler && (function (reason) { return errorHandler.call.apply(errorHandler, [interceptor, reason].concat(interceptorArgs)); }) || thrower);
|
334 | }, Promise.resolve(input));
|
335 | }
|
336 | function isJSON(str) {
|
337 | try {
|
338 | JSON.parse(str);
|
339 | }
|
340 | catch (err) {
|
341 | return false;
|
342 | }
|
343 | return true;
|
344 | }
|
345 | function identity(x) {
|
346 | return x;
|
347 | }
|
348 | function thrower(x) {
|
349 | throw x;
|
350 | }
|
351 | function callFetch(client, input, body, init, method) {
|
352 | if (!init) {
|
353 | init = {};
|
354 | }
|
355 | init.method = method;
|
356 | if (body) {
|
357 | init.body = body;
|
358 | }
|
359 | return client.fetch(input, init);
|
360 | }
|
361 |
|
362 | }
|
363 | };
|
364 | });
|