TypeScript!

This commit is contained in:
Zaid Abdulla committed 2019-02-20 03:36:52 -08:00
1 parent ee8c43747e
commit 5d3c81cb23
105 files changed
+12054 -1901

No files matched your search

+193
View File
@@ -0,0 +1,193 @@
/**
* Copyright 2013-2018 Zaid Abdulla
*
* 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 <http://www.gnu.org/licenses/>.
*/
import { ParamPath } from "./types";
export const UNDEFINED_TYPE = "[object Undefined]";
export const NULL_TYPE = "[object Null]";
export const BOOLEAN_TYPE = "[object Boolean]";
export const NUMBER_TYPE = "[object Number]";
export const STRING_TYPE = "[object String]";
export const ARRAY_TYPE = "[object Array]";
export const OBJECT_TYPE = "[object Object]";
export const REGEXP_TYPE = "[object RegExp]";
export const DATE_TYPE = "[object Date]";
export const typeOf = (obj): string => Object.prototype.toString.call(obj);
export function generateDeviceId(deviceIdStruct): 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"]);
}
export function parseAlias(pattern, start, res): number {
const aliases = [];
let i = start;
while (i < pattern.length && pattern[i] !== "]") {
const alias = [];
/* eslint-disable-next-line @typescript-eslint/no-use-before-define */
let j = (i = parsePath(pattern, i, alias) + 1);
while (pattern[j] !== "]" && pattern[j] !== ",") {
if (pattern[j] === '"' && i === j) {
++j;
while (pattern[j] !== '"' || pattern[j - 1] === "\\") {
if (++j >= pattern.length)
throw new Error("Invalid alias expression");
}
}
if (++j >= pattern.length) throw new Error("Invalid alias expression");
}
let value = pattern.slice(i, j).trim();
i = j;
if (value[0] === '"') {
try {
value = JSON.parse(value);
} catch (error) {
throw new Error("Invalid alias expression");
}
}
alias.push(value);
aliases.push(alias);
if (pattern[i] === ",") ++i;
}
// Sort to ensure identical expressions have idential string representation
function srt(a, b): number {
const jMax = Math.min(a.length, b.length);
for (let j = 0; j < jMax; j += 2) {
const kMax = Math.min(a[j].length, b[j].length);
for (let k = 0; k < kMax; ++k) {
if (Array.isArray(a[j][k])) {
if (Array.isArray(b[j][k])) return srt(a[j][k], b[j][k]);
else if (b[j][k] == null) return -1;
else return 1;
} else if (a[j][k] == null) {
if (b[j][k] == null) return 0;
else return 1;
} else if (b[j][k] == null || Array.isArray(b[j][k])) {
return -1;
} else if (a[j][k] > b[j][k]) {
return 1;
} else if (a[j][k] < b[j][k]) {
return -1;
}
}
if (a[j].length > b[j].length) return -1;
else if (a[j].length < b[j].length) return 1;
if (a[j + 1] > b[j + 1]) return -1;
else if (a[j + 1] < b[j + 1]) return 1;
}
if (a.length > b.length) return -1;
else if (a.length < b.length) return 1;
return 0;
}
aliases.sort(srt);
res.push([].concat.apply([], aliases));
return i;
}
/* eslint-disable @typescript-eslint/no-use-before-define */
export function parsePath(pattern, start, res): number;
export function parsePath(pattern, start?): ParamPath;
export function parsePath(pattern, start?, res?): number | ParamPath {
const path = [] as ParamPath;
path.wildcard = 0;
path.alias = 0;
let i = start || 0;
// Colon separator is needed for parseAlias
if (i < pattern.length && pattern[i] !== ":") {
for (;;) {
if (pattern[i] === "[") {
path.alias |= 1 << path.length;
i = parseAlias(pattern, i + 1, path) + 1;
} else {
const j = i;
while (i < pattern.length && pattern[i] !== ":" && pattern[i] !== ".")
++i;
const n = pattern.slice(j, i);
if (n === "*") path.wildcard |= 1 << path.length;
path.push(n);
}
if (i >= pattern.length || pattern[i] === ":") break;
else if (pattern[i] !== ".") throw new Error("Invalid alias expression");
++i;
}
}
Object.freeze(path);
if (res == null) return path;
res.push(path);
return i;
}
export function addPathMeta(path): ParamPath {
if (path.alias != null && path.wildcard != null) return path;
path.alias = 0;
path.wildcard = 0;
for (const [i, p] of path.entries()) {
if (Array.isArray(p)) {
path.alias |= 1 << i;
for (let j = 0; j < p.length; j += 2) addPathMeta(p[j]);
} else if (p === "*") {
path.wildcard |= 1 << i;
}
}
Object.freeze(path);
return path;
}
// Source: http://stackoverflow.com/a/6969486
export function escapeRegExp(str): string {
return str.replace(/[-[\]/{}()*+?.\\^$|]/g, "\\$&");
}