Update linting

This commit is contained in:
Zaid Humaimidi committed 2023-12-16 19:08:13 -08:00
1 parent 4f2dfb4f48
commit 0c9c027a77
112 files changed
+3781 -4125

No files matched your search

+16 -16
View File
@@ -57,7 +57,7 @@ import { ResourceLockedError } from "./common/errors";
export async function connectionRequest(
deviceId: string,
device?: Record<string, { value?: [boolean | number | string, string] }>
device?: Record<string, { value?: [boolean | number | string, string] }>,
): Promise<string> {
if (!device) {
const res = await collections.devices.findOne({ _id: deviceId });
@@ -132,25 +132,25 @@ export async function connectionRequest(
"cwmp.udpConnectionRequestPort",
{},
now,
evalCallback
evalCallback,
);
const CONNECTION_REQUEST_TIMEOUT = +getConfig(
snapshot,
"cwmp.connectionRequestTimeout",
{},
now,
evalCallback
evalCallback,
);
const CONNECTION_REQUEST_ALLOW_BASIC_AUTH = !!getConfig(
snapshot,
"cwmp.connectionRequestAllowBasicAuth",
{},
now,
evalCallback
evalCallback,
);
let authExp: Expression = getConfigExpression(
snapshot,
"cwmp.connectionRequestAuth"
"cwmp.connectionRequestAuth",
);
if (authExp === undefined) {
@@ -176,10 +176,10 @@ export async function connectionRequest(
authExp,
UDP_CONNECTION_REQUEST_PORT,
debug,
deviceId
deviceId,
).then(
() => true,
() => false
() => false,
);
} catch (err) {
// Ignore invalid address
@@ -192,7 +192,7 @@ export async function connectionRequest(
CONNECTION_REQUEST_ALLOW_BASIC_AUTH,
CONNECTION_REQUEST_TIMEOUT,
debug,
deviceId
deviceId,
);
if (await udpProm) return "";
@@ -203,12 +203,12 @@ export async function connectionRequest(
export async function awaitSessionStart(
deviceId: string,
lastInform: number,
timeout: number
timeout: number,
): Promise<boolean> {
const now = Date.now();
const device = await collections.devices.findOne(
{ _id: deviceId },
{ projection: { _lastInform: 1 } }
{ projection: { _lastInform: 1 } },
);
const li = (device["_lastInform"] as Date).getTime();
if (li > lastInform) return true;
@@ -222,7 +222,7 @@ export async function awaitSessionStart(
export async function awaitSessionEnd(
deviceId: string,
timeout: number
timeout: number,
): Promise<boolean> {
const now = Date.now();
const token = await getToken(`cwmp_session_${deviceId}`);
@@ -317,8 +317,8 @@ function sanitizeTask(task): void {
!task.provisions.every((arr) =>
arr.every(
(s) =>
s == null || ["boolean", "number", "string"].includes(typeof s)
)
s == null || ["boolean", "number", "string"].includes(typeof s),
),
)
)
throw new Error("Invalid 'provisions' property");
@@ -395,7 +395,7 @@ export async function deleteFault(id: string): Promise<void> {
export async function deleteResource(
resource: string,
id: string
id: string,
): Promise<void> {
if (resource === "devices") {
await deleteDevice(id);
@@ -434,7 +434,7 @@ export async function deleteResource(
export async function putResource(
resource: string,
id: string,
data: any
data: any,
): Promise<void> {
if (resource === "presets") {
await putPreset(id, data);
@@ -467,7 +467,7 @@ export async function putResource(
export function authLocal(
snapshot: string,
username: string,
password: string
password: string,
): Promise<boolean> {
return new Promise((resolve, reject) => {
const users = getUsers(snapshot);
+5 -5
View File
@@ -63,7 +63,7 @@ export function parseAuthorizationHeader(authHeader: string): {
// Inspired by https://github.com/jshttp/basic-auth
const USER_PASS_REGEX = /^([^:]*):(.*)$/;
const creds = USER_PASS_REGEX.exec(
Buffer.from(authHeader.slice(method.length + 1), "base64").toString()
Buffer.from(authHeader.slice(method.length + 1), "base64").toString(),
);
if (!creds) throw new Error("Unable to parse auth header");
@@ -77,7 +77,7 @@ export function parseAuthorizationHeader(authHeader: string): {
}
export function parseWwwAuthenticateHeader(
authHeader: string
authHeader: string,
): Record<string, string> {
authHeader = authHeader.trim();
const method = authHeader.split(" ", 1)[0];
@@ -100,7 +100,7 @@ export function digest(
qop?: string | Buffer,
body?: string | Buffer,
cnonce?: string | Buffer,
nc?: string | Buffer
nc?: string | Buffer,
): string {
const ha1 = createHash("md5");
ha1.update(username).update(":").update(realm).update(":").update(password);
@@ -141,7 +141,7 @@ export function solveDigest(
uri: string | Buffer,
httpMethod: string | Buffer,
body: string | Buffer,
authHeader: Record<string, string>
authHeader: Record<string, string>,
): string {
const cnonce = randomBytes(8).toString("hex");
const nc = "00000001";
@@ -163,7 +163,7 @@ export function solveDigest(
qop,
body,
cnonce,
nc
nc,
);
let authString = `Digest username="${username}"`;
+3 -3
View File
@@ -35,16 +35,16 @@ export async function del(key: string): Promise<void> {
export async function set(
key: string,
value: string,
ttl: number = MAX_CACHE_TTL
ttl: number = MAX_CACHE_TTL,
): Promise<void> {
const timestamp = new Date();
const expire = new Date(
timestamp.getTime() + CLOCK_SKEW_TOLERANCE + ttl * 1000
timestamp.getTime() + CLOCK_SKEW_TOLERANCE + ttl * 1000,
);
await collections.cache.replaceOne(
{ _id: key },
{ value, expire, timestamp },
{ upsert: true }
{ upsert: true },
);
}
+1 -1
View File
@@ -92,7 +92,7 @@ function restartWorker(worker, code, signal): void {
export function start(
workerCount: number,
servicePort: number,
serviceAddress: string
serviceAddress: string,
): void {
cluster.on("listening", (worker, address) => {
if (
+3 -3
View File
@@ -78,7 +78,7 @@ export default class Authorizer {
public getValidator(
resourceType: string,
resource: unknown
resource: unknown,
): (mutationType: string, mutation?: any, args?: any) => boolean {
if (this.validatorCache.has(resource))
return this.validatorCache.get(resource);
@@ -99,7 +99,7 @@ export default class Authorizer {
const validator = (
mutationType: string,
mutation: any,
any: any
any: any,
): boolean => {
if (!validators.length) return false;
@@ -134,7 +134,7 @@ export default class Authorizer {
const res = evaluate(
validators.length > 1 ? ["OR", validators] : validators[0],
valueFunction,
Date.now()
Date.now(),
);
return !Array.isArray(res) && !!res;
};
+1 -1
View File
@@ -1,6 +1,6 @@
export default function debounce<T>(
func: (args: T[]) => void,
timeout: number
timeout: number,
): (arg: T) => void {
let timer: ReturnType<typeof setTimeout>;
let args: T[] = [];
+16 -16
View File
@@ -32,7 +32,7 @@ class Indeterminates {
public static multiply(
indeterminates1: Indeterminates,
indeterminates2: Indeterminates
indeterminates2: Indeterminates,
): Indeterminates {
const res = new Indeterminates();
res.sortedKeys = indeterminates1.sortedKeys.slice();
@@ -108,7 +108,7 @@ class Polynomial {
const ts = terms
.slice()
.sort((a: Term, b: Term) =>
Indeterminates.compare(a.indeterminates, b.indeterminates)
Indeterminates.compare(a.indeterminates, b.indeterminates),
);
for (let i = 1; i < ts.length; ++i) {
@@ -117,12 +117,12 @@ class Polynomial {
if (Indeterminates.compare(t1.indeterminates, t2.indeterminates) === 0) {
const numerator = BI.add(
BI.mul(t1.coefficientNumerator, t2.coefficientDenominator),
BI.mul(t2.coefficientNumerator, t1.coefficientDenominator)
BI.mul(t2.coefficientNumerator, t1.coefficientDenominator),
);
const denominator = BI.mul(
t1.coefficientDenominator,
t2.coefficientDenominator
t2.coefficientDenominator,
);
const gcd = findGcd(numerator, denominator);
@@ -163,7 +163,7 @@ class Polynomial {
denominator = BI.exp(TWO, BI.BigInt(frac.length));
numerator = BI.add(
BI.mul(numerator, denominator),
BI.BigInt("0b" + frac)
BI.BigInt("0b" + frac),
);
}
@@ -204,7 +204,7 @@ class Polynomial {
public add(rhs: Polynomial): Polynomial {
return new Polynomial(
Polynomial.simplifyTerms(this.terms.concat(rhs.terms))
Polynomial.simplifyTerms(this.terms.concat(rhs.terms)),
);
}
@@ -219,18 +219,18 @@ class Polynomial {
for (const t2 of rhs.terms) {
const numerator = BI.mul(
t1.coefficientNumerator,
t2.coefficientNumerator
t2.coefficientNumerator,
);
const denominator = BI.mul(
t1.coefficientDenominator,
t2.coefficientDenominator
t2.coefficientDenominator,
);
const gcd = findGcd(numerator, denominator);
terms.push({
indeterminates: Indeterminates.multiply(
t1.indeterminates,
t2.indeterminates
t2.indeterminates,
),
coefficientNumerator: BI.div(numerator, gcd),
coefficientDenominator: BI.div(denominator, gcd),
@@ -339,7 +339,7 @@ function normalizeCallback(exp: Expression): Expression {
const e = (r[1] as Expression[]).slice();
e[i] = t;
return [and(w, r[0]), e] as [Expression, Expression];
})
}),
);
if (!Array.isArray(w) && w) break;
}
@@ -373,7 +373,7 @@ function normalizeCallback(exp: Expression): Expression {
}
return args.reduce(
(previousValue, currentValue) => previousValue.add(currentValue),
ADDITIVE_IDENTITY
ADDITIVE_IDENTITY,
) as unknown as Expression;
} else if (op === "*") {
const args: Polynomial[] = [];
@@ -384,7 +384,7 @@ function normalizeCallback(exp: Expression): Expression {
}
return args.reduce(
(previousValue, currentValue) => previousValue.multiply(currentValue),
MULTIPLICATIVE_IDENTITY
MULTIPLICATIVE_IDENTITY,
) as unknown as Expression;
} else if (op === "-") {
const args: Polynomial[] = [];
@@ -394,7 +394,7 @@ function normalizeCallback(exp: Expression): Expression {
args.push(p);
}
return args.reduce((previousValue, currentValue) =>
previousValue.subtract(currentValue)
previousValue.subtract(currentValue),
) as unknown as Expression;
} else if (op === "/") {
const args: Polynomial[] = [];
@@ -404,7 +404,7 @@ function normalizeCallback(exp: Expression): Expression {
args.push(p);
}
return args.reduce((previousValue, currentValue) =>
previousValue.divide(currentValue)
previousValue.divide(currentValue),
) as unknown as Expression;
} else if (["=", "<>", ">", ">=", "<", "<="].includes(op)) {
if (exp[1] == null || exp[2] == null) return null;
@@ -471,7 +471,7 @@ function normalizeCallback(exp: Expression): Expression {
// Restore polynomial expressions
exp = exp.map((e) =>
e instanceof Polynomial ? JSON.parse(e.toString()) : e
e instanceof Polynomial ? JSON.parse(e.toString()) : e,
);
exp = evaluateCallback(exp);
@@ -485,7 +485,7 @@ export default function normalize(expr: Expression): Expression {
expr = JSON.parse(expr.toString());
} else if (Array.isArray(expr) && expr[0] === "CASE") {
expr = expr.map((e) =>
e instanceof Polynomial ? JSON.parse(e.toString()) : e
e instanceof Polynomial ? JSON.parse(e.toString()) : e,
);
}
return expr;
+36 -36
View File
@@ -57,7 +57,7 @@ export function map<T>(exp: Expression, callback: (e: Expression) => T): T {
export async function mapAsync(
exp: Expression,
callback: (e: Expression) => Promise<Expression>
callback: (e: Expression) => Promise<Expression>,
): Promise<Expression> {
if (!Array.isArray(exp)) return callback(exp);
@@ -75,7 +75,7 @@ export async function mapAsync(
function binaryLeft(
operatorsParser: parsimmon.Parser<string>,
nextParser: parsimmon.Parser<Expression>
nextParser: parsimmon.Parser<Expression>,
): parsimmon.Parser<Expression> {
return parsimmon.seqMap(
nextParser,
@@ -85,7 +85,7 @@ function binaryLeft(
const [op, another] = ch;
if (Array.isArray(acc) && op === acc[0]) return acc.concat([another]);
return [op, acc, another];
}, first)
}, first),
);
}
@@ -98,7 +98,7 @@ const lang = parsimmon.createLanguage({
parsimmon.string("<="),
parsimmon.string("="),
parsimmon.string(">"),
parsimmon.string("<")
parsimmon.string("<"),
)
.skip(parsimmon.optWhitespace);
},
@@ -109,7 +109,7 @@ const lang = parsimmon.createLanguage({
parsimmon
.regexp(/not\s+like/i)
.result("NOT LIKE")
.desc("NOT LIKE")
.desc("NOT LIKE"),
)
.notFollowedBy(parsimmon.regexp(/[a-zA-Z0-9_]/))
.skip(parsimmon.optWhitespace);
@@ -124,7 +124,7 @@ const lang = parsimmon.createLanguage({
parsimmon
.regexp(/is\s+not\s+null/i)
.result("IS NOT NULL")
.desc("IS NOT NULL")
.desc("IS NOT NULL"),
)
.notFollowedBy(parsimmon.regexp(/[a-zA-Z0-9_]/))
.skip(parsimmon.optWhitespace);
@@ -159,8 +159,8 @@ const lang = parsimmon.createLanguage({
parsimmon.regexp(/[a-zA-Z0-9_.*-]+/),
r.Expression.wrap(
parsimmon.string("{").skip(parsimmon.optWhitespace),
parsimmon.string("}")
)
parsimmon.string("}"),
),
)
.atLeast(1)
.map((x) => ["PARAM", x.length > 1 ? ["||"].concat(x) : x[0]])
@@ -194,7 +194,7 @@ const lang = parsimmon.createLanguage({
return parsimmon
.alt(
parsimmon.regexp(/true/i).result(true).desc("TRUE"),
parsimmon.regexp(/false/i).result(false).desc("FALSE")
parsimmon.regexp(/false/i).result(false).desc("FALSE"),
)
.notFollowedBy(parsimmon.regexp(/[a-zA-Z0-9_]/))
.skip(parsimmon.optWhitespace);
@@ -215,9 +215,9 @@ const lang = parsimmon.createLanguage({
.desc("function"),
r.ExpressionList.wrap(
parsimmon.string("(").skip(parsimmon.optWhitespace),
parsimmon.string(")").skip(parsimmon.optWhitespace)
parsimmon.string(")").skip(parsimmon.optWhitespace),
),
(f, args) => ["FUNC", f.toUpperCase()].concat(args)
(f, args) => ["FUNC", f.toUpperCase()].concat(args),
);
},
WhenPair: function (r) {
@@ -233,7 +233,7 @@ const lang = parsimmon.createLanguage({
.notFollowedBy(parsimmon.regexp(/[a-zA-Z0-9_]/))
.skip(parsimmon.optWhitespace)
.desc("THEN")
.then(r.Expression)
.then(r.Expression),
);
},
CaseStatement: function (r) {
@@ -256,10 +256,10 @@ const lang = parsimmon.createLanguage({
.skip(
parsimmon
.regex(/end/i)
.notFollowedBy(parsimmon.regexp(/[a-zA-Z0-9_]/))
.notFollowedBy(parsimmon.regexp(/[a-zA-Z0-9_]/)),
)
.skip(parsimmon.optWhitespace),
(...arr) => arr.flat(2)
(...arr) => arr.flat(2),
);
},
Value: function (r) {
@@ -270,7 +270,7 @@ const lang = parsimmon.createLanguage({
r.StringValueSql,
r.StringValueJs,
r.FuncValue,
r.CaseStatement
r.CaseStatement,
);
},
ValueExpression: function (r) {
@@ -285,7 +285,7 @@ const lang = parsimmon.createLanguage({
.alt(
parsimmon.string("*"),
parsimmon.string("/"),
parsimmon.string("%")
parsimmon.string("%"),
)
.skip(parsimmon.optWhitespace),
parsimmon.alt(
@@ -293,11 +293,11 @@ const lang = parsimmon.createLanguage({
r.Parameter,
r.Expression.wrap(
parsimmon.string("(").skip(parsimmon.optWhitespace),
parsimmon.string(")").skip(parsimmon.optWhitespace)
)
)
)
)
parsimmon.string(")").skip(parsimmon.optWhitespace),
),
),
),
),
);
},
Comparison: function (r) {
@@ -307,7 +307,7 @@ const lang = parsimmon.createLanguage({
r.ValueExpression,
r.ComparisonOperator,
r.ValueExpression,
(p, o, v) => [o, p, v]
(p, o, v) => [o, p, v],
),
parsimmon.seqMap(
r.ValueExpression,
@@ -317,28 +317,28 @@ const lang = parsimmon.createLanguage({
.regexp(/escape/i)
.result("ESCAPE")
.skip(parsimmon.whitespace)
.desc("ESCAPE")
.desc("ESCAPE"),
),
r.ValueExpression,
(a, b, c, d) => [b, a, c, d]
(a, b, c, d) => [b, a, c, d],
),
parsimmon.seqMap(
r.ValueExpression,
r.LikeOperator,
r.ValueExpression,
(a, b, c) => [b, a, c]
)
(a, b, c) => [b, a, c],
),
);
},
ExpressionList: function (r) {
return r.Expression.sepBy(
parsimmon.string(",").skip(parsimmon.optWhitespace)
parsimmon.string(",").skip(parsimmon.optWhitespace),
);
},
Expression: function (r) {
function unary(
operatorsParser: parsimmon.Parser<string>,
nextParser: parsimmon.Parser<Expression>
nextParser: parsimmon.Parser<Expression>,
): parsimmon.Parser<Expression> {
return parsimmon.seq(operatorsParser, nextParser).or(nextParser);
}
@@ -347,8 +347,8 @@ const lang = parsimmon.createLanguage({
r.OrOperator,
binaryLeft(
r.AndOperator,
unary(r.NotOperator, r.Comparison.or(r.ValueExpression))
)
unary(r.NotOperator, r.Comparison.or(r.ValueExpression)),
),
).trim(parsimmon.optWhitespace);
},
});
@@ -400,7 +400,7 @@ export function stringify(exp: Expression, level = 0): string {
`${exp[1]}(${exp
.slice(2)
.map((e) => stringify(e))
.join(", ")})`
.join(", ")})`,
);
} else if (op === "PARAM") {
if (typeof exp[1] === "string") {
@@ -413,7 +413,7 @@ export function stringify(exp: Expression, level = 0): string {
if (typeof p === "string") return p;
else return `{${stringify(p)}}`;
})
.join("")
.join(""),
);
} else {
return wrap(`{${stringify(exp[1])}}`);
@@ -425,15 +425,15 @@ export function stringify(exp: Expression, level = 0): string {
return wrap(
`${stringify(exp[1], opLevels[op])} ${op} ${stringify(
exp[2],
opLevels[op]
)} ESCAPE ${stringify(exp[3], opLevels[op])}`
opLevels[op],
)} ESCAPE ${stringify(exp[3], opLevels[op])}`,
);
} else {
return wrap(
`${stringify(exp[1], opLevels[op])} ${op} ${stringify(
exp[2],
opLevels[op]
)}`
opLevels[op],
)}`,
);
}
} else if (op === "CASE") {
+26 -22
View File
@@ -7,7 +7,7 @@ type Minterm = number[];
export abstract class SynthContextBase<
T extends { toString: () => string } = unknown,
U = unknown
U = unknown,
> {
public variables = new Map<string, number>();
protected clauses = new Map<number, U>();
@@ -88,7 +88,7 @@ export abstract class Clause {
isNullable(c: Clause.IsNull): boolean {
if (!this._isNullable) {
this._isNullable = new Set(
[...this.getNullables()].map((n) => n.toString())
[...this.getNullables()].map((n) => n.toString()),
);
}
return this._isNullable.has(c.toString());
@@ -243,14 +243,14 @@ export namespace Clause {
const w = this.clauses[i].true(context);
const t = this.clauses[i + 1].true(context);
minterms.push(
...complement([...cumulative, ...complement(w), ...complement(t)])
...complement([...cumulative, ...complement(w), ...complement(t)]),
);
if (i < this.clauses.length - 2) {
cumulative.push(
...complement([
...this.clauses[i].false(context),
...this.clauses[i].null(context),
])
]),
);
}
}
@@ -263,14 +263,14 @@ export namespace Clause {
const w = this.clauses[i].true(context);
const t = this.clauses[i + 1].false(context);
minterms.push(
...complement([...cumulative, ...complement(w), ...complement(t)])
...complement([...cumulative, ...complement(w), ...complement(t)]),
);
if (i < this.clauses.length - 2) {
cumulative.push(
...complement([
...this.clauses[i].false(context),
...this.clauses[i].null(context),
])
]),
);
}
}
@@ -283,13 +283,13 @@ export namespace Clause {
const w = this.clauses[i].true(context);
const t = this.clauses[i + 1].null(context);
minterms.push(
...complement([...cumulative, ...complement(w), ...complement(t)])
...complement([...cumulative, ...complement(w), ...complement(t)]),
);
cumulative.push(
...complement([
...this.clauses[i].false(context),
...this.clauses[i].null(context),
])
]),
);
}
minterms.push(...complement([...cumulative]));
@@ -313,7 +313,7 @@ export namespace Clause {
minterms.push(...cases.pop().when);
minterms = context.minimize(
minterms,
cases.flatMap((c) => c.when)
cases.flatMap((c) => c.when),
);
if (!minterms.length) continue;
cases.push({ when: minterms, then });
@@ -395,7 +395,7 @@ export namespace Clause {
constructor(
public lhs: Clause,
public op: ">" | "<" | "=",
public rhs: boolean | number | string
public rhs: boolean | number | string,
) {
super();
}
@@ -425,7 +425,11 @@ export namespace Clause {
public readonly pattern: string[];
public readonly lhs: Clause;
constructor(lhs: Clause, public rhs: string, public esc?: string) {
constructor(
lhs: Clause,
public rhs: string,
public esc?: string,
) {
super();
const exp = lhs.expression();
let caseSensitive = true;
@@ -515,7 +519,7 @@ export namespace Clause {
clause = new Clause.Compare(
e[1],
op,
rhs as boolean | number | string
rhs as boolean | number | string,
);
}
}
@@ -535,7 +539,7 @@ export namespace Clause {
function groupBy<T, K>(
input: T[],
callback: (item: T) => K
callback: (item: T) => K,
): Iterable<[K, T[]]> {
const groups = new Map<K, T[]>();
for (const item of input) {
@@ -567,12 +571,12 @@ export class SynthContext extends SynthContextBase<Clause, Clause> {
const allClauses = [...whitelist].map((v) => this.getClause(v));
const comparisons = allClauses.filter(
(c) => c instanceof Clause.Compare
(c) => c instanceof Clause.Compare,
) as Clause.Compare[];
// Comparisons
for (const [, clauses] of groupBy(comparisons, (c) =>
JSON.stringify(c.lhs)
JSON.stringify(c.lhs),
)) {
const lhs = clauses[0].lhs;
const values = new Set(clauses.map((c) => c.rhs));
@@ -600,13 +604,13 @@ export class SynthContext extends SynthContextBase<Clause, Clause> {
for (let j = 0; j < i; j++) {
const eq2 = this.getVar(
new Clause.Compare(lhs, "=", valuesSorted[j])
new Clause.Compare(lhs, "=", valuesSorted[j]),
);
const gt2 = this.getVar(
new Clause.Compare(lhs, ">", valuesSorted[j])
new Clause.Compare(lhs, ">", valuesSorted[j]),
);
const lt2 = this.getVar(
new Clause.Compare(lhs, "<", valuesSorted[j])
new Clause.Compare(lhs, "<", valuesSorted[j]),
);
// This is the minimum clauses required if all relavent vars
@@ -631,7 +635,7 @@ export class SynthContext extends SynthContextBase<Clause, Clause> {
// LIKE
const likes = allClauses.filter(
(c) => c instanceof Clause.Like
(c) => c instanceof Clause.Like,
) as Clause.Like[];
for (const [, clauses] of groupBy(likes, (c) => JSON.stringify(c.lhs))) {
@@ -734,7 +738,7 @@ export class SynthContext extends SynthContextBase<Clause, Clause> {
for (const [k, v] of merged) {
if (v === 0b1010) continue loop;
const isNullVars = [...this.clauses.get(k).getNullables()].map((c) =>
this.getVar(c)
this.getVar(c),
);
const t = k << 2;
if (v === 0b0101) {
@@ -858,7 +862,7 @@ export function minimize(expr: Expression, boolean = false): Expression {
export function unionDiff(
expr1: Expression,
expr2: Expression
expr2: Expression,
): [Expression, Expression] {
expr2 = normalize(expr2);
@@ -887,7 +891,7 @@ export function unionDiff(
complement([
...complement([...expr1NullMinterms, ...expr1FalseMinterms]),
...complement(expr2Minterms),
])
]),
);
return [context.toExpression(union), context.toExpression(diff)];
+7 -7
View File
@@ -74,7 +74,7 @@ export function likePatternToRegExp(pat: string, esc = "", flags = ""): RegExp {
function compare(
a: boolean | number | string,
b: boolean | number | string
b: boolean | number | string,
): number {
if (typeof a === "boolean") a = +a;
if (typeof b === "boolean") b = +b;
@@ -287,19 +287,19 @@ export function evaluate(
exp: Expression,
obj: Record<string, unknown> | ((e: string) => Expression),
now: number,
cb?: (e: Expression) => Expression
cb?: (e: Expression) => Expression,
): string | number | boolean | null;
export function evaluate(
exp: Expression,
obj?: Record<string, unknown> | ((e: string) => Expression),
now?: number,
cb?: (e: Expression) => Expression
cb?: (e: Expression) => Expression,
): Expression;
export function evaluate(
exp: Expression,
obj?: Record<string, unknown> | ((e: string) => Expression),
now?: number,
cb?: (e: Expression) => Expression
cb?: (e: Expression) => Expression,
): Expression {
return map(exp, (e) => {
if (cb) e = cb(e);
@@ -327,19 +327,19 @@ export async function evaluateAsync(
exp: Expression,
obj: Record<string, unknown>,
now: number,
cb?: (e: Expression) => Promise<Expression>
cb?: (e: Expression) => Promise<Expression>,
): Promise<string | number | boolean | null>;
export async function evaluateAsync(
exp: Expression,
obj?: Record<string, unknown>,
now?: number,
cb?: (e: Expression) => Promise<Expression>
cb?: (e: Expression) => Promise<Expression>,
): Promise<Expression>;
export async function evaluateAsync(
exp: Expression,
obj?: Record<string, unknown>,
now?: number,
cb?: (e: Expression) => Promise<Expression>
cb?: (e: Expression) => Promise<Expression>,
): Promise<Expression> {
return mapAsync(exp, async (e) => {
if (cb) e = await cb(e);
+2 -2
View File
@@ -75,7 +75,7 @@ export default class PathSet {
path: Path,
superset = false,
subset = false,
depth: number = path.length
depth: number = path.length,
): Path[] {
if (path.alias) throw new Error("PathSet does not support aliased paths");
@@ -115,7 +115,7 @@ export default class PathSet {
res = [...fragmentIndexSet1, ...fragmentIndexSet2];
} else {
res = res.filter(
(r) => fragmentIndexSet1.has(r) || fragmentIndexSet2.has(r)
(r) => fragmentIndexSet1.has(r) || fragmentIndexSet2.has(r),
);
}
}
+5 -5
View File
@@ -57,7 +57,7 @@ export default class Path {
protected static parseAliasValue(
pattern: string,
index: number
index: number,
): { index: number; value: string } {
let i = index;
while (charCodeAt(pattern, i) === CHAR_SPACE) ++i;
@@ -89,7 +89,7 @@ export default class Path {
protected static parseAliasPath(
pattern: string,
index: number
index: number,
): { index: number; path: Path } {
let i = index;
while (charCodeAt(pattern, i) === CHAR_SPACE) ++i;
@@ -103,7 +103,7 @@ export default class Path {
protected static parseAlias(
pattern: string,
index: number
index: number,
): { index: number; alias: Alias } {
const alias: Alias = [];
let i = index;
@@ -136,7 +136,7 @@ export default class Path {
protected static parsePath(
pattern: string,
index: number
index: number,
): { index: number; segments: Segments } {
const segments = [];
@@ -173,7 +173,7 @@ export default class Path {
if (Array.isArray(s)) {
alias |= 1 << i;
const parts = s.map(
(al) => `${al[0].toString()}:${JSON.stringify(al[1])}`
(al) => `${al[0].toString()}:${JSON.stringify(al[1])}`,
);
return `[${parts.join(",")}]`;
} else if (s === "*") {
+6 -6
View File
@@ -15,7 +15,7 @@ const STRING_RESERVED = new Set([
function isPrintable(str: string): boolean {
return !/[^\t\n\x20-\x7e\x85\u{a0}-\u{d7ff}\u{e000}-\u{fffd}\u{10000}-\u{10ffff}]/u.test(
str
str,
);
}
@@ -99,7 +99,7 @@ function stringifyString(str: string, res: string[], prefix1, prefix2): void {
if (!isFolded) {
res.push(
`${prefix1}|${idt}${chmp}`,
...lines.map((l) => (l ? prefix2 + l : l))
...lines.map((l) => (l ? prefix2 + l : l)),
);
return;
}
@@ -129,7 +129,7 @@ function stringifyAny(
obj: unknown,
res: string[],
prefix1 = "",
prefix2 = ""
prefix2 = "",
): void {
if (obj == null) {
res.push(`${prefix1}null`);
@@ -183,7 +183,7 @@ function stringifyAny(
entries[0][1],
res,
prefix1 + `${stringifyKey(entries[0][0])}: `,
prefix2 + INDENTATION
prefix2 + INDENTATION,
);
prefix1 = prefix2;
prefix2 = prefix2 + INDENTATION;
@@ -192,7 +192,7 @@ function stringifyAny(
entries[i][1],
res,
prefix1 + `${stringifyKey(entries[i][0])}: `,
prefix2
prefix2,
);
}
} else {
@@ -204,7 +204,7 @@ function stringifyAny(
entries[i][1],
res,
prefix1 + `${stringifyKey(entries[i][0])}: `,
prefix2
prefix2,
);
}
}
+2 -2
View File
@@ -245,7 +245,7 @@ if (fsHostname) {
const FS_SSL = !!allConfig["FS_SSL_CERT"];
setConfig(
"FS_URL_PREFIX",
(FS_SSL ? "https" : "http") + `://${fsHostname}:${FS_PORT}/`
(FS_SSL ? "https" : "http") + `://${fsHostname}:${FS_PORT}/`,
);
}
@@ -255,7 +255,7 @@ for (const [k, v] of Object.entries(options))
export function get(
optionName: string,
deviceId?: string
deviceId?: string,
): string | number | boolean {
if (!deviceId) return allConfig[optionName];
+9 -10
View File
@@ -19,7 +19,6 @@
import * as crypto from "crypto";
import * as dgram from "dgram";
import { URL } from "url";
import * as http from "http";
import { evaluateAsync } from "./common/expression/util";
import { Expression } from "./types";
@@ -29,7 +28,7 @@ import * as debug from "./debug";
async function extractAuth(
exp: Expression,
dflt: any
dflt: any,
): Promise<[string, string, Expression]> {
let username, password;
const _exp = await evaluateAsync(
@@ -55,7 +54,7 @@ async function extractAuth(
}
}
return e;
}
},
);
return [username, password, _exp];
}
@@ -64,7 +63,7 @@ function httpGet(
url: URL,
options: http.RequestOptions,
_debug: boolean,
deviceId: string
deviceId: string,
): Promise<{ statusCode: number; headers: http.IncomingHttpHeaders }> {
return new Promise((resolve, reject) => {
const req = http
@@ -94,7 +93,7 @@ export async function httpConnectionRequest(
allowBasicAuth: boolean,
timeout: number,
_debug: boolean,
deviceId: string
deviceId: string,
): Promise<string> {
const url = new URL(address);
if (url.protocol !== "http:")
@@ -120,7 +119,7 @@ export async function httpConnectionRequest(
Authorization: auth.basic(username || "", password || ""),
},
},
options
options,
);
} else if (authHeader["method"] === "Digest") {
opts = Object.assign(
@@ -132,11 +131,11 @@ export async function httpConnectionRequest(
url.pathname + url.search,
"GET",
null,
authHeader
authHeader,
),
},
},
options
options,
);
} else {
return "Unrecognized auth method";
@@ -171,7 +170,7 @@ export async function httpConnectionRequest(
if (res.statusCode === 401 && res.headers["www-authenticate"]) {
try {
authHeader = auth.parseWwwAuthenticateHeader(
res.headers["www-authenticate"]
res.headers["www-authenticate"],
);
} catch (err) {
return "Connection request error: Error parsing www-authenticate header";
@@ -191,7 +190,7 @@ export async function udpConnectionRequest(
authExp: Expression,
sourcePort = 0,
_debug: boolean,
deviceId: string
deviceId: string,
): Promise<void> {
const now = Date.now();
+63 -64
View File
@@ -89,11 +89,11 @@ const stats = {
async function authenticate(
sessionContext: SessionContext,
body: string
body: string,
): Promise<boolean> {
const authExpression: Expression = localCache.getConfigExpression(
sessionContext.cacheSnapshot,
"cwmp.auth"
"cwmp.auth",
);
if (authExpression == null) return true;
@@ -102,7 +102,7 @@ async function authenticate(
if (sessionContext.httpRequest.headers["authorization"]) {
try {
authentication = auth.parseAuthorizationHeader(
sessionContext.httpRequest.headers["authorization"]
sessionContext.httpRequest.headers["authorization"],
);
} catch (err) {
return false;
@@ -159,7 +159,7 @@ async function authenticate(
authentication["qop"],
authentication["body"],
authentication["cnonce"],
authentication["nc"]
authentication["nc"],
);
return expected === authentication["response"];
}
@@ -168,7 +168,7 @@ async function authenticate(
}
}
return e;
}
},
);
if (res && !Array.isArray(res)) return true;
@@ -179,7 +179,7 @@ async function authenticate(
async function writeResponse(
sessionContext: SessionContext,
res,
close = false
close = false,
): Promise<void> {
// Close connection after last request in session
if (close) res.headers["Connection"] = "close";
@@ -231,7 +231,7 @@ async function writeResponse(
`cwmp_session_${sessionContext.deviceId}`,
sessionContext.timeout * 1000 + 15000,
0,
`cwmp_session_${sessionContext.sessionId}`
`cwmp_session_${sessionContext.sessionId}`,
);
if (!lockToken) throw new Error("Failed to extend lock");
}
@@ -242,14 +242,14 @@ function recordFault(
sessionContext: SessionContext,
fault: Fault,
provisions,
channels
channels,
): void;
function recordFault(sessionContext: SessionContext, fault: Fault): void;
function recordFault(
sessionContext: SessionContext,
fault: Fault,
provisions?,
channels?
channels?,
): void {
if (!provisions) {
provisions = sessionContext.provisions;
@@ -267,7 +267,7 @@ function recordFault(
: [];
faults[channel] = Object.assign(
{ provisions: provs, timestamp: sessionContext.timestamp },
fault
fault,
) as SessionFault;
if (channel.startsWith("task_")) {
const taskId = channel.slice(5);
@@ -314,11 +314,11 @@ function recordFault(
async function inform(
sessionContext: SessionContext,
rpc: SoapMessage
rpc: SoapMessage,
): Promise<{ code: number; headers: Record<string, string>; data: string }> {
const acsResponse = await session.inform(
sessionContext,
rpc.cpeRequest as InformRequest
rpc.cpeRequest as InformRequest,
);
const res = soap.response({
@@ -332,13 +332,12 @@ async function inform(
"cwmp.cookiesPath",
{},
sessionContext.timestamp,
(e) => session.configContextCallback(sessionContext, e)
(e) => session.configContextCallback(sessionContext, e),
);
if (cookiesPath) {
res.headers[
"Set-Cookie"
] = `session=${sessionContext.sessionId}; Path=${cookiesPath}`;
res.headers["Set-Cookie"] =
`session=${sessionContext.sessionId}; Path=${cookiesPath}`;
} else {
res.headers["Set-Cookie"] = `session=${sessionContext.sessionId}`;
}
@@ -349,7 +348,7 @@ async function inform(
async function transferComplete(sessionContext, rpc): Promise<void> {
const { acsResponse, operation, fault } = await session.transferComplete(
sessionContext,
rpc.cpeRequest
rpc.cpeRequest,
);
if (!operation) {
@@ -366,7 +365,7 @@ async function transferComplete(sessionContext, rpc): Promise<void> {
sessionContext,
fault,
operation.provisions,
operation.channels
operation.channels,
);
}
@@ -424,7 +423,7 @@ async function applyPresets(sessionContext: SessionContext): Promise<void> {
"cwmp.retryDelay",
{},
sessionContext.timestamp,
(e) => session.configContextCallback(sessionContext, e)
(e) => session.configContextCallback(sessionContext, e),
);
if (sessionContext.faults) {
@@ -452,7 +451,8 @@ async function applyPresets(sessionContext: SessionContext): Promise<void> {
const deviceEvents = {};
for (const p of deviceData.paths.find(Path.parse("Events.*"), false, true)) {
const attrs = deviceData.attributes.get(p);
if (attrs?.value && attrs.value[1][0] >= sessionContext.timestamp)
const t = attrs?.value[1][0] as number;
if (t >= sessionContext.timestamp)
deviceEvents[p.segments[1] as string] = true;
}
@@ -479,7 +479,7 @@ async function applyPresets(sessionContext: SessionContext): Promise<void> {
if (preset.schedule?.schedule) {
const r = scheduling.cron(
sessionContext.timestamp,
preset.schedule.schedule
preset.schedule.schedule,
);
if (!(r[0] + preset.schedule.duration > sessionContext.timestamp))
continue;
@@ -487,7 +487,7 @@ async function applyPresets(sessionContext: SessionContext): Promise<void> {
filteredPresets.push(preset);
for (const k of extractParams(
evaluate(preset.precondition, null, sessionContext.timestamp)
evaluate(preset.precondition, null, sessionContext.timestamp),
)) {
// Mark channel in case of fault during fetching precondition
sessionContext.channels[preset.channel] = 0;
@@ -496,7 +496,7 @@ async function applyPresets(sessionContext: SessionContext): Promise<void> {
for (const prov of preset.provisions) {
for (const arg of prov.slice(1)) {
for (const k of extractParams(
evaluate(arg, null, sessionContext.timestamp)
evaluate(arg, null, sessionContext.timestamp),
)) {
// Mark channel in case of fault during fetching precondition
sessionContext.channels[preset.channel] = 0;
@@ -538,7 +538,7 @@ async function applyPresets(sessionContext: SessionContext): Promise<void> {
for (const p of filteredPresets) {
if (
evaluate(p.precondition, {}, sessionContext.timestamp, (e) =>
session.configContextCallback(sessionContext, e)
session.configContextCallback(sessionContext, e),
)
) {
const provs = p.provisions.map((pp) => [
@@ -547,8 +547,8 @@ async function applyPresets(sessionContext: SessionContext): Promise<void> {
.slice(1)
.map((arg) =>
evaluate(arg, {}, sessionContext.timestamp, (e) =>
session.configContextCallback(sessionContext, e)
)
session.configContextCallback(sessionContext, e),
),
),
]) as [string, ...Expression[]][];
if (blackList[p.channel] === 2) {
@@ -562,7 +562,7 @@ async function applyPresets(sessionContext: SessionContext): Promise<void> {
}
for (const [channel, provisions] of Object.entries(
appendProvisionsToFaults
appendProvisionsToFaults,
)) {
if (
appendProvisions(sessionContext.faults[channel].provisions, provisions)
@@ -686,7 +686,7 @@ async function nextRpc(sessionContext: SessionContext): Promise<void> {
});
const task = sessionContext.tasks.find(
(t) => !sessionContext.faults[`task_${t._id}`]
(t) => !sessionContext.faults[`task_${t._id}`],
);
if (!task) return applyPresets(sessionContext);
@@ -747,7 +747,7 @@ async function nextRpc(sessionContext: SessionContext): Promise<void> {
session.addProvisions(
sessionContext,
`task_${task._id}`,
task.provisions
task.provisions,
);
break;
default:
@@ -784,8 +784,8 @@ async function endSession(sessionContext: SessionContext): Promise<void> {
sessionContext.deviceId,
sessionContext.deviceData,
sessionContext.new,
sessionContext.timestamp
)
sessionContext.timestamp,
),
);
if (sessionContext.operationsTouched) {
@@ -795,8 +795,8 @@ async function endSession(sessionContext: SessionContext): Promise<void> {
saveOperation(
sessionContext.deviceId,
k,
sessionContext.operations[k]
)
sessionContext.operations[k],
),
);
} else {
promises.push(deleteOperation(sessionContext.deviceId, k));
@@ -806,7 +806,7 @@ async function endSession(sessionContext: SessionContext): Promise<void> {
if (sessionContext.doneTasks?.length) {
promises.push(
clearTasks(sessionContext.deviceId, sessionContext.doneTasks)
clearTasks(sessionContext.deviceId, sessionContext.doneTasks),
);
}
@@ -815,7 +815,7 @@ async function endSession(sessionContext: SessionContext): Promise<void> {
if (sessionContext.faults[k]) {
sessionContext.faults[k].retries = sessionContext.retries[k];
promises.push(
saveFault(sessionContext.deviceId, k, sessionContext.faults[k])
saveFault(sessionContext.deviceId, k, sessionContext.faults[k]),
);
} else {
promises.push(deleteFault(sessionContext.deviceId, k));
@@ -826,7 +826,7 @@ async function endSession(sessionContext: SessionContext): Promise<void> {
await Promise.all(promises);
await lock.releaseLock(
`cwmp_session_${sessionContext.deviceId}`,
`cwmp_session_${sessionContext.sessionId}`
`cwmp_session_${sessionContext.sessionId}`,
);
if (sessionContext.new) {
logger.accessInfo({
@@ -839,7 +839,7 @@ async function endSession(sessionContext: SessionContext): Promise<void> {
async function sendAcsRequest(
sessionContext: SessionContext,
id?: string,
acsRequest?: AcsRequest
acsRequest?: AcsRequest,
): Promise<void> {
if (!acsRequest)
return writeResponse(sessionContext, soap.response(null), true);
@@ -918,7 +918,7 @@ export async function onConnection(socket: Socket): Promise<void> {
await cache.set(
`session_${sessionContext.sessionId}`,
await session.serialize(sessionContext),
Math.ceil(timeout / 1000) + 3
Math.ceil(timeout / 1000) + 3,
);
await setTimeoutPromise(timeout + 1000, false);
@@ -946,7 +946,7 @@ export async function onClientError(err: Error, socket: Socket): Promise<void> {
if (Array.isArray(e) && e[0] === "FUNC" && e[1] === "REMOTE_ADDRESS")
return remoteAddress;
return e;
}
},
);
if (debugEnabled) debug.clientError(remoteAddress, err);
@@ -985,7 +985,7 @@ async function reportBadState(sessionContext: SessionContext): Promise<void> {
async function responseUnauthorized(
sessionContext: SessionContext,
close: boolean
close: boolean,
): Promise<void> {
const resHeaders = {};
if (close) {
@@ -1024,7 +1024,7 @@ async function processRequest(
sessionContext: SessionContext,
rpc: SoapMessage,
parseWarnings: Record<string, unknown>[],
body: string
body: string,
): Promise<void> {
for (const w of parseWarnings) {
w.sessionContext = sessionContext;
@@ -1042,7 +1042,7 @@ async function processRequest(
"cwmp.debug",
{},
sessionContext.timestamp,
(e) => session.configContextCallback(sessionContext, e)
(e) => session.configContextCallback(sessionContext, e),
);
if (!sessionContext.timeout) {
@@ -1051,7 +1051,7 @@ async function processRequest(
"cwmp.sessionTimeout",
{},
sessionContext.timestamp,
(e) => session.configContextCallback(sessionContext, e)
(e) => session.configContextCallback(sessionContext, e),
);
}
@@ -1061,7 +1061,7 @@ async function processRequest(
debug.incomingHttpRequest(
sessionContext.httpRequest,
sessionContext.deviceId,
body
body,
);
}
@@ -1080,7 +1080,7 @@ async function processRequest(
`cwmp_session_${sessionContext.deviceId}`,
sessionContext.timeout * 1000 + 15000,
0,
`cwmp_session_${sessionContext.sessionId}`
`cwmp_session_${sessionContext.sessionId}`,
);
if (!lockToken) {
@@ -1092,14 +1092,14 @@ async function processRequest(
const _body = "CPE already in session";
sessionContext.httpResponse.setHeader(
"Content-Length",
Buffer.byteLength(_body)
Buffer.byteLength(_body),
);
sessionContext.httpResponse.writeHead(400, { Connection: "close" });
if (sessionContext.debug) {
debug.outgoingHttpResponse(
sessionContext.httpResponse,
sessionContext.deviceId,
_body
_body,
);
}
sessionContext.httpResponse.end(_body);
@@ -1122,7 +1122,7 @@ async function processRequest(
debug.incomingHttpRequest(
sessionContext.httpRequest,
sessionContext.deviceId,
body
body,
);
}
@@ -1180,7 +1180,7 @@ async function processRequest(
const fault = await session.rpcResponse(
sessionContext,
rpc.id,
rpc.cpeResponse
rpc.cpeResponse,
);
if (fault) {
recordFault(sessionContext, fault);
@@ -1242,9 +1242,8 @@ async function processRequest(
if (sessionContext.state !== 1) return reportBadState(sessionContext);
sessionContext.state = 2;
const { faults, operations } = await session.timeoutOperations(
sessionContext
);
const { faults, operations } =
await session.timeoutOperations(sessionContext);
for (const [i, f] of faults.entries()) {
for (const [k, v] of Object.entries(operations[i].retries))
@@ -1254,7 +1253,7 @@ async function processRequest(
sessionContext,
f,
operations[i].provisions,
operations[i].channels
operations[i].channels,
);
}
@@ -1264,7 +1263,7 @@ async function processRequest(
export async function listener(
httpRequest: IncomingMessage,
httpResponse: ServerResponse
httpResponse: ServerResponse,
): Promise<void> {
stats.concurrentRequests += 1;
try {
@@ -1282,7 +1281,7 @@ async function clientError(
httpResponse: ServerResponse,
sessionContext: SessionContext,
body: string,
msg: string
msg: string,
): Promise<void> {
let debugEnabled = false;
let deviceId: string = null;
@@ -1303,7 +1302,7 @@ async function clientError(
if (Array.isArray(e) && e[0] === "FUNC" && e[1] === "REMOTE_ADDRESS")
return getRequestOrigin(httpRequest).remoteAddress;
return e;
}
},
);
}
@@ -1330,7 +1329,7 @@ function decodeString(buffer: Buffer, charset: string): string {
async function listenerAsync(
httpRequest: IncomingMessage,
httpResponse: ServerResponse
httpResponse: ServerResponse,
): Promise<void> {
stats.totalRequests += 1;
@@ -1419,7 +1418,7 @@ async function listenerAsync(
httpResponse,
sessionContext,
body.toString(),
"Invalid session"
"Invalid session",
);
}
}
@@ -1427,7 +1426,7 @@ async function listenerAsync(
let charset: string;
if (httpRequest.headers["content-type"]) {
const m = httpRequest.headers["content-type"].match(
/charset=['"]?([^'"\s]+)/i
/charset=['"]?([^'"\s]+)/i,
);
if (m) charset = m[1].toLowerCase();
}
@@ -1465,7 +1464,7 @@ async function listenerAsync(
httpResponse,
sessionContext,
body.toString(),
msg
msg,
);
}
@@ -1498,7 +1497,7 @@ async function listenerAsync(
httpResponse,
sessionContext,
bodyStr,
err.message
err.message,
);
}
@@ -1531,7 +1530,7 @@ async function listenerAsync(
httpResponse,
null,
bodyStr,
"Invalid session"
"Invalid session",
);
}
@@ -1552,7 +1551,7 @@ async function listenerAsync(
const _sessionContext = session.init(
deviceId,
rpc.cwmpVersion,
rpc.sessionTimeout
rpc.sessionTimeout,
);
_sessionContext.cacheSnapshot = cacheSnapshot;
@@ -1584,7 +1583,7 @@ async function listenerAsync(
const parameters = await fetchDevice(
_sessionContext.deviceId,
_sessionContext.timestamp
_sessionContext.timestamp,
);
if (parameters) {
+20 -17
View File
@@ -22,7 +22,7 @@ function compareAccessLists(list1: string[], list2: string[]): boolean {
export async function fetchDevice(
id: string,
timestamp: number
timestamp: number,
): Promise<[Path, number, Attributes?][]> {
const res: [Path, number, Attributes?][] = [
[
@@ -44,7 +44,7 @@ export async function fetchDevice(
obj,
path: string,
pathLength: number,
ts: number
ts: number,
): void {
if (obj["_timestamp"]) obj["_timestamp"] = +obj["_timestamp"];
if (obj["_attributesTimestamp"])
@@ -243,7 +243,7 @@ export async function saveDevice(
deviceId: string,
deviceData: DeviceData,
isNew: boolean,
sessionTimestamp: number
sessionTimestamp: number,
): Promise<void> {
const update = { $set: {}, $unset: {}, $addToSet: {}, $pull: {} };
@@ -357,7 +357,7 @@ export async function saveDevice(
if (!update["$addToSet"]["_tags"])
update["$addToSet"]["_tags"] = { $each: [] };
update["$addToSet"]["_tags"]["$each"].push(
decodeTag(path.segments[1] as string)
decodeTag(path.segments[1] as string),
);
} else {
if (!update["$pull"]["_tags"]) {
@@ -366,7 +366,7 @@ export async function saveDevice(
};
}
update["$pull"]["_tags"]["$in"].push(
decodeTag(path.segments[1] as string)
decodeTag(path.segments[1] as string),
);
}
}
@@ -379,7 +379,10 @@ export async function saveDevice(
if (pathStr.endsWith(INVALID_PATH_SUFFIX)) {
const splits = pathStr.split(".");
splits[splits.length - 1] = decodeTag(
splits[splits.length - 1].slice(0, 0 - INVALID_PATH_SUFFIX.length)
splits[splits.length - 1].slice(
0,
0 - INVALID_PATH_SUFFIX.length,
),
);
pathStr = splits.join(".");
}
@@ -401,7 +404,7 @@ export async function saveDevice(
Number.isInteger(value2 as number)
) {
update["$set"][path.toString() + "._value"] = new Date(
value2 as number
value2 as number,
);
} else {
update["$set"][path.toString() + "._value"] = value2;
@@ -413,7 +416,7 @@ export async function saveDevice(
if (valueTimestamp2 !== valueTimestamp1) {
update["$set"][path.toString() + "._timestamp"] = new Date(
valueTimestamp2
valueTimestamp2,
);
}
@@ -533,7 +536,7 @@ export async function saveDevice(
update,
{
upsert: isNew,
}
},
);
if (!result.matchedCount && !result.upsertedCount)
@@ -546,7 +549,7 @@ export async function saveDevice(
}
export async function getFaults(
deviceId: string
deviceId: string,
): Promise<{ [channel: string]: SessionFault }> {
const res = await collections.faults
.find({ _id: { $regex: `^${escapeRegExp(deviceId)}\\:` } })
@@ -573,7 +576,7 @@ export async function getFaults(
export async function saveFault(
deviceId: string,
channel: string,
fault: SessionFault
fault: SessionFault,
): Promise<void> {
const id = `${deviceId}:${channel}`;
const f: MongoTypes.Fault = {
@@ -593,14 +596,14 @@ export async function saveFault(
export async function deleteFault(
deviceId: string,
channel: string
channel: string,
): Promise<void> {
await collections.faults.deleteOne({ _id: `${deviceId}:${channel}` });
}
export async function getDueTasks(
deviceId: string,
timestamp: number
timestamp: number,
): Promise<[Task[], number]> {
const cur = collections.tasks
.find({ device: deviceId })
@@ -664,7 +667,7 @@ export async function getDueTasks(
export async function clearTasks(
deviceId: string,
taskIds: string[]
taskIds: string[],
): Promise<void> {
await collections.tasks.deleteMany({
_id: { $in: taskIds.map((id) => new ObjectId(id)) },
@@ -672,7 +675,7 @@ export async function clearTasks(
}
export async function getOperations(
deviceId: string
deviceId: string,
): Promise<{ [commandKey: string]: Operation }> {
const res = await collections.operations
.find({ _id: { $regex: `^${escapeRegExp(deviceId)}\\:` } })
@@ -704,7 +707,7 @@ export async function getOperations(
export async function saveOperation(
deviceId: string,
commandKey: string,
operation: Operation
operation: Operation,
): Promise<void> {
const id = `${deviceId}:${commandKey}`;
const o: MongoTypes.Operation = {
@@ -723,7 +726,7 @@ export async function saveOperation(
export async function deleteOperation(
deviceId: string,
commandKey: string
commandKey: string,
): Promise<void> {
await collections.operations.deleteOne({ _id: `${deviceId}:${commandKey}` });
}
+7 -7
View File
@@ -28,7 +28,7 @@ interface Snapshot {
function flattenObject<T extends Record<keyof T, unknown>>(
src: T,
prefix = "",
dst = {} as T
dst = {} as T,
): T {
for (const k of Object.keys(src)) {
const v = src[k];
@@ -99,7 +99,7 @@ async function fetchPresets(): Promise<[string, Preset[]]> {
precondition = parse(preset["precondition"]);
} catch (error) {
precondition = convertOldPrecondition(
JSON.parse(preset["precondition"])
JSON.parse(preset["precondition"]),
);
}
@@ -166,7 +166,7 @@ async function fetchPresets(): Promise<[string, Preset[]]> {
default: {
const exhaustiveCheck: never = c;
throw new Error(
`Unknown configuration type ${exhaustiveCheck["type"]}`
`Unknown configuration type ${exhaustiveCheck["type"]}`,
);
}
}
@@ -199,7 +199,7 @@ async function fetchProvisions(): Promise<[string, Provisions]> {
.digest("hex");
provisions[r._id].script = new vm.Script(
`"use strict";(function(){\n${r.script}\n})();`,
{ filename: r._id, lineOffset: -1 }
{ filename: r._id, lineOffset: -1 },
);
}
@@ -220,7 +220,7 @@ async function fetchVirtualParameters(): Promise<[string, VirtualParameters]> {
.digest("hex");
virtualParameters[r._id].script = new vm.Script(
`"use strict";(function(){\n${r.script}\n})();`,
{ filename: r._id, lineOffset: -1 }
{ filename: r._id, lineOffset: -1 },
);
}
@@ -307,7 +307,7 @@ export function getConfig(
key: string,
context: Record<string, unknown>,
now: number,
cb?: (e: Expression) => Expression
cb?: (e: Expression) => Expression,
): string | number | boolean | null {
const snapshot = localCache.get(snapshotKey);
if (!snapshot) throw new Error("Cache snapshot does not exist");
@@ -350,7 +350,7 @@ export function getConfig(
export function getConfigExpression(
snapshotKey: string,
key: string
key: string,
): Expression {
const snapshot = localCache.get(snapshotKey);
return snapshot.config[key];
+25 -22
View File
@@ -131,7 +131,7 @@ function roundOid(oid: string, roundUp: boolean): string {
function groupBy<T, K>(
input: T[],
callback: (item: T) => K
callback: (item: T) => K,
): Iterable<[K, T[]]> {
const groups = new Map<K, T[]>();
for (const item of input) {
@@ -155,7 +155,7 @@ abstract class MongoClause {
class MongoClauseArray extends MongoClause {
constructor(
public readonly parameter: string,
public readonly value: string
public readonly value: string,
) {
super();
}
@@ -171,7 +171,7 @@ class MongoClauseCompare<T> extends MongoClause {
public readonly parameter: string,
public readonly op: "$eq" | "$gt" | "$lt" | "$gte" | "$lte",
public readonly value: T,
public readonly type: "" | "bool" | "number" | "string" | "date" | "oid"
public readonly type: "" | "bool" | "number" | "string" | "date" | "oid",
) {
super();
}
@@ -189,7 +189,10 @@ class MongoClauseCompare<T> extends MongoClause {
}
class MongoClauseType extends MongoClause {
constructor(public readonly parameter: string, public readonly type: string) {
constructor(
public readonly parameter: string,
public readonly type: string,
) {
super();
}
@@ -205,7 +208,7 @@ class MongoClauseLike extends MongoClause {
public readonly parameter: string,
pat: string,
esc: string,
public readonly caseSensitive: boolean
public readonly caseSensitive: boolean,
) {
super();
this.pattern = parseLikePattern(pat, esc);
@@ -357,8 +360,8 @@ class MongoSynthContext extends SynthContextBase<Clause, MongoClause> {
param,
"$gte",
"000000000000000000000000",
"oid"
)
"oid",
),
);
}
}
@@ -417,30 +420,30 @@ class MongoSynthContext extends SynthContextBase<Clause, MongoClause> {
for (const [parameter, clauses2] of groupBy(clauses, (c) => c.parameter)) {
const comparisons = clauses2.filter(
(c) => c instanceof MongoClauseCompare && c.value !== null
(c) => c instanceof MongoClauseCompare && c.value !== null,
) as MongoClauseCompare<unknown>[];
for (const [type, clauses3] of groupBy(comparisons, (c) => c.type)) {
const isType = this.getVar(new MongoClauseType(parameter, type));
const values = new Set(clauses3.map((c) => c.value));
const valuesSorted = Array.from(values).sort((a, b) =>
a > b ? 1 : -1
a > b ? 1 : -1,
);
for (const [i, v] of valuesSorted.entries()) {
const eq = this.getVar(
new MongoClauseCompare(parameter, "$eq", v, type)
new MongoClauseCompare(parameter, "$eq", v, type),
);
const gt = this.getVar(
new MongoClauseCompare(parameter, "$gt", v, type)
new MongoClauseCompare(parameter, "$gt", v, type),
);
const lt = this.getVar(
new MongoClauseCompare(parameter, "$lt", v, type)
new MongoClauseCompare(parameter, "$lt", v, type),
);
const gte = this.getVar(
new MongoClauseCompare(parameter, "$gte", v, type)
new MongoClauseCompare(parameter, "$gte", v, type),
);
const lte = this.getVar(
new MongoClauseCompare(parameter, "$lte", v, type)
new MongoClauseCompare(parameter, "$lte", v, type),
);
if (type === "bool") {
@@ -472,16 +475,16 @@ class MongoSynthContext extends SynthContextBase<Clause, MongoClause> {
parameter,
"$gt",
valuesSorted[i - 1],
type
)
type,
),
);
const lte2 = this.getVar(
new MongoClauseCompare(
parameter,
"$lte",
valuesSorted[i - 1],
type
)
type,
),
);
dcSet.push([(gt2 << 1) ^ 0, (gte << 1) ^ 1]);
dcSet.push([(gt2 << 1) ^ 0, (lte2 << 1) ^ 0, (lt << 1) ^ 1]);
@@ -493,7 +496,7 @@ class MongoSynthContext extends SynthContextBase<Clause, MongoClause> {
}
const likes = clauses2.filter(
(c) => c instanceof MongoClauseLike
(c) => c instanceof MongoClauseLike,
) as MongoClauseLike[];
if (likes.length) {
const isType = this.getVar(new MongoClauseType(parameter, "string"));
@@ -535,11 +538,11 @@ class MongoSynthContext extends SynthContextBase<Clause, MongoClause> {
}
const isNull = this.getVar(
new MongoClauseCompare(parameter, "$eq", null, "")
new MongoClauseCompare(parameter, "$eq", null, ""),
);
const types = getTypes(parameter, this.collection).map((t) =>
this.getVar(new MongoClauseType(parameter, t))
this.getVar(new MongoClauseType(parameter, t)),
);
dcSet.push([(isNull << 1) ^ 0, ...types.map((t) => (t << 1) ^ 0)]);
@@ -621,7 +624,7 @@ class MongoSynthContext extends SynthContextBase<Clause, MongoClause> {
export function toMongoQuery(
exp: Expression,
resource: string
resource: string,
): Filter<unknown> | false {
exp = normalize(exp);
const clause = Clause.fromExpression(normalize(exp));
+6 -6
View File
@@ -41,7 +41,7 @@ function getConnectionTimestamp(connection: Socket): Date {
export function incomingHttpRequest(
httpRequest: IncomingMessage,
deviceId: string,
body: string
body: string,
): void {
if (!DEBUG_FILE) return;
const now = new Date();
@@ -70,7 +70,7 @@ export function incomingHttpRequest(
export function outgoingHttpResponse(
httpResponse: ServerResponse,
deviceId: string,
body: string
body: string,
): void {
if (!DEBUG_FILE) return;
const now = new Date();
@@ -99,7 +99,7 @@ export function outgoingHttpRequest(
deviceId: string,
method: "GET" | "PUT" | "POST" | "DELETE",
url: URL,
body: string
body: string,
): void {
if (!DEBUG_FILE) return;
const now = new Date();
@@ -129,7 +129,7 @@ export function outgoingHttpRequestError(
deviceId: string,
method: "GET" | "PUT" | "POST" | "DELETE",
url: URL,
err: Error
err: Error,
): void {
if (!DEBUG_FILE) return;
const now = new Date();
@@ -156,7 +156,7 @@ export function outgoingHttpRequestError(
export function incomingHttpResponse(
httpResponse: IncomingMessage,
deviceId: string,
body: string
body: string,
): void {
if (!DEBUG_FILE) return;
const now = new Date();
@@ -183,7 +183,7 @@ export function outgoingUdpMessage(
remoteAddress: string,
deviceId: string,
remotePort: number,
body: string
body: string,
): void {
if (!DEBUG_FILE) return;
const now = new Date();
+8 -8
View File
@@ -28,7 +28,7 @@ const MAX_DEPTH = +config.get("MAX_DEPTH");
export function refresh(
sessionContext: SessionContext,
provision: (string | number | boolean)[],
declarations: Declaration[]
declarations: Declaration[],
): boolean {
if (
(provision.length !== 2 || typeof provision[1] !== "string") &&
@@ -84,7 +84,7 @@ export function refresh(
export function value(
sessionContext: SessionContext,
provision: (string | number | boolean)[],
declarations: Declaration[]
declarations: Declaration[],
): boolean {
if (
provision.length < 3 ||
@@ -127,7 +127,7 @@ export function value(
export function tag(
sessionContext: SessionContext,
provision: (string | number | boolean)[],
declarations: Declaration[]
declarations: Declaration[],
): boolean {
if (
provision.length !== 3 ||
@@ -151,7 +151,7 @@ export function tag(
export function reboot(
sessionContext: SessionContext,
provision: (string | number | boolean)[],
declarations: Declaration[]
declarations: Declaration[],
): boolean {
if (provision.length !== 1) throw new Error("Invalid arguments");
@@ -170,7 +170,7 @@ export function reboot(
export function reset(
sessionContext: SessionContext,
provision: (string | number | boolean)[],
declarations: Declaration[]
declarations: Declaration[],
): boolean {
if (provision.length !== 1) throw new Error("Invalid arguments");
@@ -189,7 +189,7 @@ export function reset(
export function download(
sessionContext: SessionContext,
provision: (string | number | boolean)[],
declarations: Declaration[]
declarations: Declaration[],
): boolean {
if (
(provision.length !== 3 ||
@@ -234,7 +234,7 @@ export function instances(
provision: (string | number | boolean)[],
declarations: Declaration[],
startRevision: number,
endRevision: number
endRevision: number,
): boolean {
if (provision.length !== 3 || typeof provision[1] !== "string")
throw new Error("Invalid arguments");
@@ -260,7 +260,7 @@ export function instances(
const unpacked = device.unpack(
sessionContext.deviceData,
path,
startRevision + 1
startRevision + 1,
);
count = Math.max(0, unpacked.length + count);
}
+11 -11
View File
@@ -43,7 +43,7 @@ function parseBool(v): boolean {
}
export function sanitizeParameterValue(
parameterValue: [string | number | boolean, string]
parameterValue: [string | number | boolean, string],
): [string | number | boolean, string] {
if (parameterValue[0] != null) {
switch (parameterValue[1]) {
@@ -87,7 +87,7 @@ export function sanitizeParameterValue(
export function getAliasDeclarations(
path: Path,
timestamp: number,
attrGet = null
attrGet = null,
): Declaration[] {
const stripped = path.stripAlias();
let decs: Declaration[] = [
@@ -109,7 +109,7 @@ export function getAliasDeclarations(
decs = decs.concat(
getAliasDeclarations(parent.concat(p), timestamp, {
value: timestamp,
})
}),
);
}
}
@@ -122,7 +122,7 @@ export function getAliasDeclarations(
export function unpack(
deviceData: DeviceData,
path: Path,
revision?: number
revision?: number,
): Path[] {
let allMatches = [] as Path[];
if (!path.alias) {
@@ -194,7 +194,7 @@ export function clear(
path: Path,
timestamp: number,
attributes: AttributeTimestamps,
changeFlags = 0
changeFlags = 0,
): void {
const changeTrackers = {};
@@ -212,7 +212,7 @@ export function clear(
path,
true,
true,
descendantsTimestamp ? 99 : path.length
descendantsTimestamp ? 99 : path.length,
)) {
const tracker = deviceData.trackers.get(p);
for (const k in tracker) changeTrackers[k] |= tracker[k];
@@ -274,7 +274,7 @@ export function set(
path: Path,
timestamp: number,
attributes: Attributes,
toClear?: Clear[]
toClear?: Clear[],
): Clear[] {
path = deviceData.paths.add(path);
@@ -315,7 +315,7 @@ export function set(
else if (
!compareEquality(
attributes[attrName][1],
currentAttributes[attrName][1]
currentAttributes[attrName][1],
)
)
changeFlags |= CHANGE_FLAGS[attrName];
@@ -334,7 +334,7 @@ export function set(
path.slice(0, path.length - 1),
timestamp,
{ object: [timestamp, 1] },
toClear
toClear,
);
}
}
@@ -377,7 +377,7 @@ export function track(
deviceData: DeviceData,
path: Path,
marker: string,
attributes?: string[]
attributes?: string[],
): void {
path = deviceData.paths.add(path);
let f = 1;
@@ -396,7 +396,7 @@ export function track(
export function clearTrackers(
deviceData: DeviceData,
tracker: string | string[]
tracker: string | string[],
): void {
if (Array.isArray(tracker)) {
for (const v of deviceData.trackers.values())
+1 -1
View File
@@ -123,6 +123,6 @@ export async function killAll(): Promise<void> {
Object.entries(processes).map(([k, p]) => {
delete processes[k];
return kill(p);
})
}),
);
}
+5 -5
View File
@@ -30,7 +30,7 @@ const getFile = memoize(
async (
etag: string,
size: number,
filename: string
filename: string,
): Promise<Iterable<Buffer>> => {
const chunks: Buffer[] = [];
// Using for-await over the download stream can throw ERR_STREAM_PREMATURE_CLOSE
@@ -41,7 +41,7 @@ const getFile = memoize(
new PassThrough(),
(err) => {
if (err) throw err;
}
},
);
for await (const chunk of downloadStream) chunks.push(chunk);
// Node 12-14 don't throw error when stream is closed prematurely.
@@ -49,13 +49,13 @@ const getFile = memoize(
if (size !== chunks.reduce((a, b) => a + b.length, 0))
throw new Error("File size mismatch");
return chunks;
}
},
);
async function* partialContent(
chunks: Iterable<Buffer>,
start: number,
end: number
end: number,
): AsyncIterable<Buffer> {
let bytesToSkip = start;
let bytesToRead = end - start;
@@ -100,7 +100,7 @@ function matchEtag(etag: string, header: string): boolean {
export async function listener(
request: IncomingMessage,
response: ServerResponse
response: ServerResponse,
): Promise<void> {
if (request.method !== "GET" && request.method !== "HEAD") {
response.writeHead(405, { Allow: "GET, HEAD" });
+1 -1
View File
@@ -31,7 +31,7 @@ const UNDISCOVERED_DEPTH = 7;
// point has been discovered.
export function estimateGpnCount(
gpnPatterns: [Path, number][],
depth = 0
depth = 0,
): number {
const children: { [segment: string]: [Path, number][] } = {};
const wildcardChildren: [Path, number][] = [];
+1 -1
View File
@@ -31,7 +31,7 @@ export class LocalCache<T> {
constructor(
private cacheKey: string,
private callback: () => Promise<[string, T]>
private callback: () => Promise<[string, T]>,
) {}
async getRevision(): Promise<string> {
+3 -3
View File
@@ -6,7 +6,7 @@ export async function acquireLock(
lockName: string,
ttl: number,
timeout = 0,
token = Math.random().toString(36).slice(2)
token = Math.random().toString(36).slice(2),
): Promise<string> {
try {
const now = Date.now();
@@ -18,7 +18,7 @@ export async function acquireLock(
},
$currentDate: { timestamp: true },
},
{ upsert: true, returnDocument: "after" }
{ upsert: true, returnDocument: "after" },
);
if (Math.abs(r.value.timestamp.getTime() - now) > CLOCK_SKEW_TOLERANCE)
throw new Error("Database clock skew too great");
@@ -35,7 +35,7 @@ export async function acquireLock(
export async function releaseLock(
lockName: string,
token: string
token: string,
): Promise<void> {
const res = await collections.locks.deleteOne({
_id: lockName,
+5 -5
View File
@@ -156,13 +156,13 @@ export function close(): void {
}
export function flatten(
details: Record<string, unknown>
details: Record<string, unknown>,
): Record<string, unknown> {
if (details.sessionContext) {
const sessionContext = details.sessionContext as SessionContext;
details.deviceId = sessionContext.deviceId;
details.remoteAddress = getRequestOrigin(
sessionContext.httpRequest
sessionContext.httpRequest,
).remoteAddress;
delete details.sessionContext;
}
@@ -220,7 +220,7 @@ export function flatten(
// For genieacs-ui
if (details.context) {
details.remoteAddress = getRequestOrigin(
details.context["req"]
details.context["req"],
).remoteAddress;
if (details.context["state"].user)
details.user = details.context["state"].user.username;
@@ -235,7 +235,7 @@ export function flatten(
function formatJson(
details: Record<string, unknown>,
systemd: boolean
systemd: boolean,
): string {
if (systemd) {
let severity = "";
@@ -251,7 +251,7 @@ function formatJson(
function formatSimple(
details: Record<string, unknown>,
systemd: boolean
systemd: boolean,
): string {
const skip = {
user: true,
+18 -18
View File
@@ -65,14 +65,14 @@ async function getBody(request: IncomingMessage): Promise<Buffer> {
export async function listener(
request: IncomingMessage,
response: ServerResponse
response: ServerResponse,
): Promise<void> {
response.setHeader("GenieACS-Version", VERSION);
const origin = getRequestOrigin(request);
const url = new URL(
request.url,
(origin.encrypted ? "https://" : "http://") + origin.host
(origin.encrypted ? "https://" : "http://") + origin.host,
);
const body = await getBody(request).catch(() => null);
@@ -83,7 +83,7 @@ export async function listener(
Object.assign({}, Object.fromEntries(url.searchParams), {
remoteAddress: origin.remoteAddress,
message: `${request.method} ${url.pathname}`,
})
}),
);
return handler(request, response, url, body);
}
@@ -92,7 +92,7 @@ async function handler(
request: IncomingMessage,
response: ServerResponse,
url: URL,
body: Buffer
body: Buffer,
): Promise<void> {
if (PRESETS_REGEX.test(url.pathname)) {
const presetName = decodeURIComponent(PRESETS_REGEX.exec(url.pathname)[1]);
@@ -150,7 +150,7 @@ async function handler(
}
} else if (PROVISIONS_REGEX.test(url.pathname)) {
const provisionName = decodeURIComponent(
PROVISIONS_REGEX.exec(url.pathname)[1]
PROVISIONS_REGEX.exec(url.pathname)[1],
);
if (request.method === "PUT") {
const object = {
@@ -183,7 +183,7 @@ async function handler(
}
} else if (VIRTUAL_PARAMETERS_REGEX.test(url.pathname)) {
const virtualParameterName = decodeURIComponent(
VIRTUAL_PARAMETERS_REGEX.exec(url.pathname)[1]
VIRTUAL_PARAMETERS_REGEX.exec(url.pathname)[1],
);
if (request.method === "PUT") {
const object = {
@@ -202,7 +202,7 @@ async function handler(
await collections.virtualParameters.replaceOne(
{ _id: virtualParameterName },
object,
{ upsert: true }
{ upsert: true },
);
await cache.del("cwmp-local-cache-hash");
response.writeHead(200);
@@ -225,7 +225,7 @@ async function handler(
if (request.method === "POST") {
const updateRes = await collections.devices.updateOne(
{ _id: deviceId },
{ $addToSet: { _tags: tag } }
{ $addToSet: { _tags: tag } },
);
if (!updateRes.matchedCount) {
@@ -239,7 +239,7 @@ async function handler(
} else if (request.method === "DELETE") {
const updateRes = await collections.devices.updateOne(
{ _id: deviceId },
{ $pull: { _tags: tag } }
{ $pull: { _tags: tag } },
);
if (!updateRes.matchedCount) {
@@ -277,7 +277,7 @@ async function handler(
} else if (DEVICE_TASKS_REGEX.test(url.pathname)) {
if (request.method === "POST") {
const deviceId = decodeURIComponent(
DEVICE_TASKS_REGEX.exec(url.pathname)[1]
DEVICE_TASKS_REGEX.exec(url.pathname)[1],
);
const conReq = url.searchParams.has("connection_request");
@@ -314,7 +314,7 @@ async function handler(
} else {
const status = await apiFunctions.connectionRequest(
deviceId,
flattenDevice(dev)
flattenDevice(dev),
);
if (status) {
response.writeHead(504, status);
@@ -394,7 +394,7 @@ async function handler(
}
}
return exp;
}
},
) as number;
}
@@ -403,14 +403,14 @@ async function handler(
const sessionStarted = await apiFunctions.awaitSessionStart(
deviceId,
lastInform,
onlineThreshold
onlineThreshold,
);
if (!sessionStarted) {
status = "Task queued but not processed";
} else {
const sessionEnded = await apiFunctions.awaitSessionEnd(
deviceId,
120000
120000,
);
if (!sessionEnded) {
status = "Task queued but not processed";
@@ -445,7 +445,7 @@ async function handler(
if (request.method === "DELETE") {
const task = await collections.tasks.findOne(
{ _id: new ObjectId(taskId) },
{ projection: { device: 1 } }
{ projection: { device: 1 } },
);
if (!task) {
@@ -481,7 +481,7 @@ async function handler(
if (request.method === "POST") {
const task = await collections.tasks.findOne(
{ _id: new ObjectId(taskId) },
{ projection: { device: 1 } }
{ projection: { device: 1 } },
);
const deviceId = task.device;
@@ -530,7 +530,7 @@ async function handler(
filename,
{
metadata: metadata,
}
},
);
uploadStream.on("error", reject);
@@ -589,7 +589,7 @@ async function handler(
}
const deviceId = decodeURIComponent(
DELETE_DEVICE_REGEX.exec(url.pathname)[1]
DELETE_DEVICE_REGEX.exec(url.pathname)[1],
);
try {
+1 -1
View File
@@ -88,7 +88,7 @@ export function parsePing(osPlatform: string, stdout: string): PingResult {
export function ping(
host: string,
callback: (err: Error, res?: PingResult, stdout?: string) => void
callback: (err: Error, res?: PingResult, stdout?: string) => void,
): void {
// Validate input to prevent possible remote code execution
// Credit to Alex Hordijk for reporting this vulnerability
+2 -2
View File
@@ -118,7 +118,7 @@ function permute(param, val): any[] {
}
export function expand(
query: Record<string, unknown>
query: Record<string, unknown>,
): Record<string, unknown> {
const newQuery = {};
for (const [k, v] of Object.entries(query)) {
@@ -147,7 +147,7 @@ export function expand(
export function sanitizeQueryTypes(
query: Record<string, unknown>,
types: Record<string, (v: unknown) => unknown>
types: Record<string, (v: unknown) => unknown>,
): Record<string, unknown> {
for (const [k, v] of Object.entries(query)) {
if (k[0] === "$") {
+14 -14
View File
@@ -62,7 +62,7 @@ function runExtension(sessionContext, key, extCall): Promise<Fault> {
resolve(fault);
})
.catch(reject);
}))
})),
);
}
@@ -78,7 +78,7 @@ class SandboxDate {
number?,
number?,
number?,
number?
number?,
]
) {
if (argumentList.length) return new Date(...argumentList);
@@ -143,7 +143,7 @@ class ParameterWrapper {
unpacked = device.unpack(
state.sessionContext.deviceData,
path,
state.revision
state.revision,
);
}
@@ -151,7 +151,7 @@ class ParameterWrapper {
const attr = state.sessionContext.deviceData.attributes.get(
unpacked[0],
state.revision
state.revision,
)[attrName];
if (!attr) return UNDEFINED;
@@ -170,7 +170,7 @@ class ParameterWrapper {
unpacked = device.unpack(
state.sessionContext.deviceData,
path,
state.revision
state.revision,
);
}
@@ -189,7 +189,7 @@ class ParameterWrapper {
unpacked = device.unpack(
state.sessionContext.deviceData,
path,
state.revision
state.revision,
);
}
@@ -207,7 +207,7 @@ class ParameterWrapper {
unpacked = device.unpack(
state.sessionContext.deviceData,
path,
state.revision
state.revision,
);
}
@@ -220,7 +220,7 @@ class ParameterWrapper {
function declare(
path: string,
timestamps: { [attr: string]: number },
values: { [attr: string]: any }
values: { [attr: string]: any },
): ParameterWrapper {
state.uncommitted = true;
if (!timestamps) timestamps = {};
@@ -286,7 +286,7 @@ function commit(): void {
throw COMMIT;
} else if (state.revision > state.maxRevision + 1) {
throw new Error(
"Declare function should not be called from within a try/catch block"
"Declare function should not be called from within a try/catch block",
);
}
}
@@ -351,12 +351,12 @@ function errorToFault(err: Error): Fault {
fault.detail["stack"] = err.stack;
// Trim the stack trace at the self-executing anonymous wrapper function
const stackTrimIndex = fault.detail["stack"].match(
/\s+at\s[^\s]+\s+at\s[^\s]+\s\(vm\.js.+\)/
/\s+at\s[^\s]+\s+at\s[^\s]+\s\(vm\.js.+\)/,
);
if (stackTrimIndex) {
fault.detail["stack"] = fault.detail["stack"].slice(
0,
stackTrimIndex.index
stackTrimIndex.index,
);
}
}
@@ -370,7 +370,7 @@ export async function run(
sessionContext: SessionContext,
startRevision: number,
maxRevision: number,
extCounter = 0
extCounter = 0,
): Promise<ScriptResult> {
state = {
sessionContext: sessionContext,
@@ -415,7 +415,7 @@ export async function run(
await Promise.all(
Object.entries(_state.extensions).map(async ([k, v]) => {
fault = (await runExtension(_state.sessionContext, k, v)) || fault;
})
}),
);
if (fault) {
@@ -435,7 +435,7 @@ export async function run(
sessionContext,
startRevision,
maxRevision,
extCounter - _state.extCounter
extCounter - _state.extCounter,
);
}
+2 -2
View File
@@ -37,7 +37,7 @@ export function variance(deviceId: string, vrnc: number): number {
export function interval(
timestamp: number,
intrvl: number,
offset = 0
offset = 0,
): number {
return Math.trunc((timestamp + offset) / intrvl) * intrvl - offset;
}
@@ -52,7 +52,7 @@ export function parseCron(cronExp: string): any {
export function cron(
timestamp: number,
schedule: unknown,
offset = 0
offset = 0,
): number[] {
// TODO later.js doesn't throw erorr if expression is invalid!
const ret = [0, 0];
+1 -1
View File
@@ -80,7 +80,7 @@ type Promisify<T extends (...args: any) => any> = (
export function start(
options: ServerOptions,
_listener: Promisify<http.RequestListener>
_listener: Promisify<http.RequestListener>,
): void {
listener = (req, res) => {
if (stopping) res.setHeader("Connection", "close");
+151 -148
View File
File diff suppressed because it is too large. Load diff
+18 -18
View File
@@ -158,7 +158,7 @@ const getValueType = memoize((str: string) => {
});
function parameterValueList(
xml: Element
xml: Element,
): [Path, string | number | boolean, string][] {
return xml.children
.map<[Path, string | number | boolean, string]>((e) => {
@@ -291,7 +291,7 @@ function GetParameterNamesResponse(xml): GetParameterNamesResponse {
return {
name: "GetParameterNamesResponse",
parameterList: parameterInfoList(
xml.children.find((n) => n.localName === "ParameterList")
xml.children.find((n) => n.localName === "ParameterList"),
),
};
}
@@ -308,7 +308,7 @@ function GetParameterValuesResponse(xml: Element): GetParameterValuesResponse {
return {
name: "GetParameterValuesResponse",
parameterList: parameterValueList(
xml.children.find((n) => n.localName === "ParameterList")
xml.children.find((n) => n.localName === "ParameterList"),
),
};
}
@@ -322,12 +322,12 @@ function GetParameterAttributes(methodRequest): string {
}
function GetParameterAttributesResponse(
xml: Element
xml: Element,
): GetParameterAttributesResponse {
return {
name: "GetParameterAttributesResponse",
parameterList: parameterAttributeList(
xml.children.find((n) => n.localName === "ParameterList")
xml.children.find((n) => n.localName === "ParameterList"),
),
};
}
@@ -509,19 +509,19 @@ function Download(methodRequest): string {
}</CommandKey><FileType>${methodRequest.fileType}</FileType><URL>${
methodRequest.url
}</URL><Username>${encodeEntities(
methodRequest.username || ""
methodRequest.username || "",
)}</Username><Password>${encodeEntities(
methodRequest.password || ""
methodRequest.password || "",
)}</Password><FileSize>${
methodRequest.fileSize || "0"
}</FileSize><TargetFileName>${encodeEntities(
methodRequest.targetFileName || ""
methodRequest.targetFileName || "",
)}</TargetFileName><DelaySeconds>${
methodRequest.delaySeconds || "0"
}</DelaySeconds><SuccessURL>${encodeEntities(
methodRequest.successUrl || ""
methodRequest.successUrl || "",
)}</SuccessURL><FailureURL>${encodeEntities(
methodRequest.failureUrl || ""
methodRequest.failureUrl || "",
)}</FailureURL></cwmp:Download>`;
}
@@ -732,13 +732,13 @@ function RequestDownloadResponse(): string {
function AcsFault(f: CpeFault): string {
return `<soap-env:Body:Fault><faultcode>${encodeEntities(
f.faultCode
f.faultCode,
)}</faultcode><faultstring>${encodeEntities(
f.faultString
f.faultString,
)}</faultstring><detail><cwmp:Fault><FaultCode>${encodeEntities(
f.detail.faultCode
f.detail.faultCode,
)}</FaultCode><FaultString>${encodeEntities(
f.detail.faultString
f.detail.faultString,
)}</FaultString></cwmp:Fault></detail></soap-env:Body:Fault>`;
}
@@ -839,7 +839,7 @@ function fault(xml: Element): CpeFault {
export function request(
body: string,
warn: Record<string, unknown>[]
warn: Record<string, unknown>[],
): SoapMessage {
warnings = warn;
@@ -897,7 +897,7 @@ export function request(
const attrs = memoizedParseAttrs(e.attrs);
const attr = namespace
? attrs.find(
(s) => s.namespace === "xmlns" && s.localName === namespace
(s) => s.namespace === "xmlns" && s.localName === namespace,
)
: attrs.find((s) => s.name === "xmlns");
@@ -1030,7 +1030,7 @@ export function response(rpc: {
throw new Error(
`Unknown method response type ${
(rpc.acsResponse as AcsResponse).name
}`
}`,
);
}
} else if (rpc.acsRequest) {
@@ -1067,7 +1067,7 @@ export function response(rpc: {
break;
default:
throw new Error(
`Unknown method request ${(rpc.acsRequest as AcsRequest).name}`
`Unknown method request ${(rpc.acsRequest as AcsRequest).name}`,
);
}
} else if (rpc.acsFault) {
+3 -3
View File
@@ -97,7 +97,7 @@ export type VirtualParameterDeclaration = [
value?: [string | number | boolean, string?];
notification?: number;
accessList?: string[];
}?
}?,
];
export interface SyncState {
@@ -139,7 +139,7 @@ export interface SessionContext {
AttributeTimestamps,
AttributeValues,
AttributeTimestamps,
AttributeValues
AttributeValues,
][][];
revisions: number[];
rpcCount: number;
@@ -455,7 +455,7 @@ export type Clear = [
notification?: number;
accessList?: number;
}?,
number?
number?,
];
export interface Preset {
+6 -6
View File
@@ -54,10 +54,10 @@ const getAuthorizer = memoize(
const roles: string[] = JSON.parse(rolesStr);
const allPermissions = localCache.getPermissions(snapshot);
const permissionSets: PermissionSet[] = roles.map((r) =>
Object.values(allPermissions[r] || {})
Object.values(allPermissions[r] || {}),
);
return new Authorizer(permissionSets);
}
},
);
koa.on("error", (err, ctx) => {
@@ -90,7 +90,7 @@ koa.use(
return true;
},
})
}),
);
koa.use(async (ctx, next) => {
@@ -110,7 +110,7 @@ koa.use(async (ctx, next) => {
ctx.state.authorizer = getAuthorizer(
ctx.state.configSnapshot,
JSON.stringify(roles)
JSON.stringify(roles),
);
return next();
@@ -245,7 +245,7 @@ router.get("/", async (ctx) => {
window.configSnapshot = ${JSON.stringify(ctx.state.configSnapshot)};
window.genieacsVersion = ${JSON.stringify(VERSION)};
window.username = ${JSON.stringify(
ctx.state.user ? ctx.state.user.username : ""
ctx.state.user ? ctx.state.user.username : "",
)};
window.permissionSets = ${JSON.stringify(permissionSets)};
</script>
@@ -269,7 +269,7 @@ koa.use(
[constants.BROTLI_PARAM_QUALITY]: 5,
},
},
})
}),
);
koa.use(router.routes());
+9 -9
View File
@@ -104,12 +104,12 @@ router.get(`/devices/:id.csv`, async (ctx) => {
ctx.attachment(
`device-${ctx.params.id}-${new Date()
.toISOString()
.replace(/[:.]/g, "")}.csv`
.replace(/[:.]/g, "")}.csv`,
);
ctx.body = new PassThrough();
ctx.body.write(
"Parameter,Object,Object timestamp,Writable,Writable timestamp,Value,Value type,Value timestamp,Notification,Notification timestamp,Access list,Access list timestamp\n"
"Parameter,Object,Object timestamp,Writable,Writable timestamp,Value,Value type,Value timestamp,Notification,Notification timestamp,Access list,Access list timestamp\n",
);
for (const k of Object.keys(device).sort()) {
@@ -259,7 +259,7 @@ for (const [resource, flags] of Object.entries(resources)) {
}
const columns: Record<string, Expression> = JSON.parse(
singleParam(ctx.request.query.columns)
singleParam(ctx.request.query.columns),
);
const now = Date.now();
@@ -282,11 +282,11 @@ for (const [resource, flags] of Object.entries(resources)) {
ctx.body = new PassThrough();
ctx.type = "text/csv";
ctx.attachment(
`${resource}-${new Date(now).toISOString().replace(/[:.]/g, "")}.csv`
`${resource}-${new Date(now).toISOString().replace(/[:.]/g, "")}.csv`,
);
ctx.body.write(
Object.keys(columns).map((k) => `"${k.replace(/"/, '""')}"`) + "\n"
Object.keys(columns).map((k) => `"${k.replace(/"/, '""')}"`) + "\n",
);
for await (const obj of db.query(resource, filter, options)) {
const arr = Object.values(columns).map((exp) => {
@@ -633,7 +633,7 @@ router.post("/devices/:id/tasks", async (ctx) => {
}
}
return exp;
}
},
) as number;
const lastInform = device["Events.Inform"].value[0] as number;
@@ -643,7 +643,7 @@ router.post("/devices/:id/tasks", async (ctx) => {
const sessionStarted = await apiFunctions.awaitSessionStart(
deviceId,
lastInform,
onlineThreshold
onlineThreshold,
);
if (!sessionStarted) {
status = "No contact from CPE";
@@ -655,7 +655,7 @@ router.post("/devices/:id/tasks", async (ctx) => {
if (!status) {
const promises = statuses.map((t) =>
collections.faults.count({ _id: `${deviceId}:task_${t._id}` })
collections.faults.count({ _id: `${deviceId}:task_${t._id}` }),
);
const res = await Promise.all(promises);
@@ -746,7 +746,7 @@ router.put("/users/:id/password", async (ctx) => {
!(await apiFunctions.authLocal(
ctx.state.configSnapshot,
username,
ctx.request.body.authPassword
ctx.request.body.authPassword,
))
) {
logUnauthorizedWarning(log);
+20 -20
View File
@@ -30,7 +30,7 @@ import { Script } from "vm";
import { Readable } from "stream";
function processDeviceProjection(
projection: Record<string, 1>
projection: Record<string, 1>,
): Record<string, 1> {
if (!projection) return projection;
const p = {};
@@ -58,7 +58,7 @@ function processDeviceProjection(
}
function processDeviceSort(
sort: Record<string, number>
sort: Record<string, number>,
): Record<string, number> {
if (!sort) return sort;
const s = {};
@@ -93,7 +93,7 @@ interface FlatAttributes {
accessListTimestamp?: number;
}
interface FlatDevice {
export interface FlatDevice {
[param: string]: FlatAttributes;
}
@@ -102,7 +102,7 @@ export function flattenDevice(device: Record<string, unknown>): FlatDevice {
input,
root: string,
output: FlatDevice,
timestamp: number
timestamp: number,
): void {
for (const [name, tree] of Object.entries(input)) {
if (!root) {
@@ -272,7 +272,7 @@ function flattenTask(task: unknown): Task {
}
function flattenPreset(
preset: Record<string, unknown>
preset: Record<string, unknown>,
): Record<string, unknown> {
const p = Object.assign({}, preset);
if (p.precondition) {
@@ -281,7 +281,7 @@ function flattenPreset(
parse(p.precondition as string);
} catch (error) {
p.precondition = convertOldPrecondition(
JSON.parse(p.precondition as string)
JSON.parse(p.precondition as string),
);
p.precondition = (p.precondition as string).length
? stringify(p.precondition as Expression)
@@ -377,7 +377,7 @@ interface QueryOptions {
export async function* query(
resource: string,
filter: Expression,
options?: QueryOptions
options?: QueryOptions,
): AsyncGenerator<any, void, undefined> {
options = options || {};
filter = evaluate(filter, null, Date.now());
@@ -407,7 +407,7 @@ export async function* query(
.reduce(
(obj, [k, v]) =>
Object.assign(obj, { [k]: Math.min(Math.max(v, -1), 1) }),
{}
{},
);
if (resource === "devices") s = processDeviceSort(s);
@@ -435,7 +435,7 @@ export function count(resource: string, filter: Expression): Promise<number> {
export async function updateDeviceTags(
deviceId: string,
tags: Record<string, boolean>
tags: Record<string, boolean>,
): Promise<void> {
const add = [];
const pull = [];
@@ -455,7 +455,7 @@ export async function updateDeviceTags(
export async function putPreset(
id: string,
object: Record<string, unknown>
object: Record<string, unknown>,
): Promise<void> {
const p = preProcessPreset(object);
await collections.presets.replaceOne({ _id: id }, p, { upsert: true });
@@ -467,7 +467,7 @@ export async function deletePreset(id: string): Promise<void> {
export async function putProvision(
id: string,
object: { script: string }
object: { script: string },
): Promise<void> {
if (!object.script) object.script = "";
try {
@@ -478,7 +478,7 @@ export async function putProvision(
} catch (err) {
if (err.stack?.startsWith(`${id}:`)) {
return Promise.reject(
new Error(`${err.name} at ${err.stack.split("\n", 1)[0]}`)
new Error(`${err.name} at ${err.stack.split("\n", 1)[0]}`),
);
}
return Promise.reject(err);
@@ -494,7 +494,7 @@ export async function deleteProvision(id: string): Promise<void> {
export async function putVirtualParameter(
id: string,
object: { script: string }
object: { script: string },
): Promise<void> {
if (!object.script) object.script = "";
try {
@@ -505,7 +505,7 @@ export async function putVirtualParameter(
} catch (err) {
if (err.stack?.startsWith(`${id}:`)) {
return Promise.reject(
new Error(`${err.name} at ${err.stack.split("\n", 1)[0]}`)
new Error(`${err.name} at ${err.stack.split("\n", 1)[0]}`),
);
}
return Promise.reject(err);
@@ -521,7 +521,7 @@ export async function deleteVirtualParameter(id: string): Promise<void> {
export async function putConfig(
id: string,
object: WithoutId<MongoTypes.Config>
object: WithoutId<MongoTypes.Config>,
): Promise<void> {
await collections.config.replaceOne({ _id: id }, object, { upsert: true });
}
@@ -532,7 +532,7 @@ export async function deleteConfig(id: string): Promise<void> {
export async function putPermission(
id: string,
object: WithoutId<MongoTypes.Permission>
object: WithoutId<MongoTypes.Permission>,
): Promise<void> {
await collections.permissions.replaceOne({ _id: id }, object, {
upsert: true,
@@ -545,13 +545,13 @@ export async function deletePermission(id: string): Promise<void> {
export async function putUser(
id: string,
object: Partial<WithoutId<MongoTypes.User>>
object: Partial<WithoutId<MongoTypes.User>>,
): Promise<void> {
// update instead of replace to keep the password if not set by user
await collections.users.updateOne(
{ _id: id },
{ $set: object },
{ upsert: true }
{ upsert: true },
);
}
@@ -566,7 +566,7 @@ export function downloadFile(filename: string): Readable {
export function putFile(
filename: string,
metadata: Record<string, string>,
contentStream: Readable
contentStream: Readable,
): Promise<void> {
return new Promise((resolve, reject) => {
const uploadStream = filesBucket.openUploadStreamWithId(
@@ -574,7 +574,7 @@ export function putFile(
filename,
{
metadata: metadata,
}
},
);
let readableEnded = false;
+1 -1
View File
@@ -125,7 +125,7 @@ export function getConfig(
key: string,
context: Record<string, unknown>,
now: number,
cb?: (e: Expression) => Expression
cb?: (e: Expression) => Expression,
): string | number | boolean | null {
const snapshot = localCache.get(revision);
if (!snapshot) throw new Error("Cache snapshot does not exist");
+3 -3
View File
@@ -20,7 +20,7 @@
import { EventEmitter } from "events";
export function generateDeviceId(
deviceIdStruct: Record<string, string>
deviceIdStruct: Record<string, string>,
): string {
// Escapes everything except alphanumerics and underscore
function esc(str): string {
@@ -54,7 +54,7 @@ export function encodeTag(tag: string): string {
return encodeURIComponent(tag)
.replace(
/[!~*'().]/g,
(c) => "%" + c.charCodeAt(0).toString(16).toUpperCase()
(c) => "%" + c.charCodeAt(0).toString(16).toUpperCase(),
)
.replace(/0x(?=[0-9A-Z]{2})/g, "0%78")
.replace(/%/g, "0x");
@@ -67,7 +67,7 @@ export function decodeTag(tag: string): string {
export function once(
emitter: EventEmitter,
event: string,
timeout: number
timeout: number,
): Promise<unknown[]> {
return new Promise((resolve, reject) => {
const timer = setTimeout(() => {
+1 -1
View File
@@ -138,7 +138,7 @@ export default class VersionedMap<K, V> {
const del = revisionsObj.delete || 0;
const mutations = Object.keys(revisionsObj).reduce(
(acc, cur) => (cur === "delete" ? acc : acc | (1 << +cur)),
del
del,
);
const revisions = [];