Update dependencies
This commit is contained in:
1 parent
2789961596
commit
25ea0c8b64
14 files changed
+3449
-3947
No files matched your search
+3
-2
@@ -28,6 +28,7 @@ import commonjs from "@rollup/plugin-commonjs";
|
|||||||
import postcss from "postcss";
|
import postcss from "postcss";
|
||||||
import postcssImport from "postcss-import";
|
import postcssImport from "postcss-import";
|
||||||
import postcssPresetEnv from "postcss-preset-env";
|
import postcssPresetEnv from "postcss-preset-env";
|
||||||
|
import postcssColorMod from "postcss-color-mod-function";
|
||||||
import cssnano from "cssnano";
|
import cssnano from "cssnano";
|
||||||
import { optimize } from "svgo";
|
import { optimize } from "svgo";
|
||||||
import * as xmlParser from "../lib/xml-parser";
|
import * as xmlParser from "../lib/xml-parser";
|
||||||
@@ -185,10 +186,10 @@ async function generateCss(): Promise<void> {
|
|||||||
stage: 3,
|
stage: 3,
|
||||||
features: {
|
features: {
|
||||||
"nesting-rules": true,
|
"nesting-rules": true,
|
||||||
"color-mod-function": true,
|
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
cssnano,
|
postcssColorMod,
|
||||||
|
...(MODE === "production" ? [cssnano] : []),
|
||||||
]).process(cssIn, { from: cssInPath, to: cssOutPath });
|
]).process(cssIn, { from: cssInPath, to: cssOutPath });
|
||||||
fs.writeFileSync(cssOutPath, cssOut.css);
|
fs.writeFileSync(cssOutPath, cssOut.css);
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-12
@@ -20,11 +20,12 @@
|
|||||||
import { Collection } from "mongodb";
|
import { Collection } from "mongodb";
|
||||||
import { onConnect } from "./db";
|
import { onConnect } from "./db";
|
||||||
import * as config from "./config";
|
import * as config from "./config";
|
||||||
|
import { Cache } from "./mongodb-types";
|
||||||
|
|
||||||
const CLOCK_SKEW_TOLERANCE = 30000;
|
const CLOCK_SKEW_TOLERANCE = 30000;
|
||||||
const MAX_CACHE_TTL = +config.get("MAX_CACHE_TTL");
|
const MAX_CACHE_TTL = +config.get("MAX_CACHE_TTL");
|
||||||
|
|
||||||
let cacheCollection: Collection;
|
let cacheCollection: Collection<Cache>;
|
||||||
|
|
||||||
onConnect(async (db) => {
|
onConnect(async (db) => {
|
||||||
cacheCollection = db.collection("cache");
|
cacheCollection = db.collection("cache");
|
||||||
@@ -33,8 +34,7 @@ onConnect(async (db) => {
|
|||||||
|
|
||||||
export async function get(key: string): Promise<string> {
|
export async function get(key: string): Promise<string> {
|
||||||
const res = await cacheCollection.findOne({ _id: key });
|
const res = await cacheCollection.findOne({ _id: key });
|
||||||
if (res) return res["value"];
|
return res?.value;
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function del(key: string): Promise<void> {
|
export async function del(key: string): Promise<void> {
|
||||||
@@ -52,15 +52,14 @@ export async function set(
|
|||||||
);
|
);
|
||||||
await cacheCollection.replaceOne(
|
await cacheCollection.replaceOne(
|
||||||
{ _id: key },
|
{ _id: key },
|
||||||
{ _id: key, value, expire, timestamp },
|
{ value, expire, timestamp },
|
||||||
{ upsert: true }
|
{ upsert: true }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function pop(key: string): Promise<any> {
|
export async function pop(key: string): Promise<string> {
|
||||||
const res = await cacheCollection.findOneAndDelete({ _id: key });
|
const res = await cacheCollection.findOneAndDelete({ _id: key });
|
||||||
if (res?.["value"]) return res["value"]["value"];
|
return res.value?.value;
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function acquireLock(
|
export async function acquireLock(
|
||||||
@@ -72,18 +71,16 @@ export async function acquireLock(
|
|||||||
try {
|
try {
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const r = await cacheCollection.findOneAndUpdate(
|
const r = await cacheCollection.findOneAndUpdate(
|
||||||
{ _id: lockName, token },
|
{ _id: lockName, value: token },
|
||||||
{
|
{
|
||||||
$set: {
|
$set: {
|
||||||
value: token,
|
|
||||||
expire: new Date(now + ttl + CLOCK_SKEW_TOLERANCE),
|
expire: new Date(now + ttl + CLOCK_SKEW_TOLERANCE),
|
||||||
},
|
},
|
||||||
$currentDate: { timestamp: true as unknown as Date },
|
$currentDate: { timestamp: true },
|
||||||
},
|
},
|
||||||
{ upsert: true, returnDocument: "after" }
|
{ upsert: true, returnDocument: "after" }
|
||||||
);
|
);
|
||||||
const v = r.value;
|
if (Math.abs(r.value.timestamp.getTime() - now) > CLOCK_SKEW_TOLERANCE)
|
||||||
if (Math.abs(v["timestamp"].getTime() - now) > CLOCK_SKEW_TOLERANCE)
|
|
||||||
throw new Error("Database clock skew too great");
|
throw new Error("Database clock skew too great");
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err.code !== 11000) throw err;
|
if (err.code !== 11000) throw err;
|
||||||
|
|||||||
+1
-1
@@ -536,7 +536,7 @@ async function applyPresets(sessionContext: SessionContext): Promise<void> {
|
|||||||
session.configContextCallback(sessionContext, e)
|
session.configContextCallback(sessionContext, e)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
]);
|
]) as [string, ...Expression[]][];
|
||||||
if (blackList[p.channel] === 2) {
|
if (blackList[p.channel] === 2) {
|
||||||
appendProvisionsToFaults[p.channel] = (
|
appendProvisionsToFaults[p.channel] = (
|
||||||
appendProvisionsToFaults[p.channel] || []
|
appendProvisionsToFaults[p.channel] || []
|
||||||
|
|||||||
@@ -30,19 +30,20 @@ import {
|
|||||||
Expression,
|
Expression,
|
||||||
} from "./types";
|
} from "./types";
|
||||||
import Path from "./common/path";
|
import Path from "./common/path";
|
||||||
|
import * as MongoTypes from "./mongodb-types";
|
||||||
|
|
||||||
export let tasksCollection: Collection,
|
export let tasksCollection: Collection<MongoTypes.Task>,
|
||||||
devicesCollection: Collection,
|
devicesCollection: Collection,
|
||||||
presetsCollection: Collection,
|
presetsCollection: Collection,
|
||||||
objectsCollection: Collection,
|
objectsCollection: Collection,
|
||||||
provisionsCollection: Collection,
|
provisionsCollection: Collection,
|
||||||
virtualParametersCollection: Collection,
|
virtualParametersCollection: Collection,
|
||||||
faultsCollection: Collection,
|
faultsCollection: Collection<MongoTypes.Fault>,
|
||||||
filesCollection: Collection,
|
filesCollection: Collection,
|
||||||
operationsCollection: Collection,
|
operationsCollection: Collection<MongoTypes.Operation>,
|
||||||
permissionsCollection: Collection,
|
permissionsCollection: Collection,
|
||||||
usersCollection: Collection,
|
usersCollection: Collection,
|
||||||
configCollection: Collection;
|
configCollection: Collection<MongoTypes.Config>;
|
||||||
|
|
||||||
let clientPromise: Promise<MongoClient>;
|
let clientPromise: Promise<MongoClient>;
|
||||||
|
|
||||||
@@ -643,12 +644,16 @@ export async function getFaults(
|
|||||||
const faults: { [channel: string]: SessionFault } = {};
|
const faults: { [channel: string]: SessionFault } = {};
|
||||||
for (const r of res) {
|
for (const r of res) {
|
||||||
const channel = r._id.slice(deviceId.length + 1);
|
const channel = r._id.slice(deviceId.length + 1);
|
||||||
delete r._id;
|
const fault: SessionFault = {
|
||||||
delete r.channel;
|
code: r.code,
|
||||||
delete r.device;
|
message: r.message,
|
||||||
r.timestamp = +r.timestamp;
|
...(r.detail && { detail: r.detail }),
|
||||||
r.provisions = JSON.parse(r.provisions);
|
timestamp: +r.timestamp,
|
||||||
faults[channel] = r as SessionFault;
|
provisions: JSON.parse(r.provisions),
|
||||||
|
retries: r.retries,
|
||||||
|
...(r.expiry && { expiry: +r.expiry }),
|
||||||
|
};
|
||||||
|
faults[channel] = fault;
|
||||||
}
|
}
|
||||||
|
|
||||||
return faults;
|
return faults;
|
||||||
@@ -660,12 +665,18 @@ export async function saveFault(
|
|||||||
fault: SessionFault
|
fault: SessionFault
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const id = `${deviceId}:${channel}`;
|
const id = `${deviceId}:${channel}`;
|
||||||
const f = Object.assign({}, fault) as Record<string, any>;
|
const f: MongoTypes.Fault = {
|
||||||
f["_id"] = id;
|
_id: id,
|
||||||
f["device"] = deviceId;
|
device: deviceId,
|
||||||
f["channel"] = channel;
|
channel: channel,
|
||||||
f["timestamp"] = new Date(fault.timestamp);
|
timestamp: new Date(fault.timestamp),
|
||||||
f["provisions"] = JSON.stringify(fault.provisions);
|
code: fault.code,
|
||||||
|
message: fault.message,
|
||||||
|
...(fault.detail && { detail: fault.detail }),
|
||||||
|
retries: fault.retries,
|
||||||
|
...(fault.expiry && { expiry: new Date(fault.expiry) }),
|
||||||
|
provisions: JSON.stringify(fault.provisions),
|
||||||
|
};
|
||||||
await faultsCollection.replaceOne({ _id: id }, f, { upsert: true });
|
await faultsCollection.replaceOne({ _id: id }, f, { upsert: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -683,20 +694,47 @@ export async function getDueTasks(
|
|||||||
const cur = tasksCollection.find({ device: deviceId }).sort({ timestamp: 1 });
|
const cur = tasksCollection.find({ device: deviceId }).sort({ timestamp: 1 });
|
||||||
const tasks = [] as Task[];
|
const tasks = [] as Task[];
|
||||||
|
|
||||||
for await (const task of cur) {
|
for await (const t of cur) {
|
||||||
if (task.timestamp) task.timestamp = +task.timestamp;
|
if (+t.timestamp >= timestamp) return [tasks, +t.timestamp];
|
||||||
if (task.expiry) task.expiry = +task.expiry;
|
const task: Task = {
|
||||||
if (task.timestamp >= timestamp) return [tasks, +task.timestamp];
|
_id: t._id.toString(),
|
||||||
task._id = String(task._id);
|
name: t.name,
|
||||||
|
...(t.timestamp && { timestamp: +t.timestamp }),
|
||||||
|
...(t.expiry && { expiry: +t.expiry }),
|
||||||
|
...(t.name === "getParameterValues" && {
|
||||||
|
parameterNames: t.parameterNames,
|
||||||
|
}),
|
||||||
|
...(t.name === "setParameterValues" && {
|
||||||
|
parameterValues: t.parameterValues,
|
||||||
|
}),
|
||||||
|
...(t.name === "refreshObject" && {
|
||||||
|
objectName: t.objectName,
|
||||||
|
}),
|
||||||
|
...(t.name === "download" && {
|
||||||
|
fileType: t.fileType,
|
||||||
|
fileName: t.fileName,
|
||||||
|
targetFileName: t.targetFileName,
|
||||||
|
}),
|
||||||
|
...(t.name === "addObject" && {
|
||||||
|
objectName: t.objectName,
|
||||||
|
parameterValues: t.parameterValues,
|
||||||
|
}),
|
||||||
|
...(t.name === "deleteObject" && {
|
||||||
|
objectName: t.objectName,
|
||||||
|
}),
|
||||||
|
...(t.name === "provisions" && {
|
||||||
|
provisions: t.provisions,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
tasks.push(task as Task);
|
tasks.push(task);
|
||||||
|
|
||||||
// For API compatibility
|
// For API compatibility
|
||||||
if (task.name === "download" && task.file) {
|
if (task.name === "download" && t["file"]) {
|
||||||
let q;
|
let q;
|
||||||
if (ObjectId.isValid(task.file))
|
if (ObjectId.isValid(t["file"]))
|
||||||
q = { _id: { $in: [task.file, new ObjectId(task.file)] } };
|
q = { _id: { $in: [t["file"], new ObjectId(t["file"])] } };
|
||||||
else q = { _id: task.file };
|
else q = { _id: t["file"] };
|
||||||
|
|
||||||
const res = await filesCollection.find(q).toArray();
|
const res = await filesCollection.find(q).toArray();
|
||||||
|
|
||||||
@@ -730,17 +768,22 @@ export async function getOperations(
|
|||||||
const operations: { [commandKey: string]: Operation } = {};
|
const operations: { [commandKey: string]: Operation } = {};
|
||||||
for (const r of res) {
|
for (const r of res) {
|
||||||
const commandKey = r._id.slice(deviceId.length + 1);
|
const commandKey = r._id.slice(deviceId.length + 1);
|
||||||
delete r._id;
|
|
||||||
// Workaround for a bug in v1.2.1 where operation object is saved without deserialization
|
// Workaround for a bug in v1.2.1 where operation object is saved without deserialization
|
||||||
if (typeof r.provisions !== "string") {
|
if (typeof r.provisions !== "string") {
|
||||||
operations[commandKey] = r as Operation;
|
delete r._id;
|
||||||
|
operations[commandKey] = r as unknown as Operation;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
r.timestamp = +r.timestamp;
|
const operation: Operation = {
|
||||||
if (r.args) r.args = JSON.parse(r.args);
|
name: r.name,
|
||||||
r.provisions = JSON.parse(r.provisions);
|
timestamp: +r.timestamp,
|
||||||
r.retries = JSON.parse(r.retries);
|
channels:
|
||||||
operations[commandKey] = r as Operation;
|
typeof r.channels === "string" ? JSON.parse(r.channels) : r.channels,
|
||||||
|
retries: JSON.parse(r.retries),
|
||||||
|
provisions: JSON.parse(r.provisions),
|
||||||
|
...(r.args && { args: JSON.parse(r.args) }),
|
||||||
|
};
|
||||||
|
operations[commandKey] = operation;
|
||||||
}
|
}
|
||||||
return operations;
|
return operations;
|
||||||
}
|
}
|
||||||
@@ -751,12 +794,15 @@ export async function saveOperation(
|
|||||||
operation: Operation
|
operation: Operation
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const id = `${deviceId}:${commandKey}`;
|
const id = `${deviceId}:${commandKey}`;
|
||||||
const o = Object.assign({}, operation) as Record<string, any>;
|
const o: MongoTypes.Operation = {
|
||||||
o["_id"] = id;
|
_id: id,
|
||||||
o["timestamp"] = new Date(operation.timestamp);
|
name: operation.name,
|
||||||
o["provisions"] = JSON.stringify(operation.provisions);
|
timestamp: new Date(operation.timestamp),
|
||||||
o["retries"] = JSON.stringify(operation.retries);
|
channels: JSON.stringify(operation.channels),
|
||||||
o["args"] = JSON.stringify(operation.args);
|
provisions: JSON.stringify(operation.provisions),
|
||||||
|
retries: JSON.stringify(operation.retries),
|
||||||
|
args: JSON.stringify(operation.args),
|
||||||
|
};
|
||||||
await operationsCollection.replaceOne({ _id: id }, o, {
|
await operationsCollection.replaceOne({ _id: id }, o, {
|
||||||
upsert: true,
|
upsert: true,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,107 @@
|
|||||||
|
import { ObjectId } from "mongodb";
|
||||||
|
import { Expression, FaultStruct } from "./types";
|
||||||
|
|
||||||
|
export interface Fault {
|
||||||
|
_id: string;
|
||||||
|
device: string;
|
||||||
|
channel: string;
|
||||||
|
timestamp: Date;
|
||||||
|
provisions: string;
|
||||||
|
retries: number;
|
||||||
|
code: string;
|
||||||
|
message: string;
|
||||||
|
detail?:
|
||||||
|
| FaultStruct
|
||||||
|
| {
|
||||||
|
name: string;
|
||||||
|
message: string;
|
||||||
|
stack?: string;
|
||||||
|
};
|
||||||
|
expiry?: Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TaskBase {
|
||||||
|
_id: ObjectId;
|
||||||
|
timestamp?: Date;
|
||||||
|
expiry?: Date;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TaskGetParameterValues extends TaskBase {
|
||||||
|
name: "getParameterValues";
|
||||||
|
parameterNames: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TaskSetParameterValues extends TaskBase {
|
||||||
|
name: "setParameterValues";
|
||||||
|
parameterValues: [string, string | number | boolean, string?][];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TaskRefreshObject extends TaskBase {
|
||||||
|
name: "refreshObject";
|
||||||
|
objectName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TaskReboot extends TaskBase {
|
||||||
|
name: "reboot";
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TaskFactoryReset extends TaskBase {
|
||||||
|
name: "factoryReset";
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TaskDownload extends TaskBase {
|
||||||
|
name: "download";
|
||||||
|
fileType: string;
|
||||||
|
fileName: string;
|
||||||
|
targetFileName?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TaskAddObject extends TaskBase {
|
||||||
|
name: "addObject";
|
||||||
|
objectName: string;
|
||||||
|
parameterValues: [string, string | number | boolean, string?][];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TaskDeleteObject extends TaskBase {
|
||||||
|
name: "deleteObject";
|
||||||
|
objectName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TaskProvisions extends TaskBase {
|
||||||
|
name: "provisions";
|
||||||
|
provisions?: [string, ...Expression[]][];
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Task =
|
||||||
|
| TaskGetParameterValues
|
||||||
|
| TaskSetParameterValues
|
||||||
|
| TaskRefreshObject
|
||||||
|
| TaskReboot
|
||||||
|
| TaskFactoryReset
|
||||||
|
| TaskDownload
|
||||||
|
| TaskAddObject
|
||||||
|
| TaskDeleteObject
|
||||||
|
| TaskProvisions;
|
||||||
|
|
||||||
|
export interface Operation {
|
||||||
|
_id: string;
|
||||||
|
name: string;
|
||||||
|
timestamp: Date;
|
||||||
|
channels: string;
|
||||||
|
retries: string;
|
||||||
|
provisions: string;
|
||||||
|
args: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Config {
|
||||||
|
_id: string;
|
||||||
|
value: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Cache {
|
||||||
|
_id: string;
|
||||||
|
value: string;
|
||||||
|
timestamp: Date;
|
||||||
|
expire: Date;
|
||||||
|
}
|
||||||
+1
-1
@@ -845,7 +845,7 @@ export function listener(
|
|||||||
cur.sort(sort);
|
cur.sort(sort);
|
||||||
}
|
}
|
||||||
|
|
||||||
cur.count((err, total) => {
|
collection.countDocuments(q, (err, total) => {
|
||||||
if (err) return void throwError(err);
|
if (err) return void throwError(err);
|
||||||
|
|
||||||
response.writeHead(200, {
|
response.writeHead(200, {
|
||||||
|
|||||||
+1
-1
@@ -504,7 +504,7 @@ export async function timeoutOperations(
|
|||||||
export function addProvisions(
|
export function addProvisions(
|
||||||
sessionContext: SessionContext,
|
sessionContext: SessionContext,
|
||||||
channel: string,
|
channel: string,
|
||||||
provisions: (string | number | boolean)[][]
|
provisions: [string, ...Expression[]][]
|
||||||
): void {
|
): void {
|
||||||
// Multiply by two because every iteration is two
|
// Multiply by two because every iteration is two
|
||||||
// phases: read and update
|
// phases: read and update
|
||||||
|
|||||||
+1
-1
@@ -180,7 +180,7 @@ export interface Task {
|
|||||||
fileName?: string;
|
fileName?: string;
|
||||||
targetFileName?: string;
|
targetFileName?: string;
|
||||||
expiry?: number;
|
expiry?: number;
|
||||||
provisions?: (string | number | boolean)[][];
|
provisions?: [string, ...Expression[]][];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Operation {
|
export interface Operation {
|
||||||
|
|||||||
+15
-19
@@ -115,30 +115,31 @@ export function query(
|
|||||||
cursor.toArray((err, docs) => {
|
cursor.toArray((err, docs) => {
|
||||||
if (err) return reject(err);
|
if (err) return reject(err);
|
||||||
if (resource === "devices")
|
if (resource === "devices")
|
||||||
docs = docs.map((d) => mongodbFunctions.flattenDevice(d));
|
return resolve(docs.map((d) => mongodbFunctions.flattenDevice(d)));
|
||||||
else if (resource === "faults")
|
else if (resource === "faults")
|
||||||
docs = docs.map((d) => mongodbFunctions.flattenFault(d));
|
return resolve(docs.map((d) => mongodbFunctions.flattenFault(d)));
|
||||||
else if (resource === "tasks")
|
else if (resource === "tasks")
|
||||||
docs = docs.map((d) => mongodbFunctions.flattenTask(d));
|
return resolve(docs.map((d) => mongodbFunctions.flattenTask(d)));
|
||||||
else if (resource === "presets")
|
else if (resource === "presets")
|
||||||
docs = docs.map((d) => mongodbFunctions.flattenPreset(d));
|
return resolve(docs.map((d) => mongodbFunctions.flattenPreset(d)));
|
||||||
else if (resource === "files")
|
else if (resource === "files")
|
||||||
docs = docs.map((d) => mongodbFunctions.flattenFile(d));
|
return resolve(docs.map((d) => mongodbFunctions.flattenFile(d)));
|
||||||
return resolve(docs);
|
return resolve(docs);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
cursor.forEach(
|
cursor.forEach(
|
||||||
(doc) => {
|
(doc) => {
|
||||||
if (resource === "devices") doc = mongodbFunctions.flattenDevice(doc);
|
if (resource === "devices")
|
||||||
|
callback(mongodbFunctions.flattenDevice(doc));
|
||||||
else if (resource === "faults")
|
else if (resource === "faults")
|
||||||
doc = mongodbFunctions.flattenFault(doc);
|
callback(mongodbFunctions.flattenFault(doc));
|
||||||
else if (resource === "tasks")
|
else if (resource === "tasks")
|
||||||
doc = mongodbFunctions.flattenTask(doc);
|
callback(mongodbFunctions.flattenTask(doc));
|
||||||
else if (resource === "presets")
|
else if (resource === "presets")
|
||||||
doc = mongodbFunctions.flattenPreset(doc);
|
callback(mongodbFunctions.flattenPreset(doc));
|
||||||
else if (resource === "files")
|
else if (resource === "files")
|
||||||
doc = mongodbFunctions.flattenFile(doc);
|
callback(mongodbFunctions.flattenFile(doc));
|
||||||
callback(doc);
|
else callback(doc);
|
||||||
},
|
},
|
||||||
(err) => {
|
(err) => {
|
||||||
if (err) reject(err);
|
if (err) reject(err);
|
||||||
@@ -150,7 +151,8 @@ export function query(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function count(resource: string, filter: Expression): Promise<number> {
|
export function count(resource: string, filter: Expression): Promise<number> {
|
||||||
let q;
|
const collection = db.collection(RESOURCE_COLLECTION[resource] || resource);
|
||||||
|
let q: Parameters<typeof collection.countDocuments>[0];
|
||||||
filter = expression.evaluate(filter, null, Date.now());
|
filter = expression.evaluate(filter, null, Date.now());
|
||||||
filter = minimize(filter, true);
|
filter = minimize(filter, true);
|
||||||
|
|
||||||
@@ -166,13 +168,7 @@ export function count(resource: string, filter: Expression): Promise<number> {
|
|||||||
return Promise.resolve(0);
|
return Promise.resolve(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return collection.countDocuments(q);
|
||||||
const collection = db.collection(RESOURCE_COLLECTION[resource] || resource);
|
|
||||||
collection.find(q).count((err, c) => {
|
|
||||||
if (err) reject(err);
|
|
||||||
else resolve(c);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updateDeviceTags(
|
export async function updateDeviceTags(
|
||||||
|
|||||||
Generated
+3194
-3840
File diff suppressed because it is too large.
Load diff
+28
-27
@@ -28,46 +28,47 @@
|
|||||||
"koa-bodyparser": "^4.3.0",
|
"koa-bodyparser": "^4.3.0",
|
||||||
"koa-compress": "^5.1.0",
|
"koa-compress": "^5.1.0",
|
||||||
"koa-jwt": "^4.0.3",
|
"koa-jwt": "^4.0.3",
|
||||||
"koa-router": "^10.1.1",
|
"koa-router": "^12.0.0",
|
||||||
"koa-static": "^5.0.0",
|
"koa-static": "^5.0.0",
|
||||||
"mongodb": "^4.1.3",
|
"mongodb": "^4.9.0",
|
||||||
"parsimmon": "^1.18.0",
|
"parsimmon": "^1.18.1",
|
||||||
"seedrandom": "^3.0.5"
|
"seedrandom": "^3.0.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@rollup/plugin-commonjs": "^21.0.1",
|
"@rollup/plugin-commonjs": "^22.0.2",
|
||||||
"@rollup/plugin-json": "^4.1.0",
|
"@rollup/plugin-json": "^4.1.0",
|
||||||
"@rollup/plugin-node-resolve": "^13.0.6",
|
"@rollup/plugin-node-resolve": "^13.3.0",
|
||||||
"@rollup/plugin-typescript": "^8.3.0",
|
"@rollup/plugin-typescript": "^8.3.4",
|
||||||
"@types/codemirror": "^5.60.5",
|
"@types/codemirror": "^5.60.5",
|
||||||
"@types/jsonwebtoken": "^8.5.5",
|
"@types/jsonwebtoken": "^8.5.8",
|
||||||
"@types/koa": "^2.13.4",
|
"@types/koa": "^2.13.5",
|
||||||
"@types/koa-compress": "^4.0.3",
|
"@types/koa-compress": "^4.0.3",
|
||||||
"@types/koa-router": "^7.4.4",
|
"@types/koa-router": "^7.4.4",
|
||||||
"@types/koa-static": "^4.0.2",
|
"@types/koa-static": "^4.0.2",
|
||||||
"@types/mithril": "^2.0.8",
|
"@types/mithril": "^2.0.11",
|
||||||
"@types/node": "^16.11.6",
|
"@types/node": "^18.7.9",
|
||||||
"@types/parsimmon": "^1.10.6",
|
"@types/parsimmon": "^1.10.6",
|
||||||
"@types/seedrandom": "^3.0.1",
|
"@types/seedrandom": "^3.0.2",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.2.0",
|
"@typescript-eslint/eslint-plugin": "^5.33.1",
|
||||||
"@typescript-eslint/parser": "^5.2.0",
|
"@typescript-eslint/parser": "^5.33.1",
|
||||||
"ava": "^3.15.0",
|
"ava": "^3.15.0",
|
||||||
"codemirror": "^5.63.3",
|
"codemirror": "^5.65.8",
|
||||||
"cssnano": "^5.0.8",
|
"cssnano": "^5.1.13",
|
||||||
"eslint": "^8.1.0",
|
"eslint": "^8.22.0",
|
||||||
"eslint-config-prettier": "^8.3.0",
|
"eslint-config-prettier": "^8.5.0",
|
||||||
"esm": "^3.2.25",
|
"esm": "^3.2.25",
|
||||||
"mithril": "^2.0.4",
|
"mithril": "^2.2.2",
|
||||||
"postcss": "^8.3.11",
|
"postcss": "^8.4.16",
|
||||||
"postcss-import": "^14.0.2",
|
"postcss-color-mod-function": "^3.0.3",
|
||||||
"postcss-preset-env": "^6.7.0",
|
"postcss-import": "^14.1.0",
|
||||||
"prettier": "^2.4.1",
|
"postcss-preset-env": "^7.8.0",
|
||||||
"rollup": "^2.58.3",
|
"prettier": "^2.7.1",
|
||||||
|
"rollup": "^2.78.1",
|
||||||
"rollup-plugin-terser": "^7.0.2",
|
"rollup-plugin-terser": "^7.0.2",
|
||||||
"sql.js": "^1.6.2",
|
"sql.js": "^1.7.0",
|
||||||
"svgo": "^2.7.0",
|
"svgo": "^2.8.0",
|
||||||
"ts-node": "^10.4.0",
|
"ts-node": "^10.9.1",
|
||||||
"typescript": "^4.4.4",
|
"typescript": "^4.7.4",
|
||||||
"yaml": "^1.10.2"
|
"yaml": "^1.10.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import ava, { TestInterface } from "ava";
|
import ava, { TestInterface } from "ava";
|
||||||
import { minimize, unionDiff } from "../lib/common/boolean-expression";
|
import { minimize, unionDiff } from "../lib/common/boolean-expression";
|
||||||
import { parse, stringify } from "../lib/common/expression-parser";
|
import { parse, stringify } from "../lib/common/expression-parser";
|
||||||
import initSqlJs from "sql.js";
|
import initSqlJs from "sql.js/dist/sql-asm.js";
|
||||||
|
|
||||||
const test = ava as TestInterface<{
|
const test = ava as TestInterface<{
|
||||||
query: (filter: string) => Promise<Set<number>>;
|
query: (filter: string) => Promise<Set<number>>;
|
||||||
|
|||||||
@@ -99,9 +99,9 @@ export default class Autocomplete {
|
|||||||
if (this.visible) this.hide();
|
if (this.visible) this.hide();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.container.style.left = `${domRect.left + window.pageXOffset}px`;
|
this.container.style.left = `${domRect.left + window.scrollX}px`;
|
||||||
this.container.style.width = `${domRect.width}px`;
|
this.container.style.width = `${domRect.width}px`;
|
||||||
this.container.style.top = `${domRect.bottom + window.pageYOffset}px`;
|
this.container.style.top = `${domRect.bottom + window.scrollY}px`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private hide(): void {
|
private hide(): void {
|
||||||
|
|||||||
+1
-1
@@ -648,7 +648,7 @@ span.na {
|
|||||||
|
|
||||||
span.tag {
|
span.tag {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
background-image: url('data:image/svg+xml;utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="190" height="16"><path d="M6.59 15.42l-6-6a2 2 0 0 1 0-2.83l6-6A2 2 0 0 1 8 0h180a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H8a2 2 0 0 1-1.41-.58zM4.35 6.59A2 2 0 1 0 7.17 9.4 2 2 0 0 0 4.35 6.6z" fill="#e8d5b2"></path></svg>');
|
background-image: url('data:image/svg+xml;utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="190" height="16"><path d="M6.59 15.42l-6-6a2 2 0 0 1 0-2.83l6-6A2 2 0 0 1 8 0h180a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H8a2 2 0 0 1-1.41-.58zM4.35 6.59A2 2 0 1 0 7.17 9.4 2 2 0 0 0 4.35 6.6z" fill="%23e8d5b2"></path></svg>');
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
border-radius: 0.2em;
|
border-radius: 0.2em;
|
||||||
|
|||||||
Reference in new issue
Block a user