UNPKG

apim-developer-portal1

Version:

API management developer portal

370 lines (291 loc) 10.2 kB
import { NameValuePair } from "request"; import { ArmResource } from "./contracts/armResource"; import { JwtToken } from "./contracts/jwtToken"; import { js } from "js-beautify"; export class Utils { public static getResourceName(resource: string, fullId: string, resultType: string = "name"): string { const regexp = new RegExp(`\/${resource}\/(.*)`); const matches = regexp.exec(fullId); if (matches && matches.length > 1) { switch (resultType) { case "name": return matches[1]; case "shortId": return `/${resource}/${matches[1]}`; default: throw new Error(`Unknown resultType: ${resultType}`); } } else { throw new Error("Could not parse ID."); } } public static groupBy<T>(array: T[], valueAccessor: (item: T) => string): T[][] { const grouping = array.reduce((groups, item) => { let val = valueAccessor(item); if (!val) { val = "__ungrouped__"; } groups[val] = groups[val] || []; groups[val].push(item); return groups; }, {}); return Object.keys(grouping).map(x => grouping[x]); } public static ensureLeadingSlash(url: string): string { if (!url.startsWith("/")) { url = "/" + url; } return url; } public static ensureTrailingSlash(url: string): string { if (!url.endsWith("/")) { url = url + "/"; } return url; } public static getQueryParams(queryString: string): any { const queryValues = {}; queryString.split("&").forEach((item) => { const queryParam = item.split("="); queryValues[queryParam[0]] = queryParam[1]; }); return queryValues; } public static getUrlTemplateParams(uriTemplate: string): string[] { const result = []; const matches = uriTemplate.match(/{\*?[a-zA-Z0-9_$\-]*}/gm); if (matches) { matches.forEach((match) => { if (result.indexOf(match) === -1) { result.push(match); } }); } return result; } public static formatXml(xml: string): string { const original = xml; try { let formatted = ""; const reg = /(>)(<)(\/*)/g; xml = xml.replace(reg, "$1\r\n$2$3"); let pad = 0; xml.split("\r\n").forEach((node) => { let indent = 0; if (node.match(/.+<\/\w[^>]*>$/)) { indent = 0; } else if (node.match(/^<\/\w/)) { if (pad !== 0) { pad -= 1; } } else if (node.match(/^<\w[^>]*[^\/]>.*$/)) { indent = 1; } else { indent = 0; } let padding = ""; for (let i = 0; i < pad; i++) { padding += " "; } formatted += padding + node + "\r\n"; pad += indent; }); return formatted; } catch (error) { return original; } } public static formatJson(json: string): string { const original = json; try { const formatted = js(json, { indent_size: 4 }); return formatted; } catch (error) { return original; } } /** * Formats number into string. * @param num {number} Number to be formatted. */ public static formatNumber(num: number): string { let suffix = ""; let divider = 1; if (num > 1000) { suffix = " K"; divider = 1000; } if (num > 1000 * 1000) { suffix = " M"; divider = 1000 * 1000; } if (num > 1000 * 1000 * 1000) { suffix = " G"; divider = 1000 * 1000 * 1000; } const result = Math.round(((num / divider) + Number.EPSILON) * 100) / 100; return `${result}${suffix}`; } /** * Formats number of bytes into string. * @param bytes */ public static formatBytes(bytes: number): string { let suffix = " bytes"; let divider = 1; if (bytes > 1024) { suffix = " Kb"; divider = 1024; } if (bytes > 1024 * 1024) { suffix = " Mb"; divider = 1024 * 1024; } if (bytes > 1024 * 1024 * 1024) { suffix = " Gb"; divider = 1024 * 1024 * 1024; } // const result = Math.round(((bytes / divider) + Number.EPSILON) * 100) / 100; const result = Math.floor(bytes / divider); return `${result}${suffix}`; } /** * Formats time span into string. * @param bytes */ public static formatTimespan(milliseconds: number): string { let suffix = " ms"; let divider = 1; if (milliseconds > 1000) { suffix = " s"; divider = 1000; } if (milliseconds > 1000 * 60) { suffix = " h"; divider = 1000 * 60; } return `${(milliseconds / divider).toFixed(0)}${suffix}`; } public static parseHeaderString(headerString: string): NameValuePair[] { if (!headerString) { return []; } const headers = []; const headerPairs = headerString.split("\u000d\u000a"); for (const headerPair of headerPairs) { const index = headerPair.indexOf("\u003a\u0020"); if (index > 0) { const name = headerPair.substring(0, index); const value = headerPair.substring(index + 2); const header: NameValuePair = { name: name, value: value }; headers.push(header); } } return headers; } public static addQueryParameter(uri: string, name: string, value?: string): string { uri += `${uri.indexOf("?") >= 0 ? "&" : "?"}${name}`; if (value) { uri += `=${value}`; } return uri; } public static escapeValueForODataFilter(value: string): string { value = value .replace(/\%/g, "%25") .replace(/\"/g, `"`) .replace(/\+/g, "%2B") .replace(/\//g, "%2F") .replace(/\?/g, "%3F") .replace(/#/g, "%23") .replace(/\&/g, "%26"); return value; } public static getBsonObjectId(): string { const timestamp = (new Date().getTime() / 1000 | 0).toString(16); return timestamp + "xxxxxxxxxxxxxxxx".replace(/[x]/g, () => { return (Math.random() * 16 | 0).toString(16); }).toLowerCase(); } public static parseJwt(jwtToken: string): JwtToken { const base64Url = jwtToken.split(".")[1]; const base64 = base64Url.replace("-", "+").replace("_", "/"); const decodedToken = JSON.parse(window.atob(base64)); const now = new Date(); const offset = now.getTimezoneOffset() * 60000 * 1000; if (decodedToken.exp) { decodedToken.exp = new Date(decodedToken.exp + offset); } if (decodedToken.nfb) { decodedToken.nfb = new Date(decodedToken.nfb + offset); } if (decodedToken.iat) { decodedToken.iat = new Date(decodedToken.iat + offset); } return decodedToken; } public static scrollTo(id: string): void { const e = document.getElementById(id); if (!!e && e.scrollIntoView) { e.scrollIntoView(); } } public static ensureUrlArmified(resourceUrl: string): string { const regex = /subscriptions\/.*\/resourceGroups\/.*\/providers\/microsoft.ApiManagement\/service/i; const isArmUrl = regex.test(resourceUrl); if (isArmUrl) { return resourceUrl; } const url = new URL(resourceUrl); const protocol = url.protocol; const hostname = url.hostname; const pathname = url.pathname.endsWith("/") ? url.pathname.substring(0, url.pathname.length - 1) : url.pathname; resourceUrl = `${protocol}//${hostname}/subscriptions/sid/resourceGroups/rgid/providers/Microsoft.ApiManagement/service/sid${pathname}`; return resourceUrl; } public static armifyContract(resource: string, contract: any): ArmResource { contract = Utils.clone(contract); contract.displayName = contract.name; const armifiedContract: ArmResource = { id: contract.id, name: this.getResourceName(resource, contract.id, "name"), properties: contract }; delete contract.id; delete contract.name; return armifiedContract; } /** * This is a function used to generate long date format like (Weekday, Month, Day, Year) * * @param time time string */ public static formatDateTime(time: string): string { const options = { weekday: "long", year: "numeric", month: "long", day: "numeric" }; return new Date(time).toLocaleDateString("en-US", options); } public static clone<T>(obj: T): T { return JSON.parse(JSON.stringify(obj)); } public static getUtcDateTime(): Date { const now = new Date(); const utc = new Date(now.getTime() + now.getTimezoneOffset() * 60000); return utc; } public static readFileAsByteArray(file: File): Promise<Uint8Array> { return new Promise<Uint8Array>(resolve => { const reader = new FileReader(); reader.onload = (event: any) => { resolve(event.target.result); }; reader.readAsArrayBuffer(file); }); } }