Convert backend code to ES modules

Bundling code now with Rollup for its flat bundling and tree shaking
support. Front end code still goes through Webpack for browser support.
This commit is contained in:
Zaid Abdulla committed 2019-02-04 23:47:54 -08:00
1 parent 824639976f
commit 1e41c72d60
62 files changed
+718 -898

No files matched your search

+13 -18
View File
@@ -18,15 +18,15 @@
*/
"use strict";
const crypto = require("crypto");
const dgram = require("dgram");
const URL = require("url");
const http = require("http");
const config = require("./config");
const db = require("./db");
const common = require("./common");
const auth = require("./auth");
const cache = require("./cache");
import crypto from "crypto";
import dgram from "dgram";
import URL from "url";
import http from "http";
import * as config from "./config";
import * as db from "./db";
import * as common from "./common";
import * as auth from "./auth";
import * as cache from "./cache";
function udpConReq(address, un, key, callback) {
if (!address) return false;
@@ -187,7 +187,7 @@ function httpConReq(
});
}
function connectionRequest(deviceId, callback) {
export function connectionRequest(deviceId, callback) {
const CONNECTION_REQUEST_TIMEOUT = config.get(
"CONNECTION_REQUEST_TIMEOUT",
deviceId
@@ -284,7 +284,7 @@ function connectionRequest(deviceId, callback) {
});
}
function watchTask(deviceId, taskId, timeout, callback) {
export function watchTask(deviceId, taskId, timeout, callback) {
setTimeout(() => {
db.tasksCollection.findOne(
{ _id: taskId },
@@ -324,7 +324,7 @@ function sanitizeTask(task, callback) {
callback(task);
}
function insertTasks(tasks, callback) {
export function insertTasks(tasks, callback) {
if (tasks && common.typeOf(tasks) !== common.ARRAY_TYPE) tasks = [tasks];
else if (!tasks || tasks.length === 0)
return void callback(null, tasks || []);
@@ -344,7 +344,7 @@ function insertTasks(tasks, callback) {
}
}
function deleteDevice(deviceId, callback) {
export function deleteDevice(deviceId, callback) {
db.tasksCollection.deleteMany({ device: deviceId }, err => {
if (err) return void callback(err);
db.devicesCollection.deleteOne({ _id: deviceId }, err => {
@@ -373,8 +373,3 @@ function deleteDevice(deviceId, callback) {
});
});
}
exports.connectionRequest = connectionRequest;
exports.watchTask = watchTask;
exports.insertTasks = insertTasks;
exports.deleteDevice = deleteDevice;
+7 -11
View File
@@ -18,9 +18,9 @@
*/
"use strict";
const crypto = require("crypto");
import { createHash } from "crypto";
function parseAuthHeader(authHeader) {
export function parseAuthHeader(authHeader) {
authHeader = authHeader.trim();
const method = authHeader.split(" ", 1)[0];
const res = { method: method };
@@ -53,11 +53,11 @@ function parseAuthHeader(authHeader) {
return res;
}
function basic(username, password) {
export function basic(username, password) {
return "Basic " + Buffer.from(`${username}:${password}`).toString("base64");
}
function digest(username, password, uri, httpMethod, body, authHeader) {
export function digest(username, password, uri, httpMethod, body, authHeader) {
const cnonce = "0a4f113b";
const nc = "00000001";
let qop;
@@ -68,7 +68,7 @@ function digest(username, password, uri, httpMethod, body, authHeader) {
else qop = authHeader.qop;
}
let ha1 = crypto.createHash("md5");
let ha1 = createHash("md5");
ha1
.update(username)
.update(":")
@@ -78,7 +78,7 @@ function digest(username, password, uri, httpMethod, body, authHeader) {
// TODO support "MD5-sess" algorithm directive
ha1 = ha1.digest("hex");
let ha2 = crypto.createHash("md5");
let ha2 = createHash("md5");
ha2
.update(httpMethod)
.update(":")
@@ -86,7 +86,7 @@ function digest(username, password, uri, httpMethod, body, authHeader) {
if (qop === "auth-int") ha2.update(":").update(body);
ha2 = ha2.digest("hex");
const hash = crypto.createHash("md5");
const hash = createHash("md5");
hash
.update(ha1)
.update(":")
@@ -113,7 +113,3 @@ function digest(username, password, uri, httpMethod, body, authHeader) {
return authString;
}
exports.parseAuthHeader = parseAuthHeader;
exports.basic = basic;
exports.digest = digest;
+10 -18
View File
@@ -18,7 +18,8 @@
*/
"use strict";
const config = require("./config");
import { MongoClient } from "mongodb";
import * as config from "./config";
const MAX_CACHE_TTL = config.get("MAX_CACHE_TTL");
@@ -26,11 +27,10 @@ let mongoClient;
let mongoCollection;
let mongoTimeOffset = 0;
function connect(callback) {
const mongodb = require("mongodb");
export function connect(callback) {
const MONGODB_CONNECTION_URL = config.get("MONGODB_CONNECTION_URL");
mongodb.MongoClient.connect(
MongoClient.connect(
MONGODB_CONNECTION_URL,
{ useNewUrlParser: true },
(err, client) => {
@@ -51,11 +51,11 @@ function connect(callback) {
);
}
function disconnect() {
export function disconnect() {
if (mongoClient) mongoClient.close();
}
function get(key, callback) {
export function get(key, callback) {
const expire = new Date(Date.now() - mongoTimeOffset);
if (Array.isArray(key)) {
mongoCollection.find({ _id: { $in: key } }).toArray((err, res) => {
@@ -83,13 +83,13 @@ function get(key, callback) {
}
}
function del(key, callback) {
export function del(key, callback) {
if (Array.isArray(key))
mongoCollection.deleteMany({ _id: { $in: key } }, callback);
else mongoCollection.deleteOne({ _id: key }, callback);
}
function set(key, value, ttl, callback) {
export function set(key, value, ttl, callback) {
if (!callback && typeof v === "function") {
callback = ttl;
ttl = null;
@@ -106,7 +106,7 @@ function set(key, value, ttl, callback) {
);
}
function pop(key, callback) {
export function pop(key, callback) {
mongoCollection.findOneAndDelete({ _id: key }, (err, res) => {
if (err || !res["value"]) return void callback(err);
@@ -117,7 +117,7 @@ function pop(key, callback) {
});
}
function lock(lockName, ttl, callback) {
export function lock(lockName, ttl, callback) {
const token = Math.random()
.toString(36)
.slice(2);
@@ -159,11 +159,3 @@ function lock(lockName, ttl, callback) {
}
);
}
exports.connect = connect;
exports.disconnect = disconnect;
exports.get = get;
exports.set = set;
exports.del = del;
exports.pop = pop;
exports.lock = lock;
+7 -8
View File
@@ -18,8 +18,9 @@
*/
"use strict";
const cluster = require("cluster");
const logger = require("./logger");
import cluster from "cluster";
import { cpus } from "os";
import * as logger from "./logger";
let respawnTimestamp = 0;
let tooManyCrashesTimestamp = 0;
@@ -62,7 +63,7 @@ function restartWorker(worker, code, signal) {
}, respawnTimestamp - now);
}
function start(workerCount, servicePort, serviceAddress) {
export function start(workerCount, servicePort, serviceAddress) {
cluster.on("listening", (worker, address) => {
if (
(address.addressType === 4 || address.addressType === 6) &&
@@ -80,16 +81,14 @@ function start(workerCount, servicePort, serviceAddress) {
cluster.on("exit", restartWorker);
if (!workerCount) workerCount = Math.max(2, require("os").cpus().length);
if (!workerCount) workerCount = Math.max(2, cpus().length);
for (let i = 0; i < workerCount; ++i) cluster.fork();
}
function stop() {
export function stop() {
cluster.removeListener("exit", restartWorker);
for (const pid in cluster.workers) cluster.workers[pid].kill();
}
exports.start = start;
exports.stop = stop;
exports.worker = cluster.worker;
export const worker = cluster.worker;
+15 -31
View File
@@ -18,19 +18,19 @@
*/
"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]";
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]";
const typeOf = obj => Object.prototype.toString.call(obj);
export const typeOf = obj => Object.prototype.toString.call(obj);
function generateDeviceId(deviceIdStruct) {
export function generateDeviceId(deviceIdStruct) {
// Escapes everything except alphanumerics and underscore
function esc(str) {
return str.replace(/[^A-Za-z0-9_]/g, chr => {
@@ -54,7 +54,7 @@ function generateDeviceId(deviceIdStruct) {
return esc(deviceIdStruct["OUI"]) + "-" + esc(deviceIdStruct["SerialNumber"]);
}
function parseAlias(pattern, start, res) {
export function parseAlias(pattern, start, res) {
const aliases = [];
let i = start;
while (i < pattern.length && pattern[i] !== "]") {
@@ -126,7 +126,7 @@ function parseAlias(pattern, start, res) {
return i;
}
function parsePath(pattern, start, res) {
export function parsePath(pattern, start, res) {
const path = [];
path.wildcard = 0;
path.alias = 0;
@@ -163,7 +163,7 @@ function parsePath(pattern, start, res) {
return i;
}
function addPathMeta(path) {
export function addPathMeta(path) {
if (path.alias != null && path.wildcard != null) return path;
path.alias = 0;
@@ -183,22 +183,6 @@ function addPathMeta(path) {
}
// Source: http://stackoverflow.com/a/6969486
function escapeRegExp(str) {
export 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;
+5 -7
View File
@@ -1,11 +1,11 @@
"use strict";
const validators = {
pass: require("./validators/pass"),
test: require("./validators/test")
};
import pass from "./validators/pass";
import test from "./validators/test";
class Authorizer {
const validators = { pass, test };
export default class Authorizer {
constructor(permissionSets) {
this.permissionSets = permissionSets;
this.validatorCache = new WeakMap();
@@ -77,5 +77,3 @@ class Authorizer {
return validator;
}
}
module.exports = Authorizer;
+4 -9
View File
@@ -1,6 +1,6 @@
"use strict";
const expressionParser = require("./expression-parser");
import { map, parseLikePattern } from "./expression-parser";
function or(cnf1, cnf2) {
if (cnf1.length === 0) return cnf2;
@@ -19,10 +19,10 @@ function or(cnf1, cnf2) {
return res;
}
function booleanCnf(exp) {
export function booleanCnf(exp) {
const ranges = new Map();
const likePatterns = new Map();
expressionParser.map(exp, e => {
map(exp, e => {
if (!Array.isArray(e)) return e;
if (e[0] === "LIKE" || e[0] === "NOT LIKE") {
if (
@@ -32,10 +32,7 @@ function booleanCnf(exp) {
const key = JSON.stringify(e[1]);
let s = likePatterns.get(key);
if (!s) likePatterns.set(key, (s = new Map()));
s.set(
`${e[3] || ""}:${e[2]}`,
expressionParser.parseLikePattern(e[2], e[3])
);
s.set(`${e[3] || ""}:${e[2]}`, parseLikePattern(e[2], e[3]));
}
} else if ([">", ">=", "<", "<=", "=", "<>"].includes(e[0])) {
if (!Array.isArray(e[2])) {
@@ -251,5 +248,3 @@ function likePatternIncludes(pat1, pat2, idx1 = 0, idx2 = 0) {
if (idx1 === pat1.length && idx2 === pat2.length) return true;
return false;
}
exports.booleanCnf = booleanCnf;
+5 -10
View File
@@ -1,6 +1,6 @@
"use strict";
const parsimmon = require("parsimmon");
import parsimmon from "parsimmon";
// Turn escaped characters into real ones (e.g. "\\n" becomes "\n").
function interpretEscapes(str) {
@@ -22,7 +22,7 @@ function interpretEscapes(str) {
});
}
function map(exp, callback) {
export function map(exp, callback) {
if (!Array.isArray(exp)) return callback(exp);
let clone;
@@ -271,12 +271,12 @@ const lang = parsimmon.createLanguage({
}
});
function parse(str) {
export function parse(str) {
if (!str) return null;
return lang.Expression.tryParse(str);
}
function stringify(exp, level = 0) {
export function stringify(exp, level = 0) {
if (!Array.isArray(exp)) return JSON.stringify(exp);
const opLevels = {
@@ -360,7 +360,7 @@ function stringify(exp, level = 0) {
}
}
function parseLikePattern(pat, esc) {
export function parseLikePattern(pat, esc) {
const chars = pat.split("");
for (let i = 0; i < chars.length; ++i) {
@@ -377,8 +377,3 @@ function parseLikePattern(pat, esc) {
}
return chars.filter(c => c);
}
exports.parse = parse;
exports.stringify = stringify;
exports.map = map;
exports.parseLikePattern = parseLikePattern;
+15 -25
View File
@@ -1,8 +1,8 @@
"use strict";
const expressionParser = require("./expression-parser");
const expressionCnf = require("./expression-cnf");
const satSolver = require("./sat-solver");
import { map, parseLikePattern } from "./expression-parser";
import { booleanCnf } from "./expression-cnf";
import { naiveDpll } from "./sat-solver";
const isArray = Array.isArray;
@@ -26,7 +26,7 @@ function reduce(exp, callback) {
return exp;
}
function evaluate(exp, obj, now, cb) {
export function evaluate(exp, obj, now, cb) {
function getRegExp(pat, esc) {
const k = `${esc || ""}:${pat}`;
let c = regExpCache.get(exp);
@@ -35,7 +35,7 @@ function evaluate(exp, obj, now, cb) {
return c[k];
}
return expressionParser.map(exp, e => {
return map(exp, e => {
if (cb) e = cb(e);
if (!isArray(e)) return e;
@@ -162,7 +162,7 @@ function evaluate(exp, obj, now, cb) {
});
}
function and(exp1, exp2) {
export function and(exp1, exp2) {
if (!isArray(exp1)) return exp1 ? exp2 : exp1;
if (!isArray(exp2)) return exp2 ? exp1 : exp2;
@@ -177,7 +177,7 @@ function and(exp1, exp2) {
return res;
}
function or(exp1, exp2) {
export function or(exp1, exp2) {
if (!isArray(exp1)) return exp1 ? exp1 : exp2;
if (!isArray(exp2)) return exp2 ? exp2 : exp1;
@@ -192,19 +192,19 @@ function or(exp1, exp2) {
return res;
}
function not(exp) {
export function not(exp) {
if (isArray(exp) && exp[0] === "NOT") return exp[1];
return ["NOT", exp];
}
function subset(exp1, exp2) {
export function subset(exp1, exp2) {
const e = evaluate(["NOT", ["OR", ["NOT", exp1], exp2]]);
if (!isArray(e)) return !e;
const { vars, clauses } = expressionCnf.booleanCnf(e);
return !satSolver.naiveDpll(clauses, vars);
const { vars, clauses } = booleanCnf(e);
return !naiveDpll(clauses, vars);
}
function likePatternToRegExp(pat, esc = "", flags = "") {
export function likePatternToRegExp(pat, esc = "", flags = "") {
const convChars = {
"-": "\\-",
"/": "\\/",
@@ -225,7 +225,7 @@ function likePatternToRegExp(pat, esc = "", flags = "") {
"\\%": ".*",
"\\_": "."
};
let chars = expressionParser.parseLikePattern(pat, esc);
let chars = parseLikePattern(pat, esc);
if (!chars.length) return new RegExp("^$", flags);
chars = chars.map(c => convChars[c] || c);
chars[0] = chars[0] === ".*" ? "" : "^" + chars[0];
@@ -234,21 +234,11 @@ function likePatternToRegExp(pat, esc = "", flags = "") {
return new RegExp(chars.join(""), flags);
}
function extractParams(exp) {
export function extractParams(exp) {
const params = new Set();
expressionParser.map(exp, e => {
map(exp, e => {
if (isArray(e) && e[0] === "PARAM") params.add(e[1]);
return e;
});
return Array.from(params);
}
exports.evaluate = evaluate;
exports.and = and;
exports.or = or;
exports.not = not;
exports.subset = subset;
exports.parse = expressionParser.parse;
exports.stringify = expressionParser.stringify;
exports.likePatternToRegExp = likePatternToRegExp;
exports.extractParams = extractParams;
+1 -3
View File
@@ -22,7 +22,7 @@ function getKey(obj) {
return k;
}
function memoize(func) {
export default function memoize(func) {
return (...args) => {
const key = JSON.stringify(args.map(getKey)) + getKey(func);
@@ -43,5 +43,3 @@ const interval = setInterval(() => {
// Don't hold Node.js process
if (interval.unref) interval.unref();
module.exports = memoize;
+1 -3
View File
@@ -167,10 +167,8 @@ function unitPropagate(clauses, varVals) {
return derivedVars;
}
function naiveDpll(clauses, maxvarnr) {
export function naiveDpll(clauses, maxvarnr) {
// variable values are 0 if not set, 1 if positive, -1 if negative
const varVals = new Int32Array(maxvarnr + 1);
return satisfiableAt(clauses, varVals, 0, 0);
}
exports.naiveDpll = naiveDpll;
+1 -3
View File
@@ -1,5 +1,3 @@
function pass() {
export default function pass() {
return 1;
}
module.exports = pass;
+1 -3
View File
@@ -1,4 +1,4 @@
function test(resourceType, resource) {
export default function test(resourceType, resource) {
if (resourceType === "devices") {
if (resource["Tags.test"] && resource["Tags.test"].value[0]) return 1;
} else if (resourceType === "presets") {
@@ -10,5 +10,3 @@ function test(resourceType, resource) {
}
return -1;
}
module.exports = test;
+9 -17
View File
@@ -18,8 +18,8 @@
*/
"use strict";
const path = require("path");
const fs = require("fs");
import { resolve } from "path";
import { readFileSync } from "fs";
const options = {
CONFIG_DIR: { type: "path", default: "config" },
@@ -133,7 +133,7 @@ function setConfig(name, value, commandLineArgument) {
return String(val);
case "path":
if (!val) return "";
return path.resolve(val);
return resolve(val);
default:
return null;
}
@@ -182,7 +182,7 @@ setConfig("CONFIG_DIR", options["CONFIG_DIR"]["default"]);
// Configuration file
const configFile = JSON.parse(
fs.readFileSync(path.resolve(allConfig.CONFIG_DIR, "config.json"))
readFileSync(resolve(allConfig.CONFIG_DIR, "config.json"))
);
for (const [k, v] of Object.entries(configFile)) {
if (!setConfig(k, v))
@@ -194,7 +194,7 @@ for (const [k, v] of Object.entries(configFile)) {
for (const [k, v] of Object.entries(options))
if (v["default"] != null) setConfig(k, v["default"]);
function get(optionName, deviceId) {
export function get(optionName, deviceId) {
if (!deviceId) return allConfig[optionName];
optionName = `${optionName}-${deviceId}`;
@@ -222,28 +222,20 @@ function get(optionName, deviceId) {
return null;
}
function getDefault(optionName) {
export function getDefault(optionName) {
const option = options[optionName];
if (!option) return null;
let val = option["default"];
if (val && option.type === "path") val = path.resolve(val);
if (val && option.type === "path") val = resolve(val);
return val;
}
export let auth;
// Load authentication scripts
try {
const authScript = fs.readFileSync(
path.resolve(allConfig.CONFIG_DIR, "auth.js")
);
exports.auth = (function(exports) {
eval(authScript.toString());
return exports;
})({});
auth = require(resolve(allConfig.CONFIG_DIR, "auth.js"));
} catch (error) {
// No auth.js exists
}
exports.get = get;
exports.getDefault = getDefault;
+16 -19
View File
@@ -18,20 +18,20 @@
*/
"use strict";
const zlib = require("zlib");
const crypto = require("crypto");
const fs = require("fs");
const config = require("./config");
const common = require("./common");
const soap = require("./soap");
const session = require("./session");
const query = require("./query");
const device = require("./device");
const cache = require("./cache");
const localCache = require("./local-cache");
const db = require("./db");
const logger = require("./logger");
const scheduling = require("./scheduling");
import zlib from "zlib";
import crypto from "crypto";
import fs from "fs";
import * as config from "./config";
import * as common from "./common";
import * as soap from "./soap";
import * as session from "./session";
import * as query from "./query";
import * as device from "./device";
import * as cache from "./cache";
import * as localCache from "./local-cache";
import * as db from "./db";
import * as logger from "./logger";
import * as scheduling from "./scheduling";
const MAX_CYCLES = 4;
const MAX_CONCURRENT_REQUESTS = config.get("MAX_CONCURRENT_REQUESTS");
@@ -771,7 +771,7 @@ function getSession(connection, sessionId, callback) {
const currentSessions = new WeakMap();
// When socket closes, store active sessions in cache
function onConnection(socket) {
export function onConnection(socket) {
// The property remoteAddress may be undefined after the connection is
// closed, unless we read it at least once (caching?)
socket.remoteAddress;
@@ -996,7 +996,7 @@ function processRequest(sessionContext, rpc) {
}
}
function listener(httpRequest, httpResponse) {
export function listener(httpRequest, httpResponse) {
stats.totalRequests += 1;
if (httpRequest.method !== "POST") {
@@ -1243,6 +1243,3 @@ function listener(httpRequest, httpResponse) {
});
});
}
exports.listener = listener;
exports.onConnection = onConnection;
+52 -69
View File
@@ -18,12 +18,12 @@
*/
"use strict";
const mongodb = require("mongodb");
const config = require("./config");
const common = require("./common");
const expressionParser = require("./common/expression-parser");
import { MongoClient, ObjectID } from "mongodb";
import { get } from "./config";
import { escapeRegExp } from "./common";
import { parse } from "./common/expression-parser";
let tasksCollection,
export let tasksCollection,
devicesCollection,
presetsCollection,
objectsCollection,
@@ -34,32 +34,28 @@ let tasksCollection,
operationsCollection,
configCollection;
function connect(callback) {
mongodb.MongoClient.connect(
config.get("MONGODB_CONNECTION_URL"),
export let client;
export function connect(callback) {
MongoClient.connect(
get("MONGODB_CONNECTION_URL"),
{ useNewUrlParser: true },
(err, client) => {
(err, _client) => {
if (err) return void callback(err);
exports.client = client;
client = _client;
const db = client.db();
exports.tasksCollection = tasksCollection = db.collection("tasks");
tasksCollection = db.collection("tasks");
tasksCollection.createIndex({ device: 1, timestamp: 1 });
exports.devicesCollection = devicesCollection = db.collection("devices");
exports.presetsCollection = presetsCollection = db.collection("presets");
exports.objectsCollection = objectsCollection = db.collection("objects");
exports.filesCollection = filesCollection = db.collection("fs.files");
exports.provisionsCollection = provisionsCollection = db.collection(
"provisions"
);
exports.virtualParametersCollection = virtualParametersCollection = db.collection(
"virtualParameters"
);
exports.faultsCollection = faultsCollection = db.collection("faults");
exports.operationsCollection = operationsCollection = db.collection(
"operations"
);
devicesCollection = db.collection("devices");
presetsCollection = db.collection("presets");
objectsCollection = db.collection("objects");
filesCollection = db.collection("fs.files");
provisionsCollection = db.collection("provisions");
virtualParametersCollection = db.collection("virtualParameters");
faultsCollection = db.collection("faults");
operationsCollection = db.collection("operations");
configCollection = db.collection("config");
callback();
@@ -67,8 +63,8 @@ function connect(callback) {
);
}
function disconnect() {
if (exports.client) exports.client.close();
export function disconnect() {
if (client) client.close();
}
// Optimize projection by removing overlaps
@@ -92,8 +88,8 @@ function optimizeProjection(obj) {
return obj;
}
function fetchDevice(id, timestamp, patterns, callback) {
const MAX_DEPTH = config.get("MAX_DEPTH", id);
export function fetchDevice(id, timestamp, patterns, callback) {
const MAX_DEPTH = get("MAX_DEPTH", id);
if (!patterns || !patterns.length) patterns = [[[], (1 << MAX_DEPTH) - 1]];
@@ -476,7 +472,13 @@ function fetchDevice(id, timestamp, patterns, callback) {
});
}
function saveDevice(deviceId, deviceData, isNew, sessionTimestamp, callback) {
export function saveDevice(
deviceId,
deviceData,
isNew,
sessionTimestamp,
callback
) {
const update = { $set: {}, $unset: {}, $addToSet: {}, $pull: {} };
for (const diff of deviceData.timestamps.diff()) {
@@ -724,9 +726,9 @@ function saveDevice(deviceId, deviceData, isNew, sessionTimestamp, callback) {
);
}
function getFaults(deviceId, callback) {
export function getFaults(deviceId, callback) {
faultsCollection
.find({ _id: { $regex: `^${common.escapeRegExp(deviceId)}\\:` } })
.find({ _id: { $regex: `^${escapeRegExp(deviceId)}\\:` } })
.toArray((err, res) => {
if (err) return callback(err);
@@ -745,7 +747,7 @@ function getFaults(deviceId, callback) {
});
}
function saveFault(deviceId, channel, fault, callback) {
export function saveFault(deviceId, channel, fault, callback) {
const id = `${deviceId}:${channel}`;
fault = Object.assign({}, fault);
fault._id = id;
@@ -756,11 +758,11 @@ function saveFault(deviceId, channel, fault, callback) {
faultsCollection.replaceOne({ _id: id }, fault, { upsert: true }, callback);
}
function deleteFault(deviceId, channel, callback) {
export function deleteFault(deviceId, channel, callback) {
faultsCollection.deleteOne({ _id: `${deviceId}:${channel}` }, callback);
}
function getDueTasks(deviceId, timestamp, callback) {
export function getDueTasks(deviceId, timestamp, callback) {
const cur = tasksCollection.find({ device: deviceId }).sort(["timestamp"]);
const tasks = [];
@@ -782,8 +784,8 @@ function getDueTasks(deviceId, timestamp, callback) {
// For API compatibility
if (task.name === "download" && task.file) {
let q;
if (mongodb.ObjectID.isValid(task.file))
q = { _id: { $in: [task.file, new mongodb.ObjectID(task.file)] } };
if (ObjectID.isValid(task.file))
q = { _id: { $in: [task.file, new ObjectID(task.file)] } };
else q = { _id: task.file };
filesCollection.find(q).toArray((err, res) => {
@@ -805,16 +807,16 @@ function getDueTasks(deviceId, timestamp, callback) {
);
}
function clearTasks(deviceId, taskIds, callback) {
export function clearTasks(deviceId, taskIds, callback) {
tasksCollection.deleteMany(
{ _id: { $in: taskIds.map(id => new mongodb.ObjectID(id)) } },
{ _id: { $in: taskIds.map(id => new ObjectID(id)) } },
callback
);
}
function getOperations(deviceId, callback) {
export function getOperations(deviceId, callback) {
operationsCollection
.find({ _id: { $regex: `^${common.escapeRegExp(deviceId)}\\:` } })
.find({ _id: { $regex: `^${escapeRegExp(deviceId)}\\:` } })
.toArray((err, res) => {
if (err) return void callback(err);
@@ -833,7 +835,7 @@ function getOperations(deviceId, callback) {
});
}
function saveOperation(deviceId, commandKey, operation, callback) {
export function saveOperation(deviceId, commandKey, operation, callback) {
const id = `${deviceId}:${commandKey}`;
operation = Object.assign({}, operation);
operation._id = id;
@@ -849,34 +851,34 @@ function saveOperation(deviceId, commandKey, operation, callback) {
);
}
function deleteOperation(deviceId, commandKey, callback) {
export function deleteOperation(deviceId, commandKey, callback) {
operationsCollection.deleteOne(
{ _id: `${deviceId}:${commandKey}` },
callback
);
}
function getPresets(callback) {
export function getPresets(callback) {
presetsCollection.find().toArray(callback);
}
function getObjects(callback) {
export function getObjects(callback) {
objectsCollection.find().toArray(callback);
}
function getProvisions(callback) {
export function getProvisions(callback) {
provisionsCollection.find().toArray(callback);
}
function getVirtualParameters(callback) {
export function getVirtualParameters(callback) {
virtualParametersCollection.find().toArray(callback);
}
function getFiles(callback) {
export function getFiles(callback) {
filesCollection.find().toArray(callback);
}
function getConfig(callback) {
export function getConfig(callback) {
configCollection.find().toArray((err, res) => {
if (err) return void callback(err);
@@ -884,27 +886,8 @@ function getConfig(callback) {
null,
res.map(c => ({
id: c["_id"],
value: expressionParser.parse(c["value"])
value: parse(c["value"])
}))
);
});
}
exports.connect = connect;
exports.disconnect = disconnect;
exports.fetchDevice = fetchDevice;
exports.saveDevice = saveDevice;
exports.getFaults = getFaults;
exports.saveFault = saveFault;
exports.deleteFault = deleteFault;
exports.clearTasks = clearTasks;
exports.saveOperation = saveOperation;
exports.deleteOperation = deleteOperation;
exports.getPresets = getPresets;
exports.getObjects = getObjects;
exports.getProvisions = getProvisions;
exports.getVirtualParameters = getVirtualParameters;
exports.getFiles = getFiles;
exports.getDueTasks = getDueTasks;
exports.getOperations = getOperations;
exports.getConfig = getConfig;
+11 -19
View File
@@ -18,14 +18,14 @@
*/
"use strict";
const config = require("./config");
const common = require("./common");
const device = require("./device");
const scheduling = require("./scheduling");
import * as config from "./config";
import * as common from "./common";
import * as device from "./device";
import * as scheduling from "./scheduling";
const MAX_DEPTH = config.get("MAX_DEPTH");
function refresh(sessionContext, provision, declarations) {
export function refresh(sessionContext, provision, declarations) {
const path = common.parsePath(provision[1]).slice();
const l = path.length;
path.length = MAX_DEPTH;
@@ -48,7 +48,7 @@ function refresh(sessionContext, provision, declarations) {
return true;
}
function value(sessionContext, provision, declarations) {
export function value(sessionContext, provision, declarations) {
const path = common.parsePath(provision[1]);
declarations.push({
path: path,
@@ -62,7 +62,7 @@ function value(sessionContext, provision, declarations) {
return true;
}
function tag(sessionContext, provision, declarations) {
export function tag(sessionContext, provision, declarations) {
const path = ["Tags", provision[1]];
declarations.push({
@@ -77,7 +77,7 @@ function tag(sessionContext, provision, declarations) {
return true;
}
function reboot(sessionContext, provision, declarations) {
export function reboot(sessionContext, provision, declarations) {
declarations.push({
path: ["Reboot"],
pathGet: 1,
@@ -90,7 +90,7 @@ function reboot(sessionContext, provision, declarations) {
return true;
}
function reset(sessionContext, provision, declarations) {
export function reset(sessionContext, provision, declarations) {
declarations.push({
path: ["FactoryReset"],
pathGet: 1,
@@ -103,7 +103,7 @@ function reset(sessionContext, provision, declarations) {
return true;
}
function download(sessionContext, provision, declarations) {
export function download(sessionContext, provision, declarations) {
const alias = [
["FileType"],
provision[1] || "",
@@ -134,7 +134,7 @@ function download(sessionContext, provision, declarations) {
return true;
}
function instances(
export function instances(
sessionContext,
provision,
declarations,
@@ -178,11 +178,3 @@ function instances(
return true;
}
exports.refresh = refresh;
exports.value = value;
exports.tag = tag;
exports.reboot = reboot;
exports.reset = reset;
exports.download = download;
exports.instances = instances;
+15 -17
View File
@@ -32,7 +32,7 @@ function parseBool(v) {
else return null;
}
function sanitizeParameterValue(parameterValue) {
export function sanitizeParameterValue(parameterValue) {
if (parameterValue[0] != null) {
switch (parameterValue[1]) {
case "xsd:boolean":
@@ -83,8 +83,8 @@ function sanitizeParameterValue(parameterValue) {
return parameterValue;
}
function getAliasDeclarations(path, timestamp) {
var decs = [];
export function getAliasDeclarations(path, timestamp) {
const decs = [];
function recursive(p, prefix) {
const pattern = prefix.concat(p);
@@ -113,7 +113,7 @@ function getAliasDeclarations(path, timestamp) {
return decs;
}
function unpack(deviceData, path, revision) {
export function unpack(deviceData, path, revision) {
let allMatches = [];
if (!path.alias) {
for (const p of deviceData.paths.find(path, false, true))
@@ -194,7 +194,13 @@ function unpack(deviceData, path, revision) {
return allMatches;
}
function clear(deviceData, path, timestamp, attributes, changeFlags = 0) {
export function clear(
deviceData,
path,
timestamp,
attributes,
changeFlags = 0
) {
const changeTrackers = {};
timestamp = timestamp || 0;
@@ -254,7 +260,7 @@ function clear(deviceData, path, timestamp, attributes, changeFlags = 0) {
}
function compareEquality(a, b) {
var t = typeof a;
const t = typeof a;
if (
a === null ||
a === undefined ||
@@ -268,7 +274,7 @@ function compareEquality(a, b) {
return JSON.stringify(a) === JSON.stringify(b);
}
function set(deviceData, path, timestamp, attributes, toClear) {
export function set(deviceData, path, timestamp, attributes, toClear) {
path = deviceData.paths.add(path);
const currentTimestamp = deviceData.timestamps.get(path);
@@ -366,7 +372,7 @@ function set(deviceData, path, timestamp, attributes, toClear) {
return toClear;
}
function track(deviceData, path, marker, attributes) {
export function track(deviceData, path, marker, attributes) {
path = deviceData.paths.add(path);
let f = 1;
@@ -382,7 +388,7 @@ function track(deviceData, path, marker, attributes) {
cur[marker] |= f;
}
function clearTrackers(deviceData, tracker) {
export function clearTrackers(deviceData, tracker) {
if (Array.isArray(tracker)) {
for (const v of deviceData.trackers.values())
for (const t of tracker) delete v[t];
@@ -392,11 +398,3 @@ function clearTrackers(deviceData, tracker) {
deviceData.changes.delete(tracker);
}
}
exports.sanitizeParameterValue = sanitizeParameterValue;
exports.getAliasDeclarations = getAliasDeclarations;
exports.unpack = unpack;
exports.set = set;
exports.clear = clear;
exports.track = track;
exports.clearTrackers = clearTrackers;
+6 -10
View File
@@ -18,10 +18,9 @@
*/
"use strict";
const childProcess = require("child_process");
const crypto = require("crypto");
const config = require("./config");
import { fork } from "child_process";
import crypto from "crypto";
import * as config from "./config";
const TIMEOUT = config.get("EXT_TIMEOUT");
@@ -36,11 +35,11 @@ function messageHandler(message) {
}
}
function run(args, callback) {
export function run(args, callback) {
const scriptName = args[0];
if (!processes[scriptName]) {
const p = childProcess.fork("lib/extension-wrapper", [scriptName]);
const p = fork("lib/extension-wrapper", [scriptName]);
processes[scriptName] = p;
p.on("error", () => {
@@ -91,7 +90,7 @@ function kill(process, callback) {
}, 100);
}
function killAll(callback) {
export function killAll(callback) {
let counter = 1;
for (const n in processes) {
++counter;
@@ -102,6 +101,3 @@ function killAll(callback) {
}
if (--counter === 0 && callback) callback();
}
exports.run = run;
exports.killAll = killAll;
+6 -8
View File
@@ -18,12 +18,12 @@
*/
"use strict";
const url = require("url");
const querystring = require("querystring");
const mongodb = require("mongodb");
const db = require("./db");
import url from "url";
import querystring from "querystring";
import { GridFSBucket } from "mongodb";
import * as db from "./db";
function listener(request, response) {
export function listener(request, response) {
const urlParts = url.parse(request.url, true);
if (request.method === "GET") {
const filename = querystring.unescape(urlParts.pathname.substring(1));
@@ -45,7 +45,7 @@ function listener(request, response) {
"Content-Length": file.length
});
const bucket = new mongodb.GridFSBucket(db.client.db());
const bucket = new GridFSBucket(db.client.db());
const downloadStream = bucket.openDownloadStream(filename);
downloadStream.pipe(response);
});
@@ -54,5 +54,3 @@ function listener(request, response) {
response.end("405 Method Not Allowed");
}
}
exports.listener = listener;
+1 -3
View File
@@ -28,7 +28,7 @@ const UNDISCOVERED_DEPTH = 7;
// flags is an int where its bits mark the segments in the pattern that
// need refreshing. Leading 0s indicate that the pattern up to that
// point has been discovered.
function estimateGpnCount(gpnPatterns, depth = 0) {
export function estimateGpnCount(gpnPatterns, depth = 0) {
const children = {};
const wildcardChildren = [];
let wildcardDiscovered = false;
@@ -77,5 +77,3 @@ function estimateGpnCount(gpnPatterns, depth = 0) {
return gpnCount;
}
exports.estimateGpnCount = estimateGpnCount;
+1 -3
View File
@@ -18,7 +18,7 @@
*/
"use strict";
class InstanceSet {
export default class InstanceSet {
constructor() {
this.set = new Set();
}
@@ -124,5 +124,3 @@ class InstanceSet {
return this.set.size;
}
}
module.exports = InstanceSet;
+19 -30
View File
@@ -18,16 +18,16 @@
*/
"use strict";
const vm = require("vm");
const crypto = require("crypto");
import vm from "vm";
import crypto from "crypto";
const config = require("./config");
const db = require("./db");
const cache = require("./cache");
const query = require("./query");
const logger = require("./logger");
const scheduling = require("./scheduling");
const expression = require("./common/expression");
import * as config from "./config";
import * as db from "./db";
import * as cache from "./cache";
import * as query from "./query";
import * as logger from "./logger";
import * as scheduling from "./scheduling";
import * as expression from "./common/expression";
const REFRESH = 3000;
const EVICT_TIMEOUT = 60000;
@@ -369,7 +369,7 @@ function refresh(callback) {
});
}
function getCurrentSnapshot(callback) {
export function getCurrentSnapshot(callback) {
if (Date.now() < nextRefresh) {
if (callback) return callback(null, currentSnapshot);
return Promise.resolve(currentSnapshot);
@@ -389,35 +389,35 @@ function getCurrentSnapshot(callback) {
});
}
function hasSnapshot(hash) {
export function hasSnapshot(hash) {
return snapshots.has(hash);
}
function getPresets(snapshotKey) {
export function getPresets(snapshotKey) {
const snapshot = snapshots.get(snapshotKey);
if (!snapshot) throw new Error("Cache snapshot does not exist");
return snapshot.presets;
}
function getProvisions(snapshotKey) {
export function getProvisions(snapshotKey) {
const snapshot = snapshots.get(snapshotKey);
if (!snapshot) throw new Error("Cache snapshot does not exist");
return snapshot.provisions;
}
function getVirtualParameters(snapshotKey) {
export function getVirtualParameters(snapshotKey) {
const snapshot = snapshots.get(snapshotKey);
if (!snapshot) throw new Error("Cache snapshot does not exist");
return snapshot.virtualParameters;
}
function getFiles(snapshotKey) {
export function getFiles(snapshotKey) {
const snapshot = snapshots.get(snapshotKey);
if (!snapshot) throw new Error("Cache snapshot does not exist");
return snapshot.files;
}
function getConfig(snapshotKey, key, context, now) {
export function getConfig(snapshotKey, key, context, now) {
const snapshot = snapshots.get(snapshotKey);
if (!snapshot) throw new Error("Cache snapshot does not exist");
@@ -445,34 +445,23 @@ function getConfig(snapshotKey, key, context, now) {
return expression.evaluate(snapshot.config[key], context, now || Date.now());
}
function getAuthConfig(snapshotKey) {
export function getAuthConfig(snapshotKey) {
const snapshot = snapshots.get(snapshotKey);
if (!snapshot) throw new Error("Cache snapshot does not exist");
return snapshot.config.auth;
}
function getPermissionsConfig(snapshotKey) {
export function getPermissionsConfig(snapshotKey) {
const snapshot = snapshots.get(snapshotKey);
if (!snapshot) throw new Error("Cache snapshot does not exist");
return snapshot.config.permissions;
}
function getUiConfig(snapshotKey) {
export function getUiConfig(snapshotKey) {
const snapshot = snapshots.get(snapshotKey);
if (!snapshot) throw new Error("Cache snapshot does not exist");
return snapshot.config.ui;
}
exports.getCurrentSnapshot = getCurrentSnapshot;
exports.hasSnapshot = hasSnapshot;
exports.getPresets = getPresets;
exports.getProvisions = getProvisions;
exports.getVirtualParameters = getVirtualParameters;
exports.getFiles = getFiles;
exports.getConfig = getConfig;
exports.getAuthConfig = getAuthConfig;
exports.getPermissionsConfig = getPermissionsConfig;
exports.getUiConfig = getUiConfig;
+13 -23
View File
@@ -18,10 +18,10 @@
*/
"use strict";
const fs = require("fs");
const os = require("os");
import fs from "fs";
import os from "os";
const config = require("./config");
import * as config from "./config";
const REOPEN_EVERY = 60000;
@@ -90,7 +90,7 @@ function reopen() {
setTimeout(reopen, REOPEN_EVERY - (Date.now() % REOPEN_EVERY)).unref();
}
function init(service, version) {
export function init(service, version) {
defaultMeta.hostname = os.hostname();
defaultMeta.pid = process.pid;
defaultMeta.name = `genieacs-${service}`;
@@ -129,12 +129,12 @@ function init(service, version) {
setTimeout(reopen, REOPEN_EVERY - (Date.now() % REOPEN_EVERY)).unref();
}
function close() {
export function close() {
accessLogStream.end();
logStream.end();
}
function flatten(details) {
export function flatten(details) {
if (details.sessionContext) {
details.deviceId = details.sessionContext.deviceId;
details.remoteAddress =
@@ -265,22 +265,22 @@ function log(details) {
}
}
function info(details) {
export function info(details) {
details.severity = "info";
log(details);
}
function warn(details) {
export function warn(details) {
details.severity = "warn";
log(details);
}
function error(details) {
export function error(details) {
details.severity = "error";
log(details);
}
function accessLog(details) {
export function accessLog(details) {
details.timestamp = new Date().toISOString();
if (ACCESS_LOG_FORMAT === "json") {
Object.assign(details, defaultMeta);
@@ -290,27 +290,17 @@ function accessLog(details) {
}
}
function accessInfo(details) {
export function accessInfo(details) {
details.severity = "info";
accessLog(details);
}
function accessWarn(details) {
export function accessWarn(details) {
details.severity = "warn";
accessLog(details);
}
function accessError(details) {
export function accessError(details) {
details.severity = "error";
accessLog(details);
}
exports.init = init;
exports.close = close;
exports.flatten = flatten;
exports.info = info;
exports.warn = warn;
exports.error = error;
exports.accessInfo = accessInfo;
exports.accessWarn = accessWarn;
exports.accessError = accessError;
+13 -16
View File
@@ -18,18 +18,17 @@
*/
"use strict";
const url = require("url");
const mongodb = require("mongodb");
const querystring = require("querystring");
const vm = require("vm");
const childProcess = require("child_process");
const config = require("./config");
const db = require("./db");
const query = require("./query");
const apiFunctions = require("./api-functions");
const cache = require("./cache");
const VERSION = require("../package.json").version;
import url from "url";
import mongodb from "mongodb";
import querystring from "querystring";
import vm from "vm";
import { exec } from "child_process";
import * as config from "./config";
import * as db from "./db";
import * as query from "./query";
import * as apiFunctions from "./api-functions";
import * as cache from "./cache";
import { version as VERSION } from "../package.json";
const DEVICE_TASKS_REGEX = /^\/devices\/([a-zA-Z0-9\-_%]+)\/tasks\/?$/;
const TASKS_REGEX = /^\/tasks\/([a-zA-Z0-9\-_%]+)(\/[a-zA-Z_]*)?$/;
@@ -52,7 +51,7 @@ function throwError(err, httpResponse) {
throw err;
}
function listener(request, response) {
export function listener(request, response) {
const chunks = [];
let bytes = 0;
response.setHeader("GenieACS-Version", VERSION);
@@ -520,7 +519,7 @@ function listener(request, response) {
}
} else if (PING_REGEX.test(urlParts.pathname)) {
const host = querystring.unescape(PING_REGEX.exec(urlParts.pathname)[1]);
childProcess.exec(`ping -w 1 -i 0.2 -c 3 ${host}`, (err, stdout) => {
exec(`ping -w 1 -i 0.2 -c 3 ${host}`, (err, stdout) => {
if (err) {
response.writeHead(404, { "Cache-Control": "no-cache" });
response.end(`${err.name}: ${err.message}`);
@@ -661,5 +660,3 @@ function listener(request, response) {
}
});
}
exports.listener = listener;
+1 -3
View File
@@ -18,7 +18,7 @@
*/
"use strict";
class PathSet {
export default class PathSet {
constructor() {
this.lengthIndex = [];
this.fragmentIndex = [];
@@ -161,5 +161,3 @@ class PathSet {
return res;
}
}
module.exports = PathSet;
+7 -13
View File
@@ -18,7 +18,7 @@
*/
"use strict";
const common = require("./common");
import * as common from "./common";
function stringToRegexp(input, flags) {
if (input.indexOf("*") === -1) return false;
@@ -53,7 +53,7 @@ function normalize(input) {
return input;
}
function expandValue(value) {
export function expandValue(value) {
if (common.typeOf(value) === common.ARRAY_TYPE) {
let a = [];
for (const j of value) a = a.conact(expandValue(j));
@@ -104,7 +104,7 @@ function permute(param, val) {
return conditions;
}
function expand(query) {
export function expand(query) {
const newQuery = {};
for (const [k, v] of Object.entries(query)) {
if (k[0] === "$") {
@@ -157,7 +157,7 @@ function testExpressions(params, expressions, lop) {
}
}
function test(params, query) {
export function test(params, query) {
let res;
for (const [k, v] of Object.entries(query)) {
if (k.charAt(0) === "$") {
@@ -233,7 +233,7 @@ function matchType(src, dst) {
return dst;
}
function testFilter(obj, filter) {
export function testFilter(obj, filter) {
for (const [k, v] of Object.entries(filter)) {
const [param, op] = k.split(/([^a-zA-Z0-9\-_.].*)/, 2);
const val = matchType(obj[param], v);
@@ -264,7 +264,7 @@ function testFilter(obj, filter) {
return true;
}
function convertMongoQueryToFilters(query, filters) {
export function convertMongoQueryToFilters(query, filters) {
filters = filters || {};
for (let [k, v] of Object.entries(query)) {
if (k[0] === "$") {
@@ -346,7 +346,7 @@ function convertMongoQueryToFilters(query, filters) {
return filters;
}
function sanitizeQueryTypes(query, types) {
export function sanitizeQueryTypes(query, types) {
for (const [k, v] of Object.entries(query)) {
if (k[0] === "$") {
// Logical operator
@@ -383,9 +383,3 @@ function sanitizeQueryTypes(query, types) {
return query;
}
exports.expand = expand;
exports.test = test;
exports.sanitizeQueryTypes = sanitizeQueryTypes;
exports.convertMongoQueryToFilters = convertMongoQueryToFilters;
exports.testFilter = testFilter;
+8 -10
View File
@@ -18,15 +18,15 @@
*/
"use strict";
const vm = require("vm");
import vm from "vm";
const seedrandom = require("seedrandom");
import seedrandom from "seedrandom";
const common = require("./common");
const device = require("./device");
const extensions = require("./extensions");
const logger = require("./logger");
const scheduling = require("./scheduling");
import * as common from "./common";
import * as device from "./device";
import * as extensions from "./extensions";
import * as logger from "./logger";
import * as scheduling from "./scheduling";
// Used for throwing to exit user script and commit
const COMMIT = Symbol();
@@ -327,7 +327,7 @@ function errorToFault(err) {
return fault;
}
function run(
export function run(
script,
globals,
sessionContext,
@@ -416,5 +416,3 @@ function run(
}
}
}
exports.run = run;
+6 -11
View File
@@ -18,9 +18,9 @@
*/
"use strict";
const crypto = require("crypto");
import crypto from "crypto";
const later = require("later");
import later from "later";
function md532(str) {
const digest = crypto
@@ -35,22 +35,22 @@ function md532(str) {
);
}
function variance(deviceId, vrnc) {
export function variance(deviceId, vrnc) {
return (md532(deviceId) >>> 0) % vrnc;
}
function interval(timestamp, intrvl, offset = 0) {
export function interval(timestamp, intrvl, offset = 0) {
return Math.trunc((timestamp + offset) / intrvl) * intrvl - offset;
}
function parseCron(cronExp) {
export function parseCron(cronExp) {
const parts = cronExp.trim().split(/\s+/);
if (parts.length === 5) parts.unshift("*");
return later.schedule(later.parse.cron(parts.join(" "), true));
}
function cron(timestamp, schedule, offset = 0) {
export function cron(timestamp, schedule, offset = 0) {
// TODO later.js doesn't throw erorr if expression is invalid!
const ret = [0, 0];
@@ -62,8 +62,3 @@ function cron(timestamp, schedule, offset = 0) {
return ret;
}
exports.variance = variance;
exports.interval = interval;
exports.parseCron = parseCron;
exports.cron = cron;
+5 -8
View File
@@ -18,9 +18,9 @@
*/
"use strict";
const fs = require("fs");
const http = require("http");
const https = require("https");
import fs from "fs";
import http from "http";
import https from "https";
let server, listener;
@@ -48,7 +48,7 @@ function closeServer(timeout, callback) {
});
}
function start(port, networkInterface, ssl, _listener, onConnection) {
export function start(port, networkInterface, ssl, _listener, onConnection) {
listener = _listener;
if (ssl) {
@@ -76,7 +76,7 @@ function start(port, networkInterface, ssl, _listener, onConnection) {
server.listen(port, networkInterface);
}
function stop() {
export function stop() {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error("Could not close server in a timely manner"));
@@ -84,6 +84,3 @@ function stop() {
closeServer(20000, resolve);
});
}
exports.start = start;
exports.stop = stop;
+23 -35
View File
@@ -18,17 +18,17 @@
*/
"use strict";
const config = require("./config");
const common = require("./common");
const db = require("./db");
const device = require("./device");
const sandbox = require("./sandbox");
const localCache = require("./local-cache");
const PathSet = require("./path-set");
const VersionedMap = require("./versioned-map");
const InstanceSet = require("./instance-set");
const defaultProvisions = require("./default-provisions");
const gpnHeuristic = require("./gpn-heuristic");
import * as config from "./config";
import * as common from "./common";
import * as db from "./db";
import * as device from "./device";
import * as sandbox from "./sandbox";
import * as localCache from "./local-cache";
import * as defaultProvisions from "./default-provisions";
import { estimateGpnCount } from "./gpn-heuristic";
import PathSet from "./path-set";
import VersionedMap from "./versioned-map";
import InstanceSet from "./instance-set";
function initDeviceData() {
return {
@@ -41,7 +41,7 @@ function initDeviceData() {
};
}
function init(deviceId, cwmpVersion, timeout, callback) {
export function init(deviceId, cwmpVersion, timeout, callback) {
const timestamp = Date.now();
const sessionContext = {
timestamp: timestamp,
@@ -112,7 +112,7 @@ function generateRpcId(sessionContext) {
);
}
function inform(sessionContext, rpcReq, callback) {
export function inform(sessionContext, rpcReq, callback) {
const timestamp = sessionContext.timestamp + sessionContext.iteration + 1;
const params = [
[
@@ -244,7 +244,7 @@ function inform(sessionContext, rpcReq, callback) {
});
}
function transferComplete(sessionContext, rpcReq, callback) {
export function transferComplete(sessionContext, rpcReq, callback) {
const revision =
(sessionContext.revisions[sessionContext.revisions.length - 1] || 0) + 1;
sessionContext.deviceData.timestamps.revision = revision;
@@ -410,7 +410,7 @@ function revertDownloadParameters(sessionContext, instance, callback) {
});
}
function timeoutOperations(sessionContext, callback) {
export function timeoutOperations(sessionContext, callback) {
const revision =
(sessionContext.revisions[sessionContext.revisions.length - 1] || 0) + 1;
sessionContext.deviceData.timestamps.revision = revision;
@@ -460,7 +460,7 @@ function timeoutOperations(sessionContext, callback) {
if ((counter -= 2) === 1) callback(null, faults, operations);
}
function addProvisions(sessionContext, channel, provisions) {
export function addProvisions(sessionContext, channel, provisions) {
// Multiply by two because every iteration is two
// phases: read and update
const MAX_ITERATIONS =
@@ -513,7 +513,7 @@ function addProvisions(sessionContext, channel, provisions) {
}
}
function clearProvisions(sessionContext) {
export function clearProvisions(sessionContext) {
// Multiply by two because every iteration is two
// phases: read and update
const MAX_ITERATIONS =
@@ -958,7 +958,7 @@ function runDeclarations(sessionContext, declarations) {
);
}
function rpcRequest(sessionContext, _declarations, callback) {
export function rpcRequest(sessionContext, _declarations, callback) {
if (sessionContext.rpcRequest != null) {
return void callback(
null,
@@ -1560,7 +1560,7 @@ function generateGetRpcRequest(sessionContext) {
const v = syncState.gpnPatterns.get(p);
if (v) patterns.push([p, (v >> path.length) << path.length]);
}
est = gpnHeuristic.estimateGpnCount(patterns);
est = estimateGpnCount(patterns);
}
if (est < Math.pow(2, Math.max(0, 8 - path.length))) {
@@ -2250,7 +2250,7 @@ function clear(sessionContext, toClear, callback) {
});
}
function rpcResponse(sessionContext, id, rpcRes, callback) {
export function rpcResponse(sessionContext, id, rpcRes, callback) {
if (id !== generateRpcId(sessionContext))
return void callback(new Error("Request ID not recognized"));
@@ -2583,7 +2583,7 @@ function rpcResponse(sessionContext, id, rpcRes, callback) {
clear(sessionContext, toClear, callback);
}
function rpcFault(sessionContext, id, faultResponse, callback) {
export function rpcFault(sessionContext, id, faultResponse, callback) {
const rpcReq = sessionContext.rpcRequest;
delete sessionContext.syncState;
delete sessionContext.rpcRequest;
@@ -2627,7 +2627,7 @@ function rpcFault(sessionContext, id, faultResponse, callback) {
callback(null, fault);
}
function deserialize(sessionContextString, callback) {
export function deserialize(sessionContextString, callback) {
const sessionContext = JSON.parse(sessionContextString);
for (const decs of sessionContext.declarations)
@@ -2654,7 +2654,7 @@ function deserialize(sessionContextString, callback) {
});
}
function serialize(sessionContext, callback) {
export function serialize(sessionContext, callback) {
const deviceData = [];
for (const path of sessionContext.deviceData.paths.find(
@@ -2682,15 +2682,3 @@ function serialize(sessionContext, callback) {
callback(null, sessionContextString);
}
exports.init = init;
exports.timeoutOperations = timeoutOperations;
exports.inform = inform;
exports.transferComplete = transferComplete;
exports.addProvisions = addProvisions;
exports.clearProvisions = clearProvisions;
exports.rpcRequest = rpcRequest;
exports.rpcResponse = rpcResponse;
exports.rpcFault = rpcFault;
exports.serialize = serialize;
exports.deserialize = deserialize;
+6 -9
View File
@@ -18,11 +18,11 @@
*/
"use strict";
const libxmljs = require("libxmljs");
import libxmljs from "libxmljs";
import * as config from "./config";
import { version as VERSION } from "../package.json";
const config = require("./config");
const SERVER_NAME = `GenieACS/${require("../package.json").version}`;
const SERVER_NAME = `GenieACS/${VERSION}`;
const NAMESPACES = {
"1.0": {
@@ -518,7 +518,7 @@ function fault(xml) {
return { faultCode, faultString, detail };
}
function request(data, cwmpVersion, warn) {
export function request(data, cwmpVersion, warn) {
warnings = warn;
const rpc = {
@@ -642,7 +642,7 @@ function createSoapEnv(cwmpVersion) {
return env;
}
function response(rpc) {
export function response(rpc) {
const headers = {
Server: SERVER_NAME,
SOAPServer: SERVER_NAME
@@ -716,6 +716,3 @@ function response(rpc) {
data: env.doc().toString(LIBXMLJS_SAVE_OPTIONS)
};
}
exports.request = request;
exports.response = response;
+17 -17
View File
@@ -1,19 +1,19 @@
"use strict";
const Koa = require("koa");
const Router = require("koa-router");
const koaStatic = require("koa-static");
const koaCompress = require("koa-compress");
const koaBodyParser = require("koa-bodyparser");
const koaJwt = require("koa-jwt");
const jwt = require("jsonwebtoken");
const config = require("./config");
const api = require("./ui/api");
const Authorizer = require("./common/authorizer");
const expression = require("./common/expression");
const logger = require("./logger");
const localCache = require("./local-cache");
import { Z_SYNC_FLUSH } from "zlib";
import Koa from "koa";
import Router from "koa-router";
import * as jwt from "jsonwebtoken";
import koaStatic from "koa-static";
import koaCompress from "koa-compress";
import koaBodyParser from "koa-bodyparser";
import koaJwt from "koa-jwt";
import * as config from "./config";
import api from "./ui/api";
import Authorizer from "./common/authorizer";
import { parse } from "./common/expression-parser";
import * as logger from "./logger";
import * as localCache from "./local-cache";
const koa = new Koa();
const router = new Router();
@@ -41,7 +41,7 @@ function getPermissionSets(ctx) {
].includes(k)
) {
if (v.filter == null || v.filter === "") v.filter = true;
else v.filter = expression.parse(v.filter);
else v.filter = parse(v.filter);
}
}
return p;
@@ -175,11 +175,11 @@ router.get("/", async ctx => {
koa.use(
koaCompress({
flush: require("zlib").Z_SYNC_FLUSH
flush: Z_SYNC_FLUSH
})
);
koa.use(router.routes());
koa.use(koaStatic("./public"));
exports.listener = koa.callback();
export const listener = koa.callback();
+13 -22
View File
@@ -1,14 +1,13 @@
"use strict";
const http = require("http");
const https = require("https");
const url = require("url");
import http from "http";
import https from "https";
import url from "url";
import * as config from "../config";
import * as db from "./db";
import * as mongodbFunctions from "./mongodb-functions";
const config = require("../config");
const db = require("./db");
const mongodbFunctions = require("./mongodb-functions");
function filterToMongoQuery(filter, negate = false, res = {}) {
export function filterToMongoQuery(filter, negate = false, res = {}) {
const op = filter[0];
if ((!negate && op === "AND") || (negate && op === "OR")) {
@@ -66,7 +65,7 @@ function filterToMongoQuery(filter, negate = false, res = {}) {
return res;
}
function deleteResource(resource, id) {
export function deleteResource(resource, id) {
return new Promise((resolve, reject) => {
const resourceUrl =
resource === "virtualParameters" ? "virtual_parameters" : resource;
@@ -142,7 +141,7 @@ function postTask(task, connectionRequest, callback) {
.end(JSON.stringify(task));
}
function postTasks(deviceId, tasks) {
export function postTasks(deviceId, tasks) {
return new Promise((resolve, reject) => {
let connectionRequestStatus;
const promises = [];
@@ -206,7 +205,7 @@ function postTasks(deviceId, tasks) {
});
}
function updateTags(deviceId, tags) {
export function updateTags(deviceId, tags) {
return Promise.all(
Object.entries(tags).map(
([tag, onOff]) =>
@@ -235,7 +234,7 @@ function updateTags(deviceId, tags) {
);
}
function ping(host) {
export function ping(host) {
return new Promise((resolve, reject) => {
const options = url.parse(
`http://127.0.0.1:${config.get("NBI_PORT")}/ping/${encodeURIComponent(
@@ -295,7 +294,7 @@ function ping(host) {
});
}
function putResource(resource, id, data) {
export function putResource(resource, id, data) {
return new Promise((resolve, reject) => {
const resourceUrl =
resource === "virtualParameters" ? "virtual_parameters" : resource;
@@ -348,7 +347,7 @@ function putResource(resource, id, data) {
});
}
function putFile(id, metadata, fileStream) {
export function putFile(id, metadata, fileStream) {
return new Promise((resolve, reject) => {
const options = url.parse(
`http://127.0.0.1:${config.get("NBI_PORT")}/files/${encodeURIComponent(
@@ -372,11 +371,3 @@ function putFile(id, metadata, fileStream) {
fileStream.pipe(req);
});
}
exports.postTasks = postTasks;
exports.deleteResource = deleteResource;
exports.putResource = putResource;
exports.updateTags = updateTags;
exports.filterToMongoQuery = filterToMongoQuery;
exports.ping = ping;
exports.putFile = putFile;
+17 -20
View File
@@ -1,13 +1,15 @@
"use strict";
const stream = require("stream");
const Router = require("koa-router");
const db = require("./db");
const apiFunctions = require("./api-functions");
const expression = require("../common/expression");
const logger = require("../logger");
import stream from "stream";
import Router from "koa-router";
import * as db from "./db";
import * as apiFunctions from "./api-functions";
import { evaluate, and, extractParams } from "../common/expression";
import { parse } from "../common/expression-parser";
import * as logger from "../logger";
const router = new Router();
export default router;
function logUnauthorizedWarning(log) {
log.message += " not authorized";
@@ -87,8 +89,7 @@ router.get(`/devices/:id.csv`, async ctx => {
for (const [resource, flags] of Object.entries(resources)) {
router.head(`/${resource}`, async (ctx, next) => {
let filter = true;
if (ctx.request.query.filter)
filter = expression.parse(ctx.request.query.filter);
if (ctx.request.query.filter) filter = parse(ctx.request.query.filter);
const log = {
message: `Count ${resource}`,
@@ -103,7 +104,7 @@ for (const [resource, flags] of Object.entries(resources)) {
// Exclude temporary tasks and faults
if (resource === "tasks" || resource === "faults") {
filter = expression.and(filter, [
filter = and(filter, [
"NOT",
["<", ["PARAM", "expiry"], Date.now() + 60000]
]);
@@ -121,8 +122,7 @@ for (const [resource, flags] of Object.entries(resources)) {
router.get(`/${resource}`, async (ctx, next) => {
const options = {};
let filter = true;
if (ctx.request.query.filter)
filter = expression.parse(ctx.request.query.filter);
if (ctx.request.query.filter) filter = parse(ctx.request.query.filter);
if (ctx.request.query.limit) options.limit = +ctx.request.query.limit;
if (ctx.request.query.skip) options.skip = +ctx.request.query.skip;
if (ctx.request.query.sort)
@@ -150,7 +150,7 @@ for (const [resource, flags] of Object.entries(resources)) {
// Exclude temporary tasks and faults
if (resource === "tasks" || resource === "faults") {
filter = expression.and(filter, [
filter = and(filter, [
"NOT",
["<", ["PARAM", "expiry"], Date.now() + 60000]
]);
@@ -173,8 +173,7 @@ for (const [resource, flags] of Object.entries(resources)) {
router.get(`/${resource}.csv`, async (ctx, next) => {
const options = { projection: {} };
let filter = true;
if (ctx.request.query.filter)
filter = expression.parse(ctx.request.query.filter);
if (ctx.request.query.filter) filter = parse(ctx.request.query.filter);
if (ctx.request.query.limit) options.limit = +ctx.request.query.limit;
if (ctx.request.query.skip) options.skip = +ctx.request.query.skip;
if (ctx.request.query.sort)
@@ -198,14 +197,14 @@ for (const [resource, flags] of Object.entries(resources)) {
const now = Date.now();
for (const [k, v] of Object.entries(columns)) {
const e = expression.evaluate(expression.parse(v), null, now);
const e = evaluate(parse(v), null, now);
columns[k] = e;
for (const p of expression.extractParams(e)) options.projection[p] = 1;
for (const p of extractParams(e)) options.projection[p] = 1;
}
// Exclude temporary tasks and faults
if (resource === "tasks" || resource === "faults") {
filter = expression.and(filter, [
filter = and(filter, [
"NOT",
["<", ["PARAM", "expiry"], Date.now() + 60000]
]);
@@ -222,7 +221,7 @@ for (const [resource, flags] of Object.entries(resources)) {
);
await db.query(resource, filter, options, obj => {
const arr = Object.values(columns).map(exp => {
const v = expression.evaluate(exp, obj, null, e => {
const v = evaluate(exp, obj, null, e => {
if (Array.isArray(e)) {
if (e[0] === "PARAM") {
if (resource === "devices") {
@@ -481,5 +480,3 @@ router.post("/devices/:id/tags", async (ctx, next) => {
router.get("/ping/:host", async ctx => {
ctx.body = await apiFunctions.ping(ctx.params.host);
});
module.exports = router;
+9 -14
View File
@@ -1,9 +1,9 @@
"use strict";
const mongodb = require("mongodb");
const config = require("../config");
const mongodbFunctions = require("./mongodb-functions");
const expression = require("../common/expression");
import { MongoClient } from "mongodb";
import * as config from "../config";
import * as mongodbFunctions from "./mongodb-functions";
import * as expression from "../common/expression";
const CACHE_TTL = 300000;
@@ -24,7 +24,7 @@ function getClient() {
if (!_clientPromise) {
_clientPromise = new Promise((resolve, reject) => {
const CONNECTION_URL = config.get("MONGODB_CONNECTION_URL");
mongodb.MongoClient.connect(
MongoClient.connect(
CONNECTION_URL,
{ useNewUrlParser: true },
(err, client) => {
@@ -39,7 +39,7 @@ function getClient() {
return _clientPromise;
}
function cache(key, valueGetter, ttl) {
export function cache(key, valueGetter, ttl) {
return new Promise((resolve, reject) => {
getClient()
.then(client => {
@@ -72,7 +72,7 @@ function cache(key, valueGetter, ttl) {
});
}
function query(resource, filter, options, callback) {
export function query(resource, filter, options, callback) {
options = options || {};
let q;
filter = expression.evaluate(filter, null, Date.now());
@@ -158,7 +158,7 @@ function query(resource, filter, options, callback) {
});
}
function count(resource, filter) {
export function count(resource, filter) {
let q;
filter = expression.evaluate(filter, null, Date.now());
@@ -187,15 +187,10 @@ function count(resource, filter) {
});
}
function disconnect() {
export function disconnect() {
if (_clientPromise) {
_clientPromise.then(client => {
client.close();
});
}
}
exports.query = query;
exports.count = count;
exports.cache = cache;
exports.disconnect = disconnect;
+25 -43
View File
@@ -1,10 +1,10 @@
"use strict";
const mongodb = require("mongodb");
const expressionParser = require("../common/expression-parser");
const expression = require("../common/expression");
import { ObjectID } from "mongodb";
import { map, parse, stringify } from "../common/expression-parser";
import { likePatternToRegExp } from "../common/expression";
function processDeviceFilter(filter) {
return expressionParser.map(filter, exp => {
export function processDeviceFilter(filter) {
return map(filter, exp => {
if (!Array.isArray(exp)) return exp;
if (exp[0] === "PARAM") {
@@ -32,7 +32,7 @@ function processDeviceFilter(filter) {
} else if (
["=", "<>", ">", ">=", "<", "<=", "LIKE", "NOT LIKE"].includes(exp[0])
) {
let e = expressionParser.map(exp, ee => {
let e = map(exp, ee => {
if (
Array.isArray(ee) &&
ee[0] === "PARAM" &&
@@ -54,13 +54,12 @@ function processDeviceFilter(filter) {
});
}
function processTasksFilter(filter) {
return expressionParser.map(filter, exp => {
export function processTasksFilter(filter) {
return map(filter, exp => {
if (!Array.isArray(exp)) return exp;
if (["=", "<>", ">", ">=", "<", "<="].includes(exp[0])) {
const e = exp.slice();
if (e[1][0] === "PARAM" && e[1][1] === "_id")
e[2] = new mongodb.ObjectID(e[2]);
if (e[1][0] === "PARAM" && e[1][1] === "_id") e[2] = new ObjectID(e[2]);
else if (e[1][0] === "PARAM" && e[1][1] === "timestamp")
e[2] = new Date(e[2]);
else if (e[1][0] === "PARAM" && e[1][1] === "expiry")
@@ -71,8 +70,8 @@ function processTasksFilter(filter) {
});
}
function processFaultsFilter(filter) {
return expressionParser.map(filter, exp => {
export function processFaultsFilter(filter) {
return map(filter, exp => {
if (!Array.isArray(exp)) return exp;
if (["=", "<>", ">", ">=", "<", "<="].includes(exp[0])) {
const e = exp.slice();
@@ -85,7 +84,7 @@ function processFaultsFilter(filter) {
});
}
function filterToMongoQuery(filter, negate = false, res = {}) {
export function filterToMongoQuery(filter, negate = false, res = {}) {
const op = filter[0];
if ((!negate && op === "AND") || (negate && op === "OR")) {
@@ -160,7 +159,7 @@ function filterToMongoQuery(filter, negate = false, res = {}) {
param = filter[1][1];
flags = "";
}
const r = expression.likePatternToRegExp(filter[2], filter[3], flags);
const r = likePatternToRegExp(filter[2], filter[3], flags);
if (negate) res[param] = { $not: r };
else res[param] = r;
} else {
@@ -170,7 +169,7 @@ function filterToMongoQuery(filter, negate = false, res = {}) {
return res;
}
function processDeviceProjection(projection) {
export function processDeviceProjection(projection) {
if (!projection) return projection;
const p = {};
for (const [k, v] of Object.entries(projection)) {
@@ -196,7 +195,7 @@ function processDeviceProjection(projection) {
return p;
}
function processDeviceSort(sort) {
export function processDeviceSort(sort) {
if (!sort) return sort;
const s = {};
for (const [k, v] of Object.entries(sort)) {
@@ -217,7 +216,7 @@ function parseDate(d) {
return isNaN(n) ? "" + d : n;
}
function flattenDevice(device) {
export function flattenDevice(device) {
function recursive(input, root, output, timestamp) {
for (const [name, tree] of Object.entries(input)) {
if (!root) {
@@ -361,14 +360,14 @@ function flattenDevice(device) {
return newDevice;
}
function flattenFault(fault) {
export function flattenFault(fault) {
const f = Object.assign({}, fault);
if (f.timestamp) f.timestamp = +f.timestamp;
if (f.expiry) f.expiry = +f.expiry;
return f;
}
function flattenTask(task) {
export function flattenTask(task) {
const t = Object.assign({}, task);
t._id = "" + t._id;
if (t.timestamp) t.timestamp = +t.timestamp;
@@ -443,13 +442,11 @@ function mongoQueryToFilter(query) {
return expressions;
}
function flattenPreset(preset) {
export function flattenPreset(preset) {
const p = Object.assign({}, preset);
if (p.precondition) {
p.precondition = mongoQueryToFilter(JSON.parse(p.precondition));
p.precondition = p.precondition.length
? expression.stringify(p.precondition)
: "";
p.precondition = p.precondition.length ? stringify(p.precondition) : "";
}
if (p.events) {
@@ -474,7 +471,7 @@ function flattenPreset(preset) {
return p;
}
function flattenFile(file) {
export function flattenFile(file) {
const f = {};
f["_id"] = file["_id"];
if (file.metadata) {
@@ -486,10 +483,10 @@ function flattenFile(file) {
return f;
}
function preProcessPreset(data) {
export function preProcessPreset(data) {
const preset = Object.assign({}, data);
preset.precondition = preset.precondition
? filterToMongoQuery(expression.parse(preset.precondition))
? filterToMongoQuery(parse(preset.precondition))
: {};
preset.precondition = JSON.stringify(preset.precondition);
@@ -526,25 +523,10 @@ function preProcessPreset(data) {
return preset;
}
function preProcessProvision(data) {
export function preProcessProvision(data) {
return data.script;
}
function preProcessVirtualParameters(data) {
export function preProcessVirtualParameters(data) {
return data.script;
}
exports.processDeviceFilter = processDeviceFilter;
exports.processTasksFilter = processTasksFilter;
exports.processFaultsFilter = processFaultsFilter;
exports.filterToMongoQuery = filterToMongoQuery;
exports.processDeviceProjection = processDeviceProjection;
exports.processDeviceSort = processDeviceSort;
exports.flattenDevice = flattenDevice;
exports.flattenFault = flattenFault;
exports.flattenTask = flattenTask;
exports.flattenPreset = flattenPreset;
exports.flattenFile = flattenFile;
exports.preProcessPreset = preProcessPreset;
exports.preProcessProvision = preProcessProvision;
exports.preProcessVirtualParameters = preProcessVirtualParameters;
+1 -3
View File
@@ -21,7 +21,7 @@
const NONEXISTENT = new Object();
const UNDEFINED = undefined;
class VersionedMap {
export default class VersionedMap {
constructor() {
this._sizeDiff = [0];
this._revision = 0;
@@ -189,5 +189,3 @@ class VersionedMap {
}
}
}
module.exports = VersionedMap;