Convert common.coffee to JS

This commit is contained in:
Zaid Abdulla committed 2018-08-21 11:04:44 -07:00
1 parent 079255d7bd
commit 31ab6b6a73
3 files changed
+217 -230

No files matched your search

-229
View File
@@ -1,229 +0,0 @@
###
# Copyright 2013-2017 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/>.
###
buffer = require 'buffer'
UNDEFINED_TYPE = '[object Undefined]'
NULL_TYPE = '[object Null]'
BOOLEAN_TYPE = '[object Boolean]'
NUMBER_TYPE = '[object Number]'
STRING_TYPE = '[object String]'
ARRAY_TYPE = '[object Array]'
OBJECT_TYPE = '[object Object]'
REGEXP_TYPE = '[object RegExp]'
DATE_TYPE = '[object Date]'
typeOf = (obj) ->
Object.prototype.toString.call(obj)
exports.generateDeviceId = (deviceIdStruct) ->
# Percent escaping function. Escapes everything except alphanumerics and underscore
esc = (str) ->
str.replace(/[^A-Za-z0-9_]/g, (chr) ->
buf = new buffer.Buffer(chr, 'utf8')
rep = ''
rep += "%#{b.toString(16).toUpperCase()}" for b in buf
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'])}"
exports.getParamValueFromPath = (obj, path) ->
pp = path.split('.')
ref = obj
try
for p in pp
ref = ref[p]
return ref
catch err
return undefined
pathOverlap = (a, b, start) ->
if a.length == b.length
res = 3
else if a.length > b.length
res = 2
else
res = 1
for i in [(start ? 0)...Math.min(a.length, b.length)] by 1
if a[i]?
if not b[i]?
res &= 2
else if a[i] != b[i]
return 0
else if b[i]?
res &= 1
return 0 if not res
return res
parseAlias = (pattern, start, res) ->
aliases = []
i = start
while i < pattern.length and pattern[i] != ']'
alias = []
i = j = parsePath(pattern, i, alias) + 1
while pattern[j] not in [']', ',']
if pattern[j] == '"' and i == j
++ j
while pattern[j] != '"' or pattern[j - 1] == '\\'
if ++ j >= pattern.length
throw new Error('Invalid alias expression')
if ++ j >= pattern.length
throw new Error('Invalid alias expression')
value = pattern[i...j].trim()
i = j
if value[0] == '"'
try
value = JSON.parse(value)
catch err
throw new Error('Invalid alias expression')
alias.push(value)
aliases.push(alias)
++ i if pattern[i] == ','
# Need to sort to ensure identical expressions have idential string representation
srt = (a, b) ->
for j in [0...Math.min(a.length, b.length)] by 2
for k in [0...Math.min(a[j].length, b[j].length)] by 1
if Array.isArray(a[j][k])
if Array.isArray(b[j][k])
return srt(a[j][k], b[j][k])
else if not b[j][k]?
return -1
else
return 1
else if not a[j][k]?
if not b[j][k]?
return 0
else
return 1
else if not b[j][k]? or 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
parsePath = (pattern, start, res) ->
path = []
path.wildcard = 0
path.alias = 0
i = start ? 0
# Colon separator is needed for parseAlias
if i < pattern.length and pattern[i] != ':'
while true
if pattern[i] == '['
path.alias |= 1 << path.length
i = parseAlias(pattern, i + 1, path) + 1
else
j = i
while i < pattern.length and pattern[i] != ':' and pattern[i] != '.'
++ i
n = pattern.slice(j, i)
path.wildcard |= 1 << path.length if n == '*'
path.push(n)
if i >= pattern.length or pattern[i] == ':'
break
else if pattern[i] != '.'
throw new Error('Invalid alias expression')
++ i
Object.freeze(path)
if not res?
return path
res.push(path)
return i
addPathMeta = (path) ->
return path if path.alias? or path.wildcard?
path.alias = 0
path.wildcard = 0
for p, i in path
if typeOf(p) is ARRAY_TYPE
path.alias |= 1 << i
for j in [0...p.length] by 2
addPathMeta(p[j])
else if p == '*'
path.wildcard |= 1 << i
Object.freeze(path)
return path
# Source: http://stackoverflow.com/a/6969486
escapeRegExp = (str) ->
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&")
exports.UNDEFINED_TYPE = UNDEFINED_TYPE
exports.NULL_TYPE = NULL_TYPE
exports.NUMBER_TYPE = NUMBER_TYPE
exports.STRING_TYPE = STRING_TYPE
exports.ARRAY_TYPE = ARRAY_TYPE
exports.OBJECT_TYPE = OBJECT_TYPE
exports.REGEXP_TYPE = REGEXP_TYPE
exports.typeOf = typeOf
exports.pathOverlap = pathOverlap
exports.parsePath = parsePath
exports.addPathMeta = addPathMeta
exports.escapeRegExp = escapeRegExp
+217
View File
@@ -0,0 +1,217 @@
/**
* 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/>.
*/
"use strict";
const UNDEFINED_TYPE = "[object Undefined]";
const NULL_TYPE = "[object Null]";
const BOOLEAN_TYPE = "[object Boolean]";
const NUMBER_TYPE = "[object Number]";
const STRING_TYPE = "[object String]";
const ARRAY_TYPE = "[object Array]";
const OBJECT_TYPE = "[object Object]";
const REGEXP_TYPE = "[object RegExp]";
const DATE_TYPE = "[object Date]";
const typeOf = (obj) => Object.prototype.toString.call(obj);
function generateDeviceId(deviceIdStruct) {
// Escapes everything except alphanumerics and underscore
function esc(str) {
return str.replace(/[^A-Za-z0-9_]/g, (chr) => {
const buf = new Buffer(chr, "utf8");
let rep = "";
for (let 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"]));
}
function parseAlias(pattern, start, res) {
const aliases = [];
let i = start;
while (i < pattern.length && pattern[i] !== "]") {
const alias = [];
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) {
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;
}
function parsePath(pattern, start, res) {
const path = [];
path.wildcard = 0;
path.alias = 0;
let i = start || 0;
// Colon separator is needed for parseAlias
if (i < pattern.length && pattern[i] !== ":") {
while (true) {
if (pattern[i] === "[") {
path.alias |= 1 << path.length;
i = parseAlias(pattern, i + 1, path) + 1;
} else {
let 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;
}
function addPathMeta(path) {
if (path.alias != null && path.wildcard != null)
return path;
path.alias = 0;
path.wildcard = 0;
for (let [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
function escapeRegExp(str) {
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
}
exports.UNDEFINED_TYPE = UNDEFINED_TYPE;
exports.NULL_TYPE = NULL_TYPE;
exports.BOOLEAN_TYPE = BOOLEAN_TYPE;
exports.NUMBER_TYPE = NUMBER_TYPE;
exports.STRING_TYPE = STRING_TYPE;
exports.ARRAY_TYPE = ARRAY_TYPE;
exports.OBJECT_TYPE = OBJECT_TYPE;
exports.DATE_TYPE = DATE_TYPE;
exports.REGEXP_TYPE = REGEXP_TYPE;
exports.typeOf = typeOf;
exports.generateDeviceId = generateDeviceId;
exports.parsePath = parsePath;
exports.addPathMeta = addPathMeta;
exports.escapeRegExp = escapeRegExp;