UNPKG

17.1 kBJavaScriptView Raw
1System.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});