diff --git a/bin/genieacs-cwmp b/bin/genieacs-cwmp.ts
similarity index 76%
rename from bin/genieacs-cwmp
rename to bin/genieacs-cwmp.ts
index 1d7d881..b74b513 100755
--- a/bin/genieacs-cwmp
+++ b/bin/genieacs-cwmp.ts
@@ -1,5 +1,3 @@
-#!/usr/bin/env -S node -r esm -r ts-node/register/transpile-only
-
/**
* Copyright 2013-2019 GenieACS Inc.
*
@@ -31,8 +29,8 @@ import { version as VERSION } from "../package.json";
logger.init("cwmp", VERSION);
-const SERVICE_ADDRESS = config.get("CWMP_INTERFACE");
-const SERVICE_PORT = config.get("CWMP_PORT");
+const SERVICE_ADDRESS = config.get("CWMP_INTERFACE") as string;
+const SERVICE_PORT = config.get("CWMP_PORT") as number;
function exitWorkerGracefully(): void {
setTimeout(exitWorkerUngracefully, 5000).unref();
@@ -40,7 +38,7 @@ function exitWorkerGracefully(): void {
db.disconnect(),
cache.disconnect(),
extensions.killAll(),
- cluster.worker.disconnect()
+ cluster.worker.disconnect(),
]).catch(exitWorkerUngracefully);
}
@@ -51,12 +49,12 @@ function exitWorkerUngracefully(): void {
}
if (!cluster.worker) {
- const WORKER_COUNT = config.get("CWMP_WORKER_PROCESSES");
+ const WORKER_COUNT = config.get("CWMP_WORKER_PROCESSES") as number;
logger.info({
message: `genieacs-cwmp starting`,
pid: process.pid,
- version: VERSION
+ version: VERSION,
});
cluster.start(WORKER_COUNT, SERVICE_PORT, SERVICE_ADDRESS);
@@ -64,7 +62,7 @@ if (!cluster.worker) {
process.on("SIGINT", () => {
logger.info({
message: "Received signal SIGINT, exiting",
- pid: process.pid
+ pid: process.pid,
});
cluster.stop();
@@ -73,28 +71,25 @@ if (!cluster.worker) {
process.on("SIGTERM", () => {
logger.info({
message: "Received signal SIGTERM, exiting",
- pid: process.pid
+ pid: process.pid,
});
cluster.stop();
});
} else {
const ssl = {
- key: config.get("CWMP_SSL_KEY"),
- cert: config.get("CWMP_SSL_CERT")
+ key: config.get("CWMP_SSL_KEY") as string,
+ cert: config.get("CWMP_SSL_CERT") as string,
};
- process.on("uncaughtException", err => {
+ process.on("uncaughtException", (err) => {
if ((err as NodeJS.ErrnoException).code === "ERR_IPC_DISCONNECTED") return;
logger.error({
message: "Uncaught exception",
exception: err,
- pid: process.pid
+ pid: process.pid,
});
- server
- .stop()
- .then(exitWorkerGracefully)
- .catch(exitWorkerUngracefully);
+ server.stop().then(exitWorkerGracefully).catch(exitWorkerUngracefully);
});
const initPromise = Promise.all([db.connect(), cache.connect()])
@@ -108,7 +103,7 @@ if (!cluster.worker) {
0
);
})
- .catch(err => {
+ .catch((err) => {
setTimeout(() => {
throw err;
});
@@ -116,19 +111,13 @@ if (!cluster.worker) {
process.on("SIGINT", () => {
initPromise.finally(() => {
- server
- .stop()
- .then(exitWorkerGracefully)
- .catch(exitWorkerUngracefully);
+ server.stop().then(exitWorkerGracefully).catch(exitWorkerUngracefully);
});
});
process.on("SIGTERM", () => {
initPromise.finally(() => {
- server
- .stop()
- .then(exitWorkerGracefully)
- .catch(exitWorkerUngracefully);
+ server.stop().then(exitWorkerGracefully).catch(exitWorkerUngracefully);
});
});
}
diff --git a/bin/genieacs-ext b/bin/genieacs-ext.ts
similarity index 89%
rename from bin/genieacs-ext
rename to bin/genieacs-ext.ts
index 13eb893..864c687 100755
--- a/bin/genieacs-ext
+++ b/bin/genieacs-ext.ts
@@ -1,5 +1,3 @@
-#!/usr/bin/env -S node -r esm -r ts-node/register/transpile-only
-
/**
* Copyright 2013-2019 GenieACS Inc.
*
@@ -35,8 +33,8 @@ function errorToFault(err: Error): Fault {
message: err.message,
detail: {
name: err.name,
- message: err.message
- }
+ message: err.message,
+ },
};
if (err.stack) {
@@ -56,16 +54,16 @@ function errorToFault(err: Error): Fault {
return fault;
}
-process.on("uncaughtException", err => {
+process.on("uncaughtException", (err) => {
const fault = errorToFault(err);
- jobs.forEach(jobId => {
+ jobs.forEach((jobId) => {
process.send([jobId, fault, null]);
});
jobs.clear();
process.disconnect();
});
-process.on("message", message => {
+process.on("message", (message) => {
jobs.add(message[0]);
if (!script) {
@@ -79,7 +77,7 @@ process.on("message", message => {
if (!script[funcName]) {
const fault = {
code: "ext",
- message: `No such function '${funcName}' in extension '${fileName}'`
+ message: `No such function '${funcName}' in extension '${fileName}'`,
};
process.send([message[0], fault, null]);
return;
@@ -93,4 +91,6 @@ process.on("message", message => {
});
// Ignore SIGINT
-process.on("SIGINT", () => {});
+process.on("SIGINT", () => {
+ // Ignore
+});
diff --git a/bin/genieacs-fs b/bin/genieacs-fs.ts
similarity index 76%
rename from bin/genieacs-fs
rename to bin/genieacs-fs.ts
index 75244bd..a743523 100755
--- a/bin/genieacs-fs
+++ b/bin/genieacs-fs.ts
@@ -1,5 +1,3 @@
-#!/usr/bin/env -S node -r esm -r ts-node/register/transpile-only
-
/**
* Copyright 2013-2019 GenieACS Inc.
*
@@ -30,15 +28,15 @@ import { version as VERSION } from "../package.json";
logger.init("fs", VERSION);
-const SERVICE_ADDRESS = config.get("FS_INTERFACE");
-const SERVICE_PORT = config.get("FS_PORT");
+const SERVICE_ADDRESS = config.get("FS_INTERFACE") as string;
+const SERVICE_PORT = config.get("FS_PORT") as number;
function exitWorkerGracefully(): void {
setTimeout(exitWorkerUngracefully, 5000).unref();
Promise.all([
db.disconnect(),
cache.disconnect(),
- cluster.worker.disconnect()
+ cluster.worker.disconnect(),
]).catch(exitWorkerUngracefully);
}
@@ -47,12 +45,12 @@ function exitWorkerUngracefully(): void {
}
if (!cluster.worker) {
- const WORKER_COUNT = config.get("FS_WORKER_PROCESSES");
+ const WORKER_COUNT = config.get("FS_WORKER_PROCESSES") as number;
logger.info({
message: `genieacs-fs starting`,
pid: process.pid,
- version: VERSION
+ version: VERSION,
});
cluster.start(WORKER_COUNT, SERVICE_PORT, SERVICE_ADDRESS);
@@ -60,7 +58,7 @@ if (!cluster.worker) {
process.on("SIGINT", () => {
logger.info({
message: "Received signal SIGINT, exiting",
- pid: process.pid
+ pid: process.pid,
});
cluster.stop();
@@ -69,31 +67,28 @@ if (!cluster.worker) {
process.on("SIGTERM", () => {
logger.info({
message: "Received signal SIGTERM, exiting",
- pid: process.pid
+ pid: process.pid,
});
cluster.stop();
});
} else {
const ssl = {
- key: config.get("FS_SSL_KEY"),
- cert: config.get("FS_SSL_CERT")
+ key: config.get("FS_SSL_KEY") as string,
+ cert: config.get("FS_SSL_CERT") as string,
};
let stopping = false;
- process.on("uncaughtException", err => {
+ process.on("uncaughtException", (err) => {
if ((err as NodeJS.ErrnoException).code === "ERR_IPC_DISCONNECTED") return;
logger.error({
message: "Uncaught exception",
exception: err,
- pid: process.pid
+ pid: process.pid,
});
stopping = true;
- server
- .stop()
- .then(exitWorkerGracefully)
- .catch(exitWorkerUngracefully);
+ server.stop().then(exitWorkerGracefully).catch(exitWorkerUngracefully);
});
const _listener = (req, res): void => {
@@ -105,7 +100,7 @@ if (!cluster.worker) {
.then(() => {
server.start(SERVICE_PORT, SERVICE_ADDRESS, ssl, _listener);
})
- .catch(err => {
+ .catch((err) => {
setTimeout(() => {
throw err;
});
@@ -114,20 +109,14 @@ if (!cluster.worker) {
process.on("SIGINT", () => {
stopping = true;
initPromise.finally(() => {
- server
- .stop()
- .then(exitWorkerGracefully)
- .catch(exitWorkerUngracefully);
+ server.stop().then(exitWorkerGracefully).catch(exitWorkerUngracefully);
});
});
process.on("SIGTERM", () => {
stopping = true;
initPromise.finally(() => {
- server
- .stop()
- .then(exitWorkerGracefully)
- .catch(exitWorkerUngracefully);
+ server.stop().then(exitWorkerGracefully).catch(exitWorkerUngracefully);
});
});
}
diff --git a/bin/genieacs-nbi b/bin/genieacs-nbi.ts
similarity index 77%
rename from bin/genieacs-nbi
rename to bin/genieacs-nbi.ts
index 80a555e..783cc42 100755
--- a/bin/genieacs-nbi
+++ b/bin/genieacs-nbi.ts
@@ -1,5 +1,3 @@
-#!/usr/bin/env -S node -r esm -r ts-node/register/transpile-only
-
/**
* Copyright 2013-2019 GenieACS Inc.
*
@@ -31,8 +29,8 @@ import { version as VERSION } from "../package.json";
logger.init("nbi", VERSION);
-const SERVICE_ADDRESS = config.get("NBI_INTERFACE");
-const SERVICE_PORT = config.get("NBI_PORT");
+const SERVICE_ADDRESS = config.get("NBI_INTERFACE") as string;
+const SERVICE_PORT = config.get("NBI_PORT") as number;
function exitWorkerGracefully(): void {
setTimeout(exitWorkerUngracefully, 5000).unref();
@@ -40,7 +38,7 @@ function exitWorkerGracefully(): void {
db.disconnect(),
cache.disconnect(),
extensions.killAll(),
- cluster.worker.disconnect()
+ cluster.worker.disconnect(),
]).catch(exitWorkerUngracefully);
}
@@ -51,12 +49,12 @@ function exitWorkerUngracefully(): void {
}
if (!cluster.worker) {
- const WORKER_COUNT = config.get("NBI_WORKER_PROCESSES");
+ const WORKER_COUNT = config.get("NBI_WORKER_PROCESSES") as number;
logger.info({
message: `genieacs-nbi starting`,
pid: process.pid,
- version: VERSION
+ version: VERSION,
});
cluster.start(WORKER_COUNT, SERVICE_PORT, SERVICE_ADDRESS);
@@ -64,7 +62,7 @@ if (!cluster.worker) {
process.on("SIGINT", () => {
logger.info({
message: "Received signal SIGINT, exiting",
- pid: process.pid
+ pid: process.pid,
});
cluster.stop();
@@ -73,31 +71,28 @@ if (!cluster.worker) {
process.on("SIGTERM", () => {
logger.info({
message: "Received signal SIGTERM, exiting",
- pid: process.pid
+ pid: process.pid,
});
cluster.stop();
});
} else {
const ssl = {
- key: config.get("NBI_SSL_KEY"),
- cert: config.get("NBI_SSL_CERT")
+ key: config.get("NBI_SSL_KEY") as string,
+ cert: config.get("NBI_SSL_CERT") as string,
};
let stopping = false;
- process.on("uncaughtException", err => {
+ process.on("uncaughtException", (err) => {
if ((err as NodeJS.ErrnoException).code === "ERR_IPC_DISCONNECTED") return;
logger.error({
message: "Uncaught exception",
exception: err,
- pid: process.pid
+ pid: process.pid,
});
stopping = true;
- server
- .stop()
- .then(exitWorkerGracefully)
- .catch(exitWorkerUngracefully);
+ server.stop().then(exitWorkerGracefully).catch(exitWorkerUngracefully);
});
const _listener = (req, res): void => {
@@ -109,7 +104,7 @@ if (!cluster.worker) {
.then(() => {
server.start(SERVICE_PORT, SERVICE_ADDRESS, ssl, _listener);
})
- .catch(err => {
+ .catch((err) => {
setTimeout(() => {
throw err;
});
@@ -118,20 +113,14 @@ if (!cluster.worker) {
process.on("SIGINT", () => {
stopping = true;
initPromise.finally(() => {
- server
- .stop()
- .then(exitWorkerGracefully)
- .catch(exitWorkerUngracefully);
+ server.stop().then(exitWorkerGracefully).catch(exitWorkerUngracefully);
});
});
process.on("SIGTERM", () => {
stopping = true;
initPromise.finally(() => {
- server
- .stop()
- .then(exitWorkerGracefully)
- .catch(exitWorkerUngracefully);
+ server.stop().then(exitWorkerGracefully).catch(exitWorkerUngracefully);
});
});
}
diff --git a/bin/genieacs-ui b/bin/genieacs-ui.ts
similarity index 78%
rename from bin/genieacs-ui
rename to bin/genieacs-ui.ts
index e7d2506..e798779 100755
--- a/bin/genieacs-ui
+++ b/bin/genieacs-ui.ts
@@ -1,5 +1,3 @@
-#!/usr/bin/env -S node -r esm -r ts-node/register/transpile-only
-
/**
* Copyright 2013-2019 GenieACS Inc.
*
@@ -32,8 +30,8 @@ import { version as VERSION } from "../package.json";
logger.init("ui", VERSION);
-const SERVICE_ADDRESS = config.get("UI_INTERFACE");
-const SERVICE_PORT = config.get("UI_PORT");
+const SERVICE_ADDRESS = config.get("UI_INTERFACE") as string;
+const SERVICE_PORT = config.get("UI_PORT") as number;
function exitWorkerGracefully(): void {
setTimeout(exitWorkerUngracefully, 5000).unref();
@@ -42,7 +40,7 @@ function exitWorkerGracefully(): void {
db2.disconnect(),
cache.disconnect(),
extensions.killAll(),
- cluster.worker.disconnect()
+ cluster.worker.disconnect(),
]).catch(exitWorkerUngracefully);
}
@@ -53,12 +51,12 @@ function exitWorkerUngracefully(): void {
}
if (!cluster.worker) {
- const WORKER_COUNT = config.get("UI_WORKER_PROCESSES");
+ const WORKER_COUNT = config.get("UI_WORKER_PROCESSES") as number;
logger.info({
message: `genieacs-ui starting`,
pid: process.pid,
- version: VERSION
+ version: VERSION,
});
cluster.start(WORKER_COUNT, SERVICE_PORT, SERVICE_ADDRESS);
@@ -66,7 +64,7 @@ if (!cluster.worker) {
process.on("SIGINT", () => {
logger.info({
message: "Received signal SIGINT, exiting",
- pid: process.pid
+ pid: process.pid,
});
cluster.stop();
@@ -75,31 +73,28 @@ if (!cluster.worker) {
process.on("SIGTERM", () => {
logger.info({
message: "Received signal SIGTERM, exiting",
- pid: process.pid
+ pid: process.pid,
});
cluster.stop();
});
} else {
const ssl = {
- key: config.get("UI_SSL_KEY"),
- cert: config.get("UI_SSL_CERT")
+ key: config.get("UI_SSL_KEY") as string,
+ cert: config.get("UI_SSL_CERT") as string,
};
let stopping = false;
- process.on("uncaughtException", err => {
+ process.on("uncaughtException", (err) => {
if ((err as NodeJS.ErrnoException).code === "ERR_IPC_DISCONNECTED") return;
logger.error({
message: "Uncaught exception",
exception: err,
- pid: process.pid
+ pid: process.pid,
});
stopping = true;
- server
- .stop()
- .then(exitWorkerGracefully)
- .catch(exitWorkerUngracefully);
+ server.stop().then(exitWorkerGracefully).catch(exitWorkerUngracefully);
});
const _listener = (req, res): void => {
@@ -111,7 +106,7 @@ if (!cluster.worker) {
.then(() => {
server.start(SERVICE_PORT, SERVICE_ADDRESS, ssl, _listener);
})
- .catch(err => {
+ .catch((err) => {
setTimeout(() => {
throw err;
});
@@ -120,20 +115,14 @@ if (!cluster.worker) {
process.on("SIGINT", () => {
stopping = true;
initPromise.finally(() => {
- server
- .stop()
- .then(exitWorkerGracefully)
- .catch(exitWorkerUngracefully);
+ server.stop().then(exitWorkerGracefully).catch(exitWorkerUngracefully);
});
});
process.on("SIGTERM", () => {
stopping = true;
initPromise.finally(() => {
- server
- .stop()
- .then(exitWorkerGracefully)
- .catch(exitWorkerUngracefully);
+ server.stop().then(exitWorkerGracefully).catch(exitWorkerUngracefully);
});
});
}
diff --git a/build/build.ts b/build/build.ts
index d33c940..f94d90c 100644
--- a/build/build.ts
+++ b/build/build.ts
@@ -21,7 +21,6 @@ import * as path from "path";
import * as fs from "fs";
import { promisify } from "util";
import { rollup, WarningHandler } from "rollup";
-import rollupReplace from "rollup-plugin-replace";
import rollupJson from "rollup-plugin-json";
import typescript from "rollup-plugin-typescript";
import { terser } from "rollup-plugin-terser";
@@ -78,7 +77,7 @@ const externals = [
"codemirror",
"codemirror/mode/javascript/javascript",
"codemirror/mode/yaml/yaml",
- "ipaddr.js"
+ "ipaddr.js",
];
function rmDirSync(dirPath): void {
@@ -123,9 +122,7 @@ function generateSymbol(id: string, svgStr: string): string {
}
}
const symbolBody = xml.children[0].children
- .map(c => {
- return xmlTostring(c);
- })
+ .map((c) => xmlTostring(c))
.join("");
return `${symbolBody}`;
}
@@ -147,7 +144,7 @@ async function init(): Promise {
delete packageJson["devDependencies"];
packageJson["scripts"] = {
install: packageJson["scripts"].install,
- configure: packageJson["scripts"].configure
+ configure: packageJson["scripts"].configure,
};
packageJson["version"] = `${packageJson["version"]}+${BUILD_METADATA}`;
fs.writeFileSync(
@@ -173,7 +170,7 @@ async function copyStatic(): Promise {
"README.md",
"CHANGELOG.md",
"public/logo.svg",
- "public/favicon.png"
+ "public/favicon.png",
];
for (const file of files) {
@@ -194,35 +191,31 @@ async function generateCss(): Promise {
stage: 3,
features: {
"nesting-rules": true,
- "color-mod-function": true
- }
+ "color-mod-function": true,
+ },
}),
- cssnano
+ cssnano,
]).process(cssIn, { from: cssInPath, to: cssOutPath });
fs.writeFileSync(cssOutPath, cssOut.css);
}
async function generateToolsJs(): Promise {
for (const bin of ["dump-data-model"]) {
- const inputFile = path.resolve(INPUT_DIR, `tools/${bin}`);
+ const inputFile = path.resolve(INPUT_DIR, `tools/${bin}.ts`);
const outputFile = path.resolve(OUTPUT_DIR, `tools/${bin}`);
const bundle = await rollup({
input: inputFile,
external: externals,
acorn: {
- allowHashBang: true
+ allowHashBang: true,
},
plugins: [
- rollupReplace({
- delimiters: ["", ""],
- "#!/usr/bin/env -S node -r esm -r ts-node/register/transpile-only": ""
- }),
typescript({
tsconfig: "./tsconfig.json",
- include: [`tools/${bin}`, "lib/**/*.ts"]
+ include: [`tools/${bin}.ts`, "lib/**/*.ts"],
}),
- MODE === "production" ? terser() : null
- ]
+ MODE === "production" ? terser() : null,
+ ],
});
await bundle.write({
@@ -231,7 +224,7 @@ async function generateToolsJs(): Promise {
sourcemap: "inline",
sourcemapExcludeSources: true,
banner: "#!/usr/bin/env node",
- file: outputFile
+ file: outputFile,
});
// Mark as executable
@@ -246,25 +239,21 @@ async function generateBackendJs(): Promise {
"genieacs-ext",
"genieacs-nbi",
"genieacs-fs",
- "genieacs-ui"
+ "genieacs-ui",
]) {
- const inputFile = path.resolve(INPUT_DIR, `bin/${bin}`);
+ const inputFile = path.resolve(INPUT_DIR, `bin/${bin}.ts`);
const outputFile = path.resolve(OUTPUT_DIR, `bin/${bin}`);
const bundle = await rollup({
input: inputFile,
external: externals,
acorn: {
- allowHashBang: true
+ allowHashBang: true,
},
treeshake: {
propertyReadSideEffects: false,
- pureExternalModules: true
+ pureExternalModules: true,
},
plugins: [
- rollupReplace({
- delimiters: ["", ""],
- "#!/usr/bin/env -S node -r esm -r ts-node/register/transpile-only": ""
- }),
rollupJson({ preferConst: true }),
{
resolveId: (importee, importer) => {
@@ -274,14 +263,14 @@ async function generateBackendJs(): Promise {
return path.resolve(OUTPUT_DIR, "package.json");
}
return null;
- }
+ },
},
typescript({
tsconfig: "./tsconfig.json",
- include: [`bin/${bin}`, "lib/**/*.ts"]
+ include: [`bin/${bin}.ts`, "lib/**/*.ts"],
}),
- MODE === "production" ? terser() : null
- ]
+ MODE === "production" ? terser() : null,
+ ],
});
await bundle.write({
@@ -290,7 +279,7 @@ async function generateBackendJs(): Promise {
sourcemap: "inline",
sourcemapExcludeSources: true,
banner: "#!/usr/bin/env node",
- file: outputFile
+ file: outputFile,
});
// Mark as executable
@@ -308,17 +297,17 @@ async function generateFrontendJs(): Promise {
external: externals,
plugins: [
rollupJson({ preferConst: true }),
- typescript({ tsconfig: "./tsconfig.json" })
+ typescript({ tsconfig: "./tsconfig.json" }),
],
inlineDynamicImports: true,
treeshake: {
propertyReadSideEffects: false,
- pureExternalModules: true
+ pureExternalModules: true,
},
onwarn: ((warning, warn) => {
// Ignore circular dependency warnings
if (warning.code !== "CIRCULAR_DEPENDENCY") warn(warning);
- }) as WarningHandler
+ }) as WarningHandler,
});
await bundle.write({
@@ -326,14 +315,14 @@ async function generateFrontendJs(): Promise {
format: "esm",
sourcemap: "inline",
sourcemapExcludeSources: true,
- file: outputFile
+ file: outputFile,
});
const webpackConf = {
mode: MODE,
entry: outputFile,
resolve: {
- aliasFields: ["module"]
+ aliasFields: ["module"],
},
devtool: "nosources-source-map",
module: {
@@ -341,14 +330,14 @@ async function generateFrontendJs(): Promise {
{
test: /\.js$/,
use: ["source-map-loader"],
- enforce: "pre"
- }
- ]
+ enforce: "pre",
+ },
+ ],
},
output: {
path: path.resolve(OUTPUT_DIR, "public"),
- filename: "app.js"
- }
+ filename: "app.js",
+ },
};
const stats = await promisify(webpack)(webpackConf);
@@ -379,13 +368,15 @@ init()
generateIconsSprite(),
generateToolsJs(),
generateBackendJs(),
- generateFrontendJs()
+ generateFrontendJs(),
])
- .then(() => {})
- .catch(err => {
+ .then(() => {
+ // Ignore
+ })
+ .catch((err) => {
process.stderr.write(err.stack + "\n");
});
})
- .catch(err => {
+ .catch((err) => {
process.stderr.write(err.stack + "\n");
});
diff --git a/lib/api-functions.ts b/lib/api-functions.ts
index 42c0b29..e1a7d68 100644
--- a/lib/api-functions.ts
+++ b/lib/api-functions.ts
@@ -24,11 +24,11 @@ import * as cache from "./cache";
import {
getCurrentSnapshot,
getConfig,
- getConfigExpression
+ getConfigExpression,
} from "./local-cache";
import {
httpConnectionRequest,
- udpConnectionRequest
+ udpConnectionRequest,
} from "./connection-request";
import { Expression, Task } from "./types";
import { flattenDevice } from "./mongodb-functions";
@@ -36,7 +36,7 @@ import { evaluate } from "./common/expression";
export async function connectionRequest(
deviceId: string,
- device?: {}
+ device?: Record
): Promise {
if (!device) {
const res = await db.devicesCollection.findOne({ _id: deviceId });
@@ -137,7 +137,7 @@ export async function connectionRequest(
"FUNC",
"AUTH",
["PARAM", "username"],
- ["PARAM", "password"]
+ ["PARAM", "password"],
] as Expression;
}
@@ -171,8 +171,12 @@ export async function connectionRequest(
}
}
-export async function watchTask(deviceId, taskId, timeout): Promise {
- await new Promise(resolve => setTimeout(resolve, 500));
+export async function watchTask(
+ deviceId: string,
+ taskId: string,
+ timeout: number
+): Promise {
+ await new Promise((resolve) => setTimeout(resolve, 500));
const task = await db.tasksCollection.findOne(
{ _id: taskId },
@@ -182,7 +186,7 @@ export async function watchTask(deviceId, taskId, timeout): Promise {
const q = { _id: `${deviceId}:task_${taskId}` };
const fault = await db.faultsCollection.findOne(q, {
- projection: { _id: 1 }
+ projection: { _id: 1 },
});
if (fault) return "fault";
@@ -194,7 +198,7 @@ export async function watchTask(deviceId, taskId, timeout): Promise {
function sanitizeTask(task): void {
task.timestamp = new Date(task.timestamp || Date.now());
if (task.expiry) {
- if (common.typeOf(task.expiry) === common.DATE_TYPE || isNaN(task.expiry))
+ if (task.expiry instanceof Date || isNaN(task.expiry))
task.expiry = new Date(task.expiry);
else task.expiry = new Date(task.timestamp.getTime() + +task.expiry * 1000);
}
@@ -269,8 +273,8 @@ function sanitizeTask(task): void {
return task;
}
-export async function insertTasks(tasks): Promise {
- if (tasks && common.typeOf(tasks) !== common.ARRAY_TYPE) tasks = [tasks];
+export async function insertTasks(tasks: any[]): Promise {
+ if (tasks && !Array.isArray(tasks)) tasks = [tasks];
else if (!tasks || tasks.length === 0) return tasks || [];
for (const task of tasks) {
@@ -278,7 +282,7 @@ export async function insertTasks(tasks): Promise {
if (task.uniqueKey) {
await db.tasksCollection.deleteOne({
device: task.device,
- uniqueKey: task.uniqueKey
+ uniqueKey: task.uniqueKey,
});
}
}
@@ -286,20 +290,20 @@ export async function insertTasks(tasks): Promise {
return tasks;
}
-export async function deleteDevice(deviceId): Promise {
+export async function deleteDevice(deviceId: string): Promise {
await Promise.all([
db.tasksCollection.deleteMany({ device: deviceId }),
db.devicesCollection.deleteOne({ _id: deviceId }),
db.faultsCollection.deleteMany({
_id: {
- $regex: `^${common.escapeRegExp(deviceId)}\\:`
- }
+ $regex: `^${common.escapeRegExp(deviceId)}\\:`,
+ },
}),
db.operationsCollection.deleteMany({
_id: {
- $regex: `^${common.escapeRegExp(deviceId)}\\:`
- }
+ $regex: `^${common.escapeRegExp(deviceId)}\\:`,
+ },
}),
- cache.del(`${deviceId}_tasks_faults_operations`)
+ cache.del(`${deviceId}_tasks_faults_operations`),
]);
}
diff --git a/lib/auth.ts b/lib/auth.ts
index 6489303..28fa512 100644
--- a/lib/auth.ts
+++ b/lib/auth.ts
@@ -19,11 +19,11 @@
import { createHash, randomBytes, pbkdf2 } from "crypto";
-function parseHeaderFeilds(str: string): {} {
+function parseHeaderFeilds(str: string): Record {
const res = {};
const parts = str.split(",");
- let part;
+ let part: string;
while ((part = parts.shift()) != null) {
const name = part.split("=", 1)[0];
if (name.length === part.length) {
@@ -52,7 +52,9 @@ function parseHeaderFeilds(str: string): {} {
return res;
}
-export function parseAuthorizationHeader(authHeader): { method: string } {
+export function parseAuthorizationHeader(
+ authHeader: string
+): { method: string } {
authHeader = authHeader.trim();
const method = authHeader.split(" ", 1)[0];
const res = { method: method };
@@ -74,7 +76,9 @@ export function parseAuthorizationHeader(authHeader): { method: string } {
return res;
}
-export function parseWwwAuthenticateHeader(authHeader): {} {
+export function parseWwwAuthenticateHeader(
+ authHeader: string
+): Record {
authHeader = authHeader.trim();
const method = authHeader.split(" ", 1)[0];
const res = { method: method };
@@ -82,7 +86,7 @@ export function parseWwwAuthenticateHeader(authHeader): {} {
return res;
}
-export function basic(username, password): string {
+export function basic(username: string, password: string): string {
return "Basic " + Buffer.from(`${username}:${password}`).toString("base64");
}
@@ -99,20 +103,12 @@ export function digest(
nc?: string | Buffer
): string {
const ha1 = createHash("md5");
- ha1
- .update(username)
- .update(":")
- .update(realm)
- .update(":")
- .update(password);
+ ha1.update(username).update(":").update(realm).update(":").update(password);
// TODO support "MD5-sess" algorithm directive
const ha1d = ha1.digest("hex");
const ha2 = createHash("md5");
- ha2
- .update(httpMethod)
- .update(":")
- .update(uri);
+ ha2.update(httpMethod).update(":").update(uri);
if (qop === "auth-int") {
const bodyHash = createHash("md5")
@@ -124,10 +120,7 @@ export function digest(
const ha2d = ha2.digest("hex");
const hash = createHash("md5");
- hash
- .update(ha1d)
- .update(":")
- .update(nonce);
+ hash.update(ha1d).update(":").update(nonce);
if (qop) {
hash
.update(":")
@@ -148,7 +141,7 @@ export function solveDigest(
uri: string | Buffer,
httpMethod: string | Buffer,
body: string | Buffer,
- authHeader
+ authHeader: Record
): string {
const cnonce = randomBytes(8).toString("hex");
const nc = "00000001";
@@ -185,7 +178,7 @@ export function solveDigest(
return authString;
}
-export function generateSalt(length): Promise {
+export function generateSalt(length: number): Promise {
return new Promise((resolve, reject) => {
randomBytes(length, (err, rand) => {
if (err) return void reject(err);
@@ -194,7 +187,7 @@ export function generateSalt(length): Promise {
});
}
-export function hashPassword(pass, salt): Promise {
+export function hashPassword(pass: string, salt: string): Promise {
return new Promise((resolve, reject) => {
pbkdf2(pass, salt, 10000, 128, "sha512", (err, hash) => {
if (err) return void reject(err);
diff --git a/lib/cache.ts b/lib/cache.ts
index 1a01b71..f32318f 100644
--- a/lib/cache.ts
+++ b/lib/cache.ts
@@ -29,7 +29,7 @@ let mongoTimeOffset = 0;
export async function connect(): Promise {
const MONGODB_CONNECTION_URL = "" + config.get("MONGODB_CONNECTION_URL");
clientPromise = MongoClient.connect(MONGODB_CONNECTION_URL, {
- useNewUrlParser: true
+ useNewUrlParser: true,
});
const db = (await clientPromise).db();
mongoCollection = db.collection("cache");
@@ -43,7 +43,7 @@ export async function disconnect(): Promise {
if (clientPromise) await (await clientPromise).close();
}
-export async function get(key): Promise {
+export async function get(key: string | string[]): Promise {
const expire = new Date(Date.now() - mongoTimeOffset);
if (Array.isArray(key)) {
const res = await mongoCollection.find({ _id: { $in: key } }).toArray();
@@ -54,7 +54,7 @@ export async function get(key): Promise {
});
const values = [];
- res.forEach(r => {
+ res.forEach((r) => {
if (r["expire"] > expire) values[indices[r["_id"]]] = r["value"];
});
@@ -66,7 +66,7 @@ export async function get(key): Promise {
}
}
-export async function del(key): Promise {
+export async function del(key: string | string[]): Promise {
if (Array.isArray(key))
await mongoCollection.deleteMany({ _id: { $in: key } });
else await mongoCollection.deleteOne({ _id: key });
@@ -85,7 +85,7 @@ export async function set(
);
}
-export async function pop(key): Promise {
+export async function pop(key: string): Promise {
const res = await mongoCollection.findOneAndDelete({ _id: key });
if (
@@ -98,16 +98,17 @@ export async function pop(key): Promise {
return null;
}
-export async function lock(lockName, ttl): Promise {
- const token = Math.random()
- .toString(36)
- .slice(2);
+export async function lock(
+ lockName: string,
+ ttl: number
+): Promise<(extendTtl?: number) => Promise> {
+ const token = Math.random().toString(36).slice(2);
- async function unlockOrExtend(extendTtl): Promise {
+ async function unlockOrExtend(extendTtl?: number): Promise {
if (!extendTtl) {
const res = await mongoCollection.deleteOne({
_id: lockName,
- value: token
+ value: token,
});
if (res["result"]["n"] !== 1) throw new Error("Lock expired");
} else {
@@ -131,7 +132,7 @@ export async function lock(lockName, ttl): Promise {
);
} catch (err) {
if (err && err.code === 11000) {
- await new Promise(resolve => setTimeout(resolve, 200));
+ await new Promise((resolve) => setTimeout(resolve, 200));
return lock(lockName, ttl);
}
}
diff --git a/lib/cluster.ts b/lib/cluster.ts
index 12f0559..4010af6 100644
--- a/lib/cluster.ts
+++ b/lib/cluster.ts
@@ -41,7 +41,7 @@ function restartWorker(worker, code, signal): void {
message: "Worker died",
pid: worker.process.pid,
exitCode: null,
- signal: null
+ signal: null,
};
if (code != null) msg.exitCode = code;
@@ -57,7 +57,7 @@ function restartWorker(worker, code, signal): void {
min2 = 0,
min3 = 0;
- crashes = crashes.filter(n => {
+ crashes = crashes.filter((n) => {
if (n > now - 60000) ++min1;
else if (n > now - 120000) ++min2;
else if (n > now - 180000) ++min3;
@@ -72,7 +72,7 @@ function restartWorker(worker, code, signal): void {
logger.error({
message: "Too many crashes, exiting",
- pid: process.pid
+ pid: process.pid,
});
return;
}
@@ -89,7 +89,11 @@ function restartWorker(worker, code, signal): void {
}, respawnTimestamp - now);
}
-export function start(workerCount, servicePort, serviceAddress): void {
+export function start(
+ workerCount: number,
+ servicePort: number,
+ serviceAddress: string
+): void {
cluster.on("listening", (worker, address) => {
if (
(address.addressType === 4 || address.addressType === 6) &&
@@ -100,7 +104,7 @@ export function start(workerCount, servicePort, serviceAddress): void {
message: "Worker listening",
pid: worker.process.pid,
address: address.address,
- port: address.port
+ port: address.port,
});
}
});
diff --git a/lib/common.ts b/lib/common.ts
index 7fed1af..54454c1 100644
--- a/lib/common.ts
+++ b/lib/common.ts
@@ -17,22 +17,12 @@
* along with GenieACS. If not, see .
*/
-export const UNDEFINED_TYPE = "[object Undefined]";
-export const NULL_TYPE = "[object Null]";
-export const BOOLEAN_TYPE = "[object Boolean]";
-export const NUMBER_TYPE = "[object Number]";
-export const STRING_TYPE = "[object String]";
-export const ARRAY_TYPE = "[object Array]";
-export const OBJECT_TYPE = "[object Object]";
-export const REGEXP_TYPE = "[object RegExp]";
-export const DATE_TYPE = "[object Date]";
-
-export const typeOf = (obj): string => Object.prototype.toString.call(obj);
-
-export function generateDeviceId(deviceIdStruct): string {
+export function generateDeviceId(
+ deviceIdStruct: Record
+): string {
// Escapes everything except alphanumerics and underscore
function esc(str): string {
- return str.replace(/[^A-Za-z0-9_]/g, chr => {
+ return str.replace(/[^A-Za-z0-9_]/g, (chr) => {
const buf = Buffer.from(chr, "utf8");
let rep = "";
for (const b of buf) rep += "%" + b.toString(16).toUpperCase();
@@ -54,6 +44,6 @@ export function generateDeviceId(deviceIdStruct): string {
}
// Source: http://stackoverflow.com/a/6969486
-export function escapeRegExp(str): string {
+export function escapeRegExp(str: string): string {
return str.replace(/[-[\]/{}()*+?.\\^$|]/g, "\\$&");
}
diff --git a/lib/common/authorizer.ts b/lib/common/authorizer.ts
index 793df6b..f4e2550 100644
--- a/lib/common/authorizer.ts
+++ b/lib/common/authorizer.ts
@@ -23,13 +23,13 @@ import { evaluate, or } from "./expression";
export default class Authorizer {
private permissionSets: PermissionSet[];
private validatorCache: WeakMap<
- object,
+ any,
(mutationType, mutation, any) => boolean
>;
private hasAccessCache: Map;
private getFilterCache: Map;
- public constructor(permissionSets) {
+ public constructor(permissionSets: PermissionSet[]) {
this.permissionSets = permissionSets;
this.validatorCache = new WeakMap();
this.hasAccessCache = new Map();
@@ -77,8 +77,8 @@ export default class Authorizer {
}
public getValidator(
- resourceType,
- resource
+ resourceType: string,
+ resource: unknown
): (mutationType: string, mutation?: any, args?: any) => boolean {
if (this.validatorCache.has(resource))
return this.validatorCache.get(resource);
@@ -108,7 +108,7 @@ export default class Authorizer {
mutation,
resourceType,
object: resource,
- options: any
+ options: any,
};
const valueFunction = (paramName): any => {
diff --git a/lib/common/expression-cnf.ts b/lib/common/expression-cnf.ts
index c5e44fa..2aacf75 100644
--- a/lib/common/expression-cnf.ts
+++ b/lib/common/expression-cnf.ts
@@ -65,7 +65,7 @@ function likePatternIncludes(pat1, pat2, idx1 = 0, idx2 = 0): boolean {
export function booleanCnf(exp: Expression): { vars: number; clauses: CNF } {
const ranges = new Map();
const likePatterns = new Map();
- map(exp, e => {
+ map(exp, (e) => {
if (!Array.isArray(e)) return e;
if (e[0] === "LIKE" || e[0] === "NOT LIKE") {
if (
@@ -151,7 +151,7 @@ export function booleanCnf(exp: Expression): { vars: number; clauses: CNF } {
if (to == null) vars.push(`${lhs}:${range[range.length - 1]}--`);
- return vars.map(key => {
+ return vars.map((key) => {
let f = expressions.get(key);
if (!f) {
expressions.set(key, (f = expressions.size + 1));
@@ -172,7 +172,7 @@ export function booleanCnf(exp: Expression): { vars: number; clauses: CNF } {
vars.push(`${lhs}:like:${JSON.stringify(p)}`);
}
- return vars.map(key => {
+ return vars.map((key) => {
let f = expressions.get(key);
if (!f) expressions.set(key, (f = expressions.size + 1));
return f;
@@ -184,11 +184,11 @@ export function booleanCnf(exp: Expression): { vars: number; clauses: CNF } {
}
const comparisonOperators: ComparisonOperators = {
- "=": v => [v, true, v, true],
- ">": v => [v, false, null, null],
- ">=": v => [v, true, null, null],
- "<": v => [null, null, v, false],
- "<=": v => [null, null, v, true]
+ "=": (v) => [v, true, v, true],
+ ">": (v) => [v, false, null, null],
+ ">=": (v) => [v, true, null, null],
+ "<": (v) => [null, null, v, false],
+ "<=": (v) => [null, null, v, true],
};
function recursive(clause, negate): CNF {
@@ -211,7 +211,7 @@ export function booleanCnf(exp: Expression): { vars: number; clauses: CNF } {
JSON.stringify(clause[1]),
...comparisonOperators["="](clause[2])
);
- if (!negate) return vars.map(x => [0 - x]);
+ if (!negate) return vars.map((x) => [0 - x]);
else return [vars];
} else if (op === "IS NULL") {
const v = getVariable(JSON.stringify(clause[1]), "null");
@@ -227,7 +227,7 @@ export function booleanCnf(exp: Expression): { vars: number; clauses: CNF } {
JSON.stringify(clause[1]),
...comparisonOperators[op](clause[2])
);
- if (negate) return vars.map(x => [0 - x]);
+ if (negate) return vars.map((x) => [0 - x]);
else return [vars];
} else if (!Array.isArray(clause[1])) {
op = { ">": "<", ">=": "<=", "<": ">", "<=": ">=" }[op] || op;
@@ -235,7 +235,7 @@ export function booleanCnf(exp: Expression): { vars: number; clauses: CNF } {
JSON.stringify(clause[2]),
...comparisonOperators[op](clause[1])
);
- if (negate) return vars.map(x => [0 - x]);
+ if (negate) return vars.map((x) => [0 - x]);
else return [vars];
} else {
let lhs = JSON.stringify(clause[1]);
@@ -264,7 +264,7 @@ export function booleanCnf(exp: Expression): { vars: number; clauses: CNF } {
clause[2],
clause[3]
);
- if (negate) return vars.map(x => [0 - x]);
+ if (negate) return vars.map((x) => [0 - x]);
else return [vars];
} else {
const v = getVariable(JSON.stringify(clause), "");
diff --git a/lib/common/expression-parser.ts b/lib/common/expression-parser.ts
index b78cf55..79fbbc2 100644
--- a/lib/common/expression-parser.ts
+++ b/lib/common/expression-parser.ts
@@ -27,7 +27,7 @@ function interpretEscapes(str): string {
f: "\f",
n: "\n",
r: "\r",
- t: "\t"
+ t: "\t",
};
return str.replace(/\\(u[0-9a-fA-F]{4}|[^u])/, (_, escape) => {
const type = escape.charAt(0);
@@ -40,7 +40,10 @@ function interpretEscapes(str): string {
});
}
-export function map(exp, callback): Expression {
+export function map(
+ exp: Expression,
+ callback: (exp: Expression) => Expression
+): Expression {
if (!Array.isArray(exp)) return callback(exp);
let clone;
@@ -55,7 +58,10 @@ export function map(exp, callback): Expression {
return callback(clone || exp);
}
-export async function mapAsync(exp, callback): Promise {
+export async function mapAsync(
+ exp: Expression,
+ callback: (exp: Expression) => Promise
+): Promise {
if (!Array.isArray(exp)) return callback(exp);
let clone;
@@ -70,7 +76,7 @@ export async function mapAsync(exp, callback): Promise {
return callback(clone || exp);
}
-function binaryLeft(operatorsParser, nextParser): parsimmon.Parser<{}> {
+function binaryLeft(operatorsParser, nextParser): parsimmon.Parser {
return parsimmon.seqMap(
nextParser,
parsimmon.seq(operatorsParser, nextParser).many(),
@@ -86,7 +92,7 @@ function binaryLeft(operatorsParser, nextParser): parsimmon.Parser<{}> {
}
const lang = parsimmon.createLanguage({
- ComparisonOperator: function() {
+ ComparisonOperator: function () {
return parsimmon
.alt(
parsimmon.string(">="),
@@ -98,13 +104,10 @@ const lang = parsimmon.createLanguage({
)
.skip(parsimmon.optWhitespace);
},
- LikeOperator: function() {
+ LikeOperator: function () {
return parsimmon
.alt(
- parsimmon
- .regexp(/like/i)
- .result("LIKE")
- .desc("LIKE"),
+ parsimmon.regexp(/like/i).result("LIKE").desc("LIKE"),
parsimmon
.regexp(/not\s+like/i)
.result("NOT LIKE")
@@ -113,7 +116,7 @@ const lang = parsimmon.createLanguage({
.notFollowedBy(parsimmon.regexp(/[a-zA-Z0-9_]/))
.skip(parsimmon.optWhitespace);
},
- IsNullOperator: function() {
+ IsNullOperator: function () {
return parsimmon
.alt(
parsimmon
@@ -128,7 +131,7 @@ const lang = parsimmon.createLanguage({
.notFollowedBy(parsimmon.regexp(/[a-zA-Z0-9_]/))
.skip(parsimmon.optWhitespace);
},
- NotOperator: function() {
+ NotOperator: function () {
return parsimmon
.regexp(/not/i)
.result("NOT")
@@ -136,7 +139,7 @@ const lang = parsimmon.createLanguage({
.skip(parsimmon.optWhitespace)
.desc("NOT");
},
- AndOperator: function() {
+ AndOperator: function () {
return parsimmon
.regexp(/and/i)
.result("AND")
@@ -144,7 +147,7 @@ const lang = parsimmon.createLanguage({
.skip(parsimmon.optWhitespace)
.desc("AND");
},
- OrOperator: function() {
+ OrOperator: function () {
return parsimmon
.regexp(/or/i)
.result("OR")
@@ -152,7 +155,7 @@ const lang = parsimmon.createLanguage({
.skip(parsimmon.optWhitespace)
.desc("OR");
},
- Parameter: function(r) {
+ Parameter: function (r) {
return parsimmon
.alt(
parsimmon.regexp(/[a-zA-Z0-9_.*-]+/),
@@ -162,48 +165,42 @@ const lang = parsimmon.createLanguage({
)
)
.atLeast(1)
- .map(x => ["PARAM", x.length > 1 ? ["||"].concat(x) : x[0]])
+ .map((x) => ["PARAM", x.length > 1 ? ["||"].concat(x) : x[0]])
.skip(parsimmon.optWhitespace)
.desc("parameter");
},
- StringValueSql: function() {
+ StringValueSql: function () {
return parsimmon
.regexp(/'([^']*)'/, 1)
.atLeast(1)
.skip(parsimmon.optWhitespace)
- .map(s => s.join("'"))
+ .map((s) => s.join("'"))
.desc("string");
},
- StringValueJs: function() {
+ StringValueJs: function () {
return parsimmon
.regexp(/"((?:\\.|.)*?)"/, 1)
.skip(parsimmon.optWhitespace)
.map(interpretEscapes)
.desc("string");
},
- NumberValue: function() {
+ NumberValue: function () {
return parsimmon
.regexp(/-?(0|[1-9][0-9]*)([.][0-9]+)?([eE][+-]?[0-9]+)?/)
.skip(parsimmon.optWhitespace)
.map(Number)
.desc("number");
},
- BooleanValue: function() {
+ BooleanValue: function () {
return parsimmon
.alt(
- parsimmon
- .regexp(/true/i)
- .result(true)
- .desc("TRUE"),
- parsimmon
- .regexp(/false/i)
- .result(false)
- .desc("FALSE")
+ parsimmon.regexp(/true/i).result(true).desc("TRUE"),
+ parsimmon.regexp(/false/i).result(false).desc("FALSE")
)
.notFollowedBy(parsimmon.regexp(/[a-zA-Z0-9_]/))
.skip(parsimmon.optWhitespace);
},
- NullValue: function() {
+ NullValue: function () {
return parsimmon
.regexp(/null/i)
.notFollowedBy(parsimmon.regexp(/[a-zA-Z0-9_]/))
@@ -211,7 +208,7 @@ const lang = parsimmon.createLanguage({
.result(null)
.desc("NULL");
},
- FuncValue: function(r) {
+ FuncValue: function (r) {
return parsimmon.seqMap(
parsimmon
.regexp(/([a-zA-Z0-9_]+)/, 1)
@@ -226,7 +223,7 @@ const lang = parsimmon.createLanguage({
(f, args) => ["FUNC", f.toUpperCase()].concat(args)
);
},
- Value: function(r) {
+ Value: function (r) {
return parsimmon.alt(
r.NullValue,
r.BooleanValue,
@@ -236,7 +233,7 @@ const lang = parsimmon.createLanguage({
r.FuncValue
);
},
- ValueExpression: function(r) {
+ ValueExpression: function (r) {
return binaryLeft(
parsimmon.string("||").skip(parsimmon.optWhitespace),
binaryLeft(
@@ -259,7 +256,7 @@ const lang = parsimmon.createLanguage({
)
);
},
- Comparison: function(r) {
+ Comparison: function (r) {
return parsimmon.alt(
parsimmon.seqMap(r.ValueExpression, r.IsNullOperator, (p, o) => [o, p]),
parsimmon.seqMap(
@@ -289,8 +286,8 @@ const lang = parsimmon.createLanguage({
)
);
},
- Expression: function(r) {
- function unary(operatorsParser, nextParser): parsimmon.Parser<{}> {
+ Expression: function (r) {
+ function unary(operatorsParser, nextParser): parsimmon.Parser {
return parsimmon.seq(operatorsParser, nextParser).or(nextParser);
}
@@ -301,7 +298,7 @@ const lang = parsimmon.createLanguage({
unary(r.NotOperator, r.Comparison.or(r.ValueExpression))
)
).trim(parsimmon.optWhitespace);
- }
+ },
});
export function parse(str: string): Expression {
@@ -309,7 +306,7 @@ export function parse(str: string): Expression {
return lang.Expression.tryParse(str);
}
-export function stringify(exp, level = 0): string {
+export function stringify(exp: Expression, level = 0): string {
if (!Array.isArray(exp)) return JSON.stringify(exp);
const opLevels = {
@@ -330,7 +327,7 @@ export function stringify(exp, level = 0): string {
"+": 31,
"-": 31,
"*": 32,
- "/": 32
+ "/": 32,
};
const op = exp[0].toUpperCase();
@@ -344,7 +341,7 @@ export function stringify(exp, level = 0): string {
return wrap(
`${exp[1]}(${exp
.slice(2)
- .map(e => stringify(e))
+ .map((e) => stringify(e))
.join(", ")})`
);
} else if (op === "PARAM") {
@@ -354,7 +351,7 @@ export function stringify(exp, level = 0): string {
return wrap(
exp[1]
.slice(1)
- .map(p => {
+ .map((p) => {
if (typeof p === "string") return p;
else return `{${stringify(p)}}`;
})
@@ -393,7 +390,7 @@ export function stringify(exp, level = 0): string {
}
}
-export function parseLikePattern(pat, esc): string[] {
+export function parseLikePattern(pat: string, esc: string): string[] {
const chars = pat.split("");
for (let i = 0; i < chars.length; ++i) {
@@ -408,5 +405,5 @@ export function parseLikePattern(pat, esc): string[] {
while (chars[i + 1] === "%") chars[++i] = "";
}
}
- return chars.filter(c => c);
+ return chars.filter((c) => c);
}
diff --git a/lib/common/expression.ts b/lib/common/expression.ts
index 2f30cbd..703310b 100644
--- a/lib/common/expression.ts
+++ b/lib/common/expression.ts
@@ -24,7 +24,7 @@ import { Expression } from "../types";
const isArray = Array.isArray;
-const regExpCache = new WeakMap