aurelia-http-client
Version:
A simple, restful, message-based wrapper around XMLHttpRequest.
916 lines (708 loc) • 30.6 kB
JavaScript
'use strict';
System.register(['aurelia-path', 'aurelia-pal'], function (_export, _context) {
"use strict";
var join, buildQueryString, PLATFORM, DOM, _createClass, Headers, RequestMessage, HttpResponseMessage, mimeTypes, RequestMessageProcessor, JSONPRequestMessage, JSONPXHR, HttpRequestMessage, ErrorHttpResponseMessage, RequestBuilder, HttpClient;
function _possibleConstructorReturn(self, call) {
if (!self) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return call && (typeof call === "object" || typeof call === "function") ? call : self;
}
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
enumerable: false,
writable: true,
configurable: true
}
});
if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
}
function applyXhrTransformers(xhrTransformers, client, processor, message, xhr) {
var i = void 0;
var ii = void 0;
for (i = 0, ii = xhrTransformers.length; i < ii; ++i) {
xhrTransformers[i](client, processor, message, xhr);
}
}
function timeoutTransformer(client, processor, message, xhr) {
if (message.timeout !== undefined) {
xhr.timeout = message.timeout;
}
}
_export('timeoutTransformer', timeoutTransformer);
function callbackParameterNameTransformer(client, processor, message, xhr) {
if (message.callbackParameterName !== undefined) {
xhr.callbackParameterName = message.callbackParameterName;
}
}
_export('callbackParameterNameTransformer', callbackParameterNameTransformer);
function credentialsTransformer(client, processor, message, xhr) {
if (message.withCredentials !== undefined) {
xhr.withCredentials = message.withCredentials;
}
}
_export('credentialsTransformer', credentialsTransformer);
function progressTransformer(client, processor, message, xhr) {
if (message.progressCallback) {
xhr.upload.onprogress = message.progressCallback;
}
}
_export('progressTransformer', progressTransformer);
function downloadProgressTransformer(client, processor, message, xhr) {
if (message.downloadProgressCallback) {
xhr.onprogress = message.downloadProgressCallback;
}
}
_export('downloadProgressTransformer', downloadProgressTransformer);
function responseTypeTransformer(client, processor, message, xhr) {
var responseType = message.responseType;
if (responseType === 'json') {
responseType = 'text';
}
xhr.responseType = responseType;
}
_export('responseTypeTransformer', responseTypeTransformer);
function headerTransformer(client, processor, message, xhr) {
message.headers.configureXHR(xhr);
}
_export('headerTransformer', headerTransformer);
function contentTransformer(client, processor, message, xhr) {
if (message.skipContentProcessing) {
return;
}
if (PLATFORM.global.FormData && message.content instanceof FormData) {
return;
}
if (PLATFORM.global.Blob && message.content instanceof Blob) {
return;
}
if (PLATFORM.global.ArrayBuffer && message.content instanceof ArrayBuffer) {
return;
}
if (message.content instanceof Document) {
return;
}
if (typeof message.content === 'string') {
return;
}
if (message.content === null || message.content === undefined) {
return;
}
message.content = JSON.stringify(message.content, message.replacer);
if (!message.headers.has('Content-Type')) {
message.headers.add('Content-Type', 'application/json');
}
}
_export('contentTransformer', contentTransformer);
function createJSONPRequestMessageProcessor() {
return new RequestMessageProcessor(JSONPXHR, [timeoutTransformer, callbackParameterNameTransformer]);
}
_export('createJSONPRequestMessageProcessor', createJSONPRequestMessageProcessor);
function createHttpRequestMessageProcessor() {
return new RequestMessageProcessor(PLATFORM.XMLHttpRequest, [timeoutTransformer, credentialsTransformer, progressTransformer, downloadProgressTransformer, responseTypeTransformer, contentTransformer, headerTransformer]);
}
_export('createHttpRequestMessageProcessor', createHttpRequestMessageProcessor);
function trackRequestStart(client, processor) {
client.pendingRequests.push(processor);
client.isRequesting = true;
}
function trackRequestEnd(client, processor) {
var index = client.pendingRequests.indexOf(processor);
client.pendingRequests.splice(index, 1);
client.isRequesting = client.pendingRequests.length > 0;
if (!client.isRequesting) {
var evt = DOM.createCustomEvent('aurelia-http-client-requests-drained', { bubbles: true, cancelable: true });
setTimeout(function () {
return DOM.dispatchEvent(evt);
}, 1);
}
}
return {
setters: [function (_aureliaPath) {
join = _aureliaPath.join;
buildQueryString = _aureliaPath.buildQueryString;
}, function (_aureliaPal) {
PLATFORM = _aureliaPal.PLATFORM;
DOM = _aureliaPal.DOM;
}],
execute: function () {
_createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
}();
_export('Headers', Headers = function () {
function Headers() {
var headers = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
this.headers = {};
for (var _key in headers) {
this.headers[_key.toLowerCase()] = { key: _key, value: headers[_key] };
}
}
Headers.prototype.add = function add(key, value) {
this.headers[key.toLowerCase()] = { key: key, value: value };
};
Headers.prototype.get = function get(key) {
var header = this.headers[key.toLowerCase()];
return header ? header.value : undefined;
};
Headers.prototype.clear = function clear() {
this.headers = {};
};
Headers.prototype.has = function has(header) {
return this.headers.hasOwnProperty(header.toLowerCase());
};
Headers.prototype.configureXHR = function configureXHR(xhr) {
for (var name in this.headers) {
if (this.headers.hasOwnProperty(name)) {
xhr.setRequestHeader(this.headers[name].key, this.headers[name].value);
}
}
};
Headers.parse = function parse(headerStr) {
var headers = new Headers();
if (!headerStr) {
return headers;
}
var headerPairs = headerStr.split('\r\n');
for (var i = 0; i < headerPairs.length; i++) {
var headerPair = headerPairs[i];
var index = headerPair.indexOf(': ');
if (index > 0) {
var _key2 = headerPair.substring(0, index);
var val = headerPair.substring(index + 2);
headers.add(_key2, val);
}
}
return headers;
};
return Headers;
}());
_export('Headers', Headers);
_export('RequestMessage', RequestMessage = function () {
function RequestMessage(method, url, content, headers) {
this.method = method;
this.url = url;
this.content = content;
this.headers = headers || new Headers();
this.baseUrl = '';
}
RequestMessage.prototype.buildFullUrl = function buildFullUrl() {
var absoluteUrl = /^([a-z][a-z0-9+\-.]*:)?\/\//i;
var url = absoluteUrl.test(this.url) ? this.url : join(this.baseUrl, this.url);
if (this.params) {
var qs = buildQueryString(this.params, this.traditional);
url = qs ? url + (this.url.indexOf('?') < 0 ? '?' : '&') + qs : url;
}
return url;
};
return RequestMessage;
}());
_export('RequestMessage', RequestMessage);
_export('HttpResponseMessage', HttpResponseMessage = function () {
function HttpResponseMessage(requestMessage, xhr, responseType, reviver) {
this.requestMessage = requestMessage;
this.statusCode = xhr.status;
this.response = xhr.response || xhr.responseText;
this.isSuccess = xhr.status >= 200 && xhr.status < 400;
this.statusText = xhr.statusText;
this.reviver = reviver;
this.mimeType = null;
if (xhr.getAllResponseHeaders) {
this.headers = Headers.parse(xhr.getAllResponseHeaders());
} else {
this.headers = new Headers();
}
var contentType = void 0;
if (this.headers && this.headers.headers) {
contentType = this.headers.get('Content-Type');
}
if (contentType) {
this.mimeType = responseType = contentType.split(';')[0].trim();
if (mimeTypes.hasOwnProperty(this.mimeType)) responseType = mimeTypes[this.mimeType];
}
this.responseType = responseType;
}
_createClass(HttpResponseMessage, [{
key: 'content',
get: function get() {
try {
if (this._content !== undefined) {
return this._content;
}
if (this.response === undefined || this.response === null || this.response === '') {
this._content = this.response;
return this._content;
}
if (this.responseType === 'json') {
this._content = JSON.parse(this.response, this.reviver);
return this._content;
}
if (this.reviver) {
this._content = this.reviver(this.response);
return this._content;
}
this._content = this.response;
return this._content;
} catch (e) {
if (this.isSuccess) {
throw e;
}
this._content = null;
return this._content;
}
}
}]);
return HttpResponseMessage;
}());
_export('HttpResponseMessage', HttpResponseMessage);
_export('mimeTypes', mimeTypes = {
'text/html': 'html',
'text/javascript': 'js',
'application/javascript': 'js',
'text/json': 'json',
'application/json': 'json',
'application/rss+xml': 'rss',
'application/atom+xml': 'atom',
'application/xhtml+xml': 'xhtml',
'text/markdown': 'md',
'text/xml': 'xml',
'text/mathml': 'mml',
'application/xml': 'xml',
'text/yml': 'yml',
'text/csv': 'csv',
'text/css': 'css',
'text/less': 'less',
'text/stylus': 'styl',
'text/scss': 'scss',
'text/sass': 'sass',
'text/plain': 'txt'
});
_export('mimeTypes', mimeTypes);
_export('RequestMessageProcessor', RequestMessageProcessor = function () {
function RequestMessageProcessor(xhrType, xhrTransformers) {
this.XHRType = xhrType;
this.xhrTransformers = xhrTransformers;
this.isAborted = false;
}
RequestMessageProcessor.prototype.abort = function abort() {
if (this.xhr && this.xhr.readyState !== PLATFORM.XMLHttpRequest.UNSENT) {
this.xhr.abort();
}
this.isAborted = true;
};
RequestMessageProcessor.prototype.process = function process(client, requestMessage) {
var _this = this;
var promise = new Promise(function (resolve, reject) {
var rejectResponse = void 0;
if (client.rejectPromiseWithErrorObject) {
rejectResponse = function rejectResponse(resp) {
var errorResp = new ErrorHttpResponseMessage(resp);
reject(errorResp);
};
} else {
rejectResponse = function rejectResponse(resp) {
reject(resp);
};
}
var xhr = _this.xhr = new _this.XHRType();
xhr.onload = function (e) {
var response = new HttpResponseMessage(requestMessage, xhr, requestMessage.responseType, requestMessage.reviver);
if (response.isSuccess) {
resolve(response);
} else {
rejectResponse(response);
}
};
xhr.ontimeout = function (e) {
rejectResponse(new HttpResponseMessage(requestMessage, {
response: e,
status: xhr.status,
statusText: xhr.statusText
}, 'timeout'));
};
xhr.onerror = function (e) {
rejectResponse(new HttpResponseMessage(requestMessage, {
response: e,
status: xhr.status,
statusText: xhr.statusText
}, 'error'));
};
xhr.onabort = function (e) {
rejectResponse(new HttpResponseMessage(requestMessage, {
response: e,
status: xhr.status,
statusText: xhr.statusText
}, 'abort'));
};
});
return Promise.resolve(requestMessage).then(function (message) {
var processRequest = function processRequest() {
if (_this.isAborted) {
_this.xhr.abort();
} else {
_this.xhr.open(message.method, message.buildFullUrl(), true, message.user, message.password);
applyXhrTransformers(_this.xhrTransformers, client, _this, message, _this.xhr);
if (typeof message.content === 'undefined') {
_this.xhr.send();
} else {
_this.xhr.send(message.content);
}
}
return promise;
};
var chain = [[processRequest, undefined]];
var interceptors = message.interceptors || [];
interceptors.forEach(function (interceptor) {
if (interceptor.request || interceptor.requestError) {
chain.unshift([interceptor.request ? interceptor.request.bind(interceptor) : undefined, interceptor.requestError ? interceptor.requestError.bind(interceptor) : undefined]);
}
if (interceptor.response || interceptor.responseError) {
chain.push([interceptor.response ? interceptor.response.bind(interceptor) : undefined, interceptor.responseError ? interceptor.responseError.bind(interceptor) : undefined]);
}
});
var interceptorsPromise = Promise.resolve(message);
while (chain.length) {
var _interceptorsPromise;
interceptorsPromise = (_interceptorsPromise = interceptorsPromise).then.apply(_interceptorsPromise, chain.shift());
}
return interceptorsPromise;
});
};
return RequestMessageProcessor;
}());
_export('RequestMessageProcessor', RequestMessageProcessor);
_export('JSONPRequestMessage', JSONPRequestMessage = function (_RequestMessage) {
_inherits(JSONPRequestMessage, _RequestMessage);
function JSONPRequestMessage(url, callbackParameterName) {
var _this2 = _possibleConstructorReturn(this, _RequestMessage.call(this, 'JSONP', url));
_this2.responseType = 'jsonp';
_this2.callbackParameterName = callbackParameterName;
return _this2;
}
return JSONPRequestMessage;
}(RequestMessage));
_export('JSONPRequestMessage', JSONPRequestMessage);
JSONPXHR = function () {
function JSONPXHR() {
}
JSONPXHR.prototype.open = function open(method, url) {
this.method = method;
this.url = url;
this.callbackName = 'jsonp_callback_' + Math.round(100000 * Math.random());
};
JSONPXHR.prototype.send = function send() {
var _this3 = this;
var url = this.url + (this.url.indexOf('?') >= 0 ? '&' : '?') + encodeURIComponent(this.callbackParameterName) + '=' + this.callbackName;
var script = DOM.createElement('script');
script.src = url;
script.onerror = function (e) {
cleanUp();
_this3.status = 0;
_this3.onerror(new Error('error'));
};
var cleanUp = function cleanUp() {
delete PLATFORM.global[_this3.callbackName];
DOM.removeNode(script);
};
PLATFORM.global[this.callbackName] = function (data) {
cleanUp();
if (_this3.status === undefined) {
_this3.status = 200;
_this3.statusText = 'OK';
_this3.response = data;
_this3.onload(_this3);
}
};
DOM.appendNode(script);
if (this.timeout !== undefined) {
setTimeout(function () {
if (_this3.status === undefined) {
_this3.status = 0;
_this3.ontimeout(new Error('timeout'));
}
}, this.timeout);
}
};
JSONPXHR.prototype.abort = function abort() {
if (this.status === undefined) {
this.status = 0;
this.onabort(new Error('abort'));
}
};
JSONPXHR.prototype.setRequestHeader = function setRequestHeader() {};
return JSONPXHR;
}();
_export('HttpRequestMessage', HttpRequestMessage = function (_RequestMessage2) {
_inherits(HttpRequestMessage, _RequestMessage2);
function HttpRequestMessage(method, url, content, headers) {
var _this4 = _possibleConstructorReturn(this, _RequestMessage2.call(this, method, url, content, headers));
_this4.responseType = 'json';return _this4;
}
return HttpRequestMessage;
}(RequestMessage));
_export('HttpRequestMessage', HttpRequestMessage);
_export('ErrorHttpResponseMessage', ErrorHttpResponseMessage = function (_HttpResponseMessage) {
_inherits(ErrorHttpResponseMessage, _HttpResponseMessage);
function ErrorHttpResponseMessage(responseMessage) {
var _this5 = _possibleConstructorReturn(this, _HttpResponseMessage.call(this, responseMessage.requestMessage, {
response: responseMessage.response,
status: responseMessage.statusCode,
statusText: responseMessage.statusText
}, responseMessage.responseType));
_this5.name = responseMessage.responseType;
_this5.message = 'Error: ' + responseMessage.statusCode + ' Status: ' + responseMessage.statusText;
return _this5;
}
return ErrorHttpResponseMessage;
}(HttpResponseMessage));
_export('ErrorHttpResponseMessage', ErrorHttpResponseMessage);
_export('RequestBuilder', RequestBuilder = function () {
function RequestBuilder(client) {
this.client = client;
this.transformers = client.requestTransformers.slice(0);
this.useJsonp = false;
}
RequestBuilder.prototype.asDelete = function asDelete() {
return this._addTransformer(function (client, processor, message) {
message.method = 'DELETE';
});
};
RequestBuilder.prototype.asGet = function asGet() {
return this._addTransformer(function (client, processor, message) {
message.method = 'GET';
});
};
RequestBuilder.prototype.asHead = function asHead() {
return this._addTransformer(function (client, processor, message) {
message.method = 'HEAD';
});
};
RequestBuilder.prototype.asOptions = function asOptions() {
return this._addTransformer(function (client, processor, message) {
message.method = 'OPTIONS';
});
};
RequestBuilder.prototype.asPatch = function asPatch() {
return this._addTransformer(function (client, processor, message) {
message.method = 'PATCH';
});
};
RequestBuilder.prototype.asPost = function asPost() {
return this._addTransformer(function (client, processor, message) {
message.method = 'POST';
});
};
RequestBuilder.prototype.asPut = function asPut() {
return this._addTransformer(function (client, processor, message) {
message.method = 'PUT';
});
};
RequestBuilder.prototype.asJsonp = function asJsonp(callbackParameterName) {
this.useJsonp = true;
return this._addTransformer(function (client, processor, message) {
message.callbackParameterName = callbackParameterName;
});
};
RequestBuilder.prototype.withUrl = function withUrl(url) {
return this._addTransformer(function (client, processor, message) {
message.url = url;
});
};
RequestBuilder.prototype.withContent = function withContent(content) {
return this._addTransformer(function (client, processor, message) {
message.content = content;
});
};
RequestBuilder.prototype.withBaseUrl = function withBaseUrl(baseUrl) {
return this._addTransformer(function (client, processor, message) {
message.baseUrl = baseUrl;
});
};
RequestBuilder.prototype.withParams = function withParams(params, traditional) {
return this._addTransformer(function (client, processor, message) {
message.traditional = traditional;
message.params = params;
});
};
RequestBuilder.prototype.withResponseType = function withResponseType(responseType) {
return this._addTransformer(function (client, processor, message) {
message.responseType = responseType;
});
};
RequestBuilder.prototype.withTimeout = function withTimeout(timeout) {
return this._addTransformer(function (client, processor, message) {
message.timeout = timeout;
});
};
RequestBuilder.prototype.withHeader = function withHeader(key, value) {
return this._addTransformer(function (client, processor, message) {
message.headers.add(key, value);
});
};
RequestBuilder.prototype.withCredentials = function withCredentials(value) {
return this._addTransformer(function (client, processor, message) {
message.withCredentials = value;
});
};
RequestBuilder.prototype.withLogin = function withLogin(user, password) {
return this._addTransformer(function (client, processor, message) {
message.user = user;message.password = password;
});
};
RequestBuilder.prototype.withReviver = function withReviver(reviver) {
return this._addTransformer(function (client, processor, message) {
message.reviver = reviver;
});
};
RequestBuilder.prototype.withReplacer = function withReplacer(replacer) {
return this._addTransformer(function (client, processor, message) {
message.replacer = replacer;
});
};
RequestBuilder.prototype.withProgressCallback = function withProgressCallback(progressCallback) {
return this._addTransformer(function (client, processor, message) {
message.progressCallback = progressCallback;
});
};
RequestBuilder.prototype.withDownloadProgressCallback = function withDownloadProgressCallback(downloadProgressCallback) {
return this._addTransformer(function (client, processor, message) {
message.downloadProgressCallback = downloadProgressCallback;
});
};
RequestBuilder.prototype.withCallbackParameterName = function withCallbackParameterName(callbackParameterName) {
return this._addTransformer(function (client, processor, message) {
message.callbackParameterName = callbackParameterName;
});
};
RequestBuilder.prototype.withInterceptor = function withInterceptor(interceptor) {
return this._addTransformer(function (client, processor, message) {
message.interceptors = message.interceptors || [];
message.interceptors.unshift(interceptor);
});
};
RequestBuilder.prototype.skipContentProcessing = function skipContentProcessing() {
return this._addTransformer(function (client, processor, message) {
message.skipContentProcessing = true;
});
};
RequestBuilder.prototype._addTransformer = function _addTransformer(fn) {
this.transformers.push(fn);
return this;
};
RequestBuilder.addHelper = function addHelper(name, fn) {
RequestBuilder.prototype[name] = function () {
return this._addTransformer(fn.apply(this, arguments));
};
};
RequestBuilder.prototype.send = function send() {
var message = this.useJsonp ? new JSONPRequestMessage() : new HttpRequestMessage();
return this.client.send(message, this.transformers);
};
return RequestBuilder;
}());
_export('RequestBuilder', RequestBuilder);
_export('HttpClient', HttpClient = function () {
function HttpClient() {
this.isRequesting = false;
this.rejectPromiseWithErrorObject = false;
this.requestTransformers = [];
this.requestProcessorFactories = new Map();
this.requestProcessorFactories.set(HttpRequestMessage, createHttpRequestMessageProcessor);
this.requestProcessorFactories.set(JSONPRequestMessage, createJSONPRequestMessageProcessor);
this.pendingRequests = [];
}
HttpClient.prototype.configure = function configure(fn) {
var builder = new RequestBuilder(this);
fn(builder);
this.requestTransformers = builder.transformers;
return this;
};
HttpClient.prototype.createRequest = function createRequest(url) {
var builder = new RequestBuilder(this);
if (url) {
builder.withUrl(url);
}
return builder;
};
HttpClient.prototype.send = function send(requestMessage, transformers) {
var _this6 = this;
var createProcessor = this.requestProcessorFactories.get(requestMessage.constructor);
var processor = void 0;
var promise = void 0;
var i = void 0;
var ii = void 0;
if (!createProcessor) {
throw new Error('No request message processor factory for ' + requestMessage.constructor + '.');
}
processor = createProcessor();
trackRequestStart(this, processor);
transformers = transformers || this.requestTransformers;
promise = Promise.resolve(requestMessage).then(function (message) {
for (i = 0, ii = transformers.length; i < ii; ++i) {
transformers[i](_this6, processor, message);
}
return processor.process(_this6, message).then(function (response) {
trackRequestEnd(_this6, processor);
return response;
}).catch(function (response) {
trackRequestEnd(_this6, processor);
throw response;
});
});
promise.abort = promise.cancel = function () {
processor.abort();
};
return promise;
};
HttpClient.prototype.delete = function _delete(url) {
return this.createRequest(url).asDelete().send();
};
HttpClient.prototype.get = function get(url, params, traditional) {
var req = this.createRequest(url).asGet();
if (params) {
return req.withParams(params, traditional).send();
}
return req.send();
};
HttpClient.prototype.head = function head(url) {
return this.createRequest(url).asHead().send();
};
HttpClient.prototype.jsonp = function jsonp(url) {
var callbackParameterName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'jsoncallback';
return this.createRequest(url).asJsonp(callbackParameterName).send();
};
HttpClient.prototype.options = function options(url) {
return this.createRequest(url).asOptions().send();
};
HttpClient.prototype.put = function put(url, content) {
return this.createRequest(url).asPut().withContent(content).send();
};
HttpClient.prototype.patch = function patch(url, content) {
return this.createRequest(url).asPatch().withContent(content).send();
};
HttpClient.prototype.post = function post(url, content) {
return this.createRequest(url).asPost().withContent(content).send();
};
return HttpClient;
}());
_export('HttpClient', HttpClient);
}
};
});