/** * Copyright 2013-2019 GenieACS Inc. * * This file is part of GenieACS. * * GenieACS is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * GenieACS is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with GenieACS. If not, see . */ import { EventEmitter } from "events"; export function generateDeviceId( deviceIdStruct: Record ): string { // Escapes everything except alphanumerics and underscore function esc(str): string { return str.replace(/[^A-Za-z0-9_]/g, (chr) => { const buf = Buffer.from(chr, "utf8"); let rep = ""; for (const b of buf) rep += "%" + b.toString(16).toUpperCase(); return rep; }); } // Guaranteeing globally unique id as defined in TR-069 if (deviceIdStruct["ProductClass"]) { return ( esc(deviceIdStruct["OUI"]) + "-" + esc(deviceIdStruct["ProductClass"]) + "-" + esc(deviceIdStruct["SerialNumber"]) ); } return esc(deviceIdStruct["OUI"]) + "-" + esc(deviceIdStruct["SerialNumber"]); } // Source: http://stackoverflow.com/a/6969486 export function escapeRegExp(str: string): string { return str.replace(/[-[\]/{}()*+?.\\^$|]/g, "\\$&"); } export function encodeTag(tag: string): string { return encodeURIComponent(tag) .replace( /[!~*'().]/g, (c) => "%" + c.charCodeAt(0).toString(16).toUpperCase() ) .replace(/0x(?=[0-9A-Z]{2})/g, "0%78") .replace(/%/g, "0x"); } export function decodeTag(tag: string): string { return decodeURIComponent(tag.replace(/0x(?=[0-9A-Z]{2})/g, "%")); } export function once( emitter: EventEmitter, event: string, timeout: number ): Promise { return new Promise((resolve, reject) => { const timer = setTimeout(() => { reject(new Error(`Event ${event} timed out after ${timeout} ms`)); }, timeout); emitter.once(event, (...args: unknown[]) => { clearTimeout(timer); resolve(args); }); }); } export function setTimeoutPromise(delay: number, ref = true): Promise { return new Promise((resolve) => { const timerId = setTimeout(resolve, delay); if (!ref) timerId.unref(); }); }