From a500662a27ce3b652d50f9324859fad1c908723c Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Fri, 22 Dec 2023 11:42:36 +0100 Subject: [PATCH 1/6] minor bug fix --- system/component/class.component.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/system/component/class.component.js b/system/component/class.component.js index e0bc134..691b1a1 100644 --- a/system/component/class.component.js +++ b/system/component/class.component.js @@ -786,7 +786,7 @@ module.exports = class COMPONENT extends COMMON { /** * @function _labels - * Checks if filter array contains matching labels + * Checks if filter array contains matching labels on items.labels array * * @param {Array} arr Array with item labels to check with filter * @param {Array} filter Filter array @@ -795,7 +795,13 @@ module.exports = class COMPONENT extends COMMON { */ _labels(arr, filter) { return filter.every((filter) => { - if (arr.includes(filter)) { + if (arr.map((label) => { + + // convert back to string array + // so the .include can do its job + return label.toString(); + + }).includes(filter)) { return true; @@ -805,14 +811,12 @@ module.exports = class COMPONENT extends COMMON { return arr.some((label) => { - let [k, v] = label.split("="); - if (value === "*") { - return key === k; + return key === label.key; } if (key === "*") { - return value === v; + return value === label.value; } return false; From fd6a608cc851cbb6a90f2499c64b9c183aec0b96 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Sat, 23 Dec 2023 14:20:17 +0100 Subject: [PATCH 2/6] fix #380 --- routes/router.api.plugins.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/routes/router.api.plugins.js b/routes/router.api.plugins.js index e51edea..95450b1 100644 --- a/routes/router.api.plugins.js +++ b/routes/router.api.plugins.js @@ -75,8 +75,13 @@ module.exports = (app, router) => { try { let p = path.resolve(process.cwd(), "plugins", req.item.uuid); + let files = await fs.readdir(p); - for (let file of await fs.readdir(p)) { + // add plugin directory as last item + // every files/folder inside are deleted before + files.push(p); + + for (let file of files) { await fs.rm(path.join(p, file), { recursive: true }); From 4f627f694c09472b062e08e91f4a9f3573285425 Mon Sep 17 00:00:00 2001 From: Marc Stirner Date: Sat, 23 Dec 2023 14:36:52 +0100 Subject: [PATCH 3/6] Undo last change --- routes/router.api.plugins.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/routes/router.api.plugins.js b/routes/router.api.plugins.js index 95450b1..e51edea 100644 --- a/routes/router.api.plugins.js +++ b/routes/router.api.plugins.js @@ -75,13 +75,8 @@ module.exports = (app, router) => { try { let p = path.resolve(process.cwd(), "plugins", req.item.uuid); - let files = await fs.readdir(p); - // add plugin directory as last item - // every files/folder inside are deleted before - files.push(p); - - for (let file of files) { + for (let file of await fs.readdir(p)) { await fs.rm(path.join(p, file), { recursive: true }); From 75018bd9a4da8847df9c6b7cd2746fcc4a529f30 Mon Sep 17 00:00:00 2001 From: mStirner Date: Sun, 24 Dec 2023 12:14:57 +0100 Subject: [PATCH 4/6] fix #381 --- system/component/class.component.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/system/component/class.component.js b/system/component/class.component.js index 691b1a1..575bd31 100644 --- a/system/component/class.component.js +++ b/system/component/class.component.js @@ -689,7 +689,10 @@ module.exports = class COMPONENT extends COMMON { if (key === "labels" && Array.isArray(filter[key]) && Array.isArray(target[key])) { found = filter[key].every((label) => { - return target[key].includes(label); + // fix #381 + // target[key] is a instance if class.labels.js and not of plain string. + // convert it to a array wiht plain strings, so that .includes works. + return target[key]?.toString().includes(label); }); return; From 9df38b752e04a6ae7d6e36ec484d0e4f2973eacb Mon Sep 17 00:00:00 2001 From: mStirner Date: Fri, 29 Dec 2023 19:40:14 +0100 Subject: [PATCH 5/6] fix #383 --- components/endpoints/class.command.js | 55 ++++++++++++--------- components/endpoints/class.param.js | 70 +++++++++++++++++++++++++++ 2 files changed, 102 insertions(+), 23 deletions(-) create mode 100644 components/endpoints/class.param.js diff --git a/components/endpoints/class.command.js b/components/endpoints/class.command.js index 1595d07..5aca593 100644 --- a/components/endpoints/class.command.js +++ b/components/endpoints/class.command.js @@ -4,6 +4,7 @@ const mongodb = require("mongodb"); const _timeout = require("../../helper/timeout.js"); const { interfaces } = require("../../system/shared.js"); +const Param = require("./class.param.js"); /** * @description @@ -84,6 +85,13 @@ module.exports = class Command { this.payload = obj.payload.read(0); } + // fix #383 + obj.params?.forEach((param, i, arr) => { + if (!(param instanceof Param)) { + arr[i] = new Param(param); + } + }); + // command duration timeout this.#privates.set("timeout", Number(process.env.COMMAND_RESPONSE_TIMEOUT)); @@ -190,12 +198,35 @@ module.exports = class Command { let worker = this.#privates.get("handler"); let iface = interfaces.get(this.interface); + //console.log("params array:", this.params, params) + + let valid = params.every(({ key, value }) => { + + let param = this.params.find((param) => { + return param.key === key; + }); + + // auto convert "123" to 123 + if (param.type === "number") { + value = Number(value); + } + + return typeof (value) === param.type; + + }); + if (!iface) { let err = new Error(`Interface "${this.interface}" not found, cant write to it.`); err.code = "NO_INTERFACE"; return cb(err, false); } + if (!valid) { + let err = new Error(`Invalid params type`); + err.code = "INVALID_PARAMETER_TYPE"; + return cb(err); + } + let timer = _timeout(this.#privates.get("timeout"), (timedout, duration, args) => { if (timedout) { @@ -237,29 +268,7 @@ module.exports = class Command { //payload: Joi.string().allow(null).default(null), payload: Joi.alternatives().try(Joi.string(), Joi.binary()).allow(null).default(null), description: Joi.string().allow(null).default(null), - params: Joi.array().items(Joi.object({ - type: Joi.string().valid("number", "string", "boolean").required(), - key: Joi.string().required() - }).when(".type", { - switch: [{ - is: "number", - then: Joi.object({ - value: Joi.number().default(null).allow(null), - min: Joi.number().default(0), - max: Joi.number().default(100) - }) - }, { - is: "string", - then: Joi.object({ - value: Joi.string().default(null).allow(null) - }) - }, { - is: "boolean", - then: Joi.object({ - value: Joi.boolean().default(null).allow(null) - }) - }] - })) + params: Joi.array().items(Param.schema()) }); } diff --git a/components/endpoints/class.param.js b/components/endpoints/class.param.js new file mode 100644 index 0000000..0f53c6b --- /dev/null +++ b/components/endpoints/class.param.js @@ -0,0 +1,70 @@ +const Joi = require("joi"); + +module.exports = class Param { + + constructor(obj) { + + Object.assign(this, obj); + + Object.defineProperty(this, "value", { + get() { + return obj.value; + }, + set(val) { + + if (val === null) { + obj.value = null; + return; + } + + if (typeof (val) !== obj.type) { + throw new Error(`Parameter "${obj.key}" invalid type ${typeof (val)}. Expected ${obj.type}`); + } + + if (obj.type === "number" && !(val >= obj.min && obj.max >= val)) { + throw new Error(`Invalid value: ${val}. Expected value >= ${obj.min} or ${obj.max} >= value`); + } + + obj.value = val; + + }, + enumerable: true, + configurable: true + }); + + } + + static schema() { + return Joi.object({ + type: Joi.string().valid("number", "string", "boolean").required(), + key: Joi.string().required() + }).when(".type", { + switch: [{ + is: "number", + then: Joi.object({ + value: Joi.number().default(null).allow(null), + min: Joi.number().default(0), + max: Joi.number().default(100), + //default: Joi.number().allow(null).default(null) + }) + }, { + is: "string", + then: Joi.object({ + value: Joi.string().default(null).allow(null), + //default: Joi.string().allow(null).default(null) + }) + }, { + is: "boolean", + then: Joi.object({ + value: Joi.boolean().default(null).allow(null), + //default: Joi.boolean().allow(null).default(null) + }) + }] + }); + } + + static validate(data) { + return Param.schema().validate(data); + } + +}; \ No newline at end of file From 2b2429168d64eefedc08afe1004bb2ffd40ef9a4 Mon Sep 17 00:00:00 2001 From: mStirner Date: Fri, 29 Dec 2023 19:42:48 +0100 Subject: [PATCH 6/6] minor bug fix --- routes/router.api.endpoints.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/router.api.endpoints.js b/routes/router.api.endpoints.js index 0fb8bf1..ad0217d 100644 --- a/routes/router.api.endpoints.js +++ b/routes/router.api.endpoints.js @@ -47,7 +47,7 @@ module.exports = (app, router) => { error: err.message }); } else { - res.status(500).end({ + res.status(500).json({ error: err.message }); }