UNPKG

ngx-resource-gearheart

Version:

Angular2 resource module with simple decorators. Customized by Gearheart.

473 lines (472 loc) 20.7 kB
"use strict"; 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; }