Introduce ESLint and Prettier
This commit is contained in:
1 parent
9c943d0bbf
commit
e494bdca8a
26 files changed
+1585
-1594
No files matched your search
+150
-129
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright 2013-2017 Zaid Abdulla
|
||||
* Copyright 2013-2018 Zaid Abdulla
|
||||
*
|
||||
* This file is part of GenieACS.
|
||||
*
|
||||
@@ -28,7 +28,6 @@ const extensions = require("./extensions");
|
||||
const logger = require("./logger");
|
||||
const scheduling = require("./scheduling");
|
||||
|
||||
|
||||
// Used for throwing to exit user script and commit
|
||||
const COMMIT = Symbol();
|
||||
|
||||
@@ -49,24 +48,20 @@ function runExtension(sessionContext, key, extCall, callback) {
|
||||
|
||||
if (re[key]) {
|
||||
re[key].push(callback);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
re[key] = [callback];
|
||||
extensions.run(extCall, function(err, fault, res) {
|
||||
extensions.run(extCall, (err, fault, res) => {
|
||||
const callbacks = re[key];
|
||||
delete re[key];
|
||||
if (!err && !fault)
|
||||
sessionContext.extensionsCache[key] = res;
|
||||
for (let c of callbacks)
|
||||
c(err, fault);
|
||||
if (!err && !fault) sessionContext.extensionsCache[key] = res;
|
||||
for (let c of callbacks) c(err, fault);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class SandboxDate {
|
||||
constructor() {
|
||||
if (arguments.length)
|
||||
return new Date(...arguments);
|
||||
if (arguments.length) return new Date(...arguments);
|
||||
|
||||
return new Date(state.sessionContext.timestamp);
|
||||
}
|
||||
@@ -75,120 +70,128 @@ class SandboxDate {
|
||||
let t = state.sessionContext.timestamp;
|
||||
|
||||
if (typeof intervalOrCron === "number") {
|
||||
|
||||
if (variance == null)
|
||||
variance = intervalOrCron;
|
||||
if (variance == null) variance = intervalOrCron;
|
||||
|
||||
let offset = 0;
|
||||
if (variance)
|
||||
offset = scheduling.variance(state.sessionContext.deviceId, variance);
|
||||
|
||||
t = scheduling.interval(t, intervalOrCron, offset);
|
||||
}
|
||||
else if (typeof intervalOrCron === "string") {
|
||||
} else if (typeof intervalOrCron === "string") {
|
||||
let offset = 0;
|
||||
if (variance)
|
||||
offset = scheduling.variance(state.sessionContext.deviceId, variance);
|
||||
let cron = scheduling.parseCron(intervalOrCron);
|
||||
t = scheduling.cron(t, cron, offset)[0];
|
||||
}
|
||||
else if (intervalOrCron) {
|
||||
} else if (intervalOrCron) {
|
||||
throw new Error("Invalid Date.now() argument");
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function random() {
|
||||
if (!state.rng)
|
||||
state.rng = seedrandom(state.sessionContext.deviceId);
|
||||
if (!state.rng) state.rng = seedrandom(state.sessionContext.deviceId);
|
||||
|
||||
return state.rng();
|
||||
}
|
||||
|
||||
random.seed = function(s) {
|
||||
state.rng = seedrandom(s);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class ParameterWrapper {
|
||||
constructor(path, attributes, unpacked, unpackedRevision) {
|
||||
for (let attrName of attributes) {
|
||||
Object.defineProperty(this, attrName, {get: function() {
|
||||
if (state.uncommitted)
|
||||
commit();
|
||||
Object.defineProperty(this, attrName, {
|
||||
get: function() {
|
||||
if (state.uncommitted) commit();
|
||||
|
||||
if (state.revision !== unpackedRevision) {
|
||||
unpackedRevision = state.revision;
|
||||
unpacked = device.unpack(
|
||||
state.sessionContext.deviceData,
|
||||
path,
|
||||
state.revision
|
||||
);
|
||||
}
|
||||
|
||||
if (!unpacked.length) return undefined;
|
||||
|
||||
let attr = state.sessionContext.deviceData.attributes.get(
|
||||
unpacked[0],
|
||||
state.revision
|
||||
)[attrName];
|
||||
|
||||
if (!attr) return undefined;
|
||||
|
||||
return attr[1];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Object.defineProperty(this, "path", {
|
||||
get: function() {
|
||||
if (state.uncommitted) commit();
|
||||
|
||||
if (state.revision !== unpackedRevision) {
|
||||
unpackedRevision = state.revision;
|
||||
unpacked = device.unpack(state.sessionContext.deviceData, path, state.revision);
|
||||
unpacked = device.unpack(
|
||||
state.sessionContext.deviceData,
|
||||
path,
|
||||
state.revision
|
||||
);
|
||||
}
|
||||
|
||||
if (!unpacked.length)
|
||||
return undefined;
|
||||
if (!unpacked.length) return undefined;
|
||||
|
||||
let attr = state.sessionContext.deviceData.attributes.get(unpacked[0], state.revision)[attrName];
|
||||
|
||||
if (!attr)
|
||||
return undefined;
|
||||
|
||||
return attr[1];
|
||||
}});
|
||||
}
|
||||
|
||||
Object.defineProperty(this, "path", {get: function() {
|
||||
if (state.uncommitted)
|
||||
commit();
|
||||
|
||||
if (state.revision !== unpackedRevision) {
|
||||
unpackedRevision = state.revision;
|
||||
unpacked = device.unpack(state.sessionContext.deviceData, path, state.revision);
|
||||
return unpacked[0].join(".");
|
||||
}
|
||||
});
|
||||
|
||||
if (!unpacked.length)
|
||||
return undefined;
|
||||
Object.defineProperty(this, "size", {
|
||||
get: function() {
|
||||
if (state.uncommitted) commit();
|
||||
|
||||
return unpacked[0].join(".");
|
||||
}});
|
||||
if (state.revision !== unpackedRevision) {
|
||||
unpackedRevision = state.revision;
|
||||
unpacked = device.unpack(
|
||||
state.sessionContext.deviceData,
|
||||
path,
|
||||
state.revision
|
||||
);
|
||||
}
|
||||
|
||||
Object.defineProperty(this, "size", {get: function() {
|
||||
if (state.uncommitted)
|
||||
commit();
|
||||
if (!unpacked.length) return undefined;
|
||||
|
||||
if (state.revision !== unpackedRevision) {
|
||||
unpackedRevision = state.revision;
|
||||
unpacked = device.unpack(state.sessionContext.deviceData, path, state.revision);
|
||||
return unpacked.length;
|
||||
}
|
||||
|
||||
if (!unpacked.length)
|
||||
return undefined;
|
||||
|
||||
return unpacked.length;
|
||||
}});
|
||||
});
|
||||
|
||||
this[Symbol.iterator] = function*() {
|
||||
if (state.uncommitted)
|
||||
commit();
|
||||
if (state.uncommitted) commit();
|
||||
|
||||
if (state.revision !== unpackedRevision) {
|
||||
unpackedRevision = state.revision;
|
||||
unpacked = device.unpack(state.sessionContext.deviceData, path, state.revision);
|
||||
unpacked = device.unpack(
|
||||
state.sessionContext.deviceData,
|
||||
path,
|
||||
state.revision
|
||||
);
|
||||
}
|
||||
|
||||
for (let p of unpacked)
|
||||
yield new ParameterWrapper(p, attributes, [p], state.revision);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function declare(path, timestamps, values) {
|
||||
state.uncommitted = true;
|
||||
if (!timestamps)
|
||||
timestamps = {};
|
||||
if (!timestamps) timestamps = {};
|
||||
|
||||
if (!values)
|
||||
values = {};
|
||||
if (!values) values = {};
|
||||
|
||||
let parsedPath = common.parsePath(path);
|
||||
|
||||
@@ -196,25 +199,23 @@ function declare(path, timestamps, values) {
|
||||
let attrs = {};
|
||||
|
||||
for (let attrName in values) {
|
||||
if (!timestamps[attrName])
|
||||
timestamps[attrName] = 1;
|
||||
if (!timestamps[attrName]) timestamps[attrName] = 1;
|
||||
|
||||
if (attrName === "path")
|
||||
if (attrName === "path") {
|
||||
declaration[3] = values.path;
|
||||
else {
|
||||
} else {
|
||||
attrs[attrName] = 1;
|
||||
declaration[4] = declaration[4] || {};
|
||||
if (attrName === "value" && !Array.isArray(values.value))
|
||||
declaration[4].value = [values.value];
|
||||
else
|
||||
declaration[4][attrName] = values[attrName];
|
||||
else declaration[4][attrName] = values[attrName];
|
||||
}
|
||||
}
|
||||
|
||||
for (let attrName in timestamps) {
|
||||
if (attrName === "path")
|
||||
if (attrName === "path") {
|
||||
declaration[1] = timestamps.path;
|
||||
else {
|
||||
} else {
|
||||
attrs[attrName] = 1;
|
||||
declaration[2] = declaration[2] || {};
|
||||
declaration[2][attrName] = timestamps[attrName];
|
||||
@@ -226,7 +227,6 @@ function declare(path, timestamps, values) {
|
||||
return new ParameterWrapper(parsedPath, Object.keys(attrs));
|
||||
}
|
||||
|
||||
|
||||
function clear(path, timestamp, attributes) {
|
||||
state.uncommitted = true;
|
||||
|
||||
@@ -234,20 +234,21 @@ function clear(path, timestamp, attributes) {
|
||||
state.clear.push([common.parsePath(path), timestamp, attributes]);
|
||||
}
|
||||
|
||||
|
||||
function commit() {
|
||||
++ state.revision;
|
||||
++state.revision;
|
||||
state.uncommitted = false;
|
||||
|
||||
if (state.revision === state.maxRevision + 1)
|
||||
if (state.revision === state.maxRevision + 1) {
|
||||
throw COMMIT;
|
||||
else if (state.revision > state.maxRevision + 1)
|
||||
throw new Error("Declare function should not be called from within a try/catch block");
|
||||
} else if (state.revision > state.maxRevision + 1) {
|
||||
throw new Error(
|
||||
"Declare function should not be called from within a try/catch block"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function ext() {
|
||||
++ state.extCounter;
|
||||
++state.extCounter;
|
||||
let extCall = Array.from(arguments).map(String);
|
||||
let key = `${state.revision}: ${JSON.stringify(extCall)}`;
|
||||
|
||||
@@ -258,7 +259,6 @@ function ext() {
|
||||
throw EXT;
|
||||
}
|
||||
|
||||
|
||||
function log(msg, meta) {
|
||||
if (state.revision === state.maxRevision && state.extCounter >= 0) {
|
||||
const details = Object.assign({}, meta, {
|
||||
@@ -277,26 +277,22 @@ function log(msg, meta) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Object.defineProperty(context, "Date", {value: SandboxDate});
|
||||
Object.defineProperty(context, "declare", {value: declare});
|
||||
Object.defineProperty(context, "clear", {value: clear});
|
||||
Object.defineProperty(context, "commit", {value: commit});
|
||||
Object.defineProperty(context, "ext", {value: ext});
|
||||
Object.defineProperty(context, "log", {value: log});
|
||||
Object.defineProperty(context, "Date", { value: SandboxDate });
|
||||
Object.defineProperty(context, "declare", { value: declare });
|
||||
Object.defineProperty(context, "clear", { value: clear });
|
||||
Object.defineProperty(context, "commit", { value: commit });
|
||||
Object.defineProperty(context, "ext", { value: ext });
|
||||
Object.defineProperty(context, "log", { value: log });
|
||||
|
||||
// Monkey-patch Math.random() to make it deterministic
|
||||
context.random = random;
|
||||
vm.runInContext("Math.random = random;", context);
|
||||
delete context.random;
|
||||
|
||||
|
||||
function errorToFault(err) {
|
||||
if (!err)
|
||||
return null;
|
||||
if (!err) return null;
|
||||
|
||||
if (!err.name)
|
||||
return {code: "script", message: `${err}`};
|
||||
if (!err.name) return { code: "script", message: `${err}` };
|
||||
|
||||
let fault = {
|
||||
code: `script.${err.name}`,
|
||||
@@ -310,7 +306,9 @@ function errorToFault(err) {
|
||||
if (err.stack) {
|
||||
fault.detail.stack = err.stack;
|
||||
// Trim the stack trace at the self-executing anonymous wrapper function
|
||||
let stackTrimIndex = fault.detail.stack.match(/\s+at\s[^\s]+\s+at\s[^\s]+\s\(vm\.js.+\)/);
|
||||
let stackTrimIndex = fault.detail.stack.match(
|
||||
/\s+at\s[^\s]+\s+at\s[^\s]+\s\(vm\.js.+\)/
|
||||
);
|
||||
if (stackTrimIndex)
|
||||
fault.detail.stack = fault.detail.stack.slice(0, stackTrimIndex.index);
|
||||
}
|
||||
@@ -318,8 +316,15 @@ function errorToFault(err) {
|
||||
return fault;
|
||||
}
|
||||
|
||||
|
||||
function run(script, globals, sessionContext, startRevision, maxRevision, callback, extCounter = 0) {
|
||||
function run(
|
||||
script,
|
||||
globals,
|
||||
sessionContext,
|
||||
startRevision,
|
||||
maxRevision,
|
||||
callback,
|
||||
extCounter = 0
|
||||
) {
|
||||
state = {
|
||||
sessionContext: sessionContext,
|
||||
revision: startRevision,
|
||||
@@ -332,24 +337,19 @@ function run(script, globals, sessionContext, startRevision, maxRevision, callba
|
||||
extCounter: extCounter
|
||||
};
|
||||
|
||||
for (let n of Object.keys(context))
|
||||
delete context[n];
|
||||
for (let n of Object.keys(context)) delete context[n];
|
||||
|
||||
Object.assign(context, globals);
|
||||
|
||||
let ret, status;
|
||||
|
||||
try {
|
||||
ret = script.runInContext(context, {displayErrors: false});
|
||||
ret = script.runInContext(context, { displayErrors: false });
|
||||
status = 0;
|
||||
}
|
||||
catch (err) {
|
||||
if (err === COMMIT)
|
||||
status = 1;
|
||||
else if (err === EXT)
|
||||
status = 2;
|
||||
else
|
||||
return callback(null, errorToFault(err));
|
||||
} catch (err) {
|
||||
if (err === COMMIT) status = 1;
|
||||
else if (err === EXT) status = 2;
|
||||
else return callback(null, errorToFault(err));
|
||||
}
|
||||
|
||||
let _state = state;
|
||||
@@ -363,26 +363,47 @@ function run(script, globals, sessionContext, startRevision, maxRevision, callba
|
||||
let counter = 3;
|
||||
for (let key of Object.keys(_state.extensions)) {
|
||||
counter += 2;
|
||||
runExtension(_state.sessionContext, key, _state.extensions[key], function(err, fault) {
|
||||
if (err || fault) {
|
||||
if (counter & 1)
|
||||
callback(err, fault);
|
||||
return counter = 0;
|
||||
runExtension(
|
||||
_state.sessionContext,
|
||||
key,
|
||||
_state.extensions[key],
|
||||
(err, fault) => {
|
||||
if (err || fault) {
|
||||
if (counter & 1) callback(err, fault);
|
||||
return (counter = 0);
|
||||
}
|
||||
if ((counter -= 2) === 1) {
|
||||
if (status === 2) {
|
||||
return run.apply(null, args);
|
||||
} else {
|
||||
return callback(
|
||||
null,
|
||||
null,
|
||||
_state.clear,
|
||||
_state.declarations,
|
||||
status === 0,
|
||||
ret
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((counter -= 2) === 1)
|
||||
if (status === 2)
|
||||
return run.apply(null, args);
|
||||
else
|
||||
return callback(null, null, _state.clear, _state.declarations, status === 0, ret);
|
||||
});
|
||||
);
|
||||
}
|
||||
|
||||
if ((counter -= 2) === 1)
|
||||
if (status === 2)
|
||||
if ((counter -= 2) === 1) {
|
||||
if (status === 2) {
|
||||
return run.apply(null, args);
|
||||
else
|
||||
return callback(null, null, _state.clear, _state.declarations, status === 0, ret);
|
||||
} else {
|
||||
return callback(
|
||||
null,
|
||||
null,
|
||||
_state.clear,
|
||||
_state.declarations,
|
||||
status === 0,
|
||||
ret
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
exports.run = run;
|
||||
Reference in new issue
Block a user