TypeScript!
This commit is contained in:
1 parent
ee8c43747e
commit
5d3c81cb23
105 files changed
+12054
-1901
No files matched your search
@@ -1,9 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
import { exec } from "child_process";
|
||||
import { ObjectID } from "mongodb";
|
||||
import * as db from "./db";
|
||||
import { del } from "../cache";
|
||||
import { ObjectID } from "mongodb";
|
||||
import { exec } from "child_process";
|
||||
import {
|
||||
insertTasks,
|
||||
watchTask,
|
||||
@@ -11,7 +9,7 @@ import {
|
||||
deleteDevice
|
||||
} from "../api-functions";
|
||||
|
||||
function deleteFault(id) {
|
||||
function deleteFault(id): Promise<void> {
|
||||
const deviceId = id.split(":", 1)[0];
|
||||
const channel = id.slice(deviceId.length + 1);
|
||||
return new Promise((resolve, reject) => {
|
||||
@@ -30,7 +28,7 @@ function deleteFault(id) {
|
||||
});
|
||||
}
|
||||
|
||||
export function deleteResource(resource, id) {
|
||||
export function deleteResource(resource, id): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
let promise;
|
||||
|
||||
@@ -80,7 +78,11 @@ export function deleteResource(resource, id) {
|
||||
});
|
||||
}
|
||||
|
||||
export function postTasks(deviceId, tasks, timeout) {
|
||||
export function postTasks(
|
||||
deviceId,
|
||||
tasks,
|
||||
timeout
|
||||
): Promise<{ connectionRequest: string; tasks: any[] }> {
|
||||
return new Promise((resolve, reject) => {
|
||||
for (const task of tasks) task.device = deviceId;
|
||||
|
||||
@@ -139,7 +141,17 @@ export function postTasks(deviceId, tasks, timeout) {
|
||||
});
|
||||
}
|
||||
|
||||
export function ping(host) {
|
||||
interface PingResponse {
|
||||
packetsTransmitted: number;
|
||||
packetsReceived: number;
|
||||
packetLoss: string;
|
||||
min: number;
|
||||
avg: number;
|
||||
max: number;
|
||||
mdev: number;
|
||||
}
|
||||
|
||||
export function ping(host): Promise<PingResponse> {
|
||||
return new Promise((resolve, reject) => {
|
||||
exec(`ping -w 1 -i 0.2 -c 3 ${host}`, (err, stdout) => {
|
||||
if (err) return void reject(err);
|
||||
@@ -162,7 +174,7 @@ export function ping(host) {
|
||||
});
|
||||
}
|
||||
|
||||
export function putResource(resource, id, data) {
|
||||
export function putResource(resource, id, data): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
let promise;
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
"use strict";
|
||||
|
||||
import stream from "stream";
|
||||
import * as stream from "stream";
|
||||
import Router from "koa-router";
|
||||
import * as db from "./db";
|
||||
import * as apiFunctions from "./api-functions";
|
||||
@@ -8,11 +6,12 @@ import { evaluate, and, extractParams } from "../common/expression";
|
||||
import { parse } from "../common/expression-parser";
|
||||
import * as logger from "../logger";
|
||||
import { getConfig } from "../local-cache";
|
||||
import { QueryOptions, Expression } from "../types";
|
||||
|
||||
const router = new Router();
|
||||
export default router;
|
||||
|
||||
function logUnauthorizedWarning(log) {
|
||||
function logUnauthorizedWarning(log): void {
|
||||
log.message += " not authorized";
|
||||
logger.accessWarn(log);
|
||||
}
|
||||
@@ -91,13 +90,14 @@ router.get(`/devices/:id.csv`, async ctx => {
|
||||
|
||||
for (const [resource, flags] of Object.entries(resources)) {
|
||||
router.head(`/${resource}`, async (ctx, next) => {
|
||||
let filter = true;
|
||||
let filter: Expression = true;
|
||||
if (ctx.request.query.filter) filter = parse(ctx.request.query.filter);
|
||||
|
||||
const log = {
|
||||
message: `Count ${resource}`,
|
||||
context: ctx,
|
||||
filter: ctx.request.query.filter
|
||||
filter: ctx.request.query.filter,
|
||||
count: null
|
||||
};
|
||||
|
||||
if (!ctx.state.authorizer.hasAccess(resource, 1)) {
|
||||
@@ -115,7 +115,7 @@ for (const [resource, flags] of Object.entries(resources)) {
|
||||
|
||||
const count = await db.count(resource, filter);
|
||||
|
||||
ctx.set("X-Total-Count", count);
|
||||
ctx.set("X-Total-Count", `${count}`);
|
||||
ctx.body = "";
|
||||
|
||||
log.count = count;
|
||||
@@ -123,8 +123,8 @@ for (const [resource, flags] of Object.entries(resources)) {
|
||||
});
|
||||
|
||||
router.get(`/${resource}`, async (ctx, next) => {
|
||||
const options = {};
|
||||
let filter = true;
|
||||
const options: QueryOptions = {};
|
||||
let filter: Expression = true;
|
||||
if (ctx.request.query.filter) filter = parse(ctx.request.query.filter);
|
||||
if (ctx.request.query.limit) options.limit = +ctx.request.query.limit;
|
||||
if (ctx.request.query.skip) options.skip = +ctx.request.query.skip;
|
||||
@@ -174,8 +174,8 @@ for (const [resource, flags] of Object.entries(resources)) {
|
||||
|
||||
// CSV download
|
||||
router.get(`/${resource}.csv`, async (ctx, next) => {
|
||||
const options = { projection: {} };
|
||||
let filter = true;
|
||||
const options: QueryOptions = { projection: {} };
|
||||
let filter: Expression = true;
|
||||
if (ctx.request.query.filter) filter = parse(ctx.request.query.filter);
|
||||
if (ctx.request.query.limit) options.limit = +ctx.request.query.limit;
|
||||
if (ctx.request.query.skip) options.skip = +ctx.request.query.skip;
|
||||
@@ -356,9 +356,9 @@ for (const [resource, flags] of Object.entries(resources)) {
|
||||
return void (ctx.status = 403);
|
||||
}
|
||||
|
||||
const err = await apiFunctions.putResource(resource, id, obj);
|
||||
|
||||
if (err) {
|
||||
try {
|
||||
await apiFunctions.putResource(resource, id, obj);
|
||||
} catch (err) {
|
||||
log.message += " failed";
|
||||
logger.accessWarn(log);
|
||||
ctx.body = err;
|
||||
@@ -379,7 +379,8 @@ router.put("/files/:id", async (ctx, next) => {
|
||||
const log = {
|
||||
message: `Upload ${resource}`,
|
||||
context: ctx,
|
||||
id: id
|
||||
id: id,
|
||||
metadata: null
|
||||
};
|
||||
|
||||
const authorizer = ctx.state.authorizer;
|
||||
@@ -412,7 +413,8 @@ router.post("/devices/:id/tasks", async (ctx, next) => {
|
||||
const log = {
|
||||
message: "Commit tasks",
|
||||
context: ctx,
|
||||
deviceId: ctx.params.id
|
||||
deviceId: ctx.params.id,
|
||||
tasks: null
|
||||
};
|
||||
|
||||
const authorizer = ctx.state.authorizer;
|
||||
+29
-25
@@ -1,10 +1,9 @@
|
||||
"use strict";
|
||||
|
||||
import { MongoClient, GridFSBucket } from "mongodb";
|
||||
import * as config from "../config";
|
||||
import * as mongodbFunctions from "./mongodb-functions";
|
||||
import * as expression from "../common/expression";
|
||||
import { preProcessPreset } from "./mongodb-functions";
|
||||
import { QueryOptions } from "../types";
|
||||
|
||||
const CACHE_TTL = 300000;
|
||||
|
||||
@@ -14,17 +13,17 @@ const RESOURCE_COLLECTION = {
|
||||
files: "fs.files"
|
||||
};
|
||||
|
||||
function ensureIndexes(client) {
|
||||
function ensureIndexes(client): void {
|
||||
client
|
||||
.db()
|
||||
.collection("cache")
|
||||
.createIndex({ expire: 1 }, { expireAfterSeconds: 0 });
|
||||
}
|
||||
|
||||
function getClient() {
|
||||
function getClient(): Promise<MongoClient> {
|
||||
if (!_clientPromise) {
|
||||
_clientPromise = new Promise((resolve, reject) => {
|
||||
const CONNECTION_URL = config.get("MONGODB_CONNECTION_URL");
|
||||
const CONNECTION_URL = "" + config.get("MONGODB_CONNECTION_URL");
|
||||
MongoClient.connect(
|
||||
CONNECTION_URL,
|
||||
{ useNewUrlParser: true },
|
||||
@@ -40,14 +39,14 @@ function getClient() {
|
||||
return _clientPromise;
|
||||
}
|
||||
|
||||
export function cache(key, valueGetter, ttl) {
|
||||
export function cache<T>(key, valueGetter: () => Promise<T>, ttl): Promise<T> {
|
||||
return new Promise((resolve, reject) => {
|
||||
getClient()
|
||||
.then(client => {
|
||||
const collection = client.db().collection("cache");
|
||||
collection.findOne({ _id: key }, (err, doc) => {
|
||||
if (err) return void reject(err);
|
||||
if (doc != null) return void resolve(JSON.parse(doc.value));
|
||||
if (doc != null) return void resolve(JSON.parse(doc.value) as T);
|
||||
valueGetter()
|
||||
.then(res => {
|
||||
const expire = Date.now() + (ttl || CACHE_TTL);
|
||||
@@ -73,7 +72,12 @@ export function cache(key, valueGetter, ttl) {
|
||||
});
|
||||
}
|
||||
|
||||
export function query(resource, filter, options, callback) {
|
||||
export function query(
|
||||
resource,
|
||||
filter,
|
||||
options?: QueryOptions,
|
||||
callback?: (doc: any) => void
|
||||
): Promise<any[]> {
|
||||
options = options || {};
|
||||
let q;
|
||||
filter = expression.evaluate(filter, null, Date.now());
|
||||
@@ -159,7 +163,7 @@ export function query(resource, filter, options, callback) {
|
||||
});
|
||||
}
|
||||
|
||||
export function count(resource, filter) {
|
||||
export function count(resource, filter): Promise<number> {
|
||||
let q;
|
||||
filter = expression.evaluate(filter, null, Date.now());
|
||||
|
||||
@@ -188,7 +192,7 @@ export function count(resource, filter) {
|
||||
});
|
||||
}
|
||||
|
||||
export function updateDeviceTags(deviceId, tags) {
|
||||
export function updateDeviceTags(deviceId, tags): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const add = [];
|
||||
const pull = [];
|
||||
@@ -213,7 +217,7 @@ export function updateDeviceTags(deviceId, tags) {
|
||||
});
|
||||
}
|
||||
|
||||
function putResource(resource, id, object) {
|
||||
function putResource(resource, id, object): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
getClient()
|
||||
.then(client => {
|
||||
@@ -229,7 +233,7 @@ function putResource(resource, id, object) {
|
||||
});
|
||||
}
|
||||
|
||||
function deleteResource(resource, id) {
|
||||
function deleteResource(resource, id): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
getClient()
|
||||
.then(client => {
|
||||
@@ -245,40 +249,40 @@ function deleteResource(resource, id) {
|
||||
});
|
||||
}
|
||||
|
||||
export function putPreset(id, object) {
|
||||
export function putPreset(id, object): Promise<void> {
|
||||
object = preProcessPreset(object);
|
||||
return putResource("presets", id, object);
|
||||
}
|
||||
|
||||
export function deletePreset(id) {
|
||||
export function deletePreset(id): Promise<void> {
|
||||
return deleteResource("presets", id);
|
||||
}
|
||||
|
||||
export function putProvision(id, object) {
|
||||
export function putProvision(id, object): Promise<void> {
|
||||
return putResource("provisions", id, object);
|
||||
}
|
||||
|
||||
export function deleteProvision(id) {
|
||||
export function deleteProvision(id): Promise<void> {
|
||||
return deleteResource("provisions", id);
|
||||
}
|
||||
|
||||
export function putVirtualParameter(id, object) {
|
||||
export function putVirtualParameter(id, object): Promise<void> {
|
||||
return putResource("virtualParameters", id, object);
|
||||
}
|
||||
|
||||
export function deleteVirtualParameter(id) {
|
||||
export function deleteVirtualParameter(id): Promise<void> {
|
||||
return deleteResource("virtualParameters", id);
|
||||
}
|
||||
|
||||
export function putConfig(id, object) {
|
||||
export function putConfig(id, object): Promise<void> {
|
||||
return putResource("config", id, object);
|
||||
}
|
||||
|
||||
export function deleteConfig(id) {
|
||||
export function deleteConfig(id): Promise<void> {
|
||||
return deleteResource("config", id);
|
||||
}
|
||||
|
||||
export function putFile(filename, metadata, contentStream) {
|
||||
export function putFile(filename, metadata, contentStream): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
getClient()
|
||||
.then(client => {
|
||||
@@ -295,7 +299,7 @@ export function putFile(filename, metadata, contentStream) {
|
||||
});
|
||||
}
|
||||
|
||||
export function deleteFile(filename) {
|
||||
export function deleteFile(filename): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
getClient()
|
||||
.then(client => {
|
||||
@@ -309,15 +313,15 @@ export function deleteFile(filename) {
|
||||
});
|
||||
}
|
||||
|
||||
export function deleteFault(id) {
|
||||
export function deleteFault(id): Promise<void> {
|
||||
return deleteResource("faults", id);
|
||||
}
|
||||
|
||||
export function deleteTask(id) {
|
||||
export function deleteTask(id): Promise<void> {
|
||||
return deleteResource("tasks", id);
|
||||
}
|
||||
|
||||
export function disconnect() {
|
||||
export function disconnect(): void {
|
||||
if (_clientPromise) {
|
||||
_clientPromise.then(client => {
|
||||
client.close();
|
||||
@@ -1,11 +1,11 @@
|
||||
"use strict";
|
||||
import { ObjectID } from "mongodb";
|
||||
import { map, parse, stringify } from "../common/expression-parser";
|
||||
import { likePatternToRegExp, evaluate } from "../common/expression";
|
||||
import { Expression, Fault, Task } from "../types";
|
||||
|
||||
const isArray = Array.isArray;
|
||||
|
||||
export function processDeviceFilter(filter) {
|
||||
export function processDeviceFilter(filter): Expression {
|
||||
return map(filter, exp => {
|
||||
if (!isArray(exp)) return exp;
|
||||
|
||||
@@ -46,7 +46,7 @@ export function processDeviceFilter(filter) {
|
||||
});
|
||||
|
||||
if (typeof e[2] === "number") {
|
||||
const alt = e.slice();
|
||||
const alt = (e as any[]).slice();
|
||||
alt[2] = new Date(e[2]);
|
||||
e = ["OR", e, alt];
|
||||
}
|
||||
@@ -56,7 +56,7 @@ export function processDeviceFilter(filter) {
|
||||
});
|
||||
}
|
||||
|
||||
export function processTasksFilter(filter) {
|
||||
export function processTasksFilter(filter): Expression {
|
||||
return map(filter, exp => {
|
||||
if (!isArray(exp)) return exp;
|
||||
if (["=", "<>", ">", ">=", "<", "<="].includes(exp[0])) {
|
||||
@@ -72,7 +72,7 @@ export function processTasksFilter(filter) {
|
||||
});
|
||||
}
|
||||
|
||||
export function processFaultsFilter(filter) {
|
||||
export function processFaultsFilter(filter): Expression {
|
||||
return map(filter, exp => {
|
||||
if (!isArray(exp)) return exp;
|
||||
if (["=", "<>", ">", ">=", "<", "<="].includes(exp[0])) {
|
||||
@@ -86,7 +86,7 @@ export function processFaultsFilter(filter) {
|
||||
});
|
||||
}
|
||||
|
||||
export function filterToMongoQuery(exp) {
|
||||
export function filterToMongoQuery(exp: Expression): {} {
|
||||
const ops = {
|
||||
OR: 0,
|
||||
AND: 0,
|
||||
@@ -103,7 +103,7 @@ export function filterToMongoQuery(exp) {
|
||||
"IS NOT NULL": 1
|
||||
};
|
||||
|
||||
function recursive(filter, negate, res = {}) {
|
||||
function recursive(filter, negate, res = {}): {} {
|
||||
const op = filter[0];
|
||||
|
||||
if (ops[op] === 0) {
|
||||
@@ -219,7 +219,7 @@ export function filterToMongoQuery(exp) {
|
||||
return recursive(_exp, false);
|
||||
}
|
||||
|
||||
export function processDeviceProjection(projection) {
|
||||
export function processDeviceProjection(projection: {}): {} {
|
||||
if (!projection) return projection;
|
||||
const p = {};
|
||||
for (const [k, v] of Object.entries(projection)) {
|
||||
@@ -245,7 +245,7 @@ export function processDeviceProjection(projection) {
|
||||
return p;
|
||||
}
|
||||
|
||||
export function processDeviceSort(sort) {
|
||||
export function processDeviceSort(sort: {}): {} {
|
||||
if (!sort) return sort;
|
||||
const s = {};
|
||||
for (const [k, v] of Object.entries(sort)) {
|
||||
@@ -261,13 +261,24 @@ export function processDeviceSort(sort) {
|
||||
return s;
|
||||
}
|
||||
|
||||
function parseDate(d) {
|
||||
function parseDate(d): number | string {
|
||||
const n = +d;
|
||||
return isNaN(n) ? "" + d : n;
|
||||
}
|
||||
|
||||
export function flattenDevice(device) {
|
||||
function recursive(input, root, output, timestamp) {
|
||||
interface FlatDevice {
|
||||
[param: string]: {
|
||||
object: boolean;
|
||||
objectTimestamp: number;
|
||||
writable: boolean;
|
||||
writableTimestamp: number;
|
||||
value: [string | number | boolean, string];
|
||||
valueTimestamp: number;
|
||||
};
|
||||
}
|
||||
|
||||
export function flattenDevice(device): FlatDevice {
|
||||
function recursive(input, root, output, timestamp): void {
|
||||
for (const [name, tree] of Object.entries(input)) {
|
||||
if (!root) {
|
||||
if (name === "_lastInform") {
|
||||
@@ -356,7 +367,7 @@ export function flattenDevice(device) {
|
||||
objectTimestamp: timestamp
|
||||
};
|
||||
|
||||
for (const t of tree) {
|
||||
for (const t of tree as string[]) {
|
||||
output[`Tags.${t}`] = {
|
||||
value: [true, "xsd:boolean"],
|
||||
valueTimestamp: timestamp,
|
||||
@@ -410,14 +421,14 @@ export function flattenDevice(device) {
|
||||
return newDevice;
|
||||
}
|
||||
|
||||
export function flattenFault(fault) {
|
||||
export function flattenFault(fault): Fault {
|
||||
const f = Object.assign({}, fault);
|
||||
if (f.timestamp) f.timestamp = +f.timestamp;
|
||||
if (f.expiry) f.expiry = +f.expiry;
|
||||
return f;
|
||||
}
|
||||
|
||||
export function flattenTask(task) {
|
||||
export function flattenTask(task): Task {
|
||||
const t = Object.assign({}, task);
|
||||
t._id = "" + t._id;
|
||||
if (t.timestamp) t.timestamp = +t.timestamp;
|
||||
@@ -425,9 +436,9 @@ export function flattenTask(task) {
|
||||
return t;
|
||||
}
|
||||
|
||||
function mongoQueryToFilter(query) {
|
||||
function mongoQueryToFilter(query): Expression {
|
||||
const expressions = [];
|
||||
function recursive(_query) {
|
||||
function recursive(_query): void {
|
||||
for (const [k, v] of Object.entries(_query)) {
|
||||
if (k[0] === "$") {
|
||||
if (k === "$and") for (const vv of Object.values(v)) recursive(vv);
|
||||
@@ -492,7 +503,7 @@ function mongoQueryToFilter(query) {
|
||||
return expressions;
|
||||
}
|
||||
|
||||
export function flattenPreset(preset) {
|
||||
export function flattenPreset(preset): {} {
|
||||
const p = Object.assign({}, preset);
|
||||
if (p.precondition) {
|
||||
p.precondition = mongoQueryToFilter(JSON.parse(p.precondition));
|
||||
@@ -521,7 +532,7 @@ export function flattenPreset(preset) {
|
||||
return p;
|
||||
}
|
||||
|
||||
export function flattenFile(file) {
|
||||
export function flattenFile(file): {} {
|
||||
const f = {};
|
||||
f["_id"] = file["_id"];
|
||||
if (file.metadata) {
|
||||
@@ -533,7 +544,7 @@ export function flattenFile(file) {
|
||||
return f;
|
||||
}
|
||||
|
||||
export function preProcessPreset(data) {
|
||||
export function preProcessPreset(data): {} {
|
||||
const preset = Object.assign({}, data);
|
||||
preset.precondition = preset.precondition
|
||||
? filterToMongoQuery(parse(preset.precondition))
|
||||
@@ -561,7 +572,8 @@ export function preProcessPreset(data) {
|
||||
|
||||
const configuration = {
|
||||
type: "provision",
|
||||
name: preset.provision
|
||||
name: preset.provision,
|
||||
args: null
|
||||
};
|
||||
|
||||
if (preset.provisionArgs)
|
||||
Reference in new issue
Block a user