import { GenericResource } from "azure-arm-resource/lib/resource/models"; import * as fs from "fs"; import { User } from "azure-graph/lib/models"; const pattern = new RegExp( "/subscriptions/([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})(/|$)" ); export function flatten(arr: T[][]): T[] { return [].concat.apply([], arr); } export function toArray(obj: T | T[]): T[] { return Array.isArray(obj) ? obj : [obj]; } export function unique(arr: T[]): T[] { function onlyUnique(value, index, self) { return self.indexOf(value) === index; } return arr.filter(onlyUnique); } export function bimap(obj: { [key: string]: any }): { [key: string]: any } { const result = {}; for (const key of Object.keys(obj)) { const value = obj[key]; result[key] = value; result[value] = key; } return Object.freeze(result); } export function memoize(instance: T): T { const memoized = {}; for (const name of Object.keys(instance)) { memoized[name] = instance[name]; } const prototype = Object.getPrototypeOf(instance); for (const name of Object.getOwnPropertyNames(prototype)) { if (name === "constructor") { continue; } const cache = {}; memoized[name] = (...args: any[]) => { const hasFunction = args.some(arg => typeof arg === "function"); if (hasFunction) { // don't cache invocations with callback parameters return instance[name].apply(memoized, args); } const key = JSON.stringify(args) || ""; const cached = cache[key]; if (cached) { return cached; } else { const result = instance[name].apply(memoized, args); if (!result) { throw new Error("Function returned null result!"); } cache[key] = result; return result; } }; } return memoized as T; } export async function readFile(path: string): Promise { return new Promise((resolve, reject) => { fs.readFile(path, { encoding: "utf8" }, (err, data) => { if (err) { reject(err); } else { resolve(data); } }); }); } export function getFileName(className: string) { return className .replace(/([a-z])([A-Z])/g, m => `${m[0]}-${m[1].toLowerCase()}`) .toLowerCase(); } export function getClassName(fileName: string) { return fileName.replace(/(-|^)([a-z])/g, m => m[1] ? m[1].toUpperCase() : m[0].toUpperCase() ); } export function isUUID(str: string): boolean { return str.match(/^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$/i) != null; } export function getSubscriptionId(resource: GenericResource): string { if (resource.id) { const m = resource.id.match(pattern); if (m && m[1]) { return m[1].toLowerCase(); } throw new Error(`Invalid resource ID: ${resource.id}`); } throw new Error("Missing resource ID!"); } export function isVM(resource: GenericResource): boolean { return resource && resource.type === "Microsoft.Compute/virtualMachines"; } export function getEmail(user: User): string | null { if (user.userType === "Member") { return user.userPrincipalName!!; } else if (user.userType === "Guest") { return user.mail!!; } else { return null; } }