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:
1 parent
824639976f
commit
1e41c72d60
62 files changed
+718
-898
No files matched your search
+2
-1
@@ -4,7 +4,8 @@
|
||||
"node": true
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 8
|
||||
"ecmaVersion": 8,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"extends": "eslint:recommended",
|
||||
"rules": {
|
||||
|
||||
+12
-12
@@ -1,20 +1,20 @@
|
||||
#!/usr/bin/env node
|
||||
#!/usr/bin/env -S node -r esm
|
||||
"use strict";
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
|
||||
process.chdir(path.resolve(path.dirname(fs.realpathSync(__filename)), ".."));
|
||||
|
||||
const config = require("../lib/config");
|
||||
const logger = require("../lib/logger");
|
||||
const cluster = require("../lib/cluster");
|
||||
const server = require("../lib/server");
|
||||
const cwmp = require("../lib/cwmp");
|
||||
const db = require("../lib/db");
|
||||
const extensions = require("../lib/extensions");
|
||||
const cache = require("../lib/cache");
|
||||
import * as config from "../lib/config";
|
||||
import * as logger from "../lib/logger";
|
||||
import * as cluster from "../lib/cluster";
|
||||
import * as server from "../lib/server";
|
||||
import * as cwmp from "../lib/cwmp";
|
||||
import * as db from "../lib/db";
|
||||
import * as extensions from "../lib/extensions";
|
||||
import * as cache from "../lib/cache";
|
||||
|
||||
const VERSION = require("../package.json").version;
|
||||
import { version as VERSION } from "../package.json";
|
||||
|
||||
logger.init("cwmp", VERSION);
|
||||
|
||||
|
||||
+12
-19
@@ -1,19 +1,18 @@
|
||||
#!/usr/bin/env node
|
||||
#!/usr/bin/env -S node -r esm
|
||||
"use strict";
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
|
||||
process.chdir(path.resolve(path.dirname(fs.realpathSync(__filename)), ".."));
|
||||
|
||||
const config = require("../lib/config");
|
||||
const logger = require("../lib/logger");
|
||||
const cluster = require("../lib/cluster");
|
||||
const server = require("../lib/server");
|
||||
const _fs = require("../lib/fs");
|
||||
const db = require("../lib/db");
|
||||
const cache = require("../lib/cache");
|
||||
|
||||
const VERSION = require("../package.json").version;
|
||||
import * as config from "../lib/config";
|
||||
import * as logger from "../lib/logger";
|
||||
import * as cluster from "../lib/cluster";
|
||||
import * as server from "../lib/server";
|
||||
import { listener } from "../lib/fs";
|
||||
import * as db from "../lib/db";
|
||||
import * as cache from "../lib/cache";
|
||||
import { version as VERSION } from "../package.json";
|
||||
|
||||
logger.init("fs", VERSION);
|
||||
|
||||
@@ -99,13 +98,7 @@ if (!cluster.worker) {
|
||||
if (err) throw err;
|
||||
cache.connect(err => {
|
||||
if (err) throw err;
|
||||
server.start(
|
||||
SERVICE_PORT,
|
||||
SERVICE_ADDRESS,
|
||||
ssl,
|
||||
_fs.listener,
|
||||
_fs.onConnection
|
||||
);
|
||||
server.start(SERVICE_PORT, SERVICE_ADDRESS, ssl, listener);
|
||||
});
|
||||
});
|
||||
}
|
||||
+13
-20
@@ -1,20 +1,19 @@
|
||||
#!/usr/bin/env node
|
||||
#!/usr/bin/env -S node -r esm
|
||||
"use strict";
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
|
||||
process.chdir(path.resolve(path.dirname(fs.realpathSync(__filename)), ".."));
|
||||
|
||||
const config = require("../lib/config");
|
||||
const logger = require("../lib/logger");
|
||||
const cluster = require("../lib/cluster");
|
||||
const server = require("../lib/server");
|
||||
const nbi = require("../lib/nbi");
|
||||
const db = require("../lib/db");
|
||||
const extensions = require("../lib/extensions");
|
||||
const cache = require("../lib/cache");
|
||||
|
||||
const VERSION = require("../package.json").version;
|
||||
import * as config from "../lib/config";
|
||||
import * as logger from "../lib/logger";
|
||||
import * as cluster from "../lib/cluster";
|
||||
import * as server from "../lib/server";
|
||||
import { listener } from "../lib/nbi";
|
||||
import * as db from "../lib/db";
|
||||
import * as extensions from "../lib/extensions";
|
||||
import * as cache from "../lib/cache";
|
||||
import { version as VERSION } from "../package.json";
|
||||
|
||||
logger.init("nbi", VERSION);
|
||||
|
||||
@@ -103,13 +102,7 @@ if (!cluster.worker) {
|
||||
if (err) throw err;
|
||||
cache.connect(err => {
|
||||
if (err) throw err;
|
||||
server.start(
|
||||
SERVICE_PORT,
|
||||
SERVICE_ADDRESS,
|
||||
ssl,
|
||||
nbi.listener,
|
||||
nbi.onConnection
|
||||
);
|
||||
server.start(SERVICE_PORT, SERVICE_ADDRESS, ssl, listener);
|
||||
});
|
||||
});
|
||||
}
|
||||
+15
-22
@@ -1,20 +1,19 @@
|
||||
#!/usr/bin/env node
|
||||
#!/usr/bin/env -S node -r esm
|
||||
"use strict";
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
import * as path from "path";
|
||||
import * as fs from "fs";
|
||||
|
||||
process.chdir(path.resolve(path.dirname(fs.realpathSync(__filename)), ".."));
|
||||
|
||||
const config = require("../lib/config");
|
||||
const logger = require("../lib/logger");
|
||||
const cluster = require("../lib/cluster");
|
||||
const server = require("../lib/server");
|
||||
const ui = require("../lib/ui");
|
||||
const db = require("../lib/ui/db");
|
||||
const db2 = require("../lib/db");
|
||||
const cache = require("../lib/cache");
|
||||
|
||||
const VERSION = require("../package.json").version;
|
||||
import * as config from "../lib/config";
|
||||
import * as logger from "../lib/logger";
|
||||
import * as cluster from "../lib/cluster";
|
||||
import * as server from "../lib/server";
|
||||
import { listener } from "../lib/ui";
|
||||
import * as db from "../lib/ui/db";
|
||||
import * as db2 from "../lib/db";
|
||||
import * as cache from "../lib/cache";
|
||||
import { version as VERSION } from "../package.json";
|
||||
|
||||
logger.init("ui", VERSION);
|
||||
|
||||
@@ -102,22 +101,16 @@ if (!cluster.worker) {
|
||||
.catch(exitWorkerUngracefully);
|
||||
});
|
||||
|
||||
const listener = (req, res) => {
|
||||
const _listener = (req, res) => {
|
||||
if (stopping) res.setHeader("Connection", "close");
|
||||
ui.listener(req, res);
|
||||
listener(req, res);
|
||||
};
|
||||
|
||||
db2.connect(err => {
|
||||
if (err) throw err;
|
||||
cache.connect(err => {
|
||||
if (err) throw err;
|
||||
server.start(
|
||||
SERVICE_PORT,
|
||||
SERVICE_ADDRESS,
|
||||
ssl,
|
||||
listener,
|
||||
ui.onConnection
|
||||
);
|
||||
server.start(SERVICE_PORT, SERVICE_ADDRESS, ssl, _listener);
|
||||
});
|
||||
});
|
||||
}
|
||||
+153
-84
@@ -1,8 +1,11 @@
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
const util = require("util");
|
||||
const { promisify } = require("util");
|
||||
const { rollup } = require("rollup");
|
||||
const rollupReplace = require("rollup-plugin-replace");
|
||||
const rollupJson = require("rollup-plugin-json");
|
||||
const { terser } = require("rollup-plugin-terser");
|
||||
const webpack = require("webpack");
|
||||
const nodeExternals = require("webpack-node-externals");
|
||||
const postcss = require("postcss");
|
||||
const postcssImport = require("postcss-import");
|
||||
const postcssCssNext = require("postcss-cssnext");
|
||||
@@ -18,6 +21,37 @@ const BUILD_METADATA = new Date()
|
||||
const INPUT_DIR = path.resolve(__dirname, "..");
|
||||
const OUTPUT_DIR = path.resolve(__dirname, "../dist");
|
||||
|
||||
const externals = [
|
||||
"path",
|
||||
"fs",
|
||||
"cluster",
|
||||
"os",
|
||||
"http",
|
||||
"https",
|
||||
"zlib",
|
||||
"crypto",
|
||||
"mongodb",
|
||||
"libxmljs",
|
||||
"vm",
|
||||
"later",
|
||||
"parsimmon",
|
||||
"seedrandom",
|
||||
"querystring",
|
||||
"child_process",
|
||||
"dgram",
|
||||
"url",
|
||||
"koa",
|
||||
"koa-router",
|
||||
"koa-compress",
|
||||
"koa-bodyparser",
|
||||
"koa-jwt",
|
||||
"koa-static",
|
||||
"jsonwebtoken",
|
||||
"stream",
|
||||
"mithril",
|
||||
"parsimmon"
|
||||
];
|
||||
|
||||
function rmDirSync(dirPath) {
|
||||
if (!fs.existsSync(dirPath)) return;
|
||||
const files = fs.readdirSync(dirPath);
|
||||
@@ -30,22 +64,6 @@ function rmDirSync(dirPath) {
|
||||
fs.rmdirSync(dirPath);
|
||||
}
|
||||
|
||||
function cpDirSync(src, dst) {
|
||||
fs.mkdirSync(dst);
|
||||
const files = fs.readdirSync(src);
|
||||
for (const file of files) {
|
||||
const current = fs.lstatSync(path.join(src, file));
|
||||
if (current.isDirectory()) {
|
||||
cpDirSync(path.join(src, file), path.join(dst, file));
|
||||
} else if (current.isSymbolicLink()) {
|
||||
const symlink = fs.readlinkSync(path.join(src, file));
|
||||
fs.symlinkSync(symlink, path.join(dst, file));
|
||||
} else {
|
||||
fs.copyFileSync(path.join(src, file), path.join(dst, file));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function init() {
|
||||
// Delete any old output directory
|
||||
rmDirSync(OUTPUT_DIR);
|
||||
@@ -56,6 +74,7 @@ async function init() {
|
||||
fs.mkdirSync(OUTPUT_DIR + "/config");
|
||||
fs.mkdirSync(OUTPUT_DIR + "/debug");
|
||||
fs.mkdirSync(OUTPUT_DIR + "/public");
|
||||
fs.mkdirSync(OUTPUT_DIR + "/tools");
|
||||
|
||||
// Create package.json
|
||||
const packageJson = require("../package.json");
|
||||
@@ -90,11 +109,6 @@ async function copyStatic() {
|
||||
path.resolve(OUTPUT_DIR, file)
|
||||
);
|
||||
}
|
||||
|
||||
cpDirSync(
|
||||
path.resolve(INPUT_DIR, "tools"),
|
||||
path.resolve(OUTPUT_DIR, "tools")
|
||||
);
|
||||
}
|
||||
|
||||
async function generateCss() {
|
||||
@@ -109,82 +123,137 @@ async function generateCss() {
|
||||
fs.writeFileSync(cssOutPath, cssOut.css);
|
||||
}
|
||||
|
||||
async function generateJs() {
|
||||
const backendConf = {
|
||||
mode: MODE,
|
||||
target: "node",
|
||||
node: false,
|
||||
entry: {
|
||||
"genieacs-cwmp": path.resolve(INPUT_DIR, "bin/genieacs-cwmp"),
|
||||
"genieacs-nbi": path.resolve(INPUT_DIR, "bin/genieacs-nbi"),
|
||||
"genieacs-fs": path.resolve(INPUT_DIR, "bin/genieacs-fs"),
|
||||
"genieacs-ui": path.resolve(INPUT_DIR, "bin/genieacs-ui")
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
[path.resolve(INPUT_DIR, "package.json")]: path.resolve(
|
||||
OUTPUT_DIR,
|
||||
"package.json"
|
||||
)
|
||||
}
|
||||
},
|
||||
externals: [nodeExternals()],
|
||||
output: {
|
||||
path: path.resolve(OUTPUT_DIR, "bin")
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
include: path.resolve(INPUT_DIR, "bin"),
|
||||
use: path.join(__dirname, "./shebang-loader")
|
||||
}
|
||||
async function generateToolsJs() {
|
||||
for (const bin of ["configure-ui", "dump-data-model"]) {
|
||||
const inputFile = path.resolve(INPUT_DIR, `tools/${bin}`);
|
||||
const outputFile = path.resolve(OUTPUT_DIR, `tools/${bin}`);
|
||||
const bundle = await rollup({
|
||||
input: inputFile,
|
||||
external: externals,
|
||||
acorn: {
|
||||
allowHashBang: true
|
||||
},
|
||||
plugins: [
|
||||
rollupReplace({
|
||||
delimiters: ["", ""],
|
||||
"#!/usr/bin/env -S node -r esm": ""
|
||||
}),
|
||||
MODE === "production" ? terser() : null
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
new webpack.BannerPlugin({ banner: "#!/usr/bin/env node", raw: true })
|
||||
]
|
||||
};
|
||||
});
|
||||
|
||||
const frontendConf = {
|
||||
mode: MODE,
|
||||
entry: path.resolve(INPUT_DIR, "ui/app.js"),
|
||||
output: {
|
||||
path: path.resolve(OUTPUT_DIR, "public"),
|
||||
filename: "app.js"
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
[path.resolve(INPUT_DIR, "package.json")]: path.resolve(
|
||||
OUTPUT_DIR,
|
||||
"package.json"
|
||||
)
|
||||
}
|
||||
}
|
||||
};
|
||||
await bundle.write({
|
||||
format: "cjs",
|
||||
preferConst: true,
|
||||
banner: "#!/usr/bin/env node",
|
||||
file: outputFile
|
||||
});
|
||||
|
||||
const stats = await util.promisify(webpack)([backendConf, frontendConf]);
|
||||
// Mark as executable
|
||||
const mode = fs.statSync(outputFile).mode;
|
||||
fs.chmodSync(outputFile, mode | 73);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove js ext and mark as executable
|
||||
for (const file of [
|
||||
async function generateBackendJs() {
|
||||
for (const bin of [
|
||||
"genieacs-cwmp",
|
||||
"genieacs-nbi",
|
||||
"genieacs-fs",
|
||||
"genieacs-ui"
|
||||
]) {
|
||||
fs.renameSync(
|
||||
path.resolve(OUTPUT_DIR, `bin/${file}.js`),
|
||||
path.resolve(OUTPUT_DIR, `bin/${file}`)
|
||||
);
|
||||
const mode = fs.statSync(path.resolve(OUTPUT_DIR, `bin/${file}`)).mode;
|
||||
fs.chmodSync(path.resolve(OUTPUT_DIR, `bin/${file}`), mode | 73);
|
||||
}
|
||||
const inputFile = path.resolve(INPUT_DIR, `bin/${bin}`);
|
||||
const outputFile = path.resolve(OUTPUT_DIR, `bin/${bin}`);
|
||||
const bundle = await rollup({
|
||||
input: inputFile,
|
||||
external: externals,
|
||||
acorn: {
|
||||
allowHashBang: true
|
||||
},
|
||||
treeshake: {
|
||||
propertyReadSideEffects: false,
|
||||
pureExternalModules: true
|
||||
},
|
||||
plugins: [
|
||||
rollupReplace({
|
||||
delimiters: ["", ""],
|
||||
"#!/usr/bin/env -S node -r esm": ""
|
||||
}),
|
||||
rollupJson({ preferConst: true }),
|
||||
{
|
||||
resolveId: (importee, importer) => {
|
||||
if (importee.endsWith("/package.json")) {
|
||||
const p = path.resolve(path.dirname(importer), importee);
|
||||
if (p === path.resolve(INPUT_DIR, "package.json"))
|
||||
return path.resolve(OUTPUT_DIR, "package.json");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
},
|
||||
MODE === "production" ? terser() : null
|
||||
]
|
||||
});
|
||||
|
||||
await bundle.write({
|
||||
format: "cjs",
|
||||
preferConst: true,
|
||||
banner: "#!/usr/bin/env node",
|
||||
file: outputFile
|
||||
});
|
||||
|
||||
// Mark as executable
|
||||
const mode = fs.statSync(outputFile).mode;
|
||||
fs.chmodSync(outputFile, mode | 73);
|
||||
}
|
||||
}
|
||||
|
||||
async function generateFrontendJs() {
|
||||
const inputFile = path.resolve(INPUT_DIR, "ui/app.js");
|
||||
const outputFile = path.resolve(OUTPUT_DIR, "public/app.js");
|
||||
|
||||
const bundle = await rollup({
|
||||
input: inputFile,
|
||||
external: externals,
|
||||
plugins: [rollupJson({ preferConst: true })],
|
||||
inlineDynamicImports: true,
|
||||
treeshake: {
|
||||
propertyReadSideEffects: false,
|
||||
pureExternalModules: true
|
||||
},
|
||||
onwarn: (warning, warn) => {
|
||||
// Ignore circular dependency warnings
|
||||
if (warning.code !== "CIRCULAR_DEPENDENCY") warn(warning);
|
||||
}
|
||||
});
|
||||
|
||||
await bundle.write({
|
||||
preferConst: true,
|
||||
format: "esm",
|
||||
file: outputFile
|
||||
});
|
||||
|
||||
const webpackConf = {
|
||||
mode: MODE,
|
||||
entry: outputFile,
|
||||
output: {
|
||||
path: path.resolve(OUTPUT_DIR, "public"),
|
||||
filename: "app.js"
|
||||
}
|
||||
};
|
||||
|
||||
const stats = await promisify(webpack)(webpackConf);
|
||||
process.stdout.write(stats.toString({ colors: true }) + "\n");
|
||||
}
|
||||
|
||||
init()
|
||||
.then(() => {
|
||||
Promise.all([copyStatic(), generateCss(), generateJs()])
|
||||
Promise.all([
|
||||
copyStatic(),
|
||||
generateCss(),
|
||||
generateToolsJs(),
|
||||
generateBackendJs(),
|
||||
generateFrontendJs()
|
||||
])
|
||||
.then(() => {})
|
||||
.catch(err => {
|
||||
process.stderr.write(err.stack + "\n");
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
module.exports = function(source) {
|
||||
return source.replace(/^#![^\n\r]*[\r\n]/, "");
|
||||
};
|
||||
+13
-18
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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,5 +1,3 @@
|
||||
function pass() {
|
||||
export default function pass() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
module.exports = pass;
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
@@ -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;
|
||||
+7
-3
@@ -38,12 +38,16 @@
|
||||
"codemirror": "^5.40.0",
|
||||
"cssnano": "^4.0.5",
|
||||
"eslint": "^5.10.0",
|
||||
"esm": "^3.1.1",
|
||||
"mithril": "^1.1.6",
|
||||
"postcss-cssnext": "^3.1.0",
|
||||
"postcss-import": "^11.1.0",
|
||||
"prettier": "^1.15.3",
|
||||
"rollup": "^1.1.2",
|
||||
"rollup-plugin-json": "^3.1.0",
|
||||
"rollup-plugin-replace": "^2.1.0",
|
||||
"rollup-plugin-terser": "^4.0.2",
|
||||
"webpack": "^4.16.3",
|
||||
"webpack-node-externals": "^1.7.2",
|
||||
"yaml": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
@@ -53,8 +57,8 @@
|
||||
"compile": "echo 'Compile step no longer required, skipping.'",
|
||||
"configure": "if [ ! -f ./config/config.json ]; then cp ./config/config-sample.json ./config/config.json; fi",
|
||||
"install": "npm run configure",
|
||||
"test": "ava --verbose --color",
|
||||
"lint": "eslint --fix lib ui build test bin/*; prettier --write \"lib/**/*.js\" \"ui/**/*.js\" \"build/**/*.js\" \"test/**/*.js\" bin/*",
|
||||
"test": "ava -r esm --verbose --color",
|
||||
"lint": "eslint --fix lib ui build test bin/* tools/*; prettier --parser babylon --write \"lib/**/*.js\" \"ui/**/*.js\" \"build/**/*.js\" \"test/**/*.js\" bin/* tools/*",
|
||||
"build": "node build/build"
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
const ava = require("ava");
|
||||
const common = require("../lib/common.js");
|
||||
import ava from "ava";
|
||||
import * as common from "../lib/common.js";
|
||||
|
||||
ava("typeOf", t => {
|
||||
const cases = [
|
||||
|
||||
+5
-5
@@ -1,8 +1,8 @@
|
||||
#!/usr/bin/env node
|
||||
#!/usr/bin/env -S node -r esm
|
||||
"use strict";
|
||||
|
||||
const mongodb = require("mongodb");
|
||||
const config = require("../lib/config");
|
||||
import { MongoClient } from "mongodb";
|
||||
import { get } from "../lib/config";
|
||||
|
||||
const configData = {
|
||||
"auth.simple.users.admin.password": "'admin'",
|
||||
@@ -158,8 +158,8 @@ const configData = {
|
||||
};
|
||||
|
||||
async function run() {
|
||||
const client = await mongodb.MongoClient.connect(
|
||||
config.get("MONGODB_CONNECTION_URL"),
|
||||
const client = await MongoClient.connect(
|
||||
get("MONGODB_CONNECTION_URL"),
|
||||
{ useNewUrlParser: true }
|
||||
);
|
||||
const collection = client.db().collection("config");
|
||||
|
||||
+35
-42
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env node
|
||||
#!/usr/bin/env -S node -r esm
|
||||
/**
|
||||
* Copyright 2013-2017 Zaid Abdulla
|
||||
*
|
||||
@@ -19,73 +19,66 @@
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { connect, devicesCollection } from "../lib/db";
|
||||
|
||||
const outputFilename = path.resolve(`data_model_${process.argv[2]}.json`);
|
||||
process.chdir(path.resolve(path.dirname(fs.realpathSync(__filename)), ".."));
|
||||
|
||||
const db = require("../lib/db");
|
||||
|
||||
const dataModel = {};
|
||||
|
||||
function recursive(object, p) {
|
||||
if (!p) p = "";
|
||||
|
||||
function recursive(object, path) {
|
||||
if (!path)
|
||||
path = "";
|
||||
for (const key in object) {
|
||||
if (key[0] === "_" || !object[key]) continue;
|
||||
|
||||
for (let key in object) {
|
||||
if (key[0] === "_" || !object[key])
|
||||
continue;
|
||||
|
||||
let isObject = object[key]["_object"];
|
||||
let isValue = "_value" in object[key];
|
||||
const isObject = object[key]["_object"];
|
||||
const isValue = "_value" in object[key];
|
||||
|
||||
if ((isObject && isValue) || (!isObject && !isValue))
|
||||
throw new Error("Unexpected object");
|
||||
|
||||
if (isValue) {
|
||||
let value = object[key]["_value"];
|
||||
if (typeof value === "boolean")
|
||||
value = +value;
|
||||
if (typeof value === "boolean") value = +value;
|
||||
|
||||
let values = [object[key]["_writable"] || false, value.toString()];
|
||||
if (object[key]["_type"])
|
||||
values.push(object[key]["_type"]);
|
||||
const values = [object[key]["_writable"] || false, value.toString()];
|
||||
if (object[key]["_type"]) values.push(object[key]["_type"]);
|
||||
|
||||
dataModel[`${path}${key}`] = values;
|
||||
dataModel[`${p}${key}`] = values;
|
||||
}
|
||||
|
||||
if (isObject) {
|
||||
let values = [object[key]["_writable"] || false];
|
||||
dataModel[`${path}${key}.`] = values;
|
||||
recursive(object[key], `${path}${key}.`);
|
||||
const values = [object[key]["_writable"] || false];
|
||||
dataModel[`${p}${key}.`] = values;
|
||||
recursive(object[key], `${p}${key}.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
connect(err => {
|
||||
if (err) throw err;
|
||||
|
||||
db.connect(function(err) {
|
||||
if (err)
|
||||
throw err;
|
||||
return devicesCollection.findOne(
|
||||
{
|
||||
_id: process.argv[2]
|
||||
},
|
||||
{},
|
||||
(err, device) => {
|
||||
if (err) throw err;
|
||||
|
||||
return db.devicesCollection.findOne({
|
||||
_id: process.argv[2]
|
||||
}, {}, function(err, device) {
|
||||
if (err)
|
||||
throw err;
|
||||
if (!device) throw new Error("Device not found");
|
||||
|
||||
if (!device)
|
||||
throw new Error("Device not found");
|
||||
recursive(device);
|
||||
|
||||
recursive(device);
|
||||
fs.writeFile(outputFilename, JSON.stringify(dataModel, null, 2), () => {
|
||||
if (err) throw err;
|
||||
|
||||
fs.writeFile(outputFilename, JSON.stringify(dataModel, null, 2), function() {
|
||||
if (err)
|
||||
throw err;
|
||||
|
||||
console.log(`${outputFilename} saved`);
|
||||
process.exit(0);
|
||||
});
|
||||
});
|
||||
process.stdout.write(`${outputFilename} saved\n`);
|
||||
process.exit(0);
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
+1
-2
@@ -5,7 +5,6 @@
|
||||
},
|
||||
"parser": "babel-eslint",
|
||||
"parserOptions": {
|
||||
"allowImportExportEverywhere": true,
|
||||
"sourceType": "module"
|
||||
"allowImportExportEverywhere": true
|
||||
}
|
||||
}
|
||||
+19
-16
@@ -13,20 +13,23 @@ import tags from "./components/tags";
|
||||
import ping from "./components/ping";
|
||||
import deviceLink from "./components/device-link";
|
||||
|
||||
function get(name) {
|
||||
if (name === "parameter") return parameter;
|
||||
else if (name === "parameter-list") return parameterList;
|
||||
else if (name === "parameter-table") return parameterTable;
|
||||
else if (name === "overview-dot") return overviewDot;
|
||||
else if (name === "container") return container;
|
||||
else if (name === "summon-button") return summonButton;
|
||||
else if (name === "device-faults") return deviceFaults;
|
||||
else if (name === "all-parameters") return allParameters;
|
||||
else if (name === "device-actions") return deviceActions;
|
||||
else if (name === "tags") return tags;
|
||||
else if (name === "ping") return ping;
|
||||
else if (name === "device-link") return deviceLink;
|
||||
else throw new Error(`No such component '${name}'`);
|
||||
}
|
||||
const comps = {
|
||||
parameter,
|
||||
"parameter-list": parameterList,
|
||||
"parameter-table": parameterTable,
|
||||
"overview-dot": overviewDot,
|
||||
container,
|
||||
"summon-button": summonButton,
|
||||
"device-faults": deviceFaults,
|
||||
"all-parameters": allParameters,
|
||||
"device-actions": deviceActions,
|
||||
tags,
|
||||
ping,
|
||||
"device-link": deviceLink
|
||||
};
|
||||
|
||||
export { get };
|
||||
export function get(name) {
|
||||
const c = comps[name];
|
||||
if (!c) throw new Error(`No such component '${name}'`);
|
||||
return c;
|
||||
}
|
||||
@@ -4,10 +4,10 @@ import m from "mithril";
|
||||
import * as components from "../components";
|
||||
import * as taskQueue from "../task-queue";
|
||||
import longTextComponent from "../long-text-component";
|
||||
import * as expression from "../../lib/common/expression";
|
||||
import { parse } from "../../lib/common/expression-parser";
|
||||
import memoize from "../../lib/common/memoize";
|
||||
|
||||
const memoizedParse = memoize(expression.parse);
|
||||
const memoizedParse = memoize(parse);
|
||||
|
||||
function escapeRegExp(str) {
|
||||
return str.replace(/[-[\]/{}()*+?.\\^$|]/g, "\\$&");
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
"use strict";
|
||||
|
||||
import m from "mithril";
|
||||
import * as components from "../components";
|
||||
import { get } from "../components";
|
||||
import memoize from "../../lib/common/memoize";
|
||||
|
||||
const getChildAttrs = memoize((attrs, device) =>
|
||||
Object.assign({}, attrs, { device: device })
|
||||
);
|
||||
|
||||
const component = {
|
||||
export default {
|
||||
view: vnode => {
|
||||
const device = vnode.attrs.device;
|
||||
|
||||
const rows = Object.values(vnode.attrs.parameters).map(parameter => {
|
||||
const p = m(
|
||||
components.get(parameter.type || "parameter"),
|
||||
get(parameter.type || "parameter"),
|
||||
getChildAttrs(parameter, device)
|
||||
);
|
||||
|
||||
@@ -33,5 +33,3 @@ const component = {
|
||||
return m("table.parameter-list", rows);
|
||||
}
|
||||
};
|
||||
|
||||
export default component;
|
||||
+6
-6
@@ -8,19 +8,20 @@ import * as store from "./store";
|
||||
import * as components from "./components";
|
||||
import * as taskQueue from "./task-queue";
|
||||
import * as notifications from "./notifications";
|
||||
import * as expression from "../lib/common/expression";
|
||||
import { evaluate, extractParams } from "../lib/common/expression";
|
||||
import { parse, stringify } from "../lib/common/expression-parser";
|
||||
import memoize from "../lib/common/memoize";
|
||||
import * as smartQuery from "./smart-query";
|
||||
import * as expressionParser from "../lib/common/expression-parser";
|
||||
|
||||
const PAGE_SIZE = config.ui.pageSize || 10;
|
||||
|
||||
const memoizedParse = memoize(expression.parse);
|
||||
const memoizedParse = memoize(parse);
|
||||
const memoizedJsonParse = memoize(JSON.parse);
|
||||
const memoizedGetSortable = memoize(p => {
|
||||
const expressionParams = expression.extractParams(p);
|
||||
const expressionParams = extractParams(p);
|
||||
if (expressionParams.length === 1) {
|
||||
const param = expression.evaluate(expressionParams[0]);
|
||||
const param = evaluate(expressionParams[0]);
|
||||
if (typeof param === "string") return param;
|
||||
}
|
||||
return null;
|
||||
@@ -28,8 +29,7 @@ const memoizedGetSortable = memoize(p => {
|
||||
|
||||
const getDownloadUrl = memoize((filter, indexParameters) => {
|
||||
const columns = {};
|
||||
for (const p of indexParameters)
|
||||
columns[p.label] = expression.stringify(p.parameter);
|
||||
for (const p of indexParameters) columns[p.label] = stringify(p.parameter);
|
||||
return `/api/devices.csv?${m.buildQueryString({
|
||||
filter: filter,
|
||||
columns: JSON.stringify(columns)
|
||||
|
||||
+3
-4
@@ -5,16 +5,15 @@ import config from "./config";
|
||||
import filterComponent from "./filter-component";
|
||||
import * as store from "./store";
|
||||
import * as notifications from "./notifications";
|
||||
import * as expression from "../lib/common/expression";
|
||||
import memoize from "../lib/common/memoize";
|
||||
import * as smartQuery from "./smart-query";
|
||||
import * as expressionParser from "../lib/common/expression-parser";
|
||||
import { map, parse } from "../lib/common/expression-parser";
|
||||
import { loadYaml, yaml } from "./dynamic-loader";
|
||||
import longTextComponent from "./long-text-component";
|
||||
|
||||
const PAGE_SIZE = config.ui.pageSize || 10;
|
||||
|
||||
const memoizedParse = memoize(expression.parse);
|
||||
const memoizedParse = memoize(parse);
|
||||
const memoizedJsonParse = memoize(JSON.parse);
|
||||
|
||||
const attributes = [
|
||||
@@ -41,7 +40,7 @@ const getDownloadUrl = memoize(filter => {
|
||||
});
|
||||
|
||||
const unpackSmartQuery = memoize(query => {
|
||||
return expressionParser.map(query, e => {
|
||||
return map(query, e => {
|
||||
if (Array.isArray(e) && e[0] === "FUNC" && e[1] === "Q")
|
||||
return smartQuery.unpack("faults", e[2], e[3]);
|
||||
return e;
|
||||
|
||||
+3
-4
@@ -5,17 +5,16 @@ import m from "mithril";
|
||||
import config from "./config";
|
||||
import filterComponent from "./filter-component";
|
||||
import * as store from "./store";
|
||||
import * as expression from "../lib/common/expression";
|
||||
import * as notifications from "./notifications";
|
||||
import memoize from "../lib/common/memoize";
|
||||
import putFormComponent from "./put-form-component";
|
||||
import * as overlay from "./overlay";
|
||||
import * as smartQuery from "./smart-query";
|
||||
import * as expressionParser from "../lib/common/expression-parser";
|
||||
import { map, parse } from "../lib/common/expression-parser";
|
||||
|
||||
const PAGE_SIZE = config.ui.pageSize || 10;
|
||||
|
||||
const memoizedParse = memoize(expression.parse);
|
||||
const memoizedParse = memoize(parse);
|
||||
const memoizedJsonParse = memoize(JSON.parse);
|
||||
|
||||
const attributes = [
|
||||
@@ -45,7 +44,7 @@ const formData = {
|
||||
};
|
||||
|
||||
const unpackSmartQuery = memoize(query => {
|
||||
return expressionParser.map(query, e => {
|
||||
return map(query, e => {
|
||||
if (Array.isArray(e) && e[0] === "FUNC" && e[1] === "Q")
|
||||
return smartQuery.unpack("files", e[2], e[3]);
|
||||
return e;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
import m from "mithril";
|
||||
import * as expression from "../lib/common/expression";
|
||||
import { parse, stringify } from "../lib/common/expression-parser";
|
||||
import memoize from "../lib/common/memoize";
|
||||
import Autocomplete from "./autocomplete-compnent";
|
||||
import * as smartQuery from "./smart-query";
|
||||
@@ -21,19 +21,19 @@ function parseFilter(f) {
|
||||
const v = f.slice(k.length + 1).trim();
|
||||
return ["FUNC", "Q", k.trim(), v];
|
||||
}
|
||||
return expression.parse(f);
|
||||
return parse(f);
|
||||
}
|
||||
|
||||
function stringifyFilter(f) {
|
||||
if (Array.isArray(f) && f[0] === "FUNC" && f[1] === "Q")
|
||||
return `${f[2]}: ${f[3]}`;
|
||||
return expression.stringify(f);
|
||||
return stringify(f);
|
||||
}
|
||||
|
||||
const splitFilter = memoize(filter => {
|
||||
if (!filter) return [""];
|
||||
const list = [];
|
||||
const f = expression.parse(filter);
|
||||
const f = parse(filter);
|
||||
if (Array.isArray(f) && f[0] === "AND")
|
||||
for (const ff of f.slice(1)) list.push(stringifyFilter(ff));
|
||||
else list.push(stringifyFilter(f));
|
||||
@@ -70,7 +70,7 @@ const component = {
|
||||
} else {
|
||||
if (filter.length > 1) filter = ["AND"].concat(filter);
|
||||
else filter = filter[0];
|
||||
vnode.attrs.onChange(expression.stringify(filter));
|
||||
vnode.attrs.onChange(stringify(filter));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
"use strict";
|
||||
|
||||
import m from "mithril";
|
||||
import * as expression from "../lib/common/expression";
|
||||
import { stringify } from "../lib/common/expression-parser";
|
||||
import memoize from "../lib/common/memoize";
|
||||
|
||||
const memoizedStringify = memoize(expression.stringify);
|
||||
const memoizedStringify = memoize(stringify);
|
||||
|
||||
const drawChart = function(chartData) {
|
||||
const slices = chartData.slices;
|
||||
|
||||
+3
-4
@@ -6,16 +6,15 @@ import config from "./config";
|
||||
import filterComponent from "./filter-component";
|
||||
import * as overlay from "./overlay";
|
||||
import * as store from "./store";
|
||||
import * as expression from "../lib/common/expression";
|
||||
import * as notifications from "./notifications";
|
||||
import putFormComponent from "./put-form-component";
|
||||
import memoize from "../lib/common/memoize";
|
||||
import * as smartQuery from "./smart-query";
|
||||
import * as expressionParser from "../lib/common/expression-parser";
|
||||
import { map, parse } from "../lib/common/expression-parser";
|
||||
|
||||
const PAGE_SIZE = config.ui.pageSize || 10;
|
||||
|
||||
const memoizedParse = memoize(expression.parse);
|
||||
const memoizedParse = memoize(parse);
|
||||
const memoizedJsonParse = memoize(JSON.parse);
|
||||
|
||||
const attributes = [
|
||||
@@ -30,7 +29,7 @@ const attributes = [
|
||||
];
|
||||
|
||||
const unpackSmartQuery = memoize(query => {
|
||||
return expressionParser.map(query, e => {
|
||||
return map(query, e => {
|
||||
if (Array.isArray(e) && e[0] === "FUNC" && e[1] === "Q")
|
||||
return smartQuery.unpack("presets", e[2], e[3]);
|
||||
return e;
|
||||
|
||||
@@ -5,18 +5,17 @@ import m from "mithril";
|
||||
import config from "./config";
|
||||
import filterComponent from "./filter-component";
|
||||
import * as store from "./store";
|
||||
import * as expression from "../lib/common/expression";
|
||||
import * as notifications from "./notifications";
|
||||
import memoize from "../lib/common/memoize";
|
||||
import putFormComponent from "./put-form-component";
|
||||
import * as overlay from "./overlay";
|
||||
import * as smartQuery from "./smart-query";
|
||||
import * as expressionParser from "../lib/common/expression-parser";
|
||||
import { map, parse } from "../lib/common/expression-parser";
|
||||
import { loadCodeMirror } from "./dynamic-loader";
|
||||
|
||||
const PAGE_SIZE = config.ui.pageSize || 10;
|
||||
|
||||
const memoizedParse = memoize(expression.parse);
|
||||
const memoizedParse = memoize(parse);
|
||||
const memoizedJsonParse = memoize(JSON.parse);
|
||||
|
||||
const attributes = [
|
||||
@@ -25,7 +24,7 @@ const attributes = [
|
||||
];
|
||||
|
||||
const unpackSmartQuery = memoize(query => {
|
||||
return expressionParser.map(query, e => {
|
||||
return map(query, e => {
|
||||
if (Array.isArray(e) && e[0] === "FUNC" && e[1] === "Q")
|
||||
return smartQuery.unpack("provisions", e[2], e[3]);
|
||||
return e;
|
||||
|
||||
+24
-36
@@ -1,12 +1,12 @@
|
||||
"use strict";
|
||||
|
||||
import m from "mithril";
|
||||
import * as expressionParser from "../lib/common/expression-parser";
|
||||
import * as expression from "../lib/common/expression";
|
||||
import { map, stringify } from "../lib/common/expression-parser";
|
||||
import { or, and, not, evaluate, subset } from "../lib/common/expression";
|
||||
import memoize from "../lib/common/memoize";
|
||||
|
||||
const memoizedStringify = memoize(expression.stringify);
|
||||
const memoizedEvaluate = memoize(expression.evaluate);
|
||||
const memoizedStringify = memoize(stringify);
|
||||
const memoizedEvaluate = memoize(evaluate);
|
||||
|
||||
let fulfillTimestamp = 0;
|
||||
|
||||
@@ -74,43 +74,37 @@ function limitFilter(filter, sort, bookmark) {
|
||||
const arr = Object.entries(sort)
|
||||
.sort(sortSort)
|
||||
.reverse();
|
||||
return expression.and(
|
||||
return and(
|
||||
filter,
|
||||
arr.reduce((cur, kv) => {
|
||||
const [param, asc] = kv;
|
||||
if (asc <= 0) {
|
||||
if (bookmark[param] == null) {
|
||||
return expression.or(
|
||||
return or(
|
||||
["IS NOT NULL", ["PARAM", param]],
|
||||
expression.and(["IS NULL", ["PARAM", param]], cur)
|
||||
and(["IS NULL", ["PARAM", param]], cur)
|
||||
);
|
||||
}
|
||||
|
||||
let f = null;
|
||||
|
||||
if (typeof bookmark[param] !== "string")
|
||||
f = expression.or(f, [">=", ["PARAM", param], ""]);
|
||||
f = or(f, [">=", ["PARAM", param], ""]);
|
||||
|
||||
f = expression.or(f, [">", ["PARAM", param], bookmark[param]]);
|
||||
return expression.or(
|
||||
f,
|
||||
expression.and(["=", ["PARAM", param], bookmark[param]], cur)
|
||||
);
|
||||
f = or(f, [">", ["PARAM", param], bookmark[param]]);
|
||||
return or(f, and(["=", ["PARAM", param], bookmark[param]], cur));
|
||||
} else {
|
||||
let f = ["IS NULL", ["PARAM", param]];
|
||||
if (bookmark[param] == null) return expression.and(f, cur);
|
||||
if (bookmark[param] == null) return and(f, cur);
|
||||
|
||||
if (typeof bookmark[param] !== "number") {
|
||||
f = expression.or(f, [">=", ["PARAM", param], 0]);
|
||||
f = expression.or(f, ["<", ["PARAM", param], 0]);
|
||||
f = or(f, [">=", ["PARAM", param], 0]);
|
||||
f = or(f, ["<", ["PARAM", param], 0]);
|
||||
}
|
||||
|
||||
f = expression.or(f, ["<", ["PARAM", param], bookmark[param]]);
|
||||
f = or(f, ["<", ["PARAM", param], bookmark[param]]);
|
||||
|
||||
return expression.or(
|
||||
f,
|
||||
expression.and(["=", ["PARAM", param], bookmark[param]], cur)
|
||||
);
|
||||
return or(f, and(["=", ["PARAM", param], bookmark[param]], cur));
|
||||
}
|
||||
}, true)
|
||||
);
|
||||
@@ -157,7 +151,7 @@ function compareFunction(sort) {
|
||||
function findMatches(resourceType, filter, sort, limit) {
|
||||
// Handle "tag =" and "tag <>" special cases
|
||||
if (resourceType === "devices") {
|
||||
filter = expressionParser.map(filter, e => {
|
||||
filter = map(filter, e => {
|
||||
if (
|
||||
Array.isArray(e) &&
|
||||
Array.isArray(e[1]) &&
|
||||
@@ -173,7 +167,7 @@ function findMatches(resourceType, filter, sort, limit) {
|
||||
|
||||
let value = [];
|
||||
for (const obj of resources[resourceType].objects.values())
|
||||
if (expression.evaluate(filter, obj, fulfillTimestamp)) value.push(obj);
|
||||
if (evaluate(filter, obj, fulfillTimestamp)) value.push(obj);
|
||||
|
||||
value = value.sort(compareFunction(sort));
|
||||
if (limit) value = value.slice(0, limit);
|
||||
@@ -191,7 +185,7 @@ function inferQuery(resourceType, queryResponse) {
|
||||
if (bookmark) filter = limitFilter(filter, sort, bookmark);
|
||||
if (
|
||||
resources[resourceType].combinedFilter &&
|
||||
expression.subset(filter, resources[resourceType].combinedFilter)
|
||||
subset(filter, resources[resourceType].combinedFilter)
|
||||
)
|
||||
queries.fulfilled.set(queryResponse, fulfillTimestamp);
|
||||
}
|
||||
@@ -356,7 +350,7 @@ function fulfill(accessTimestamp, _fulfillTimestamp) {
|
||||
|
||||
if (
|
||||
resources[resourceType].combinedFilter &&
|
||||
expression.subset(filter, resources[resourceType].combinedFilter)
|
||||
subset(filter, resources[resourceType].combinedFilter)
|
||||
) {
|
||||
queries.value.set(
|
||||
queryResponse,
|
||||
@@ -367,7 +361,7 @@ function fulfill(accessTimestamp, _fulfillTimestamp) {
|
||||
return false;
|
||||
}
|
||||
|
||||
combinedFilter = expression.or(combinedFilter, filter);
|
||||
combinedFilter = or(combinedFilter, filter);
|
||||
return true;
|
||||
});
|
||||
|
||||
@@ -379,12 +373,12 @@ function fulfill(accessTimestamp, _fulfillTimestamp) {
|
||||
deleted = new Set(resources[resourceType].objects.keys());
|
||||
let combinedFilterDiff = combinedFilter;
|
||||
if (resources[resourceType].combinedFilter) {
|
||||
combinedFilterDiff = expression.and(
|
||||
combinedFilterDiff = and(
|
||||
combinedFilterDiff,
|
||||
expression.not(resources[resourceType].combinedFilter)
|
||||
not(resources[resourceType].combinedFilter)
|
||||
);
|
||||
}
|
||||
resources[resourceType].combinedFilter = expression.or(
|
||||
resources[resourceType].combinedFilter = or(
|
||||
combinedFilter,
|
||||
resources[resourceType].combinedFilter
|
||||
);
|
||||
@@ -411,13 +405,7 @@ function fulfill(accessTimestamp, _fulfillTimestamp) {
|
||||
|
||||
for (const d of deleted) {
|
||||
const obj = resources[resourceType].objects.get(d);
|
||||
if (
|
||||
expression.evaluate(
|
||||
combinedFilterDiff,
|
||||
obj,
|
||||
fulfillTimestamp
|
||||
)
|
||||
)
|
||||
if (evaluate(combinedFilterDiff, obj, fulfillTimestamp))
|
||||
resources[resourceType].objects.delete(d);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,18 +5,17 @@ import m from "mithril";
|
||||
import config from "./config";
|
||||
import filterComponent from "./filter-component";
|
||||
import * as store from "./store";
|
||||
import * as expression from "../lib/common/expression";
|
||||
import * as notifications from "./notifications";
|
||||
import memoize from "../lib/common/memoize";
|
||||
import putFormComponent from "./put-form-component";
|
||||
import * as overlay from "./overlay";
|
||||
import * as smartQuery from "./smart-query";
|
||||
import * as expressionParser from "../lib/common/expression-parser";
|
||||
import { map, parse } from "../lib/common/expression-parser";
|
||||
import { loadCodeMirror } from "./dynamic-loader";
|
||||
|
||||
const PAGE_SIZE = config.ui.pageSize || 10;
|
||||
|
||||
const memoizedParse = memoize(expression.parse);
|
||||
const memoizedParse = memoize(parse);
|
||||
const memoizedJsonParse = memoize(JSON.parse);
|
||||
|
||||
const attributes = [
|
||||
@@ -25,7 +24,7 @@ const attributes = [
|
||||
];
|
||||
|
||||
const unpackSmartQuery = memoize(query => {
|
||||
return expressionParser.map(query, e => {
|
||||
return map(query, e => {
|
||||
if (Array.isArray(e) && e[0] === "FUNC" && e[1] === "Q")
|
||||
return smartQuery.unpack("virtualParameters", e[2], e[3]);
|
||||
return e;
|
||||
|
||||
Reference in new issue
Block a user