ngx-resource-gearheart
Version:
Angular2 resource module with simple decorators. Customized by Gearheart.
473 lines (472 loc) • 20.7 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
var http_1 = require("@angular/http");
var Rx_1 = require("rxjs/Rx");
var ResourceGlobalConfig_1 = require("./ResourceGlobalConfig");
var StorageAction_1 = require("./StorageAction");
function ResourceAction(methodOptions) {
methodOptions = methodOptions || {};
if (methodOptions.method === undefined) {
methodOptions.method = http_1.RequestMethod.Get;
}
return function (target, propertyKey) {
target[propertyKey] = function () {
var _this = this;
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
var data = args.length ? args[0] : null;
var params = args.length > 1 ? args[1] : null;
var callback = args.length > 2 ? args[2] : null;
if (typeof data === 'function') {
callback = data;
data = null;
}
else if (typeof params === 'function') {
callback = params;
params = null;
}
var resourceOptions = this.getResourceOptions();
var mockRequest = ResourceGlobalConfig_1.ResourceGlobalConfig.mockResponses && resourceOptions.mock !== false && methodOptions.mock !== false && (!!methodOptions.mockCollection || !!resourceOptions.mockCollection);
var isGetRequest = methodOptions.method === http_1.RequestMethod.Get;
var ret = null;
var map = methodOptions.map ? methodOptions.map.bind(this) : this.map;
var filter = methodOptions.filter ? methodOptions.filter : this.filter;
var initObject = methodOptions.initResultObject ?
methodOptions.initResultObject.bind(this) : this.initResultObject;
if (methodOptions.isLazy) {
ret = {};
}
else {
if (methodOptions.isArray) {
ret = [];
}
else {
if (data && data.$resource === this) {
// Setting data to ret
ret = data;
data = data.toJSON ? data.toJSON() : toJSON(data);
}
else {
ret = initObject.bind(this)();
}
}
}
var mainDeferredSubscriber = null;
var mainObservable = null;
ret.$resolved = false;
ret.$observable = Rx_1.Observable.create(function (subscriber) {
mainDeferredSubscriber = subscriber;
}).flatMap(function () { return mainObservable; });
ret.$abortRequest = function () {
ret.$resolved = true;
};
ret.$resource = this;
function releaseMainDeferredSubscriber() {
if (mainDeferredSubscriber) {
mainDeferredSubscriber.next();
mainDeferredSubscriber.complete();
mainDeferredSubscriber = null;
}
}
if (!methodOptions.isLazy) {
ret.$observable = ret.$observable.publish();
ret.$observable.connect();
}
Promise.all([
Promise.resolve(methodOptions.url || this.getUrl(methodOptions)),
Promise.resolve(methodOptions.path || this.getPath(methodOptions)),
Promise.resolve(methodOptions.headers || this.getHeaders(methodOptions)),
Promise.resolve(methodOptions.params || this.getParams(methodOptions)),
Promise.resolve(methodOptions.data || this.getData(methodOptions))
])
.then(function (dataAll) {
if (ret.$resolved) {
mainObservable = Rx_1.Observable.create(function (observer) {
observer.next(null);
});
releaseMainDeferredSubscriber();
}
var url = dataAll[0] + dataAll[1];
var headers = new http_1.Headers(dataAll[2]);
var defPathParams = dataAll[3];
var usedPathParams = {};
var usedPathParamsValues = {};
if (!Array.isArray(data) || params) {
if (!Array.isArray(data)) {
data = Object.assign({}, dataAll[4], data);
}
var pathParams = url.match(/{([^}]*)}/g) || [];
var _loop_1 = function (i) {
var pathParam = pathParams[i];
var pathKey = pathParam.substr(1, pathParam.length - 2);
var isMandatory = pathKey[0] === '!';
if (isMandatory) {
pathKey = pathKey.substr(1);
}
var isGetOnly = pathKey[0] === ':';
if (isGetOnly) {
pathKey = pathKey.substr(1);
}
var value = getValueForPath(pathKey, defPathParams, params || data, usedPathParams);
if (isGetOnly && !params) {
delete data[pathKey];
}
if (isNullOrUndefined(value)) {
if (isMandatory) {
var consoleMsg_1 = "Mandatory " + pathParam + " path parameter is missing";
mainObservable = Rx_1.Observable.create(function (observer) {
observer.error(new Error(consoleMsg_1));
});
console.warn(consoleMsg_1);
releaseMainDeferredSubscriber();
return { value: void 0 };
}
url = url.substr(0, url.indexOf(pathParam));
return "break";
}
else {
usedPathParamsValues[pathKey] = value;
}
;
// Replacing in the url
url = url.replace(pathParam, value);
};
for (var i = 0; i < pathParams.length; i++) {
var state_1 = _loop_1(i);
if (typeof state_1 === "object")
return state_1.value;
if (state_1 === "break")
break;
}
}
// Removing double slashed from final url
url = url.replace(/\/\/+/g, '/');
if (url.startsWith('http')) {
url = url.replace(':/', '://');
}
// Remove trailing slash
if (typeof methodOptions.removeTrailingSlash === 'undefined') {
methodOptions.removeTrailingSlash = _this.removeTrailingSlash();
}
if (methodOptions.removeTrailingSlash) {
while (url[url.length - 1] === '/') {
url = url.substr(0, url.length - 1);
}
}
// Remove mapped params
for (var key in defPathParams) {
if (defPathParams[key][0] === '@') {
delete defPathParams[key];
}
}
// Default search params or data
var body = null;
var searchParams;
if (isGetRequest) {
// GET
searchParams = Object.assign({}, defPathParams, data);
}
else {
// NON GET
if (data) {
var _body = {};
if (methodOptions.rootNode) {
_body["" + methodOptions.rootNode] = data;
}
else {
_body = data;
}
body = JSON.stringify(_body);
}
searchParams = defPathParams;
}
// Setting search params
var search = !!methodOptions.queryEncoder ? new http_1.URLSearchParams('', new methodOptions.queryEncoder()) : new http_1.URLSearchParams();
if (!params) {
for (var key in searchParams) {
if (searchParams.hasOwnProperty(key) && !usedPathParams[key]) {
var value = searchParams[key];
appendSearchParams(search, key, value);
}
}
}
// Adding TS if needed
var tsName = methodOptions.addTimestamp || resourceOptions.addTimestamp;
if (tsName) {
if (tsName === true) {
tsName = 'ts';
}
search.append(tsName, '' + new Date().getTime());
}
// Removing Content-Type header if no body
if (!body) {
headers.delete('content-type');
}
// Creating request options
var requestOptions = new http_1.RequestOptions({
method: methodOptions.method,
headers: headers,
body: body,
url: url,
search: search,
withCredentials: methodOptions.withCredentials || resourceOptions.withCredentials
});
// Creating request object
var req = new http_1.Request(requestOptions);
req = methodOptions.requestInterceptor ?
methodOptions.requestInterceptor(req, methodOptions) :
_this.requestInterceptor(req, methodOptions);
if (!req) {
mainObservable = Rx_1.Observable.create(function (observer) {
observer.error(new Error('Request is null'));
});
console.warn('Request is null');
releaseMainDeferredSubscriber();
return;
}
var requestObservable;
if (mockRequest) {
var mockCollection = !!methodOptions.mockCollection ? methodOptions.mockCollection : { collection: resourceOptions.mockCollection };
var resp = null;
if (typeof mockCollection === 'function') {
resp = mockCollection(propertyKey, usedPathParamsValues, searchParams, JSON.parse(body), methodOptions.method);
}
else {
resp = getMockedResponse(mockCollection, usedPathParamsValues, searchParams, JSON.parse(body), methodOptions.method);
}
resp = new FakeResponse(resp);
requestObservable = Rx_1.Observable.from([resp]);
// noinspection TypeScriptValidateTypes
requestObservable = methodOptions.responseInterceptor ?
methodOptions.responseInterceptor.bind(_this)(requestObservable, req, methodOptions) :
_this.responseInterceptor(requestObservable, req, methodOptions);
}
else {
// Doing the request
requestObservable = _this._request(req, methodOptions);
}
if (methodOptions.isLazy) {
mainObservable = requestObservable;
}
else {
mainObservable = Rx_1.Observable.create(function (subscriber) {
var reqSubscr = requestObservable.subscribe(function (resp) {
if (resp !== null) {
if (methodOptions.isArray) {
// Expecting array
if (!Array.isArray(resp)) {
console.error('Returned data should be an array. Received', resp);
}
else {
ret.push.apply(ret, resp
.filter(filter)
.map(map)
.map(function (respItem) {
respItem.$resource = _this;
return setDataToObject(initObject.bind(respItem.$resource)(), respItem);
}));
}
}
else {
// Expecting object
if (Array.isArray(resp)) {
console.error('Returned data should be an object. Received', resp);
}
else {
if (filter(resp)) {
setDataToObject(ret, map(resp));
}
}
}
}
ret.$resolved = true;
subscriber.next(ret);
}, function (err) { return subscriber.error(err); }, function () {
ret.$resolved = true;
subscriber.complete();
if (callback) {
callback(ret);
}
});
ret.$abortRequest = function () {
if (ret.$resolved) {
return;
}
reqSubscr.unsubscribe();
ret.$resolved = true;
};
});
}
if (!!_this.storage && !!methodOptions.storageAction) {
mainObservable = mainObservable.do(function (resp) {
methodOptions.storageAction.bind(_this)(_this.storage, resp);
});
}
releaseMainDeferredSubscriber();
});
return ret;
};
if (!!methodOptions.storageAction && methodOptions.storageAction === StorageAction_1.StorageAction.LOAD) {
target.storageLoad = target[propertyKey];
}
;
};
}
exports.ResourceAction = ResourceAction;
function setDataToObject(ret, resp) {
if (ret.$setData) {
ret.$setData(resp);
}
else {
Object.assign(ret, resp);
}
return ret;
}
exports.setDataToObject = setDataToObject;
function appendSearchParams(search, key, value) {
/// Convert dates to ISO format string
if (value instanceof Date) {
search.append(key, value.toISOString());
return;
}
if (typeof value === 'object') {
switch (ResourceGlobalConfig_1.ResourceGlobalConfig.getParamsMappingType) {
case ResourceGlobalConfig_1.TGetParamsMappingType.Plain:
if (Array.isArray(value)) {
for (var _i = 0, value_1 = value; _i < value_1.length; _i++) {
var arr_value = value_1[_i];
search.append(key, arr_value);
}
}
else {
if (value && typeof value === 'object') {
/// Convert dates to ISO format string
if (value instanceof Date) {
value = value.toISOString();
}
else {
value = JSON.stringify(value);
}
}
search.append(key, value);
}
break;
case ResourceGlobalConfig_1.TGetParamsMappingType.Bracket:
/// Convert object and arrays to query params
for (var k in value) {
if (value.hasOwnProperty(k)) {
appendSearchParams(search, key + '[' + k + ']', value[k]);
}
}
break;
}
return;
}
search.append(key, value);
}
exports.appendSearchParams = appendSearchParams;
function getValueForPath(key, params, data, usedPathParams) {
if (!isNullOrUndefined(data[key]) && typeof data[key] !== 'object') {
usedPathParams[key] = true;
return data[key];
}
if (isNullOrUndefined(params[key])) {
return null;
}
if (params[key][0] === '@') {
return getValueForPath(params[key].substr(1), params, data, usedPathParams);
}
usedPathParams[key] = true;
return params[key];
}
function isNullOrUndefined(value) {
return value === null || value === undefined;
}
function toJSON(obj) {
var retObj = {};
for (var propName in obj) {
if (!(obj[propName] instanceof Function) && !(propName.charAt(0) === '$')) {
retObj[propName] = obj[propName];
}
}
return retObj;
}
var FakeResponse = (function () {
function FakeResponse(resp) {
var _this = this;
this.json = function () { return _this._resp; };
this._resp = resp;
}
Object.defineProperty(FakeResponse.prototype, "_body", {
get: function () {
return JSON.stringify(this._resp);
},
enumerable: true,
configurable: true
});
return FakeResponse;
}());
function getMockedResponse(collection, params, searchParams, data, requestMethod) {
if (requestMethod === http_1.RequestMethod.Get) {
if (Object.keys(params).length === 0) {
return collection.collection;
}
else {
if (!collection.lookupParams || Object.keys(collection.lookupParams).length === 0) {
var result = collection.collection;
var _loop_2 = function (key) {
if (params.hasOwnProperty(key)) {
result = result.filter(function (item) { return item[key] === params[key]; });
}
};
for (var key in params) {
_loop_2(key);
}
return !!result.length ? result[0] : null;
}
else {
return collection.collection.filter(function (itm) {
var result = true;
for (var key in collection.lookupParams) {
if (collection.lookupParams.hasOwnProperty(key)) {
result = result && params[key] === itm[collection.lookupParams[key]];
}
}
return result;
});
}
}
}
else if (requestMethod === http_1.RequestMethod.Post) {
collection.collection.push(data);
return data;
}
else if (requestMethod === http_1.RequestMethod.Put || requestMethod === http_1.RequestMethod.Patch) {
var result = collection.collection.find(function (item) {
for (var key in params) {
if (item[key] !== params[key]) {
return false;
}
}
return true;
});
if (!!result) {
Object.assign(result, data);
return result;
}
}
else if (requestMethod === http_1.RequestMethod.Delete) {
var resultIdx = collection.collection.findIndex(function (item) {
for (var key in params) {
if (item[key] !== params[key]) {
return false;
}
}
return true;
});
collection.collection.splice(resultIdx, 1);
}
return null;
}