export class utils { static isString(obj: any): boolean { return typeof (obj) === "string" || obj instanceof String; } static isBoolean(obj: any): boolean { return typeof (obj) === "boolean"; } static isBlob(obj: any): boolean { return obj instanceof Blob; } static isNumber(value: any): boolean { return typeof value === "number" && isFinite(value); } static isFunction(func: any): boolean { return typeof func === "function"; } static serializeToJSON(data): string { if (!utils.isString(data) && !this.isBlob(data)) { return JSON.stringify(data); } return data; } static parseStringToJson(data) { if (!data) { return null; } const number = Number(data); if (!isNaN(number)) { return number; } let result = null; try { result = JSON.parse(data); result = utils._parseDateProperties(result); } catch (e) { console.log("An unexpected error occurred while parsing the response from server: " + e.message + ". Response body was: '" + data + "'"); } return result; } static convertDateFieldToISOString(data: object): object { /* TODOSDK: when write tests for this try to use "Object.keys(obj).forEach(function(){})", Phantomjs does not recognize "for..in" operator. */ for (const obj in data) { if (data[obj] instanceof Date) { data[obj] = data[obj].toISOString(); } } return data; } static hex16() { return Math.floor((1 + Math.random()) * 0x10000).toString(16).substr(1); } static addTrailingSlash(url: string): string { url = utils.removeSlashes(url); url += "/"; return url; } static removeSlashes(url: string) { let ret = url; const lastChar = ret.substr(-1); if (lastChar == "/") ret = ret.substr(0, ret.length - 1); return ret; } static clone(from: any, to = {}, action: Function = null): any { if (!to) to = {}; for (const property in from) { if (from[property] && from[property].constructor && from[property].constructor === Object && typeof from[property] == "function") { to[property] = to[property] || {}; arguments.callee(to[property], from[property]); } else { to[property] = from[property]; } if (typeof action === "function") action(to); } return to; } private static _parseDateProperties(data) { for (const obj in data) { // TODO if (data[obj] instanceof Array || (data[obj] instanceof Object && !data[obj] instanceof Function)) this._parseDateProperties(data[obj]); else data[obj] = utils._tryFormatFieldToDate(data[obj]); } return data; } private static _tryFormatFieldToDate(date) { if ((/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*))(?:Z|(\+|-)([\d|:]*))?$/).test(date)) { date = new Date(date); } return date; } }