TypeScript!

This commit is contained in:
Zaid Abdulla committed 2019-02-20 03:36:52 -08:00
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;
+18 -16
View File
@@ -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
View File
@@ -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)